// ECO-PANNEAU.FR - _react/admin/_admin_panneaux.jsx

// 1. - COMPOSANT CARTE ISOLÉ ET RÉUTILISABLE ADMINISTRATEUR
window.pano_AdminPanelCard = ({
    panel: p, clients, isPinned, toggleDashboardPin, unreadSupport, needsControl, hasBeenSuspended, isViolation, detected,
    setPreviewPanneau, refreshData, setManagingPanneau, setValidationErrors,
    openModal, openLocalModal, openDialog, openLocalDialog, closeCurrentLayer, openChat, activeDialog, dialogId, data
}) => {
    const { useState } = React;
    
    const { isMounted, safeFetch } = window.pano_useSafeFetch();

    const [isSaving, setIsSaving] = useState(false);
    const [suspendReason, setSuspendReason] = useState("");
    const [adminPassword, setAdminPassword] = useState("");
    const [deletePassword, setDeletePassword] = useState("");
    const [deleteAesKey, setDeleteAesKey] = useState("");
    const [deleteReason, setDeleteReason] = useState("");

    const { DataCard, IconBadge, StatusBadge, Button, NotificationBadge, Modal, FormInput } = window.pano_getComponents();
    const { BuildingIcon, PinIcon, QrCodeIcon, EyeIcon, AlertTriangleIcon, CheckCircleIcon, MessageSquareIcon, UserIcon, LockIcon, Trash2Icon, PowerIcon } = window.pano_getIcons();

    const handleOpenModal = (n, id, s) => {
        if (openModal) openModal(n, id, s);
        else if (openLocalModal) openLocalModal(n, id, s);
    };

    const handleOpenDialog = (n, id, s) => {
        if (openDialog) openDialog(n, id, s);
        else if (openLocalDialog) openLocalDialog(n, id, s);
    };

    const handleCloseLayer = () => {
        if (closeCurrentLayer) closeCurrentLayer();
    };

    const handleOpenChat = (id, s) => {
        if (openChat) openChat(id, s);
        else {
            const prev = window.history.state || { panoStack: [], level: 0, currentTab: 'dashboard' };
            const newStack = (prev.panoStack || []).filter(l => l.type !== 'chat');
            newStack.push({ type: 'chat', name: 'chat', targetId: id });
            window.history.pushState({ ...prev, panoStack: newStack, level: newStack.length }, '', window.location.href);
            window.dispatchEvent(new Event('pano_stack_sync'));
        }
    };

    const owner = clients.find(c => c.id === (p.client_uid || p.clientName));
    const supportThreadId = 'SUPPORT_' + (p.client_uid || p.clientName);
    
    const hasDraft = p.draft_data && Object.keys(p.draft_data).length > 0;

    const adminSettings = data?.settings || {};
    const limitStrikes = parseInt(adminSettings.limit_strikes_suspend || 5, 10);
    const suspendCount = p.suspend_count || 0;
    const canHardDelete = suspendCount >= limitStrikes;

    let cardVariant = 'default';
    if (isViolation) cardVariant = 'danger';
    else if (p.status === 'Attente validation') cardVariant = 'warning';
    else if (p.status === 'Suspendu') cardVariant = 'warning';

    const handleValidatePanel = async () => {
        const d = await safeFetch('panneaux/mark_seen', { 
            body: { id: p.id }, 
            setLoading: setIsSaving,
            successMessage: "Panneau validé et activé." 
        });
        
        if (!isMounted.current) return;
        if (d && refreshData) refreshData();
    };

    const handleSuspendSubmit = async (e) => {
        e.preventDefault();
        if (!suspendReason.trim() || !adminPassword) return;

        const d1 = await safeFetch('panneaux/status', { 
            body: { id: p.id, status: 'Suspendu', password: adminPassword, reason: suspendReason },
            setLoading: setIsSaving
        });
        
        if (!isMounted.current) return;

        if (d1) {
            const message = `Le panneau "${p.name}" a été suspendu ou rejeté car il nécessite une correction.\n\nMotif :\n${suspendReason}\n\nVeuillez apporter les corrections nécessaires pour pouvoir le réactiver (statut "Actif").\n\nVous trouverez en pièce jointe de l'e-mail qui vient de vous être envoyé, un rappel de nos Conditions Générales de Vente (CGV).`;
            await safeFetch('interactions', {
                body: { panneauId: supportThreadId, detail: message, author: 'Admin', targetEmail: 'Client', type: 'message' }
            });
            
            if (!isMounted.current) return;
            
            if (refreshData) refreshData();
            handleCloseLayer();
            setTimeout(() => { 
                if (isMounted.current) {
                    setSuspendReason(""); 
                    setAdminPassword(""); 
                }
            }, 300);
        }
    };

    const handleDeleteSubmit = async (e) => {
        e.preventDefault();
        if (!deletePassword || !deleteAesKey || !deleteReason.trim()) return;

        const needsDOE = p.status === 'Actif' || p.status === 'Suppression programmée' || p.status === 'Suspendu';

        if (needsDOE) {
            const d = await safeFetch('archives/doe', {
                body: { id: p.id, admin_delete_reason: deleteReason, password: deletePassword, aes_key_confirm: deleteAesKey },
                setLoading: setIsSaving,
                successMessage: "Panneau clôturé (D.O.E généré) et client notifié."
            });
            
            if (!isMounted.current) return;
            
            if (d) {
                if (refreshData) refreshData();
                handleCloseLayer();
                setTimeout(() => {
                    if (isMounted.current) {
                        setDeletePassword(""); setDeleteAesKey(""); setDeleteReason("");
                    }
                }, 300);
            }
        } else {
            const d = await safeFetch('panneaux/delete', { 
                body: { id: p.id, force_immediate: true, password: deletePassword, aes_key_confirm: deleteAesKey, admin_delete_reason: deleteReason }, 
                setLoading: setIsSaving,
                successMessage: "Panneau supprimé définitivement et client notifié."
            });
            
            if (!isMounted.current) return;

            if (d) {
                if (refreshData) refreshData();
                handleCloseLayer();
                setTimeout(() => { 
                    if (isMounted.current) {
                        setDeletePassword(""); setDeleteAesKey(""); setDeleteReason("");
                    }
                }, 300);
            }
        }
    };

    return (
        <>
            <DataCard variant={cardVariant} className="min-w-0 w-full p-4 relative group">
                <div 
                    role="button" 
                    tabIndex={0} 
                    onClick={(e) => { e.stopPropagation(); toggleDashboardPin && toggleDashboardPin('panels', p.id, e); }} 
                    className={`absolute top-2 right-2 z-20 p-1 cursor-pointer transition-all duration-200 ${isPinned ? 'text-purple-500 opacity-100 hover:scale-110' : 'text-slate-300 opacity-0 group-hover:opacity-100 hover:text-slate-500 hover:scale-110'}`}
                    style={{ transform: 'rotate(30deg)' }}
                    title={isPinned ? "Désépingler" : "Épingler au tableau de bord"}
                >
                    <PinIcon size={18} filled={isPinned} />
                </div>

                <div className="flex justify-between items-start gap-3 min-w-0">
                    <div className="flex items-start gap-3 min-w-0 flex-1">
                        <IconBadge icon={BuildingIcon} variant={p.status === 'Actif' ? 'success' : (p.status === 'Suspendu' || p.status === 'Attente validation' ? 'danger' : 'secondary')} size="lg" className="shrink-0" />
                        <div className="min-w-0 flex-1">
                            <h3 className={`font-black text-lg break-words leading-tight ${p.name ? 'text-slate-800' : 'text-slate-400 italic'}`} title={p.name}>{p.name || 'Projet sans nom'}</h3>
                            {p.location && <p className="text-xs font-medium text-slate-500 mt-1 break-words leading-tight" title={p.location}>{p.location}</p>}
                            <div className="flex items-center gap-1 mt-1 text-blue-600 min-w-0">
                                <UserIcon size={10} className="shrink-0" />
                                <p className="text-[10px] font-bold break-words leading-tight truncate">{owner ? owner.name : p.clientName}</p>
                            </div>
                        </div>
                    </div>
                    
                    <div className="flex flex-col items-end gap-2 shrink-0 mt-2">
                        <div className="flex items-center gap-2">
                            {p.status === 'Actif' && hasDraft && (
                                <span className="text-[10px] font-black uppercase tracking-widest bg-purple-100 text-purple-700 px-2 py-0.5 rounded shadow-sm">Modifié</span>
                            )}
                            {p.status !== 'Actif' && <StatusBadge status={p.status} />}
                        </div>
                    </div>
                </div>
                
                <div className="flex flex-wrap items-center gap-2 pt-3 border-t border-slate-100 mt-auto min-w-0">
                    
                    {needsControl ? (
                        <Button 
                            variant={hasBeenSuspended ? "warningSolid" : "info"} 
                            icon={AlertTriangleIcon} 
                            onClick={(e) => {
                                e.stopPropagation();
                                const panelToView = p.draft_data ? { ...p, ...p.draft_data } : p;
                                if (setPreviewPanneau) setPreviewPanneau(panelToView); 
                                handleOpenModal('preview_admin', p.id, false);
                            }} 
                            className="flex-1 text-[10px] justify-center" 
                            title="Contrôler la demande du client"
                        >
                            Contrôler
                        </Button>
                    ) : (
                        <Button 
                            variant="secondary" 
                            shape="square"
                            icon={p.status === 'Actif' ? QrCodeIcon : EyeIcon} 
                            onClick={(e) => {
                                e.stopPropagation();
                                const livePanel = { ...p };
                                if (p.status === 'Actif') {
                                    delete livePanel.draft_data;
                                } else {
                                    Object.assign(livePanel, livePanel.draft_data || {});
                                }
                                if (setPreviewPanneau) setPreviewPanneau(livePanel);
                                handleOpenModal('preview_admin', p.id, false);
                            }} 
                            className={`bg-white shadow-sm ${p.status === 'Actif' ? 'text-emerald-600 hover:border-emerald-300 hover:bg-emerald-50' : 'text-slate-500 hover:border-blue-300 hover:bg-blue-50'}`} 
                            title={p.status === 'Actif' ? "Voir le panneau public en ligne" : "Aperçu du panneau"} 
                        />
                    )}

                    {p.status === 'Attente validation' && (
                        <Button variant="successSolid" icon={CheckCircleIcon} onClick={(e) => { e.stopPropagation(); handleValidatePanel(); }} disabled={isSaving} className="flex-1 text-[10px] justify-center">Valider</Button>
                    )}
                    
                    {isViolation && (
                        <Button variant="danger" shape="round" icon={AlertTriangleIcon} onClick={(e) => { e.stopPropagation(); handleOpenDialog('moderation', p.id, false); }} className="shadow-none border-none bg-red-50 text-red-600 hover:bg-red-100" title="Alerte modération" />
                    )}

                    <Button 
                        variant="info" 
                        shape="square" 
                        icon={MessageSquareIcon} 
                        onClick={(e) => { 
                            e.stopPropagation(); 
                            handleOpenChat(supportThreadId, false); 
                        }} 
                        className="shadow-none border-none bg-white relative" 
                        title="Contacter le propriétaire"
                    >
                        <NotificationBadge count={unreadSupport} className="absolute -top-2 -right-2 scale-75" />
                    </Button>
                    
                    {canHardDelete && (
                        <Button variant="danger" shape="round" icon={Trash2Icon} onClick={(e) => { e.stopPropagation(); setDeletePassword(""); setDeleteAesKey(""); setDeleteReason(""); handleOpenDialog('delete_panel', p.id, false); }} className="shadow-none shrink-0 bg-white hover:bg-red-50" title="Supprimer définitivement" />
                    )}
                </div>
            </DataCard>

            {/* Modales Encapsulées */}
            {activeDialog === 'suspend' && dialogId === p.id && Modal && (
                <Modal 
                    title="Suspendre / Rejeter" 
                    type="warning" 
                    onClose={handleCloseLayer} 
                    preventClose={isSaving} 
                    actions={(close) => (
                        <>
                            <Button variant="secondary" type="button" onClick={close} disabled={isSaving} className="flex-1 py-3 justify-center">Annuler</Button>
                            <Button variant="warningSolid" type="submit" form={`suspend-form-${p.id}`} disabled={isSaving || !suspendReason.trim() || !adminPassword} className="flex-[2] py-3 uppercase tracking-widest justify-center shadow-md text-xs">
                                {isSaving ? "Traitement..." : "Suspendre le panneau"}
                            </Button>
                        </>
                    )}
                >
                    <form id={`suspend-form-${p.id}`} onSubmit={handleSuspendSubmit} className="space-y-4">
                        <div className="bg-amber-50 p-4 rounded-xl border border-amber-200">
                            <p className="text-sm text-amber-800 font-bold break-words leading-relaxed mb-1">
                                Avertissement N°{suspendCount + 1} / {limitStrikes}
                            </p>
                            <p className="text-xs text-amber-700">Le client recevra un e-mail formel contenant votre motif ainsi que les Conditions Générales de Vente (CGV) en pièce jointe PDF.</p>
                        </div>

                        <div className="space-y-2">
                            <label className="text-xs font-bold text-slate-500 uppercase block break-words">Explication pour le client</label>
                            <textarea 
                                value={suspendReason} 
                                onChange={e => setSuspendReason(e.target.value)} 
                                required 
                                rows={3}
                                placeholder="Motif détaillé de la suspension..."
                                className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-amber-500 outline-none transition resize-none custom-scrollbar break-words"
                            />
                        </div>
                        <div className="p-3 bg-slate-50 border border-slate-200 rounded-xl min-w-0">
                            <FormInput label="Sécurité requise" icon={<LockIcon size={14}/>} type="password" value={adminPassword} onChange={e => setAdminPassword(e.target.value)} placeholder="Mot de passe admin" required className="min-w-0" />
                        </div>
                    </form>
                </Modal>
            )}

            {activeDialog === 'delete_panel' && dialogId === p.id && Modal && (
                <Modal 
                    title="Suppression forcée du panneau" 
                    type="error" 
                    onClose={handleCloseLayer} 
                    preventClose={isSaving} 
                    actions={(close) => (
                        <>
                            <Button variant="secondary" type="button" onClick={close} disabled={isSaving} className="flex-1 py-3 justify-center">Annuler</Button>
                            <Button variant="dangerSolid" type="submit" form={`delete-panel-form-${p.id}`} disabled={isSaving || !deletePassword || !deleteAesKey || !deleteReason.trim()} className="flex-[2] py-3 uppercase tracking-widest justify-center shadow-md text-xs">Clôturer / Détruire</Button>
                        </>
                    )}
                >
                    <form id={`delete-panel-form-${p.id}`} onSubmit={handleDeleteSubmit} className="space-y-4 min-w-0">
                        <p className="text-sm text-slate-600 font-medium break-words leading-relaxed">
                            Ce panneau a épuisé son quota d'avertissements ({suspendCount} avertissements). Vous êtes sur le point de le détruire de force. 
                            {p.status === 'Actif' || p.status === 'Suppression programmée' || p.status === 'Suspendu' ? ' Son archive D.O.E sera tout de même générée et transmise au client.' : ' Le panneau sera effacé définitivement.'}
                        </p>
                        
                        <div className="space-y-2">
                            <label className="text-xs font-bold text-slate-500 uppercase block break-words">Motif de la suppression <span className="text-red-500">*</span></label>
                            <textarea 
                                value={deleteReason} 
                                onChange={e => setDeleteReason(e.target.value)} 
                                required 
                                rows={3}
                                placeholder="Expliquez la raison (ce message sera envoyé par e-mail au client)..."
                                className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-red-500 outline-none transition resize-none custom-scrollbar break-words"
                            />
                        </div>

                        <div className="p-3 bg-red-50 border border-red-200 rounded-xl space-y-3 min-w-0 mt-4">
                            <h4 className="text-xs font-bold text-red-700 uppercase flex items-center gap-2 mb-2 break-words"><LockIcon size={14} className="shrink-0"/> Sécurité requise</h4>
                            <FormInput type="password" value={deletePassword} onChange={e => setDeletePassword(e.target.value)} placeholder="Mot de passe admin" required error className="min-w-0" />
                            <FormInput type="password" value={deleteAesKey} onChange={e => setDeleteAesKey(e.target.value)} placeholder="Clé AES_KEY_CONFIRM" required error className="min-w-0" />
                        </div>
                    </form>
                </Modal>
            )}

            {activeDialog === 'moderation' && dialogId === p.id && Modal && (
                <Modal 
                    title="Alerte modération" 
                    type="error" 
                    onClose={handleCloseLayer} 
                    actions={(close) => (
                        <div className="flex flex-col gap-2 w-full">
                            <Button variant="info" icon={MessageSquareIcon} onClick={() => { handleCloseLayer(); setTimeout(() => { handleOpenChat(supportThreadId, false); }, 100); }} className="w-full py-3 justify-center text-sm shadow-sm">Contacter le propriétaire</Button>
                            <Button variant="dangerSolid" icon={PowerIcon} onClick={() => { handleCloseLayer(); setTimeout(() => handleOpenDialog('suspend', p.id, false), 100); }} className="w-full py-3 justify-center text-sm shadow-md">Suspendre le panneau (Avertissement N°{suspendCount + 1})</Button>
                            <Button variant="secondary" onClick={close} className="w-full py-3 justify-center text-sm">Ignorer</Button>
                        </div>
                    )}
                >
                    <div className="space-y-4 min-w-0">
                        <div className="bg-red-50 p-3 rounded-xl border border-red-200 min-w-0">
                            <p className="text-sm text-red-800 font-bold mb-2 break-words">Mots sensibles détectés :</p>
                            {detected?.black?.length > 0 && <p className="text-xs text-red-600 font-black break-words leading-relaxed">Liste noire : {detected.black.join(', ')}</p>}
                            {detected?.grey?.length > 0 && <p className="text-xs text-orange-600 font-bold mt-1 break-words leading-relaxed">Liste grise : {detected.grey.join(', ')}</p>}
                        </div>
                    </div>
                </Modal>
            )}
        </>
    );
};

