maj
This commit is contained in:
218
admin/src/app/settings/page.tsx
Normal file
218
admin/src/app/settings/page.tsx
Normal file
@@ -0,0 +1,218 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect, useTransition } from 'react';
|
||||
import { Save, Globe, Mail, Phone, MapPin, Share2, Link as LinkIcon, Loader2 } from 'lucide-react';
|
||||
import { getSiteSettings, updateSiteSettings } from '@/app/actions/settings';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
||||
export default function SettingsPage() {
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [settings, setSettings] = useState<any>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
async function loadData() {
|
||||
const data = await getSiteSettings();
|
||||
setSettings(data);
|
||||
setLoading(false);
|
||||
}
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(e.currentTarget);
|
||||
const data = {
|
||||
siteName: formData.get('siteName'),
|
||||
siteSlogan: formData.get('siteSlogan'),
|
||||
contactEmail: formData.get('contactEmail'),
|
||||
contactPhone: formData.get('contactPhone'),
|
||||
address: formData.get('address'),
|
||||
facebookUrl: formData.get('facebookUrl'),
|
||||
twitterUrl: formData.get('twitterUrl'),
|
||||
instagramUrl: formData.get('instagramUrl'),
|
||||
linkedinUrl: formData.get('linkedinUrl'),
|
||||
footerText: formData.get('footerText'),
|
||||
};
|
||||
|
||||
startTransition(async () => {
|
||||
const result = await updateSiteSettings(data);
|
||||
if (result.success) {
|
||||
toast.success("Paramètres mis à jour avec succès");
|
||||
} else {
|
||||
toast.error("Erreur lors de la mise à jour");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center p-20">
|
||||
<Loader2 className="w-8 h-8 animate-spin text-indigo-500" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-8 max-w-5xl mx-auto">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-white">Configuration du Site</h1>
|
||||
<p className="text-slate-400">Gérez les informations globales et les coordonnées de contact du site principal.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
{/* Section Générale */}
|
||||
<div className="bg-slate-900/50 border border-slate-700 rounded-2xl overflow-hidden">
|
||||
<div className="p-4 bg-slate-800/50 border-b border-slate-700 flex items-center gap-2">
|
||||
<Globe className="w-5 h-5 text-indigo-400" />
|
||||
<h2 className="font-semibold text-white">Informations Générales</h2>
|
||||
</div>
|
||||
<div className="p-6 grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Nom du site</label>
|
||||
<input
|
||||
name="siteName"
|
||||
defaultValue={settings?.siteName}
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Slogan du site</label>
|
||||
<input
|
||||
name="siteSlogan"
|
||||
defaultValue={settings?.siteSlogan}
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="md:col-span-2 space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Texte du pied de page (Footer)</label>
|
||||
<input
|
||||
name="footerText"
|
||||
defaultValue={settings?.footerText}
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section Contact */}
|
||||
<div className="bg-slate-900/50 border border-slate-700 rounded-2xl overflow-hidden">
|
||||
<div className="p-4 bg-slate-800/50 border-b border-slate-700 flex items-center gap-2">
|
||||
<Mail className="w-5 h-5 text-emerald-400" />
|
||||
<h2 className="font-semibold text-white">Coordonnées de Contact</h2>
|
||||
</div>
|
||||
<div className="p-6 grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Email de support</label>
|
||||
<div className="relative">
|
||||
<Mail className="absolute left-3 top-3.5 w-4 h-4 text-slate-500" />
|
||||
<input
|
||||
name="contactEmail"
|
||||
defaultValue={settings?.contactEmail}
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 pl-10 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Téléphone de contact</label>
|
||||
<div className="relative">
|
||||
<Phone className="absolute left-3 top-3.5 w-4 h-4 text-slate-500" />
|
||||
<input
|
||||
name="contactPhone"
|
||||
defaultValue={settings?.contactPhone}
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 pl-10 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:col-span-2 space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Adresse physique</label>
|
||||
<div className="relative">
|
||||
<MapPin className="absolute left-3 top-3.5 w-4 h-4 text-slate-500" />
|
||||
<input
|
||||
name="address"
|
||||
defaultValue={settings?.address}
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 pl-10 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section Réseaux Sociaux */}
|
||||
<div className="bg-slate-900/50 border border-slate-700 rounded-2xl overflow-hidden">
|
||||
<div className="p-4 bg-slate-800/50 border-b border-slate-700 flex items-center gap-2">
|
||||
<Share2 className="w-5 h-5 text-blue-400" />
|
||||
<h2 className="font-semibold text-white">Réseaux Sociaux</h2>
|
||||
</div>
|
||||
<div className="p-6 grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Facebook URL</label>
|
||||
<div className="relative">
|
||||
<LinkIcon className="absolute left-3 top-3.5 w-4 h-4 text-slate-500" />
|
||||
<input
|
||||
name="facebookUrl"
|
||||
defaultValue={settings?.facebookUrl}
|
||||
placeholder="https://facebook.com/..."
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 pl-10 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Twitter (X) URL</label>
|
||||
<div className="relative">
|
||||
<LinkIcon className="absolute left-3 top-3.5 w-4 h-4 text-slate-500" />
|
||||
<input
|
||||
name="twitterUrl"
|
||||
defaultValue={settings?.twitterUrl}
|
||||
placeholder="https://twitter.com/..."
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 pl-10 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">Instagram URL</label>
|
||||
<div className="relative">
|
||||
<LinkIcon className="absolute left-3 top-3.5 w-4 h-4 text-slate-500" />
|
||||
<input
|
||||
name="instagramUrl"
|
||||
defaultValue={settings?.instagramUrl}
|
||||
placeholder="https://instagram.com/..."
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 pl-10 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-400">LinkedIn URL</label>
|
||||
<div className="relative">
|
||||
<LinkIcon className="absolute left-3 top-3.5 w-4 h-4 text-slate-500" />
|
||||
<input
|
||||
name="linkedinUrl"
|
||||
defaultValue={settings?.linkedinUrl}
|
||||
placeholder="https://linkedin.com/in/..."
|
||||
className="w-full bg-slate-950 border border-slate-700 rounded-xl p-3 pl-10 text-white focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isPending}
|
||||
className="bg-indigo-600 hover:bg-indigo-700 disabled:bg-slate-700 text-white px-8 py-3 rounded-xl font-bold transition-all shadow-lg flex items-center gap-2"
|
||||
>
|
||||
{isPending ? (
|
||||
<Loader2 className="w-5 h-5 animate-spin" />
|
||||
) : (
|
||||
<Save className="w-5 h-5" />
|
||||
)}
|
||||
Enregistrer les modifications
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user