Skip to content

Commit

Permalink
✨ add create group page
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnsonMao committed Jan 28, 2024
1 parent 5cca26b commit ce8164e
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 0 deletions.
41 changes: 41 additions & 0 deletions components/Group/Form/Form.styled.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import styled from '@emotion/styled';
import InputLabel from '@mui/material/InputLabel';

export const StyledHeading = styled.h1`
margin-bottom: 8px;
text-align: center;
font-size: 22px;
font-weight: 700;
color: #536166;
`;

export const StyledDescription = styled.p`
margin-bottom: 40px;
text-align: center;
font-size: 14px;
font-weight: 400;
color: #536166;
`;

export const StyledContainer = styled.main`
position: relative;
margin: 0 auto;
width: 720px;
@media (max-width: 760px) {
padding: 20px;
width: 100%;
}
`;

export const StyledLabel = styled(InputLabel)`
display: block;
margin-bottom: 8px;
font-size: 16px;
font-weight: 500;
color: #293a3d;
`;

export const StyledGroup = styled.div`
margin-bottom: 20px;
`;
85 changes: 85 additions & 0 deletions components/Group/Form/FormItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { useId } from 'react';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import { StyledLabel, StyledGroup } from './Form.styled';
import Select from './Select';

function Wrapper({ id, required, label, children }) {
return (
<StyledGroup>
<StyledLabel htmlFor={id} required={required}>
{label}
</StyledLabel>
{children}
</StyledGroup>
);
}

export default function FormItem({
type,
label,
placeholder,
required,
options,
itemLabel,
itemValue,
value = '',
}) {
const id = useId();
const formItemId = `form-item-${id}`;
const wrapperProps = { id: formItemId, required, label };

if (type === 'select') {
return (
<Wrapper {...wrapperProps}>
<Select
id={formItemId}
options={options}
placeholder={placeholder}
value={value}
itemLabel={itemLabel}
itemValue={itemValue}
/>
</Wrapper>
);
}

if (type === 'location') {
return (
<Wrapper {...wrapperProps}>
<Box sx={{ display: 'flex', label: { whiteSpace: 'nowrap' } }}>
<FormControlLabel control={<Checkbox />} label="實體活動" />
<Select
id={formItemId}
options={options}
placeholder="地點"
value={value}
itemLabel={itemLabel}
itemValue={itemValue}
/>
</Box>
<div>
<FormControlLabel control={<Checkbox />} label="線上" />
</div>
<div>
<FormControlLabel control={<Checkbox />} label="待討論" />
</div>
</Wrapper>
);
}

return (
<Wrapper {...wrapperProps}>
<TextField
fullWidth
id={formItemId}
sx={{ '& legend': { display: 'none' } }}
size="small"
placeholder={placeholder}
value={value}
/>
</Wrapper>
);
}
45 changes: 45 additions & 0 deletions components/Group/Form/Select.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import MuiSelect from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';

export default function Select({
id,
value,
placeholder,
options = [],
itemLabel = 'label',
itemValue = 'key',
fullWidth = true,
sx,
}) {
const getValue = (any, key) => (typeof any === 'object' ? any[key] : any);

return (
<MuiSelect
displayEmpty
fullWidth={fullWidth}
id={id}
size="small"
sx={{
color: value ? '#000' : '#92989A',
'& legend': { display: 'none' },
'& fieldset': { top: 0 },
...sx,
}}
value={value}
>
{placeholder && (
<MenuItem disabled value="">
{placeholder}
</MenuItem>
)}
{options.map((item) => (
<MenuItem
key={getValue(item, itemValue)}
value={getValue(item, itemValue)}
>
{getValue(item, itemLabel)}
</MenuItem>
))}
</MuiSelect>
);
}
70 changes: 70 additions & 0 deletions components/Group/Form/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import Box from '@mui/material/Box';
import { CATEGORIES } from '@/constants/category';
import { AREAS } from '@/constants/areas';
import StyledPaper from '../Paper.styled';
import FormItem from './FormItem';
import {
StyledHeading,
StyledDescription,
StyledContainer,
} from './Form.styled';

const TaiwanAreas = AREAS.filter((area) => area.label !== '線上');

export default function GroupForm({ mode }) {
const isCreateMode = mode === 'create';

return (
<Box sx={{ background: '#f3fcfc', py: '60px' }}>
<StyledContainer>
<StyledPaper sx={{ p: '40px', mb: '16px' }}>
<StyledHeading>
{isCreateMode ? '發起揪團' : '編輯揪團'}
</StyledHeading>
<StyledDescription>
填寫完整資訊可以幫助其他夥伴更了解揪團內容哦!
</StyledDescription>
<FormItem
label="主題"
placeholder="為你的揪團取個響亮的主題吧!"
required
/>
<FormItem label="活動圖片" />
<FormItem
type="select"
label="學習領域"
options={CATEGORIES}
placeholder="這個活動的學習領域?"
required
/>
<FormItem
type="location"
label="地點"
options={TaiwanAreas}
itemValue="label"
required
/>
<FormItem
type="datePicker"
label="時間"
placeholder="希望在什麼時間舉行?"
/>
</StyledPaper>
<StyledPaper sx={{ p: '40px' }}>
<FormItem label="想找的夥伴" placeholder="想找什麼類型的夥伴?" />
<FormItem
label="適合的教育階段"
placeholder="活動適合什麼教育階段的夥伴?"
required
/>
<FormItem
label="描述"
placeholder="簡單的跟大家介紹你是誰,說明你的揪團活動內容、運作方式,邀請志同道合的夥伴一起來參與!"
required
/>
<FormItem label="標籤" placeholder="搜尋或新增標籤" />
</StyledPaper>
</StyledContainer>
</Box>
);
}
35 changes: 35 additions & 0 deletions pages/group/create/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { useMemo } from 'react';
import { useRouter } from 'next/router';
import SEOConfig from '@/shared/components/SEO';
import GroupForm from '@/components/Group/Form';
import Navigation from '@/shared/components/Navigation_v2';
import Footer from '@/shared/components/Footer_v2';

function GroupPage() {
const router = useRouter();

const SEOData = useMemo(
() => ({
title: '發起揪團|島島阿學',
description:
'「島島阿學」揪團專區,結交志同道合的學習夥伴!發起各種豐富多彩的揪團活動,共同探索學習的樂趣。一同參與,共同成長,打造學習的共好社群。加入我們,一起開啟學習的冒險旅程!',
keywords: '島島阿學',
author: '島島阿學',
copyright: '島島阿學',
imgLink: 'https://www.daoedu.tw/preview.webp',
link: `${process.env.HOSTNAME}${router?.asPath}`,
}),
[router?.asPath],
);

return (
<>
<SEOConfig data={SEOData} />
<Navigation />
<GroupForm mode="create" />
<Footer />
</>
);
}

export default GroupPage;

0 comments on commit ce8164e

Please sign in to comment.