Skip to content
14 changes: 13 additions & 1 deletion src/components/Modal/ReviewModal/AddReviewModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const aromaMap: Record<string, string> = {
์˜คํฌ: 'OAK',
๋ฐ”๋‹๋ผ: 'VANILLA',
ํ›„์ถ”: 'PEPPER',
์ œ๋นต: 'BAKERY',
์ œ๋นต: 'BAKING',
ํ’€: 'GRASS',
์‚ฌ๊ณผ: 'APPLE',
๋ณต์ˆญ์•„: 'PEACH',
Expand Down Expand Up @@ -174,6 +174,12 @@ const AddReviewModal = ({ wineId, wineName }: { wineId: number; wineName: string
};
////

const content = watch('content');
const aromaList = watch('aroma');
const rating = watch('rating');

const isFormValid = rating > 0 && content.trim().length > 0 && aromaList.length > 0;

const renderButton = (
<Button
onClick={handleSubmit(onSubmit)}
Expand All @@ -182,6 +188,8 @@ const AddReviewModal = ({ wineId, wineName }: { wineId: number; wineName: string
size='xl'
width='full'
fontSize='lg'
disabled={!isFormValid}
className={!isFormValid ? 'cursor-not-allowed' : ''}
>
๋ฆฌ๋ทฐ ๋‚จ๊ธฐ๊ธฐ
</Button>
Expand Down Expand Up @@ -212,6 +220,10 @@ const AddReviewModal = ({ wineId, wineName }: { wineId: number; wineName: string
id='content'
{...register('content', {
required: '๋ฆฌ๋ทฐ ๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.',
maxLength: {
value: 500,
message: '์ตœ๋Œ€ 500์ž๊นŒ์ง€ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.',
},
onChange: () => clearErrors('content'),
})}
placeholder='ํ›„๊ธฐ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”'
Expand Down
14 changes: 13 additions & 1 deletion src/components/Modal/ReviewModal/EditReviewModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const aromaMap: Record<string, string> = {
์˜คํฌ: 'OAK',
๋ฐ”๋‹๋ผ: 'VANILLA',
ํ›„์ถ”: 'PEPPER',
์ œ๋นต: 'BAKERY',
์ œ๋นต: 'BAKING',
ํ’€: 'GRASS',
์‚ฌ๊ณผ: 'APPLE',
๋ณต์ˆญ์•„: 'PEACH',
Expand Down Expand Up @@ -176,6 +176,12 @@ const EditReviewModal = ({
}
};

const content = watch('content');
const aromaList = watch('aroma');
const rating = watch('rating');

const isFormValid = rating > 0 && content.trim().length > 0 && aromaList.length > 0;

const renderButton = (
<Button
onClick={handleSubmit(onSubmit)}
Expand All @@ -184,6 +190,8 @@ const EditReviewModal = ({
size='xl'
width='full'
fontSize='lg'
disabled={!isFormValid}
className={!isFormValid ? 'cursor-not-allowed' : ''}
>
์ˆ˜์ • ์™„๋ฃŒ
</Button>
Expand Down Expand Up @@ -215,6 +223,10 @@ const EditReviewModal = ({
id='content'
{...register('content', {
required: '๋ฆฌ๋ทฐ ๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.',
maxLength: {
value: 500,
message: '์ตœ๋Œ€ 500์ž๊นŒ์ง€ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.',
},
onChange: () => clearErrors('content'),
})}
placeholder='ํ›„๊ธฐ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”'
Expand Down
74 changes: 50 additions & 24 deletions src/components/Modal/WineModal/AddWineModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import CameraIcon from '@/assets/camera.svg';
import DropdownIcon from '@/assets/dropdowntriangle.svg';
import BasicBottomSheet from '@/components/common/BottomSheet/BasicBottomSheet';
import { useMediaQuery } from '@/hooks/useMediaQuery';
import { getTrimmedHandlers } from '@/lib/inputCheck';
import { getCommaNumberHandlers } from '@/lib/inputNumberCheck';
import { renameFileIfNeeded } from '@/lib/renameFile';

import SelectDropdown from '../../common/dropdown/SelectDropdown';
Expand All @@ -18,7 +20,7 @@ import { Button } from '../../ui/button';

interface WineForm {
wineName: string;
winePrice: number;
winePrice: string;
wineOrigin: string;
wineImage: FileList;
wineType: string;
Expand Down Expand Up @@ -59,14 +61,15 @@ const AddWineModal = ({ showRegisterModal, setShowRegisterModal }: AddWineModalP
trigger,
setValue,
reset,
watch,
} = useForm<WineForm>({
mode: 'onBlur',
});

const resetForm = () => {
reset({
wineName: '',
winePrice: NaN,
winePrice: '',
wineOrigin: '',
wineImage: {} as FileList,
wineType: '',
Expand All @@ -76,17 +79,8 @@ const AddWineModal = ({ showRegisterModal, setShowRegisterModal }: AddWineModalP
if (fileInputRef.current) fileInputRef.current.value = '';
};

const handlePostWine = async (form: WineForm) => {
const file = form.wineImage[0];
const imageUrl = await uploadImage(file);
const requestData: PostWineRequest = {
name: form.wineName,
region: form.wineOrigin,
image: imageUrl,
price: Number(form.winePrice),
type: form.wineType.toUpperCase() as 'RED' | 'WHITE' | 'SPARKLING',
};
return postWine(requestData);
const handlePostWine = async (data: PostWineRequest) => {
return postWine(data);
};

const postWineMutation = useMutation({
Expand All @@ -104,13 +98,22 @@ const AddWineModal = ({ showRegisterModal, setShowRegisterModal }: AddWineModalP
},
});

//WineForm์˜ price๋ฅผ string์œผ๋กœ ํ•ด์„œ ์‰ผํ‘œ ๊ฐ€๋Šฅ ํ›„ >>์„œ๋ฒ„์— ์ €์žฅํ• ๋•Œ๋Š” ์‰ผํ‘œ ์ œ๊ฑฐ ํ›„ ์ˆซ์ž๋กœ ๋ณ€ํ™˜์„ ์œ„ํ•ด์„œ
const onSubmit = async (form: WineForm) => {
let file = form.wineImage[0];
file = renameFileIfNeeded(file); //์ด๋ฏธ์ง€ํŒŒ์ผ ์ด๋ฆ„ ์ •๊ทœํ™”
postWineMutation.mutate({
...form,
wineImage: [file] as unknown as FileList,
});
const file = renameFileIfNeeded(form.wineImage[0]); //์ด๋ฏธ์ง€ํŒŒ์ผ ์ด๋ฆ„ ์ •๊ทœํ™”

const imageUrl = await uploadImage(file); //์ด๋ฏธ์ง€ ์—…๋กœ๋“œํ•ด์„œ URL์–ป๊ณ 

const numberPrice = Number(form.winePrice.replace(/,/g, '')); //๊ฐ€๊ฒฉ ์‰ผํ‘œ ์ œ๊ฑฐ ํ›„ ์ˆซ์ž๋กœ ๋ณ€ํ™˜

const requestData: PostWineRequest = {
name: form.wineName,
region: form.wineOrigin,
image: imageUrl,
price: numberPrice,
type: form.wineType.toUpperCase() as 'RED' | 'WHITE' | 'SPARKLING',
};
postWineMutation.mutate(requestData);
};

const categoryOptions = [
Expand Down Expand Up @@ -141,7 +144,7 @@ const AddWineModal = ({ showRegisterModal, setShowRegisterModal }: AddWineModalP
<Input
{...register('wineName', {
required: '์™€์ธ ์ด๋ฆ„์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.',
onChange: () => clearErrors('wineName'),
...getTrimmedHandlers<WineForm>('wineName', setValue, clearErrors), //์ •๊ทœ์‹ ๊ฒ€์‚ฌ ํ•จ์ˆ˜
})}
errorMessage={errors.wineName?.message}
id='wineName'
Expand All @@ -155,11 +158,16 @@ const AddWineModal = ({ showRegisterModal, setShowRegisterModal }: AddWineModalP
<Input
{...register('winePrice', {
required: '๊ฐ€๊ฒฉ์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.',
onChange: () => clearErrors('winePrice'),
pattern: {
value: /^[1-9][0-9]{0,9}(,[0-9]{3})*$/, // ์ด 10์ž๋ฆฌ, 1~9๋กœ ์‹œ์ž‘
message: '์ˆซ์ž๋งŒ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•˜๋ฉฐ, 0์œผ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.',
},
...getCommaNumberHandlers<WineForm>('winePrice', setValue, clearErrors), //์ •๊ทœ์‹ ๊ฒ€์‚ฌ ํ•จ์ˆ˜
})}
errorMessage={errors.winePrice?.message}
id='winePrice'
type='number'
type='text'
inputMode='numeric' //๋ชจ๋ฐ”์ผ์‹œ ์ˆซ์žํŒจ๋“œ
variant='name'
placeholder='๊ฐ€๊ฒฉ ์ž…๋ ฅ'
className='[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none custom-text-md-regular md:custom-text-lg-regular'
Expand All @@ -169,7 +177,7 @@ const AddWineModal = ({ showRegisterModal, setShowRegisterModal }: AddWineModalP
<Input
{...register('wineOrigin', {
required: '์›์‚ฐ์ง€๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.',
onChange: () => clearErrors('wineOrigin'),
...getTrimmedHandlers<WineForm>('wineOrigin', setValue, clearErrors), //์ •๊ทœ์‹ ๊ฒ€์‚ฌ ํ•จ์ˆ˜
})}
errorMessage={errors.wineOrigin?.message}
id='wineOrigin'
Expand Down Expand Up @@ -256,6 +264,19 @@ const AddWineModal = ({ showRegisterModal, setShowRegisterModal }: AddWineModalP
</form>
);

const watchedName = watch('wineName');
const watchedPrice = watch('winePrice');
const watchedOrigin = watch('wineOrigin');
const watchedType = watch('wineType');
const watchedImage = watch('wineImage');

const isFormValid =
watchedName?.trim() &&
watchedPrice &&
watchedOrigin?.trim() &&
watchedType?.trim() &&
watchedImage?.length > 0;

const renderButton = (
<div className='flex gap-2 w-full'>
<Button
Expand All @@ -278,7 +299,12 @@ const AddWineModal = ({ showRegisterModal, setShowRegisterModal }: AddWineModalP
size='xl'
fontSize='lg'
width='full'
className='w-full md:w-[294px] lg:w-[294px]'
className={
!isFormValid
? 'cursor-not-allowed w-full md:w-[294px] lg:w-[294px]'
: 'w-full md:w-[294px] lg:w-[294px]'
}
disabled={!isFormValid}
>
์™€์ธ ๋“ฑ๋กํ•˜๊ธฐ
</Button>
Expand Down
45 changes: 35 additions & 10 deletions src/components/Modal/WineModal/EditWineModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import Input from '@/components/common/Input';
import BasicModal from '@/components/common/Modal/BasicModal';
import { Button } from '@/components/ui/button';
import { useMediaQuery } from '@/hooks/useMediaQuery';
import { getTrimmedHandlers } from '@/lib/inputCheck';
import { getCommaNumberHandlers } from '@/lib/inputNumberCheck';
import { renameFileIfNeeded } from '@/lib/renameFile';

interface WineForm {
wineName: string;
winePrice: number;
winePrice: string;
wineOrigin: string;
wineImage: FileList;
wineType: string;
Expand Down Expand Up @@ -55,7 +57,7 @@ const EditWineModal = ({ wine, showEditModal, setShowEditModal }: EditWineModalP
mode: 'onBlur',
defaultValues: {
wineName: wine.name,
winePrice: wine.price,
winePrice: wine.price.toLocaleString(), //์‰ผํ‘œ ํฌํ•จํ•ด์„œ ๋ฌธ์ž์—ด๋กœ ์›๋ž˜๋Š” wine.price(number)์˜€์Œ
wineOrigin: wine.region,
wineType: wine.type,
},
Expand Down Expand Up @@ -92,7 +94,7 @@ const EditWineModal = ({ wine, showEditModal, setShowEditModal }: EditWineModalP
queryClient.invalidateQueries({ queryKey: ['wines'] });
reset({
wineName: wine.name,
winePrice: wine.price,
winePrice: wine.price.toLocaleString(),
wineOrigin: wine.region,
wineType: wine.type,
});
Expand All @@ -116,10 +118,13 @@ const EditWineModal = ({ wine, showEditModal, setShowEditModal }: EditWineModalP
imageUrl = uploaded + `?t=${Date.now()}`; // ์บ์‹œ ๋ฐฉ์ง€
setPreviewImage(imageUrl); // ์ด๋ฏธ์ง€ ๊ฐฑ์‹ 
}

const numberPrice = Number(form.winePrice.replace(/,/g, '')); //์‰ผํ‘œ ์ œ๊ฑฐ ํ›„ ์ˆซ์ž๋กœ

updateWineMutation.mutate({
wineId: wine.wineId,
name: form.wineName,
price: Number(form.winePrice),
price: numberPrice,
region: form.wineOrigin,
type: form.wineType.toUpperCase() as 'RED' | 'WHITE' | 'SPARKLING',
image: imageUrl,
Expand All @@ -135,14 +140,27 @@ const EditWineModal = ({ wine, showEditModal, setShowEditModal }: EditWineModalP
if (!isOpen) {
reset({
wineName: wine.name,
winePrice: wine.price,
winePrice: wine.price.toLocaleString(),
wineOrigin: wine.region,
wineType: wine.type,
});
setPreviewImage(wine.image);
}
};

const watchedName = watch('wineName');
const watchedPrice = watch('winePrice');
const watchedOrigin = watch('wineOrigin');
const watchedType = watch('wineType');
const watchedImage = watch('wineImage');

const isFormValid =
watchedName?.trim() &&
watchedPrice &&
watchedOrigin?.trim() &&
watchedType?.trim() &&
watchedImage?.length > 0;

const renderButton = (
<Button
onClick={handleSubmit(onSubmit)}
Expand All @@ -151,6 +169,8 @@ const EditWineModal = ({ wine, showEditModal, setShowEditModal }: EditWineModalP
size='xl'
width='full'
fontSize='lg'
disabled={!isFormValid}
className={!isFormValid ? 'cursor-not-allowed' : ''}
>
์ˆ˜์ • ์™„๋ฃŒ
</Button>
Expand All @@ -169,7 +189,7 @@ const EditWineModal = ({ wine, showEditModal, setShowEditModal }: EditWineModalP
placeholder='์™€์ธ ์ด๋ฆ„ ์ž…๋ ฅ'
{...register('wineName', {
required: '์™€์ธ ์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
onChange: () => clearErrors('wineName'),
...getTrimmedHandlers<WineForm>('wineName', setValue, clearErrors), //์ •๊ทœ์‹ ๊ฒ€์‚ฌ ํ•จ์ˆ˜
})}
errorMessage={errors.wineName?.message}
/>
Expand All @@ -181,12 +201,17 @@ const EditWineModal = ({ wine, showEditModal, setShowEditModal }: EditWineModalP
<Input
className='w-full [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none custom-text-md-regular md:custom-text-lg-regular'
id='winePrice'
type='number'
type='text'
placeholder='๊ฐ€๊ฒฉ ์ž…๋ ฅ'
{...register('winePrice', {
required: '๊ฐ€๊ฒฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
onChange: () => clearErrors('winePrice'),
required: '๊ฐ€๊ฒฉ์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.',
pattern: {
value: /^[1-9][0-9]{0,9}(,[0-9]{3})*$/, // ์ด 10์ž๋ฆฌ, 1~9๋กœ ์‹œ์ž‘
message: '์ˆซ์ž๋งŒ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•˜๋ฉฐ, 0์œผ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.',
},
...getCommaNumberHandlers<WineForm>('winePrice', setValue, clearErrors), //์ •๊ทœ์‹ ๊ฒ€์‚ฌ ํ•จ์ˆ˜
})}
inputMode='numeric'
errorMessage={errors.winePrice?.message}
/>

Expand All @@ -201,7 +226,7 @@ const EditWineModal = ({ wine, showEditModal, setShowEditModal }: EditWineModalP
placeholder='์›์‚ฐ์ง€ ์ž…๋ ฅ'
{...register('wineOrigin', {
required: '์›์‚ฐ์ง€๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
onChange: () => clearErrors('wineOrigin'),
...getTrimmedHandlers<WineForm>('wineOrigin', setValue, clearErrors), //์ •๊ทœ์‹ ๊ฒ€์‚ฌ ํ•จ์ˆ˜
})}
errorMessage={errors.wineOrigin?.message}
/>
Expand Down
Loading