88 lines
4.6 KiB
React
88 lines
4.6 KiB
React
|
|
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>
|
||
|
|
);
|
||
|
|
}
|