-
Notifications
You must be signed in to change notification settings - Fork 1
[feat] add sidebar dashboards #18
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 8 commits
8a6f373
05f682b
0d3bbc0
a091022
5acef90
6bcbf5d
e3c3a2d
bb9eabc
b376394
2566702
01d73cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,6 @@ | |
|
|
||
| .sideBarWrapper { | ||
| border-right: 1px solid var(--gray-300); | ||
| padding: 22px; | ||
| } | ||
|
|
||
| .mainWrapper { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,4 +37,6 @@ button { | |
| a { | ||
| text-decoration: none; | ||
| color: inherit; | ||
| display: inherit; | ||
| width: inherit; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,94 @@ | ||
| .dashBoards { | ||
| .dashboards { | ||
| width: 100%; | ||
| display: flex; | ||
| flex-direction: column; | ||
| justify-content: center; | ||
| gap: 6px; | ||
| } | ||
|
|
||
| .active { | ||
| color: salmon; | ||
| border-radius: 4px; | ||
| background: var(--violet-light); | ||
| } | ||
|
|
||
| .titleContainer { | ||
| display: flex; | ||
| justify-content: center; | ||
| align-items: center; | ||
| padding: 16px; | ||
| } | ||
|
|
||
| .dot { | ||
| width: 8px; | ||
| height: 8px; | ||
| border-radius: 999px; | ||
| } | ||
|
|
||
| .title, | ||
| .crown { | ||
| display: none; | ||
| color: var(--gray-500); | ||
| font-size: 18px; | ||
| font-weight: 500; | ||
| } | ||
|
|
||
| .arrowLeft, | ||
| .arrowRight { | ||
| border: 1px solid var(--gray-300); | ||
| border-right: none; | ||
| border-radius: 0; | ||
| background: var(--white); | ||
| height: 35px; | ||
| } | ||
|
|
||
| .arrowRight { | ||
| border-top: none; | ||
| } | ||
|
|
||
| .arrowLeft:disabled, | ||
| .arrowRight:disabled { | ||
| background: var(--white); | ||
| } | ||
|
|
||
| @media screen and (min-width: 768px) { | ||
| .dashboardsWrapper { | ||
| margin-top: 10px; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 15px; | ||
| } | ||
|
|
||
| .title, | ||
| .crown { | ||
| display: inline; | ||
| } | ||
|
|
||
| .crown { | ||
| margin-left: -8px; | ||
| } | ||
|
|
||
| .titleContainer { | ||
| justify-content: flex-start; | ||
| gap: 16px; | ||
| padding: 8px 10px; | ||
| } | ||
|
|
||
| .arrowWrapper { | ||
| margin-top: 20px; | ||
| } | ||
|
|
||
| .arrowLeft, | ||
| .arrowRight { | ||
| border: 1px solid var(--gray-300); | ||
| width: 40px; | ||
| height: 40px; | ||
| } | ||
|
|
||
| .arrowLeft { | ||
| border-radius: 4px 0px 0px 4px; | ||
| } | ||
|
|
||
| .arrowRight { | ||
| border-radius: 0px 4px 4px 0px; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,127 @@ | ||
| import Link from 'next/link'; | ||
| import { usePathname } from 'next/navigation'; | ||
| import type { GetDashboardsResponse } from '@/app/(with-header-sidebar)/mydashboard/_types/dashboards'; | ||
| import styles from './Dashboards.module.css'; | ||
| import type { | ||
| Dashboard, | ||
| GetDashboardsResponse, | ||
| } from '@/app/(with-header-sidebar)/mydashboard/_types/dashboards'; | ||
| import useApi from '@/app/(with-header-sidebar)/mydashboard/_hooks/useApi'; | ||
| import Image from 'next/image'; | ||
| import Button from '../Button'; | ||
| import { useState } from 'react'; | ||
| import styles from './Dashboards.module.css'; | ||
|
|
||
| export default function Dashboards() { | ||
| const pathname = usePathname(); | ||
| const PAGE_SIZE = 12; | ||
|
|
||
| export default function Dashboards() { | ||
| const [page, setPage] = useState(1); | ||
| const { data } = useApi<GetDashboardsResponse>('/dashboards', { | ||
| method: 'GET', | ||
| params: { navigationMethod: 'infiniteScroll', page: 1, size: 10 }, | ||
| params: { navigationMethod: 'pagination', page, size: PAGE_SIZE }, | ||
| }); | ||
|
|
||
| const dashboards = data?.dashboards; | ||
| const dashboards = data?.dashboards ?? []; | ||
| const totalCount = data?.totalCount ?? 0; | ||
| const totalPages = Math.ceil(totalCount / PAGE_SIZE); | ||
|
|
||
| const handlePageChange = (direction: 'next' | 'prev') => { | ||
| setPage((prevPage) => { | ||
| if (direction === 'next' && prevPage < totalPages) return prevPage + 1; | ||
| if (direction === 'prev' && prevPage > 1) return prevPage - 1; | ||
| return prevPage; | ||
| }); | ||
| }; | ||
|
|
||
| return ( | ||
| <div className={styles.dashboards}> | ||
| <DashboardList dashboards={dashboards} /> | ||
| <Pagination | ||
| currentPage={page} | ||
| totalPages={totalPages} | ||
| onPageChange={handlePageChange} | ||
| /> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| function DashboardList({ dashboards }: { dashboards: Dashboard[] }) { | ||
|
||
| return ( | ||
| <ul className={styles.dashboardsWrapper}> | ||
| {dashboards.map((board) => ( | ||
| <DashboardItem key={board.id} {...board} /> | ||
| ))} | ||
| </ul> | ||
| ); | ||
| } | ||
|
|
||
| function DashboardItem({ id, color, title, createdByMe }: Dashboard) { | ||
| const isActive = usePathname() === `/dashboard/${id}`; | ||
|
|
||
| return ( | ||
| <li> | ||
| <Link | ||
| href={`/dashboard/${id}`} | ||
| className={`link ${isActive ? styles.active : ''}`} | ||
| > | ||
| <div className={styles.titleContainer}> | ||
| <div style={{ background: color }} className={styles.dot}></div> | ||
| <span className={styles.title}>{title}</span> | ||
| {createdByMe && ( | ||
| <span className={styles.crown}> | ||
| <Image src="/icons/crown.svg" alt="μκ΄" width={15} height={12} /> | ||
| </span> | ||
| )} | ||
| </div> | ||
| </Link> | ||
| </li> | ||
| ); | ||
| } | ||
|
|
||
| function Pagination({ | ||
| currentPage, | ||
| totalPages, | ||
| onPageChange, | ||
| }: { | ||
| currentPage: number; | ||
| totalPages: number; | ||
| onPageChange: (direction: 'next' | 'prev') => void; | ||
| }) { | ||
| const isFirstPage = currentPage === 1; | ||
| const isLastPage = currentPage >= totalPages; | ||
|
|
||
| return ( | ||
| <div className={styles.dashBoards}> | ||
| {dashboards && | ||
| dashboards.map((board) => ( | ||
| <Link | ||
| key={board.id} | ||
| href={`/dashboard/${board.id}`} | ||
| className={`link ${pathname === '/dashboard/' + board.id ? styles.active : ''}`} | ||
| > | ||
| {board.title} | ||
| </Link> | ||
| ))} | ||
| <div className={styles.arrowWrapper}> | ||
| <Button | ||
| className={styles.arrowLeft} | ||
| onClick={() => onPageChange('prev')} | ||
| disabled={isFirstPage} | ||
| > | ||
| <Image | ||
| src={ | ||
| isFirstPage | ||
| ? '/icons/arrow_left_light.svg' | ||
| : '/icons/arrow_left.svg' | ||
| } | ||
| alt="μΌμͺ½μΌλ‘ μ΄λ" | ||
| width={16} | ||
| height={16} | ||
| /> | ||
| </Button> | ||
| <Button | ||
| className={styles.arrowRight} | ||
| onClick={() => onPageChange('next')} | ||
| disabled={isLastPage} | ||
| > | ||
| <Image | ||
| src={ | ||
| isLastPage | ||
| ? '/icons/arrow_right_light.svg' | ||
| : '/icons/arrow_right.svg' | ||
| } | ||
| alt="μ€λ₯Έμͺ½μΌλ‘ μ΄λ" | ||
| width={16} | ||
| height={16} | ||
| /> | ||
| </Button> | ||
| </div> | ||
| ); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
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.
μ΄κ±°.. Linkμ¬μ© μ active μΆκ°ν λ λ΄λ§λλ‘ css ν΄λμ€κ° μΆκ°κ° μλλλΌκ΅¬μ..
λλΆλͺ ν μΆκ°λ₯Όνλλ° λ₯μ€νΈκ° Link λ§μ΄νΈν λ λ λ°λ‘ μ²λ¦¬λ₯Ό νλκ²κ°μλ° ν΄λμ€κ° μ μ©μ΄μλΌμγ
μ΄λ°μμΌλ‘ μΆκ°νλ©΄ aaa μλ μ΄λ»κ² ν΄λ μ μ©μ΄μλλλ°... λ λ°λ‘ legacybasis?μΈμ§λ¨Όμ§ μμ± μΆκ°νκ³ μμμμλ‘ aνκ·Έ λ£κ³ ν΄λ μλκ³ .. css λͺ¨λμμμλ νκ·Έμ νμλ μλκ°μ§κ³ κ·Έκ²λ μ μ©μλκ³ ...
κ²°κ΅.. resetμΌλ‘ μμ
aνκ·Έλ displayλ witdh λΆλͺ¨κΊΌ css μμλ°κ² μΆκ°νμ΅λλ€
Uh oh!
There was an error while loading. Please reload this page.
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.
className={link ${isActive ? styles.active : styles.aaa}}μ¬κΈ°μ link μ λ λνλ μ μΈκ°μ???
<li></li>νκ·Έλ‘ κ°μΈμ Έμλλ° μ¬κΈ°μ μ€νμΌμ μ μ©νλ©΄ λμ§μμκΉμ???κ·Έλ¦¬κ³ μλ§
<li>νκ·Έ μμ λ©΄ Link μ€νμΌ μ μ μ© λ κ² κ°μ΅λλ€.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.
@najitwo μ κ° νκ³ μΆμλκ² κ²°κ΅ aνκ·Έλ₯Ό display blockμ²λΌ μ 체 widthλ₯Ό λ¨Ήλ건λ°
liμ μ€νμΌ μ μ©ν΄λ κ·Έ μμμΈ aνκ·Έλ inline μ€νμΌμ΄λΌ μ 체 widthλ₯Ό μλ¨ΉλλΌκ΅¬μπ«