249 lines
No EOL
7.3 KiB
TypeScript
249 lines
No EOL
7.3 KiB
TypeScript
"use client";
|
|
import { useState, useEffect } from "react";
|
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
import { Label } from "@/components/ui/label";
|
|
import { AlertTriangle, Power, PowerOff } from "lucide-react";
|
|
|
|
interface MaintenanceStatus {
|
|
is_maintenance_mode: boolean;
|
|
maintenance_message: string | null;
|
|
scheduled_end_date: string | null;
|
|
}
|
|
|
|
interface MaintenanceButtonProps {
|
|
isStaff: boolean;
|
|
}
|
|
|
|
export function MaintenanceButton({ isStaff }: MaintenanceButtonProps) {
|
|
const [status, setStatus] = useState<MaintenanceStatus | null>(null);
|
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
const [message, setMessage] = useState("");
|
|
const [endDate, setEndDate] = useState("");
|
|
const [endTime, setEndTime] = useState("");
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
// Charger le statut au montage
|
|
useEffect(() => {
|
|
if (isStaff) {
|
|
fetchMaintenanceStatus();
|
|
}
|
|
}, [isStaff]);
|
|
|
|
const fetchMaintenanceStatus = async () => {
|
|
try {
|
|
const response = await fetch("/api/maintenance");
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setStatus(data);
|
|
} else {
|
|
// Fallback par défaut si l'API n'existe pas encore
|
|
setStatus({
|
|
is_maintenance_mode: false,
|
|
maintenance_message: null,
|
|
scheduled_end_date: null
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to fetch maintenance status:", error);
|
|
// Fallback par défaut en cas d'erreur
|
|
setStatus({
|
|
is_maintenance_mode: false,
|
|
maintenance_message: null,
|
|
scheduled_end_date: null
|
|
});
|
|
}
|
|
};
|
|
|
|
const handleActivateMaintenance = () => {
|
|
// Réinitialiser les valeurs du modal
|
|
setMessage("L'Espace Paie est temporairement indisponible pour maintenance.");
|
|
|
|
// Date par défaut : dans 2 heures
|
|
const defaultEnd = new Date();
|
|
defaultEnd.setHours(defaultEnd.getHours() + 2);
|
|
|
|
setEndDate(defaultEnd.toISOString().split('T')[0]);
|
|
setEndTime(defaultEnd.toTimeString().slice(0, 5));
|
|
|
|
setIsModalOpen(true);
|
|
};
|
|
|
|
const handleDeactivateMaintenance = async () => {
|
|
setIsLoading(true);
|
|
try {
|
|
const response = await fetch("/api/maintenance", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
is_maintenance_mode: false,
|
|
maintenance_message: null,
|
|
scheduled_end_date: null
|
|
})
|
|
});
|
|
|
|
if (response.ok) {
|
|
const newStatus = await response.json();
|
|
setStatus(newStatus);
|
|
} else {
|
|
alert("Erreur lors de la désactivation de la maintenance");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error deactivating maintenance:", error);
|
|
alert("Erreur lors de la désactivation de la maintenance");
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleConfirmMaintenance = async () => {
|
|
if (!message.trim()) {
|
|
alert("Veuillez saisir un message de maintenance");
|
|
return;
|
|
}
|
|
|
|
if (!endDate || !endTime) {
|
|
alert("Veuillez sélectionner une date et heure de fin");
|
|
return;
|
|
}
|
|
|
|
setIsLoading(true);
|
|
try {
|
|
const scheduledEndDate = new Date(`${endDate}T${endTime}:00`).toISOString();
|
|
|
|
const response = await fetch("/api/maintenance", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
is_maintenance_mode: true,
|
|
maintenance_message: message,
|
|
scheduled_end_date: scheduledEndDate
|
|
})
|
|
});
|
|
|
|
if (response.ok) {
|
|
const newStatus = await response.json();
|
|
setStatus(newStatus);
|
|
setIsModalOpen(false);
|
|
} else {
|
|
alert("Erreur lors de l'activation de la maintenance");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error activating maintenance:", error);
|
|
alert("Erreur lors de l'activation de la maintenance");
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
// Ne pas afficher le composant si ce n'est pas un staff
|
|
if (!isStaff) {
|
|
return null;
|
|
}
|
|
|
|
// Afficher un placeholder pendant le chargement
|
|
if (!status) {
|
|
return (
|
|
<Button
|
|
disabled
|
|
variant="outline"
|
|
size="sm"
|
|
className="flex items-center gap-2 text-gray-400 border-gray-200"
|
|
>
|
|
<PowerOff size={16} />
|
|
Chargement...
|
|
</Button>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{status.is_maintenance_mode ? (
|
|
<Button
|
|
onClick={handleDeactivateMaintenance}
|
|
disabled={isLoading}
|
|
variant="outline"
|
|
size="sm"
|
|
className="flex items-center gap-2 text-green-600 border-green-200 hover:bg-green-50"
|
|
>
|
|
<Power size={16} />
|
|
Réactiver l'Espace Paie
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
onClick={handleActivateMaintenance}
|
|
disabled={isLoading}
|
|
variant="outline"
|
|
size="sm"
|
|
className="flex items-center gap-2 text-orange-600 border-orange-200 hover:bg-orange-50"
|
|
>
|
|
<PowerOff size={16} />
|
|
Fermer l'Espace Paie
|
|
</Button>
|
|
)}
|
|
|
|
<Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
|
|
<DialogContent className="max-w-md">
|
|
<DialogHeader>
|
|
<DialogTitle className="flex items-center gap-2">
|
|
<AlertTriangle className="text-orange-500" size={20} />
|
|
Fermer l'Espace Paie
|
|
</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-4">
|
|
<div>
|
|
<Label htmlFor="message">Message de maintenance</Label>
|
|
<Textarea
|
|
id="message"
|
|
value={message}
|
|
onChange={(e) => setMessage(e.target.value)}
|
|
placeholder="Message affiché aux utilisateurs..."
|
|
rows={3}
|
|
className="mt-1"
|
|
/>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-3">
|
|
<div>
|
|
<Label htmlFor="endDate">Date de fin prévue</Label>
|
|
<Input
|
|
id="endDate"
|
|
type="date"
|
|
value={endDate}
|
|
onChange={(e) => setEndDate(e.target.value)}
|
|
className="mt-1"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Label htmlFor="endTime">Heure de fin</Label>
|
|
<Input
|
|
id="endTime"
|
|
type="time"
|
|
value={endTime}
|
|
onChange={(e) => setEndTime(e.target.value)}
|
|
className="mt-1"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
<Button variant="outline" onClick={() => setIsModalOpen(false)}>
|
|
Annuler
|
|
</Button>
|
|
<Button
|
|
onClick={handleConfirmMaintenance}
|
|
disabled={isLoading}
|
|
className="bg-orange-600 hover:bg-orange-700"
|
|
>
|
|
{isLoading ? "Activation..." : "Activer la maintenance"}
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</>
|
|
);
|
|
} |