groupe-meditation/frontend/src/features/assemblees/assembleeUi.jsx

88 lines
4.6 KiB
React
Raw Normal View History

import React from 'react';
import { labelDateReunion } from '../../utils/datesReunion';
export const INPUT = 'w-full p-3 bg-gray-50 rounded-xl border-0 focus:ring-2 focus:ring-aa-blue';
const STATUTS = {
proposee: ['À seconder', 'bg-yellow-100 text-yellow-700'],
secondee: ['Secondée', 'bg-blue-100 text-blue-700'],
rejetee: ['Rejetée', 'bg-red-100 text-red-700'],
};
export function boutonAction(actif) {
return `p-3 rounded-xl text-sm font-bold ${actif ? 'bg-aa-blue text-white' : 'bg-gray-50 text-gray-700'}`;
}
export function Card({ titre, children }) {
return <div className="bg-white rounded-2xl p-4 shadow-sm space-y-3"><h2 className="font-bold text-gray-800">{titre}</h2>{children}</div>;
}
export function Champ({ label, children }) {
return <label className="block"><span className="text-xs text-gray-400 block mb-1">{label}</span>{children}</label>;
}
export function SelectDate({ value, onChange, dates }) {
if (!dates.length) {
return <div className="rounded-xl bg-gray-50 p-3 text-sm text-gray-500">Configurez le jour de réunion dans les paramètres du groupe.</div>;
}
return (
<select value={value} onChange={(e) => onChange(e.target.value)} className={INPUT}>
{dates.map((d) => <option key={d} value={d}>{labelDateReunion(d)}</option>)}
</select>
);
}
export function MembreSelect({ label, value, onChange, membres }) {
return (
<select value={value} onChange={(e) => onChange(e.target.value)} className={INPUT}>
<option value="">{label}</option>
{membres.map((m) => <option key={m.id} value={m.id}>{m.prenom}</option>)}
</select>
);
}
export function DecisionItem({ p, membres, estExecutif, form, setForm, seconderPour, setSeconderPour, seconder, voter }) {
const [label, cls] = STATUTS[p.statut] || STATUTS.proposee;
const motif = (form.etant_donne_que || '').trim();
const decision = (form.groupe_a_decide_de || '').trim();
return (
<div className="rounded-xl bg-gray-50 p-3 space-y-2">
<div className="flex items-start justify-between gap-2">
<div className="min-w-0">
<p className="font-bold text-gray-800">{p.sujet}</p>
{p.description && <p className="text-sm text-gray-500">{p.description}</p>}
<p className="text-xs text-gray-400 mt-1">Proposée par {p.proposeur_prenom}{p.secondeur_prenom ? ` · Secondée par ${p.secondeur_prenom}` : ''}</p>
</div>
<span className={`text-xs px-2 py-1 rounded-full font-medium whitespace-nowrap ${cls}`}>{label}</span>
</div>
{p.statut === 'proposee' && (
<div className="space-y-2">
{estExecutif && <textarea value={form.etant_donne_que || ''} onChange={(e) => setForm('etant_donne_que', e.target.value)} placeholder="ÉTANT DONNÉ QUE..." rows={2} className={`${INPUT} resize-none text-sm`} />}
<div className="grid grid-cols-2 gap-2">
{estExecutif && <button onClick={() => voter(p.id, 'rejetee')} disabled={!motif} className="p-2 bg-red-50 text-red-700 rounded-xl text-sm font-bold disabled:opacity-40">Rejeter</button>}
<button onClick={() => seconder(p.id)} className="p-2 bg-blue-50 text-blue-700 rounded-xl text-sm font-bold">Je seconde</button>
</div>
{estExecutif && (
<div className="grid grid-cols-[1fr_auto] gap-2">
<MembreSelect label="Seconder pour" value={seconderPour} onChange={setSeconderPour} membres={membres} />
<button onClick={() => seconder(p.id, seconderPour)} disabled={!seconderPour} className="px-4 bg-blue-600 text-white rounded-xl text-sm font-bold disabled:opacity-40">OK</button>
</div>
)}
</div>
)}
{p.statut === 'secondee' && estExecutif && (
<div className="space-y-2">
<textarea value={form.etant_donne_que || ''} onChange={(e) => setForm('etant_donne_que', e.target.value)} placeholder="ÉTANT DONNÉ QUE..." rows={2} className={`${INPUT} resize-none text-sm`} />
<textarea value={form.groupe_a_decide_de || ''} onChange={(e) => setForm('groupe_a_decide_de', e.target.value)} placeholder="LE GROUPE A DÉCIDÉ DE..." rows={2} className={`${INPUT} resize-none text-sm`} />
<div className="grid grid-cols-2 gap-2">
<button onClick={() => voter(p.id, 'rejetee')} disabled={!motif} className="p-2 bg-red-50 text-red-700 rounded-xl text-sm font-bold disabled:opacity-40">Rejeter</button>
<button onClick={() => voter(p.id, 'adoptee')} disabled={!motif || !decision} className="p-2 bg-green-50 text-green-700 rounded-xl text-sm font-bold disabled:opacity-40">Transformer</button>
</div>
</div>
)}
</div>
);
}