181 lines
5.8 KiB
TypeScript
181 lines
5.8 KiB
TypeScript
'use client';
|
|
import { useState, useEffect } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Textarea } from '@/components/ui/textarea';
|
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
|
import { Label } from '@/components/ui/label';
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
|
import { campaignService } from '@/lib/services';
|
|
import { Campaign, CampaignStatus } from '@/types';
|
|
|
|
interface EditCampaignModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
onSuccess: () => void;
|
|
campaign: Campaign | null;
|
|
}
|
|
|
|
export default function EditCampaignModal({ isOpen, onClose, onSuccess, campaign }: EditCampaignModalProps) {
|
|
const [formData, setFormData] = useState({
|
|
title: '',
|
|
description: '',
|
|
status: 'deposit' as CampaignStatus,
|
|
budget_per_user: '',
|
|
spending_tiers: ''
|
|
});
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState('');
|
|
|
|
useEffect(() => {
|
|
if (campaign) {
|
|
setFormData({
|
|
title: campaign.title,
|
|
description: campaign.description,
|
|
status: campaign.status,
|
|
budget_per_user: campaign.budget_per_user.toString(),
|
|
spending_tiers: campaign.spending_tiers
|
|
});
|
|
}
|
|
}, [campaign]);
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (!campaign) return;
|
|
|
|
setLoading(true);
|
|
setError('');
|
|
|
|
try {
|
|
await campaignService.update(campaign.id, {
|
|
title: formData.title,
|
|
description: formData.description,
|
|
status: formData.status,
|
|
budget_per_user: parseInt(formData.budget_per_user),
|
|
spending_tiers: formData.spending_tiers
|
|
});
|
|
|
|
onSuccess();
|
|
} catch (err) {
|
|
setError('Erreur lors de la modification de la campagne');
|
|
console.error(err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
setFormData(prev => ({
|
|
...prev,
|
|
[e.target.name]: e.target.value
|
|
}));
|
|
};
|
|
|
|
const handleStatusChange = (value: string) => {
|
|
setFormData(prev => ({
|
|
...prev,
|
|
status: value as CampaignStatus
|
|
}));
|
|
};
|
|
|
|
if (!campaign) return null;
|
|
|
|
return (
|
|
<Dialog open={isOpen} onOpenChange={onClose}>
|
|
<DialogContent className="sm:max-w-[500px]">
|
|
<DialogHeader>
|
|
<DialogTitle>Modifier la campagne</DialogTitle>
|
|
<DialogDescription>
|
|
Modifiez les paramètres de votre campagne de budget participatif.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
{error && (
|
|
<div className="p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
|
|
<p className="text-sm text-red-600 dark:text-red-400">{error}</p>
|
|
</div>
|
|
)}
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="title">Titre de la campagne *</Label>
|
|
<Input
|
|
id="title"
|
|
name="title"
|
|
value={formData.title}
|
|
onChange={handleChange}
|
|
placeholder="Ex: Amélioration des espaces verts"
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="description">Description *</Label>
|
|
<Textarea
|
|
id="description"
|
|
name="description"
|
|
value={formData.description}
|
|
onChange={handleChange}
|
|
placeholder="Décrivez l'objectif de cette campagne..."
|
|
rows={3}
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="status">Statut de la campagne</Label>
|
|
<Select value={formData.status} onValueChange={handleStatusChange}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Sélectionnez un statut" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="deposit">Dépôt de propositions</SelectItem>
|
|
<SelectItem value="voting">En cours de vote</SelectItem>
|
|
<SelectItem value="closed">Terminée</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="budget_per_user">Budget par utilisateur (€) *</Label>
|
|
<Input
|
|
id="budget_per_user"
|
|
name="budget_per_user"
|
|
type="number"
|
|
value={formData.budget_per_user}
|
|
onChange={handleChange}
|
|
placeholder="100"
|
|
min="1"
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="spending_tiers">Paliers de dépense *</Label>
|
|
<Input
|
|
id="spending_tiers"
|
|
name="spending_tiers"
|
|
value={formData.spending_tiers}
|
|
onChange={handleChange}
|
|
placeholder="Ex: 0, 10, 25, 50, 100"
|
|
required
|
|
/>
|
|
<p className="text-xs text-slate-500 dark:text-slate-400">
|
|
Séparez les montants par des virgules (ex: 0, 10, 25, 50, 100)
|
|
</p>
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
<Button type="button" variant="outline" onClick={onClose}>
|
|
Annuler
|
|
</Button>
|
|
<Button type="submit" disabled={loading}>
|
|
{loading ? 'Modification...' : 'Modifier la campagne'}
|
|
</Button>
|
|
</DialogFooter>
|
|
</form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|