diff --git a/client/src/components/CafeActionBar.tsx b/client/src/components/CafeActionBar.tsx index 9055aad8..bd6224d4 100644 --- a/client/src/components/CafeActionBar.tsx +++ b/client/src/components/CafeActionBar.tsx @@ -1,12 +1,15 @@ -import { Suspense, useState, type PropsWithChildren } from 'react'; -import { PiReadCvLogoFill } from 'react-icons/pi'; -import { styled } from 'styled-components'; +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 LikeButton from './LikeButton'; -import ShareButton from './ShareButton'; +import IconButton from './IconButton'; type CafeActionBarProps = { cafe: Cafe; @@ -14,42 +17,62 @@ type CafeActionBarProps = { 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) { - alert('로그인이 필요합니다!'); + showToast('error', '로그인이 필요합니다!'); return; } - setLiked({ isLiked: !isLiked }); }; - const handlePreventClickPropagation: React.MouseEventHandler = (event) => { - event.stopPropagation(); + const handleMenuOpen = () => { + setIsMenuOpened(true); + }; + + const handleMenuClose = () => { + setIsMenuOpened(false); }; return ( - - - - - - setIsMenuOpened(true)}> - - - - + + + + + + + + + + + + + + + + {isMenuOpened && ( - setIsMenuOpened(false)} /> + )} @@ -59,51 +82,12 @@ const CafeActionBar = (props: CafeActionBarProps) => { export default CafeActionBar; const Container = styled.aside` - position: absolute; - right: 0; - bottom: 133px; - display: flex; flex-direction: column; - gap: ${({ theme }) => theme.space[3]}; + gap: ${({ theme }) => theme.space[5]}; align-self: flex-end; - padding-right: ${({ theme }) => theme.space[3]}; -`; + padding: ${({ theme }) => theme.space[3]}; -const Action = styled.button` - padding: 0; color: white; - background: none; - border: none; -`; - -type ActionButtonProps = PropsWithChildren<{ - label: string; -}>; - -const ActionButton = (props: ActionButtonProps) => { - const { label, children } = props; - - return ( - - {children} - {label} - - ); -}; - -const ActionButtonContainer = styled.button` - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; -`; - -const ActionButtonIcon = styled.div` - font-size: ${({ theme }) => theme.fontSize['4xl']}; - - & > svg { - display: block; - } `; diff --git a/client/src/components/CafeCard.tsx b/client/src/components/CafeCard.tsx index 18f21595..5e5bac3d 100644 --- a/client/src/components/CafeCard.tsx +++ b/client/src/components/CafeCard.tsx @@ -32,30 +32,40 @@ const CafeCard = (props: CardProps) => { {`${currentImageIndex + 1}`}/{cafe.images.length} + {cafe.images.map((image, index) => ( ))} + + + + { + event.stopPropagation(); + setIsShowDetail(true); + }} + /> + + + + + + {cafe.images.map((_, index) => ( ))} - { - event.stopPropagation(); - setIsShowDetail(true); - }} - /> - + {isShowDetail && setIsShowDetail(false)} />} ); @@ -138,3 +148,18 @@ const CardQuantityContents = styled.div` background-color: ${({ theme }) => theme.color.background.secondary}; border-radius: 10px; `; + +const Bottom = styled.div` + position: absolute; + bottom: 40px; + display: flex; + width: 100%; +`; + +const BottomItem = styled.div<{ $fullWidth?: boolean; $align?: 'left' | 'right' }>` + position: absolute; + bottom: 0; + ${({ $align }) => $align === 'left' && 'left: 0;'} + ${({ $align }) => $align === 'right' && 'right: 0;'} + ${({ $fullWidth }) => $fullWidth && 'width: 100%;'} +`; diff --git a/client/src/components/CafeSummary.tsx b/client/src/components/CafeSummary.tsx index 007ce22c..6877e398 100644 --- a/client/src/components/CafeSummary.tsx +++ b/client/src/components/CafeSummary.tsx @@ -1,4 +1,3 @@ -import { BiSolidInfoCircle } from 'react-icons/bi'; import { SlLocationPin } from 'react-icons/sl'; import { styled } from 'styled-components'; @@ -20,26 +19,14 @@ const CafeSummary = (props: CafeSummaryProps) => { {address} - - - ); }; const Container = styled.div` cursor: pointer; - - position: absolute; - bottom: 0; - display: flex; - width: 100%; - margin-bottom: 40px; padding: ${({ theme }) => theme.space[3]}; `; @@ -63,21 +50,4 @@ const LocationPinIcon = styled(SlLocationPin)` font-size: ${({ theme }) => theme.fontSize.sm}; `; -const ButtonList = styled.div` - margin-left: auto; - font-size: ${({ theme }) => theme.fontSize.sm}; -`; - -const ButtonText = styled.span``; - -const Button = styled.button` - display: flex; - flex-direction: column; - align-items: flex-end; -`; - -const SolidInfoCircleIcon = styled(BiSolidInfoCircle)` - font-size: ${({ theme }) => theme.fontSize['4xl']}; -`; - export default CafeSummary; diff --git a/client/src/components/CommentButton.stories.tsx b/client/src/components/CommentButton.stories.tsx deleted file mode 100644 index b8f94ebb..00000000 --- a/client/src/components/CommentButton.stories.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import CommentButton from './CommentButton'; - -type Story = StoryObj; - -const meta: Meta = { - title: 'CommentButton', - component: CommentButton, -}; - -export default meta; - -export const Default: Story = { - args: {}, -}; diff --git a/client/src/components/CommentButton.tsx b/client/src/components/CommentButton.tsx deleted file mode 100644 index 7ca63b9b..00000000 --- a/client/src/components/CommentButton.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { PiChatFill } from 'react-icons/pi'; -import { styled } from 'styled-components'; - -const CommentButton = () => { - const handleClick = () => { - alert('아직 준비중입니다!'); - }; - - return ( - -