Refactor ChallengesSection component to utilize initial challenges and users data: Replace fetching logic with props for challenges and users, streamline challenge creation with a dedicated form component, and enhance UI for better user experience.
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m49s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m49s
This commit is contained in:
140
components/challenges/ChallengeForm.tsx
Normal file
140
components/challenges/ChallengeForm.tsx
Normal file
@@ -0,0 +1,140 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user