diff --git a/client/src/components/CafeActionBar.tsx b/client/src/components/CafeActionBar.tsx
deleted file mode 100644
index bd6224d4..00000000
--- a/client/src/components/CafeActionBar.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-import { Suspense, useState } from 'react';
-import { BiSolidInfoCircle } from 'react-icons/bi';
-import { FaShare } from 'react-icons/fa';
-import { PiHeartFill, PiReadCvLogoFill } from 'react-icons/pi';
-import { styled, useTheme } from 'styled-components';
-import { useToast } from '../context/ToastContext';
-import useCafeLikes from '../hooks/useCafeLikes';
-import useClipboard from '../hooks/useClipboard';
-import useUser from '../hooks/useUser';
-import type { Cafe } from '../types';
-import CafeMenuBottomSheet from './CafeMenuBottomSheet';
-import IconButton from './IconButton';
-
-type CafeActionBarProps = {
- cafe: Cafe;
-};
-
-const CafeActionBar = (props: CafeActionBarProps) => {
- const { cafe } = props;
- const theme = useTheme();
- const showToast = useToast();
- const clipboard = useClipboard();
-
- const { isLiked, setLiked } = useCafeLikes(cafe);
- const { data: user } = useUser();
- const [isMenuOpened, setIsMenuOpened] = useState(false);
-
- const likeCount = cafe.likeCount + (isLiked ? 1 : 0);
-
- const handleShare = async () => {
- try {
- await clipboard.copyToClipboard(`https://yozm.cafe/cafes/${cafe.id}`);
- showToast('success', 'URL이 복사되었습니다!');
- } catch (error) {
- showToast('error', `URL 복사 실패: ${error}`);
- }
- };
-
- const handleLikeCountIncrease = () => {
- if (!user) {
- showToast('error', '로그인이 필요합니다!');
- return;
- }
- setLiked({ isLiked: !isLiked });
- };
-
- const handleMenuOpen = () => {
- setIsMenuOpened(true);
- };
-
- const handleMenuClose = () => {
- setIsMenuOpened(false);
- };
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {isMenuOpened && (
-
-
-
- )}
-
- );
-};
-
-export default CafeActionBar;
-
-const Container = styled.aside`
- display: flex;
- flex-direction: column;
- gap: ${({ theme }) => theme.space[5]};
- align-self: flex-end;
-
- padding: ${({ theme }) => theme.space[3]};
-
- color: white;
-`;
diff --git a/client/src/components/CafeCard.tsx b/client/src/components/CafeCard.tsx
index 5e5bac3d..4993c613 100644
--- a/client/src/components/CafeCard.tsx
+++ b/client/src/components/CafeCard.tsx
@@ -1,11 +1,19 @@
-import type { UIEventHandler } from 'react';
-import { useCallback, useState } from 'react';
-import { styled } from 'styled-components';
+import type { MouseEventHandler, UIEventHandler } from 'react';
+import { Suspense, useCallback, useState } from 'react';
+import { BiSolidInfoCircle } from 'react-icons/bi';
+import { FaShare } from 'react-icons/fa';
+import { PiHeartFill, PiReadCvLogoFill } from 'react-icons/pi';
+import { styled, useTheme } from 'styled-components';
+import { useToast } from '../context/ToastContext';
+import useCafeLikes from '../hooks/useCafeLikes';
+import useClipboard from '../hooks/useClipboard';
+import useUser from '../hooks/useUser';
import type { Cafe } from '../types';
import Resource from '../utils/Resource';
-import CafeActionBar from './CafeActionBar';
import CafeDetailBottomSheet from './CafeDetailBottomSheet';
+import CafeMenuBottomSheet from './CafeMenuBottomSheet';
import CafeSummary from './CafeSummary';
+import IconButton from './IconButton';
type CardProps = {
cafe: Cafe;
@@ -14,9 +22,18 @@ type CardProps = {
const CafeCard = (props: CardProps) => {
const { cafe } = props;
+ const theme = useTheme();
+ const showToast = useToast();
+ const clipboard = useClipboard();
+ const { isLiked, setLiked } = useCafeLikes(cafe);
+ const { data: user } = useUser();
+
const [isShowDetail, setIsShowDetail] = useState(false);
+ const [isMenuOpened, setIsMenuOpened] = useState(false);
const [currentImageIndex, setCurrentImageIndex] = useState(0);
+ const likeCount = cafe.likeCount + (isLiked ? 1 : 0);
+
const handleScroll: UIEventHandler = useCallback((event) => {
if (!(event.target instanceof HTMLDivElement)) return;
@@ -25,6 +42,43 @@ const CafeCard = (props: CardProps) => {
setCurrentImageIndex(index);
}, []);
+ const handleShare = async () => {
+ try {
+ await clipboard.copyToClipboard(`https://yozm.cafe/cafes/${cafe.id}`);
+ showToast('success', 'URL이 복사되었습니다!');
+ } catch (error) {
+ showToast('error', `URL 복사 실패: ${error}`);
+ }
+ };
+
+ const handleLikeCountIncrease = () => {
+ if (!user) {
+ showToast('error', '로그인이 필요합니다!');
+ return;
+ }
+ setLiked({ isLiked: !isLiked });
+ };
+
+ const handleDetailOpen = () => {
+ setIsShowDetail(true);
+ };
+
+ const handleDetailClose = () => {
+ setIsShowDetail(false);
+ };
+
+ const handleMenuOpen = () => {
+ setIsMenuOpened(true);
+ };
+
+ const handleMenuClose = () => {
+ setIsMenuOpened(false);
+ };
+
+ const handleStopPropagation: MouseEventHandler = (event) => {
+ event.stopPropagation();
+ };
+
return (
@@ -44,19 +98,29 @@ const CafeCard = (props: CardProps) => {
))}
-
+
- {
- event.stopPropagation();
- setIsShowDetail(true);
- }}
- />
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -66,7 +130,13 @@ const CafeCard = (props: CardProps) => {
))}
- {isShowDetail && setIsShowDetail(false)} />}
+ {isShowDetail && }
+
+ {isMenuOpened && (
+
+
+
+ )}
);
};
@@ -163,3 +233,14 @@ const BottomItem = styled.div<{ $fullWidth?: boolean; $align?: 'left' | 'right'
${({ $align }) => $align === 'right' && 'right: 0;'}
${({ $fullWidth }) => $fullWidth && 'width: 100%;'}
`;
+
+const ActionBar = styled.aside`
+ display: flex;
+ flex-direction: column;
+ gap: ${({ theme }) => theme.space[5]};
+ align-self: flex-end;
+
+ padding: ${({ theme }) => theme.space[3]};
+
+ color: white;
+`;