forked from picktoss/pick-toss-next
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: collection detail (picktoss#303)
* feat: bookmark collection * fix: 변경된 컬렉션 api 적용 * feat: collection detail
- Loading branch information
1 parent
ddfa195
commit 4dc74de
Showing
17 changed files
with
324 additions
and
311 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 |
---|---|---|
@@ -1,20 +1,13 @@ | ||
import DetailInfoWithQuizzes from '@/features/collection/components/detail-info-with-quizzes' | ||
import FixedBottom from '@/shared/components/custom/fixed-bottom' | ||
import { Button } from '@/shared/components/ui/button' | ||
import Link from 'next/link' | ||
import DetailInfo from '@/features/collection/components/detail-info' | ||
|
||
const CollectionDetailPage = () => { | ||
return ( | ||
<> | ||
<DetailInfoWithQuizzes /> | ||
<FixedBottom> | ||
<Link href="#"> | ||
{/* 이동 /quiz/[id] - searchParams로 collectionId, createdAt, collectionName, collectionEmoji 넣어서 */} | ||
<Button className="w-full">퀴즈 시작하기</Button> | ||
</Link> | ||
</FixedBottom> | ||
</> | ||
) | ||
interface Props { | ||
params: { | ||
id: string | ||
} | ||
} | ||
|
||
const CollectionDetailPage = ({ params }: Props) => { | ||
return <DetailInfo id={Number(params.id)} /> | ||
} | ||
|
||
export default CollectionDetailPage |
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 |
---|---|---|
@@ -1,11 +1,18 @@ | ||
import { PropsWithChildren } from 'react' | ||
import { PropsWithChildren, forwardRef } from 'react' | ||
|
||
const CollectionList = ({ children }: PropsWithChildren) => { | ||
interface CollectionListProps extends PropsWithChildren {} | ||
|
||
const CollectionList = forwardRef<HTMLDivElement, CollectionListProps>(({ children }, ref) => { | ||
return ( | ||
<div className="h-[calc(100dvh-88px-114px)] overflow-y-scroll bg-gray-50 px-[16px] pb-[60px] pt-[24px]"> | ||
<div | ||
ref={ref} | ||
className="h-[calc(100dvh-88px-114px)] overflow-y-scroll bg-gray-50 px-[16px] pb-[60px] pt-[24px]" | ||
> | ||
<div className="grid grid-cols-2 gap-[11px]">{children}</div> | ||
</div> | ||
) | ||
} | ||
}) | ||
|
||
CollectionList.displayName = 'CollectionList' | ||
|
||
export default CollectionList |
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
66 changes: 0 additions & 66 deletions
66
src/features/collection/components/detail-info-with-quizzes/index.tsx
This file was deleted.
Oops, something went wrong.
110 changes: 110 additions & 0 deletions
110
src/features/collection/components/detail-info/index.tsx
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,110 @@ | ||
'use client' | ||
|
||
import QuizCard from '@/features/quiz/components/quiz-card' | ||
import { useCollectionInfo } from '@/requests/collection/hooks' | ||
import CategoryTag from '@/shared/components/custom/category-tag' | ||
import FixedBottom from '@/shared/components/custom/fixed-bottom' | ||
import Loading from '@/shared/components/custom/loading' | ||
import { Button } from '@/shared/components/ui/button' | ||
import Text from '@/shared/components/ui/text' | ||
import { useUser } from '@/shared/hooks/use-user' | ||
import Link from 'next/link' | ||
import { useMemo } from 'react' | ||
|
||
interface Props { | ||
id: number | ||
} | ||
|
||
const DetailInfo = ({ id }: Props) => { | ||
const { user } = useUser() | ||
const { data: collectionData } = useCollectionInfo(id) | ||
|
||
const quizCounts = useMemo(() => { | ||
if (!collectionData?.quizzes) return { multiple: 0, ox: 0 } | ||
|
||
return collectionData.quizzes.reduce( | ||
(acc, quiz) => { | ||
if (quiz.quizType === 'MULTIPLE_CHOICE') { | ||
acc.multiple += 1 | ||
} else if (quiz.quizType === 'MIX_UP') { | ||
acc.ox += 1 | ||
} | ||
return acc | ||
}, | ||
{ multiple: 0, ox: 0 } | ||
) | ||
}, [collectionData?.quizzes]) | ||
|
||
const isMine = user?.id === collectionData?.member.creatorId | ||
|
||
/** TODO: Spinner로 대체 */ | ||
if (!collectionData) return <Loading center size="xs" /> | ||
|
||
return ( | ||
<> | ||
<div> | ||
<div className="flex flex-col items-center pb-[27px] pt-[16px]"> | ||
<div className="flex-center size-[64px] rounded-full bg-background-base-02 text-hero"> | ||
{collectionData.emoji} | ||
</div> | ||
<Text as="h1" typography="title2" className="mt-[16px]"> | ||
{collectionData.name} | ||
</Text> | ||
<CategoryTag title={collectionData.collectionCategory} className="mt-[10px]" /> | ||
</div> | ||
<div className="h-px w-full bg-border-divider" /> | ||
<div className="p-[24px_16px_64px_16px]"> | ||
<div> | ||
<Text typography="subtitle1-bold" className="text-text-primary"> | ||
{quizCounts.multiple + quizCounts.ox} 문제 | ||
</Text> | ||
<div className="mt-[8px] flex items-center gap-[8px]"> | ||
<Text typography="text1-medium" className="text-text-sub"> | ||
객관식 {quizCounts.multiple} | ||
</Text> | ||
<div className="size-[3px] rounded-full bg-background-container-01" /> | ||
<Text typography="text1-medium" className="text-text-sub"> | ||
O/X {quizCounts.ox} | ||
</Text> | ||
</div> | ||
</div> | ||
<Text as="p" typography="text1-medium" className="mt-[24px] text-text-secondary"> | ||
{collectionData.description} | ||
</Text> | ||
</div> | ||
</div> | ||
|
||
{isMine && ( | ||
<div className="flex-1 bg-background-base-02 px-[16px] py-[24px]"> | ||
<div className="flex flex-col gap-[12px]"> | ||
{collectionData.quizzes.map((quiz) => ( | ||
<QuizCard | ||
header={ | ||
<div className="flex items-center justify-between text-icon-tertiary"> | ||
<Text typography="title3" className="text-text-accent"> | ||
Q. | ||
</Text> | ||
|
||
{/* 내가 만든 컬렉션일 경우 디렉토리 > 문서이름 이런식으로 breadcrumb 필요 */} | ||
{/* <Text typography='text2-medium' color='caption'>전공 공부 {'>'} 최근이슈</Text> */} | ||
</div> | ||
} | ||
key={quiz.id} | ||
quiz={quiz} | ||
/> | ||
))} | ||
</div> | ||
</div> | ||
)} | ||
|
||
<FixedBottom> | ||
<Link href="#"> | ||
{/* 이동 /quiz/[id] - searchParams로 collectionId, createdAt, collectionName, collectionEmoji 넣어서 */} | ||
<Button className="w-full">퀴즈 시작하기</Button> | ||
</Link> | ||
</FixedBottom> | ||
</> | ||
) | ||
} | ||
|
||
export default DetailInfo |
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
Oops, something went wrong.