Add event registration and feedback points to site preferences: Update SitePreferences model and related components to include eventRegistrationPoints and eventFeedbackPoints, ensuring proper handling of user scores during event interactions.

This commit is contained in:
Julien Froidefond
2025-12-16 16:38:01 +01:00
parent f45cc1839e
commit 3dd82c2bd4
20 changed files with 652 additions and 19 deletions

View File

@@ -0,0 +1,166 @@
"use client";
import { useState, useEffect } from "react";
import { updateSitePreferences } from "@/actions/admin/preferences";
import { Button, Card, Input } from "@/components/ui";
interface SitePreferences {
id: string;
eventRegistrationPoints: number;
}
interface EventPointsPreferencesProps {
initialPreferences: SitePreferences;
}
export default function EventPointsPreferences({
initialPreferences,
}: EventPointsPreferencesProps) {
const [preferences, setPreferences] = useState<SitePreferences | null>(
initialPreferences
);
const [isEditing, setIsEditing] = useState(false);
const [formData, setFormData] = useState({
eventRegistrationPoints: initialPreferences.eventRegistrationPoints.toString(),
});
const [isSaving, setIsSaving] = useState(false);
// Synchroniser les préférences quand initialPreferences change
useEffect(() => {
setPreferences(initialPreferences);
setFormData({
eventRegistrationPoints: initialPreferences.eventRegistrationPoints.toString(),
});
}, [initialPreferences]);
const handleEdit = () => {
setIsEditing(true);
};
const handleSave = async () => {
const points = parseInt(formData.eventRegistrationPoints, 10);
if (isNaN(points) || points < 0) {
alert("Le nombre de points doit être un nombre positif");
return;
}
setIsSaving(true);
try {
const result = await updateSitePreferences({
eventRegistrationPoints: points,
});
if (result.success && result.data) {
setPreferences(result.data);
setFormData({
eventRegistrationPoints: result.data.eventRegistrationPoints.toString(),
});
setIsEditing(false);
} else {
console.error("Error updating preferences:", result.error);
alert(result.error || "Erreur lors de la mise à jour");
}
} catch (error) {
console.error("Error updating preferences:", error);
alert("Erreur lors de la mise à jour");
} finally {
setIsSaving(false);
}
};
const handleCancel = () => {
setIsEditing(false);
if (preferences) {
setFormData({
eventRegistrationPoints: preferences.eventRegistrationPoints.toString(),
});
}
};
return (
<Card variant="default" className="p-3 sm:p-4">
<div className="flex flex-col sm:flex-row sm:justify-between sm:items-start gap-3 mb-4">
<div className="min-w-0 flex-1">
<h3 className="text-pixel-gold font-bold text-base sm:text-lg break-words">
Points d&apos;inscription aux événements
</h3>
<p className="text-gray-400 text-xs sm:text-sm">
Nombre de points attribués lorsqu&apos;un utilisateur s&apos;inscrit à un événement
</p>
</div>
{!isEditing && (
<Button
onClick={handleEdit}
variant="primary"
size="sm"
className="whitespace-nowrap flex-shrink-0"
>
Modifier
</Button>
)}
</div>
{isEditing ? (
<div className="space-y-4">
<div>
<label
htmlFor="eventRegistrationPoints"
className="block text-sm font-medium text-pixel-gold mb-2"
>
Points d&apos;inscription
</label>
<Input
id="eventRegistrationPoints"
type="number"
min="0"
value={formData.eventRegistrationPoints}
onChange={(e) =>
setFormData({
...formData,
eventRegistrationPoints: e.target.value,
})
}
placeholder="100"
className="w-full"
/>
<p className="text-xs text-gray-400 mt-1">
Les utilisateurs gagneront ce nombre de points lors de leur inscription à un événement
</p>
</div>
<div className="flex flex-col sm:flex-row gap-2 pt-4">
<Button
onClick={handleSave}
variant="success"
size="md"
disabled={isSaving}
>
{isSaving ? "Enregistrement..." : "Enregistrer"}
</Button>
<Button
onClick={handleCancel}
variant="secondary"
size="md"
disabled={isSaving}
>
Annuler
</Button>
</div>
</div>
) : (
<div className="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4">
<span className="text-pixel-gold font-bold text-sm sm:text-base min-w-0 sm:min-w-[200px] flex-shrink-0">
Points actuels:
</span>
<div className="flex items-center gap-2">
<span className="text-lg sm:text-xl font-bold text-white">
{preferences?.eventRegistrationPoints ?? 100}
</span>
<span className="text-xs sm:text-sm text-gray-400">points</span>
</div>
</div>
)}
</Card>
);
}