Skip to content

Commit

Permalink
feat: ユーザー画面に、SubmissionとTestCasesを表示できるようにする (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
r9i6k0u1 authored Nov 27, 2024
1 parent 4afb792 commit b757d8a
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 26 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"dependencies": {
"@monaco-editor/react": "4.6.0",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-slot": "^1.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { cn } from "@/lib/utils"

import { Submissions } from "./submissions"
import { TestCases } from "./test-cases"
import { TestResults } from "./test-results"

export type InfoPanelProps = ComponentPropsWithoutRef<"div">

Expand All @@ -15,15 +14,11 @@ export const InfoPanel: FC<InfoPanelProps> = ({ className, ...props }) => {
<Tabs className="flex h-full flex-col" defaultValue="submissions">
<TabsList className="mr-auto">
<TabsTrigger value="submissions">Submissions</TabsTrigger>
<TabsTrigger value="tests">Tests</TabsTrigger>
<TabsTrigger value="test-cases">Test Cases</TabsTrigger>
</TabsList>
<TabsContent className="flex-1 overflow-y-auto" value="submissions">
<Submissions />
</TabsContent>
<TabsContent value="tests">
<TestResults />
</TabsContent>
<TabsContent value="test-cases">
<TestCases />
</TabsContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import type { ComponentPropsWithoutRef, FC } from "react"

import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
import { Dialog, DialogContent, DialogOverlay } from "@radix-ui/react-dialog"
import { intlFormatDistance } from "date-fns"
import { CheckIcon, XIcon } from "lucide-react"
import { components } from "openapi/schema"
import { useState } from "react"

import { useProblem } from "../../-hooks/use-problem"

Expand All @@ -15,18 +17,32 @@ export type SubmissionsProps = ComponentPropsWithoutRef<"div">
export const Submissions: FC<SubmissionsProps> = ({ className, ...props }) => {
const { submissions } = useProblem()

// ダイアログを表示するための状態管理
const [isDialogOpen, setIsDialogOpen] = useState(false)
const [selectedSubmission, setSelectedSubmission] = useState<
Submission | undefined
>()

// ダイアログを開く関数
const openDialog = (submission: Submission) => {
setSelectedSubmission(submission)
setIsDialogOpen(true)
}

// ダイアログを閉じる関数
const closeDialog = () => {
setIsDialogOpen(false)
setSelectedSubmission(undefined)
}
return (
<div className={cn("grid grid-cols-[auto_1fr_auto]", className)} {...props}>
{submissions.data?.map((submission) => (
{submissions.data?.map((submission, i) => (
<Button
className="col-span-3 grid grid-cols-subgrid gap-4"
key={submission.id}
onClick={() => {
// todo: Display submission details
alert("WIP: Display submission details")
}}
key={i}
onClick={() => openDialog(submission)} // ボタンクリックでダイアログを開く
size="sm"
variant="ghost"
variant="outline"
>
<div className="flex flex-row gap-1">
<StatusIcon status={submission.result.status} />
Expand All @@ -38,6 +54,90 @@ export const Submissions: FC<SubmissionsProps> = ({ className, ...props }) => {
</div>
</Button>
))}
{/* モーダル */}
{selectedSubmission && (
<Dialog onOpenChange={setIsDialogOpen} open={isDialogOpen}>
<DialogOverlay className="fixed inset-0 bg-black opacity-50" />
<DialogContent
className="fixed inset-0 flex items-center justify-center p-4"
style={{ maxWidth: "90%", width: "auto" }}
>
<div className="w-full max-w-lg rounded-lg bg-white p-6 shadow-lg dark:border-gray-700 dark:bg-gray-800">
{/* モーダル内の閉じるボタン */}
<div className="flex justify-end">
<button
className="text-lg font-semibold text-red-500 hover:text-red-700"
onClick={closeDialog}
>
×
</button>
</div>

<div className="space-y-4">
<h2 className="text-lg font-semibold">Submission Details</h2>
<table className="w-full table-auto border-collapse border border-gray-300">
<thead>
<tr>
<th className="border-b border-gray-300 px-4 py-2 text-left">
Field
</th>
<th className="border-b border-gray-300 px-4 py-2 text-left">
Value
</th>
</tr>
</thead>
<tbody>
<tr>
<td className="border-b border-gray-300 px-4 py-2 font-semibold">
Student ID
</td>
<td className="border-b border-gray-300 px-4 py-2">
{selectedSubmission.student_id}
</td>
</tr>
<tr>
<td className="border-b border-gray-300 px-4 py-2 font-semibold">
Status
</td>
<td className="flex items-center gap-2 border-b border-gray-300 px-4 py-2">
<StatusIcon status={selectedSubmission.result.status} />
<span>{selectedSubmission.result.status}</span>
</td>
</tr>
<tr>
<td className="border-b border-gray-300 px-4 py-2 font-semibold">
Time Ago
</td>
<td className="border-b border-gray-300 px-4 py-2 text-left text-muted-foreground">
{intlFormatDistance(
new Date(selectedSubmission.submitted_at),
new Date(),
)}
</td>
</tr>
<tr>
<td className="border-b border-gray-300 px-4 py-2 font-semibold">
Code
</td>
<td className="border-b border-gray-300 px-4 py-2">
{selectedSubmission.code}
</td>
</tr>
<tr>
<td className="border-b border-gray-300 px-4 py-2 font-semibold">
Message
</td>
<td className="border-b border-gray-300 px-4 py-2">
{selectedSubmission.result.message}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</DialogContent>
</Dialog>
)}
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import type { ComponentPropsWithoutRef, FC } from "react"

import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"

import { useProblem } from "../../-hooks/use-problem"

export type TestCasesProps = ComponentPropsWithoutRef<"div">

// todo: Implement TestCases
export const TestCases: FC<TestCasesProps> = ({ className, ...props }) => {
const { problem } = useProblem()
return (
<div className={className} {...props}>
WIP: Display test cases
<div className={cn("grid grid-cols-[auto_lfr_auto]", className)} {...props}>
{problem.data?.test_cases.map(({ input, output }, i) => (
<Button
className="col-span-2 grid grid-cols-subgrid gap-4"
key={i}
size="sm"
variant="ghost"
>
<div className="text-left">入力:{input}</div>
<div className="text-left">出力:{output}</div>
</Button>
))}
</div>
)
}

This file was deleted.

0 comments on commit b757d8a

Please sign in to comment.