Skip to content

Commit c7e49d1

Browse files
authored
Merge pull request #285 from WeGo-Together/somang-feat/create-group
[Feat] 모임생성/수정 정책 필드 추가
2 parents 3215f5f + 25f7e01 commit c7e49d1

File tree

14 files changed

+75
-38
lines changed

14 files changed

+75
-38
lines changed

src/app/create-group/[groupId]/page.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
GroupDetailField,
1313
GroupImagesField,
1414
GroupLocationField,
15+
GroupPolicyField,
1516
GroupSubmitButton,
1617
GroupTagsField,
1718
GroupTitleField,
@@ -38,7 +39,9 @@ const EditGroupPage = ({ params }: Props) => {
3839
tags,
3940
description,
4041
maxParticipants,
42+
joinPolicy,
4143
images,
44+
participantCount,
4245
} = data as GetGroupDetailsResponse;
4346

4447
const { defaultImages } = convertToDefaultImages(images);
@@ -51,8 +54,8 @@ const EditGroupPage = ({ params }: Props) => {
5154
tags,
5255
description,
5356
maxParticipants,
57+
joinPolicy,
5458
images: defaultImages,
55-
joinPolicy: 'FREE',
5659
} as CreateGroupFormValues,
5760
validators: {
5861
onChange: createGroupSchema,
@@ -77,9 +80,15 @@ const EditGroupPage = ({ params }: Props) => {
7780
<form.Field children={(field) => <GroupLocationField field={field} />} name='location' />
7881
<form.Field children={(field) => <GroupDateField field={field} />} name='startTime' />
7982
<form.Field
80-
children={(field) => <GroupCapField field={field} />}
83+
children={(field) => (
84+
<GroupCapField field={field} participantCount={participantCount} />
85+
)}
8186
name='maxParticipants'
8287
/>
88+
<form.Field
89+
children={(field) => <GroupPolicyField field={field} isEditMode={true} />}
90+
name='joinPolicy'
91+
/>
8392
<form.Field children={(field) => <GroupImagesField field={field} />} name='images' />
8493
<form.Field children={(field) => <GroupDetailField field={field} />} name='description' />
8594
<form.Field children={(field) => <GroupTagsField field={field} />} name='tags' />

src/app/create-group/page.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
GroupDetailField,
1111
GroupImagesField,
1212
GroupLocationField,
13+
GroupPolicyField,
1314
GroupSubmitButton,
1415
GroupTagsField,
1516
GroupTitleField,
@@ -29,8 +30,8 @@ const CreateGroupPage = () => {
2930
tags: [],
3031
description: '',
3132
maxParticipants: 0,
32-
images: [],
3333
joinPolicy: 'FREE',
34+
images: [],
3435
} as CreateGroupFormValues,
3536
validators: {
3637
onChange: createGroupSchema,
@@ -58,6 +59,10 @@ const CreateGroupPage = () => {
5859
children={(field) => <GroupCapField field={field} />}
5960
name='maxParticipants'
6061
/>
62+
<form.Field
63+
children={(field) => <GroupPolicyField field={field} isEditMode={false} />}
64+
name='joinPolicy'
65+
/>
6166
<form.Field children={(field) => <GroupImagesField field={field} />} name='images' />
6267
<form.Field children={(field) => <GroupDetailField field={field} />} name='description' />
6368
<form.Field children={(field) => <GroupTagsField field={field} />} name='tags' />

src/components/pages/create-group/fields/cap-field/index.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,18 @@ import { Input, Label } from '@/components/ui';
77

88
interface Props {
99
field: AnyFieldApi;
10+
participantCount?: number;
1011
}
1112

12-
export const GroupCapField = ({ field }: Props) => {
13+
export const GroupCapField = ({ field, participantCount = 0 }: Props) => {
14+
const handleOnBlur = (e: React.ChangeEvent<HTMLInputElement>) => {
15+
const value = Number(e.target.value);
16+
17+
if (value < participantCount) field.handleChange(participantCount);
18+
else if (value < 2) field.handleChange(2);
19+
else if (value > 12) field.handleChange(12);
20+
};
21+
1322
return (
1423
<div className='mt-3 flex w-full flex-col gap-1'>
1524
<Label htmlFor='create-group-cap' required>
@@ -32,11 +41,7 @@ export const GroupCapField = ({ field }: Props) => {
3241
required
3342
type='number'
3443
value={!!field.state.value && field.state.value}
35-
onBlur={(e) => {
36-
const value = Number(e.target.value);
37-
if (value < 2) field.handleChange(2);
38-
else if (value > 12) field.handleChange(12);
39-
}}
44+
onBlur={(e) => handleOnBlur(e)}
4045
onChange={(e) => {
4146
field.handleChange(Number(e.target.value));
4247
}}

src/components/pages/create-group/fields/date-field/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ export const GroupDateField = ({ field }: Props) => {
4646
hasValue && 'text-gray-800',
4747
)}
4848
>
49-
{hasValue ? formattedDate : '날짜와 시간을 선택해주세요'}
49+
{hasValue ? (
50+
formattedDate
51+
) : (
52+
<span className='select-none'>날짜와 시간을 선택해주세요</span>
53+
)}
5054
</p>
5155
</button>
5256
{isInvalid && <Hint className='mt-0.5' message={field.state.meta.errors[0].message} />}

src/components/pages/create-group/fields/detail-feild/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export const GroupDetailField = ({ field }: Props) => {
1818
</Label>
1919
<textarea
2020
id='create-group-Detail'
21-
className='bg-mono-white scrollbar-thin focus:border-mint-500 text-text-md-medium h-40 w-full resize-none rounded-2xl border border-gray-300 px-5 py-4 text-gray-800 focus:outline-none'
21+
className='bg-mono-white scrollbar-thin focus:border-mint-500 text-text-md-medium h-40 w-full resize-none rounded-2xl border border-gray-300 px-5 py-4 text-gray-800 placeholder:select-none focus:outline-none'
2222
maxLength={300}
2323
placeholder='모임에 대해 설명해주세요'
2424
required
@@ -27,9 +27,9 @@ export const GroupDetailField = ({ field }: Props) => {
2727
/>
2828
<div className='mt-0.5 flex'>
2929
{isInvalid && <Hint message={field.state.meta.errors[0].message} />}
30-
<div className='text-text-sm-medium ml-auto text-right text-gray-500'>
30+
<span className='text-text-sm-medium ml-auto text-right text-gray-500 select-none'>
3131
{field.state.value.length}/300
32-
</div>
32+
</span>
3333
</div>
3434
</div>
3535
);

src/components/pages/create-group/fields/images-field/index.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ export const GroupImagesField = ({ field }: Props) => {
9090
({ imageUrl100x100 }: PreUploadGroupImageResponse['images'][0], idx: number) => (
9191
<div key={imageUrl100x100} className='relative aspect-square w-full max-w-20'>
9292
<Image
93-
className='border-mono-black/5 h-full w-full rounded-2xl border-1 object-cover'
93+
className='border-mono-black/5 h-full w-full rounded-2xl border-1 object-cover select-none'
9494
alt='썸네일 이미지'
95+
draggable={false}
9596
fill
9697
src={imageUrl100x100}
9798
/>
@@ -112,7 +113,9 @@ export const GroupImagesField = ({ field }: Props) => {
112113
),
113114
)}
114115
</div>
115-
<p className='text-text-sm-medium px-2 text-gray-500'>최대 3개까지 업로드할 수 있어요.</p>
116+
<p className='text-text-sm-medium px-2 text-gray-500 select-none'>
117+
최대 3개까지 업로드할 수 있어요.
118+
</p>
116119
</div>
117120
);
118121
};

src/components/pages/create-group/fields/location-field/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const GroupLocationField = ({ field }: Props) => {
1919
open(<LocationSearchModal LocationField={field} />);
2020
};
2121

22+
const hasValue = field.state.value;
2223
const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid;
2324

2425
return (
@@ -39,11 +40,11 @@ export const GroupLocationField = ({ field }: Props) => {
3940
/>
4041
<p
4142
className={clsx(
42-
'text-text-md-medium text-left text-gray-500',
43+
'text-text-md-medium text-left text-gray-500 select-none',
4344
field.state.value && 'text-gray-800',
4445
)}
4546
>
46-
{field.state.value ? field.state.value : '모임 장소를 입력해주세요'}
47+
{hasValue ? field.state.value : <span>모임 장소를 입력해주세요</span>}
4748
</p>
4849
</button>
4950
{isInvalid && <Hint className='mt-0.5' message={field.state.meta.errors[0].message} />}

src/components/pages/create-group/fields/policy-field/index.tsx

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,33 @@ import { Label } from '@/components/ui';
44

55
interface Props {
66
field: AnyFieldApi;
7+
isEditMode: boolean;
78
}
89

9-
export const GroupPolicyField = ({ field }: Props) => {
10+
export const GroupPolicyField = ({ field, isEditMode }: Props) => {
1011
return (
1112
<div className='mt-6 space-y-4'>
12-
<Label htmlFor='create-group-policy'>참여 방식</Label>
13+
<Label htmlFor='create-group-joinPolicy'>참여 방식</Label>
1314
{POLICY_OPTIONS.map(({ type, name, description }) => {
1415
return (
15-
<div key={name} className='flex items-start gap-2'>
16-
<input
17-
id={name}
18-
className='size-6'
19-
checked={field.state.value === type}
20-
name='create-group-policy'
21-
type='radio'
22-
value={type}
23-
onChange={(e) => field.handleChange(e.target.value)}
24-
/>
25-
<Label htmlFor={name}>
26-
<p>{name}</p>
16+
<label key={name} className='flex gap-2 px-2 select-none'>
17+
<span className='flex-center has-focus:border-mint-500 size-6 cursor-pointer rounded-full border-1 border-gray-200 bg-white has-disabled:cursor-auto has-disabled:bg-gray-200'>
18+
<input
19+
className='checked:bg-mint-500 size-3 cursor-pointer appearance-none rounded-full outline-none disabled:cursor-auto'
20+
checked={field.state.value === type}
21+
disabled={isEditMode}
22+
name='create-group-policy'
23+
type='radio'
24+
value={type}
25+
onChange={(e) => field.handleChange(e.target.value)}
26+
/>
27+
</span>
28+
29+
<div className='text-text-sm-medium'>
30+
<p className='text-gray-700'>{name}</p>
2731
<p className='text-gray-500'>{description}</p>
28-
</Label>
29-
</div>
32+
</div>
33+
</label>
3034
);
3135
})}
3236
</div>

src/components/pages/create-group/fields/tags-field/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ export const GroupTagsField = ({ field }: Props) => {
7575
))}
7676
</ul>
7777

78-
<p className='text-text-sm-medium px-2 text-gray-500'>최대 10개까지 업로드할 수 있어요.</p>
78+
<p className='text-text-sm-medium px-2 text-gray-500 select-none'>
79+
최대 10개까지 업로드할 수 있어요.
80+
</p>
7981
{isInvalid && <Hint className='mt-0.5' message={field.state.meta.errors[0].message} />}
8082
</div>
8183
);

src/components/pages/create-group/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export { GroupDateField } from './fields/date-field';
33
export { GroupDetailField } from './fields/detail-feild';
44
export { GroupImagesField } from './fields/images-field';
55
export { GroupLocationField } from './fields/location-field';
6+
export { GroupPolicyField } from './fields/policy-field';
67
export { GroupTagsField } from './fields/tags-field';
78
export { GroupTitleField } from './fields/title-field';
89
export { GroupSubmitButton } from './post-button';

0 commit comments

Comments
 (0)