mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-12 01:36:43 +02:00
feat(grid): add premium semi-blocking glassmorphism loading overlay with real-time stream progression
This commit is contained in:
1 parent
475ba230b0
commit
1b5c260813
2 files changed
+82
-16
No files matched your search
@@ -49,6 +49,7 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
|
||||
const [rowsLoaded, setRowsLoaded] = useState(0);
|
||||
const [totalRows, setTotalRows] = useState<number | null>(null);
|
||||
const [loadError, setLoadError] = useState<string | null>(null);
|
||||
const [showStartOverlay, setShowStartOverlay] = useState(false);
|
||||
|
||||
const noSalesCount = useMemo(() => countNoSalesIn6Months(rows), [rows]);
|
||||
|
||||
@@ -99,6 +100,7 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
|
||||
setTotalRows(null);
|
||||
setLoadError(null);
|
||||
setIsLoadingRows(true);
|
||||
setShowStartOverlay(true);
|
||||
|
||||
async function loadRows() {
|
||||
try {
|
||||
@@ -294,6 +296,75 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
|
||||
<FloatingSummaryBar />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Overlay de démarrage premium (Glassmorphism semi-bloquant) */}
|
||||
{showStartOverlay && isLoadingRows && (
|
||||
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4 backdrop-blur-md bg-slate-950/30 dark:bg-black/40 animate-fade-in">
|
||||
<div
|
||||
className="w-full max-w-md rounded-2xl border p-6 shadow-2xl flex flex-col items-center text-center space-y-5 transition-transform duration-300 transform scale-100"
|
||||
style={{
|
||||
background: "rgba(255, 255, 255, 0.75)",
|
||||
borderColor: "var(--border)",
|
||||
backdropFilter: "blur(20px)",
|
||||
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
|
||||
}}
|
||||
>
|
||||
{/* Header avec logo ou icône animée */}
|
||||
<div className="relative flex items-center justify-center w-16 h-16 rounded-full bg-emerald-500/10 text-emerald-600 dark:text-emerald-400">
|
||||
<Loader2 className="w-8 h-8 animate-spin" />
|
||||
<div className="absolute inset-0 rounded-full border border-emerald-500/20 animate-ping duration-1000" />
|
||||
</div>
|
||||
|
||||
{/* Titre et descriptions */}
|
||||
<div className="space-y-1">
|
||||
<h3 className="text-lg font-bold tracking-tight text-emerald-800 dark:text-emerald-400">
|
||||
Flux d'Assortiment en cours
|
||||
</h3>
|
||||
<p className="text-xs text-muted-foreground max-w-[280px] mx-auto animate-pulse" style={{ color: "var(--text-muted)" }}>
|
||||
Chargement progressif et en temps réel des données pour <span className="font-semibold" style={{ color: "var(--text-secondary)" }}>{nomFournisseur}</span>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Barre de progression dynamique */}
|
||||
<div className="w-full space-y-2">
|
||||
<div className="flex justify-between text-xs font-semibold" style={{ color: "var(--text-secondary)" }}>
|
||||
<span>Progression</span>
|
||||
<span>
|
||||
{totalRows
|
||||
? `${Math.round((rowsLoaded / totalRows) * 100)}%`
|
||||
: `${rowsLoaded.toLocaleString("fr-FR")} réfs`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="w-full h-2 rounded-full overflow-hidden bg-slate-100 dark:bg-slate-800" style={{ border: "1px solid var(--border)" }}>
|
||||
<div
|
||||
className="h-full bg-gradient-to-r from-emerald-500 to-teal-500 transition-all duration-300 ease-out rounded-full"
|
||||
style={{
|
||||
width: totalRows ? `${(rowsLoaded / totalRows) * 100}%` : "40%",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-[11px] font-medium animate-pulse" style={{ color: "var(--text-muted)" }}>
|
||||
{totalRows
|
||||
? `${rowsLoaded.toLocaleString("fr-FR")} sur ${totalRows.toLocaleString("fr-FR")} références chargées`
|
||||
: `${rowsLoaded.toLocaleString("fr-FR")} références récupérées...`}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Boutons d'action */}
|
||||
<div className="w-full pt-2 flex flex-col gap-2">
|
||||
<button
|
||||
onClick={() => setShowStartOverlay(false)}
|
||||
className="w-full flex items-center justify-center gap-2 px-4 py-2.5 rounded-xl text-sm font-semibold text-white bg-emerald-600 hover:bg-emerald-500 active:scale-95 hover:shadow-lg hover:shadow-emerald-500/20 transition-all duration-200"
|
||||
>
|
||||
Explorer les premières données
|
||||
</button>
|
||||
<p className="text-[10px] text-muted italic" style={{ color: "var(--text-muted)" }}>
|
||||
Le chargement continuera en arrière-plan sans bloquer votre navigation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,24 +1,19 @@
|
||||
# Plan - Commit et Push des optimisations de performances de la grille
|
||||
# Plan - Implémentation de l'overlay de chargement premium (Glassmorphism)
|
||||
|
||||
## Contexte
|
||||
L'utilisateur a demandé de commiter et pusher de nouvelles modifications locales. L'analyse révèle des optimisations de performances clés apportées au store Zustand de la grille :
|
||||
1. Indexation rapide des lignes de produits par `codein` dans `rowsByCodein` pour accélérer la mise à jour des brouillons de O(N) à O(1).
|
||||
2. Debouncing du calcul des résumés (`computeSummary`) afin d'alléger le thread principal lors des imports en streaming ou des modifications de masse.
|
||||
L'utilisateur souhaite ajouter un indicateur visuel de chargement lors du chargement de la grille. L'option retenue est un overlay de démarrage en verre dépoli (glassmorphism) semi-bloquant. Cet overlay affiche la progression du streaming en temps réel et propose un bouton pour ignorer l'overlay et explorer directement les premières données déjà chargées.
|
||||
|
||||
## Focus Actuel
|
||||
Validation finale et dépôt propre.
|
||||
Validation finale et publication Git (commit et push).
|
||||
|
||||
## Master Plan
|
||||
- [x] Analyser l'état de Git et identifier les nouveaux fichiers modifiés (Fait: 5 fichiers)
|
||||
- [x] Vérifier la compilation globale du projet avec `rtk tsc` (Fait)
|
||||
- [x] Ajouter les fichiers à l'index Git (`rtk git add`) (Fait)
|
||||
- [x] Créer le commit avec un message décrivant les optimisations de performance (`rtk git commit`) (Fait: "perf(grid): optimize state store with O(1) row indexing and debounced summary calculations")
|
||||
- [x] Envoyer le commit vers le dépôt distant (`rtk git push`) (Fait)
|
||||
- [x] Valider le statut Git final (Fait)
|
||||
- [x] Définir le concept de design avec l'utilisateur (Fait: Option A sélectionnée)
|
||||
- [x] Modifier `src/features/grid/components/grid-client.tsx` (Fait)
|
||||
- [x] Vérifier la compilation globale avec `rtk tsc` (Fait: aucune erreur)
|
||||
- [ ] Valider l'esthétique et le comportement en simulant le chargement
|
||||
- [ ] Mettre à jour Git (commit et push)
|
||||
|
||||
## Progress Log
|
||||
- **2026-05-26 13:53** : Analyse des nouvelles modifications. Découverte des optimisations majeures sur `use-grid-store.ts` (indexation O(1) et debouncing des calculs de résumé).
|
||||
- **2026-05-26 13:54** : Vérification de la compilation TypeScript via `rtk tsc` (aucune erreur liée à nos changements).
|
||||
- **2026-05-26 13:55** : Indexation des fichiers modifiés et de `task.md` via `rtk git add .`.
|
||||
- **2026-05-26 13:56** : Création du commit décrivant l'indexation de O(N) à O(1) et le debouncing.
|
||||
- **2026-05-26 13:57** : Push des modifications sur `origin/main` effectué avec succès.
|
||||
- **2026-05-26 13:58** : Choix du design validé par l'utilisateur (Option A : Overlay de démarrage en glassmorphism avec option d'exploration). Initialisation du plan dans `task.md`.
|
||||
- **2026-05-26 14:00** : Intégration de l'overlay de chargement premium en verre dépoli (glassmorphism) semi-bloquant avec indicateur dynamique et bouton d'exploration.
|
||||
- **2026-05-26 14:01** : Vérification de la compilation avec `rtk tsc` réussie.
|
||||
Reference in new issue
Block a user