"fix-guest-auto-flush-on-submit"
This commit is contained in:
@@ -2,18 +2,42 @@
|
||||
* Gestion de la liste d'invités pour une facture.
|
||||
* Ajout / suppression d'invités (nom + entreprise).
|
||||
*/
|
||||
import { useState } from 'react';
|
||||
import { useState, useImperativeHandle, forwardRef } from 'react';
|
||||
import type { Guest } from '../types';
|
||||
|
||||
export interface GuestManagerHandle {
|
||||
/**
|
||||
* Si un invité est en cours de saisie (champ non validé), l'ajoute à la liste
|
||||
* et retourne la liste complète (incluant ce nouvel invité).
|
||||
* Retourne null si rien à flusher.
|
||||
*/
|
||||
flushPending: () => Guest[] | null;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
guests: Guest[];
|
||||
onChange: (guests: Guest[]) => void;
|
||||
}
|
||||
|
||||
export default function GuestManager({ guests, onChange }: Props) {
|
||||
const GuestManager = forwardRef<GuestManagerHandle, Props>(function GuestManager({ guests, onChange }, ref) {
|
||||
const [name, setName] = useState('');
|
||||
const [company, setCompany] = useState('');
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
flushPending() {
|
||||
const trimmed = name.trim();
|
||||
if (!trimmed) return null;
|
||||
const updated: Guest[] = [
|
||||
...guests,
|
||||
{ name: trimmed, company: company.trim() || null, sort_order: guests.length },
|
||||
];
|
||||
onChange(updated);
|
||||
setName('');
|
||||
setCompany('');
|
||||
return updated;
|
||||
},
|
||||
}));
|
||||
|
||||
function addGuest() {
|
||||
const trimmed = name.trim();
|
||||
if (!trimmed) return;
|
||||
@@ -94,4 +118,6 @@ export default function GuestManager({ guests, onChange }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default GuestManager;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import toast from 'react-hot-toast';
|
||||
import api from '../api/client';
|
||||
import Camera from '../components/Camera';
|
||||
import GuestManager from '../components/GuestManager';
|
||||
import GuestManager, { type GuestManagerHandle } from '../components/GuestManager';
|
||||
import { useOCR } from '../hooks/useOCR';
|
||||
import { useOfflineQueue } from '../hooks/useOfflineQueue';
|
||||
import type { Company, Category, Guest, InvoiceImage } from '../types';
|
||||
@@ -34,6 +34,9 @@ export default function NewInvoice() {
|
||||
// Ref pour retenir l'invoice_id créé si le send échoue hors ligne
|
||||
const createdInvoiceIdRef = useRef<string | null>(null);
|
||||
|
||||
// Ref vers GuestManager pour flusher l'invité en cours de saisie
|
||||
const guestManagerRef = useRef<GuestManagerHandle>(null);
|
||||
|
||||
// ── Étape du flux ──────────────────────────────────────────
|
||||
const [step, setStep] = useState<Step>('capture');
|
||||
|
||||
@@ -101,6 +104,15 @@ export default function NewInvoice() {
|
||||
|
||||
createdInvoiceIdRef.current = null;
|
||||
|
||||
// Auto-ajouter l'invité en cours de saisie s'il n'a pas encore été
|
||||
// validé via "Ajouter l'invité" (cas fréquent : l'utilisateur tape
|
||||
// le nom et clique directement sur "Envoyer").
|
||||
// flushPending() retourne la liste complète si un guest a été flushé,
|
||||
// null sinon — on utilise cette valeur pour éviter un souci de timing
|
||||
// avec la mise à jour asynchrone du state React.
|
||||
const guestsFlushed = guestManagerRef.current?.flushPending() ?? null;
|
||||
const finalGuests = guestsFlushed ?? guests;
|
||||
|
||||
const invoiceImages: InvoiceImage[] = images.map((img) => ({
|
||||
path: img.filename,
|
||||
order: img.order,
|
||||
@@ -116,7 +128,7 @@ export default function NewInvoice() {
|
||||
comment: comment || undefined,
|
||||
images: invoiceImages,
|
||||
add_to_tracking: addTracking,
|
||||
guests,
|
||||
guests: finalGuests,
|
||||
});
|
||||
|
||||
// Mémoriser l'id en cas d'échec du send hors ligne
|
||||
@@ -441,7 +453,7 @@ export default function NewInvoice() {
|
||||
|
||||
{showGuests && (
|
||||
<div className="mt-3">
|
||||
<GuestManager guests={guests} onChange={setGuests} />
|
||||
<GuestManager ref={guestManagerRef} guests={guests} onChange={setGuests} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user