From 815ff906ab68a050b26c03f6d1718c85706f0707 Mon Sep 17 00:00:00 2001 From: Eunseo Sim <55528304+simeunseo@users.noreply.github.com> Date: Mon, 25 Nov 2024 22:07:55 +0900 Subject: [PATCH 01/24] =?UTF-8?q?feat:=20Tab=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20value?= =?UTF-8?q?=EC=99=80=20label=EC=9D=84=20=EB=B6=84=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/components/common/Tab/index.tsx | 21 ++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/web/src/components/common/Tab/index.tsx b/apps/web/src/components/common/Tab/index.tsx index 5ba63fb9..cdf7cbf0 100644 --- a/apps/web/src/components/common/Tab/index.tsx +++ b/apps/web/src/components/common/Tab/index.tsx @@ -1,16 +1,17 @@ import { KeyboardEvent } from 'react'; -export interface TabData { - name: string; +export interface TabData { + value: T; + label: string; onClick: () => void; } -interface TabProps { - tabItems: TabData[]; - selectedTab: string; +interface TabProps { + tabItems: TabData[]; + selectedTab: T; } -function Tab({ tabItems, selectedTab }: TabProps) { +function Tab({ tabItems, selectedTab }: TabProps) { const handleKeyDown = (e: KeyboardEvent, onClick: () => void) => { if (e.key !== 'Enter') return; onClick(); @@ -20,15 +21,15 @@ function Tab({ tabItems, selectedTab }: TabProps) {
{tabItems.map((tab) => ( ))}
From 4d51092bbeb907dc566c1e674e2b51b367c173d0 Mon Sep 17 00:00:00 2001 From: Eunseo Sim <55528304+simeunseo@users.noreply.github.com> Date: Mon, 25 Nov 2024 22:10:45 +0900 Subject: [PATCH 02/24] =?UTF-8?q?feat:=20=EB=B3=80=EA=B2=BD=EB=90=9C=20Tab?= =?UTF-8?q?=20=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=20=EB=A7=9E=EC=B6=B0=EC=84=9C=20DashboardTab=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/components/dashboard/DashboardTab.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/web/src/components/dashboard/DashboardTab.tsx b/apps/web/src/components/dashboard/DashboardTab.tsx index 224f4424..7edffb97 100644 --- a/apps/web/src/components/dashboard/DashboardTab.tsx +++ b/apps/web/src/components/dashboard/DashboardTab.tsx @@ -15,21 +15,23 @@ const DASHBOARD_ROUTES = { function DashboardTab() { const navigate = useNavigate(); - const [selectedTab, setSelectedTab] = useState(DASHBOARD_TAB.APPLIED); + const [selectedTab, setSelectedTab] = useState('APPLIED'); - const DASHBOARD_TAB_DATA: TabData[] = [ + const DASHBOARD_TAB_DATA: TabData[] = [ { - name: DASHBOARD_TAB.APPLIED, + value: 'APPLIED', + label: DASHBOARD_TAB.APPLIED, onClick: () => { navigate({ to: DASHBOARD_ROUTES.APPLIED }); - setSelectedTab(DASHBOARD_TAB.APPLIED); + setSelectedTab('APPLIED'); }, }, { - name: DASHBOARD_TAB.OPENED, + value: 'OPENED', + label: DASHBOARD_TAB.OPENED, onClick: () => { navigate({ to: DASHBOARD_ROUTES.OPENED }); - setSelectedTab(DASHBOARD_TAB.OPENED); + setSelectedTab('OPENED'); }, }, ]; From d5e90bf053507e28560ba00e8fcf8edfc662f8aa Mon Sep 17 00:00:00 2001 From: Eunseo Sim <55528304+simeunseo@users.noreply.github.com> Date: Mon, 25 Nov 2024 22:10:55 +0900 Subject: [PATCH 03/24] =?UTF-8?q?feat:=20Tab=20story=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/stories/Tab.stories.tsx | 39 ++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/apps/web/src/stories/Tab.stories.tsx b/apps/web/src/stories/Tab.stories.tsx index 32e360b5..68bf86a9 100644 --- a/apps/web/src/stories/Tab.stories.tsx +++ b/apps/web/src/stories/Tab.stories.tsx @@ -7,6 +7,8 @@ import Tab from '@/components/common/Tab'; import type { TabData } from '@/components/common/Tab'; import type { Meta, StoryObj } from '@storybook/react'; +type TabValues = '전체' | '진행중' | '종료'; + const meta: Meta = { title: 'common/Tab', component: Tab, @@ -15,11 +17,11 @@ const meta: Meta = { tabItems: { description: '탭 아이템들의 배열입니다.', table: { - type: { summary: 'TabData[]' }, + type: { summary: 'TabData[]' }, }, }, selectedTab: { - description: '현재 선택된 탭의 이름입니다.', + description: '현재 선택된 탭의 value입니다.', control: 'text', }, }, @@ -33,15 +35,17 @@ const meta: Meta = { import Tab from '@/components/common/Tab'; // Basic usage -const [selectedTab, setSelectedTab] = useState('Tab 1'); +const [selectedTab, setSelectedTab] = useState<'tab1' | 'tab2'>('tab1'); const tabItems = [ { - name: 'Tab 1', - onClick: () => setSelectedTab('Tab 1'), + value: 'tab1', + label: 'Tab 1', + onClick: () => setSelectedTab('tab1'), }, { - name: 'Tab 2', - onClick: () => setSelectedTab('Tab 2'), + value: 'tab2', + label: 'Tab 2', + onClick: () => setSelectedTab('tab2'), }, ]; @@ -60,21 +64,24 @@ export default meta; type Story = StoryObj; interface TabWithHooksProps { - initialSelectedTab?: string; - items?: TabData[]; + initialSelectedTab?: TabValues; + items?: TabData[]; } -const defaultTabItems: TabData[] = [ +const defaultTabItems: TabData[] = [ { - name: '전체', + value: '전체', + label: '전체', onClick: () => action('onClick')('전체'), }, { - name: '진행중', + value: '진행중', + label: '진행중', onClick: () => action('onClick')('진행중'), }, { - name: '종료', + value: '종료', + label: '종료', onClick: () => action('onClick')('종료'), }, ]; @@ -83,13 +90,13 @@ const TabWithHooks = ({ initialSelectedTab = '전체', items = defaultTabItems, }: TabWithHooksProps) => { - const [selectedTab, setSelectedTab] = useState(initialSelectedTab); + const [selectedTab, setSelectedTab] = useState(initialSelectedTab); const tabItems = items.map((item) => ({ ...item, onClick: () => { - setSelectedTab(item.name); - action('onClick')(item.name); + setSelectedTab(item.value); + action('onClick')(item.value); }, })); From 473f4069b15a617b7f5efe8b8bdaa33429bafb61 Mon Sep 17 00:00:00 2001 From: Eunseo Sim <55528304+simeunseo@users.noreply.github.com> Date: Mon, 25 Nov 2024 22:11:14 +0900 Subject: [PATCH 04/24] =?UTF-8?q?feat:=20=ED=8B=B0=ED=81=B4=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=97=90=EC=84=9C=20=EC=A7=84=ED=96=89?= =?UTF-8?q?=EC=98=88=EC=A0=95/=EC=A2=85=EB=A3=8C=20=ED=83=AD=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 --- apps/web/src/components/ticle/list/index.tsx | 25 +++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/ticle/list/index.tsx b/apps/web/src/components/ticle/list/index.tsx index 507d2924..03b30745 100644 --- a/apps/web/src/components/ticle/list/index.tsx +++ b/apps/web/src/components/ticle/list/index.tsx @@ -1,9 +1,8 @@ import { Link } from '@tanstack/react-router'; import { useState } from 'react'; -import Loading from '@/components/common/Loading/Loading'; -import SearchInput from '@/components/common/SearchInput'; import Select, { Option } from '@/components/common/Select'; +import Tab, { TabData } from '@/components/common/Tab'; import { useTicleList } from '@/hooks/api/ticle'; import { formatDateTimeRange } from '@/utils/date'; @@ -30,9 +29,29 @@ const SORT_OPTIONS: Option[] = [ }, ]; +const TICLE_LIST_TAB = { + OPENED: '진행 예정 티클', + CLOSED: '종료된 티클', +} as const; + function TicleList() { const [sortOption, setSortOption] = useState