From b11f524edf193381725820c261c1f6fa9541a4f0 Mon Sep 17 00:00:00 2001 From: malloc3141 Date: Wed, 15 Jan 2025 18:34:44 +0900 Subject: [PATCH] feat: refactor Tag component to LightTag, impl custom tooltip --- packages/web/src/app/proposal/page.tsx | 20 ++------ .../web/src/common/components/PageTitle.tsx | 7 +-- .../components/Tag/{Tag.tsx => LightTag.tsx} | 11 ++--- .../proposal/components/ExpenditureTable.tsx | 35 +++++++------- .../proposal/components/IncomeTable.tsx | 28 ++++++----- .../proposal/components/TotalTable.tsx | 22 +++++---- .../proposal/components/ViewResult.tsx | 14 +++--- .../_atomic/ExpenditureHelpButton.tsx | 46 +++++++++++++++++++ .../services/_mock/mockProposalTableData.ts | 9 ++++ packages/web/src/utils/getTagDetail.ts | 4 +- .../web/stories/Buttons/Button.stories.tsx | 4 +- packages/web/stories/Tag.stories.tsx | 8 ++-- pnpm-lock.yaml | 2 +- 13 files changed, 130 insertions(+), 80 deletions(-) rename packages/web/src/common/components/Tag/{Tag.tsx => LightTag.tsx} (92%) create mode 100644 packages/web/src/features/proposal/components/_atomic/ExpenditureHelpButton.tsx diff --git a/packages/web/src/app/proposal/page.tsx b/packages/web/src/app/proposal/page.tsx index 794618b..d066a27 100644 --- a/packages/web/src/app/proposal/page.tsx +++ b/packages/web/src/app/proposal/page.tsx @@ -15,7 +15,9 @@ import { mockExpenditureData, mockIncomeData, mockTotalData, + mockViewResultData, } from "@sparcs-students/web/features/proposal/services/_mock/mockProposalTableData"; +import PageTitle from "@sparcs-students/web/common/components/PageTitle"; const Proposal = () => ( // const [semester, setSemester] = useState(""); // 2022~2028년, 봄학기/가을학기 @@ -23,15 +25,7 @@ const Proposal = () => ( // const [organization, setOrganization] = useState(""); - - 예결산 조회 - + 예결산 조회 @@ -45,13 +39,7 @@ const Proposal = () => ( - + diff --git a/packages/web/src/common/components/PageTitle.tsx b/packages/web/src/common/components/PageTitle.tsx index 6eb8d69..e4ede9f 100644 --- a/packages/web/src/common/components/PageTitle.tsx +++ b/packages/web/src/common/components/PageTitle.tsx @@ -7,10 +7,11 @@ const PageTitleInner = styled.div` position: relative; width: fit-content; font-family: ${({ theme }) => theme.fonts.FAMILY.PRETENDARD}; - font-size: 32px; - line-height: 48px; + font-size: 30px; + line-height: 40px; font-weight: ${({ theme }) => theme.fonts.WEIGHT.SEMIBOLD}; - color: ${({ theme }) => theme.colors.BLACK}; + color: ${({ theme }) => theme.colors.GREEN[800]}; + padding: 0 80px; `; const PageTitle: React.FC = ({ diff --git a/packages/web/src/common/components/Tag/Tag.tsx b/packages/web/src/common/components/Tag/LightTag.tsx similarity index 92% rename from packages/web/src/common/components/Tag/Tag.tsx rename to packages/web/src/common/components/Tag/LightTag.tsx index 6b7bbb2..89a9853 100644 --- a/packages/web/src/common/components/Tag/Tag.tsx +++ b/packages/web/src/common/components/Tag/LightTag.tsx @@ -1,7 +1,7 @@ import React from "react"; import styled from "styled-components"; -type TagColor = +export type LightTagColor = | "GREEN800" | "GREEN600" | "GREEN100" @@ -20,7 +20,7 @@ type TagColor = | "THISTLE" | "CHERRY"; -const TagInner = styled.div<{ color: TagColor; width: string }>` +const TagInner = styled.div<{ color: LightTagColor; width: string }>` position: relative; width: ${({ width }) => width}; padding: ${({ width }) => (width === "fit-content" ? "4px 12px" : "4px 0px")}; @@ -89,11 +89,11 @@ const TagInner = styled.div<{ color: TagColor; width: string }>` `; interface TagProps extends React.PropsWithChildren { - color?: TagColor; + color?: LightTagColor; width?: string; } -const Tag: React.FC = ({ +const LightTag: React.FC = ({ children =
, color = "BLUE", width = "fit-content", @@ -103,5 +103,4 @@ const Tag: React.FC = ({ ); -export type { TagColor }; -export default Tag; +export default LightTag; diff --git a/packages/web/src/features/proposal/components/ExpenditureTable.tsx b/packages/web/src/features/proposal/components/ExpenditureTable.tsx index c68e61f..86751c5 100644 --- a/packages/web/src/features/proposal/components/ExpenditureTable.tsx +++ b/packages/web/src/features/proposal/components/ExpenditureTable.tsx @@ -13,7 +13,7 @@ import { BudgetDivisionIncomeE, BudgetDomainE, } from "@sparcs-students/interface/common/enum/budget.enum"; -import Tag from "@sparcs-students/web/common/components/Tag/Tag"; +import LightTag from "@sparcs-students/web/common/components/Tag/LightTag"; import { getDarkTagDetail, getTagDetail, @@ -26,8 +26,7 @@ import { import { useFormatter } from "next-intl"; import DetailButton from "@sparcs-students/web/features/proposal/components/_atomic/DetailButton"; import DarkTag from "@sparcs-students/web/common/components/Tag/DarkTag"; -import { Tooltip } from "@mui/material"; -import HelpOutlineButton from "@mui/icons-material/HelpOutline"; +import ExpenditureHelpButton from "./_atomic/ExpenditureHelpButton"; export interface ExpenditureProps { code: number; @@ -57,15 +56,15 @@ const columns = [ switch (Math.trunc(info.getValue() / 100)) { case 1: case 4: - return {info.getValue()}; + return {info.getValue()}; case 2: case 5: - return {info.getValue()}; + return {info.getValue()}; case 3: case 6: - return {info.getValue()}; + return {info.getValue()}; default: - return -; + return -; } }, size: 80, @@ -78,7 +77,7 @@ const columns = [ info.getValue(), budgetDomainTagList, ); - return {text}; + return {text}; }, size: 80, }), @@ -90,7 +89,7 @@ const columns = [ info.getValue(), budgetDivisionIncomeTagList, ); - return {text}; + return {text}; }, size: 120, }), @@ -141,12 +140,16 @@ const columns = [ header: "비율", cell: info => { if (info.getValue() > 100) { - return {info.getValue().toFixed(1)}%; + return ( + {info.getValue().toFixed(1)}% + ); } if (info.getValue() <= 100) { - return {info.getValue().toFixed(1)}%; + return ( + {info.getValue().toFixed(1)}% + ); } - return -; + return -; }, size: 90, }), @@ -168,10 +171,10 @@ const columns = [ case "사후승인": return {info.getValue()}; default: - return -; + return -; } }, - // TODO: Add Tag by enum + // TODO: Add LightTag by enum size: 90, }), columnHelper.accessor("explanation", { @@ -196,9 +199,7 @@ const ExpenditureTable: React.FC = ({ data }) => { 지출 - - - + diff --git a/packages/web/src/features/proposal/components/IncomeTable.tsx b/packages/web/src/features/proposal/components/IncomeTable.tsx index 4be5fbf..6dba36e 100644 --- a/packages/web/src/features/proposal/components/IncomeTable.tsx +++ b/packages/web/src/features/proposal/components/IncomeTable.tsx @@ -8,7 +8,7 @@ import { useReactTable, } from "@tanstack/react-table"; import Table from "@sparcs-students/web/common/components/Table"; -import Tag from "@sparcs-students/web/common/components/Tag/Tag"; +import LightTag from "@sparcs-students/web/common/components/Tag/LightTag"; import { getTagDetail } from "@sparcs-students/web/utils/getTagDetail"; import { budgetDivisionIncomeTagList, @@ -48,15 +48,15 @@ const columns = [ switch (Math.trunc(info.getValue() / 100)) { case 1: case 4: - return {info.getValue()}; + return {info.getValue()}; case 2: case 5: - return {info.getValue()}; + return {info.getValue()}; case 3: case 6: - return {info.getValue()}; + return {info.getValue()}; default: - return -; + return -; } }, size: 80, @@ -69,7 +69,7 @@ const columns = [ info.getValue(), budgetDomainTagList, ); - return {text}; + return {text}; }, size: 80, }), @@ -81,7 +81,7 @@ const columns = [ info.getValue(), budgetDivisionIncomeTagList, ); - return {text}; + return {text}; }, size: 120, }), @@ -120,12 +120,16 @@ const columns = [ header: "비율", cell: info => { if (info.getValue() > 100) { - return {info.getValue().toFixed(1)}%; + return ( + {info.getValue().toFixed(1)}% + ); } if (info.getValue() <= 100) { - return {info.getValue().toFixed(1)}%; + return ( + {info.getValue().toFixed(1)}% + ); } - return -; + return -; }, size: 90, }), @@ -147,10 +151,10 @@ const columns = [ case "사후승인": return {info.getValue()}; default: - return -; + return -; } }, - // TODO: Add Tag by enum + // TODO: Add LightTag by enum size: 90, }), columnHelper.accessor("explanation", { diff --git a/packages/web/src/features/proposal/components/TotalTable.tsx b/packages/web/src/features/proposal/components/TotalTable.tsx index bfeb84c..524d915 100644 --- a/packages/web/src/features/proposal/components/TotalTable.tsx +++ b/packages/web/src/features/proposal/components/TotalTable.tsx @@ -10,7 +10,7 @@ import { import Table from "@sparcs-students/web/common/components/Table"; import { BudgetDomainE } from "@sparcs-students/interface/common/enum/budget.enum"; import { useFormatter } from "next-intl"; -import Tag from "@sparcs-students/web/common/components/Tag/Tag"; +import LightTag from "@sparcs-students/web/common/components/Tag/LightTag"; import { getTagDetail } from "@sparcs-students/web/utils/getTagDetail"; import { budgetDomainTagList } from "@sparcs-students/web/constants/tableTagList"; @@ -37,7 +37,7 @@ const columns = [ info.getValue(), budgetDomainTagList, ); - return {text}; + return {text}; }, size: 150, }), @@ -47,13 +47,13 @@ const columns = [ cell: info => { switch (info.getValue()) { case "수입": - return {info.getValue()}; + return {info.getValue()}; case "지출": - return {info.getValue()}; + return {info.getValue()}; case "총계": - return {info.getValue()}; + return {info.getValue()}; default: - return -; + return -; } // TODO: use enum for return }, @@ -88,12 +88,16 @@ const columns = [ header: "비율", cell: info => { if (info.getValue() > 100) { - return {info.getValue().toFixed(1)}%; + return ( + {info.getValue().toFixed(1)}% + ); } if (info.getValue() <= 100) { - return {info.getValue().toFixed(1)}%; + return ( + {info.getValue().toFixed(1)}% + ); } - return -; + return -; }, size: 150, }), diff --git a/packages/web/src/features/proposal/components/ViewResult.tsx b/packages/web/src/features/proposal/components/ViewResult.tsx index 57e7ba8..1239073 100644 --- a/packages/web/src/features/proposal/components/ViewResult.tsx +++ b/packages/web/src/features/proposal/components/ViewResult.tsx @@ -1,5 +1,3 @@ -"use client"; - import React from "react"; import FlexWrapper from "@sparcs-students/web/common/components/FlexWrapper"; @@ -12,7 +10,7 @@ import { } from "@tanstack/react-table"; import Table from "@sparcs-students/web/common/components/Table"; -interface ViewResultProps { +export interface ViewResultProps { fileName: string; organization: string; period: string; @@ -56,11 +54,11 @@ const columns = [ ]; const ViewResult: React.FC = ({ - fileName = "전산학부 24년도 예산안", - organization = "전산학부", - period = "2024년도 하반기", - headPerson = "김스튜", - submitDate = new Date(), + fileName, + organization, + period, + headPerson, + submitDate, }) => { const tableData = [ { diff --git a/packages/web/src/features/proposal/components/_atomic/ExpenditureHelpButton.tsx b/packages/web/src/features/proposal/components/_atomic/ExpenditureHelpButton.tsx new file mode 100644 index 0000000..d0e67dd --- /dev/null +++ b/packages/web/src/features/proposal/components/_atomic/ExpenditureHelpButton.tsx @@ -0,0 +1,46 @@ +import HelpOutlineButton from "@mui/icons-material/HelpOutline"; +import React, { useState } from "react"; +import FlexWrapper from "@sparcs-students/web/common/components/FlexWrapper"; +import styled from "styled-components"; + +const ToolTipWrapper = styled.div` + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 16px 20px; + font-size: 16px; + line-height: 20px; + text-align: center; + + width: 340px; + box-shadow: 0px 8px 8px rgba(0, 0, 0, 0.25); + border-radius: 4px; +`; + +const ExpenditureHelpButton = () => { + const [showTooltip, setShowTooltip] = useState(false); + const handleMouseEnter = () => { + setShowTooltip(true); + }; + + const handleMouseLeave = () => { + setShowTooltip(false); + }; + + return ( + + + {showTooltip && ( + + 지출 항목을 클릭하면 각 사업의 상세 설명을 확인할 수 있습니다. + + )} + + ); +}; + +export default ExpenditureHelpButton; diff --git a/packages/web/src/features/proposal/services/_mock/mockProposalTableData.ts b/packages/web/src/features/proposal/services/_mock/mockProposalTableData.ts index a2089fa..715da49 100644 --- a/packages/web/src/features/proposal/services/_mock/mockProposalTableData.ts +++ b/packages/web/src/features/proposal/services/_mock/mockProposalTableData.ts @@ -6,6 +6,15 @@ import { } from "@sparcs-students/interface/common/enum/budget.enum"; import { ExpenditureProps } from "@sparcs-students/web/features/proposal/components/ExpenditureTable"; import { TotalProps } from "@sparcs-students/web/features/proposal/components/TotalTable"; +import { ViewResultProps } from "@sparcs-students/web/features/proposal/components/ViewResult"; + +export const mockViewResultData: ViewResultProps = { + fileName: "전산학부 24년도 예산안", + organization: "전산학부", + period: "2024년도 하반기", + headPerson: "김스튜", + submitDate: Date(), +}; export const mockIncomeData: IncomeProps[] = [ { diff --git a/packages/web/src/utils/getTagDetail.ts b/packages/web/src/utils/getTagDetail.ts index 3d70e3e..7db4c08 100644 --- a/packages/web/src/utils/getTagDetail.ts +++ b/packages/web/src/utils/getTagDetail.ts @@ -1,9 +1,9 @@ -import { TagColor } from "@sparcs-students/web/common/components/Tag/Tag"; +import { LightTagColor } from "@sparcs-students/web/common/components/Tag/LightTag"; import { DarkTagColor } from "@sparcs-students/web/common/components/Tag/DarkTag"; interface StatusDetail { text: string; - color: TagColor; + color: LightTagColor; } interface DarkStatusDetail { diff --git a/packages/web/stories/Buttons/Button.stories.tsx b/packages/web/stories/Buttons/Button.stories.tsx index f817cd5..e36f8a0 100644 --- a/packages/web/stories/Buttons/Button.stories.tsx +++ b/packages/web/stories/Buttons/Button.stories.tsx @@ -4,7 +4,7 @@ import React from "react"; import { fn } from "@storybook/test"; import Button from "@sparcs-students/web/common/components/Buttons/Button"; -import Tag from "@sparcs-students/web/common/components/Tag/Tag"; +import LightTag from "@sparcs-students/web/common/components/Tag/LightTag"; const meta: Meta = { title: "components/Buttons/Button", @@ -38,7 +38,7 @@ export const example: Story = { args: { type: "default", buttonText: "Button", - children: Example Tag Children, + children: Example Tag Children, iconType: "person", }, }; diff --git a/packages/web/stories/Tag.stories.tsx b/packages/web/stories/Tag.stories.tsx index 9fe46f5..709feb4 100644 --- a/packages/web/stories/Tag.stories.tsx +++ b/packages/web/stories/Tag.stories.tsx @@ -1,10 +1,10 @@ import type { Meta, StoryObj } from "@storybook/react"; -import Tag from "@sparcs-students/web/common/components/Tag/Tag"; +import LightTag from "@sparcs-students/web/common/components/Tag/LightTag"; -const meta: Meta = { - title: "components/Tag", - component: Tag, +const meta: Meta = { + title: "components/LightTag", + component: LightTag, parameters: { layout: "centered", }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 079286b..39d9b48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4137,7 +4137,7 @@ packages: engines: {node: '>=0.10'} esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/LightTag==} engines: {node: '>=4.0'} estraverse@4.3.0: