Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6b7ea7c
Feat: μŠ€μΌˆλ ˆν†€ μ»΄ν¬λ„ŒνŠΈ μΆ”κ°€
yulrang Nov 20, 2024
3257b25
πŸ› Fix: 컬럼 μˆ˜μ •
yulrang Nov 20, 2024
536f3b2
✨ Feat: λ§ˆμ΄νŽ˜μ΄μ§€ ν”„λ‘œν•„ μŠ€μΌˆλ ˆν†€ μΆ”κ°€
yulrang Nov 20, 2024
17d4514
✨ Feat: μž‘μ„±κ°€λŠ₯ν•œλ¦¬λ·° μŠ€μΌˆλ ˆν†€ μΆ”κ°€
yulrang Nov 20, 2024
59ac630
✨ Feat: λ‚˜μ˜ 리뷰 μŠ€μΌˆλ ˆν†€ μΆ”κ°€κ°€
yulrang Nov 20, 2024
e0e83ee
♿️ Fix: μ ‘κ·Όμ„± κ°œμ„ 
yulrang Nov 20, 2024
0878802
✨ Feat: λ‚˜μ˜ 약속 λ‘œλ”© μŠ€μΌˆλ ˆν†€ μΆ”κ°€
yulrang Nov 20, 2024
ff82386
πŸ’„ Design: ν˜Έλ²„μ‹œ 그림자 적용
yulrang Nov 20, 2024
f8f4f95
🚨 Fix: λΉŒλ“œ 였λ₯˜ μˆ˜μ •
yulrang Nov 20, 2024
52eb474
πŸ› Fix: DateTimePicker λ™μž‘κ°œμ„ 
yulrang Nov 20, 2024
013fde3
♿️ Fix: 크루 폼 μ ‘κ·Όμ„± κ°œμ„ 
yulrang Nov 20, 2024
8ecaabf
♿️ Fix : 약속 폼 μ ‘κ·Όμ„± κ°œμ„ 
yulrang Nov 20, 2024
fef8165
♿️ Fix: 크루찾기 μ ‘κ·Όμ„± κ°œμ„ 
yulrang Nov 20, 2024
fea5c28
πŸ› Fix: 이미지 fill, cover μ›Œλ‹ μ—†μ• κΈ°
yulrang Nov 20, 2024
de86036
Merge branch 'develop' into Fix/YoulBugFix
yulrang Nov 20, 2024
4dc9e50
Merge branch 'develop' into Fix/YoulBugFix
yulrang Nov 20, 2024
3ce5331
🍱 Fix: μƒ˜ν”Œ 이미지 ꡐ체
yulrang Nov 21, 2024
cbb4d4e
✨ Feat: 메타 μ„€μ •
yulrang Nov 21, 2024
2656c9c
Merge branch 'Fix/YoulBugFix' of https://github.com/CodeitFESI4-Team1…
yulrang Nov 21, 2024
43a4179
Merge branch 'develop' into Fix/YoulBugFix
yulrang Nov 21, 2024
43fd284
⬇️ Chore: package install
yulrang Nov 21, 2024
9260be9
πŸ› Fix: νŒŒμΌμΈν’‹ λ™μž‘ κ°œμ„ 
yulrang Nov 21, 2024
96f1e22
Co-authored-by: JEP <[email protected]>
yulrang Nov 21, 2024
0a5ab41
πŸ› Fix: FileInput λ™μž‘ κ°œμ„ 
yulrang Nov 21, 2024
5e014cf
🚨 Fix: λΉŒλ“œμ˜€λ₯˜ μˆ˜μ •
yulrang Nov 21, 2024
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
120 changes: 120 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified public/assets/images/crew-sample/crew-sample-2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion public/assets/images/crew-sample/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ImgCrewSample03 from './crew-sample-3.jpg';
const ImgCrewSamples = [ImgCrewSample01, ImgCrewSample02, ImgCrewSample03];
const ImgCrewSampleUrls = [
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/0e05d971-15a8-4a32-bf03-80d12cae392e',
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/eb35c35d-829a-402b-8019-29e42f91589f',
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/817dac5a-f5e7-43c4-b32e-50d1ad2983aa',
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/471b3b3b-b23c-48e8-8e6b-9a7ec31e1917',
];

Expand Down
Binary file modified public/assets/images/gathering-sample/gathering-sample-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/assets/images/gathering-sample/gathering-sample-2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/assets/images/gathering-sample/gathering-sample-3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions public/assets/images/gathering-sample/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import ImgGatheringSample03 from './gathering-sample-3.jpg';

const ImgGatheringSamples = [ImgGatheringSample01, ImgGatheringSample02, ImgGatheringSample03];
const ImgGatheringSampleUrls = [
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/1ff61110-e238-4fd6-8736-e6f03483f4df',
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/85ad6a48-a1cb-4c8f-b713-94b9e18b023a',
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/60bc093c-cb3a-4628-93b9-fbf19e47a1ac',
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/e276276c-c79e-4654-a2b2-279bccb7ca05',
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/69d4f72f-8bad-4e9e-894c-9e8c9b57db2d',
'https://crewcrew.s3.ap-northeast-2.amazonaws.com/crew/d3c507f4-0391-4acb-8bc3-ae5379bdb058',
];

export default ImgGatheringSampleUrls;
Binary file added public/assets/images/og.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 0 additions & 6 deletions src/_apis/image/get-image-url.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { fetchApi } from '@/src/utils/api';
import validateFile from '@/src/utils/validate-file';
import Toast from '@/src/components/common/toast';
import { GetImageUrlResponseTypes } from '@/src/types/create-crew';

export async function getImageUrl(
Expand All @@ -10,9 +8,6 @@ export async function getImageUrl(
const formData = new FormData();
if (file instanceof File) {
try {
if (!validateFile(file)) {
throw new Error('Invalid file');
}
formData.append('file', file);

const response: { data: GetImageUrlResponseTypes } = await fetchApi(
Expand All @@ -28,7 +23,6 @@ export async function getImageUrl(

return response.data;
} catch (error) {
// eslint-disable-next-line no-console
throw error;
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/_queries/crew/crew-detail-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export function useCreateCrewQuery() {
}
queryClient.invalidateQueries({ queryKey: ['crewLists', 'crewDetail'] });
toast.success('크루가 μƒμ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.');
localStorage.removeItem('createCrew');

Comment on lines +27 to +28
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codebase verification

createCrew localStorage 정리 μ½”λ“œκ°€ 두 κ³³μ—μ„œ λ°œκ²¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€

localStorage.removeItem('createCrew')κ°€ λ‹€μŒ 두 μœ„μΉ˜μ—μ„œ λ°œκ²¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€:

  • src/app/(crew)/crew/create/_components/create-crew-form/index.tsx
  • src/_queries/crew/crew-detail-queries.ts

λ™μΌν•œ cleanup μž‘μ—…μ΄ 두 κ³³μ—μ„œ μˆ˜ν–‰λ˜κ³  μžˆμ–΄ 쀑볡 μ½”λ“œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€. ν•œ 곳으둜 ν†΅ν•©ν•˜λŠ” 것이 μ’‹κ² μŠ΅λ‹ˆλ‹€.

πŸ”— Analysis chain

CreateCrewPageμ—μ„œ 쀑볡 cleanup μ½”λ“œ 확인이 ν•„μš”ν•©λ‹ˆλ‹€.

이전 μœ„μΉ˜μΈ CreateCrewPage μ»΄ν¬λ„ŒνŠΈμ—μ„œ λ™μΌν•œ cleanup μ½”λ“œκ°€ μ™„μ „νžˆ μ œκ±°λ˜μ—ˆλŠ”μ§€ 확인이 ν•„μš”ν•©λ‹ˆλ‹€.

λ‹€μŒ 슀크립트둜 ν™•μΈν•΄λ³΄μ„Έμš”:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# CreateCrewPageμ—μ„œ localStorage.removeItem('createCrew') μ‚¬μš© μ—¬λΆ€ 확인
rg "localStorage\.removeItem\('createCrew'\)" "src/app/(crew)/crew/create/page.tsx"

Length of output: 91


Script:

#!/bin/bash
# Check for any usage of 'createCrew' in localStorage operations within CreateCrewPage
rg "localStorage.*createCrew" "src/app/(crew)/crew/create/page.tsx"

# Also check the entire codebase for any remaining cleanup of 'createCrew' in localStorage
rg "localStorage.*createCrew"

# Use ast-grep to find any useEffect hooks that might contain cleanup
ast-grep --pattern 'useEffect(() => { $$$ }, $$$)'  "src/app/(crew)/crew/create/page.tsx"

Length of output: 543

router.push(`/crew/detail/${data.crewId}`);
},
onError: (error) => {
Expand Down
75 changes: 51 additions & 24 deletions src/app/(crew)/crew/create/_components/create-crew-form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use client';

import { useEffect, useState } from 'react';
import { FormEvent, useEffect, useState } from 'react';
import { Controller, useForm, useWatch } from 'react-hook-form';
import useFormPersist from 'react-hook-form-persist';
import { toast } from 'react-toastify';
import { useRouter } from 'next/navigation';
import { NumberInput } from '@mantine/core';
import { getImageUrl } from '@/src/_apis/image/get-image-url';
Expand Down Expand Up @@ -39,13 +40,14 @@ export default function CreateCrewForm({
trigger,
clearErrors,
watch,
setError,
formState: { errors, isValid, isSubmitting, isSubmitSuccessful },
} = useForm<CreateCrewFormTypes>({
defaultValues: data,
mode: 'onBlur',
});

useFormPersist(type === 'create' ? 'createCrew' : 'editCrew', {
useFormPersist(type === 'create' ? 'createCrew' : '', {
watch,
setValue,
storage: typeof window !== 'undefined' ? window.localStorage : undefined,
Expand Down Expand Up @@ -88,9 +90,30 @@ export default function CreateCrewForm({
file: File | string | null,
onChange: (value: string | File) => void,
) => {
if (file instanceof File) {
const imgResponse = await getImageUrl(file, 'CREW');
onChange(imgResponse?.imageUrl || '');
try {
// 파일 등둝 처리
if (file instanceof File) {
const imgResponse = await getImageUrl(file, 'CREW');
if (imgResponse?.imageUrl) {
clearErrors('imageUrl'); // μ—λŸ¬ μ΄ˆκΈ°ν™”
onChange(imgResponse.imageUrl); // 이미지 URL μ„€μ •
} else {
throw new Error('이미지 μ—…λ‘œλ“œ 쀑 λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.');
}
}
} catch (error) {
// API μ—λŸ¬ 처리
setError('imageUrl', { type: 'server', message: errors.imageUrl?.message });
setValue('imageUrl', '');
}
};

const handleSendForm = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (type === 'create') {
handleSubmit(onSubmit)();
} else {
handleSubmit(onEdit)();
}
};

Expand All @@ -112,7 +135,7 @@ export default function CreateCrewForm({
}, [mainCategory, mainLocation, isSubmitSuccessful]);

return (
<form onSubmit={type === 'edit' ? handleSubmit(onEdit) : handleSubmit(onSubmit)}>
<form onSubmit={handleSendForm}>
<div className="flex flex-col gap-6">
<div className="flex flex-col gap-3">
<div className="flex justify-between">
Expand Down Expand Up @@ -154,7 +177,7 @@ export default function CreateCrewForm({
</div>
<div className="flex flex-col gap-3">
<label
htmlFor="crew-category"
htmlFor="crew-mainCategory"
className="text-base font-semibold text-gray-800 md:text-xl"
>
μΉ΄ν…Œκ³ λ¦¬λ₯Ό μ„ νƒν•΄μ£Όμ„Έμš”.
Expand All @@ -167,6 +190,7 @@ export default function CreateCrewForm({
render={({ field }) => (
<DropDown
{...field}
id="crew-mainCategory"
variant="default"
inWhere="form"
placeholder={isEdit && field.value ? field.value : '메인 μΉ΄ν…Œκ³ λ¦¬'}
Expand All @@ -180,12 +204,16 @@ export default function CreateCrewForm({
/>
)}
/>
<label htmlFor="crew-subCategory" className="sr-only">
μ„ΈλΆ€ μΉ΄ν…Œκ³ λ¦¬λ₯Ό μ„ νƒν•΄μ£Όμ„Έμš”.
</label>
<Controller
name="subCategory"
control={control}
render={({ field }) => (
<DropDown
{...field}
id="crew-subCategory"
variant="default"
inWhere="form"
placeholder={isEdit && field.value ? field.value : 'μ„ΈλΆ€ μΉ΄ν…Œκ³ λ¦¬'}
Expand All @@ -199,31 +227,21 @@ export default function CreateCrewForm({
</div>

<div className="flex flex-col gap-3">
<label htmlFor="crew-image" className="text-base font-semibold text-gray-800 md:text-xl">
<span className="text-base font-semibold text-gray-800 md:text-xl">
λŒ€ν‘œμ΄λ―Έμ§€λ₯Ό μ„ νƒν•˜κ±°λ‚˜ μ²¨λΆ€ν•΄μ£Όμ„Έμš”.
</label>
</span>
Comment on lines +230 to +232
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

이미지 선택 UI의 μ‹œλ§¨ν‹± λ§ˆν¬μ—… κ°œμ„ μ΄ ν•„μš”ν•©λ‹ˆλ‹€.

label μ—˜λ¦¬λ¨ΌνŠΈλ₯Ό span으둜 λ³€κ²½ν•˜λ©΄ 접근성이 μ €ν•˜λ  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒκ³Ό 같이 μˆ˜μ •ν•˜λŠ” 것을 μ œμ•ˆλ“œλ¦½λ‹ˆλ‹€:

-          <span className="text-base font-semibold text-gray-800 md:text-xl">
+          <label htmlFor="crew-image" className="text-base font-semibold text-gray-800 md:text-xl">
            λŒ€ν‘œμ΄λ―Έμ§€λ₯Ό μ„ νƒν•˜κ±°λ‚˜ μ²¨λΆ€ν•΄μ£Όμ„Έμš”.
-          </span>
+          </label>

Committable suggestion skipped: line range outside the PR's diff.

<Controller
name="imageUrl"
control={control}
rules={{
required: '이미지λ₯Ό μ„ νƒν•΄μ£Όμ„Έμš”.',
validate: {
fileSize: (file) =>
file && file instanceof File
? file.size <= 5242880 || '파일 ν¬κΈ°λŠ” 5MB μ΄ν•˜μ—¬μ•Ό ν•©λ‹ˆλ‹€.'
: true, // λ¬Έμžμ—΄μΈ 경우 크기 검사λ₯Ό κ±΄λ„ˆλœλ‹ˆλ‹€.
fileType: (file) =>
file && file instanceof File
? ['image/jpeg', 'image/jpg', 'image/png'].includes(file.type) ||
'JPG, PNG 파일만 μ—…λ‘œλ“œ κ°€λŠ₯ν•©λ‹ˆλ‹€.'
: true, // λ¬Έμžμ—΄μΈ 경우 파일 νƒ€μž… 검사λ₯Ό κ±΄λ„ˆλœλ‹ˆλ‹€.
},
}}
render={({ field }) => (
<FileInputWrap
{...field}
isEdit={isEdit}
sample={ImgCrewSampleUrls}
error={errors.imageUrl}
onChange={(newValue) => {
handleFileChange(newValue, field.onChange);
field.onChange(newValue);
Expand All @@ -232,12 +250,12 @@ export default function CreateCrewForm({
/>
)}
/>
{errors.imageUrl && <p className="text-red-500">{errors.imageUrl.message}</p>}
{errors.imageUrl && <p className="text-xs text-red-500">{errors.imageUrl.message}</p>}
</div>

<div className="flex flex-col gap-3">
<label
htmlFor="crew-category"
htmlFor="crew-mainLocation"
className="text-base font-semibold text-gray-800 md:text-xl"
>
지역을 μ„ νƒν•΄μ£Όμ„Έμš”.
Expand All @@ -250,6 +268,7 @@ export default function CreateCrewForm({
render={({ field }) => (
<DropDown
{...field}
id="crew-mainLocation"
variant="default"
inWhere="form"
placeholder={isEdit && field.value ? field.value : 'νŠΉλ³„μ‹œ/도'}
Expand All @@ -263,13 +282,17 @@ export default function CreateCrewForm({
/>
)}
/>
<label htmlFor="crew-subLocation" className="sr-only">
μ„ΈλΆ€ 지역을 μ„ νƒν•΄μ£Όμ„Έμš”.
</label>
<Controller
name="subLocation"
control={control}
rules={{ required: 'μ‹œ/κ΅°/ꡬλ₯Ό μ„ νƒν•΄μ£Όμ„Έμš”.' }}
render={({ field }) => (
<DropDown
{...field}
id="crew-subLocation"
variant="default"
inWhere="form"
placeholder={isEdit && field.value ? field.value : 'μ‹œ/κ΅°/ꡬ'}
Expand Down Expand Up @@ -314,11 +337,14 @@ export default function CreateCrewForm({
</div>
<div className="flex flex-col gap-3">
<div className="flex justify-between">
<label htmlFor="gathering-introduce" className="text-base font-semibold text-gray-800">
<label
htmlFor="crew-introduce"
className="text-base font-semibold text-gray-800 md:text-xl"
>
크루 μ†Œκ°œ
</label>
<span>
<span className="text-blue-500">{introduce?.length}</span>/100
<span className="text-blue-500">{introduce.length}</span>/100
</span>
</div>
<Controller
Expand All @@ -327,6 +353,7 @@ export default function CreateCrewForm({
render={({ field }) => (
<Textarea
{...field}
id="crew-introduce"
placeholder="크루 μ†Œκ°œκΈ€μ„ 100자 μ΄λ‚΄λ‘œ μž…λ ₯ν•΄μ£Όμ„Έμš”."
maxLength={100}
inputClassNames="h-40 py-2.5 px-4 bg-gray-100 placeholder:text-gray-400 font-pretendard text-base font-medium rounded-xl"
Expand Down
Loading
Loading