forked from codesquad-members-2023/second-hand
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
…detail-header-more-button [FE] 상품 상세 페이지 Header의 [더보기] 버튼 기능 #171
- Loading branch information
Showing
8 changed files
with
213 additions
and
21 deletions.
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
fe/src/components/ProductDetail/ProductDetailHeader/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { useState } from 'react'; | ||
import { useNavigate } from 'react-router-dom'; | ||
|
||
import { ICON_NAME, REQUEST_URL } from '@constants/index'; | ||
|
||
import useFetch, { REQUEST_METHOD } from '@hooks/useFetch'; | ||
|
||
import Icon from '@components/common/Icon'; | ||
import Modal from '@components/common/Modal'; | ||
import Popup from '@components/common/Popup'; | ||
import ModalPortal from '@components/ModalPortal'; | ||
import * as S from './style'; | ||
|
||
interface ProductDetailHeaderProps { | ||
postId: number; | ||
isSeller: boolean; | ||
} | ||
|
||
const ProductDetailHeader = ({ postId, isSeller }: ProductDetailHeaderProps) => { | ||
const [isModalOpen, setIsModalOpen] = useState(false); | ||
const [isPopupOpen, setIsPopupOpen] = useState(false); | ||
const navigate = useNavigate(); | ||
|
||
const { responseState: deletePostState, fetchData: deletePost } = useFetch({ | ||
url: `${REQUEST_URL.POSTS}/${postId}`, | ||
options: { | ||
method: REQUEST_METHOD.DELETE, | ||
headers: { Authorization: `Bearer ${localStorage.getItem('Token')}` }, | ||
}, | ||
skip: true, | ||
}); | ||
|
||
const deleteProduct = () => { | ||
deletePost(); | ||
|
||
if (deletePostState === 'ERROR') { | ||
alert('게시글 삭제에 싪패했습니다.'); | ||
return; | ||
} | ||
|
||
navigate('/'); | ||
}; | ||
|
||
const openPopup = () => setIsPopupOpen(true); | ||
|
||
return ( | ||
<S.Header> | ||
<button onClick={() => navigate(-1)}> | ||
<Icon name={ICON_NAME.CHEVRON_LEFT} /> | ||
</button> | ||
{isSeller && ( | ||
<button onClick={() => setIsModalOpen(true)}> | ||
<Icon name={ICON_NAME.ELLIPSIS} /> | ||
</button> | ||
)} | ||
{isPopupOpen && ( | ||
<ModalPortal> | ||
<Popup text="정말로 해당 게시물을 삭제할 것입니까?"> | ||
<S.ClosePopupButton onClick={() => setIsPopupOpen(false)}>아니오</S.ClosePopupButton> | ||
<S.DeletePostButton onClick={deleteProduct}>예</S.DeletePostButton> | ||
</Popup> | ||
</ModalPortal> | ||
)} | ||
{isModalOpen && ( | ||
<ModalPortal> | ||
<Modal | ||
options={[ | ||
{ text: '게시글 수정', colorType: 'default', handler: () => console.log('게시글 수정') }, | ||
{ text: '삭제', colorType: 'warning', handler: openPopup }, | ||
]} | ||
closeModalHandler={() => setIsModalOpen(false)} | ||
/> | ||
</ModalPortal> | ||
)} | ||
</S.Header> | ||
); | ||
}; | ||
|
||
export default ProductDetailHeader; |
36 changes: 36 additions & 0 deletions
36
fe/src/components/ProductDetail/ProductDetailHeader/style.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import styled from 'styled-components'; | ||
|
||
const ClosePopupButton = styled.button` | ||
width: 100%; | ||
max-width: 200px; | ||
padding: 8px 0; | ||
border: 1px solid ${({ theme }) => theme.colors.neutral.border.default}; | ||
border-radius: 10px; | ||
color: ${({ theme }) => theme.colors.neutral.text.default}; | ||
`; | ||
|
||
const DeletePostButton = styled.button` | ||
width: 100%; | ||
max-width: 200px; | ||
padding: 8px 0; | ||
border: 1px solid ${({ theme }) => theme.colors.neutral.border.default}; | ||
border-radius: 10px; | ||
color: ${({ theme }) => theme.colors.system.warning}; | ||
`; | ||
|
||
const Header = styled.header` | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
position: fixed; | ||
width: 100%; | ||
height: 44px; | ||
padding: 16px; | ||
`; | ||
|
||
export { ClosePopupButton, DeletePostButton, Header }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import Popup from '.'; | ||
|
||
const popupMeta: Meta<typeof Popup> = { | ||
title: 'common/Popup', | ||
component: Popup, | ||
}; | ||
|
||
export default popupMeta; | ||
|
||
type PopupStory = StoryObj<typeof Popup>; | ||
|
||
export const PrimaryPopup: PopupStory = { | ||
args: { | ||
text: '정말로 삭제하시겠습니까?', | ||
children: ( | ||
<> | ||
<button style={{ width: '100px', border: '1px solid black' }}>예</button> | ||
<button style={{ width: '100px', border: '1px solid black' }}>아니오</button> | ||
</> | ||
), | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import * as S from './style'; | ||
|
||
interface PopupProps { | ||
text: string; | ||
children: React.ReactNode; | ||
} | ||
|
||
const Popup = ({ text, children }: PopupProps) => { | ||
return ( | ||
<> | ||
<S.Popup> | ||
<span>{text}</span> | ||
<S.ButtonsLayout>{children}</S.ButtonsLayout> | ||
</S.Popup> | ||
<S.Overlay /> | ||
</> | ||
); | ||
}; | ||
|
||
export default Popup; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import styled from 'styled-components'; | ||
|
||
const Popup = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: space-between; | ||
align-items: center; | ||
gap: 15px; | ||
position: fixed; | ||
top: 50%; | ||
left: 50%; | ||
transform: translate(-50%, -50%); | ||
width: 80%; | ||
padding: 30px 20px; | ||
background-color: ${({ theme }) => theme.colors.neutral.background.weak}; | ||
border-radius: 15px; | ||
font-size: ${({ theme }) => theme.fonts.callout.fontSize}; | ||
font-weight: ${({ theme }) => theme.fonts.callout.fontWeight}; | ||
line-height: ${({ theme }) => theme.fonts.callout.lineHeight}; | ||
color: ${({ theme }) => theme.colors.neutral.text.strong}; | ||
z-index: 20; | ||
`; | ||
|
||
const ButtonsLayout = styled.div` | ||
display: flex; | ||
justify-content: center; | ||
gap: 15px; | ||
width: 100%; | ||
`; | ||
|
||
const Overlay = styled.div` | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
bottom: 0; | ||
overflow: auto; | ||
width: 100%; | ||
height: 100%; | ||
background-color: ${({ theme }) => theme.colors.neutral.overLay}; | ||
z-index: 15; | ||
`; | ||
|
||
export { Popup, ButtonsLayout, Overlay }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters