All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m49s
141 lines
3.5 KiB
TypeScript
141 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { Card, Input, Textarea, Button, Select } from "@/components/ui";
|
|
|
|
interface User {
|
|
id: string;
|
|
username: string;
|
|
avatar: string | null;
|
|
score: number;
|
|
level: number;
|
|
}
|
|
|
|
interface ChallengeFormProps {
|
|
users: User[];
|
|
onSubmit: (data: {
|
|
challengedId: string;
|
|
title: string;
|
|
description: string;
|
|
pointsReward: number;
|
|
}) => void;
|
|
onCancel?: () => void;
|
|
isPending?: boolean;
|
|
}
|
|
|
|
export default function ChallengeForm({
|
|
users,
|
|
onSubmit,
|
|
onCancel,
|
|
isPending = false,
|
|
}: ChallengeFormProps) {
|
|
const [challengedId, setChallengedId] = useState("");
|
|
const [title, setTitle] = useState("");
|
|
const [description, setDescription] = useState("");
|
|
const [pointsReward, setPointsReward] = useState(100);
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (!challengedId || !title || !description) {
|
|
return;
|
|
}
|
|
onSubmit({
|
|
challengedId,
|
|
title,
|
|
description,
|
|
pointsReward,
|
|
});
|
|
};
|
|
|
|
const handleCancel = () => {
|
|
setChallengedId("");
|
|
setTitle("");
|
|
setDescription("");
|
|
setPointsReward(100);
|
|
onCancel?.();
|
|
};
|
|
|
|
return (
|
|
<Card variant="dark" className="p-6 mb-8">
|
|
<h2 className="text-xl font-bold text-pixel-gold mb-4">
|
|
Créer un nouveau défi
|
|
</h2>
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
<Select
|
|
label="Défier qui ?"
|
|
value={challengedId}
|
|
onChange={(e) => setChallengedId(e.target.value)}
|
|
>
|
|
<option value="">Sélectionner un joueur</option>
|
|
{users.map((user) => (
|
|
<option key={user.id} value={user.id}>
|
|
{user.username} (Lv.{user.level} - {user.score} pts)
|
|
</option>
|
|
))}
|
|
</Select>
|
|
|
|
<div>
|
|
<label className="block text-sm font-bold text-pixel-gold mb-2">
|
|
Titre du défi
|
|
</label>
|
|
<Input
|
|
value={title}
|
|
onChange={(e) => setTitle(e.target.value)}
|
|
placeholder="Ex: Qui participera à plus d'événements ce mois ?"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-bold text-pixel-gold mb-2">
|
|
Description
|
|
</label>
|
|
<Textarea
|
|
value={description}
|
|
onChange={(e) => setDescription(e.target.value)}
|
|
placeholder="Décrivez les règles du défi..."
|
|
rows={4}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-bold text-pixel-gold mb-2">
|
|
Points à gagner (défaut: 100)
|
|
</label>
|
|
<Input
|
|
type="number"
|
|
value={pointsReward}
|
|
onChange={(e) =>
|
|
setPointsReward(parseInt(e.target.value) || 100)
|
|
}
|
|
min={1}
|
|
max={1000}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex gap-2">
|
|
<Button
|
|
type="submit"
|
|
variant="primary"
|
|
disabled={isPending || !challengedId || !title || !description}
|
|
className="flex-1"
|
|
>
|
|
{isPending ? "Création..." : "Créer le défi"}
|
|
</Button>
|
|
{onCancel && (
|
|
<Button
|
|
type="button"
|
|
onClick={handleCancel}
|
|
variant="secondary"
|
|
disabled={isPending}
|
|
>
|
|
Annuler
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</form>
|
|
</Card>
|
|
);
|
|
}
|
|
|