From 38bb8bfa7ee22be6a3554aa522180c468611de15 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Tue, 9 Jul 2024 14:37:55 +0900 Subject: [PATCH 01/60] =?UTF-8?q?feat:=20=EB=AA=A8=EB=93=A0=20=ED=9A=8C?= =?UTF-8?q?=EC=B0=A8=20=EB=93=9C=EB=A1=AD=EB=8B=A4=EC=9A=B4=20=EB=B7=B0=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/svgs/icon_chevron_back.svg | 3 + src/assets/svgs/IconChevronBack.tsx | 13 +++ src/assets/svgs/index.ts | 1 + .../narrowDropDown/NarrowDropDown.styled.ts | 105 ++++++++++++++++++ .../commons/narrowDropDown/NarrowDropDown.tsx | 36 ++++++ src/routes/Router.tsx | 2 + 6 files changed, 160 insertions(+) create mode 100644 public/svgs/icon_chevron_back.svg create mode 100644 src/assets/svgs/IconChevronBack.tsx create mode 100644 src/components/commons/narrowDropDown/NarrowDropDown.styled.ts create mode 100644 src/components/commons/narrowDropDown/NarrowDropDown.tsx diff --git a/public/svgs/icon_chevron_back.svg b/public/svgs/icon_chevron_back.svg new file mode 100644 index 00000000..0da9be5d --- /dev/null +++ b/public/svgs/icon_chevron_back.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/svgs/IconChevronBack.tsx b/src/assets/svgs/IconChevronBack.tsx new file mode 100644 index 00000000..adc09dff --- /dev/null +++ b/src/assets/svgs/IconChevronBack.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; +import type { SVGProps } from "react"; +const SvgIconChevronBack = (props: SVGProps) => ( + + + +); +export default SvgIconChevronBack; diff --git a/src/assets/svgs/index.ts b/src/assets/svgs/index.ts index 76170fe0..fe0d130f 100644 --- a/src/assets/svgs/index.ts +++ b/src/assets/svgs/index.ts @@ -1,3 +1,4 @@ +export { default as IconChevronBack } from "./IconChevronBack"; export { default as IconMinus } from "./IconMinus"; export { default as IconPlus } from "./IconPlus"; export { default as IconTextfiedlDelete } from "./IconTextfiedlDelete"; diff --git a/src/components/commons/narrowDropDown/NarrowDropDown.styled.ts b/src/components/commons/narrowDropDown/NarrowDropDown.styled.ts new file mode 100644 index 00000000..dc1994ff --- /dev/null +++ b/src/components/commons/narrowDropDown/NarrowDropDown.styled.ts @@ -0,0 +1,105 @@ +import SvgIconChevronBack from "@assets/svgs/IconChevronBack"; +import styled, { css } from "styled-components"; + +export const DropdownWrapper = styled.div` + position: relative; +`; + +export const DropdownButton = styled.button` + display: inline-flex; + flex-shrink: 0; + gap: 0.6rem; + align-items: center; + height: 4rem; + padding: 0.8rem 0.8rem 0.8rem 1.2rem; + + border: 1px solid ${({ theme }) => theme.colors.gray_400}; + border-radius: 0.4rem; +`; + +export const DropDownButtonContent = styled.button` + display: flex; + gap: 0.4rem; + align-items: center; +`; + +export const ButtonContentSpan = styled.span` + color: ${({ theme }) => theme.colors.gray_0}; + ${({ theme }) => theme.fonts["body2-normal-medi"]}; +`; + +export const SvgIcon = styled(SvgIconChevronBack)<{ $rotate: boolean }>` + width: 16px; + height: 16px; + + transform: rotate(180deg); + + ${(prop) => + prop.$rotate && + css` + transform: rotate(360deg); + `} +`; + +export const DropdownContentWrapper = styled.div<{ $show: boolean }>` + display: ${(props) => (props.$show ? "flex" : "none")}; + flex-shrink: 0; + gap: 0.6rem; + align-items: center; + width: 10.2rem; + margin-top: 0.8rem; + padding: 0.8rem 0.8rem 0.8rem 1.2rem; + + border: 1px solid ${({ theme }) => theme.colors.gray_400}; + + /* overflow: hidden; + position: absolute; + z-index: 1; + */ + + border-radius: 0.4rem; +`; + +export const DropdownContentLayout = styled.div` + display: flex; + flex-direction: column; + gap: 0.6rem; + align-items: flex-start; + justify-content: center; +`; + +export const DropdownContentBox = styled.div` + display: flex; + flex-direction: column; + gap: 0.8rem; + align-items: flex-start; + width: 6.8rem; + + /* 피그마에서는 겹치는 부분이 제대로 계산 안되서, 개발하면서 적당히 줄여둠 */ + padding: 0.2rem 0 0.6rem; + + border-bottom: 1px solid ${({ theme }) => theme.colors.gray_700}; +`; + +export const DropdownContentText = styled.span` + display: flex; + gap: 0.4rem; + align-items: center; + align-self: stretch; + justify-content: flex-start; + + color: ${({ theme }) => theme.colors.gray_0}; + ${({ theme }) => theme.fonts["body2-normal-medi"]}; +`; + +export const DropdownItem = styled.a` + display: block; + padding: 12px 16px; + + color: black; + text-decoration: none; + + &:hover { + background-color: #f1f1f1; + } +`; diff --git a/src/components/commons/narrowDropDown/NarrowDropDown.tsx b/src/components/commons/narrowDropDown/NarrowDropDown.tsx new file mode 100644 index 00000000..e41331e5 --- /dev/null +++ b/src/components/commons/narrowDropDown/NarrowDropDown.tsx @@ -0,0 +1,36 @@ +import { useState } from "react"; +import * as S from "./NarrowDropDown.styled"; + +const NarrowDropDown = () => { + const [showDropdown, setShowDropdown] = useState(false); + + const handleToggle = () => { + setShowDropdown(!showDropdown); + }; + + return ( + + + + 모든 회차 + + + + + + + 1차 + + + 2차 + + + 3차 + + + + + ); +}; + +export default NarrowDropDown; diff --git a/src/routes/Router.tsx b/src/routes/Router.tsx index ec5dfadf..d30d105d 100644 --- a/src/routes/Router.tsx +++ b/src/routes/Router.tsx @@ -1,3 +1,4 @@ +import NarrowDropDown from "@components/commons/narrowDropDown/NarrowDropDown"; import Apage from "@pages/APage/Apage"; import ModalTest from "@pages/ModalTest"; import TestPage from "@pages/test/TestPage"; @@ -17,6 +18,7 @@ const router = createBrowserRouter([ // element: , // }, { path: "/testpage", element: }, + { path: "/droptest", element: }, // ... ]); export default router; From 914b562884043c7e3ada9bcd6c110d7c3f9e6db7 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Tue, 9 Jul 2024 15:32:44 +0900 Subject: [PATCH 02/60] =?UTF-8?q?fix:=20=EB=93=9C=EB=A1=AD=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=20=EB=B0=B0=EA=B2=BD=20=EA=B2=80=EC=9D=80=EC=83=89?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95,=20=ED=95=84=ED=84=B0?= =?UTF-8?q?=EB=A7=81=20=EA=B4=80=EB=A0=A8=20=EC=A3=BC=EC=84=9D=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../narrowDropDown/NarrowDropDown.styled.ts | 9 ++------- .../commons/narrowDropDown/NarrowDropDown.tsx | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/components/commons/narrowDropDown/NarrowDropDown.styled.ts b/src/components/commons/narrowDropDown/NarrowDropDown.styled.ts index dc1994ff..a89cf1d9 100644 --- a/src/components/commons/narrowDropDown/NarrowDropDown.styled.ts +++ b/src/components/commons/narrowDropDown/NarrowDropDown.styled.ts @@ -50,13 +50,8 @@ export const DropdownContentWrapper = styled.div<{ $show: boolean }>` margin-top: 0.8rem; padding: 0.8rem 0.8rem 0.8rem 1.2rem; + background-color: ${({ theme }) => theme.colors.black}; border: 1px solid ${({ theme }) => theme.colors.gray_400}; - - /* overflow: hidden; - position: absolute; - z-index: 1; - */ - border-radius: 0.4rem; `; @@ -68,7 +63,7 @@ export const DropdownContentLayout = styled.div` justify-content: center; `; -export const DropdownContentBox = styled.div` +export const DropdownContentButton = styled.button` display: flex; flex-direction: column; gap: 0.8rem; diff --git a/src/components/commons/narrowDropDown/NarrowDropDown.tsx b/src/components/commons/narrowDropDown/NarrowDropDown.tsx index e41331e5..328ab5b8 100644 --- a/src/components/commons/narrowDropDown/NarrowDropDown.tsx +++ b/src/components/commons/narrowDropDown/NarrowDropDown.tsx @@ -8,6 +8,12 @@ const NarrowDropDown = () => { setShowDropdown(!showDropdown); }; + //공연별로 총 회차 값으로 넘겨주기로 함. + //각 공연별 회차는, DB 테이블 구조에 따라 enum값으로 넘겨주기로 함 + //필터링은 회차 번호(scheduleNumber : FIRST, SECOND, THIRD), 입금 완료 여부는 paymentStatus에 따라 나뉠거임 + // + const GetEXConstant: number = 3; + return ( @@ -18,15 +24,16 @@ const NarrowDropDown = () => { - + {} + 1차 - - + + 2차 - - + + 3차 - + From d6e3fd105d0d05b8256539acebac100ef8fb7cad Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Tue, 9 Jul 2024 15:51:59 +0900 Subject: [PATCH 03/60] =?UTF-8?q?fix:=20NarrowDropDown=EC=9D=84=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B0=9C=EC=9D=B8=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ticketholderlist/TicketHolderList.styled.ts | 0 src/pages/ticketholderlist/TicketHolderList.tsx | 7 +++++++ .../components}/narrowDropDown/NarrowDropDown.styled.ts | 0 .../components}/narrowDropDown/NarrowDropDown.tsx | 0 4 files changed, 7 insertions(+) create mode 100644 src/pages/ticketholderlist/TicketHolderList.styled.ts create mode 100644 src/pages/ticketholderlist/TicketHolderList.tsx rename src/{components/commons => pages/ticketholderlist/components}/narrowDropDown/NarrowDropDown.styled.ts (100%) rename src/{components/commons => pages/ticketholderlist/components}/narrowDropDown/NarrowDropDown.tsx (100%) diff --git a/src/pages/ticketholderlist/TicketHolderList.styled.ts b/src/pages/ticketholderlist/TicketHolderList.styled.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx new file mode 100644 index 00000000..cc44c4af --- /dev/null +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -0,0 +1,7 @@ +import React from "react"; + +const TicketHolderList = () => { + return
; +}; + +export default TicketHolderList; diff --git a/src/components/commons/narrowDropDown/NarrowDropDown.styled.ts b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts similarity index 100% rename from src/components/commons/narrowDropDown/NarrowDropDown.styled.ts rename to src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts diff --git a/src/components/commons/narrowDropDown/NarrowDropDown.tsx b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx similarity index 100% rename from src/components/commons/narrowDropDown/NarrowDropDown.tsx rename to src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx From b3a7670d3354cd2b17efee218e3f60156dac1f75 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Tue, 9 Jul 2024 17:03:44 +0900 Subject: [PATCH 04/60] =?UTF-8?q?feat:=20=ED=8B=B0=EC=BC=93=ED=99=80?= =?UTF-8?q?=EB=8D=94=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=ED=97=A4=EB=8D=94,=20=EB=B0=B0=EB=84=88=20?= =?UTF-8?q?=EB=B7=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/svgs/index.ts | 4 -- .../commons/navigation/Navigation.tsx | 5 ++ .../TicketHolderList.styled.ts | 45 ++++++++++++++++++ .../ticketholderlist/TicketHolderList.tsx | 21 ++++++-- .../ticketholderlist/constants/silkagel.png | Bin 0 -> 18768 bytes src/routes/Router.tsx | 3 ++ 6 files changed, 71 insertions(+), 7 deletions(-) delete mode 100644 src/assets/svgs/index.ts create mode 100644 src/pages/ticketholderlist/constants/silkagel.png diff --git a/src/assets/svgs/index.ts b/src/assets/svgs/index.ts deleted file mode 100644 index fe0d130f..00000000 --- a/src/assets/svgs/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { default as IconChevronBack } from "./IconChevronBack"; -export { default as IconMinus } from "./IconMinus"; -export { default as IconPlus } from "./IconPlus"; -export { default as IconTextfiedlDelete } from "./IconTextfiedlDelete"; diff --git a/src/components/commons/navigation/Navigation.tsx b/src/components/commons/navigation/Navigation.tsx index 6b845c56..0832d729 100644 --- a/src/components/commons/navigation/Navigation.tsx +++ b/src/components/commons/navigation/Navigation.tsx @@ -72,6 +72,11 @@ const Navigation = () => { // TODO: 공연목록, 수정, 삭제 따라 position, title, subTitle 다르게 setHeaderPosition(NAVIGATION_STATE.ICON_TITLE); break; + case "/ticketholderlist": + setHeaderPosition(NAVIGATION_STATE.ICON_TITLE_SUB_TEXT); + setTitle("내가 등록한 공연"); + setSubText("상태 저장"); + break; default: setTitle(""); } diff --git a/src/pages/ticketholderlist/TicketHolderList.styled.ts b/src/pages/ticketholderlist/TicketHolderList.styled.ts index e69de29b..bb682d5e 100644 --- a/src/pages/ticketholderlist/TicketHolderList.styled.ts +++ b/src/pages/ticketholderlist/TicketHolderList.styled.ts @@ -0,0 +1,45 @@ +import styled from "styled-components"; + +export const BannerWrapper = styled.div<{ $image: string }>` + width: 37.5rem; + height: 7.2rem; + + /* 사용자가 입력한 이미지 background 적당히 잘라서 사용하도록 */ + background-image: url(${({ $image }) => $image}); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +`; + +export const BannerTextLayout = styled.div` + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 37.5rem; + height: 7.2rem; + + background: rgb(0 0 0 / 60%); +`; + +export const BannerTextBox = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + width: 32.7rem; +`; + +export const BannerTitleText = styled.span` + color: ${({ theme }) => theme.colors.white}; + ${({ theme }) => theme.fonts.heading4}; +`; + +export const BannerStateTextBox = styled.span` + color: ${({ theme }) => theme.colors.white}; + ${({ theme }) => theme.fonts["body1-normal-semi"]}; +`; + +export const CountTextSpan = styled.span` + color: ${({ theme }) => theme.colors.pink_400}; + ${({ theme }) => theme.fonts["body1-normal-semi"]}; +`; diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index cc44c4af..6d8cb021 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -1,7 +1,22 @@ -import React from "react"; - +import * as S from "./TicketHolderList.styled"; +import eximg from "./constants/silkagel.png"; const TicketHolderList = () => { - return
; + return ( + + + + + 실리카겔 락앤롤 + + 현재 + 17매 + 예매됨 + + + + + + ); }; export default TicketHolderList; diff --git a/src/pages/ticketholderlist/constants/silkagel.png b/src/pages/ticketholderlist/constants/silkagel.png new file mode 100644 index 0000000000000000000000000000000000000000..a5295d7b6ff8506474f46ce399a0782e27ccee59 GIT binary patch literal 18768 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 LNkvXXu0mjf3P{ux literal 0 HcmV?d00001 diff --git a/src/routes/Router.tsx b/src/routes/Router.tsx index 6f913932..36ea7a99 100644 --- a/src/routes/Router.tsx +++ b/src/routes/Router.tsx @@ -7,6 +7,7 @@ import Manage from "@pages/manage/Manage"; import ModalTest from "@pages/ModalTest"; import Register from "@pages/register/Register"; import TestPage from "@pages/test/TestPage"; +import TicketHolderList from "@pages/ticketholderlist/TicketHolderList"; import ViewBottomSheetTest from "@pages/ViewBottomSheetTest"; import { createBrowserRouter } from "react-router-dom"; @@ -21,6 +22,8 @@ const router = createBrowserRouter([ { path: "register", element: }, { path: "book", element: }, { path: "manage", element: }, + { path: "ticketholderlist", element: }, + // ... other pages ], }, From a4c05dc3f34f51c1588dd7f0d879261dbd3f4a4e Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Tue, 9 Jul 2024 22:27:33 +0900 Subject: [PATCH 05/60] =?UTF-8?q?fix:=20=EB=93=9C=EB=A1=AD=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=20=EB=A9=94=EB=89=B4=20=EB=B6=80=EB=AA=A8=20=EC=9A=94?= =?UTF-8?q?=EC=86=8C=20=ED=81=AC=EA=B8=B0=20=EC=A1=B0=EC=A0=95=EC=95=88?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95,=20z-index=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/MyRegisterdShow/MyRegisterdShow.tsx | 2 +- .../RegisteredCard.styled.ts | 0 .../{ => registeredcard}/RegisteredCard.tsx | 2 +- src/pages/MyRegisterdShow/hooks/.gitkeep | 0 src/pages/MyRegisterdShow/types/.gitkeep | 0 src/pages/MyRegisterdShow/utils/.gitkeep | 0 .../TicketHolderList.styled.ts | 53 +++++++------------ .../ticketholderlist/TicketHolderList.tsx | 36 +++++++------ .../components/banner/Banner.styled.ts | 45 ++++++++++++++++ .../components/banner/Banner.tsx | 35 ++++++++++++ .../narrowDropDown/NarrowDropDown.styled.ts | 5 +- 11 files changed, 127 insertions(+), 51 deletions(-) rename src/pages/MyRegisterdShow/components/{ => registeredcard}/RegisteredCard.styled.ts (100%) rename src/pages/MyRegisterdShow/components/{ => registeredcard}/RegisteredCard.tsx (93%) delete mode 100644 src/pages/MyRegisterdShow/hooks/.gitkeep delete mode 100644 src/pages/MyRegisterdShow/types/.gitkeep delete mode 100644 src/pages/MyRegisterdShow/utils/.gitkeep create mode 100644 src/pages/ticketholderlist/components/banner/Banner.styled.ts create mode 100644 src/pages/ticketholderlist/components/banner/Banner.tsx diff --git a/src/pages/MyRegisterdShow/MyRegisterdShow.tsx b/src/pages/MyRegisterdShow/MyRegisterdShow.tsx index 50f12596..f78c663b 100644 --- a/src/pages/MyRegisterdShow/MyRegisterdShow.tsx +++ b/src/pages/MyRegisterdShow/MyRegisterdShow.tsx @@ -3,7 +3,7 @@ import { useState } from "react"; import { useNavigate } from "react-router-dom"; import bannerNarrow from "../../assets/images/banner_narrow.png"; import * as S from "./MyRegisterdShow.styled"; -import RegisteredCard from "./components/RegisteredCard"; +import RegisteredCard from "./components/registeredcard/RegisteredCard"; import { MY_REGISTERED_SHOW, RegisteredObjProps } from "./constants/myRegisterShow"; const MyRegisterdShow = () => { diff --git a/src/pages/MyRegisterdShow/components/RegisteredCard.styled.ts b/src/pages/MyRegisterdShow/components/registeredcard/RegisteredCard.styled.ts similarity index 100% rename from src/pages/MyRegisterdShow/components/RegisteredCard.styled.ts rename to src/pages/MyRegisterdShow/components/registeredcard/RegisteredCard.styled.ts diff --git a/src/pages/MyRegisterdShow/components/RegisteredCard.tsx b/src/pages/MyRegisterdShow/components/registeredcard/RegisteredCard.tsx similarity index 93% rename from src/pages/MyRegisterdShow/components/RegisteredCard.tsx rename to src/pages/MyRegisterdShow/components/registeredcard/RegisteredCard.tsx index ac4655bc..a685957d 100644 --- a/src/pages/MyRegisterdShow/components/RegisteredCard.tsx +++ b/src/pages/MyRegisterdShow/components/registeredcard/RegisteredCard.tsx @@ -1,5 +1,5 @@ import Button from "@components/commons/button/Button"; -import { RegisteredObjProps } from "../constants/myRegisterShow"; +import { RegisteredObjProps } from "../../constants/myRegisterShow"; import * as S from "./RegisteredCard.styled"; const RegisteredCard = ({ title, period, genre, image }: Omit) => { diff --git a/src/pages/MyRegisterdShow/hooks/.gitkeep b/src/pages/MyRegisterdShow/hooks/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/pages/MyRegisterdShow/types/.gitkeep b/src/pages/MyRegisterdShow/types/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/pages/MyRegisterdShow/utils/.gitkeep b/src/pages/MyRegisterdShow/utils/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/pages/ticketholderlist/TicketHolderList.styled.ts b/src/pages/ticketholderlist/TicketHolderList.styled.ts index bb682d5e..9d74462a 100644 --- a/src/pages/ticketholderlist/TicketHolderList.styled.ts +++ b/src/pages/ticketholderlist/TicketHolderList.styled.ts @@ -1,45 +1,32 @@ import styled from "styled-components"; -export const BannerWrapper = styled.div<{ $image: string }>` - width: 37.5rem; - height: 7.2rem; - - /* 사용자가 입력한 이미지 background 적당히 잘라서 사용하도록 */ - background-image: url(${({ $image }) => $image}); - background-repeat: no-repeat; - background-position: center; - background-size: cover; -`; - -export const BannerTextLayout = styled.div` +export const BodyWrapper = styled.main` display: flex; - flex-shrink: 0; - align-items: center; + align-items: flex-start; justify-content: center; - width: 37.5rem; - height: 7.2rem; - - background: rgb(0 0 0 / 60%); + width: 37.4rem; + height: auto; + min-height: 60.8rem; /* 60.8rem(body의 높이) + 5.6rem(헤더의 높이) */ + padding: 2.4rem; `; -export const BannerTextBox = styled.div` +export const BodyLayout = styled.section` display: flex; - align-items: center; - justify-content: space-between; - width: 32.7rem; + flex: 1 0 0; + flex-direction: column; + gap: 2.4rem; + align-items: flex-start; `; -export const BannerTitleText = styled.span` - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.heading4}; -`; - -export const BannerStateTextBox = styled.span` - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts["body1-normal-semi"]}; +export const LayoutHeaderBox = styled.div` + display: flex; + gap: 3.2rem; + align-items: flex-end; + align-self: stretch; `; -export const CountTextSpan = styled.span` - color: ${({ theme }) => theme.colors.pink_400}; - ${({ theme }) => theme.fonts["body1-normal-semi"]}; +export const LayoutFilterBox = styled.div` + display: flex; + gap: 0.6rem; + align-items: center; `; diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index 6d8cb021..3f8af379 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -1,21 +1,27 @@ -import * as S from "./TicketHolderList.styled"; +import { useState } from "react"; +import Banner from "./components/banner/Banner"; +import NarrowDropDown from "./components/narrowDropDown/NarrowDropDown"; import eximg from "./constants/silkagel.png"; +import * as S from "./TicketHolderList.styled"; const TicketHolderList = () => { + const [reservedCount, setReservedCount] = useState(0); + //이거 판매 완료되었는지 여부에 따라서 렌더링하는거 다르게 할지 물어보기, 색깔도 어떻게 할 지 물어보기 + const [isOutdated, setIsOutdated] = useState(false); + return ( - - - - - 실리카겔 락앤롤 - - 현재 - 17매 - 예매됨 - - - - - + <> + + + + + + + + + + + + ); }; diff --git a/src/pages/ticketholderlist/components/banner/Banner.styled.ts b/src/pages/ticketholderlist/components/banner/Banner.styled.ts new file mode 100644 index 00000000..bb682d5e --- /dev/null +++ b/src/pages/ticketholderlist/components/banner/Banner.styled.ts @@ -0,0 +1,45 @@ +import styled from "styled-components"; + +export const BannerWrapper = styled.div<{ $image: string }>` + width: 37.5rem; + height: 7.2rem; + + /* 사용자가 입력한 이미지 background 적당히 잘라서 사용하도록 */ + background-image: url(${({ $image }) => $image}); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +`; + +export const BannerTextLayout = styled.div` + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 37.5rem; + height: 7.2rem; + + background: rgb(0 0 0 / 60%); +`; + +export const BannerTextBox = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + width: 32.7rem; +`; + +export const BannerTitleText = styled.span` + color: ${({ theme }) => theme.colors.white}; + ${({ theme }) => theme.fonts.heading4}; +`; + +export const BannerStateTextBox = styled.span` + color: ${({ theme }) => theme.colors.white}; + ${({ theme }) => theme.fonts["body1-normal-semi"]}; +`; + +export const CountTextSpan = styled.span` + color: ${({ theme }) => theme.colors.pink_400}; + ${({ theme }) => theme.fonts["body1-normal-semi"]}; +`; diff --git a/src/pages/ticketholderlist/components/banner/Banner.tsx b/src/pages/ticketholderlist/components/banner/Banner.tsx new file mode 100644 index 00000000..fb64c122 --- /dev/null +++ b/src/pages/ticketholderlist/components/banner/Banner.tsx @@ -0,0 +1,35 @@ +import * as S from "./Banner.styled"; + +interface BannerProps { + image: string; + reservedCount: number; + isOutdated: boolean; +} + +const Banner = ({ image, reservedCount, isOutdated }: BannerProps) => { + return ( + + + + + 실리카겔 락앤롤 + {isOutdated ? ( + + 총 {reservedCount}매 + 판매 됨 + + ) : ( + + 현재 + {reservedCount}매 + 예매됨 + + )} + + + + + ); +}; + +export default Banner; diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts index a89cf1d9..d149dbdb 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts @@ -42,11 +42,14 @@ export const SvgIcon = styled(SvgIconChevronBack)<{ $rotate: boolean }>` `; export const DropdownContentWrapper = styled.div<{ $show: boolean }>` + position: absolute; + top: 4.06rem; /* 버튼의 높이 3.26rem + 간격 0.8rem */ + z-index: 1; display: ${(props) => (props.$show ? "flex" : "none")}; flex-shrink: 0; gap: 0.6rem; align-items: center; - width: 10.2rem; + width: 9.2rem; margin-top: 0.8rem; padding: 0.8rem 0.8rem 0.8rem 1.2rem; From 2a34bea70c9c7cc89f0d023ca74429b28e109100 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Wed, 10 Jul 2024 01:03:01 +0900 Subject: [PATCH 06/60] =?UTF-8?q?feat:=20=EB=93=9C=EB=A1=AD=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=20=EB=A9=94=EB=89=B4=20=EB=A1=9C=EC=A7=81=20=EC=99=84?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ticketholderlist/TicketHolderList.tsx | 16 ++++- .../narrowDropDown/NarrowDropDown.tsx | 68 +++++++++++++++---- 2 files changed, 68 insertions(+), 16 deletions(-) diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index 3f8af379..6b6cd284 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -8,6 +8,11 @@ const TicketHolderList = () => { //이거 판매 완료되었는지 여부에 따라서 렌더링하는거 다르게 할지 물어보기, 색깔도 어떻게 할 지 물어보기 const [isOutdated, setIsOutdated] = useState(false); + // 0, undefined 일 때는 전체 렌더링 + const [schedule, setSchedule] = useState(0); //1,2,3 에 따라 필터링 + const [payment, setPayment] = useState(undefined); + + const count = 5; //나중에 api로 받아와서 반영해야함. state로 바꿀 필요 있을까? return ( <> @@ -15,10 +20,17 @@ const TicketHolderList = () => { - - + {/*set 함수 직접 넘기는 거 안좋다고 했지만, 내부에서 감싸야 하므로 넘김 */} + + 모든 회차 + + + 입금 상태 + + {`현재 눌린 회차 번호 : ${schedule}`} + {`현재 눌린 지불 여부 : ${payment}`} diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx index 328ab5b8..f1013c18 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx @@ -1,39 +1,79 @@ -import { useState } from "react"; +import { ReactNode, useState } from "react"; import * as S from "./NarrowDropDown.styled"; -const NarrowDropDown = () => { +interface DropdownProps { + children: ReactNode; + totalScheduleCount: number; + setSchedule?: (param: number) => void; + setPayment?: (param: boolean) => void; +} + +const NarrowDropDown = ({ + children, + totalScheduleCount, + setSchedule, + setPayment, +}: DropdownProps) => { const [showDropdown, setShowDropdown] = useState(false); const handleToggle = () => { setShowDropdown(!showDropdown); }; + const renderDropdownContent = (count: number, childrenNode: ReactNode) => { + const items = []; + const childrenString = childrenNode?.toString(); + if (childrenString === "모든 회차") { + for (let i = 1; i <= count; i++) { + const handleSchedule = () => { + setSchedule?.(i); + }; + items.push( + + {i}차 + + ); + } + } else if (childrenString === "입금 상태") { + const handlePaymentFalse = () => { + setPayment?.(false); + }; + + const handlePaymentTrue = () => { + setPayment?.(true); + }; + + items.push( + + 미입금 + + ); + items.push( + + 입금완료 + + ); + } + + return items; + }; + //공연별로 총 회차 값으로 넘겨주기로 함. //각 공연별 회차는, DB 테이블 구조에 따라 enum값으로 넘겨주기로 함 //필터링은 회차 번호(scheduleNumber : FIRST, SECOND, THIRD), 입금 완료 여부는 paymentStatus에 따라 나뉠거임 // - const GetEXConstant: number = 3; return ( - 모든 회차 + {children} - {} - - 1차 - - - 2차 - - - 3차 - + {renderDropdownContent(totalScheduleCount, children)} From f6f2ac9c0918930e7f0fcb704c83a3f4b2fd052e Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Wed, 10 Jul 2024 02:39:54 +0900 Subject: [PATCH 07/60] =?UTF-8?q?feat,fix:=20toggle(=EA=B0=84=EB=9E=B5?= =?UTF-8?q?=ED=9E=88,=EC=9E=90=EC=84=B8=ED=9E=88)=20=EB=B7=B0=20=EC=99=84?= =?UTF-8?q?=EC=84=B1,=20=EB=B0=B0=EC=97=B4=EC=97=90=20key=20=EB=B6=80?= =?UTF-8?q?=EC=97=AC,=20=EB=B2=84=ED=8A=BC=20=EC=95=88=EC=97=90=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/svgs/icon_toggle_off.svg | 4 +++ public/svgs/icon_toggle_on.svg | 6 +++++ src/assets/svgs/IconToggleOff.tsx | 9 +++++++ src/assets/svgs/IconToggleOn.tsx | 9 +++++++ src/assets/svgs/index.tsx | 5 +++- .../TicketHolderList.styled.ts | 22 +++++++++++++++ .../ticketholderlist/TicketHolderList.tsx | 27 +++++++++++++++++++ .../narrowDropDown/NarrowDropDown.styled.ts | 2 +- .../narrowDropDown/NarrowDropDown.tsx | 6 ++--- 9 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 public/svgs/icon_toggle_off.svg create mode 100644 public/svgs/icon_toggle_on.svg create mode 100644 src/assets/svgs/IconToggleOff.tsx create mode 100644 src/assets/svgs/IconToggleOn.tsx diff --git a/public/svgs/icon_toggle_off.svg b/public/svgs/icon_toggle_off.svg new file mode 100644 index 00000000..4a4197b0 --- /dev/null +++ b/public/svgs/icon_toggle_off.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/svgs/icon_toggle_on.svg b/public/svgs/icon_toggle_on.svg new file mode 100644 index 00000000..c23c6c7d --- /dev/null +++ b/public/svgs/icon_toggle_on.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/svgs/IconToggleOff.tsx b/src/assets/svgs/IconToggleOff.tsx new file mode 100644 index 00000000..d584f216 --- /dev/null +++ b/src/assets/svgs/IconToggleOff.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; +import type { SVGProps } from "react"; +const SvgIconToggleOff = (props: SVGProps) => ( + + + + +); +export default SvgIconToggleOff; diff --git a/src/assets/svgs/IconToggleOn.tsx b/src/assets/svgs/IconToggleOn.tsx new file mode 100644 index 00000000..1f6d2ca4 --- /dev/null +++ b/src/assets/svgs/IconToggleOn.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; +import type { SVGProps } from "react"; +const SvgIconToggleOn = (props: SVGProps) => ( + + + + +); +export default SvgIconToggleOn; diff --git a/src/assets/svgs/index.tsx b/src/assets/svgs/index.tsx index bd7bf2f4..7bb7293c 100644 --- a/src/assets/svgs/index.tsx +++ b/src/assets/svgs/index.tsx @@ -1,10 +1,13 @@ -export { default as IcomCopy } from "./IcomCopy"; export { default as IcHamburgar } from "./IcHamburgar"; +export { default as IcomCopy } from "./IcomCopy"; export { default as IconArrowLeft } from "./IconArrowLeft"; export { default as IconArrowRight } from "./IconArrowRight"; export { default as IconCheck } from "./IconCheck"; +export { default as IconChevronBack } from "./IconChevronBack"; export { default as IconLogo } from "./IconLogo"; export { default as IconMinus } from "./IconMinus"; export { default as IconPlus } from "./IconPlus"; export { default as IconTextfiedlDelete } from "./IconTextfiedlDelete"; +export { default as IconToggleOff } from "./IconToggleOff"; +export { default as IconToggleOn } from "./IconToggleOn"; export { default as IconXButton } from "./IconXButton"; diff --git a/src/pages/ticketholderlist/TicketHolderList.styled.ts b/src/pages/ticketholderlist/TicketHolderList.styled.ts index 9d74462a..b0391a3d 100644 --- a/src/pages/ticketholderlist/TicketHolderList.styled.ts +++ b/src/pages/ticketholderlist/TicketHolderList.styled.ts @@ -1,3 +1,4 @@ +import { IconToggleOff, IconToggleOn } from "@assets/svgs"; import styled from "styled-components"; export const BodyWrapper = styled.main` @@ -30,3 +31,24 @@ export const LayoutFilterBox = styled.div` gap: 0.6rem; align-items: center; `; + +export const ToggleWrapper = styled.div` + display: flex; + gap: 0.4rem; + align-items: center; +`; + +export const ToggleText = styled.span` + color: ${({ theme }) => theme.colors.gray_400}; + ${({ theme }) => theme.fonts["body2-normal-medi"]}; +`; + +export const ToggleOnIcon = styled(IconToggleOn)<{ $width: string; $height: string }>` + width: ${({ $width }) => $width}; + height: ${({ $height }) => $height}; +`; + +export const ToggleOffIcon = styled(IconToggleOff)<{ $width: string; $height: string }>` + width: ${({ $width }) => $width}; + height: ${({ $height }) => $height}; +`; diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index 6b6cd284..14c0d493 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -3,15 +3,21 @@ import Banner from "./components/banner/Banner"; import NarrowDropDown from "./components/narrowDropDown/NarrowDropDown"; import eximg from "./constants/silkagel.png"; import * as S from "./TicketHolderList.styled"; + const TicketHolderList = () => { const [reservedCount, setReservedCount] = useState(0); //이거 판매 완료되었는지 여부에 따라서 렌더링하는거 다르게 할지 물어보기, 색깔도 어떻게 할 지 물어보기 const [isOutdated, setIsOutdated] = useState(false); + const [detail, setDetail] = useState(false); // 0, undefined 일 때는 전체 렌더링 const [schedule, setSchedule] = useState(0); //1,2,3 에 따라 필터링 const [payment, setPayment] = useState(undefined); + const handleToggleButton = () => { + setDetail((prop) => !prop); + }; + const count = 5; //나중에 api로 받아와서 반영해야함. state로 바꿀 필요 있을까? return ( <> @@ -28,6 +34,27 @@ const TicketHolderList = () => { 입금 상태
+ + {detail ? ( + <> + 자세히 + + + ) : ( + <> + 간략히 + + + )} + {`현재 눌린 회차 번호 : ${schedule}`} {`현재 눌린 지불 여부 : ${payment}`} diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts index d149dbdb..0629fd68 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts @@ -17,7 +17,7 @@ export const DropdownButton = styled.button` border-radius: 0.4rem; `; -export const DropDownButtonContent = styled.button` +export const DropDownButtonContent = styled.div` display: flex; gap: 0.4rem; align-items: center; diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx index f1013c18..8a51c1d8 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx @@ -29,7 +29,7 @@ const NarrowDropDown = ({ setSchedule?.(i); }; items.push( - + {i}차 ); @@ -44,12 +44,12 @@ const NarrowDropDown = ({ }; items.push( - + 미입금 ); items.push( - + 입금완료 ); From deeb59e85040016944c640271e4e5ae6323be4c0 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Wed, 10 Jul 2024 02:51:23 +0900 Subject: [PATCH 08/60] =?UTF-8?q?=ED=95=98=EB=8B=A8=20fix=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EB=B7=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ticketholderlist/TicketHolderList.styled.ts | 6 ++++++ src/pages/ticketholderlist/TicketHolderList.tsx | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/pages/ticketholderlist/TicketHolderList.styled.ts b/src/pages/ticketholderlist/TicketHolderList.styled.ts index b0391a3d..842781d5 100644 --- a/src/pages/ticketholderlist/TicketHolderList.styled.ts +++ b/src/pages/ticketholderlist/TicketHolderList.styled.ts @@ -52,3 +52,9 @@ export const ToggleOffIcon = styled(IconToggleOff)<{ $width: string; $height: st width: ${({ $width }) => $width}; height: ${({ $height }) => $height}; `; + +export const FooterButtonWrapper = styled.div` + position: fixed; + bottom: 0; + z-index: 1; +`; diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index 14c0d493..90a47b58 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -1,3 +1,4 @@ +import Button from "@components/commons/button/Button"; import { useState } from "react"; import Banner from "./components/banner/Banner"; import NarrowDropDown from "./components/narrowDropDown/NarrowDropDown"; @@ -56,8 +57,12 @@ const TicketHolderList = () => { )} + {`현재 눌린 회차 번호 : ${schedule}`} {`현재 눌린 지불 여부 : ${payment}`} + + + From df94efe6cfc700f3fdc1344279a2373858b168c2 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Wed, 10 Jul 2024 04:18:14 +0900 Subject: [PATCH 09/60] =?UTF-8?q?feat:=20ManagerCard(=EC=9E=85=EA=B8=88?= =?UTF-8?q?=EC=99=84=EB=A3=8C=EC=97=AC=EB=B6=80=EC=B9=B4=EB=93=9C)=20?= =?UTF-8?q?=EB=B7=B0=20=EA=B5=AC=ED=98=84=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/svgs/Icon_checkbox_selected_on.svg | 7 ++ public/svgs/Icon_checkbox_unselected_on.svg | 3 + src/assets/svgs/IconCheckboxSelectedOn.tsx | 17 +++++ src/assets/svgs/IconCheckboxUnselectedOn.tsx | 8 +++ src/assets/svgs/index.tsx | 2 + .../ticketholderlist/TicketHolderList.tsx | 10 ++- .../managecard/ManagerCard.styled.ts | 68 +++++++++++++++++++ .../components/managecard/ManagerCard.tsx | 25 +++++++ 8 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 public/svgs/Icon_checkbox_selected_on.svg create mode 100644 public/svgs/Icon_checkbox_unselected_on.svg create mode 100644 src/assets/svgs/IconCheckboxSelectedOn.tsx create mode 100644 src/assets/svgs/IconCheckboxUnselectedOn.tsx create mode 100644 src/pages/ticketholderlist/components/managecard/ManagerCard.styled.ts create mode 100644 src/pages/ticketholderlist/components/managecard/ManagerCard.tsx diff --git a/public/svgs/Icon_checkbox_selected_on.svg b/public/svgs/Icon_checkbox_selected_on.svg new file mode 100644 index 00000000..69f4fe65 --- /dev/null +++ b/public/svgs/Icon_checkbox_selected_on.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/svgs/Icon_checkbox_unselected_on.svg b/public/svgs/Icon_checkbox_unselected_on.svg new file mode 100644 index 00000000..0bbb7e17 --- /dev/null +++ b/public/svgs/Icon_checkbox_unselected_on.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/svgs/IconCheckboxSelectedOn.tsx b/src/assets/svgs/IconCheckboxSelectedOn.tsx new file mode 100644 index 00000000..f026c681 --- /dev/null +++ b/src/assets/svgs/IconCheckboxSelectedOn.tsx @@ -0,0 +1,17 @@ +import * as React from "react"; +import type { SVGProps } from "react"; +const SvgIconCheckboxSelectedOn = (props: SVGProps) => ( + + + + + +); +export default SvgIconCheckboxSelectedOn; diff --git a/src/assets/svgs/IconCheckboxUnselectedOn.tsx b/src/assets/svgs/IconCheckboxUnselectedOn.tsx new file mode 100644 index 00000000..746b0984 --- /dev/null +++ b/src/assets/svgs/IconCheckboxUnselectedOn.tsx @@ -0,0 +1,8 @@ +import * as React from "react"; +import type { SVGProps } from "react"; +const SvgIconCheckboxUnselectedOn = (props: SVGProps) => ( + + + +); +export default SvgIconCheckboxUnselectedOn; diff --git a/src/assets/svgs/index.tsx b/src/assets/svgs/index.tsx index 7bb7293c..bba10fee 100644 --- a/src/assets/svgs/index.tsx +++ b/src/assets/svgs/index.tsx @@ -3,6 +3,8 @@ export { default as IcomCopy } from "./IcomCopy"; export { default as IconArrowLeft } from "./IconArrowLeft"; export { default as IconArrowRight } from "./IconArrowRight"; export { default as IconCheck } from "./IconCheck"; +export { default as IconCheckboxSelectedOn } from "./IconCheckboxSelectedOn"; +export { default as IconCheckboxUnselectedOn } from "./IconCheckboxUnselectedOn"; export { default as IconChevronBack } from "./IconChevronBack"; export { default as IconLogo } from "./IconLogo"; export { default as IconMinus } from "./IconMinus"; diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index 90a47b58..fceaa457 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -1,7 +1,8 @@ import Button from "@components/commons/button/Button"; import { useState } from "react"; import Banner from "./components/banner/Banner"; -import NarrowDropDown from "./components/narrowDropDown/NarrowDropDown"; +import ManagerCard from "./components/managecard/ManagerCard"; +import NarrowDropDown from "./components/narrowdropdown/NarrowDropDown"; import eximg from "./constants/silkagel.png"; import * as S from "./TicketHolderList.styled"; @@ -10,6 +11,7 @@ const TicketHolderList = () => { //이거 판매 완료되었는지 여부에 따라서 렌더링하는거 다르게 할지 물어보기, 색깔도 어떻게 할 지 물어보기 const [isOutdated, setIsOutdated] = useState(false); const [detail, setDetail] = useState(false); + const [paid, setPaid] = useState(false); // 0, undefined 일 때는 전체 렌더링 const [schedule, setSchedule] = useState(0); //1,2,3 에 따라 필터링 @@ -19,6 +21,10 @@ const TicketHolderList = () => { setDetail((prop) => !prop); }; + const handlePaidButton = () => { + setPaid((prop) => !prop); + }; + const count = 5; //나중에 api로 받아와서 반영해야함. state로 바꿀 필요 있을까? return ( <> @@ -57,7 +63,7 @@ const TicketHolderList = () => { )} - + {`현재 눌린 회차 번호 : ${schedule}`} {`현재 눌린 지불 여부 : ${payment}`} diff --git a/src/pages/ticketholderlist/components/managecard/ManagerCard.styled.ts b/src/pages/ticketholderlist/components/managecard/ManagerCard.styled.ts new file mode 100644 index 00000000..58284221 --- /dev/null +++ b/src/pages/ticketholderlist/components/managecard/ManagerCard.styled.ts @@ -0,0 +1,68 @@ +import { IconCheckboxSelectedOn, IconCheckboxUnselectedOn } from "@assets/svgs"; +import styled from "styled-components"; + +export const ManagerCardWrapper = styled.article<{ $isDetail: boolean }>` + display: flex; + flex-shrink: 0; + align-items: flex-start; + justify-content: center; + width: 32.6rem; + height: ${({ $isDetail }) => ($isDetail ? "14.6rem" : "7.4rem")}; +`; + +export const ManagerCardLayout = styled.div<{ $isDetail: boolean }>` + display: flex; + flex-direction: column; + flex-shrink: 0; + gap: 1.6rem; + align-items: flex-start; + width: 25.2rem; + height: ${({ $isDetail }) => ($isDetail ? "14.6rem" : "7.4rem")}; + padding: 2rem 1.6rem; + + background-color: ${({ theme }) => theme.colors.gray_800}; + border-right: 1px solid ${({ theme }) => theme.colors.black}; + border-radius: 6px; +`; + +export const ManagerCardRadioLayout = styled.div<{ $isDetail: boolean; $isPaid: boolean }>` + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 7.4rem; + height: ${({ $isDetail }) => ($isDetail ? "14.6rem" : "7.4rem")}; + padding: 1.5rem 1.5rem 1.5rem 1.6rem; + + background-color: ${({ theme, $isPaid }) => + $isPaid ? theme.colors.pink_600 : theme.colors.gray_800}; + border-radius: 6px; +`; + +export const ManagerCardRadioBox = styled.div` + display: flex; + flex-direction: column; + flex-shrink: 0; + gap: 1rem; + align-items: center; + width: 4.3rem; + + cursor: pointer; +`; + +export const SelectedIcon = styled(IconCheckboxSelectedOn)` + width: 1.8rem; + height: 1.8rem; +`; + +export const UnselectedIcon = styled(IconCheckboxUnselectedOn)` + width: 1.8rem; + height: 1.8rem; +`; + +export const ManagerCardRadioText = styled.span` + color: ${({ theme }) => theme.colors.white}; + text-align: center; + + ${({ theme }) => theme.fonts["caption1-semi"]}; +`; diff --git a/src/pages/ticketholderlist/components/managecard/ManagerCard.tsx b/src/pages/ticketholderlist/components/managecard/ManagerCard.tsx new file mode 100644 index 00000000..51fb7bf5 --- /dev/null +++ b/src/pages/ticketholderlist/components/managecard/ManagerCard.tsx @@ -0,0 +1,25 @@ +import * as S from "./ManagerCard.styled"; + +const ManagerCard = ({ + isPaid, + isDetail, + setDetail, +}: { + isPaid: boolean; + isDetail: boolean; + setDetail: () => void; +}) => { + return ( + + + + + {isPaid ? : } + {isPaid ? "입금 완료" : "미입금"} + + + + ); +}; + +export default ManagerCard; From 4ea2f873c46496d2b62a1a60a20ceae13e09ad5e Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Wed, 10 Jul 2024 15:12:10 +0900 Subject: [PATCH 10/60] =?UTF-8?q?feat:=20=EB=B2=84=ED=8A=BC=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C=20=EC=83=89=EA=B9=94=20=EB=8B=AC=EB=9D=BC?= =?UTF-8?q?=EC=A7=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ticketholderlist/TicketHolderList.tsx | 12 +++++++-- .../narrowDropDown/NarrowDropDown.styled.ts | 9 ++++++- .../narrowDropDown/NarrowDropDown.tsx | 25 ++++++++++++++++--- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index fceaa457..5235cf2f 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -34,10 +34,18 @@ const TicketHolderList = () => { {/*set 함수 직접 넘기는 거 안좋다고 했지만, 내부에서 감싸야 하므로 넘김 */} - + 모든 회차 - + 입금 상태 diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts index 0629fd68..34aa43f3 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts @@ -66,7 +66,10 @@ export const DropdownContentLayout = styled.div` justify-content: center; `; -export const DropdownContentButton = styled.button` +export const DropdownContentButton = styled.button<{ + $schedule: number; + $payment: boolean | undefined; +}>` display: flex; flex-direction: column; gap: 0.8rem; @@ -76,6 +79,10 @@ export const DropdownContentButton = styled.button` /* 피그마에서는 겹치는 부분이 제대로 계산 안되서, 개발하면서 적당히 줄여둠 */ padding: 0.2rem 0 0.6rem; + background-color: ${({ theme, $schedule, key }) => + $schedule === key ? theme.colors.gray_800 : "initial"}; + + /* 그냥 눌렀을 때 색깔 변경되는거 내일 하자......... */ border-bottom: 1px solid ${({ theme }) => theme.colors.gray_700}; `; diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx index 8a51c1d8..b6e2482f 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx @@ -4,6 +4,8 @@ import * as S from "./NarrowDropDown.styled"; interface DropdownProps { children: ReactNode; totalScheduleCount: number; + schedule: number; + payment?: boolean | undefined; setSchedule?: (param: number) => void; setPayment?: (param: boolean) => void; } @@ -11,6 +13,8 @@ interface DropdownProps { const NarrowDropDown = ({ children, totalScheduleCount, + schedule, + payment, setSchedule, setPayment, }: DropdownProps) => { @@ -29,7 +33,12 @@ const NarrowDropDown = ({ setSchedule?.(i); }; items.push( - + {i}차 ); @@ -44,12 +53,22 @@ const NarrowDropDown = ({ }; items.push( - + 미입금 ); items.push( - + 입금완료 ); From 48c9d5f9a2adef000d3de74e5e4fa8ed99c59587 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Wed, 10 Jul 2024 16:21:10 +0900 Subject: [PATCH 11/60] =?UTF-8?q?Revert=20"feat:=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EC=83=89=EA=B9=94=20=EB=8B=AC?= =?UTF-8?q?=EB=9D=BC=EC=A7=90"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4ea2f873c46496d2b62a1a60a20ceae13e09ad5e. --- .../ticketholderlist/TicketHolderList.tsx | 12 ++------- .../narrowDropDown/NarrowDropDown.styled.ts | 9 +------ .../narrowDropDown/NarrowDropDown.tsx | 25 +++---------------- 3 files changed, 6 insertions(+), 40 deletions(-) diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index 5235cf2f..fceaa457 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -34,18 +34,10 @@ const TicketHolderList = () => { {/*set 함수 직접 넘기는 거 안좋다고 했지만, 내부에서 감싸야 하므로 넘김 */} - + 모든 회차 - + 입금 상태 diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts index 34aa43f3..0629fd68 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts @@ -66,10 +66,7 @@ export const DropdownContentLayout = styled.div` justify-content: center; `; -export const DropdownContentButton = styled.button<{ - $schedule: number; - $payment: boolean | undefined; -}>` +export const DropdownContentButton = styled.button` display: flex; flex-direction: column; gap: 0.8rem; @@ -79,10 +76,6 @@ export const DropdownContentButton = styled.button<{ /* 피그마에서는 겹치는 부분이 제대로 계산 안되서, 개발하면서 적당히 줄여둠 */ padding: 0.2rem 0 0.6rem; - background-color: ${({ theme, $schedule, key }) => - $schedule === key ? theme.colors.gray_800 : "initial"}; - - /* 그냥 눌렀을 때 색깔 변경되는거 내일 하자......... */ border-bottom: 1px solid ${({ theme }) => theme.colors.gray_700}; `; diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx index b6e2482f..8a51c1d8 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx @@ -4,8 +4,6 @@ import * as S from "./NarrowDropDown.styled"; interface DropdownProps { children: ReactNode; totalScheduleCount: number; - schedule: number; - payment?: boolean | undefined; setSchedule?: (param: number) => void; setPayment?: (param: boolean) => void; } @@ -13,8 +11,6 @@ interface DropdownProps { const NarrowDropDown = ({ children, totalScheduleCount, - schedule, - payment, setSchedule, setPayment, }: DropdownProps) => { @@ -33,12 +29,7 @@ const NarrowDropDown = ({ setSchedule?.(i); }; items.push( - + {i}차 ); @@ -53,22 +44,12 @@ const NarrowDropDown = ({ }; items.push( - + 미입금 ); items.push( - + 입금완료 ); From 65634221d0af122b4d5052df5095065f847b9f7b Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Wed, 10 Jul 2024 17:35:19 +0900 Subject: [PATCH 12/60] =?UTF-8?q?fix:=20dropdown=20=ED=95=98=EC=9C=84?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EC=84=A0=ED=83=9D=ED=95=A0=EB=95=8C?= =?UTF-8?q?=EB=A7=88=EB=8B=A4=20=EC=83=81=EC=9C=84=20=EB=A9=94=EB=89=B4?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=A6=84=20=EC=9E=90=EC=B2=B4=EA=B0=80=20?= =?UTF-8?q?=EB=B3=80=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ticketholderlist/TicketHolderList.tsx | 14 ++++++++++++-- .../narrowDropDown/NarrowDropDown.styled.ts | 3 +++ .../components/narrowDropDown/NarrowDropDown.tsx | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index fceaa457..d6cec50c 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -34,10 +34,20 @@ const TicketHolderList = () => { {/*set 함수 직접 넘기는 거 안좋다고 했지만, 내부에서 감싸야 하므로 넘김 */} - + 모든 회차 - + 입금 상태 diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts index 0629fd68..4fa7f9b3 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts @@ -10,6 +10,7 @@ export const DropdownButton = styled.button` flex-shrink: 0; gap: 0.6rem; align-items: center; + min-width: 9.3rem; height: 4rem; padding: 0.8rem 0.8rem 0.8rem 1.2rem; @@ -21,6 +22,8 @@ export const DropDownButtonContent = styled.div` display: flex; gap: 0.4rem; align-items: center; + justify-content: space-between; + width: 100%; `; export const ButtonContentSpan = styled.span` diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx index 8a51c1d8..e40aa58d 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx @@ -4,6 +4,8 @@ import * as S from "./NarrowDropDown.styled"; interface DropdownProps { children: ReactNode; totalScheduleCount: number; + schedule: number; + payment: boolean | undefined; setSchedule?: (param: number) => void; setPayment?: (param: boolean) => void; } @@ -11,6 +13,8 @@ interface DropdownProps { const NarrowDropDown = ({ children, totalScheduleCount, + schedule, + payment, setSchedule, setPayment, }: DropdownProps) => { @@ -63,11 +67,20 @@ const NarrowDropDown = ({ //필터링은 회차 번호(scheduleNumber : FIRST, SECOND, THIRD), 입금 완료 여부는 paymentStatus에 따라 나뉠거임 // + let changedChildren; + if (children === "입금 상태" && payment !== undefined) { + changedChildren = payment ? "입금완료" : "미입금"; + } else if (children === "모든 회차" && schedule !== 0) { + changedChildren = `${schedule}차`; + } + return ( - {children} + + {changedChildren === undefined ? children : changedChildren} + From d09d8c5ef8b9c6f5a003ea3c78d88380354f7c45 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Wed, 10 Jul 2024 18:57:59 +0900 Subject: [PATCH 13/60] =?UTF-8?q?feat:=20=EB=93=9C=EB=A1=AD=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=20=EB=A9=94=EB=89=B4=20=EB=B7=B0=20=EB=93=9C=EB=94=94?= =?UTF-8?q?=EC=96=B4=20=EC=99=84=EC=84=B1=20(=ED=95=84=ED=84=B0=EB=A7=81?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=EB=A7=8C=20=EB=82=98=EC=A4=91=EC=97=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=98=EB=A9=B4=20=EB=90=A8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../narrowDropDown/NarrowDropDown.styled.ts | 15 +++++-- .../narrowDropDown/NarrowDropDown.tsx | 39 ++++++++++++++++--- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts index 4fa7f9b3..eb433cfb 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.styled.ts @@ -5,7 +5,7 @@ export const DropdownWrapper = styled.div` position: relative; `; -export const DropdownButton = styled.button` +export const DropdownButton = styled.button<{ $isChoosed: boolean }>` display: inline-flex; flex-shrink: 0; gap: 0.6rem; @@ -14,7 +14,8 @@ export const DropdownButton = styled.button` height: 4rem; padding: 0.8rem 0.8rem 0.8rem 1.2rem; - border: 1px solid ${({ theme }) => theme.colors.gray_400}; + border: 1px solid + ${({ theme, $isChoosed }) => ($isChoosed ? theme.colors.gray_0 : theme.colors.gray_700)}; border-radius: 0.4rem; `; @@ -82,7 +83,9 @@ export const DropdownContentButton = styled.button` border-bottom: 1px solid ${({ theme }) => theme.colors.gray_700}; `; -export const DropdownContentText = styled.span` +export const DropdownContentText = styled.span<{ + $selected: boolean; +}>` display: flex; gap: 0.4rem; align-items: center; @@ -91,6 +94,12 @@ export const DropdownContentText = styled.span` color: ${({ theme }) => theme.colors.gray_0}; ${({ theme }) => theme.fonts["body2-normal-medi"]}; + + ${({ $selected }) => + $selected && + css` + color: ${({ theme }) => theme.colors.pink_400}; + `} `; export const DropdownItem = styled.a` diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx index e40aa58d..34467910 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx @@ -7,7 +7,7 @@ interface DropdownProps { schedule: number; payment: boolean | undefined; setSchedule?: (param: number) => void; - setPayment?: (param: boolean) => void; + setPayment?: (param: boolean | undefined) => void; } const NarrowDropDown = ({ @@ -19,6 +19,7 @@ const NarrowDropDown = ({ setPayment, }: DropdownProps) => { const [showDropdown, setShowDropdown] = useState(false); + const [isOneChoosed, setIsOneChoosed] = useState(false); const handleToggle = () => { setShowDropdown(!showDropdown); @@ -28,33 +29,61 @@ const NarrowDropDown = ({ const items = []; const childrenString = childrenNode?.toString(); if (childrenString === "모든 회차") { + const handleScheduleAll = () => { + setSchedule?.(0); + setIsOneChoosed(false); + setShowDropdown(false); + }; + items.push( + + 전체 + + ); for (let i = 1; i <= count; i++) { const handleSchedule = () => { setSchedule?.(i); + setIsOneChoosed(true); + setShowDropdown(false); }; items.push( - {i}차 + {i}차 ); } } else if (childrenString === "입금 상태") { + const handlePaymentUndefined = () => { + setPayment?.(undefined); + setIsOneChoosed(false); + setShowDropdown(false); + }; + const handlePaymentFalse = () => { setPayment?.(false); + setIsOneChoosed(true); + setShowDropdown(false); }; const handlePaymentTrue = () => { setPayment?.(true); + setIsOneChoosed(true); + setShowDropdown(false); }; + items.push( + + 전체 + + ); + items.push( - 미입금 + 미입금 ); items.push( - 입금완료 + 입금완료 ); } @@ -76,7 +105,7 @@ const NarrowDropDown = ({ return ( - + {changedChildren === undefined ? children : changedChildren} From 7db50a70a7749242f6008cdae4f95f905f125658 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Wed, 10 Jul 2024 21:32:32 +0900 Subject: [PATCH 14/60] =?UTF-8?q?feat:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=9A=A9=20=EC=83=81=EC=88=98=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20prop=EC=9C=BC=EB=A1=9C=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=ED=95=B4=EC=84=9C=20ManagerCard=EB=A5=BC=20=EC=A0=81?= =?UTF-8?q?=EC=A0=88=ED=9E=88=20=EB=B0=98=EB=B3=B5=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ticketholderlist/TicketHolderList.tsx | 22 +++- .../components/managecard/ManagerCard.tsx | 25 ----- .../ManagerCard.styled.ts | 29 +++++ .../components/managercard/ManagerCard.tsx | 79 ++++++++++++++ .../narrowDropDown/NarrowDropDown.tsx | 4 +- .../constants/ticketholderlist.ts | 101 ++++++++++++++++++ 6 files changed, 230 insertions(+), 30 deletions(-) delete mode 100644 src/pages/ticketholderlist/components/managecard/ManagerCard.tsx rename src/pages/ticketholderlist/components/{managecard => managercard}/ManagerCard.styled.ts (73%) create mode 100644 src/pages/ticketholderlist/components/managercard/ManagerCard.tsx create mode 100644 src/pages/ticketholderlist/constants/ticketholderlist.ts diff --git a/src/pages/ticketholderlist/TicketHolderList.tsx b/src/pages/ticketholderlist/TicketHolderList.tsx index d6cec50c..3fdf23e7 100644 --- a/src/pages/ticketholderlist/TicketHolderList.tsx +++ b/src/pages/ticketholderlist/TicketHolderList.tsx @@ -1,9 +1,10 @@ import Button from "@components/commons/button/Button"; import { useState } from "react"; import Banner from "./components/banner/Banner"; -import ManagerCard from "./components/managecard/ManagerCard"; +import ManagerCard from "./components/managercard/ManagerCard"; import NarrowDropDown from "./components/narrowdropdown/NarrowDropDown"; import eximg from "./constants/silkagel.png"; +import { RESPONSE_TICKETHOLDER } from "./constants/ticketholderlist"; import * as S from "./TicketHolderList.styled"; const TicketHolderList = () => { @@ -25,7 +26,8 @@ const TicketHolderList = () => { setPaid((prop) => !prop); }; - const count = 5; //나중에 api로 받아와서 반영해야함. state로 바꿀 필요 있을까? + const count = RESPONSE_TICKETHOLDER.data.totalScheduleCount; //나중에 api로 받아와서 반영해야함. state로 바꿀 필요 있을까? + const response_data = RESPONSE_TICKETHOLDER.data.bookingList; // 나중에 state로 관리해주기 return ( <> @@ -73,9 +75,23 @@ const TicketHolderList = () => { )} - + {response_data.map((obj, index) => ( + + ))} + {/* {`현재 눌린 회차 번호 : ${schedule}`} {`현재 눌린 지불 여부 : ${payment}`} + */} + diff --git a/src/pages/ticketholderlist/components/managecard/ManagerCard.tsx b/src/pages/ticketholderlist/components/managecard/ManagerCard.tsx deleted file mode 100644 index 51fb7bf5..00000000 --- a/src/pages/ticketholderlist/components/managecard/ManagerCard.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as S from "./ManagerCard.styled"; - -const ManagerCard = ({ - isPaid, - isDetail, - setDetail, -}: { - isPaid: boolean; - isDetail: boolean; - setDetail: () => void; -}) => { - return ( - - - - - {isPaid ? : } - {isPaid ? "입금 완료" : "미입금"} - - - - ); -}; - -export default ManagerCard; diff --git a/src/pages/ticketholderlist/components/managecard/ManagerCard.styled.ts b/src/pages/ticketholderlist/components/managercard/ManagerCard.styled.ts similarity index 73% rename from src/pages/ticketholderlist/components/managecard/ManagerCard.styled.ts rename to src/pages/ticketholderlist/components/managercard/ManagerCard.styled.ts index 58284221..e536d34a 100644 --- a/src/pages/ticketholderlist/components/managecard/ManagerCard.styled.ts +++ b/src/pages/ticketholderlist/components/managercard/ManagerCard.styled.ts @@ -25,6 +25,35 @@ export const ManagerCardLayout = styled.div<{ $isDetail: boolean }>` border-radius: 6px; `; +export const ManagerCardBox = styled.div` + display: flex; + flex-direction: column; + gap: 0.4rem; + align-items: flex-start; + align-self: stretch; +`; + +export const ManagerCardTextBox = styled.div` + display: flex; + gap: 2.2rem; + align-items: center; + justify-content: space-between; +`; + +export const ManagerCardTextTitle = styled.span` + width: 3.7rem; + + color: ${({ theme }) => theme.colors.gray_400}; + ${({ theme }) => theme.fonts["body2-normal-medi"]}; +`; + +export const ManagerCardTextContent = styled.span` + width: 17.3rem; + + color: ${({ theme }) => theme.colors.white}; + ${({ theme }) => theme.fonts["body2-normal-medi"]}; +`; + export const ManagerCardRadioLayout = styled.div<{ $isDetail: boolean; $isPaid: boolean }>` display: flex; flex-shrink: 0; diff --git a/src/pages/ticketholderlist/components/managercard/ManagerCard.tsx b/src/pages/ticketholderlist/components/managercard/ManagerCard.tsx new file mode 100644 index 00000000..e21567a6 --- /dev/null +++ b/src/pages/ticketholderlist/components/managercard/ManagerCard.tsx @@ -0,0 +1,79 @@ +import * as S from "./ManagerCard.styled"; + +const ManagerCard = ({ + isPaid, + isDetail, + setDetail, + bookername, + purchaseTicketeCount, + scheduleNumber, + bookerPhoneNumber, + createAt, +}: { + isPaid: boolean; + isDetail: boolean; + setDetail: () => void; + bookername: string; + purchaseTicketeCount: number; + scheduleNumber: string; + bookerPhoneNumber: string; + createAt: string; +}) => { + const date = createAt.split("T")[0]; + const formattedDate = date.replace(/-/g, "."); + const convertingNumber = (scheduleNumberrr: string) => { + switch (scheduleNumberrr) { + case "FIRST": + return 1; + break; + case "SECOND": + return 2; + break; + case "THIRD": + return 3; + break; + default: + console.log("error"); + } + }; + return ( + + + + + 이름 + {bookername} + + + 매수 + {`${purchaseTicketeCount}매`} + + {isDetail && ( + <> + + 회차 + {`${convertingNumber(scheduleNumber)}회차`} + + + 연락처 + {bookerPhoneNumber} + + + 예매일 + {formattedDate} + + + )} + + + + + {isPaid ? : } + {isPaid ? "입금 완료" : "미입금"} + + + + ); +}; + +export default ManagerCard; diff --git a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx index 34467910..1fdf48dd 100644 --- a/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx +++ b/src/pages/ticketholderlist/components/narrowDropDown/NarrowDropDown.tsx @@ -35,7 +35,7 @@ const NarrowDropDown = ({ setShowDropdown(false); }; items.push( - + 전체 ); @@ -71,7 +71,7 @@ const NarrowDropDown = ({ }; items.push( - + 전체 ); diff --git a/src/pages/ticketholderlist/constants/ticketholderlist.ts b/src/pages/ticketholderlist/constants/ticketholderlist.ts new file mode 100644 index 00000000..9f17fc35 --- /dev/null +++ b/src/pages/ticketholderlist/constants/ticketholderlist.ts @@ -0,0 +1,101 @@ +export interface BookingListProps { + bookingId: number; + bookerName: string; + bookerPhoneNumber: string; + scheduleId: number; + purchaseTicketCount: number; + createdAt: string; + isPaymentCompleted: boolean; + scheduleNumber: string; +} + +export interface TicketHolderListProps { + performanceTitle: string; + isBooking: boolean; + totalScheduleCount: number; + bookingList: BookingListProps[]; +} + +export interface TicketHolderListDataProps { + data: TicketHolderListProps; +} + +export const RESPONSE_TICKETHOLDER = { + data: { + performanceTitle: "비트밴드 정기공연", + isBooking: true, + totalScheduleCount: 3, + bookingList: [ + { + bookingId: 1, + bookerName: "황혜린", + bookerPhoneNumber: "010-1234-5678", + scheduleId: 2, //scheduleId는 테이블의 특성에 따라 존재하는 것 + purchaseTicketCount: 3, + createdAt: "2024-07-07T12:34:56.789Z", + isPaymentCompleted: true, + scheduleNumber: "SECOND", + }, + { + bookingId: 2, + bookerName: "이동훈", + bookerPhoneNumber: "010-1234-0000", + scheduleId: 1, + purchaseTicketCount: 2, + createdAt: "2024-07-08T12:34:56.789Z", + isPaymentCompleted: false, + scheduleNumber: "FIRST", + }, + { + bookingId: 3, + bookerName: "공준혁", + bookerPhoneNumber: "010-1234-9999", + scheduleId: 1, + purchaseTicketCount: 9, + createdAt: "2024-07-08T12:34:56.789Z", + isPaymentCompleted: true, + scheduleNumber: "THIRD", + }, + { + bookingId: 4, + bookerName: "정도영", + bookerPhoneNumber: "010-1234-0000", + scheduleId: 3, + purchaseTicketCount: 4, + createdAt: "2024-07-11T12:34:56.789Z", + isPaymentCompleted: false, + scheduleNumber: "THIRD", + }, + { + bookingId: 5, + bookerName: "김채현", + bookerPhoneNumber: "010-1234-0000", + scheduleId: 3, + purchaseTicketCount: 6, + createdAt: "2024-07-15T12:34:56.789Z", + isPaymentCompleted: false, + scheduleNumber: "THIRD", + }, + { + bookingId: 6, + bookerName: "윤신지", + bookerPhoneNumber: "010-1234-0000", + scheduleId: 3, + purchaseTicketCount: 2, + createdAt: "2024-07-03T12:34:56.789Z", + isPaymentCompleted: true, + scheduleNumber: "THIRD", + }, + { + bookingId: 7, + bookerName: "익명인", + bookerPhoneNumber: "010-1000-0000", + scheduleId: 1, + purchaseTicketCount: 2, + createdAt: "2024-07-08T12:34:56.789Z", + isPaymentCompleted: true, + scheduleNumber: "SECOND", + }, + ], + }, +}; From 1e406016e015f184c15bbbd2ae763777884fea77 Mon Sep 17 00:00:00 2001 From: jerry Date: Wed, 10 Jul 2024 22:57:20 +0900 Subject: [PATCH 15/60] =?UTF-8?q?feat:=20=EB=8D=94=EB=AF=B8=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/book/constants/dummy.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/pages/book/constants/dummy.ts diff --git a/src/pages/book/constants/dummy.ts b/src/pages/book/constants/dummy.ts new file mode 100644 index 00000000..6b05abe6 --- /dev/null +++ b/src/pages/book/constants/dummy.ts @@ -0,0 +1,26 @@ +import exImg from "src/pages/MyRegisterdShow/constants/silkagel.png"; + +export const BOOK_DETAIL_INFO = { + performanceId: 1, + performanceTitle: "비트밴드 정기공연", + ticketPrice: "5000", + genre: "BAND", + posterImage: exImg, + performanceVenue: "홍대상상마당", + performancePeriod: "2023.12.28~2023.12.29", + performanceTeamName: "비트밴드", + scheduleList: [ + { + scheduleId: 1, + performanceDate: "2023-12-28T19:30:00", + availableTicketCount: 100, + scheduleNumber: "FIRST", + }, + { + scheduleId: 2, + performanceDate: "2023-12-29T19:30:00", + availableTicketCount: 90, + scheduleNumber: "SECOND", + }, + ], +}; From 56035c315e4813a16281fc79c6b73e93f630656c Mon Sep 17 00:00:00 2001 From: jerry Date: Wed, 10 Jul 2024 23:59:08 +0900 Subject: [PATCH 16/60] =?UTF-8?q?feat:=20Info=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/book/Book.tsx | 25 +++++++- src/pages/book/components/info/Info.styled.ts | 59 +++++++++++++++++++ src/pages/book/components/info/Info.tsx | 41 +++++++++++++ 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/pages/book/components/info/Info.styled.ts create mode 100644 src/pages/book/components/info/Info.tsx diff --git a/src/pages/book/Book.tsx b/src/pages/book/Book.tsx index 8a162f92..2e3c1144 100644 --- a/src/pages/book/Book.tsx +++ b/src/pages/book/Book.tsx @@ -1,5 +1,28 @@ +import { useState } from "react"; +import styled from "styled-components"; +import Info from "./components/info/Info"; +import { BOOK_DETAIL_INFO } from "./constants/dummy"; + const Book = () => { - return
Book
; + const [detail, setDetail] = useState(BOOK_DETAIL_INFO); + + return ( + + + + ); }; export default Book; + +const ContentWrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; +`; diff --git a/src/pages/book/components/info/Info.styled.ts b/src/pages/book/components/info/Info.styled.ts new file mode 100644 index 00000000..27ffc0ea --- /dev/null +++ b/src/pages/book/components/info/Info.styled.ts @@ -0,0 +1,59 @@ +import styled from "styled-components"; + +export const InfoContainer = styled.section` + display: flex; + flex-direction: column; + gap: 2rem; + width: 32.7rem; + margin-top: 1.6rem; +`; + +export const InfoTop = styled.div` + display: flex; +`; + +export const InfoPoster = styled.img<{ $imgsrc: string }>` + width: 9.5rem; + height: 12.8rem; + margin-right: 1.4rem; + + background-image: url(${({ $imgsrc }) => $imgsrc}); + background-size: 100% 100%; + border-radius: 4px; +`; + +export const InfoTextBox = styled.div` + display: flex; + flex-direction: column; +`; + +export const InfoType = styled.p` + color: ${({ theme }) => theme.colors.gray_500}; + ${({ theme }) => theme.fonts["caption1-semi"]}; +`; + +export const InfoTitle = styled.h1` + color: ${({ theme }) => theme.colors.white}; + + ${({ theme }) => theme.fonts["body1-normal-semi"]}; +`; + +export const InfoTeamText = styled.span` + margin-right: 0.6rem; + + color: ${({ theme }) => theme.colors.gray_400}; + + ${({ theme }) => theme.fonts["body2-normal-medi"]}; +`; + +export const InfoTeamName = styled.span` + color: ${({ theme }) => theme.colors.white}; + + ${({ theme }) => theme.fonts["body2-normal-medi"]}; +`; + +export const InfoBottom = styled.div` + display: flex; + flex-direction: column; + gap: 0.8rem; +`; diff --git a/src/pages/book/components/info/Info.tsx b/src/pages/book/components/info/Info.tsx new file mode 100644 index 00000000..b77e1746 --- /dev/null +++ b/src/pages/book/components/info/Info.tsx @@ -0,0 +1,41 @@ +import Spacing from "@components/commons/spacing/Spacing"; +import * as S from "./Info.styled"; + +interface InfoProps { + genre: string; + title: string; + teamName: string; + venue: string; + period: string; +} + +const Info = ({ genre, title, teamName, venue, period }: InfoProps) => { + return ( + + + + + + {genre} + + {title} + +
+ 공연진 + {teamName} +
+
+
+ + + {/* TODO: 변경 */} + {/* } text={venue} /> */} + {venue} + {/* } text={period} /> */} + {period} + +
+ ); +}; + +export default Info; From f04285dff3069860aa73375b103fbb1209558b83 Mon Sep 17 00:00:00 2001 From: imddoy Date: Thu, 11 Jul 2024 00:59:25 +0900 Subject: [PATCH 17/60] =?UTF-8?q?chore:=20=EC=99=84=EB=A3=8C=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 ++ src/pages/register/RegisterCompolete.tsx | 5 ++++ src/routes/Router.tsx | 1 + yarn.lock | 36 +++++++++++++++++++++++- 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/pages/register/RegisterCompolete.tsx diff --git a/package.json b/package.json index e106dcd4..a3088a5a 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,12 @@ }, "dependencies": { "jotai": "^2.8.4", + "lottie-react": "^2.4.0", "postcss": "^8.4.38", "postcss-scss": "^4.0.9", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-lottie-player": "^2.0.0", "react-router-dom": "^6.24.0", "shelljs": "^0.8.5", "styled-components": "^6.1.11", diff --git a/src/pages/register/RegisterCompolete.tsx b/src/pages/register/RegisterCompolete.tsx new file mode 100644 index 00000000..f771662b --- /dev/null +++ b/src/pages/register/RegisterCompolete.tsx @@ -0,0 +1,5 @@ +const RegisterCompolete = () => { + return
RegisterCompolete
; +}; + +export default RegisterCompolete; diff --git a/src/routes/Router.tsx b/src/routes/Router.tsx index bd22329d..df613cd7 100644 --- a/src/routes/Router.tsx +++ b/src/routes/Router.tsx @@ -20,6 +20,7 @@ const router = createBrowserRouter([ { path: "lookup", element: }, { path: "testpage", element: }, { path: "register", element: }, + { path: "register-complete", element: }, { path: "book", element: }, { path: "manage", element: }, { path: "myregisteredshow", element: }, diff --git a/yarn.lock b/yarn.lock index 1e55cbd8..a5dc06c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5448,6 +5448,7 @@ __metadata: husky: "npm:^8.0.0" jotai: "npm:^2.8.4" lint-staged: "npm:^15.2.7" + lottie-react: "npm:^2.4.0" postcss: "npm:^8.4.38" postcss-scss: "npm:^4.0.9" postcss-styled-syntax: "npm:^0.6.4" @@ -5455,6 +5456,7 @@ __metadata: prettier-linter-helpers: "npm:^1.0.0" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" + react-lottie-player: "npm:^2.0.0" react-router-dom: "npm:^6.24.0" shelljs: "npm:^0.8.5" storybook: "npm:^8.1.11" @@ -9427,6 +9429,25 @@ __metadata: languageName: node linkType: hard +"lottie-react@npm:^2.4.0": + version: 2.4.0 + resolution: "lottie-react@npm:2.4.0" + dependencies: + lottie-web: "npm:^5.10.2" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/5c0ef3f1832b21232fe6826cc021cd90bb0e3c9d63f1047031ce77a0992092f8712b6f3a6aeeaa0f410d918ca557df160b1c776399f69b498c560273767befe0 + languageName: node + linkType: hard + +"lottie-web@npm:^5.10.2, lottie-web@npm:^5.12.2": + version: 5.12.2 + resolution: "lottie-web@npm:5.12.2" + checksum: 10c0/0aeaf631b10a76afd025df70c2a1486543530708e07a316946c08e55891dac483ffbaf2bf3648ae0b9c54c733118a0a086fd150aa76f7848606214c67ad72c30 + languageName: node + linkType: hard + "loupe@npm:^2.3.6, loupe@npm:^2.3.7": version: 2.3.7 resolution: "loupe@npm:2.3.7" @@ -10939,6 +10960,19 @@ __metadata: languageName: node linkType: hard +"react-lottie-player@npm:^2.0.0": + version: 2.0.0 + resolution: "react-lottie-player@npm:2.0.0" + dependencies: + fast-deep-equal: "npm:^3.1.3" + lottie-web: "npm:^5.12.2" + rfdc: "npm:^1.3.0" + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/a48361f441bf4230e85a40e803e1b747d50db283f851e34ec593dcc70faf87096e725cdc5f2f938c0552a0e2a5cbafb0aabe8fdbe508444fcaf1e265d5574057 + languageName: node + linkType: hard + "react-remove-scroll-bar@npm:^2.3.4": version: 2.3.6 resolution: "react-remove-scroll-bar@npm:2.3.6" @@ -11362,7 +11396,7 @@ __metadata: languageName: node linkType: hard -"rfdc@npm:^1.4.1": +"rfdc@npm:^1.3.0, rfdc@npm:^1.4.1": version: 1.4.1 resolution: "rfdc@npm:1.4.1" checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7 From 6235615c7f690078a13589e585c4c436198010b5 Mon Sep 17 00:00:00 2001 From: jerry Date: Thu, 11 Jul 2024 01:14:38 +0900 Subject: [PATCH 18/60] =?UTF-8?q?feat:=20=EA=B8=B0=EB=B3=B8=20=ED=8F=B0?= =?UTF-8?q?=ED=8A=B8=20=EC=83=89=EC=83=81=20=ED=9D=B0=EC=83=89=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/global.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/styles/global.ts b/src/styles/global.ts index 30e76f15..44648ba2 100644 --- a/src/styles/global.ts +++ b/src/styles/global.ts @@ -60,6 +60,8 @@ const global = createGlobalStyle` margin: 0 auto; overflow-x: hidden; + color: ${({ theme }) => theme.colors.white}; + background-color: ${({ theme }) => theme.colors.gray_900}; } From eecd1e173f54ce744a7bec155a2ab8a779e1d9f5 Mon Sep 17 00:00:00 2001 From: jerry Date: Thu, 11 Jul 2024 01:44:58 +0900 Subject: [PATCH 19/60] =?UTF-8?q?feat:=20Count=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/book/Book.tsx | 21 ++++++++++ .../book/components/count/Count.styled.ts | 42 +++++++++++++++++++ src/pages/book/components/count/Count.tsx | 29 +++++++++++++ src/pages/book/components/info/Info.styled.ts | 2 +- src/pages/book/constants/dummy.ts | 2 +- 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/pages/book/components/count/Count.styled.ts create mode 100644 src/pages/book/components/count/Count.tsx diff --git a/src/pages/book/Book.tsx b/src/pages/book/Book.tsx index 2e3c1144..07eaad4a 100644 --- a/src/pages/book/Book.tsx +++ b/src/pages/book/Book.tsx @@ -1,11 +1,23 @@ import { useState } from "react"; import styled from "styled-components"; +import Count from "./components/count/Count"; import Info from "./components/info/Info"; +import Select from "./components/select/Select"; import { BOOK_DETAIL_INFO } from "./constants/dummy"; const Book = () => { const [detail, setDetail] = useState(BOOK_DETAIL_INFO); + const [round, setRound] = useState(1); + + const onMinusClick = () => { + setRound((prev) => prev - 1); + }; + + const onPlusClick = () => { + setRound((prev) => prev + 1); + }; + return ( { venue={detail.performanceVenue} period={detail.performancePeriod} /> + + onChange(value)} /> + + + ); +}; + +export default RadioButton; + +const Label = styled.label<{ checked: boolean }>` + display: flex; + align-items: center; + justify-content: space-between; + padding: 1.2rem 1rem 1.2rem 1.6rem; + + background-color: ${({ theme }) => theme.colors.gray_800}; + cursor: pointer; + border: 2px solid transparent; + border-radius: 6px; + + ${({ checked, theme }) => + checked && + ` + background-color: ${theme.colors.gray_800}; + border: 2px solid ${theme.colors.pink_400}; + `} + + &:hover { + background-color: ${({ theme }) => theme.colors.gray_800}; + border-color: ${({ theme }) => theme.colors.pink_400}; + } +`; + +const Input = styled.input` + display: none; +`; + +const DateTimeDivider = styled.div` + display: inline-block; + width: 1px; + height: 12px; + margin: 0 1rem; + + background-color: ${({ theme }) => theme.colors.gray_500}; +`; + +const Text = styled.span` + color: ${({ theme }) => theme.colors.gray_0}; + ${({ theme }) => theme.fonts["body1-normal-medi"]}; +`; + +const CustomRadio = styled.span<{ checked: boolean }>` + position: relative; + width: 2rem; + height: 2rem; + padding-right: 0.6rem; + ${({ theme, checked }) => + checked + ? `border: 6px solid ${theme.colors.pink_400}` + : `border: 2px solid ${theme.colors.gray_300}`}; + + border-radius: 100%; + + &::after { + position: absolute; + top: 50%; + left: 50%; + display: ${({ checked }) => (checked ? "block" : "none")}; + width: 1rem; + height: 1rem; + + background-color: ${({ theme }) => theme.colors.white}; + transform: translate(-50%, -50%); + border-radius: 50%; + + content: ""; + } +`; diff --git a/src/pages/book/components/select/RadioGroup.tsx b/src/pages/book/components/select/RadioGroup.tsx new file mode 100644 index 00000000..f89e0087 --- /dev/null +++ b/src/pages/book/components/select/RadioGroup.tsx @@ -0,0 +1,27 @@ +import styled from "styled-components"; +import RadioButton from "./RadioButton"; +import { SelectProps } from "./Select"; + +const RadioGroup = ({ selectedValue, handleRadioChange, scheduleList }: SelectProps) => { + return ( + + {scheduleList.map((schedule, i) => ( + + ))} + + ); +}; + +export default RadioGroup; + +export const RadioGroupWrapper = styled.section` + display: flex; + flex-direction: column; + gap: 1.2rem; +`; diff --git a/src/pages/book/components/select/Select.styled.ts b/src/pages/book/components/select/Select.styled.ts new file mode 100644 index 00000000..e9f71ea8 --- /dev/null +++ b/src/pages/book/components/select/Select.styled.ts @@ -0,0 +1,24 @@ +import styled from "styled-components"; + +export const Wrapper = styled.section` + display: flex; + flex-direction: column; + gap: 1.4rem; + width: 100%; + padding: 2.4rem 0; + + border-bottom: 1px solid ${({ theme }) => theme.colors.gray_800}; +`; + +export const Container = styled.div` + display: flex; + justify-content: space-between; + width: 100%; +`; + +export const Title = styled.h2` + margin-bottom: 0.2rem; + + color: ${({ theme }) => theme.colors.white}; + ${({ theme }) => theme.fonts.heading4}; +`; diff --git a/src/pages/book/components/select/Select.tsx b/src/pages/book/components/select/Select.tsx new file mode 100644 index 00000000..53fa0c3b --- /dev/null +++ b/src/pages/book/components/select/Select.tsx @@ -0,0 +1,28 @@ +import RadioGroup from "./RadioGroup"; +import * as S from "./Select.styled"; + +export interface SelectProps { + selectedValue: number; + handleRadioChange: (value: number) => void; + scheduleList: { + scheduleId: number; + performanceDate: string; + availableTicketCount: number; + scheduleNumber: string; + }[]; +} + +const Select = ({ selectedValue, handleRadioChange, scheduleList }: SelectProps) => { + return ( + + 회차 선택 + + + ); +}; + +export default Select; From fd28f493e8051ecfb8ab596faef501710049ee8c Mon Sep 17 00:00:00 2001 From: jerry Date: Fri, 12 Jul 2024 00:59:11 +0900 Subject: [PATCH 42/60] =?UTF-8?q?feat:=20Divider=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/book/Book.tsx | 13 +++++++++++++ src/pages/book/components/info/Info.tsx | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/pages/book/Book.tsx b/src/pages/book/Book.tsx index e392e726..94eb2ec4 100644 --- a/src/pages/book/Book.tsx +++ b/src/pages/book/Book.tsx @@ -89,6 +89,8 @@ const Book = () => { venue={detail.performanceVenue} period={detail.performancePeriod} /> + + onChange(value)} /> - + {isSoldOut ? ( + 매진 + ) : ( + <> + onChange(value)} /> + + + )} ); }; export default RadioButton; -const Label = styled.label<{ checked: boolean }>` +const Label = styled.label<{ checked: boolean; $isSoldOut: boolean }>` display: flex; align-items: center; justify-content: space-between; padding: 1.2rem 1rem 1.2rem 1.6rem; + ${({ $isSoldOut, theme }) => + $isSoldOut + ? ` + color: ${theme.colors.gray_600};` + : `color: ${theme.colors.gray_0}`}; + background-color: ${({ theme }) => theme.colors.gray_800}; cursor: pointer; border: 2px solid transparent; @@ -43,11 +55,6 @@ const Label = styled.label<{ checked: boolean }>` background-color: ${theme.colors.gray_800}; border: 2px solid ${theme.colors.pink_400}; `} - - &:hover { - background-color: ${({ theme }) => theme.colors.gray_800}; - border-color: ${({ theme }) => theme.colors.pink_400}; - } `; const Input = styled.input` @@ -64,7 +71,6 @@ const DateTimeDivider = styled.div` `; const Text = styled.span` - color: ${({ theme }) => theme.colors.gray_0}; ${({ theme }) => theme.fonts["body1-normal-medi"]}; `; @@ -95,3 +101,8 @@ const CustomRadio = styled.span<{ checked: boolean }>` content: ""; } `; + +const SoldOutText = styled.span` + color: ${({ theme }) => theme.colors.gray_600}; + ${({ theme }) => theme.fonts["body2-normal-semi"]}; +`; diff --git a/src/pages/book/components/select/RadioGroup.tsx b/src/pages/book/components/select/RadioGroup.tsx index f89e0087..3de53251 100644 --- a/src/pages/book/components/select/RadioGroup.tsx +++ b/src/pages/book/components/select/RadioGroup.tsx @@ -11,6 +11,7 @@ const RadioGroup = ({ selectedValue, handleRadioChange, scheduleList }: SelectPr label={schedule.performanceDate} value={schedule.scheduleId} checked={selectedValue === schedule.scheduleId} + isSoldOut={schedule.availableTicketCount === 0} onChange={handleRadioChange} /> ))} diff --git a/src/pages/book/constants/dummy.ts b/src/pages/book/constants/dummy.ts index f937a671..a38df027 100644 --- a/src/pages/book/constants/dummy.ts +++ b/src/pages/book/constants/dummy.ts @@ -11,7 +11,7 @@ export const BOOK_DETAIL_INFO = { { scheduleId: 1, performanceDate: "2023-12-28T19:30:00", - availableTicketCount: 100, + availableTicketCount: 0, scheduleNumber: "FIRST", }, { @@ -20,5 +20,11 @@ export const BOOK_DETAIL_INFO = { availableTicketCount: 4, scheduleNumber: "SECOND", }, + { + scheduleId: 3, + performanceDate: "2023-12-30T19:30:00", + availableTicketCount: 8, + scheduleNumber: "THIRD", + }, ], }; From 03ccfe262aaf3242828dff4b416936816679a9ee Mon Sep 17 00:00:00 2001 From: jerry Date: Fri, 12 Jul 2024 02:11:01 +0900 Subject: [PATCH 45/60] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=20=EC=98=88?= =?UTF-8?q?=EB=A7=A4=20=EC=9A=94=EC=B2=AD=20request=20=ED=98=95=EC=8B=9D?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EB=8F=84=EB=A1=9D=20formData=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/book/Book.tsx | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/pages/book/Book.tsx b/src/pages/book/Book.tsx index c715f047..9e5e18bb 100644 --- a/src/pages/book/Book.tsx +++ b/src/pages/book/Book.tsx @@ -15,12 +15,17 @@ import { BOOK_DETAIL_INFO } from "./constants/dummy"; const Book = () => { const { performanceId } = useParams<{ performanceId: string }>(); + // TODO: 회원/비회원 여부 + // navigate 할 때 state로 넘기기 ? + const isNonMember = true; + const [detail, setDetail] = useState(BOOK_DETAIL_INFO); const [selectedValue, setSelectedValue] = useState(); const [round, setRound] = useState(1); const [bookerInfo, setBookerInfo] = useState({ - name: "", - phoneNumber: "", + bookerName: "", + bookerPhoneNumber: "", + birthDate: "", }); const [isTermChecked, setIsTermChecked] = useState(false); const [isOpen, setIsOpen] = useState(false); @@ -63,17 +68,25 @@ const Book = () => { }; const handleClickBookRequst = () => { - // TODO: 티켓 매수 요청 get 요청 후, true 인 상태일 때 바텀 시트 열기 - const formData = { selectedValue, round, bookerInfo, isTermChecked }; + // TODO: 티켓 매수 요청 get 요청 후, true 인 상태이면, 바텀 시트 열기 + + const formData = { + scheduleId: performanceId, + selectedValue, + purchaseTicketCount: round, + ...bookerInfo, + totalPaymentAmount: detail.ticketPrice * round, + }; + console.log(formData); - // TODO: 예매하기 post 요청 + // TODO: 회원, 비회원 여부에 따라서 예매하기 post 요청 // TODO: 완료 페이지로 navigate }; useEffect(() => { - if (selectedValue && bookerInfo.name && bookerInfo.phoneNumber && isTermChecked) { + if (selectedValue && bookerInfo.bookerName && bookerInfo.bookerPhoneNumber && isTermChecked) { setActiveButton(true); } else { setActiveButton(false); @@ -106,7 +119,11 @@ const Book = () => { } /> - + - + { - + ); }; export default Book; - -const ContentWrapper = styled.div` - display: flex; - flex-direction: column; - align-items: center; - padding: 0 2.4rem; -`; - -const Divider = styled.div` - width: 375px; - height: 8px; - margin-top: 1.6rem; - - background: ${({ theme }) => theme.colors.gray_800}; - opacity: 0.6; - border: 1px s; -`; - -const FooterContainer = styled.div` - position: sticky; - bottom: 0; - padding: 2.4rem; - - background-color: ${({ theme }) => theme.colors.gray_900}; -`; diff --git a/src/pages/book/components/select/RadioButton.styled.ts b/src/pages/book/components/select/RadioButton.styled.ts new file mode 100644 index 00000000..6d39c789 --- /dev/null +++ b/src/pages/book/components/select/RadioButton.styled.ts @@ -0,0 +1,76 @@ +import styled from "styled-components"; + +export const Label = styled.label<{ checked: boolean; $isSoldOut: boolean }>` + display: flex; + align-items: center; + justify-content: space-between; + padding: 1.2rem 1rem 1.2rem 1.6rem; + + ${({ $isSoldOut, theme }) => + $isSoldOut + ? ` + color: ${theme.colors.gray_600};` + : `color: ${theme.colors.gray_0}`}; + + background-color: ${({ theme }) => theme.colors.gray_800}; + cursor: pointer; + border: 2px solid transparent; + border-radius: 6px; + + ${({ checked, theme }) => + checked && + ` + background-color: ${theme.colors.gray_800}; + border: 2px solid ${theme.colors.pink_400}; + `} +`; + +export const Input = styled.input` + display: none; +`; + +export const DateTimeDivider = styled.div` + display: inline-block; + width: 1px; + height: 12px; + margin: 0 1rem; + + background-color: ${({ theme }) => theme.colors.gray_500}; +`; + +export const Text = styled.span` + ${({ theme }) => theme.fonts["body1-normal-medi"]}; +`; + +export const CustomRadio = styled.span<{ checked: boolean }>` + position: relative; + width: 2rem; + height: 2rem; + padding-right: 0.6rem; + ${({ theme, checked }) => + checked + ? `border: 6px solid ${theme.colors.pink_400}` + : `border: 2px solid ${theme.colors.gray_300}`}; + + border-radius: 100%; + + &::after { + position: absolute; + top: 50%; + left: 50%; + display: ${({ checked }) => (checked ? "block" : "none")}; + width: 1rem; + height: 1rem; + + background-color: ${({ theme }) => theme.colors.white}; + transform: translate(-50%, -50%); + border-radius: 50%; + + content: ""; + } +`; + +export const SoldOutText = styled.span` + color: ${({ theme }) => theme.colors.gray_600}; + ${({ theme }) => theme.fonts["body2-normal-semi"]}; +`; diff --git a/src/pages/book/components/select/RadioButton.tsx b/src/pages/book/components/select/RadioButton.tsx index cec185ae..bc8e379c 100644 --- a/src/pages/book/components/select/RadioButton.tsx +++ b/src/pages/book/components/select/RadioButton.tsx @@ -1,4 +1,4 @@ -import styled from "styled-components"; +import * as S from "./RadioButton.styled"; interface RadioButtonProps { label: string; @@ -11,98 +11,23 @@ interface RadioButtonProps { const RadioButton = ({ label, value, checked, isSoldOut, onChange }: RadioButtonProps) => { const [date, time] = label.split("T"); return ( - + ); }; export default RadioButton; - -const Label = styled.label<{ checked: boolean; $isSoldOut: boolean }>` - display: flex; - align-items: center; - justify-content: space-between; - padding: 1.2rem 1rem 1.2rem 1.6rem; - - ${({ $isSoldOut, theme }) => - $isSoldOut - ? ` - color: ${theme.colors.gray_600};` - : `color: ${theme.colors.gray_0}`}; - - background-color: ${({ theme }) => theme.colors.gray_800}; - cursor: pointer; - border: 2px solid transparent; - border-radius: 6px; - - ${({ checked, theme }) => - checked && - ` - background-color: ${theme.colors.gray_800}; - border: 2px solid ${theme.colors.pink_400}; - `} -`; - -const Input = styled.input` - display: none; -`; - -const DateTimeDivider = styled.div` - display: inline-block; - width: 1px; - height: 12px; - margin: 0 1rem; - - background-color: ${({ theme }) => theme.colors.gray_500}; -`; - -const Text = styled.span` - ${({ theme }) => theme.fonts["body1-normal-medi"]}; -`; - -const CustomRadio = styled.span<{ checked: boolean }>` - position: relative; - width: 2rem; - height: 2rem; - padding-right: 0.6rem; - ${({ theme, checked }) => - checked - ? `border: 6px solid ${theme.colors.pink_400}` - : `border: 2px solid ${theme.colors.gray_300}`}; - - border-radius: 100%; - - &::after { - position: absolute; - top: 50%; - left: 50%; - display: ${({ checked }) => (checked ? "block" : "none")}; - width: 1rem; - height: 1rem; - - background-color: ${({ theme }) => theme.colors.white}; - transform: translate(-50%, -50%); - border-radius: 50%; - - content: ""; - } -`; - -const SoldOutText = styled.span` - color: ${({ theme }) => theme.colors.gray_600}; - ${({ theme }) => theme.fonts["body2-normal-semi"]}; -`; From 1470b6ba0de232272c48285ffb1fb10d33b3f292 Mon Sep 17 00:00:00 2001 From: jerry Date: Sun, 14 Jul 2024 22:49:46 +0900 Subject: [PATCH 60/60] =?UTF-8?q?fix:=20formData=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/book/typings/formData.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/book/typings/formData.ts b/src/pages/book/typings/formData.ts index fd796dfc..37c695b1 100644 --- a/src/pages/book/typings/formData.ts +++ b/src/pages/book/typings/formData.ts @@ -3,8 +3,8 @@ export interface FormData { selectedValue: number | undefined; purchaseTicketCount: number; totalPaymentAmount: number; - bookerName?: string; - bookerPhoneNumber?: string; + bookerName: string; + bookerPhoneNumber: string; // 비회원일 경우에만 추가될 속성 birthDate?: string; password?: string;