peer-at-code-web/ui/Puzzle.tsx
2023-04-17 21:03:12 +02:00

127 lines
3.6 KiB
TypeScript

'use client';
import cookies from 'js-cookie';
import { notFound } from 'next/navigation';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { useSWRConfig } from 'swr';
import { usePuzzle } from '@/lib/hooks/use-puzzles';
import AppLink from './AppLink';
import Button from './Button';
import Input from './Input';
import ToHTML from './ToHTML';
type PuzzleData = {
answer: string;
// filename: string;
// code_file: File[];
};
type Granted = {
tries: number;
score?: number;
};
export default function Puzzle({ token, id }: { token: string; id: number }) {
const [granted, setGranted] = useState<Granted | null>(null);
const { data: puzzle, isLoading } = usePuzzle({ token, id });
const { mutate } = useSWRConfig();
const { register, handleSubmit } = useForm<PuzzleData>({
defaultValues: {
answer: ''
// filename: '',
// code_file: []
}
});
async function onSubmit(data: PuzzleData) {
const formData = new FormData();
// if (data.code_file[0].size > 16 * 1024 * 1024) {
// alert('Fichier trop volumineux');
// return;
// }
formData.append('answer', data.answer);
// formData.append('filename', 'placeholder');
// formData.append('code_file', new Blob(), 'placeholder');
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/puzzleResponse/${puzzle!.id}`, {
method: 'POST',
body: formData,
headers: {
Authorization: `Bearer ${cookies.get('token')}}`
}
});
if (res.ok || res.status === 406) {
mutate(`puzzles/${puzzle?.id}`);
setGranted(await res.json());
}
}
if (!puzzle && isLoading) {
return <></>;
}
if (!puzzle) {
notFound();
}
return (
<div className="flex h-full w-full flex-col justify-between space-y-4">
<h1 className="text-2xl font-bold sm:text-3xl md:text-4xl">{puzzle.name}</h1>
<div className="flex h-screen w-full overflow-y-auto">
<ToHTML className="font-code text-xs sm:text-base" data={puzzle.content} />
</div>
{!puzzle.score ? (
<form
className="flex w-full flex-col justify-between sm:flex-row"
onSubmit={handleSubmit(onSubmit)}
encType="multipart/form-data"
>
<div className="flex flex-col items-center justify-center space-x-0 sm:flex-row sm:space-x-6">
<Input
className="w-full"
label="Réponse"
type="text"
placeholder="12"
required
{...register('answer')}
/>
{granted && (
<div className="flex flex-col">
<p className="text-sm text-muted">Tentatives actuelles : {granted.tries}</p>
{granted.score && <p className="text-sm text-muted">Score : {granted.score}</p>}
</div>
)}
{/* <Input
className="h-16 w-full sm:w-1/3"
label="Code"
type="file"
required
accept=".py,.js,.ts,.java,.rs,.c"
{...register('code_file')}
/> */}
</div>
<Button kind="brand" className="mt-6" type="submit">
Envoyer
</Button>
</form>
) : (
<div className="flex items-center justify-between">
<p className="text-sm text-highlight-secondary">
Score : {puzzle.score} (Score maximum: {puzzle.scoreMax})
</p>
<AppLink href="/dashboard/puzzles" className="text-sm text-highlight-secondary">
Retour aux puzzles
</AppLink>
</div>
)}
</div>
);
}