Skip to content

Commit

Permalink
feat(fe): edit contest page card list (#1386)
Browse files Browse the repository at this point in the history
* feat: modify fetch paths based on session presence

* fix(fe): fix fetch path for the main page

* fix: fix contest card overflow error

* fix: fix card padding

* feat(fe): change badge status when registered

* feat: add status at data table

* fix(deps): update tiptap monorepo to ^2.2.2 (#1356)

* fix(deps): update tiptap monorepo to ^2.2.2

* fix: fix lockfile

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jaemin Choi <1dotolee@gmail.com>

* feat(be): implement get-contest api (#1370)

* feat(be): implement get-contest api
- 참가자 수 participants를 함께 반환하는 getContest api 구현

* docs(be): add get-contest api docs

* chore(be): modify get-contest, get-contests to include participants
- _count를 활용해 참가자수가 contest 정보에 포함되도록 설정

* test(be): modify test to use contest-with-participants

* chore(be): remove unused pipe

* chore(be): add is-visible field to problem model (#1366)

* chore(be): add is-visible field to problem model

* chore(be): modify problem input type
- problem input type에서 visible 여부 설정 가능하도록 변경

* docs(be): modify admin create-problem api docs
- input에 isVisible 설정 반영

* test(be): add is-visible to input

* test(be): add is-visible to problem input

* feat(be): add update-visibility api

* docs(be): add update-visibility api docs

* chore(be): delete useless update-visibility function

* chore(be): modify get-problem functions to check is-visible

Co-authored-by: SH9480P <realsehwan@gmail.com>

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jaemin Choi <1dotolee@gmail.com>
Co-authored-by: Jaehyeon Kim <kjhkk1020@naver.com>
Co-authored-by: SH9480P <realsehwan@gmail.com>
  • Loading branch information
5 people authored Feb 15, 2024
1 parent c52d42c commit ed98ae3
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 15 deletions.
2 changes: 2 additions & 0 deletions frontend-client/app/(main)/_components/Badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { cn } from '@/lib/utils'
import React from 'react'

const variants = {
registeredOngoing: 'bg-rose-700',
registeredUpcoming: 'bg-rose-700',
ongoing: 'bg-emerald-700',
upcoming: 'bg-blue-700',
finished: 'bg-gray-700',
Expand Down
10 changes: 8 additions & 2 deletions frontend-client/app/(main)/_components/ContestCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import TimeDiff from './TimeDiff'
const variants = {
ongoing: 'bg-gradient-to-br from-blue-500 to-blue-950',
upcoming: 'bg-gradient-to-br from-emerald-600 to-emerald-900',
finished: 'bg-gray-500'
finished: 'bg-gray-500',
registeredOngoing: 'bg-gradient-to-br from-blue-500 to-blue-950',
registeredUpcoming: 'bg-gradient-to-br from-emerald-600 to-emerald-900'
}

interface Props {
Expand All @@ -36,7 +38,11 @@ export default function ContestCard({ contest }: Props) {
>
<CardHeader className="pb-0">
<Badge type={contest.status}>
<p>{contest.status}</p>
<p>
{contest.status.startsWith('registered')
? 'registered'
: contest.status}
</p>
</Badge>
<CardTitle className="overflow-hidden text-ellipsis whitespace-nowrap text-lg font-semibold">
{contest.title}
Expand Down
2 changes: 1 addition & 1 deletion frontend-client/app/(main)/_components/ContestCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const getContests = async () => {
const data: {
ongoing: Contest[]
upcoming: Contest[]
} = await fetcher.get('contest').json()
} = await fetcher.get('contest/ongoing-upcoming').json()

data.ongoing.forEach((contest) => {
contest.status = 'ongoing'
Expand Down
16 changes: 15 additions & 1 deletion frontend-client/app/(main)/contest/_components/Columns.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client'

import Badge from '@/app/(main)/_components/Badge'
import type { Contest } from '@/types/type'
import type { ColumnDef } from '@tanstack/react-table'
import dayjs from 'dayjs'
Expand All @@ -14,6 +15,19 @@ export const columns: ColumnDef<Contest>[] = [
</p>
)
},
{
header: 'Status',
accessorKey: 'status',
cell: ({ row }) => (
<Badge type={row.original.status}>
<p>
{row.original.status.startsWith('registered')
? 'registered'
: row.original.status}
</p>
</Badge>
)
},
{
header: 'Starts at',
accessorKey: 'startTime',
Expand All @@ -27,6 +41,6 @@ export const columns: ColumnDef<Contest>[] = [
{
header: 'Participants',
accessorKey: 'participants',
cell: ({ row }) => row.original.id
cell: ({ row }) => row.original.participants
}
]
48 changes: 41 additions & 7 deletions frontend-client/app/(main)/contest/_components/ContestCardList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ import {
CarouselNext,
CarouselPrevious
} from '@/components/ui/carousel'
import { fetcher } from '@/lib/utils'
import { fetcher, fetcherWithAuth } from '@/lib/utils'
import type { Contest } from '@/types/type'
import type { Route } from 'next'
import type { Session } from 'next-auth'
import Link from 'next/link'

const getContests = async () => {
const data: {
ongoing: Contest[]
upcoming: Contest[]
} = await fetcher.get('contest').json()
} = await fetcher.get('contest/ongoing-upcoming').json()
data.ongoing.forEach((contest) => {
contest.status = 'ongoing'
})
Expand All @@ -25,16 +26,49 @@ const getContests = async () => {
return data.ongoing.concat(data.upcoming)
}

const getRegisteredContests = async () => {
const data: {
registeredOngoing: Contest[]
registeredUpcoming: Contest[]
ongoing: Contest[]
upcoming: Contest[]
} = await fetcherWithAuth
.get('contest/ongoing-upcoming-with-registered')
.json()
data.registeredOngoing.forEach((contest) => {
contest.status = 'registeredOngoing'
})
data.registeredUpcoming.forEach((contest) => {
contest.status = 'registeredUpcoming'
})
data.ongoing.forEach((contest) => {
contest.status = 'ongoing'
})
data.upcoming.forEach((contest) => {
contest.status = 'upcoming'
})
return data.ongoing.concat(
data.upcoming.concat(data.registeredOngoing.concat(data.registeredUpcoming))
)
}

export default async function Contest({
title,
type
type,
session
}: {
type: string
title: string
session?: Session | null
}) {
const data = (await getContests()).filter(
(contest) => contest.status.toLowerCase() === type.toLowerCase()
const data = (
session ? await getRegisteredContests() : await getContests()
).filter(
(contest) =>
contest.status.toLowerCase() === 'registered' + type.toLowerCase() ||
contest.status.toLowerCase() === type.toLowerCase()
)

const contestChunks = []
for (let i = 0; i < data.length; i += 3)
contestChunks.push(data.slice(i, i + 3))
Expand All @@ -50,14 +84,14 @@ export default async function Contest({
<CarouselNext />
</div>
</div>
<CarouselContent className="p-2">
<CarouselContent className="p-1">
{contestChunks.map((contestChunk) => (
<CarouselItem key={contestChunk[0].id} className="flex w-full gap-3">
{contestChunk.map((contest) => (
<Link
key={contest.id}
href={`/contest/${contest.id}` as Route}
className="block w-1/3"
className="block w-1/3 overflow-hidden p-2"
>
<ContestCard contest={contest} />
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export default async function FinishedContestTable() {
title: 'text-left w-2/5 md:w-3/6',
startTime: 'w-1/5 md:w-1/6',
endTime: 'w-1/5 md:w-1/6',
participants: 'w-1/5 md:w-1/6'
participants: 'w-1/5 md:w-1/6',
status: 'w-1/4 md:w-1/6'
}}
name="contest"
/>
Expand Down
11 changes: 9 additions & 2 deletions frontend-client/app/(main)/contest/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Skeleton } from '@/components/ui/skeleton'
import { auth } from '@/lib/auth'
import { Suspense } from 'react'
import ContestCardList from './_components/ContestCardList'
import FinishedContestTable from './_components/FinishedContestTable'
Expand Down Expand Up @@ -40,17 +41,23 @@ function FinishedContestTableFallback() {
)
}

export default function Contest() {
export default async function Contest() {
const session = await auth()
return (
<>
<div className="mb-12 flex flex-col gap-12">
<Suspense fallback={<ContestCardListFallback />}>
<ContestCardList title="Join the contest now!" type="Ongoing" />
<ContestCardList
title="Join the contest now!"
type="Ongoing"
session={session}
/>
</Suspense>
<Suspense fallback={<ContestCardListFallback />}>
<ContestCardList
title="Check out upcoming contests"
type="Upcoming"
session={session}
/>
</Suspense>
</div>
Expand Down
8 changes: 7 additions & 1 deletion frontend-client/types/type.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export type ContestStatus = 'ongoing' | 'upcoming' | 'finished'
export type ContestStatus =
| 'ongoing'
| 'upcoming'
| 'finished'
| 'registeredOngoing'
| 'registeredUpcoming'
export type Level = 'Level1' | 'Level2' | 'Level3' | 'Level4' | 'Level5'
export type Language = 'C' | 'Cpp' | 'Golang' | 'Java' | 'Python2' | 'Python3'

Expand All @@ -9,6 +14,7 @@ export interface Contest {
endTime: Date
group: { id: string; groupName: string }
status: ContestStatus
participants: number
}

export interface WorkbookProblem {
Expand Down

0 comments on commit ed98ae3

Please sign in to comment.