From f8855c2bf7b6990637134e1b56f64d8828ca7b35 Mon Sep 17 00:00:00 2001 From: "SeungJu, Lee" <84257439+SeungJL@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:59:59 +0900 Subject: [PATCH] Renew/store page (#245) --- components/Icons/ArrowIcons.tsx | 26 +- components/Icons/CircleIcons.tsx | 18 + components/Icons/DotIcons.tsx | 10 +- components/Icons/RuleIcon.tsx | 3 +- components/Icons/icons.tsx | 9 + components/atoms/ButtonWrapper.tsx | 1 + components/atoms/CountNum.tsx | 9 +- components/atoms/InfoCol.tsx | 36 ++ components/atoms/InfoColSkeleton.tsx | 22 + components/atoms/buttons/ArrowBackButton.tsx | 21 +- components/atoms/buttons/MenuButton.tsx | 5 +- components/layouts/Header.tsx | 19 +- components/molecules/navs/TabNav.tsx | 2 +- .../imageSliderType/ImageSliderBanner.tsx | 30 +- modals/Modals.tsx | 4 +- modals/RuleModal.tsx | 67 +-- modals/gather/GatherRuleModal.tsx | 59 ++- modals/pop-up/LastWeekAttendPopUp.tsx | 112 ++--- modals/promotion/PromotionRuleModal.tsx | 55 ++- modals/store/StoreApplyGiftModal.tsx | 16 +- modals/store/StoreGiftWinModal.tsx | 45 +- modals/store/StoreMembersModal.tsx | 120 ++++++ .../group/detail/GroupParticipation.tsx | 2 +- .../group/writing/QuestionBottomDrawer.tsx | 1 + pageTemplates/layout/Layout.tsx | 3 +- pages/board/index.tsx | 40 +- pages/group/[id]/index.tsx | 3 +- pages/group/index.tsx | 2 +- pages/group/writing/condition.tsx | 3 +- pages/ranking/index.tsx | 48 ++- pages/square/index.tsx | 71 ++-- pages/store/[id]/index.tsx | 194 +++++++-- pages/store/index.tsx | 354 ++++++++-------- pages/user/point.tsx | 4 +- storage/Store.tsx | 387 +++++++++--------- .../atoms/buttons/ArrowBackButton.stories.ts | 19 - theme.ts | 13 +- 37 files changed, 1038 insertions(+), 795 deletions(-) create mode 100644 components/atoms/InfoCol.tsx create mode 100644 components/atoms/InfoColSkeleton.tsx create mode 100644 modals/store/StoreMembersModal.tsx delete mode 100644 stories/atoms/buttons/ArrowBackButton.stories.ts diff --git a/components/Icons/ArrowIcons.tsx b/components/Icons/ArrowIcons.tsx index 320c79327..229a27a8c 100644 --- a/components/Icons/ArrowIcons.tsx +++ b/components/Icons/ArrowIcons.tsx @@ -1,11 +1,19 @@ -export function ShortArrowIcon({ dir }: { dir: "right" | "bottom" | "top" }) { +export function ShortArrowIcon({ + dir, + color = "mint", +}: { + color?: "mint" | "white"; + dir: "right" | "bottom" | "top" | "left"; +}) { + const colorText = color === "mint" ? "#00C2B3" : "white"; + return dir === "right" ? ( ) : dir === "bottom" ? ( @@ -14,7 +22,17 @@ export function ShortArrowIcon({ dir }: { dir: "right" | "bottom" | "top" }) { fillRule="evenodd" clipRule="evenodd" d="M1.95 4.3124C1.95 4.1399 2.0175 3.9674 2.145 3.8324C2.2715 3.70645 2.44274 3.63574 2.62125 3.63574C2.79976 3.63574 2.971 3.70645 3.0975 3.8324L6 6.7349L8.895 3.8324C9.0215 3.70645 9.19274 3.63574 9.37125 3.63574C9.54976 3.63574 9.721 3.70645 9.8475 3.8324C9.97345 3.9589 10.0442 4.13014 10.0442 4.30865C10.0442 4.48716 9.97345 4.6584 9.8475 4.7849L6.4725 8.1599C6.346 8.28585 6.17476 8.35656 5.99625 8.35656C5.81774 8.35656 5.6465 8.28585 5.52 8.1599L2.145 4.7849C2.0175 4.6574 1.95 4.4849 1.95 4.3124Z" - fill="#00C2B3" + fill={colorText} + /> + + ) : dir === "left" ? ( + + + ) : ( @@ -23,7 +41,7 @@ export function ShortArrowIcon({ dir }: { dir: "right" | "bottom" | "top" }) { fillRule="evenodd" clipRule="evenodd" d="M1.95 7.6876C1.95 7.8601 2.0175 8.0326 2.145 8.1676C2.2715 8.29355 2.44274 8.36426 2.62125 8.36426C2.79976 8.36426 2.971 8.29355 3.0975 8.1676L6 5.2651L8.895 8.1676C9.0215 8.29355 9.19274 8.36426 9.37125 8.36426C9.54976 8.36426 9.721 8.29355 9.8475 8.1676C9.97345 8.0411 10.0442 7.86986 10.0442 7.69135C10.0442 7.51284 9.97345 7.3416 9.8475 7.2151L6.4725 3.8401C6.346 3.71415 6.17476 3.64344 5.99625 3.64344C5.81774 3.64344 5.6465 3.71415 5.52 3.8401L2.145 7.2151C2.0175 7.3426 1.95 7.5151 1.95 7.6876Z" - fill="#00C2B3" + fill={colorText} /> ); diff --git a/components/Icons/CircleIcons.tsx b/components/Icons/CircleIcons.tsx index 53ce337e5..b925ec07e 100644 --- a/components/Icons/CircleIcons.tsx +++ b/components/Icons/CircleIcons.tsx @@ -131,3 +131,21 @@ export function XCircleIcon({ size }: { size: "sm" | "md" }) { ); } + +export function InfoCircleIcon() { + return + + + + + + + + + +} diff --git a/components/Icons/DotIcons.tsx b/components/Icons/DotIcons.tsx index b36dd4dc2..d074054a8 100644 --- a/components/Icons/DotIcons.tsx +++ b/components/Icons/DotIcons.tsx @@ -1,4 +1,10 @@ -export function EllipsisIcon({ size }: { size: "sm" | "md" }) { +export function EllipsisIcon({ + size, + color = "gray", +}: { + size: "sm" | "md"; + color?: "white" | "gray"; +}) { const width = size === "sm" ? 12 : 20; return ( ); diff --git a/components/Icons/RuleIcon.tsx b/components/Icons/RuleIcon.tsx index 1b3ddec5b..7acf77393 100644 --- a/components/Icons/RuleIcon.tsx +++ b/components/Icons/RuleIcon.tsx @@ -1,11 +1,12 @@ import styled from "styled-components"; import { IModal } from "../../types/components/modalTypes"; +import { InfoCircleIcon } from "./CircleIcons"; function RuleIcon({ setIsModal }: IModal) { return ( setIsModal(true)}> - + ); } diff --git a/components/Icons/icons.tsx b/components/Icons/icons.tsx index a6b0bc599..804aedc73 100644 --- a/components/Icons/icons.tsx +++ b/components/Icons/icons.tsx @@ -11,6 +11,15 @@ export function UserIcon() { ); } +export function TrophyIcon() { + return + + +} + export function KakaoChatIcon() { return ( - + {value} {unit} - + @@ -48,7 +49,7 @@ function CountNum({ value, setValue, unit, min = 1, isSmall, maxValue }: ICountN const Layout = styled.div<{ isSmall: boolean }>` display: flex; align-items: center; - font-size: ${(props) => (props.isSmall ? "14px" : "20px")}; + font-size: ${(props) => (props.isSmall ? "14px" : "18px")}; `; const IconWrapper = styled.button<{ @@ -65,6 +66,4 @@ const IconWrapper = styled.button<{ cursor: pointer; `; -const Count = styled.span``; - export default CountNum; diff --git a/components/atoms/InfoCol.tsx b/components/atoms/InfoCol.tsx new file mode 100644 index 000000000..fc601257e --- /dev/null +++ b/components/atoms/InfoCol.tsx @@ -0,0 +1,36 @@ +import { Box, Flex } from "@chakra-ui/react"; + +export interface InfoColOptions { + left: string; + right: string; +} + +interface InfoColProps { + optionsArr: InfoColOptions[]; + isMint?: boolean; +} + +function InfoCol({ optionsArr, isMint }: InfoColProps) { + return ( + + {optionsArr.map(({ left, right }, idx) => ( + + {left} + + {right} + + + ))} + + ); +} + +export default InfoCol; diff --git a/components/atoms/InfoColSkeleton.tsx b/components/atoms/InfoColSkeleton.tsx new file mode 100644 index 000000000..24db5d44f --- /dev/null +++ b/components/atoms/InfoColSkeleton.tsx @@ -0,0 +1,22 @@ +import { Box, Flex, Skeleton } from "@chakra-ui/react"; + +interface InfoColSkeletonProps { + leftArr: string[]; +} + +function InfoColSkeleton({ leftArr }: InfoColSkeletonProps) { + return ( + + {leftArr.map((text, idx) => ( + + {text} + + 1 + + + ))} + + ); +} + +export default InfoColSkeleton; diff --git a/components/atoms/buttons/ArrowBackButton.tsx b/components/atoms/buttons/ArrowBackButton.tsx index 36b6baee4..34c731e2e 100644 --- a/components/atoms/buttons/ArrowBackButton.tsx +++ b/components/atoms/buttons/ArrowBackButton.tsx @@ -1,13 +1,20 @@ import { useRouter } from "next/navigation"; +import { ShortArrowIcon } from "../../Icons/ArrowIcons"; import ButtonWrapper from "../ButtonWrapper"; interface IArrowBackButton { defaultUrl?: string; url?: string; func?: () => void; + color?: "mint" | "white"; } -export default function ArrowBackButton({ url, func, defaultUrl }: IArrowBackButton) { +export default function ArrowBackButton({ + url, + func, + defaultUrl, + color = "white", +}: IArrowBackButton) { const router = useRouter(); const handleGoBack = () => { @@ -20,13 +27,19 @@ export default function ArrowBackButton({ url, func, defaultUrl }: IArrowBackBut else router.push(defaultUrl); }; - return ; + return ; } -export function ArrowBackButtonUI({ onClick }: { onClick: () => void }) { +export function ArrowBackButtonUI({ + onClick, + color, +}: { + onClick: () => void; + color: "mint" | "white"; +}) { return ( - + ); } diff --git a/components/atoms/buttons/MenuButton.tsx b/components/atoms/buttons/MenuButton.tsx index caeb9196e..920eb03cd 100644 --- a/components/atoms/buttons/MenuButton.tsx +++ b/components/atoms/buttons/MenuButton.tsx @@ -2,7 +2,6 @@ import { Button, Menu, MenuButton as ChakraMenuButton, MenuItem, MenuList } from import { EllipsisIcon } from "../../Icons/DotIcons"; import KakaoShareBtn from "../../Icons/KakaoShareBtn"; -import ButtonWrapper from "../ButtonWrapper"; export interface MenuProps { text?: string; @@ -21,9 +20,7 @@ function MenuButton({ menuArr }: MenuButtonProps) { {({ isOpen }) => ( <> - - - + {menuArr.map((menu) => ( diff --git a/components/layouts/Header.tsx b/components/layouts/Header.tsx index 86678af8f..566143c1e 100644 --- a/components/layouts/Header.tsx +++ b/components/layouts/Header.tsx @@ -14,6 +14,7 @@ interface IHeader { isBorder?: boolean; children?: React.ReactNode; defaultUrl?: string; + isTransparent?: boolean; } export default function Header({ @@ -24,20 +25,29 @@ export default function Header({ rightPadding, func, children, - isCenter, + isCenter = true, isBorder = true, defaultUrl, + isTransparent, }: IHeader) { function HeaderLayout() { return ( - {isBack && } + {isBack && ( + + )} {!isCenter && ( {title} @@ -72,8 +82,9 @@ const HeaderContainer = styled.header<{ isBack?: boolean; isCenter?: boolean; rightPadding: number; + isTransparent: boolean; }>` - background-color: white; + background-color: ${(props) => (props.isTransparent ? "transparent" : "white")}; height: var(--header-h); font-size: 16px; padding-right: ${(props) => props.rightPadding || 20}px; diff --git a/components/molecules/navs/TabNav.tsx b/components/molecules/navs/TabNav.tsx index ce5014a28..a100fcad2 100644 --- a/components/molecules/navs/TabNav.tsx +++ b/components/molecules/navs/TabNav.tsx @@ -58,7 +58,7 @@ export default function TabNav({ p={!isMain ? "8px 20px" : "8px 16px"} flex={isFullSize ? 1 : undefined} key={tab.text} - color={tab.text === selected ? "black" : undefined} + color={tab.text === selected ? (isBlack ? "black" : "mint") : undefined} onClick={tab.text !== selected ? tab.func : undefined} _focus={{ outline: "none", diff --git a/components/organisms/imageSlider/imageSliderType/ImageSliderBanner.tsx b/components/organisms/imageSlider/imageSliderType/ImageSliderBanner.tsx index 9941fdae1..a4bbfd802 100644 --- a/components/organisms/imageSlider/imageSliderType/ImageSliderBanner.tsx +++ b/components/organisms/imageSlider/imageSliderType/ImageSliderBanner.tsx @@ -4,6 +4,7 @@ import "swiper/css/pagination"; import { Box } from "@chakra-ui/react"; import Image from "next/image"; import { useRouter } from "next/navigation"; +import { useState } from "react"; import styled from "styled-components"; import SwiperCore from "swiper"; import { Autoplay, Pagination, Scrollbar } from "swiper/modules"; @@ -26,6 +27,7 @@ interface IImageSliderEventBanner { function ImageSliderBanner({ imageArr, isLightBanner }: IImageSliderEventBanner) { const typeToast = useTypeToast(); const router = useRouter(); + const [currentSlide, setCurrentSlide] = useState(0); const onClick = (url: string) => { if (url) { @@ -38,6 +40,7 @@ function ImageSliderBanner({ imageArr, isLightBanner }: IImageSliderEventBanner) return ( setCurrentSlide(swiper.activeIndex)} autoplay={{ delay: 3000, disableOnInteraction: true, @@ -55,17 +59,15 @@ function ImageSliderBanner({ imageArr, isLightBanner }: IImageSliderEventBanner) {imageArr.map((item, index) => ( onClick(item?.url)}> - - - eventImg - - + + eventImg + ))} @@ -73,7 +75,7 @@ function ImageSliderBanner({ imageArr, isLightBanner }: IImageSliderEventBanner) ); } -const StyledSwiper = styled(Swiper)` +const StyledSwiper = styled(Swiper)<{ index: number }>` .swiper-wrapper { display: -webkit-inline-box; } @@ -87,7 +89,7 @@ const StyledSwiper = styled(Swiper)` .swiper-pagination-bullet-active { background-color: var(--color-mint); } - .swiper-pagination-bullet:nth-child(1) { + .swiper-pagination-bullet:nth-child(${(props) => props.index}) { width: 12px; /* 첫 번째 원의 가로 길이 */ height: 4px; border-radius: 16px; @@ -95,6 +97,4 @@ const StyledSwiper = styled(Swiper)` } `; -const Container = styled.div``; - export default ImageSliderBanner; diff --git a/modals/Modals.tsx b/modals/Modals.tsx index c7726804d..c19744774 100644 --- a/modals/Modals.tsx +++ b/modals/Modals.tsx @@ -70,8 +70,8 @@ export function ModalLayout({ const onClose = () => setIsModal(false); const { main, sub, isFull = true } = footerOptions || {}; - const { text = "확인", func = onClose } = main || {}; - const { text: subText = "취소", func: subFunc = onClose } = sub || {}; + const { text = "확 인", func = onClose } = main || {}; + const { text: subText = "취 소", func: subFunc = onClose } = sub || {}; const [modalTop, setModalTop] = useState("0%"); useEffect(() => { diff --git a/modals/RuleModal.tsx b/modals/RuleModal.tsx index ed48ad6e2..3313b4c25 100644 --- a/modals/RuleModal.tsx +++ b/modals/RuleModal.tsx @@ -1,8 +1,7 @@ -import styled from "styled-components"; +import { Box } from "@chakra-ui/react"; -import { ModalSubtitle } from "../styles/layout/modal"; import { IModal } from "../types/components/modalTypes"; -import { IFooterOptions, IPaddingOptions, ModalLayout } from "./Modals"; +import { ModalLayout } from "./Modals"; export interface IContentBasic { title: string; @@ -15,66 +14,18 @@ export interface IRuleModalContent { } interface IRuleModal extends IModal { - content: IRuleModalContent; + title: string; + text: string; + children: React.ReactNode; } -function RuleModal({ setIsModal, content }: IRuleModal) { - if (!content) return null; - const header = content.headerContent; - const main = content.mainContent; - - function ContentItem({ title, texts }: IContentBasic) { - return ( - - {title} - - {texts.map((text, idx) => ( -
  • {text}
  • - ))} -
    -
    - ); - } - - const footerOptions: IFooterOptions = { - main: {}, - isFull: false, - }; - - const paddingOptions: IPaddingOptions = { - body: { - bottom: 0, - }, - }; - +function RuleModal({ setIsModal, title, text, children }: IRuleModal) { return ( - - {header.text} - {main.map((item, idx) => ( - - ))} + + {text} + {children} ); } -const Item = styled.div``; - -const ItemContent = styled.ul` - font-size: 13px; - margin-left: var(--gap-4); - margin-top: var(--gap-1); - margin-bottom: var(--gap-3); - line-height: 1.8; -`; - -const RuleTitle = styled.span` - font-weight: 600; - font-size: 14px; -`; - export default RuleModal; diff --git a/modals/gather/GatherRuleModal.tsx b/modals/gather/GatherRuleModal.tsx index 5191bbcab..46db46dad 100644 --- a/modals/gather/GatherRuleModal.tsx +++ b/modals/gather/GatherRuleModal.tsx @@ -1,35 +1,32 @@ -import { IModal } from "../../types/components/modalTypes"; -import RuleModal, { IRuleModalContent } from "../RuleModal"; +function GatherRuleModal() { + // const content: IRuleModalContent = { + // headerContent: { + // title: "모임 게시판", + // text: "다양한 주제의 모임과 번개를 개설하거나 참여할 수 있어요! 재밌는 모임 같이 참여해요~!", + // }, + // mainContent: [ + // { + // title: "ABOUT 모임 게시판은 어떤게 다르나요?", + // texts: [ + // "누구나 모임을 개설할 수 있어요! 날짜와 장소, 주제를 선택해서 모임을 열어봐요!", + // "필요한 내용들을 형식화해서 쉽게 모임을 열 수 있어요!", + // "주제, 장소, 참여시간, 진행방식 등의 요소들을 한 눈에 볼 수 있어서 따로 고민하거나 설명하지 않아도 진행이 간단해요!", + // "같은 동아리여도 초면인 사람들이 많아서 모임에 나가기가 고민될 수 있어요! 인원 수, 성별, 나이 등을 고려하여 참여자를 받을 수 있어서 새로운 만남에 대한 부담이 적어요!", + // ], + // }, + // { + // title: "모임 개설자 필독", + // texts: [ + // "카카오톡 공유를 통해 모임글을 공지 톡방에 올려주세요!", + // "모임이 확정되면 인원들과 단톡방을 만들어주세요!", + // "모임 취소는 신청자가 없는 경우 완전히 삭제되고, 신청자가 있는 경우에는 취소 상태로 변경됩니다.", + // "모임 진행시 간단한 인증 사진을 찍어주세요!", + // ], + // }, + // ], + // }; -function GatherRuleModal({ setIsModal }: IModal) { - const content: IRuleModalContent = { - headerContent: { - title: "모임 게시판", - text: "다양한 주제의 모임과 번개를 개설하거나 참여할 수 있어요! 재밌는 모임 같이 참여해요~!", - }, - mainContent: [ - { - title: "ABOUT 모임 게시판은 어떤게 다르나요?", - texts: [ - "누구나 모임을 개설할 수 있어요! 날짜와 장소, 주제를 선택해서 모임을 열어봐요!", - "필요한 내용들을 형식화해서 쉽게 모임을 열 수 있어요!", - "주제, 장소, 참여시간, 진행방식 등의 요소들을 한 눈에 볼 수 있어서 따로 고민하거나 설명하지 않아도 진행이 간단해요!", - "같은 동아리여도 초면인 사람들이 많아서 모임에 나가기가 고민될 수 있어요! 인원 수, 성별, 나이 등을 고려하여 참여자를 받을 수 있어서 새로운 만남에 대한 부담이 적어요!", - ], - }, - { - title: "모임 개설자 필독", - texts: [ - "카카오톡 공유를 통해 모임글을 공지 톡방에 올려주세요!", - "모임이 확정되면 인원들과 단톡방을 만들어주세요!", - "모임 취소는 신청자가 없는 경우 완전히 삭제되고, 신청자가 있는 경우에는 취소 상태로 변경됩니다.", - "모임 진행시 간단한 인증 사진을 찍어주세요!", - ], - }, - ], - }; - - return ; + return null; } export default GatherRuleModal; diff --git a/modals/pop-up/LastWeekAttendPopUp.tsx b/modals/pop-up/LastWeekAttendPopUp.tsx index f21d5065c..8a2b19113 100644 --- a/modals/pop-up/LastWeekAttendPopUp.tsx +++ b/modals/pop-up/LastWeekAttendPopUp.tsx @@ -5,7 +5,8 @@ import styled from "styled-components"; import Avatar from "../../components/atoms/Avatar"; import UserBadge from "../../components/atoms/badges/UserBadge"; -import Skeleton from "../../components/atoms/skeleton/Skeleton"; +import InfoCol from "../../components/atoms/InfoCol"; +import InfoColSkeleton from "../../components/atoms/InfoColSkeleton"; import ProgressMark from "../../components/molecules/ProgressMark"; import { USER_ROLE } from "../../constants/settingValue/role"; import { usePointSystemLogQuery, useUserInfoQuery } from "../../hooks/user/queries"; @@ -62,7 +63,7 @@ function LastWeekAttendPopUp({ setIsModal }: IModal) { >
    - - {scoreObj ? ( - <> - - 이번 달 동아리 점수 - {userInfo?.monthScore} 점 - - - 이번 달 스터디 점수 - {scoreObj.study} 점 - - - 이번 달 모임 점수 - {scoreObj.gather} 점 - - - 이번 달에 받은 좋아요 - {likeCnt || 0} 개 - - - ) : ( - <> - - 이번 달 동아리 점수 - - 2 - - - - 이번 달 스터디 점수 - - 2 - - - - 이번 달 모임 점수 - - 2 - - - - 이번 달에 받은 좋아요 - - - 2 - - - - )} - + {scoreObj ? ( + + ) : ( + + )} {totalScore >= 0 && @@ -165,6 +147,7 @@ function LastWeekAttendPopUp({ setIsModal }: IModal) { } const Message = styled.div` + margin-top: 12px; padding: 12px 16px; min-height: 48px; border-radius: 8px; @@ -174,29 +157,4 @@ const Message = styled.div` background-color: var(--gray-100); `; -const Info = styled.div` - width: 100%; - display: flex; - flex-direction: column; - margin-bottom: 12px; -`; - -const Item = styled.div` - width: 100%; - - display: flex; - justify-content: space-between; - font-size: 11px; - margin: 4px 0; - - > span:first-child { - font-weight: regular; - color: var(--gray-600); - } - > span:last-child { - font-weight: medium; - color: var(--gray-800); - } -`; - export default LastWeekAttendPopUp; diff --git a/modals/promotion/PromotionRuleModal.tsx b/modals/promotion/PromotionRuleModal.tsx index b6dc326ad..a7302e222 100644 --- a/modals/promotion/PromotionRuleModal.tsx +++ b/modals/promotion/PromotionRuleModal.tsx @@ -1,32 +1,29 @@ -import { IModal } from "../../types/components/modalTypes"; -import RuleModal, { IRuleModalContent } from "../RuleModal"; - -function PromotionRuleModal({ setIsModal }: IModal) { - const content: IRuleModalContent = { - headerContent: { - title: "홍보 페이지", - text: "본인 학교 에브리타임에 동아리 홍보글을 작성해주시면와 추첨을 통해 매 달BBQ 황금 올리브 치킨 세트를 드립니다! 중복 지원도 가능하니까 생각나실 때 여러번 지원해주시면 더 감사합니다 ^^...", - }, - mainContent: [ - { - title: "포인트는 어떻게 얻나요?", - texts: ["스터디에 참여하거나, 이벤트, 건의, 홍보 등을 통해 포인트를 흭득할 수 있어요!"], - }, - { - title: "응모는 어떤 걸 하는 게 좋나요?", - texts: [ - "모든 상품의 기대 가성비는 거의 동일해요! 머리 아프게 고민하지 말고 원하시는 것으로 응모하시면 됩니다!", - ], - }, - { - title: "상품 마다 인원수가 있는 건 뭔가요?", - texts: [ - "예측 가능한 당첨이 될 수 있도록 최대 응모 횟수와 당첨 숫자를 제한하고 있어요. 트로피의 숫자는 당첨 개수이고, 아래의 숫자는 현재 응모 인원과 최대 응모 가능 인원이에요!", - ], - }, - ], - }; - return ; +function PromotionRuleModal() { + // const content: IRuleModalContent = { + // headerContent: { + // title: "홍보 페이지", + // text: "본인 학교 에브리타임에 동아리 홍보글을 작성해주시면와 추첨을 통해 매 달BBQ 황금 올리브 치킨 세트를 드립니다! 중복 지원도 가능하니까 생각나실 때 여러번 지원해주시면 더 감사합니다 ^^...", + // }, + // mainContent: [ + // { + // title: "포인트는 어떻게 얻나요?", + // texts: ["스터디에 참여하거나, 이벤트, 건의, 홍보 등을 통해 포인트를 흭득할 수 있어요!"], + // }, + // { + // title: "응모는 어떤 걸 하는 게 좋나요?", + // texts: [ + // "모든 상품의 기대 가성비는 거의 동일해요! 머리 아프게 고민하지 말고 원하시는 것으로 응모하시면 됩니다!", + // ], + // }, + // { + // title: "상품 마다 인원수가 있는 건 뭔가요?", + // texts: [ + // "예측 가능한 당첨이 될 수 있도록 최대 응모 횟수와 당첨 숫자를 제한하고 있어요. 트로피의 숫자는 당첨 개수이고, 아래의 숫자는 현재 응모 인원과 최대 응모 가능 인원이에요!", + // ], + // }, + // ], + // }; + return null; } export default PromotionRuleModal; diff --git a/modals/store/StoreApplyGiftModal.tsx b/modals/store/StoreApplyGiftModal.tsx index 143bd28f5..977290ff4 100644 --- a/modals/store/StoreApplyGiftModal.tsx +++ b/modals/store/StoreApplyGiftModal.tsx @@ -96,7 +96,7 @@ function StoreApplyGiftModal({ setIsModal, giftInfo }: IStoreApplyGiftModal) { return ( - + {!isLoading ? ( <> @@ -111,10 +111,7 @@ function StoreApplyGiftModal({ setIsModal, giftInfo }: IStoreApplyGiftModal) { 필요 포인트 myPoint}>{totalCost} point - - 최대 구매 개수 - myPoint}>{maxCnt} 개 - + @@ -130,17 +127,22 @@ function StoreApplyGiftModal({ setIsModal, giftInfo }: IStoreApplyGiftModal) { const Item = styled.div` display: flex; justify-content: space-between; - margin-bottom: var(--gap-1); + padding: 4px 0; + > span:first-child { + color: var(--gray-600); + } > span:last-child { font-weight: 600; } `; const NeedPoint = styled.span<{ overMax: boolean }>` - color: ${(props) => props.overMax && "var(--color-red)"}; + color: ${(props) => (props.overMax ? "var(--color-red)" : "var(--color-mint)")}; `; const CountNav = styled.nav` + margin-top: 12px; + flex: 1; display: flex; align-items: center; diff --git a/modals/store/StoreGiftWinModal.tsx b/modals/store/StoreGiftWinModal.tsx index 445aacdde..6aa6f732f 100644 --- a/modals/store/StoreGiftWinModal.tsx +++ b/modals/store/StoreGiftWinModal.tsx @@ -1,4 +1,4 @@ -import styled from "styled-components"; +import { Box, Flex } from "@chakra-ui/react"; import { IGiftEntry } from "../../pages/store"; import { IModal } from "../../types/components/modalTypes"; @@ -27,38 +27,25 @@ function StoreGiftWinModal({ setIsModal, applicants, winCnt }: IStoreGiftWinModa return ( - 당첨을 축하합니다! - + + 당첨을 축하합니다. + + {winners.map((num, idx) => ( - {users[num]?.name || "비공개"} + + {users[num]?.name?.[0]}*{users[num]?.name?.[2]} + ))} - +
    ); } -const Message = styled.div` - text-align: center; - font-weight: 700; - font-size: 16px; - color: var(--color-mint); - margin-top: var(--gap-1); - margin-bottom: var(--gap-5); -`; - -const Winner = styled.div` - padding: 12px 0; - display: flex; - align-items: center; - - border-radius: var(--rounded-lg); - justify-content: space-around; - border: var(--border-mint); -`; - -const Win = styled.span` - font-size: 15px; - font-weight: 600; -`; - export default StoreGiftWinModal; diff --git a/modals/store/StoreMembersModal.tsx b/modals/store/StoreMembersModal.tsx new file mode 100644 index 000000000..586b3071e --- /dev/null +++ b/modals/store/StoreMembersModal.tsx @@ -0,0 +1,120 @@ +import "swiper/css/autoplay"; +import "swiper/css/pagination"; + +import { Box, Flex } from "@chakra-ui/react"; +import { useState } from "react"; +import styled from "styled-components"; +import SwiperCore from "swiper"; +import { Pagination, Scrollbar } from "swiper/modules"; +import { Swiper, SwiperSlide } from "swiper/react"; + +import { IModal } from "../../types/components/modalTypes"; +import { IStoreApplicant } from "../../types/models/store"; +import { ModalLayout } from "../Modals"; + +SwiperCore.use([Scrollbar]); + +interface StoreMembersModalProps extends IModal { + members: IStoreApplicant[]; +} + +function StoreMembersModal({ setIsModal, members }: StoreMembersModalProps) { + const [currentSlide, setCurrentSlide] = useState(0); + + const chunkArray = (arr: IStoreApplicant[], size: number) => { + const result: IStoreApplicant[][] = []; + for (let i = 0; i < arr.length; i += size) { + result.push(arr.slice(i, i + size)); + } + return result; + }; + + const arr = chunkArray(members, 5); + + return ( + + setCurrentSlide(swiper.activeIndex)} + > + {arr.map((memberArr, index) => ( + + + {memberArr.map((member, idx) => ( + + + {member.name[0]}*{member.name?.[2]} + + {member.cnt}회 + + ))} + {arr.length === 1 && ( + + )} + + + ))} + + + ); +} + +const StyledSwiper = styled(Swiper)<{ index: number }>` + overflow: hidden; + + .swiper-wrapper { + display: -webkit-inline-box; + } + .swiper-pagination-bullet { + background-color: var(--gray-400); + width: 4px; + height: 4px; + opacity: 0.8; + } + + .swiper-pagination-bullet-active { + background-color: var(--color-mint); + } + .swiper-pagination-bullet:nth-child(${(props) => props.index}) { + width: 12px; /* 첫 번째 원의 가로 길이 */ + height: 4px; + border-radius: 16px; + opacity: 0.6; + } +`; + +export default StoreMembersModal; diff --git a/pageTemplates/group/detail/GroupParticipation.tsx b/pageTemplates/group/detail/GroupParticipation.tsx index abc1bee11..d1a098914 100644 --- a/pageTemplates/group/detail/GroupParticipation.tsx +++ b/pageTemplates/group/detail/GroupParticipation.tsx @@ -12,7 +12,7 @@ interface IGroupParticipation { function GroupParticipation({ data }: IGroupParticipation) { const isSecret = data?.isSecret; - + console.log(53, data); const userCardArr: IProfileCommentCard[] = data.participants.map((par) => { if (isSecret) { return { diff --git a/pageTemplates/group/writing/QuestionBottomDrawer.tsx b/pageTemplates/group/writing/QuestionBottomDrawer.tsx index 9f78a0636..e027b186a 100644 --- a/pageTemplates/group/writing/QuestionBottomDrawer.tsx +++ b/pageTemplates/group/writing/QuestionBottomDrawer.tsx @@ -35,6 +35,7 @@ function QuestionBottomDrawer({ const onClickLeft = () => { setQuestion(null); + setIsModal(false); onClose(); }; diff --git a/pageTemplates/layout/Layout.tsx b/pageTemplates/layout/Layout.tsx index d14c0d978..1574b2bc1 100644 --- a/pageTemplates/layout/Layout.tsx +++ b/pageTemplates/layout/Layout.tsx @@ -87,7 +87,8 @@ function Layout({ children }: ILayout) { ? { paddingTop: "56px", } - : !NOT_PADDING_NAV_SEGMENT.includes(currentSegment?.[0]) + : !NOT_PADDING_NAV_SEGMENT.includes(currentSegment?.[0]) && + !(currentSegment?.[0] === "store" && currentSegment?.[1]) ? { paddingTop: "56px", paddingBottom: `calc(var(--bottom-nav-height) + ${iPhoneNotchSize()}px`, diff --git a/pages/board/index.tsx b/pages/board/index.tsx index fc8f416c4..abed44648 100644 --- a/pages/board/index.tsx +++ b/pages/board/index.tsx @@ -1,10 +1,8 @@ import { useSession } from "next-auth/react"; -import { useState } from "react"; import WritingButton from "../../components/atoms/buttons/WritingButton"; import Header from "../../components/layouts/Header"; import Slide from "../../components/layouts/PageSlide"; -import RuleModal, { IRuleModalContent } from "../../modals/RuleModal"; import SquareSecretSection from "../../pageTemplates/square/SquareSecretSection"; function BoardPage() { @@ -12,7 +10,7 @@ function BoardPage() { const isGuest = session?.user.name === "guest"; - const [isRuleModal, setIsRuleModal] = useState(false); + // const [isRuleModal, setIsRuleModal] = useState(false); return ( <> @@ -21,27 +19,27 @@ function BoardPage() { {!isGuest && } - {isRuleModal && } + {/* {isRuleModal && } */} ); } -const SECRET_CONTENT: IRuleModalContent = { - mainContent: [ - { - title: "시크릿 스퀘어 설명", - - texts: [ - "익명성이 보장됩니다.", - "주제에 상관없이 다양한 소통 가능", - "보유중인 아바타 중 선택하여 사용 가능(예정)", - ], - }, - ], - headerContent: { - title: "시크릿 스퀘어", - text: "익명으로 소통을 할 수 있는 커뮤니티", - }, -}; +// const SECRET_CONTENT: IRuleModalContent = { +// mainContent: [ +// { +// title: "시크릿 스퀘어 설명", + +// texts: [ +// "익명성이 보장됩니다.", +// "주제에 상관없이 다양한 소통 가능", +// "보유중인 아바타 중 선택하여 사용 가능(예정)", +// ], +// }, +// ], +// headerContent: { +// title: "시크릿 스퀘어", +// text: "익명으로 소통을 할 수 있는 커뮤니티", +// }, +// }; export default BoardPage; diff --git a/pages/group/[id]/index.tsx b/pages/group/[id]/index.tsx index 4234f0658..90bbf5e20 100644 --- a/pages/group/[id]/index.tsx +++ b/pages/group/[id]/index.tsx @@ -39,7 +39,7 @@ function GroupDetail() { const [group, setTransferGroup] = useRecoilState(transferGroupDataState); const { data: groupData, refetch } = useGroupIdQuery(id, { enabled: !!id && !group }); - + console.log(1234, groupData); useEffect(() => { if (groupData) { setTransferGroup(groupData); @@ -120,6 +120,7 @@ function GroupDetail() { }))} selected={category} isFullSize + isBlack /> {category === "정 보" ? ( diff --git a/pages/group/index.tsx b/pages/group/index.tsx index 4db2bc41b..0d448bc75 100644 --- a/pages/group/index.tsx +++ b/pages/group/index.tsx @@ -1,6 +1,6 @@ import { Box, Flex } from "@chakra-ui/react"; -import { useSession } from "next-auth/react"; import { useRouter, useSearchParams } from "next/navigation"; +import { useSession } from "next-auth/react"; import { useEffect, useRef, useState } from "react"; import { useSetRecoilState } from "recoil"; import styled from "styled-components"; diff --git a/pages/group/writing/condition.tsx b/pages/group/writing/condition.tsx index 20966dab0..341294d27 100644 --- a/pages/group/writing/condition.tsx +++ b/pages/group/writing/condition.tsx @@ -137,7 +137,7 @@ function WritingCondition() { if (temp.length) return String(temp) + " " + "제한"; return null; }; - + console.log(24, condition); return ( <> @@ -287,6 +287,7 @@ function WritingCondition() { { + console.log(54); setCondition((old) => ({ ...old, isAgree: false })); setIsQuestionModal(false); }} diff --git a/pages/ranking/index.tsx b/pages/ranking/index.tsx index 32c2b7ad7..3752bad5b 100644 --- a/pages/ranking/index.tsx +++ b/pages/ranking/index.tsx @@ -11,7 +11,6 @@ import { useAdminUsersLocationControlQuery } from "../../hooks/admin/quries"; import { useTypeToast } from "../../hooks/custom/CustomToast"; import { useUserAttendRateQuery } from "../../hooks/user/sub/studyRecord/queries"; import { IUserRankings, sortUserRanking } from "../../libs/userEventLibs/userHelpers"; -import RuleModal, { IRuleModalContent } from "../../modals/RuleModal"; import RankingMembers from "../../pageTemplates/ranking/RankingMembers"; import RankingOverview from "../../pageTemplates/ranking/RankingOverview"; import StatisticsFilterBar from "../../pageTemplates/ranking/StatisticsFilterBar"; @@ -35,26 +34,26 @@ export interface RankingFilterOptionProps { isLocationFilter: boolean; } -const CONTENT: IRuleModalContent = { - headerContent: { - title: "ABOUT 랭킹", - text: "동아리 내의 랭킹 또는 내 통계를 확인할 수 있습니다.", - }, - mainContent: [ - { - title: "카테고리 설명", - texts: [ - "월간 랭킹은 이번 달 동아리 활동 점수입니다. 매달 초기화 됩니다.", - "스터디 랭킹은 이번 달 스터디 참여 횟수입니다. 매달 초기화 됩니다.", - "누적 랭킹은 동아리 점수입니다. 등급을 나타내는 지표입니다.", - ], - }, - { - title: "메달", - texts: ["공개 예정 컨텐츠"], - }, - ], -}; +// const CONTENT: IRuleModalContent = { +// headerContent: { +// title: "ABOUT 랭킹", +// text: "동아리 내의 랭킹 또는 내 통계를 확인할 수 있습니다.", +// }, +// mainContent: [ +// { +// title: "카테고리 설명", +// texts: [ +// "월간 랭킹은 이번 달 동아리 활동 점수입니다. 매달 초기화 됩니다.", +// "스터디 랭킹은 이번 달 스터디 참여 횟수입니다. 매달 초기화 됩니다.", +// "누적 랭킹은 동아리 점수입니다. 등급을 나타내는 지표입니다.", +// ], +// }, +// { +// title: "메달", +// texts: ["공개 예정 컨텐츠"], +// }, +// ], +// }; function Ranking() { const typeToast = useTypeToast(); @@ -66,10 +65,10 @@ function Ranking() { category: "월간 랭킹", isLocationFilter: false, }); - const [isModal, setIsModal] = useState(false); + // const [isModal, setIsModal] = useState(false); const categorySource = CATEGORY_SOURCE[filterOptions.category]; - + const { data: attendRecords } = useUserAttendRateQuery( dayjs().startOf("month"), dayjs(), @@ -90,7 +89,6 @@ function Ranking() { enabled: !!session, }, ); - useEffect(() => { if (filterOptions.category === "스터디 랭킹" && !attendRecords) return; @@ -146,7 +144,7 @@ function Ranking() { )} - {isModal && } + {/* {isModal && } */} ); } diff --git a/pages/square/index.tsx b/pages/square/index.tsx index 3ad49962b..62b79acc1 100644 --- a/pages/square/index.tsx +++ b/pages/square/index.tsx @@ -4,7 +4,6 @@ import { useEffect, useState } from "react"; import WritingButton from "../../components/atoms/buttons/WritingButton"; import Slide from "../../components/layouts/PageSlide"; -import RuleModal, { IRuleModalContent } from "../../modals/RuleModal"; import SquareSecretSection from "../../pageTemplates/square/SquareSecretSection"; import { SquareTab } from "../../pageTemplates/square/SquareTabNav"; @@ -16,7 +15,7 @@ function SquarePage() { const isGuest = session?.user.name === "guest"; const [tab, setTab] = useState("시크릿 스퀘어"); - const [isRuleModal, setIsRuleModal] = useState(false); + // const [isRuleModal, setIsRuleModal] = useState(false); useEffect(() => { if (!tabParam) { @@ -34,49 +33,49 @@ function SquarePage() { {tab === "시크릿 스퀘어" && !isGuest && } - {isRuleModal && ( + {/* {isRuleModal && ( - )} + )} */} ); } -const LOUNGE_CONTENT: IRuleModalContent = { - mainContent: [ - { - title: "라운지 설명", +// const LOUNGE_CONTENT: IRuleModalContent = { +// mainContent: [ +// { +// title: "라운지 설명", - texts: [ - "번개 게시글 또는 소모임 피드에서 작성 가능", - "리뷰/피드 작성시 200 point 획득 !", - "좋아요 누르기 or 댓글 작성 만으로도 포인트 획득 !", - ], - }, - ], - headerContent: { - title: "라운지", - text: "번개 리뷰나 소모임 피드를 확인할 수 있습니다.", - }, -}; -const SECRET_CONTENT: IRuleModalContent = { - mainContent: [ - { - title: "시크릿 스퀘어 설명", +// texts: [ +// "번개 게시글 또는 소모임 피드에서 작성 가능", +// "리뷰/피드 작성시 200 point 획득 !", +// "좋아요 누르기 or 댓글 작성 만으로도 포인트 획득 !", +// ], +// }, +// ], +// headerContent: { +// title: "라운지", +// text: "번개 리뷰나 소모임 피드를 확인할 수 있습니다.", +// }, +// }; +// const SECRET_CONTENT: IRuleModalContent = { +// mainContent: [ +// { +// title: "시크릿 스퀘어 설명", - texts: [ - "익명성이 보장됩니다.", - "주제에 상관없이 다양한 소통 가능", - "보유중인 아바타 중 선택하여 사용 가능(예정)", - ], - }, - ], - headerContent: { - title: "시크릿 스퀘어", - text: "익명으로 소통을 할 수 있는 커뮤니티", - }, -}; +// texts: [ +// "익명성이 보장됩니다.", +// "주제에 상관없이 다양한 소통 가능", +// "보유중인 아바타 중 선택하여 사용 가능(예정)", +// ], +// }, +// ], +// headerContent: { +// title: "시크릿 스퀘어", +// text: "익명으로 소통을 할 수 있는 커뮤니티", +// }, +// }; export default SquarePage; diff --git a/pages/store/[id]/index.tsx b/pages/store/[id]/index.tsx index ee0d0134a..3fd178194 100644 --- a/pages/store/[id]/index.tsx +++ b/pages/store/[id]/index.tsx @@ -1,58 +1,180 @@ import "dayjs/locale/ko"; +import { Badge, Box, Button, Flex } from "@chakra-ui/react"; import dayjs from "dayjs"; import localizedFormat from "dayjs/plugin/localizedFormat"; -import { useState } from "react"; +import Image from "next/image"; +import { useEffect, useState } from "react"; import { useRecoilValue } from "recoil"; -import styled from "styled-components"; +import MenuButton from "../../../components/atoms/buttons/MenuButton"; import Header from "../../../components/layouts/Header"; -import Slide from "../../../components/layouts/PageSlide"; +import BottomFlexDrawer from "../../../components/organisms/drawer/BottomFlexDrawer"; +import { useTypeToast } from "../../../hooks/custom/CustomToast"; import StoreApplyGiftModal from "../../../modals/store/StoreApplyGiftModal"; import StoreGiftWinModal from "../../../modals/store/StoreGiftWinModal"; -import StoreDetailCover from "../../../pageTemplates/store/detail/StoreDetailCover"; -import StoreDetailDetails from "../../../pageTemplates/store/detail/StoreDetailDetails"; -import StoreDetailNav from "../../../pageTemplates/store/detail/StoreDetailNav"; -import StoreDetailOverview from "../../../pageTemplates/store/detail/StoreDetailOverview"; +import StoreMembersModal from "../../../modals/store/StoreMembersModal"; import { transferStoreGiftDataState } from "../../../recoils/transferRecoils"; dayjs.extend(localizedFormat); dayjs.locale("ko"); function StoreItem() { - const [isApplyModal, setIsApplyModal] = useState(false); - const [isWinModal, setIsWinModal] = useState(false); + const typeToast = useTypeToast(); + const [modalType, setModalType] = useState<"vote" | "winner" | "member">(); + + const [drawerHeight, setDrawerHeight] = useState(0); const storeGiftData = useRecoilValue(transferStoreGiftDataState); + const giftInfo = storeGiftData?.data; - const isActive = storeGiftData?.isActive; + + const isResult = giftInfo.totalCnt >= giftInfo.max; + + useEffect(() => { + // 높이 계산: 100dvh - 100dvw + const calculateHeight = () => { + const viewportHeight = window.innerHeight; // 100dvh + const viewportWidth = window.innerWidth; // 100dvw + setDrawerHeight(viewportHeight - viewportWidth); + }; + + // 초기 계산 + calculateHeight(); + + // 창 크기 변경 시 재계산 + window.addEventListener("resize", calculateHeight); + return () => { + window.removeEventListener("resize", calculateHeight); + }; + }, []); return ( <> -
    - - {storeGiftData && ( - - - - - - - )} - - {isApplyModal && } - {isWinModal && ( + + +
    + { + typeToast("not-yet"); + }, + }, + ]} + /> +
    + + {storeGiftData && storeImageCover} + +
    + + {drawerHeight && ( + {}} + > + {storeGiftData && ( + + + {giftInfo.brand} + + + {giftInfo.name} + + + 현재 전체 응모 횟수는 ‘{giftInfo.totalCnt}회’입니다. + + + {giftInfo.point} Point + + + 추첨 인원 + + {giftInfo.winner}명 + + + + 응모 가능 인원 + + {giftInfo.max}명 + + + + 안내사항 + + + 당첨자는 중복되지 않습니다. +
    + 응모할 수 있는 최대 횟수는 개인 점수에 따라 달라집니다. +
    +
    + )} + + + + +
    + )} + {modalType === "member" && ( + setModalType(null)} /> + )} + {modalType === "vote" && ( + setModalType(null)} giftInfo={giftInfo} /> + )} + {modalType === "winner" && ( setModalType(null)} applicants={giftInfo} winCnt={giftInfo.winner} /> @@ -61,10 +183,4 @@ function StoreItem() { ); } -const Layout = styled.div` - display: flex; - flex-direction: column; - margin: 0 var(--gap-4); -`; - export default StoreItem; diff --git a/pages/store/index.tsx b/pages/store/index.tsx index 10ca8c55f..e7ddb09a7 100644 --- a/pages/store/index.tsx +++ b/pages/store/index.tsx @@ -1,20 +1,24 @@ -import { Button } from "@chakra-ui/react"; +import { Box, Button, Flex, Grid } from "@chakra-ui/react"; import Image from "next/image"; import { useRouter } from "next/router"; +import { useSession } from "next-auth/react"; import { useEffect, useState } from "react"; import { useRecoilState, useSetRecoilState } from "recoil"; -import styled from "styled-components"; +import InfoCol from "../../components/atoms/InfoCol"; +import { TrophyIcon } from "../../components/Icons/icons"; import RuleIcon from "../../components/Icons/RuleIcon"; import Header from "../../components/layouts/Header"; import Slide from "../../components/layouts/PageSlide"; +import TabNav, { ITabNavOptions } from "../../components/molecules/navs/TabNav"; import { useErrorToast } from "../../hooks/custom/CustomToast"; import { useStoreGiftEntryQuery } from "../../hooks/sub/store/queries"; -import RuleModal, { IRuleModalContent } from "../../modals/RuleModal"; +import RuleModal from "../../modals/RuleModal"; import { isPrevBooleanState } from "../../recoils/previousAtoms"; import { transferStoreGiftDataState } from "../../recoils/transferRecoils"; import { STORE_GIFT_ACTIVE, STORE_GIFT_INACTIVE } from "../../storage/Store"; import { IStoreApplicant, IStoreGift } from "../../types/models/store"; +import { selectRandomWinners } from "../../utils/validationUtils"; export interface IGiftEntry extends IStoreGift { users: IStoreApplicant[]; @@ -25,33 +29,8 @@ interface IGiftEntries { inactive: IGiftEntry[]; } -const content: IRuleModalContent = { - headerContent: { - title: "포인트 스토어", - text: "동아리 활동을 통해 포인트를 모으고 추첨에 응모해보세요! 다양한 상품이 있습니다 ~!", - }, - mainContent: [ - { - title: "포인트는 어떻게 얻나요?", - texts: [ - "스터디 참여, 출석체크, 이벤트, 건의, 홍보 등 여러 컨텐츠에서 포인트를 흭득할 수 있어요!", - ], - }, - - { - title: "상품 당첨과 인원 관련해서 궁금해요.", - texts: ["트로피의 숫자는 당첨 개수, 왼쪽 숫자는 현재 인원과 최대 응모 가능한 인원이에요!"], - }, - { - title: "응모 최대 개수에 제한이 있나요?", - texts: [ - "네. 상품 당 중복해서 투표할 수 있는 숫자는 유저 개인 등급에 따라 달라집니다. 기본 아메리카노는 1개, 이후 등급이 오를때마다 하나씩 더 추가돼요.", - ], - }, - ], -}; - -function Event() { +function StorePage() { + const { data: session } = useSession(); const router = useRouter(); const errorToast = useErrorToast(); const [giftEntries, setGiftEntries] = useState(); @@ -98,6 +77,7 @@ function Event() { gift.totalCnt += who.cnt; } }); + setGiftEntries(temp); setIsLoading(false); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -113,176 +93,172 @@ function Event() { router.push(`/store/${item.giftId}`); }; + const tabNavOptions: ITabNavOptions[] = [ + { + text: "현재 상품", + func: () => { + setIsShowActive(true); + }, + }, + { + text: "지난 상품", + func: () => { + setIsShowActive(false); + }, + }, + ]; + + const pointInfoArr: { left: string; right: string }[] = [ + { + left: "스터디 출석체크", + right: "5 Point", + }, + { + left: "번개 모임 참여", + right: "5 Point", + }, + { + left: "일일 출석체크", + right: "2 Point", + }, + { + left: "피드 좋아요 누르기", + right: "2 Point", + }, + { + left: "함께한 멤버 좋아요 보내기", + right: "2 Point", + }, + { + left: "동아리 홍보 글 올리기", + right: "100 Point", + }, + ]; + return ( <>
    - - + + + + All Products + {!isLoading && ( - - {giftArr.map((item, idx) => ( - onClickGift(item)}> - - - {isShowActive ? item.totalCnt : item.max} - /{item.max} - - - {new Array(item.winner).fill(0).map((_, idx) => ( -
    - -
    - ))} -
    -
    - - storeGift + + {giftArr.map((item, idx) => { + const winners: number[] = selectRandomWinners(item.max, item.winner, item.giftId); + const users = item.users.reduce((acc, curr) => { + for (let i = 0; i < curr.cnt; i++) { + acc.push(curr); + } + return acc; + }, []); + const winUsers = winners.map((win) => users[win]); + const isMyWin = winUsers.some((user) => user?.uid === session?.user.uid); - {(!isShowActive || item.max <= item.totalCnt) && 추첨 완료} - - - {item.name} - {item.point} point - - {(!isShowActive || item.max <= item.totalCnt) && } -
    - ))} -
    + return ( + + ); + })} + )} -
    +
    - {isModal && } + {isModal && ( + + + + )} ); } -const Layout = styled.div` - margin: 0 var(--gap-4); -`; - -const Nav = styled.nav` - margin-top: var(--gap-3); - display: flex; -`; - -const Container = styled.div` - display: grid; - grid-template-columns: repeat(2, 1fr); - grid-template-rows: repeat(2, 1fr); - - padding: var(--gap-4) 0; - gap: var(--gap-3); -`; - -const Item = styled.button` - position: relative; - - padding: var(--gap-2); - background-color: white; - border: var(--border); - - display: flex; - flex-direction: column; - align-items: center; - border-radius: var(--rounded-lg); -`; - -const Status = styled.div` - justify-content: space-between; - display: flex; - width: 100%; - font-size: 14px; -`; - -const Trophy = styled.div` - display: flex; - margin-left: 4px; - > div { - margin-left: 4px; - } -`; - -const ApplyCnt = styled.div` - color: var(--gray-700); - font-size: 16px; -`; - -const ImageWrapper = styled.div` - display: flex; - justify-content: center; - align-items: center; - width: 100px; - height: 100px; - border-radius: var(--rounded-lg); - overflow: hidden; -`; - -const Info = styled.div` - margin-top: 12px; - font-size: 16px; - display: flex; - flex-direction: column; - align-items: center; -`; - -const Name = styled.span` - font-weight: 600; -`; - -const Point = styled.span` - color: var(--color-mint); - font-size: 16px; -`; - -const Circle = styled.div` - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - z-index: 1; - border: 2px solid var(--gray-800); - display: flex; - font-size: 14px; - justify-content: center; - align-items: center; - font-weight: 800; - width: 80px; - height: 80px; - border-radius: 50%; -`; -const CompletedRapple = styled.div` - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: var(--gray-300); - opacity: 0.5; -`; -export default Event; +export default StorePage; diff --git a/pages/user/point.tsx b/pages/user/point.tsx index 21b9ec4e0..5c90698ec 100644 --- a/pages/user/point.tsx +++ b/pages/user/point.tsx @@ -15,7 +15,7 @@ function PointLog() { const { data: session } = useSession(); const { data: point } = usePointSystemQuery("point"); const { data: pointLog } = usePointSystemLogQuery("point"); - + console.log(point, pointLog); const filterLog = pointLog?.filter((item) => item.meta.value); const headerInfos = ["날짜", "내용", "점수"]; @@ -56,7 +56,7 @@ function PointLog() { const Layout = styled.div` display: flex; flex-direction: column; - margin: 0 var(--gap-4); + margin-top: var(--gap-5); font-weight: 600; min-height: 100dvh; diff --git a/storage/Store.tsx b/storage/Store.tsx index fa2a32ac9..969a0e0b0 100644 --- a/storage/Store.tsx +++ b/storage/Store.tsx @@ -3,146 +3,188 @@ import { IStoreGift } from "../types/models/store"; export const STORE_GIFT_ACTIVE: IStoreGift[] = [ { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%A9%94%EA%B0%80_%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", - name: "메가 아메리카노", - brand: "메가커피", - point: 20, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EA%B0%90%EA%B7%A4.webp", + name: "제주 감귤", + brand: "수플린", + point: 110, winner: 3, max: 30, - giftId: 38, + giftId: 57, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/CU_3000%EC%9B%90%EA%B6%8C.webp", - name: "3000원 상품권", - brand: "CU", - point: 20, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%B6%98%EC%8B%9D%EC%9D%B4+%EB%A8%B8%EA%B7%B8%EC%9E%94.webp", + name: "춘식이 머그잔", + brand: "프렌즈리빙", + point: 65, winner: 2, max: 30, - giftId: 39, + giftId: 58, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B2%A0%EC%8A%A4%ED%82%A8%EB%9D%BC%EB%B9%88%EC%8A%A4_%EC%8B%B1%EA%B8%80.webp", - name: "베스킨라빈스 싱글", - brand: "베스킨라빈스", - point: 20, - winner: 2, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EC%98%81+10000.webp", + name: "올리브영 10000원권", + brand: "올리브영", + point: 70, + winner: 3, + giftId: 59, max: 40, - giftId: 40, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%8A%A4%ED%83%80%EB%B2%85%EC%8A%A4_%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", - name: "아메리카노", - brand: "스타벅스", - point: 30, - winner: 2, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC+10000.webp", + name: "배달의 민족 10000원", + brand: "배달의민족", + point: 100, + winner: 3, max: 30, - giftId: 41, + giftId: 60, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/KakaoTalk_20240605_010554846.jpg", - name: "5000원 상품권", - brand: "GS", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%B9%B4%ED%94%BC%EB%B0%94%EB%9D%BC.webp", + name: "콧물 카피바라", + brand: "루시아이", point: 50, - winner: 3, - max: 30, - giftId: 50, + winner: 1, + max: 26, + giftId: 61, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%8B%A4%EC%9D%B4%EC%86%8C_5000%EC%9B%90%EA%B6%8C.webp", - name: "다이소 5000원", - brand: "다이소", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%99%A9%EC%98%AC+%EC%84%B8%ED%8A%B8.webp", + name: "황금올리브 치킨 세트", + brand: "BBQ", point: 50, - winner: 2, - giftId: 42, - max: 20, + winner: 1, + giftId: 62, + max: 50, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%88%AC%EC%8D%B8_%EC%95%84%EC%9D%B4%EC%8A%A4%EB%B0%95%EC%8A%A4+%EC%84%B8%ED%8A%B8.webp", - name: "아이스박스 세트", - brand: "투썸", - point: 65, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C+(10).webp", + name: "잔망루피 핫팩", + brand: "잔망루피", + point: 75, winner: 3, - giftId: 43, - max: 30, + max: 40, + giftId: 63, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B9%85%EB%A7%A5.jpg", - name: "빅맥 세트", - brand: "맥도날드", - point: 72, - winner: 2, - giftId: 49, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%AA%A8%EB%9E%98%EB%A9%8D.webp", + name: "모래멍 샌드아트", + brand: "아트조이", + point: 60, + winner: 1, max: 20, + giftId: 64, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EB%A6%AC%EB%B8%8C%EC%98%81_10000%EC%9B%90%EA%B6%8C.webp", - name: "올리브영 10000원", - brand: "올리브영", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%88%88%EB%A7%88%EC%82%AC%EC%A7%80%EA%B8%B0.webp", + name: "눈 마사지기", + brand: "휴플러스", point: 100, - winner: 3, - giftId: 44, + winner: 1, max: 30, + giftId: 65, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EB%A6%AC%EB%B8%8C%EC%98%81_10000%EC%9B%90%EA%B6%8C.webp", - name: "올리브영 20000원", - brand: "올리브영", - point: 200, - winner: 2, - giftId: 45, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%86%8C+%EC%8A%AC%EB%A6%AC%ED%8D%BC.webp", + name: "윈터카우 실내슬리퍼", + brand: "날씨요정", + point: 85, + winner: 1, max: 20, + giftId: 66, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC_10000.webp", - name: "배달의민족 10000원", - brand: "배달의 민족", - point: 100, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%B9%B4%ED%94%BC%EB%B0%94%EB%9D%BC+%ED%82%A4%EB%A7%81.webp", + name: "카피바라 키링", + brand: "제이블롬", + point: 30, winner: 2, - max: 20, - giftId: 46, + max: 30, + giftId: 67, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC_10000.webp", - name: "배달의민족 20000원", - brand: "배달의 민족", - point: 200, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%A7%91%EC%88%9C%EC%9D%B4%EB%8B%B4%EC%9A%94.webp", + name: "집순이 담요", + brand: "수면잠옷", + point: 60, + winner: 1, + max: 30, + giftId: 68, + }, + + { + image: + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%8B%B4%ED%8A%B8.webp", + name: "페리페라 글로이 틴트", + brand: "페리페라", + point: 60, winner: 2, - max: 20, - giftId: 47, + max: 30, + giftId: 69, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/KakaoTalk_20240228_195332095_02.jpg", - name: "굽네치킨 세트", - brand: "굽네치킨", - point: 125, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%95%B8%EB%93%9C%ED%81%AC%EB%A6%BC.webp", + name: "퍼퓸 핸드크림", + brand: "더블유드레스룸", + point: 45, winner: 1, - max: 16, - giftId: 48, + max: 30, + giftId: 70, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/KakaoTalk_20240228_195332095_09.jpg", - name: "춘식이 베이비필로우", - brand: "카카오 프렌즈", - point: 75, - winner: 1, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%8B%B8%EC%9D%B4%EB%B2%84%EA%B1%B0.webp", + name: "싸이버거 세트", + brand: "싸이버거", + point: 60, + winner: 2, + max: 25, + giftId: 71, + }, + { + image: + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EA%B5%90%EB%B3%B4%EB%AC%B8%EA%B3%A0+10000.webp", + name: "교보문고 10000원권", + brand: "교보문구", + point: 100, + winner: 2, max: 20, - giftId: 32, + giftId: 72, }, + { + image: + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/gs25.webp", + name: "GS25 5000원권", + brand: "GS25", + point: 50, + winner: 2, + max: 20, + giftId: 73, + }, + { + image: + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EC%98%81+5000.webp", + name: "올리브영 5000원권", + brand: "올리브영", + point: 50, + winner: 2, + max: 20, + giftId: 74, + }, + { image: "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/KakaoTalk_20240228_195332095_10.jpg", @@ -156,29 +198,71 @@ export const STORE_GIFT_ACTIVE: IStoreGift[] = [ { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/KakaoTalk_20240228_195332095_03.jpg", - name: "빙그레 고구마", - brand: "맘스터치", - point: 15, - winner: 2, + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%8A%A4%EB%B2%85+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", + name: "아메리카노", + brand: "스타벅스", + point: 40, + winner: 3, max: 30, - giftId: 35, + giftId: 75, + }, + + { + image: + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%88%AC%EC%8D%B8+%EB%B0%94%EB%8B%88%EB%9D%BC%EB%9D%BC%EB%96%BC.webp", + name: "바닐라라떼", + brand: "탐앤탐스", + point: 30, + winner: 1, + max: 20, + giftId: 78, + }, + { + image: + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%95%A0%EB%A6%AC%EC%8A%A4+%EB%B0%94%EB%8B%90%EB%9D%BC+%EB%94%9C%EB%9D%BC%EC%9D%B4%ED%8A%B8.webp", + name: "바닐라 딜라이트", + brand: "할리스", + point: 30, + winner: 1, + max: 20, + giftId: 80, + }, + { + image: + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%88%AC%EC%8D%B8+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", + name: "아메리카노", + brand: "투썸플레이스", + point: 45, + winner: 3, + max: 30, + giftId: 81, }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%EA%B8%B0%EB%B3%B8_100px_%ED%88%AC%EB%AA%85.png", - name: "삐약이 아바타(한정)", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%A9%94%EA%B0%80+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", + name: "아메리카노", brand: "메가커피", - point: 150, - winner: 5, - max: 5, - giftId: 56, + point: 20, + winner: 3, + max: 30, + giftId: 82, }, + + // { + // image: + // "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%EA%B8%B0%EB%B3%B8_100px_%ED%88%AC%EB%AA%85.png", + // name: "삐약이 아바타(한정)", + // brand: "메가커피", + // point: 150, + // winner: 5, + // max: 5, + // giftId: 56, + // }, { image: "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%ED%8E%AD%EA%B7%84+1.png", name: "펭귄 아바타(한정)", - brand: "메가커피", + brand: "어바웃", point: 150, winner: 5, max: 5, @@ -188,27 +272,18 @@ export const STORE_GIFT_ACTIVE: IStoreGift[] = [ image: "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%EB%B0%B0%EA%B2%BD1.png", name: "배경 프로필 1(한정)", - brand: "아바타", + brand: "어바웃", point: 100, winner: 5, max: 5, giftId: 51, }, - { - image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%EB%B0%B0%EA%B2%BD2.png", - name: "배경 프로필 2(한정)", - brand: "아바타", - point: 100, - winner: 5, - max: 5, - giftId: 52, - }, + { image: "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%EB%B0%B0%EA%B2%BD3.png", name: "배경 프로필 3(한정)", - brand: "아바타", + brand: "어바웃", point: 100, winner: 5, max: 5, @@ -218,7 +293,7 @@ export const STORE_GIFT_ACTIVE: IStoreGift[] = [ image: "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%95%84%EB%B0%94%ED%83%80+%EC%95%84%EC%9D%B4%EC%BD%98/%EB%B0%B0%EA%B2%BD/KakaoTalk_20240804_224737102_05.png", name: "배경 프로필 4(한정)", - brand: "아바타", + brand: "", point: 100, winner: 5, max: 5, @@ -250,7 +325,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%8A%A4%ED%83%80%EB%B2%85%EC%8A%A4_%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%8A%A4%EB%B2%85+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", name: "아메리카노", brand: "스타벅스", point: 30, @@ -261,7 +336,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EB%A6%AC%EB%B8%8C%EC%98%81_10000%EC%9B%90%EA%B6%8C.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EC%98%81+10000.webp", name: "기프트카드 10000원", brand: "올리브영", point: 70, @@ -301,7 +376,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EB%A6%AC%EB%B8%8C%EC%98%81_10000%EC%9B%90%EA%B6%8C.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EC%98%81+10000.webp", name: "10000원 상품권", brand: "올리브영", point: 200, @@ -339,9 +414,10 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ max: 10, giftId: 9, }, + { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC_10000.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC+10000.webp", name: "배달의 민족 10000원", brand: "배달의 민족", point: 100, @@ -351,7 +427,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EB%A6%AC%EB%B8%8C%EC%98%81_10000%EC%9B%90%EA%B6%8C.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EC%98%81+10000.webp", name: "올리브영 10000원", brand: "올리브영", point: 100, @@ -361,7 +437,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%83%90%EC%95%A4%ED%83%90%EC%8A%A4_%EB%B0%94%EB%8B%90%EB%9D%BC%EB%9D%BC%EB%96%BC.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%88%AC%EC%8D%B8+%EB%B0%94%EB%8B%88%EB%9D%BC%EB%9D%BC%EB%96%BC.webp", name: "탐앤탐스 바닐라라떼", brand: "탐앤탐스", point: 55, @@ -371,7 +447,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%8A%A4%ED%83%80%EB%B2%85%EC%8A%A4_%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%8A%A4%EB%B2%85+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", name: "스타벅스 아메리카노", brand: "스타벅스", point: 45, @@ -381,7 +457,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%95%A0%EB%A6%AC%EC%8A%A4_%EB%B0%94%EB%8B%90%EB%9D%BC+%EB%94%9C%EB%9D%BC%EC%9D%B4%ED%8A%B8.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%95%A0%EB%A6%AC%EC%8A%A4+%EB%B0%94%EB%8B%90%EB%9D%BC+%EB%94%9C%EB%9D%BC%EC%9D%B4%ED%8A%B8.webp", name: "할리스 바닐라 딜라이트", brand: "할리스", point: 60, @@ -391,7 +467,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%88%AC%EC%8D%B8_%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%ED%88%AC%EC%8D%B8+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", name: "투썸 아메리카노", brand: "투썸", point: 45, @@ -401,7 +477,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%A9%94%EA%B0%80_%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%A9%94%EA%B0%80+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", name: "메가 아메리카노", brand: "메가커피", point: 60, @@ -471,7 +547,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EB%A6%AC%EB%B8%8C%EC%98%81_10000%EC%9B%90%EA%B6%8C.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EC%98%81+10000.webp", name: "올리브영 10000원", brand: "올리브영", point: 120, @@ -501,7 +577,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC_10000.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC+10000.webp", name: "배달의민족 10000원", brand: "배달의 민족", point: 130, @@ -551,7 +627,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%A9%94%EA%B0%80_%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%A9%94%EA%B0%80+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", name: "메가 아메리카노", brand: "메가커피", point: 20, @@ -582,7 +658,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%8A%A4%ED%83%80%EB%B2%85%EC%8A%A4_%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%8A%A4%EB%B2%85+%EC%95%84%EB%A9%94%EB%A6%AC%EC%B9%B4%EB%85%B8.webp", name: "아메리카노", brand: "스타벅스", point: 30, @@ -632,7 +708,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EB%A6%AC%EB%B8%8C%EC%98%81_10000%EC%9B%90%EA%B6%8C.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EC%98%81+10000.webp", name: "올리브영 10000원", brand: "올리브영", point: 100, @@ -642,7 +718,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EB%A6%AC%EB%B8%8C%EC%98%81_10000%EC%9B%90%EA%B6%8C.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EC%98%AC%EC%98%81+10000.webp", name: "올리브영 20000원", brand: "올리브영", point: 200, @@ -652,7 +728,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC_10000.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC+10000.webp", name: "배달의민족 10000원", brand: "배달의 민족", point: 100, @@ -662,7 +738,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ }, { image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC_10000.webp", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/%EB%B0%B0%EB%AF%BC+10000.webp", name: "배달의민족 20000원", brand: "배달의 민족", point: 200, @@ -691,16 +767,6 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ max: 20, giftId: 32, }, - { - image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%8A%A4%ED%86%A0%EC%96%B4/KakaoTalk_20240228_195332095_10.jpg", - name: "공주님 발 매트", - brand: "굴뚝 강아지", - point: 80, - winner: 1, - max: 20, - giftId: 33, - }, { image: @@ -712,36 +778,7 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ max: 30, giftId: 35, }, - { - image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%EA%B8%B0%EB%B3%B8_100px_%ED%88%AC%EB%AA%85.png", - name: "삐약이 아바타(한정)", - brand: "메가커피", - point: 150, - winner: 5, - max: 5, - giftId: 56, - }, - { - image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%ED%8E%AD%EA%B7%84+1.png", - name: "펭귄 아바타(한정)", - brand: "메가커피", - point: 150, - winner: 5, - max: 5, - giftId: 54, - }, - { - image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%EB%B0%B0%EA%B2%BD1.png", - name: "배경 프로필 1(한정)", - brand: "아바타", - point: 100, - winner: 5, - max: 5, - giftId: 51, - }, + { image: "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%EB%B0%B0%EA%B2%BD2.png", @@ -752,26 +789,6 @@ export const STORE_GIFT_INACTIVE: IStoreGift[] = [ max: 5, giftId: 52, }, - { - image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%8F%99%EC%95%84%EB%A6%AC/%EB%B0%B0%EA%B2%BD3.png", - name: "배경 프로필 3(한정)", - brand: "아바타", - point: 100, - winner: 5, - max: 5, - giftId: 53, - }, - { - image: - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%95%84%EB%B0%94%ED%83%80+%EC%95%84%EC%9D%B4%EC%BD%98/%EB%B0%B0%EA%B2%BD/KakaoTalk_20240804_224737102_05.png", - name: "배경 프로필 4(한정)", - brand: "아바타", - point: 100, - winner: 5, - max: 5, - giftId: 55, - }, ]; export const STORE_GIFT = [...STORE_GIFT_ACTIVE, ...STORE_GIFT_INACTIVE]; diff --git a/stories/atoms/buttons/ArrowBackButton.stories.ts b/stories/atoms/buttons/ArrowBackButton.stories.ts deleted file mode 100644 index 1624f2aa6..000000000 --- a/stories/atoms/buttons/ArrowBackButton.stories.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react"; - -import { ArrowBackButtonUI } from "../../../components/atoms/buttons/ArrowBackButton"; - -const meta = { - title: "ATOMS/Button/ArrowBackButton", - component: ArrowBackButtonUI, - tags: ["autodocs"], -} satisfies Meta; - -export default meta; - -type Story = StoryObj; - -export const Primary: Story = { - args: { - onClick: () => {}, - }, -}; diff --git a/theme.ts b/theme.ts index c96ad353f..91702d6ee 100644 --- a/theme.ts +++ b/theme.ts @@ -68,7 +68,7 @@ const theme = extendTheme({ 900: "black", }, black: { - 500: "#303030", // 명도 46% (유지) + 500: "#424242", // 명도 46% (유지) }, mint: { 50: "#e0f7f5", @@ -334,6 +334,17 @@ const theme = extendTheme({ }, }, }, + Tabs: { + baseStyle: (props) => ({ + tab: { + _selected: { + color: props.colorScheme === "mint" ? "mint.500" : "black.500", // 활성화된 탭 텍스트 색상 + borderColor: props.colorScheme === "mint" ? "mint.500" : "black.500", // 활성화된 탭 하단 테두리 색상 + fontWeight: "semibold", + }, + }, + }), + }, }, });