// 2. - ONGLET PRINCIPAL DE GESTION PANNEAUX ADMIN
window.pano_AdminPanelsTab = ({ data, refreshData, setManagingPanneau, setValidationErrors, setPreviewPanneau, adminOpts, toggleDashboardPin }) => {
    const { useMemo } = React;
    
    const urlModal = window.pano_useUrlModal ? window.pano_useUrlModal() : {};
    const { openModal, openDialog, closeCurrentLayer, openChat, activeDialog, dialogId } = urlModal;

    const { Button, IconBadge, CardGrid, SearchBar, EmptySearch, PaginationFooter, AdminPanelCard } = window.pano_getComponents();
    const { BuildingIcon, AlertTriangleIcon, PinIcon } = window.pano_getIcons();

    // CORRECTION PERF 1 : Pré-calcul des listes de violations pour éviter le parsing à chaque panneau
    const violationLists = useMemo(() => {
        const black = (data.settings?.blacklist || '').split(',').map(s => s.trim().toLowerCase()).filter(Boolean);
        const grey = (data.settings?.greylist || '').split(',').map(s => s.trim().toLowerCase()).filter(Boolean);
        return { black, grey };
    }, [data.settings?.blacklist, data.settings?.greylist]);

    const checkPanelViolations = (p, lists) => {
        let blackCount = 0; let greyCount = 0;
        const textToSearch = [p.name, p.location, p.description, p.maitreOuvrage].filter(Boolean).join(' ').toLowerCase();
        const detected = { black: [], grey: [] };
        
        const containsWord = (text, word) => {
            const escapedWord = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
            const regex = new RegExp(`\\b${escapedWord}\\b`, 'iu');
            return regex.test(text);
        };
        
        lists.black.forEach(word => { if(containsWord(textToSearch, word)) { blackCount++; detected.black.push(word); } });
        lists.grey.forEach(word => { if(containsWord(textToSearch, word)) { greyCount++; detected.grey.push(word); } });
        
        return { isViolation: blackCount > 0 || greyCount > 2, detected };
    };

    const panneaux = data.panneaux || [];
    const clients = data.clients || [];

    // CORRECTION PERF 2 : Création d'un dictionnaire O(1) pour la recherche des propriétaires
    const clientsMap = useMemo(() => {
        const map = {};
        clients.forEach(c => { map[c.id] = c; });
        return map;
    }, [clients]);

    const regularPanneaux = panneaux.filter(p => p.id !== 'demo-panneau' && p.status !== 'Brouillon');

    const threads = useMemo(() => {
        return window.pano_buildAdminChatThreads ? window.pano_buildAdminChatThreads(data.interactions || [], panneaux, clients) : [];
    }, [data.interactions, panneaux, clients]);

    const unreadMap = useMemo(() => {
        const map = {};
        threads.forEach(t => {
            if (t.unread > 0 && t.type === 'support') {
                const cuid = t.id.replace('SUPPORT_', '');
                if (!map[cuid]) map[cuid] = { support: 0 };
                map[cuid].support += t.unread;
            }
        });
        return map;
    }, [threads]);

    const { 
        searchQuery, setSearchQuery, 
        visibleCount, setVisibleCount, 
        filteredData: filteredPanneaux 
    } = window.pano_useSearchAndPagination(regularPanneaux, (p, q) => {
        const n = window.pano_normalizeString;
        const owner = clientsMap[p.client_uid || p.clientName]; // O(1) Lookup instantané
        const ownerSearchStr = n(owner ? [owner.name, owner.full_name, owner.fullName, owner.email].filter(Boolean).join(' ') : '');

        return n(p.name).includes(q) ||
               n(p.clientName).includes(q) ||
               n(p.id).includes(q) ||
               n(p.location).includes(q) ||
               n(p.status).includes(q) ||
               ownerSearchStr.includes(q); 
    });

    const pinnedIds = adminOpts?.panels || [];
    const attentionPanels = [];
    const pinnedPanels = [];
    const otherPanels = [];

    filteredPanneaux.forEach(p => {
        const { isViolation, detected } = checkPanelViolations(p, violationLists); // Utilisation de la liste pré-calculée
        const needsControl = p.status === 'Attente validation' || (!p.admin_seen && p.status === 'Actif');
        const needsAttention = needsControl || isViolation;
        const isPinned = pinnedIds.includes(p.id);

        const cardProps = {
            panel: p, clients, isPinned, toggleDashboardPin,
            unreadSupport: unreadMap[p.clientName]?.support || 0,
            needsControl, hasBeenSuspended: (p.suspend_count || 0) > 0,
            isViolation, detected, setPreviewPanneau, refreshData,
            setManagingPanneau, setValidationErrors,
            openModal, openDialog, closeCurrentLayer, openChat, activeDialog, dialogId,
            data 
        };

        if (needsAttention) attentionPanels.push(cardProps);
        else if (isPinned) pinnedPanels.push(cardProps);
        else otherPanels.push(cardProps);
    });

    const displayedOtherPanels = otherPanels.slice(0, visibleCount);

    return (
        <div className="space-y-8 animate-in fade-in slide-in-from-bottom-4 min-w-0 w-full">
            <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
                <div className="min-w-0">
                    <h1 className="text-3xl font-black text-slate-800 break-words">Panneaux (Admin)</h1>
                    <p className="text-slate-500 font-medium break-words leading-relaxed">Modération et gestion de la base de données.</p>
                </div>
                
                {regularPanneaux.length > 0 && SearchBar && (
                    <div className="w-full md:w-auto flex-1 flex justify-end gap-2 shrink-0">
                        <SearchBar searchQuery={searchQuery} setSearchQuery={setSearchQuery} placeholder="Rechercher (Nom, Client, Statut)..." />
                    </div>
                )}
            </div>

            {regularPanneaux.length === 0 ? (
                <div className="text-center p-12 bg-white rounded-3xl border border-slate-200 border-dashed min-w-0 w-full">
                    <BuildingIcon size={48} className="mx-auto text-slate-300 mb-4" />
                    <h3 className="text-lg font-black text-slate-700 break-words">Aucun panneau dans la base</h3>
                </div>
            ) : filteredPanneaux.length === 0 ? (
                EmptySearch && <EmptySearch searchQuery={searchQuery} />
            ) : (
                <>
                    {attentionPanels.length > 0 && (
                        <div className="mb-10 space-y-4 min-w-0 w-full">
                            <h2 className="text-lg font-black text-slate-800 flex items-center gap-2 border-b border-slate-200 pb-2">
                                <AlertTriangleIcon size={20} className="text-amber-500" /> Action requise
                            </h2>
                            <CardGrid minWidth="320px">
                                {attentionPanels.map(props => <AdminPanelCard key={`att_${props.panel.id}`} {...props} />)}
                            </CardGrid>
                        </div>
                    )}

                    {pinnedPanels.length > 0 && (
                        <div className="mb-10 space-y-4 min-w-0 w-full">
                            <h2 className="text-lg font-black text-slate-800 flex items-center gap-2 border-b border-slate-200 pb-2">
                                <PinIcon size={20} className="text-purple-600" filled /> Favoris (Épinglés)
                            </h2>
                            <CardGrid minWidth="320px">
                                {pinnedPanels.map(props => <AdminPanelCard key={`pin_${props.panel.id}`} {...props} />)}
                            </CardGrid>
                        </div>
                    )}

                    {otherPanels.length > 0 && (
                        <div className="space-y-4 min-w-0 w-full">
                            <h2 className="text-lg font-black text-slate-800 flex items-center gap-2 border-b border-slate-200 pb-2">
                                <BuildingIcon size={20} className="text-blue-600" /> Autres panneaux
                                <span className="ml-auto text-sm font-bold text-slate-400 bg-slate-100 px-3 py-1 rounded-lg">{otherPanels.length}</span>
                            </h2>
                            <CardGrid minWidth="320px">
                                {displayedOtherPanels.map(props => <AdminPanelCard key={`oth_${props.panel.id}`} {...props} />)}
                            </CardGrid>
                            
                            {PaginationFooter && (
                                <PaginationFooter visibleCount={visibleCount} setVisibleCount={setVisibleCount} totalCount={otherPanels.length} itemName="panneaux" />
                            )}
                        </div>
                    )}
                </>
            )}
        </div>
    );
};

/* EOF ========== [_react/admin/_admin_panneaux.jsx] */