) => {
+ setTextareaValue(e.target.value);
+ };
+
+ return (
+
+ );
+}
+
+export default SuggestionForm;
+
+const StyledForm = styled.form`
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+
+ font-size: ${FONT_SIZE.md};
+
+ p {
+ color: var(--gray-3);
+ }
+`;
+
+const StyledUnorderedList = styled.ul`
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+`;
+
+const StyledListItem = styled.li`
+ display: flex;
+ align-items: center;
+ gap: 0.8rem;
+`;
+
+const StyledTextarea = styled.textarea`
+ height: 128px;
+
+ padding: 0.8rem;
+
+ border: none;
+ border-radius: ${BORDER_RADIUS.sm};
+ background-color: var(--gray-1);
+`;
+
+const CheckBox = styled.input.attrs({ type: 'checkbox' })`
+ width: 24px;
+ height: 24px;
+
+ border: 1px solid #ddd;
+ border-radius: 50%;
+ background-image: url('~/assets/icons/unchecked-icon.svg');
+ background-size: cover;
+
+ transition: all 0.2s ease;
+ appearance: none;
+
+ &:checked {
+ border: 1px solid var(--primary-6);
+ background-color: var(--primary-6);
+ background-image: url('~/assets/icons/checked-icon.svg');
+ background-size: cover;
+ }
+`;
diff --git a/frontend/src/components/Form/SuggestionForm/index.tsx b/frontend/src/components/Form/SuggestionForm/index.tsx
new file mode 100644
index 000000000..afb5f5567
--- /dev/null
+++ b/frontend/src/components/Form/SuggestionForm/index.tsx
@@ -0,0 +1,3 @@
+import SuggestionForm from './SuggestionForm';
+
+export default SuggestionForm;
diff --git a/frontend/src/components/FormModal/FormModal.tsx b/frontend/src/components/FormModal/FormModal.tsx
new file mode 100644
index 000000000..ba65c308d
--- /dev/null
+++ b/frontend/src/components/FormModal/FormModal.tsx
@@ -0,0 +1,50 @@
+import Dialog from '../@common/Dialog';
+import RestaurantReviewList from '../RestaurantReviewList/RestaurantReviewList';
+import { ReviewDeleteForm, ReviewForm, ReviewReportForm } from '../ReviewForm';
+
+const REVIEW_FORM_TITLE = {
+ create: '리뷰 작성하기',
+ update: '리뷰 수정하기',
+ delete: '리뷰 삭제하기',
+ report: '리뷰 신고하기',
+ all: '리뷰 모두 보기',
+} as const;
+
+interface FormModalProps {
+ type: keyof typeof REVIEW_FORM_TITLE;
+ reviewId?: number;
+}
+
+function FormModal({ type, reviewId }: FormModalProps) {
+ return (
+
+ {type === 'create' && (
+
+ )}
+ {type === 'update' && (
+
+ )}
+ {type === 'delete' && (
+
+ )}
+ {type === 'report' && (
+
+ )}
+ {type === 'all' && (
+
+ )}
+
+ );
+}
+
+export default FormModal;
diff --git a/frontend/src/components/FormModal/index.tsx b/frontend/src/components/FormModal/index.tsx
new file mode 100644
index 000000000..9028427d0
--- /dev/null
+++ b/frontend/src/components/FormModal/index.tsx
@@ -0,0 +1,3 @@
+import FormModal from '~/components/FormModal/FormModal';
+
+export default FormModal;
diff --git a/frontend/src/components/InfoDropDown/InfoDropDown.tsx b/frontend/src/components/InfoDropDown/InfoDropDown.tsx
index ca35d1ead..e33bd933a 100644
--- a/frontend/src/components/InfoDropDown/InfoDropDown.tsx
+++ b/frontend/src/components/InfoDropDown/InfoDropDown.tsx
@@ -4,13 +4,12 @@ import { useNavigate } from 'react-router-dom';
import { styled } from 'styled-components';
import { getProfile } from '~/api/user';
import InfoButton from '~/components/@common/InfoButton';
-import LoginModal from '~/components/LoginModal';
-import useBooleanState from '~/hooks/useBooleanState';
import { ProfileData } from '~/@types/api.types';
+import useCeluveatModal from '~/hooks/useCeluveatModal';
function InfoDropDown() {
- const { value: isModalOpen, setTrue: openModal, setFalse: closeModal } = useBooleanState(false);
+ const { openLoginModal } = useCeluveatModal();
const { data, isSuccess: isLogin } = useQuery({
queryKey: ['profile'],
queryFn: getProfile,
@@ -31,38 +30,34 @@ function InfoDropDown() {
};
return (
- <>
-
-
-
-
-
-
-
-
- {isLogin ? (
- <>
-
- 마이 페이지
-
-
- 위시리스트
-
-
- 회원 탈퇴
-
- >
- ) : (
-
- 로그인
+
+
+
+
+
+
+
+
+ {isLogin ? (
+ <>
+
+ 마이 페이지
- )}
-
-
-
-
-
- >
+
+ 위시리스트
+
+
+ 회원 탈퇴
+
+ >
+ ) : (
+
+ 로그인
+
+ )}
+
+
+
);
}
diff --git a/frontend/src/components/LoginModal/LoginModal.stories.tsx b/frontend/src/components/LoginModal/LoginModal.stories.tsx
index 62c004311..44b52f9b0 100644
--- a/frontend/src/components/LoginModal/LoginModal.stories.tsx
+++ b/frontend/src/components/LoginModal/LoginModal.stories.tsx
@@ -20,9 +20,4 @@ export default meta;
type Story = StoryObj;
-export const Default: Story = {
- args: {
- isOpen: true,
- close: () => {},
- },
-};
+export const Default: Story = {};
diff --git a/frontend/src/components/LoginModal/LoginModal.tsx b/frontend/src/components/LoginModal/LoginModal.tsx
index 9c0b46847..6b7e93319 100644
--- a/frontend/src/components/LoginModal/LoginModal.tsx
+++ b/frontend/src/components/LoginModal/LoginModal.tsx
@@ -1,20 +1,15 @@
import { styled } from 'styled-components';
import LoginButton from '~/components/@common/LoginButton';
-import Modal from '../@common/Modal';
+import Dialog from '../@common/Dialog';
-interface LoginModalProps {
- isOpen: boolean;
- close: VoidFunction;
-}
-
-function LoginModal({ isOpen, close }: LoginModalProps) {
+function LoginModal() {
return (
-
+
+
);
}
diff --git a/frontend/src/components/MiniRestaurantCard/MiniRestaurantCard.tsx b/frontend/src/components/MiniRestaurantCard/MiniRestaurantCard.tsx
index ae5e251ea..ddb534016 100644
--- a/frontend/src/components/MiniRestaurantCard/MiniRestaurantCard.tsx
+++ b/frontend/src/components/MiniRestaurantCard/MiniRestaurantCard.tsx
@@ -7,7 +7,6 @@ import Star from '~/assets/icons/star.svg';
import type { Celeb } from '~/@types/celeb.types';
import type { Restaurant } from '~/@types/restaurant.types';
-import LoginModal from '~/components/LoginModal';
import useToggleLikeNotUpdate from '~/hooks/server/useToggleLikeNotUpdate';
import WaterMarkImage from '../@common/WaterMarkImage';
import ProfileImageList from '../@common/ProfileImageList';
@@ -36,7 +35,7 @@ function MiniRestaurantCard({
hideProfile = false,
}: MiniRestaurantCardProps) {
const { id, images, name, roadAddress, category, rating, distance } = restaurant;
- const { isModalOpen, closeModal, toggleRestaurantLike, isLiked } = useToggleLikeNotUpdate(restaurant);
+ const { toggleRestaurantLike, isLiked } = useToggleLikeNotUpdate(restaurant);
const navigate = useNavigate();
@@ -51,45 +50,41 @@ function MiniRestaurantCard({
};
return (
- <>
-
-
-
- {showLike && (
-
-
-
+
+
+
+ {showLike && (
+
+
+
+ )}
+
+
+
+ {name}
+ {showRating && (
+
+ {rating.toFixed(2)}
+
)}
-
-
-
- {name}
- {showRating && (
-
- {rating.toFixed(2)}
-
- )}
-
- {category}
- {roadAddress}
- {showDistance && {distance}m 이내}
- {!hideProfile && (
- {celebs && }
- )}
-
-
-
-
- >
+
+ {category}
+ {roadAddress}
+ {showDistance && {distance}m 이내}
+ {!hideProfile && (
+ {celebs && }
+ )}
+
+
);
}
diff --git a/frontend/src/components/RestaurantCard/RestaurantCard.tsx b/frontend/src/components/RestaurantCard/RestaurantCard.tsx
index 238d60424..c560a2648 100644
--- a/frontend/src/components/RestaurantCard/RestaurantCard.tsx
+++ b/frontend/src/components/RestaurantCard/RestaurantCard.tsx
@@ -8,7 +8,6 @@ import { FONT_SIZE, truncateText } from '~/styles/common';
import type { Celeb } from '~/@types/celeb.types';
import type { Restaurant } from '~/@types/restaurant.types';
-import LoginModal from '~/components/LoginModal';
import useToggleLikeNotUpdate from '~/hooks/server/useToggleLikeNotUpdate';
interface RestaurantCardProps {
@@ -21,7 +20,7 @@ interface RestaurantCardProps {
function RestaurantCard({ restaurant, celebs, size, type = 'list', setHoveredId = () => {} }: RestaurantCardProps) {
const { id, images, name, roadAddress, category, phoneNumber, likeCount } = restaurant;
- const { isModalOpen, closeModal, toggleRestaurantLike, isLiked } = useToggleLikeNotUpdate(restaurant);
+ const { toggleRestaurantLike, isLiked } = useToggleLikeNotUpdate(restaurant);
const navigate = useNavigate();
@@ -36,37 +35,33 @@ function RestaurantCard({ restaurant, celebs, size, type = 'list', setHoveredId
};
return (
- <>
-
-
-
-
-
-
-
-
-
- {category}
- {name}
- {roadAddress}
- {phoneNumber}
-
-
- 좋아요 {likeCount.toLocaleString()}개
- {celebs && }
-
-
-
-
-
- >
+
+
+
+
+
+
+
+
+
+ {category}
+ {name}
+ {roadAddress}
+ {phoneNumber}
+
+
+ 좋아요 {likeCount.toLocaleString()}개
+ {celebs && }
+
+
+
);
}
diff --git a/frontend/src/components/RestaurantDetailLikeButton/RestaurantDetailLikeButton.tsx b/frontend/src/components/RestaurantDetailLikeButton/RestaurantDetailLikeButton.tsx
index 4ecbc444b..086f108ea 100644
--- a/frontend/src/components/RestaurantDetailLikeButton/RestaurantDetailLikeButton.tsx
+++ b/frontend/src/components/RestaurantDetailLikeButton/RestaurantDetailLikeButton.tsx
@@ -1,6 +1,5 @@
import { useQuery } from '@tanstack/react-query';
import useToggleLikeNotUpdate from '~/hooks/server/useToggleLikeNotUpdate';
-import LoginModal from '~/components/LoginModal';
import WhiteLove from '~/assets/icons/love.svg';
import { RestaurantData } from '~/@types/api.types';
import { getRestaurantDetail } from '~/api/restaurant';
@@ -20,26 +19,13 @@ function RestaurantDetailLikeButton({ showText = true, restaurantId, celebId }:
suspense: true,
});
- const { isModalOpen, isLiked, closeModal, toggleRestaurantLike } = useToggleLikeNotUpdate(restaurant);
+ const { isLiked, toggleRestaurantLike } = useToggleLikeNotUpdate(restaurant);
return (
- <>
-
-
-
- >
+
);
}
diff --git a/frontend/src/components/RestaurantReviewItem/RestaurantReviewItem.tsx b/frontend/src/components/RestaurantReviewItem/RestaurantReviewItem.tsx
index f085db2e5..fdaf47cce 100644
--- a/frontend/src/components/RestaurantReviewItem/RestaurantReviewItem.tsx
+++ b/frontend/src/components/RestaurantReviewItem/RestaurantReviewItem.tsx
@@ -8,7 +8,6 @@ import SpeakerphoneIcon from '~/assets/icons/etc/speakerphone.svg';
import StarRating from '~/components/@common/StarRating';
import ProfileImage from '~/components/@common/ProfileImage';
-import { useReviewModalContext } from '~/hooks/context/ReviewModalProvider';
import useRestaurantReview from '~/hooks/server/useRestaurantReview';
import { FONT_SIZE } from '~/styles/common';
@@ -16,13 +15,13 @@ import { getProfile } from '~/api/user';
import { getReviewImgUrl, lookImage } from '~/utils/image';
import type { ProfileData, RestaurantReview } from '~/@types/api.types';
+import useCeluveatModal from '~/hooks/useCeluveatModal';
interface RestaurantReviewItemProps {
review: RestaurantReview;
- isInModal: boolean;
}
-function RestaurantReviewItem({ review, isInModal }: RestaurantReviewItemProps) {
+function RestaurantReviewItem({ review }: RestaurantReviewItemProps) {
const { data: profileData } = useQuery({
queryKey: ['profile'],
queryFn: getProfile,
@@ -30,7 +29,7 @@ function RestaurantReviewItem({ review, isInModal }: RestaurantReviewItemProps)
const { getReviewIsLiked, toggleRestaurantReviewLike } = useRestaurantReview();
- const { openReviewModal, setReviewId } = useReviewModalContext();
+ const { openReviewFormModal } = useCeluveatModal();
const isUsersReview = profileData?.memberId === review.memberId;
@@ -50,8 +49,7 @@ function RestaurantReviewItem({ review, isInModal }: RestaurantReviewItemProps)