-
Notifications
You must be signed in to change notification settings - Fork 1
๐[Design] ํ๋กํ ํ์ด์ง ๋ ์ด์์ ๊ตฌํ #119 #152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6d35f91
299df72
4dfce6e
dfe8742
2fb101a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import React from 'react'; | ||
|
|
||
| function Profile() { | ||
| return ( | ||
| <div> | ||
| <div className="bg-black">profile page</div> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| export default Profile; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,12 @@ | ||
| import ProfilePage from '@/features/profile/components/ProfilePage'; | ||
| import React from 'react'; | ||
|
|
||
| const Profile = () => { | ||
| return <div>Profile</div>; | ||
| return ( | ||
| <> | ||
| <ProfilePage /> | ||
| </> | ||
| ); | ||
| }; | ||
|
|
||
| export default Profile; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,17 @@ | ||
| 'use client'; | ||
| import { useState } from 'react'; | ||
| import React, { useState } from 'react'; | ||
| import { IcSorting } from '../../../public/icons/index'; | ||
|
|
||
| interface SortingButtonProps { | ||
| interface SortingButtonProps extends React.ComponentPropsWithoutRef<'button'> { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. export ๋์ง ์๋ Props ํ์
์ ์์ฆ Props์ฐ๋ ๊ฒ ๊ฐ์์. |
||
| variant: 'byDeadline' | 'byDate'; | ||
| onClickSorting: (sortBy: string) => void; | ||
| } | ||
|
|
||
| function SortingButton({ variant, onClickSorting }: SortingButtonProps) { | ||
| function SortingButton({ | ||
| variant, | ||
| onClickSorting, | ||
| ...buttonProps | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...props๊ฐ ์ ๋ง ๋ฆฌํฉํ ๋ง ๋ด์ฑ๋ ๊ธธ๋ฌ์ฃผ๊ณ , ํ์ ์์ ์ ์ด๋ชปํ๊ฒ ๋ง๋๋ ๊ฒ ๊ฐ์์. ๊ทธ๋์ ์กฐ๊ธ ๋ ํ๋กญ์ค๋ ๋ช ์์ ์ผ๋ก ์์ฑํด์ฃผ๋ ๊ฒ์ด ์ข์ต๋๋ค. |
||
| }: SortingButtonProps) { | ||
| const [isActive, setIsActive] = useState(false); | ||
|
|
||
| const onClick = (): void => { | ||
|
|
@@ -37,6 +41,7 @@ function SortingButton({ variant, onClickSorting }: SortingButtonProps) { | |
|
|
||
| return ( | ||
| <button | ||
| {...buttonProps} | ||
| className={`flex h-[40px] items-center rounded-xl border px-[12px] py-[8px] text-sm font-medium ${ | ||
| variant === 'byDeadline' && isActive | ||
| ? 'border-green-normal-01 text-green-normal-01' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,17 @@ | ||
| export const BOOK_TABS = ['์ ์ฒด', '์์ ์ฑ ', '์ง์ ์ฑ '] as const; | ||
|
|
||
| export const CONTENT_TABS = ['๋ชจ์', '๊ตํ'] as const; | ||
| export const MY_PAGE_TABS = [ | ||
| '๋์ ๋ชจ์', | ||
| '๋ด๊ฐ ๋ง๋ ๋ชจ์', | ||
| '๋์ ๋ฆฌ๋ทฐ', | ||
|
|
||
| export const CLUB_TABS = ['๋์ ๋ชจ์', '๋ด๊ฐ ๋ง๋ ๋ชจ์', '๋์ ๋ฆฌ๋ทฐ'] as const; | ||
|
|
||
| export const EXCHANGE_TABS = [ | ||
| '๋์ ๊ตํ', | ||
| '๋ด๊ฐ ๋ฑ๋กํ ์ฑ ', | ||
| '๊ตํ ๋ฆฌ๋ทฐ', | ||
| ] as const; | ||
|
|
||
| export type TabType = 'MAIN_TAB' | 'SUB_TAB'; | ||
| export type BookTab = (typeof BOOK_TABS)[number]; | ||
| export type ContentTab = (typeof CONTENT_TABS)[number]; | ||
| export type MyPageTab = (typeof MY_PAGE_TABS)[number]; | ||
| export type ClubTab = (typeof CLUB_TABS)[number]; | ||
| export type ExchangeTab = (typeof EXCHANGE_TABS)[number]; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import Profile from './profile/Profile'; | ||
|
|
||
| function Header() { | ||
| return ( | ||
| <div | ||
| className="flex w-full min-w-[336px] flex-col items-center pb-[20px] pt-[24px] sm:pl-[20px] sm:pr-[19px] md:px-[24px] lg:px-[102px]" | ||
| role="upper" | ||
| > | ||
| <h1 className="w-full min-w-[336px] text-xl font-bold text-gray-black"> | ||
| ๋ง์ด ํ์ด์ง | ||
| </h1> | ||
| <Profile /> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| export default Header; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| 'use client'; | ||
| import Tab from '@/components/tab/Tab'; | ||
| import { CONTENT_TABS, ContentTab } from '@/constants'; | ||
| import { useState } from 'react'; | ||
| import ClubContents from './clubs/ClubContents'; | ||
| import ExchangeContents from './exchange/ExchangeContents'; | ||
|
|
||
| function MainContent() { | ||
| const [selectedTab, setSelectedTab] = useState<ContentTab>(CONTENT_TABS[0]); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์ ์๊ฐ์๋ useSelectTab์ผ๋ก ํ
์ ํ๋๊ตฌ์ฑํ๊ณ , ์ฟผ๋ฆฌํ๋ผ๋ฏธํฐ๋ฅผ ํ๋์ ์ ์ญ์ ์ธ ์ํ๋ก ์ฐ์๋ฉด ์ข์์. |
||
|
|
||
| return ( | ||
| <div> | ||
| <div className="w-full border-b-2 sm:px-5 md:px-6 lg:px-[102px]"> | ||
| <Tab | ||
| items={CONTENT_TABS} | ||
| activeTab={selectedTab} | ||
| onTabChange={(item) => setSelectedTab(item)} | ||
| tabType="MAIN_TAB" | ||
| /> | ||
| </div> | ||
| {selectedTab === CONTENT_TABS[0] ? ( | ||
| <ClubContents /> | ||
| ) : ( | ||
| <ExchangeContents /> | ||
| )} | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| export default MainContent; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import Header from './Header'; | ||
| import MainContent from './MainContent'; | ||
|
|
||
| function ProfilePage() { | ||
| return ( | ||
| <div className="flex w-full min-w-[375px] flex-col"> | ||
| <Header /> | ||
| <MainContent /> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| export default ProfilePage; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import SortingButton from '@/components/sorting-button/SortingButton'; | ||
| import { CLUB_TABS, ClubTab } from '@/constants'; | ||
| import { useState } from 'react'; | ||
| import JoinedClubList from './JoinedClubList'; | ||
| import MyReviewList from './MyReviewList'; | ||
| import HostedClubList from './HostedClubsList'; | ||
| import Tab from '@/components/tab/Tab'; | ||
|
|
||
| export default function ClubContents() { | ||
| const [sortBy, setSortBy] = useState<string | undefined>('NEWEST'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ํ๋์ฝ๋ฉ์ด ์๋๋ผ, enum as const ์ ์ธ๋ ๊ฐ์ ๋ฉค๋ฒ๊ฐ์ด ๋ค์ด์ค๋ฉด ์ข์ ๊ฒ ๊ฐ์์. ValueOf <- ์ฐพ์๋ณด์๋ฉด ์ข์ต๋๋ค. type ValueOf = T[keyof T]; KeyOf TypeOf |
||
| const [selectedList, setSelectedList] = useState<ClubTab>(CLUB_TABS[0]); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์กฐ๊ธ ๋ ๋น์ฆ๋์ค ๋ก์ง์ ์ข ๋ ๋ณด๊ธฐ ์ฝ๊ฒ ๊ฐ์ ํ๋ฉด ์ข์ ๊ฒ ๊ฐ์์ |
||
|
|
||
| const renderList = (selectedList: ClubTab) => { | ||
| switch (selectedList) { | ||
| case CLUB_TABS[0]: | ||
| return <JoinedClubList />; | ||
| case CLUB_TABS[1]: | ||
| return <HostedClubList />; | ||
| case CLUB_TABS[2]: | ||
| return <MyReviewList />; | ||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <div | ||
| className="min-h-screen w-full flex-grow bg-gray-light-02 pt-3 sm:px-[20px] sm:pb-[44px] md:px-[24px] md:pb-[45px] lg:px-[102px] lg:pb-[41px]" | ||
| role="main" | ||
| > | ||
| <div className="flex items-center justify-between gap-x-2 sm:overflow-auto sm:whitespace-nowrap sm:[&::-webkit-scrollbar]:hidden"> | ||
| <Tab | ||
| items={CLUB_TABS} | ||
| activeTab={selectedList} | ||
| onTabChange={(item) => setSelectedList(item)} | ||
| tabType="SUB_TAB" | ||
| /> | ||
|
|
||
| <SortingButton | ||
| variant="byDate" | ||
| onClickSorting={(order) => { | ||
| setSortBy(order); | ||
| console.log(sortBy); | ||
| }} | ||
| /> | ||
| </div> | ||
| <div className="pt-[18px]">{renderList(selectedList)}</div> | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function HostedClubList() { | ||
| return <div>๋ด๊ฐ ๋ง๋ ๋ชจ์ ๋ทฐ</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function JoinedClubList() { | ||
| return <div>๋์ ๋ชจ์ ๋ทฐ</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function MyReviewList() { | ||
| return <div>๋์ ๋ฆฌ๋ทฐ ๋ทฐ</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import SortingButton from '@/components/sorting-button/SortingButton'; | ||
| import { EXCHANGE_TABS, ExchangeTab } from '@/constants'; | ||
| import { useState } from 'react'; | ||
| import TradeRecords from './TradeRecords'; | ||
| import MyRegisteredBooks from './MyRegisteredBooks'; | ||
| import TradeReviews from './TradeReviews'; | ||
| import Tab from '@/components/tab/Tab'; | ||
|
|
||
| export default function ClubContents() { | ||
| const [sortBy, setSortBy] = useState<string | undefined>('NEWEST'); | ||
| const [selectedList, setSelectedList] = useState<ExchangeTab>( | ||
| EXCHANGE_TABS[0], | ||
| ); | ||
|
|
||
| const renderList = (selectedList: ExchangeTab) => { | ||
| switch (selectedList) { | ||
| case EXCHANGE_TABS[0]: | ||
| return <TradeRecords />; | ||
| case EXCHANGE_TABS[1]: | ||
| return <MyRegisteredBooks />; | ||
| case EXCHANGE_TABS[2]: | ||
| return <TradeReviews />; | ||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <div | ||
| className="min-h-screen w-full flex-grow bg-gray-light-02 pt-3 sm:px-[20px] sm:pb-[44px] md:px-[24px] md:pb-[45px] lg:px-[102px] lg:pb-[41px]" | ||
| role="main" | ||
| > | ||
| <div className="flex items-center justify-between gap-x-2 sm:overflow-auto sm:whitespace-nowrap sm:[&::-webkit-scrollbar]:hidden"> | ||
| <Tab | ||
| items={EXCHANGE_TABS} | ||
| activeTab={selectedList} | ||
| onTabChange={(item) => setSelectedList(item)} | ||
| tabType="SUB_TAB" | ||
| /> | ||
|
|
||
| <SortingButton | ||
| variant="byDate" | ||
| onClickSorting={(order) => { | ||
| setSortBy(order); | ||
| console.log(sortBy); | ||
| }} | ||
| /> | ||
| </div> | ||
| <div className="pt-[18px]">{renderList(selectedList)}</div> | ||
| </div> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function MyRegisteredBooks() { | ||
| return <div>๋ด๊ฐ ๋ฑ๋กํ ์ฑ </div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function TradeRecords() { | ||
| return <div>๋์ ๊ตํ ๊ธฐ๋ก</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function TradeReviews() { | ||
| return <div>๊ตํ ๋ฆฌ๋ทฐ</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| function Profile() { | ||
| return <div className="mt-5 flex h-[200px] w-full min-w-[336px]">ํ๋กํ</div>; | ||
| } | ||
| export default Profile; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ํ๋๊ทธ๋จผํธ๊ฐ ํ์์์ ๊ฒ ๊ฐ์ต๋๋ค!