-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create RowButtonBlock components (#120)
- Loading branch information
Showing
6 changed files
with
317 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import Link, { LinkProps } from "next/link"; | ||
import styled from "styled-components"; | ||
|
||
interface RowButtonBlockProps { | ||
text: string; | ||
url?: string; | ||
func?: () => void; | ||
} | ||
|
||
function RowButtonBlock({ text, url, func }: RowButtonBlockProps) { | ||
return ( | ||
<>{url ? <CustomLink href={url}>{text}</CustomLink> : <Button onClick={func}>{text}</Button>}</> | ||
); | ||
} | ||
|
||
const Button = styled.button` | ||
width: 100%; | ||
padding: var(--gap-4) var(--gap-4); | ||
text-align: start; | ||
border-bottom: var(--border); | ||
`; | ||
|
||
const CustomLink = styled(Link)<LinkProps>` | ||
display: block; | ||
padding: var(--gap-4) var(--gap-4); | ||
text-align: start; | ||
border-bottom: var(--border); | ||
`; | ||
|
||
export default RowButtonBlock; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import { Badge, Progress } from "@chakra-ui/react"; | ||
import { faQuestionCircle } from "@fortawesome/pro-light-svg-icons"; | ||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||
import { useState } from "react"; | ||
import styled from "styled-components"; | ||
|
||
import { BADGE_COLOR_MAPPINGS, BADGE_INFO } from "../../constants/serviceConstants/badgeConstants"; | ||
import { SCHEME_TO_COLOR } from "../../constants/styles"; | ||
import BadgeInfoModal from "../../modals/store/badgeInfoModal/BadgeInfoModal"; | ||
|
||
interface IAttendanceBar { | ||
myScore: number; | ||
hasQuestion?: boolean; | ||
} | ||
|
||
function AttendanceBar({ myScore, hasQuestion = true }: IAttendanceBar) { | ||
const userBadge = { badge: "아메리카노", nextBadge: "망고" }; | ||
|
||
const [isBadgeModal, setIsBadgeModal] = useState(false); | ||
|
||
const { badge, nextBadge } = userBadge; | ||
|
||
const badgeColor = BADGE_COLOR_MAPPINGS[userBadge.badge]; | ||
|
||
const getBadgePoint = () => { | ||
for (let i = 0; i < BADGE_INFO.length; i++) { | ||
const badgeInfo = BADGE_INFO[i]; | ||
if (badgeInfo.badge === nextBadge) { | ||
return { | ||
nextBadgePoint: badgeInfo.minScore, | ||
badgeGap: badgeInfo.minScore - BADGE_INFO[i - 1].minScore, | ||
}; | ||
} | ||
} | ||
}; | ||
const { nextBadgePoint, badgeGap } = getBadgePoint() || {}; | ||
|
||
return ( | ||
<> | ||
<Layout> | ||
<Grade> | ||
<div> | ||
<Badge fontSize="14px" marginRight="var(--gap-2)" colorScheme={badgeColor}> | ||
{badge} | ||
</Badge> | ||
<BadgeName color={SCHEME_TO_COLOR[badgeColor] || badgeColor}>{myScore}점</BadgeName> | ||
{hasQuestion && ( | ||
<IconWrapper onClick={() => setIsBadgeModal(true)}> | ||
<FontAwesomeIcon icon={faQuestionCircle} size="sm" /> | ||
</IconWrapper> | ||
)} | ||
</div> | ||
{nextBadge && ( | ||
<div> | ||
<BadgeName color={BADGE_COLOR_MAPPINGS[nextBadge]}>{nextBadgePoint}점</BadgeName> | ||
<Badge fontSize="14px" colorScheme={BADGE_COLOR_MAPPINGS[nextBadge]} marginLeft="6px"> | ||
{nextBadge} | ||
</Badge> | ||
</div> | ||
)} | ||
</Grade> | ||
<Progress | ||
value={(1 - (nextBadgePoint - myScore) / badgeGap) * 100} | ||
height="12px" | ||
colorScheme="mintTheme" | ||
hasStripe | ||
/> | ||
</Layout> | ||
|
||
{isBadgeModal && <BadgeInfoModal setIsModal={setIsBadgeModal} />} | ||
</> | ||
); | ||
} | ||
|
||
const Layout = styled.div` | ||
margin-bottom: var(--gap-3); | ||
`; | ||
const Grade = styled.div` | ||
display: flex; | ||
justify-content: space-between; | ||
margin-bottom: var(--gap-3); | ||
align-items: center; | ||
> div { | ||
display: flex; | ||
align-items: center; | ||
} | ||
`; | ||
|
||
const BadgeName = styled.span<{ color: string }>` | ||
color: ${(props) => props.color}; | ||
font-weight: 600; | ||
`; | ||
|
||
const IconWrapper = styled.button` | ||
color: var(--gray-2); | ||
font-size: 14px; | ||
margin-left: var(--gap-2); | ||
`; | ||
|
||
export default AttendanceBar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
import dayjs from "dayjs"; | ||
import styled from "styled-components"; | ||
|
||
import Avatar from "../../components/atoms/Avatar"; | ||
import { PopOverIcon } from "../../components/atoms/Icons/PopOverIcon"; | ||
import { IFooterOptions, ModalLayout } from "../../modals/Modals"; | ||
import AttendanceBar from "./AttendanceBar"; | ||
|
||
function AttendanceModal({ type }: { type: 1 | 2 | 3 }) { | ||
const today = dayjs(); | ||
const firstDayOfMonth = today.startOf("month"); | ||
const differenceInDays = today.diff(firstDayOfMonth, "day"); | ||
const weekNumber = Math.floor(differenceInDays / 7) + 1; | ||
|
||
const footerOptions: IFooterOptions = { | ||
main: {}, | ||
isFull: true, | ||
}; | ||
|
||
return ( | ||
<> | ||
<ModalLayout | ||
title={`${dayjs().month() + 1}월 2주차 주간 체크`} | ||
headerOptions={{}} | ||
footerOptions={footerOptions} | ||
setIsModal={() => {}} | ||
> | ||
<ScoreBarWrapper> | ||
<AttendanceBar myScore={17} /> | ||
<span>임시 달성시 +10 포인트, 거북이 아바타 해금!</span> | ||
</ScoreBarWrapper> | ||
<ProfileWrapper> | ||
<span>이승주 {type === 1 ? "(동아리원)" : "(수습멤버)"}</span> | ||
<ImageWrapper> | ||
<Avatar image="" size="md" /> | ||
</ImageWrapper> | ||
</ProfileWrapper> | ||
<Container> | ||
<Info> | ||
<Item> | ||
<span>{weekNumber}주차 스터디 투표</span> | ||
<span>2 회</span> | ||
</Item> | ||
<Item> | ||
<span>{weekNumber}주차 스터디 출석</span> | ||
<span>2 회</span> | ||
</Item> | ||
<Item> | ||
<div style={{ display: "flex" }}> | ||
<span>이번 달 스터디 점수</span> | ||
<PopOverIcon | ||
title="월간 스터디 점수" | ||
text="최소 1점을 넘어야합니다. 출석을 기준으로 정규 스터디는 1회당 1점, 개인, FREE 스터디는 2회당 1점입니다." | ||
/> | ||
</div> | ||
<span>40 점</span> | ||
</Item> | ||
<Item> | ||
<span>다음 참여 정산일</span> | ||
<span> {dayjs().add(1, "month").month() + 1}월 1일</span> | ||
</Item> | ||
<Item> | ||
<span>보유 보증금</span> | ||
<span>2000원</span> | ||
</Item> | ||
</Info> | ||
</Container> | ||
<Message> | ||
{type === 2 ? ( | ||
<div> | ||
🎉신규 가입을 환영해요🎉 | ||
<br /> | ||
앞으로 열심히 활동해봐요~! | ||
</div> | ||
) : type === 1 ? ( | ||
<div> | ||
이번 달 스터디에 참여하지 않았어요. | ||
<br /> {-dayjs().add(1, "month").date(1).diff(dayjs(), "day")}일 뒤에 경고를 받습니다. | ||
</div> | ||
) : ( | ||
<div> | ||
🎉잘 하고 있어요🎉 | ||
<br /> | ||
이번주도 열심히 파이팅~! | ||
</div> | ||
)} | ||
</Message> | ||
</ModalLayout> | ||
</> | ||
); | ||
} | ||
|
||
const Message = styled.div` | ||
padding: var(--gap-2) var(--gap-3); | ||
color: var(--gray-2); | ||
border-radius: var(--rounded); | ||
background-color: var(--gray-8); | ||
`; | ||
|
||
const ProfileWrapper = styled.div` | ||
padding: 8px 0; | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
border-bottom: var(--border); | ||
> span:first-child { | ||
font-weight: 500; | ||
font-size: 16px; | ||
} | ||
`; | ||
|
||
const ScoreBarWrapper = styled.div` | ||
padding: var(--gap-2) 0; | ||
border-bottom: var(--border); | ||
display: flex; | ||
flex-direction: column; | ||
> span { | ||
font-size: 12px; | ||
color: var(--gray-3); | ||
margin-left: auto; | ||
} | ||
`; | ||
|
||
const Container = styled.div` | ||
padding: var(--gap-3) 0; | ||
display: flex; | ||
flex-direction: row; | ||
height: 100%; | ||
`; | ||
|
||
const Info = styled.div` | ||
width: 100%; | ||
display: flex; | ||
flex-direction: column; | ||
`; | ||
|
||
const ImageWrapper = styled.div` | ||
margin-left: auto; | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-start; | ||
align-items: center; | ||
> span { | ||
display: inline-block; | ||
margin-top: var(--gap-1); | ||
} | ||
`; | ||
|
||
const Item = styled.div` | ||
display: flex; | ||
justify-content: space-between; | ||
font-size: 14px; | ||
padding: var(--gap-1) 0; | ||
> span:last-child { | ||
font-weight: 600; | ||
} | ||
`; | ||
|
||
export default AttendanceModal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import AttendanceModal from "../../design/attendance/AttendanceModal"; | ||
|
||
const meta = { | ||
title: "DESIGNS/AttendanceModal", | ||
component: AttendanceModal, | ||
parameters: {}, | ||
tags: ["autodocs"], | ||
argTypes: {}, | ||
args: {}, | ||
} satisfies Meta<typeof AttendanceModal>; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof meta>; | ||
|
||
export const Primary: Story = { | ||
args: { | ||
type: 1, | ||
}, | ||
}; | ||
export const Secondary: Story = { | ||
args: { | ||
type: 2, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters