From ed98ae3041facea88de8c0e7bdc7ebcc4d1473d3 Mon Sep 17 00:00:00 2001
From: YooJin Lee <113789141+youznn@users.noreply.github.com>
Date: Thu, 15 Feb 2024 16:59:39 +0900
Subject: [PATCH] feat(fe): edit contest page card list (#1386)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 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
---------
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
Co-authored-by: SH9480P
---
.../app/(main)/_components/Badge.tsx | 2 +
.../app/(main)/_components/ContestCard.tsx | 10 +++-
.../app/(main)/_components/ContestCards.tsx | 2 +-
.../(main)/contest/_components/Columns.tsx | 16 ++++++-
.../contest/_components/ContestCardList.tsx | 48 ++++++++++++++++---
.../_components/FinishedContestTable.tsx | 3 +-
frontend-client/app/(main)/contest/page.tsx | 11 ++++-
frontend-client/types/type.ts | 8 +++-
8 files changed, 85 insertions(+), 15 deletions(-)
diff --git a/frontend-client/app/(main)/_components/Badge.tsx b/frontend-client/app/(main)/_components/Badge.tsx
index d22a3decfe..f7f8d843de 100644
--- a/frontend-client/app/(main)/_components/Badge.tsx
+++ b/frontend-client/app/(main)/_components/Badge.tsx
@@ -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',
diff --git a/frontend-client/app/(main)/_components/ContestCard.tsx b/frontend-client/app/(main)/_components/ContestCard.tsx
index 2165d3a614..ab8dceb1e3 100644
--- a/frontend-client/app/(main)/_components/ContestCard.tsx
+++ b/frontend-client/app/(main)/_components/ContestCard.tsx
@@ -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 {
@@ -36,7 +38,11 @@ export default function ContestCard({ contest }: Props) {
>
- {contest.status}
+
+ {contest.status.startsWith('registered')
+ ? 'registered'
+ : contest.status}
+
{contest.title}
diff --git a/frontend-client/app/(main)/_components/ContestCards.tsx b/frontend-client/app/(main)/_components/ContestCards.tsx
index e634c50f26..938a3d6abc 100644
--- a/frontend-client/app/(main)/_components/ContestCards.tsx
+++ b/frontend-client/app/(main)/_components/ContestCards.tsx
@@ -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'
diff --git a/frontend-client/app/(main)/contest/_components/Columns.tsx b/frontend-client/app/(main)/contest/_components/Columns.tsx
index baed725b28..a23fac9f4d 100644
--- a/frontend-client/app/(main)/contest/_components/Columns.tsx
+++ b/frontend-client/app/(main)/contest/_components/Columns.tsx
@@ -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'
@@ -14,6 +15,19 @@ export const columns: ColumnDef[] = [
)
},
+ {
+ header: 'Status',
+ accessorKey: 'status',
+ cell: ({ row }) => (
+
+
+ {row.original.status.startsWith('registered')
+ ? 'registered'
+ : row.original.status}
+
+
+ )
+ },
{
header: 'Starts at',
accessorKey: 'startTime',
@@ -27,6 +41,6 @@ export const columns: ColumnDef[] = [
{
header: 'Participants',
accessorKey: 'participants',
- cell: ({ row }) => row.original.id
+ cell: ({ row }) => row.original.participants
}
]
diff --git a/frontend-client/app/(main)/contest/_components/ContestCardList.tsx b/frontend-client/app/(main)/contest/_components/ContestCardList.tsx
index 75019b86ce..9b760f687a 100644
--- a/frontend-client/app/(main)/contest/_components/ContestCardList.tsx
+++ b/frontend-client/app/(main)/contest/_components/ContestCardList.tsx
@@ -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'
})
@@ -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))
@@ -50,14 +84,14 @@ export default async function Contest({
-
+
{contestChunks.map((contestChunk) => (
{contestChunk.map((contest) => (
diff --git a/frontend-client/app/(main)/contest/_components/FinishedContestTable.tsx b/frontend-client/app/(main)/contest/_components/FinishedContestTable.tsx
index 045d4c354d..e7fffddaa2 100644
--- a/frontend-client/app/(main)/contest/_components/FinishedContestTable.tsx
+++ b/frontend-client/app/(main)/contest/_components/FinishedContestTable.tsx
@@ -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"
/>
diff --git a/frontend-client/app/(main)/contest/page.tsx b/frontend-client/app/(main)/contest/page.tsx
index a288c18a39..8f31b15227 100644
--- a/frontend-client/app/(main)/contest/page.tsx
+++ b/frontend-client/app/(main)/contest/page.tsx
@@ -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'
@@ -40,17 +41,23 @@ function FinishedContestTableFallback() {
)
}
-export default function Contest() {
+export default async function Contest() {
+ const session = await auth()
return (
<>
}>
-
+
}>
diff --git a/frontend-client/types/type.ts b/frontend-client/types/type.ts
index cf62e79e6b..aa959e9666 100644
--- a/frontend-client/types/type.ts
+++ b/frontend-client/types/type.ts
@@ -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'
@@ -9,6 +14,7 @@ export interface Contest {
endTime: Date
group: { id: string; groupName: string }
status: ContestStatus
+ participants: number
}
export interface WorkbookProblem {