import { useQuery } from "@tanstack/react-query";
import { Plus, Upload } from "lucide-react";
import { api } from "@/lib/api";
import { queryKeys } from "@/lib/queryKeys";
import { Button } from "@/components/ui/Button";
import { AppSidebar } from "./AppSidebar";
import { AppTopbar } from "./AppTopbar";
import { MobileTabBar } from "./MobileTabBar";
import { DemoClock } from "@/components/demo/DemoClock";
import { Link } from "@tanstack/react-router";
import {
ManualInvoiceProvider,
useManualInvoice,
} from "@/hooks/useManualInvoiceDialog";
/**
* Shell de l'app authentifiée :
* - Desktop : sidebar fixe à gauche + main + topbar sticky en haut
* - Mobile : pas de sidebar, topbar avec brand, tab bar fixe en bas
*
* Le bottom-padding mobile (pb-20) évite que le tab bar masque le contenu.
*/
type AppLayoutProps = {
children: React.ReactNode;
/** Titre du topbar (sinon greeting + date). */
title?: string;
subtitle?: string;
/** Actions à droite du topbar. */
actions?: React.ReactNode;
};
type DashboardKpis = {
rubisCount: number;
rubisThisMonth: number;
hoursLiberatedThisMonth: number;
encaisseCents: number;
encaisseDeltaCents: number;
dsoDays: number;
dsoDeltaDays: number;
factureToRelance: number;
factureInRelance: number;
factureNewToday: number;
miseEnDemeurePending: number;
};
export function AppLayout({ children, title, subtitle, actions }: AppLayoutProps) {
return (
{children}
);
}
function AppLayoutInner({ children, title, subtitle, actions }: AppLayoutProps) {
const manual = useManualInvoice();
// KPIs partagés layout ↔ dashboard : on les charge ici pour que le sidebar
// affiche le compteur sans attendre le rendu du dashboard.
const { data: kpis } = useQuery({
queryKey: queryKeys.dashboard.kpis(),
queryFn: () => api.get("/api/v1/dashboard/kpis"),
staleTime: 30_000,
});
// Actions globales par défaut (visibles desktop seulement). Sur mobile,
// chaque route gère ses propres CTA en tête de contenu (cf. wireframe 4.3).
const defaultActions = (
);
return (
{children}
{/* Horloge démo — auto-cachée si org.demoMode = false */}