From 8a361c4077bb4d954ad0dbf69981623ebaca5bf7 Mon Sep 17 00:00:00 2001 From: manNomi Date: Sat, 14 Feb 2026 19:30:53 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=92=84=20=EC=96=B4=EB=93=9C=EB=AF=BC?= =?UTF-8?q?=20=EC=84=B1=EC=A0=81=20=EA=B4=80=EB=A6=AC=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=ED=94=BC=EA=B7=B8=EB=A7=88=20=EC=8B=9C=EC=95=88=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/src/routes/scores/index.tsx | 166 +++++++++++++++++++++---- 1 file changed, 140 insertions(+), 26 deletions(-) diff --git a/apps/admin/src/routes/scores/index.tsx b/apps/admin/src/routes/scores/index.tsx index 2fc550f1..bd727632 100644 --- a/apps/admin/src/routes/scores/index.tsx +++ b/apps/admin/src/routes/scores/index.tsx @@ -1,8 +1,12 @@ import { createFileRoute, redirect } from "@tanstack/react-router"; +import { Building2, FileText, Search, SquarePen, UserCircle2 } from "lucide-react"; import { useState } from "react"; import { GpaScoreTable } from "@/components/features/scores/GpaScoreTable"; import { LanguageScoreTable } from "@/components/features/scores/LanguageScoreTable"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { cn } from "@/lib/utils"; import { isTokenExpired } from "@/lib/utils/jwtUtils"; import { loadAccessToken } from "@/lib/utils/localStorage"; import type { VerifyStatus } from "@/types/scores"; @@ -22,37 +26,147 @@ export const Route = createFileRoute("/scores/")({ function ScoresPage() { const [verifyFilter, setVerifyFilter] = useState("PENDING"); + const [searchKeyword, setSearchKeyword] = useState(""); + + const sideMenus = [ + { label: "대학 관리", icon: Building2, active: true }, + { label: "멘토 관리", icon: UserCircle2, active: false }, + { label: "유저 관리", icon: UserCircle2, active: false }, + { label: "성적 관리", icon: FileText, active: false }, + ] as const; + + const topTabs = ["권역/나라", "나라/대학", "대학 지원 정보", "대학 상세 정보"] as const; + + const verifyFilters: Array<{ value: VerifyStatus; label: string }> = [ + { value: "PENDING", label: "대기중" }, + { value: "APPROVED", label: "승인됨" }, + { value: "REJECTED", label: "거절됨" }, + ]; return ( -
-

성적 관리

- -
- -
+
+
+ + +
+
+
+ {topTabs.map((tab) => ( + + ))} +
- - - GPA 성적 - 어학성적 - +
+

권역/나라

- - - +
+ setSearchKeyword(event.target.value)} + placeholder="검색어를 입력한 후 검색할 카테고리를 선택해주세요" + className="h-9 border-slate-200 bg-slate-50 pr-10 text-xs" + /> + +
- - - - + +
+ +
+ {verifyFilters.map((option) => ( + + ))} +
+ +
+ + + + GPA 성적 + + + 어학성적 + + + + + + + + + + + +
+
+
+
); } From 459dad187c2ba4f66ef8ef1ca7c43805daa3ea93 Mon Sep 17 00:00:00 2001 From: manNomi Date: Sat, 14 Feb 2026 21:38:35 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20?= =?UTF-8?q?=EC=84=B1=EC=A0=81=20=EA=B4=80=EB=A6=AC=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=ED=8F=AC=EB=A7=B7=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/src/routes/scores/index.tsx | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/apps/admin/src/routes/scores/index.tsx b/apps/admin/src/routes/scores/index.tsx index bd727632..d16c6a8f 100644 --- a/apps/admin/src/routes/scores/index.tsx +++ b/apps/admin/src/routes/scores/index.tsx @@ -64,9 +64,7 @@ function ScoresPage() { type="button" className={cn( "flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-left text-[13px] font-medium transition-colors", - menu.active - ? "bg-indigo-50 text-indigo-600" - : "text-slate-400 hover:bg-white hover:text-slate-600", + menu.active ? "bg-indigo-50 text-indigo-600" : "text-slate-400 hover:bg-white hover:text-slate-600", )} > @@ -85,9 +83,7 @@ function ScoresPage() { type="button" className={cn( "rounded-md px-3 py-1.5 text-xs font-semibold tracking-[-0.01em] transition-colors", - tab === "권역/나라" - ? "bg-white text-indigo-600 shadow-sm" - : "text-slate-500 hover:text-slate-700", + tab === "권역/나라" ? "bg-white text-indigo-600 shadow-sm" : "text-slate-500 hover:text-slate-700", )} > {tab} @@ -108,7 +104,10 @@ function ScoresPage() {
- @@ -128,9 +127,7 @@ function ScoresPage() { {option.label} From e8e8d0a018abce94df738d1ca658c15c6f2dadd7 Mon Sep 17 00:00:00 2001 From: manNomi Date: Sat, 14 Feb 2026 22:17:43 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=92=84=20=EC=96=B4=EB=93=9C=EB=AF=BC?= =?UTF-8?q?=20=EC=84=B1=EC=A0=81=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=9B=B9?= =?UTF-8?q?=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../features/scores/GpaScoreTable.tsx | 20 +-- .../features/scores/LanguageScoreTable.tsx | 20 +-- .../features/scores/ScoreVerifyButton.tsx | 8 +- .../features/scores/StatusBadge.tsx | 8 +- .../src/components/layout/AdminLayout.tsx | 2 +- apps/admin/src/components/ui/button.tsx | 12 +- apps/admin/src/components/ui/input.tsx | 2 +- apps/admin/src/components/ui/table.tsx | 15 +- apps/admin/src/components/ui/tabs.tsx | 16 +- apps/admin/src/routes/scores/index.tsx | 49 +++-- apps/admin/src/styles.css | 167 +++++++++++++++++- 11 files changed, 236 insertions(+), 83 deletions(-) diff --git a/apps/admin/src/components/features/scores/GpaScoreTable.tsx b/apps/admin/src/components/features/scores/GpaScoreTable.tsx index 6d7a9bfd..4ecea310 100644 --- a/apps/admin/src/components/features/scores/GpaScoreTable.tsx +++ b/apps/admin/src/components/features/scores/GpaScoreTable.tsx @@ -90,7 +90,7 @@ export function GpaScoreTable({ verifyFilter }: Props) { }; return ( -
+
@@ -111,27 +111,27 @@ export function GpaScoreTable({ verifyFilter }: Props) {
-
- 로딩중... +
+ 로딩중...
) : scores.length === 0 ? ( - + 데이터가 없습니다 ) : ( scores.map((score) => ( - + {score.gpaScoreStatusResponse.id}
프로필 {score.siteUserResponse.nickname}
@@ -144,7 +144,7 @@ export function GpaScoreTable({ verifyFilter }: Props) { step="0.01" value={editingGpa} onChange={(e) => setEditingGpa(Number.parseFloat(e.target.value))} - className="w-20 rounded border px-2 py-1" + className="w-20 rounded border border-k-200 bg-k-0 px-2 py-1 typo-regular-4 text-k-700" />
) : ( @@ -159,7 +159,7 @@ export function GpaScoreTable({ verifyFilter }: Props) { step="0.01" value={editingGpaCriteria} onChange={(e) => setEditingGpaCriteria(Number.parseFloat(e.target.value))} - className="w-20 rounded border px-2 py-1" + className="w-20 rounded border border-k-200 bg-k-0 px-2 py-1 typo-regular-4 text-k-700" />
{/* 페이지네이션 */} -
+
diff --git a/apps/admin/src/components/features/scores/LanguageScoreTable.tsx b/apps/admin/src/components/features/scores/LanguageScoreTable.tsx index 6ac176b0..344a6a83 100644 --- a/apps/admin/src/components/features/scores/LanguageScoreTable.tsx +++ b/apps/admin/src/components/features/scores/LanguageScoreTable.tsx @@ -105,7 +105,7 @@ export function LanguageScoreTable({ verifyFilter }: Props) { }; return ( -
+
@@ -126,27 +126,27 @@ export function LanguageScoreTable({ verifyFilter }: Props) {
-
- 로딩중... +
+ 로딩중...
) : scores.length === 0 ? ( - + 데이터가 없습니다 ) : ( scores.map((score) => ( - + {score.languageTestScoreStatusResponse.id}
프로필 {score.siteUserResponse.nickname}
@@ -157,7 +157,7 @@ export function LanguageScoreTable({ verifyFilter }: Props) {
-
+
diff --git a/apps/admin/src/components/features/scores/ScoreVerifyButton.tsx b/apps/admin/src/components/features/scores/ScoreVerifyButton.tsx index 583be920..3a12e780 100644 --- a/apps/admin/src/components/features/scores/ScoreVerifyButton.tsx +++ b/apps/admin/src/components/features/scores/ScoreVerifyButton.tsx @@ -33,7 +33,7 @@ export function ScoreVerifyButton({ currentStatus, onVerifyChange }: Props) { @@ -45,12 +45,12 @@ export function ScoreVerifyButton({ currentStatus, onVerifyChange }: Props) { value={rejectReason} onChange={(e) => setRejectReason(e.target.value)} placeholder="거절 사유" - className="rounded border px-2 py-1" + className="rounded border border-k-200 bg-k-0 px-2 py-1 typo-regular-4 text-k-700" /> @@ -59,7 +59,7 @@ export function ScoreVerifyButton({ currentStatus, onVerifyChange }: Props) { diff --git a/apps/admin/src/components/features/scores/StatusBadge.tsx b/apps/admin/src/components/features/scores/StatusBadge.tsx index 434871d5..2949e357 100644 --- a/apps/admin/src/components/features/scores/StatusBadge.tsx +++ b/apps/admin/src/components/features/scores/StatusBadge.tsx @@ -1,9 +1,9 @@ import type { VerifyStatus } from "@/types/scores"; const statusStyles = { - PENDING: "bg-yellow-100 text-yellow-800", - APPROVED: "bg-green-100 text-green-800", - REJECTED: "bg-red-100 text-red-800", + PENDING: "bg-primary-100 text-primary", + APPROVED: "bg-[#E9F7EC] text-[#15A861]", + REJECTED: "bg-[#FFD9D9] text-[#E22A2D]", }; const statusLabels = { @@ -18,7 +18,7 @@ interface StatusBadgeProps { export function StatusBadge({ status }: StatusBadgeProps) { return ( - + {statusLabels[status]} ); diff --git a/apps/admin/src/components/layout/AdminLayout.tsx b/apps/admin/src/components/layout/AdminLayout.tsx index 636cdc12..d60d44a5 100644 --- a/apps/admin/src/components/layout/AdminLayout.tsx +++ b/apps/admin/src/components/layout/AdminLayout.tsx @@ -4,7 +4,7 @@ interface AdminLayoutProps { export function AdminLayout({ children }: AdminLayoutProps) { return ( -
+
{children}
); diff --git a/apps/admin/src/components/ui/button.tsx b/apps/admin/src/components/ui/button.tsx index 502bf39e..bf9301ee 100644 --- a/apps/admin/src/components/ui/button.tsx +++ b/apps/admin/src/components/ui/button.tsx @@ -5,15 +5,15 @@ import * as React from "react"; import { cn } from "@/lib/utils"; const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md typo-sb-11 transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", { variants: { variant: { - default: "bg-primary text-primary-foreground shadow hover:bg-primary/90", - destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", - outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground", - secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", + default: "bg-primary text-k-0 shadow-sm hover:bg-primary-600", + destructive: "bg-[#E22A2D] text-k-0 shadow-sm hover:bg-[#BA1E21]", + outline: "border border-k-200 bg-k-0 text-k-700 shadow-sm hover:bg-k-50", + secondary: "bg-k-50 text-k-700 shadow-sm hover:bg-k-100", + ghost: "text-k-600 hover:bg-k-50 hover:text-k-800", link: "text-primary underline-offset-4 hover:underline", }, size: { diff --git a/apps/admin/src/components/ui/input.tsx b/apps/admin/src/components/ui/input.tsx index 875315a0..2cc968f4 100644 --- a/apps/admin/src/components/ui/input.tsx +++ b/apps/admin/src/components/ui/input.tsx @@ -8,7 +8,7 @@ const Input = React.forwardRef>( >( ({ className, ...props }, ref) => (
- +
), ); Table.displayName = "Table"; const TableHeader = React.forwardRef>( - ({ className, ...props }, ref) => , + ({ className, ...props }, ref) => ( + + ), ); TableHeader.displayName = "TableHeader"; @@ -34,7 +36,7 @@ const TableRow = React.forwardRef ( ), @@ -46,7 +48,7 @@ const TableHead = React.forwardRef[role=checkbox]]:translate-y-[2px]", + "h-10 px-2 text-left align-middle typo-sb-11 text-k-600 [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className, )} {...props} @@ -59,7 +61,10 @@ const TableCell = React.forwardRef (
[role=checkbox]]:translate-y-[2px]", className)} + className={cn( + "p-2 align-middle typo-regular-4 text-k-700 [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", + className, + )} {...props} /> ), diff --git a/apps/admin/src/components/ui/tabs.tsx b/apps/admin/src/components/ui/tabs.tsx index 6dcfd29e..06516a17 100644 --- a/apps/admin/src/components/ui/tabs.tsx +++ b/apps/admin/src/components/ui/tabs.tsx @@ -11,10 +11,7 @@ const TabsList = React.forwardRef< >(({ className, ...props }, ref) => ( )); @@ -27,7 +24,7 @@ const TabsTrigger = React.forwardRef< , React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); TabsContent.displayName = TabsPrimitive.Content.displayName; diff --git a/apps/admin/src/routes/scores/index.tsx b/apps/admin/src/routes/scores/index.tsx index d16c6a8f..d37c217f 100644 --- a/apps/admin/src/routes/scores/index.tsx +++ b/apps/admin/src/routes/scores/index.tsx @@ -44,27 +44,27 @@ function ScoresPage() { ]; return ( -
+
-