Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/group detail #35

Merged
merged 8 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
);
}
8 changes: 5 additions & 3 deletions components/Group/GroupList/GroupCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import {
StyledLabel,
StyledText,
StyledTitle,
StyledStatus,
} from './GroupCard.styled';

function GroupCard({
_id,
photoURL,
photoAlt,
title = '未定義主題',
Expand All @@ -25,7 +27,7 @@ function GroupCard({
updatedDate,
}) {
return (
<StyledGroupCard>
<StyledGroupCard href={`/group/detail?id=${_id}`}>
<Image alt={photoAlt || '未放封面'} src={photoURL || emptyCoverImg.src} />
<StyledContainer>
<StyledTitle>{title}</StyledTitle>
Expand All @@ -49,9 +51,9 @@ function GroupCard({
<StyledFooter>
<time>{timeDuration(updatedDate)}</time>
{isGrouping ? (
<div>揪團中</div>
<StyledStatus>揪團中</StyledStatus>
) : (
<div className="finished">已結束</div>
<StyledStatus className="finished">已結束</StyledStatus>
)}
</StyledFooter>
</StyledContainer>
Expand Down
59 changes: 30 additions & 29 deletions components/Group/GroupList/GroupCard.styled.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styled from '@emotion/styled';
import Link from 'next/link';

export const StyledLabel = styled.span`
flex-basis: 50px;
Expand All @@ -21,6 +22,7 @@ export const StyledTitle = styled.h2`
font-weight: bold;
line-height: 1.4;
display: -webkit-box;
color: #293a3d;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
Expand All @@ -39,41 +41,39 @@ export const StyledFooter = styled.footer`
justify-content: space-between;
align-items: center;

time,
div {
font-size: 12px;
}

time {
font-size: 12px;
font-weight: 300;
color: #92989a;
}
`;

div {
--bg-color: #def5f5;
--color: #16b9b3;
display: flex;
align-items: center;
padding: 4px 10px;
background: var(--bg-color);
color: var(--color);
border-radius: 4px;
font-weight: 500;
gap: 4px;
export const StyledStatus = styled.div`
--bg-color: #def5f5;
--color: #16b9b3;
display: flex;
align-items: center;
width: max-content;
font-size: 12px;
padding: 4px 10px;
background: var(--bg-color);
color: var(--color);
border-radius: 4px;
font-weight: 500;
gap: 4px;

&::before {
content: '';
display: block;
width: 8px;
height: 8px;
background: var(--color);
border-radius: 50%;
}
&::before {
content: '';
display: block;
width: 8px;
height: 8px;
background: var(--color);
border-radius: 50%;
}

&.finished {
--bg-color: #f3f3f3;
--color: #92989a;
}
&.finished {
--bg-color: #f3f3f3;
--color: #92989a;
}
`;

Expand All @@ -89,7 +89,8 @@ export const StyledAreas = styled.div`
align-items: center;
`;

export const StyledGroupCard = styled.div`
export const StyledGroupCard = styled(Link)`
display: block;
position: relative;
background: #fff;
padding: 0.5rem;
Expand Down
Loading
Loading