diff --git a/package-lock.json b/package-lock.json index af73917b..ac0eef6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "tailwind-merge": "^3.3.1", "tailwindcss-animate": "^1.0.7", "use-sync-external-store": "^1.5.0", + "vaul": "^1.1.2", "zod": "^4.0.5", "zustand": "^5.0.5" }, @@ -10877,6 +10878,19 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, + "node_modules/vaul": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", + "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-dialog": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, "node_modules/watchpack": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", diff --git a/package.json b/package.json index 7cdb29a8..08557573 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "tailwind-merge": "^3.3.1", "tailwindcss-animate": "^1.0.7", "use-sync-external-store": "^1.5.0", + "vaul": "^1.1.2", "zod": "^4.0.5", "zustand": "^5.0.5" }, diff --git a/src/components/Modal/DeleteModal/DeleteModal.tsx b/src/components/Modal/DeleteModal/DeleteModal.tsx index ddb2a121..b7033f9b 100644 --- a/src/components/Modal/DeleteModal/DeleteModal.tsx +++ b/src/components/Modal/DeleteModal/DeleteModal.tsx @@ -2,8 +2,10 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { AxiosError } from 'axios'; import { deleteReview, deleteWine, DeleteResponse } from '@/api/delete'; +import BasicBottomSheet from '@/components/common/BottomSheet/BasicBottomSheet'; import BasicModal from '@/components/common/Modal/BasicModal'; import { Button } from '@/components/ui/button'; +import { useMediaQuery } from '@/hooks/useMediaQuery'; interface DeleteModalProps { type: 'wine' | 'review'; @@ -14,6 +16,7 @@ interface DeleteModalProps { const DeleteModal = ({ type, id, showDeleteModal, setShowDeleteModal }: DeleteModalProps) => { const queryClient = useQueryClient(); + const isDesktop = useMediaQuery('(min-width: 640px)'); const deleteWineMutation = useMutation({ mutationFn: (id) => deleteWine(id), @@ -51,44 +54,52 @@ const DeleteModal = ({ type, id, showDeleteModal, setShowDeleteModal }: DeleteMo } }; - return ( -
- setShowDeleteModal(isOpen)} - showCloseButton={false} - buttons={ -
- - -
- } + const buttons = ( +
+ +
); + + return isDesktop ? ( + setShowDeleteModal(isOpen)} + showCloseButton={false} + > + + 정말로 삭제하시겠습니까? + + {buttons} + + ) : ( + + {buttons} + + ); }; export default DeleteModal; diff --git a/src/components/Modal/FilterModal/FilterModal.tsx b/src/components/Modal/FilterModal/FilterModal.tsx index d3f653eb..08cd1ea2 100644 --- a/src/components/Modal/FilterModal/FilterModal.tsx +++ b/src/components/Modal/FilterModal/FilterModal.tsx @@ -1,8 +1,10 @@ import React from 'react'; +import BasicBottomSheet from '@/components/common/BottomSheet/BasicBottomSheet'; import WineTypeFilter from '@/components/common/Filter/WineTypeFilter'; import BasicModal from '@/components/common/Modal/BasicModal'; import { Button } from '@/components/ui/button'; +import { useMediaQuery } from '@/hooks/useMediaQuery'; import useFilterStore from '@/stores/filterStore'; const FilterModal = ({ @@ -13,47 +15,68 @@ const FilterModal = ({ onOpenChange: (isOpen: boolean) => void; }) => { const reset = useFilterStore((state) => state.reset); + const isDesktop = useMediaQuery('(min-width: 640px)'); const handleApplyFilter = (e: React.FormEvent) => { e.preventDefault(); onOpenChange(false); // 필터 적용 후 모달을 close }; + const renderButton = ( +
+ + +
+ ); + + const renderForm = ( +
+ + + ); + return (
- - - -
- } - > -
- - -
+ {isDesktop ? ( + + {renderForm} + + ) : ( +
+ + {renderForm} + +
+ )}
); }; diff --git a/src/components/Modal/ReviewModal/AddReviewModal.tsx b/src/components/Modal/ReviewModal/AddReviewModal.tsx index 25c0a29a..b76fe836 100644 --- a/src/components/Modal/ReviewModal/AddReviewModal.tsx +++ b/src/components/Modal/ReviewModal/AddReviewModal.tsx @@ -6,7 +6,9 @@ import Image from 'next/image'; import { useForm } from 'react-hook-form'; import { postReview } from '@/api/addreview'; +import BasicBottomSheet from '@/components/common/BottomSheet/BasicBottomSheet'; import StarRating from '@/components/Modal/ReviewModal/StarRating'; +import { useMediaQuery } from '@/hooks/useMediaQuery'; import { cn } from '@/lib/utils'; import BasicModal from '../../common/Modal/BasicModal'; @@ -85,6 +87,7 @@ const aromaMap: Record = { const AddReviewModal = ({ wineId, wineName }: { wineId: number; wineName: string }) => { const [showRegisterModal, setShowRegisterModal] = useState(false); const queryClient = useQueryClient(); + const isDesktop = useMediaQuery('(min-width: 640px)'); const { register, @@ -168,149 +171,162 @@ const AddReviewModal = ({ wineId, wineName }: { wineId: number; wineName: string }; //// + const renderButton = ( + + ); + + const renderForm = () => ( +
+
+ 리뷰 아이콘 +
+ {wineName} + + setValue('rating', rating)} /> + +
+
+