feat: add Monaco diff editor for submission changes

This commit is contained in:
2026-08-06 16:16:30 +09:00
parent 4b2e25d385
commit 604da5d6e1
8 changed files with 480 additions and 313 deletions
+11 -11
View File
@@ -232,9 +232,9 @@ export function StudentsPage({ session, selectedCourseId }: { session: AuthSessi
</label>
</div>
<div>
<div>
<div className="hidden gap-4 grid-cols-[44px_108px_minmax(160px,1fr)_minmax(116px,0.7fr)_78px_minmax(150px,1fr)_58px_58px_118px_70px_42px] items-center border-b border-[#cbd5e1] bg-[#f8fafc] px-4 py-3 text-center text-[11px] font-bold text-[#64748b] xl:grid">
<div className="overflow-x-auto">
<div className="min-w-[1180px]">
<div className="grid grid-cols-[44px_108px_minmax(160px,1fr)_minmax(116px,0.7fr)_78px_minmax(150px,1fr)_58px_58px_118px_70px_42px] items-center gap-4 border-b border-[#cbd5e1] bg-[#f8fafc] px-4 py-3 text-center text-[11px] font-bold text-[#64748b]">
<span>No.</span>
<span>이름</span>
<span>이메일</span>
@@ -258,13 +258,13 @@ export function StudentsPage({ session, selectedCourseId }: { session: AuthSessi
<EmptyState message={error} />
) : filteredStudents.length > 0 ? (
pagedStudents.map((student, index) => (
<article className="grid gap-4 px-4 py-4 xl:grid-cols-[44px_108px_minmax(160px,1fr)_minmax(116px,0.7fr)_78px_minmax(150px,1fr)_58px_58px_118px_70px_42px] xl:items-center" key={student.id}>
<article className="grid grid-cols-[44px_108px_minmax(160px,1fr)_minmax(116px,0.7fr)_78px_minmax(150px,1fr)_58px_58px_118px_70px_42px] items-center gap-4 px-4 py-4" key={student.id}>
<Cell label="번호">
<span className="text-[13px] font-bold text-[#64748b]">{filteredStudents.length - ((page - 1) * pageSize + index)}</span>
</Cell>
<div className="min-w-0 text-center">
<p className="mb-2 text-[11px] font-bold text-[#94a3b8] xl:hidden">이름</p>
<p className="hidden">이름</p>
<h3 className="truncate text-[14px] font-black text-[#111827]">{student.name}</h3>
</div>
@@ -284,7 +284,7 @@ export function StudentsPage({ session, selectedCourseId }: { session: AuthSessi
<div>
<div className="mb-2 flex items-center justify-between text-[12px] font-bold text-[#475569]">
<span className="xl:hidden">진행률</span>
<span className="hidden">진행률</span>
<span className="font-semibold text-[#4f46e5]">{student.progress}%</span>
</div>
<div className="h-1.5 overflow-hidden rounded-full bg-[#dbe3ef]">
@@ -491,7 +491,7 @@ function EmptyState({ message }: { message: string }) {
function Cell({ label, children }: { label: string; children: React.ReactNode }) {
return (
<div className="min-w-0 text-center">
<p className="mb-2 text-[11px] font-bold text-[#94a3b8] xl:hidden">{label}</p>
<p className="hidden">{label}</p>
{children}
</div>
);
@@ -500,11 +500,11 @@ function Cell({ label, children }: { label: string; children: React.ReactNode })
function StudentMetric({ icon: Icon, label, value, danger = false }: { icon: typeof GitBranch; label: string; value: number; danger?: boolean }) {
return (
<div className="min-w-0 text-center">
<div className="flex items-center justify-center gap-1.5 text-[11px] font-bold text-[#94a3b8] xl:hidden">
<div className="hidden">
<Icon size={13} aria-hidden="true" />
{label}
</div>
<p className={`mt-1 text-[13px] font-semibold xl:mt-0 ${danger ? 'text-[#e11d48]' : 'text-[#111827]'}`}>{value}</p>
<p className={`mt-0 text-[13px] font-semibold ${danger ? 'text-[#e11d48]' : 'text-[#111827]'}`}>{value}</p>
</div>
);
}
@@ -514,7 +514,7 @@ function StudentIssueMetric({ student, onOpen }: { student: InstructorStudent; o
return (
<div className="min-w-0 text-center">
<div className="flex items-center justify-center gap-1.5 text-[11px] font-bold text-[#94a3b8] xl:hidden">
<div className="hidden">
<CircleAlert size={13} aria-hidden="true" />
이슈
</div>
@@ -525,7 +525,7 @@ function StudentIssueMetric({ student, onOpen }: { student: InstructorStudent; o
}}
disabled={!hasIssues}
className={[
'mt-1 inline-flex h-7 min-w-7 items-center justify-center rounded-md px-2 text-[13px] font-black xl:mt-0',
'mt-0 inline-flex h-7 min-w-7 items-center justify-center rounded-md px-2 text-[13px] font-black',
hasIssues
? 'cursor-pointer bg-[#fff1f2] text-[#e11d48] transition-colors hover:bg-[#ffe4e6]'
: 'cursor-default bg-transparent text-[#111827]',