@lastbrain/app 0.1.33 → 0.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -172,7 +172,7 @@ export function DocPage({ modules = [], defaultContent }) {
172
172
  ];
173
173
  return (_jsx("div", { className: "w-full pt-8 md:pt-12 pb-24 lg:pb-8", children: _jsxs("div", { className: "container mx-auto md:px-4 py-8", children: [_jsx("div", { className: "fixed w-full h-16 left-0 bottom-0 bg-background/20 backdrop-blur-lg z-50 lg:hidden p-2", children: _jsx("div", { className: "flex justify-center", children: _jsx(Button, { isIconOnly: true, variant: "solid", onPress: () => setIsDrawerOpen(true), children: _jsx(Menu, { size: 24 }) }) }) }), _jsx(Drawer, { isOpen: isDrawerOpen, onOpenChange: setIsDrawerOpen, placement: "left", children: _jsxs(DrawerContent, { children: [_jsx(DrawerHeader, { children: _jsx("h2", { className: "text-xl font-semibold", children: "Navigation" }) }), _jsx(DrawerBody, { children: _jsx(NavigationListbox, { navigationItems: navigationItems, selectedModule: selectedModule, scrollToSection: scrollToSection, setSelectedModule: setSelectedModule }) })] }) }), _jsxs("div", { className: "flex gap-8", children: [_jsx("aside", { className: "hidden lg:block w-64 shrink-0 sticky top-18 self-start", children: _jsxs(Card, { children: [_jsx(CardHeader, { className: "pb-2", children: _jsx("h2", { className: "text-xl font-semibold", children: "Navigation" }) }), _jsx(CardBody, { children: _jsx(NavigationListbox, { navigationItems: navigationItems, selectedModule: selectedModule, scrollToSection: scrollToSection, setSelectedModule: setSelectedModule }) })] }) }), _jsxs("main", { className: "flex-1 w-full min-w-0 space-y-8", children: [defaultContent ? (_jsx("div", { children: defaultContent })) : (_jsx(DefaultDocumentation, {})), modules.length > 0 && (_jsxs("div", { className: "space-y-6", children: [_jsxs(Card, { id: "section-modules", className: "scroll-mt-32", children: [_jsx(CardHeader, { children: _jsx("h2", { className: "text-2xl font-semibold", children: "Modules disponibles" }) }), _jsxs(CardBody, { children: [_jsx("p", { className: "text-slate-600 dark:text-slate-400 mb-4", children: "Voici la liste de tous les modules disponibles dans LastBrain. Les modules actifs sont utilis\u00E9s dans votre application." }), _jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: modules.map((module) => (_jsx(Card, { isPressable: module.available, onPress: () => module.available && scrollToSection(module.id), className: `${module.available
174
174
  ? "cursor-pointer hover:shadow-lg"
175
- : "opacity-70"} transition-shadow`, children: _jsxs(CardBody, { children: [_jsxs("div", { className: "flex items-start justify-between mb-2", children: [_jsx("h3", { className: "text-lg font-semibold", children: module.name }), _jsx(Chip, { size: "sm", color: module.available ? "success" : "warning", variant: "flat", children: module.available ? "Actif" : "Inactif" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-2", children: module.description }), !module.available && (_jsxs("div", { className: "flex justify-between items-center text-xs text-default-700 mt-2", children: [_jsx("span", { children: "Pour activer : " }), _jsx(Snippet, { hideSymbol: true, color: "primary", children: `pnpm lastbrain add-module ${module.id}` })] }))] }) }, module.id))) })] })] }), modules
175
+ : "opacity-70"} transition-shadow`, children: _jsxs(CardBody, { children: [_jsxs("div", { className: "flex items-start justify-between mb-2", children: [_jsxs("h3", { className: "text-lg font-semibold flex flex-inline items-center gap-2", children: [_jsx(Blocks, { size: 20, className: "shrink-0" }), module.name] }), _jsx(Chip, { size: "sm", color: module.available ? "success" : "warning", variant: "flat", children: module.available ? "Actif" : "Inactif" })] }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mb-2", children: module.description }), !module.available && (_jsxs("div", { className: "flex justify-between items-center text-xs text-default-700 mt-2", children: [_jsx("span", { children: "Pour activer : " }), _jsx(Snippet, { hideSymbol: true, color: "primary", children: `pnpm lastbrain add-module ${module.id}` })] }))] }) }, module.id))) })] })] }), modules
176
176
  .filter((m) => m.available)
177
177
  .map((module) => (_jsx("div", { id: `module-${module.id}`, className: "scroll-mt-32", children: module.content }, module.id)))] }))] })] })] }) }));
178
178
  }
@@ -3,5 +3,5 @@ import NextLink from "next/link";
3
3
  import { Button, Card, CardBody, CardHeader, Chip, Snippet, } from "@lastbrain/ui";
4
4
  import { Rocket, Package, Database, Code, Zap, Shield, ArrowRight, BookOpen, } from "lucide-react";
5
5
  export function SimpleHomePage({ showAuth }) {
6
- return (_jsxs("div", { className: "min-h-screen", children: [_jsxs("section", { className: "relative overflow-hidden bg-gradient-to-br from-blue-50 via-purple-50 to-pink-50 dark:from-slate-900 dark:via-purple-900/20 dark:to-blue-900/20", children: [_jsx("div", { className: "absolute inset-0 bg-grid-slate-200/50 dark:bg-grid-slate-700/25 mask-[radial-gradient(ellipse_at_center,transparent_20%,black)]" }), _jsx("div", { className: "relative container mx-auto px-4 py-24 md:py-32", children: _jsxs("div", { className: "max-w-4xl mx-auto text-center", children: [_jsxs("div", { className: "inline-flex items-center gap-2 px-4 py-2 rounded-full bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 mb-8", children: [_jsx(Zap, { size: 16 }), _jsx("span", { className: "text-sm font-medium", children: "Framework modulaire Next.js" })] }), _jsx("h1", { className: "text-5xl md:text-7xl font-bold mb-6 bg-gradient-to-r from-blue-600 via-purple-600 to-pink-600 bg-clip-text text-transparent", children: "Bienvenue sur LastBrain" }), _jsx("p", { className: "text-xl md:text-2xl text-slate-600 dark:text-slate-300 mb-12 max-w-2xl mx-auto", children: "Cr\u00E9ez des applications modernes avec une architecture modulaire, puissante et \u00E9volutive." }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-4 justify-center", children: [_jsx(NextLink, { href: "/docs", children: _jsx(Button, { size: "lg", color: "primary", endContent: _jsx(ArrowRight, { size: 20 }), className: "text-base font-medium", children: "Voir la documentation" }) }), showAuth && (_jsx(NextLink, { href: "/signup", children: _jsx(Button, { size: "lg", variant: "bordered", className: "text-base font-medium", children: "Cr\u00E9er un compte" }) }))] })] }) })] }), _jsx("section", { className: "py-20 bg-white dark:bg-slate-950", children: _jsx("div", { className: "container mx-auto px-4", children: _jsxs("div", { className: "max-w-6xl mx-auto", children: [_jsxs("div", { className: "text-center mb-16", children: [_jsx("h2", { className: "text-3xl md:text-4xl font-bold mb-4", children: "Tout ce dont vous avez besoin" }), _jsx("p", { className: "text-lg text-slate-600 dark:text-slate-400", children: "Une stack moderne pour d\u00E9marrer rapidement" })] }), _jsxs("div", { className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3", children: [_jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-blue-100 dark:bg-blue-900/30", children: _jsx(Package, { className: "text-blue-600 dark:text-blue-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "Modulaire" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Architecture bas\u00E9e sur des modules r\u00E9utilisables. Ajoutez ou retirez des fonctionnalit\u00E9s en une commande." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-purple-100 dark:bg-purple-900/30", children: _jsx(Database, { className: "text-purple-600 dark:text-purple-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "Supabase" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Base de donn\u00E9es PostgreSQL, authentification et migrations automatiques. Tout en local pour le d\u00E9veloppement." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-green-100 dark:bg-green-900/30", children: _jsx(Zap, { className: "text-green-600 dark:text-green-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "Rapide" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Next.js 15, React 19, Tailwind CSS v4. Hot reload et g\u00E9n\u00E9ration automatique des routes." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-orange-100 dark:bg-orange-900/30", children: _jsx(Code, { className: "text-orange-600 dark:text-orange-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "TypeScript" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "100% TypeScript avec types partag\u00E9s entre frontend et backend. Monorepo pnpm pour une gestion optimale." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-pink-100 dark:bg-pink-900/30", children: _jsx(Shield, { className: "text-pink-600 dark:text-pink-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "S\u00E9curis\u00E9" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Middleware d'authentification automatique. Routes prot\u00E9g\u00E9es pour /auth et /admin configur\u00E9es par d\u00E9faut." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-cyan-100 dark:bg-cyan-900/30", children: _jsx(BookOpen, { className: "text-cyan-600 dark:text-cyan-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "Document\u00E9" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Documentation compl\u00E8te et interactive. Chaque module documente automatiquement ses pages et APIs." }) })] })] })] }) }) }), _jsx("section", { className: "py-20 bg-slate-50 dark:bg-slate-900/50", children: _jsx("div", { className: "container mx-auto px-4", children: _jsxs("div", { className: "max-w-4xl mx-auto", children: [_jsxs("div", { className: "text-center mb-12", children: [_jsxs("div", { className: "inline-flex items-center gap-2 mb-4", children: [_jsx(Rocket, { size: 24, className: "text-blue-600" }), _jsx("h2", { className: "text-3xl md:text-4xl font-bold", children: "D\u00E9marrez en 4 \u00E9tapes" })] }), _jsx("p", { className: "text-lg text-slate-600 dark:text-slate-400", children: "Votre application pr\u00EAte en quelques minutes" })] }), _jsxs("div", { className: "space-y-6", children: [_jsx(Card, { className: "border-l-4 border-l-blue-500", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "shrink-0 w-8 h-8 rounded-full bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center font-bold text-blue-600 dark:text-blue-400", children: "1" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Cr\u00E9ez votre application" }), _jsx(Snippet, { className: "w-full", children: "pnpx @lastbrain/app init mon-app" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: "L'assistant interactif vous guidera pour :" }), _jsxs("ul", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2 ml-4 space-y-1", children: [_jsx("li", { children: "\u2022 Choisir les modules \u00E0 installer (auth, ai...)" }), _jsx("li", { children: "\u2022 Cr\u00E9er la structure compl\u00E8te du projet" }), _jsx("li", { children: "\u2022 Installer automatiquement les d\u00E9pendances" }), _jsx("li", { children: "\u2022 G\u00E9n\u00E9rer les routes des modules" })] })] })] }) }) }), _jsx(Card, { className: "border-l-4 border-l-purple-500", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "shrink-0 w-8 h-8 rounded-full bg-purple-100 dark:bg-purple-900/30 flex items-center justify-center font-bold text-purple-600 dark:text-purple-400", children: "2" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Acc\u00E9dez au dossier" }), _jsx(Snippet, { className: "w-full", children: "cd mon-app" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: "Entrez dans le dossier de votre nouvelle application" })] })] }) }) }), _jsx(Card, { className: "border-l-4 border-l-orange-500", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "shrink-0 w-8 h-8 rounded-full bg-orange-100 dark:bg-orange-900/30 flex items-center justify-center font-bold text-orange-600 dark:text-orange-400", children: "3" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Initialisez Supabase" }), _jsx(Snippet, { className: "w-full", children: "pnpm db:init" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: "D\u00E9marre Supabase en local et applique toutes les migrations (base + modules)" })] })] }) }) }), _jsx(Card, { className: "border-l-4 border-l-green-500", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "shrink-0 w-8 h-8 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center font-bold text-green-600 dark:text-green-400", children: "4" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Lancez le serveur" }), _jsx(Snippet, { className: "w-full", children: "pnpm dev" }), _jsxs("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: ["Ouvre l'application sur", " ", _jsx("strong", { children: "http://localhost:3000" })] })] })] }) }) }), _jsx(Card, { className: "bg-blue-50 dark:bg-blue-950/30 border-blue-200 dark:border-blue-800", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-blue-100 dark:bg-blue-900/30 shrink-0", children: _jsx(Package, { className: "text-blue-600 dark:text-blue-400", size: 20 }) }), _jsxs("div", { children: [_jsx("h4", { className: "font-semibold mb-2 text-blue-900 dark:text-blue-100", children: "Ajouter des modules plus tard" }), _jsxs("div", { className: "space-y-2", children: [_jsx(Snippet, { className: "w-full", size: "sm", children: "pnpm lastbrain add-module auth" }), _jsx(Snippet, { className: "w-full", size: "sm", children: "pnpm build:modules" })] }), _jsxs("div", { className: "text-sm text-blue-700 dark:text-blue-300 mt-2", children: ["Modules disponibles :", " ", _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "auth" }), " ", _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "ai" })] })] })] }) }) })] })] }) }) }), _jsx("section", { className: "py-20 bg-gradient-to-r from-blue-600 to-purple-600 text-white", children: _jsx("div", { className: "container mx-auto px-4", children: _jsxs("div", { className: "max-w-3xl mx-auto text-center", children: [_jsx("h2", { className: "text-3xl md:text-4xl font-bold mb-4", children: "Pr\u00EAt \u00E0 commencer ?" }), _jsx("p", { className: "text-lg text-blue-100 mb-8", children: "Explorez la documentation compl\u00E8te pour d\u00E9couvrir toutes les fonctionnalit\u00E9s" }), _jsx(NextLink, { href: "/docs", children: _jsx(Button, { size: "lg", className: "bg-white text-blue-600 hover:bg-blue-50 font-medium", endContent: _jsx(BookOpen, { size: 20 }), children: "Consulter la documentation" }) })] }) }) })] }));
6
+ return (_jsxs("div", { className: "min-h-screen", children: [_jsxs("section", { className: "relative overflow-hidden bg-gradient-to-br from-blue-50 via-purple-50 to-pink-50 dark:from-slate-900 dark:via-purple-900/20 dark:to-blue-900/20", children: [_jsx("div", { className: "absolute inset-0 bg-grid-slate-200/50 dark:bg-grid-slate-700/25 mask-[radial-gradient(ellipse_at_center,transparent_20%,black)]" }), _jsx("div", { className: "relative container mx-auto px-4 py-24 md:py-32", children: _jsxs("div", { className: "max-w-4xl mx-auto text-center", children: [_jsxs("div", { className: "inline-flex items-center gap-2 px-4 py-2 rounded-full bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 mb-8", children: [_jsx(Zap, { size: 16 }), _jsx("span", { className: "text-sm font-medium", children: "Framework modulaire Next.js" })] }), _jsx("h1", { className: "text-5xl md:text-7xl font-bold mb-6 bg-gradient-to-r from-blue-600 via-purple-600 to-pink-600 bg-clip-text text-transparent", children: "Bienvenue sur LastBrain" }), _jsx("p", { className: "text-xl md:text-2xl text-slate-600 dark:text-slate-300 mb-12 max-w-2xl mx-auto", children: "Cr\u00E9ez des applications modernes avec une architecture modulaire, puissante et \u00E9volutive." }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-4 justify-center", children: [_jsx(NextLink, { href: "/docs", children: _jsx(Button, { size: "lg", color: "primary", endContent: _jsx(ArrowRight, { size: 20 }), className: "text-base font-medium", children: "Voir la documentation" }) }), showAuth && (_jsx(NextLink, { href: "/signup", children: _jsx(Button, { size: "lg", variant: "bordered", className: "text-base font-medium", children: "Cr\u00E9er un compte" }) }))] })] }) })] }), _jsx("section", { className: "py-20 bg-white dark:bg-slate-950", children: _jsx("div", { className: "container mx-auto px-4", children: _jsxs("div", { className: "max-w-6xl mx-auto", children: [_jsxs("div", { className: "text-center mb-16", children: [_jsx("h2", { className: "text-3xl md:text-4xl font-bold mb-4", children: "Tout ce dont vous avez besoin" }), _jsx("p", { className: "text-lg text-slate-600 dark:text-slate-400", children: "Une stack moderne pour d\u00E9marrer rapidement" })] }), _jsxs("div", { className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3", children: [_jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-blue-100 dark:bg-blue-900/30", children: _jsx(Package, { className: "text-blue-600 dark:text-blue-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "Modulaire" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Architecture bas\u00E9e sur des modules r\u00E9utilisables. Ajoutez ou retirez des fonctionnalit\u00E9s en une commande." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-purple-100 dark:bg-purple-900/30", children: _jsx(Database, { className: "text-purple-600 dark:text-purple-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "Supabase" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Base de donn\u00E9es PostgreSQL, authentification et migrations automatiques. Tout en local pour le d\u00E9veloppement." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-green-100 dark:bg-green-900/30", children: _jsx(Zap, { className: "text-green-600 dark:text-green-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "Rapide" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Next.js 15, React 19, Tailwind CSS v4. Hot reload et g\u00E9n\u00E9ration automatique des routes." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-orange-100 dark:bg-orange-900/30", children: _jsx(Code, { className: "text-orange-600 dark:text-orange-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "TypeScript" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "100% TypeScript avec types partag\u00E9s entre frontend et backend. Monorepo pnpm pour une gestion optimale." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-pink-100 dark:bg-pink-900/30", children: _jsx(Shield, { className: "text-pink-600 dark:text-pink-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "S\u00E9curis\u00E9" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Middleware d'authentification automatique. Routes prot\u00E9g\u00E9es pour /auth et /admin configur\u00E9es par d\u00E9faut." }) })] }), _jsxs(Card, { className: "hover:shadow-xl transition-shadow", children: [_jsx(CardHeader, { className: "pb-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-cyan-100 dark:bg-cyan-900/30", children: _jsx(BookOpen, { className: "text-cyan-600 dark:text-cyan-400", size: 24 }) }), _jsx("h3", { className: "text-xl font-semibold", children: "Document\u00E9" })] }) }), _jsx(CardBody, { className: "pt-2", children: _jsx("p", { className: "text-slate-600 dark:text-slate-400", children: "Documentation compl\u00E8te et interactive. Chaque module documente automatiquement ses pages et APIs." }) })] })] })] }) }) }), _jsx("section", { className: "py-20 bg-slate-50 dark:bg-slate-900/50", children: _jsx("div", { className: "container mx-auto px-4", children: _jsxs("div", { className: "max-w-4xl mx-auto", children: [_jsxs("div", { className: "text-center mb-12", children: [_jsxs("div", { className: "inline-flex items-center gap-2 mb-4", children: [_jsx(Rocket, { size: 24, className: "text-blue-600" }), _jsx("h2", { className: "text-3xl md:text-4xl font-bold", children: "D\u00E9marrez en 4 \u00E9tapes" })] }), _jsx("p", { className: "text-lg text-slate-600 dark:text-slate-400", children: "Votre application pr\u00EAte en quelques minutes" })] }), _jsxs("div", { className: "space-y-6", children: [_jsx(Card, { className: "border-l-4 border-l-blue-500", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "shrink-0 w-8 h-8 rounded-full bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center font-bold text-blue-600 dark:text-blue-400", children: "1" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Cr\u00E9ez votre application" }), _jsx(Snippet, { className: "w-full", children: "pnpx @lastbrain/app@latest init mon-app" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: "L'assistant interactif vous guidera pour :" }), _jsxs("ul", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2 ml-4 space-y-1", children: [_jsx("li", { children: "\u2022 Choisir les modules \u00E0 installer (auth, ai...)" }), _jsx("li", { children: "\u2022 Cr\u00E9er la structure compl\u00E8te du projet" }), _jsx("li", { children: "\u2022 Installer automatiquement les d\u00E9pendances" }), _jsx("li", { children: "\u2022 G\u00E9n\u00E9rer les routes des modules" })] })] })] }) }) }), _jsx(Card, { className: "border-l-4 border-l-purple-500", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "shrink-0 w-8 h-8 rounded-full bg-purple-100 dark:bg-purple-900/30 flex items-center justify-center font-bold text-purple-600 dark:text-purple-400", children: "2" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Acc\u00E9dez au dossier" }), _jsx(Snippet, { className: "w-full", children: "cd mon-app" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: "Entrez dans le dossier de votre nouvelle application" })] })] }) }) }), _jsx(Card, { className: "border-l-4 border-l-orange-500", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "shrink-0 w-8 h-8 rounded-full bg-orange-100 dark:bg-orange-900/30 flex items-center justify-center font-bold text-orange-600 dark:text-orange-400", children: "3" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Initialisez Supabase" }), _jsx(Snippet, { className: "w-full", children: "pnpm db:init" }), _jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: "D\u00E9marre Supabase en local et applique toutes les migrations (base + modules)" })] })] }) }) }), _jsx(Card, { className: "border-l-4 border-l-green-500", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "shrink-0 w-8 h-8 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center font-bold text-green-600 dark:text-green-400", children: "4" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-lg font-semibold mb-2", children: "Lancez le serveur" }), _jsx(Snippet, { className: "w-full", children: "pnpm dev" }), _jsxs("p", { className: "text-sm text-slate-600 dark:text-slate-400 mt-2", children: ["Ouvre l'application sur", " ", _jsx("strong", { children: "http://localhost:3000" })] })] })] }) }) }), _jsx(Card, { className: "bg-blue-50 dark:bg-blue-950/30 border-blue-200 dark:border-blue-800", children: _jsx(CardBody, { children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "p-2 rounded-lg bg-blue-100 dark:bg-blue-900/30 shrink-0", children: _jsx(Package, { className: "text-blue-600 dark:text-blue-400", size: 20 }) }), _jsxs("div", { children: [_jsx("h4", { className: "font-semibold mb-2 text-blue-900 dark:text-blue-100", children: "Ajouter des modules plus tard" }), _jsxs("div", { className: "space-y-2", children: [_jsx(Snippet, { className: "w-full", size: "sm", children: "pnpm lastbrain add-module auth" }), _jsx(Snippet, { className: "w-full", size: "sm", children: "pnpm build:modules" })] }), _jsxs("div", { className: "text-sm text-blue-700 dark:text-blue-300 mt-2", children: ["Modules disponibles :", " ", _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "auth" }), " ", _jsx(Chip, { size: "sm", color: "primary", variant: "flat", children: "ai" })] })] })] }) }) })] })] }) }) }), _jsx("section", { className: "py-20 bg-gradient-to-r from-blue-600 to-purple-600 text-white", children: _jsx("div", { className: "container mx-auto px-4", children: _jsxs("div", { className: "max-w-3xl mx-auto text-center", children: [_jsx("h2", { className: "text-3xl md:text-4xl font-bold mb-4", children: "Pr\u00EAt \u00E0 commencer ?" }), _jsx("p", { className: "text-lg text-blue-100 mb-8", children: "Explorez la documentation compl\u00E8te pour d\u00E9couvrir toutes les fonctionnalit\u00E9s" }), _jsx(NextLink, { href: "/docs", children: _jsx(Button, { size: "lg", className: "bg-white text-blue-600 hover:bg-blue-50 font-medium", endContent: _jsx(BookOpen, { size: 20 }), children: "Consulter la documentation" }) })] }) }) })] }));
7
7
  }
@@ -177,33 +177,32 @@ BEGIN
177
177
  ), false
178
178
  ) as is_foreign_key,
179
179
  (
180
- SELECT ccu.table_name::text
181
- FROM information_schema.table_constraints tc
182
- JOIN information_schema.key_column_usage kcu
183
- ON tc.constraint_name = kcu.constraint_name
184
- AND tc.table_schema = kcu.table_schema
185
- JOIN information_schema.constraint_column_usage ccu
186
- ON ccu.constraint_name = tc.constraint_name
187
- AND ccu.table_schema = tc.table_schema
188
- WHERE tc.constraint_type = 'FOREIGN KEY'
189
- AND tc.table_schema = 'public'
190
- AND tc.table_name = p_table_name
191
- AND kcu.column_name = c.column_name
180
+ SELECT
181
+ CASE
182
+ WHEN nsp.nspname = 'public' THEN ref_table.relname::text
183
+ ELSE nsp.nspname::text || '.' || ref_table.relname::text
184
+ END
185
+ FROM pg_constraint con
186
+ JOIN pg_attribute att ON att.attrelid = con.conrelid AND att.attnum = ANY(con.conkey)
187
+ JOIN pg_class tbl ON tbl.oid = con.conrelid
188
+ JOIN pg_class ref_table ON ref_table.oid = con.confrelid
189
+ JOIN pg_namespace nsp ON nsp.oid = ref_table.relnamespace
190
+ WHERE con.contype = 'f'
191
+ AND tbl.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')
192
+ AND tbl.relname = p_table_name
193
+ AND att.attname = c.column_name
192
194
  LIMIT 1
193
195
  ) as foreign_table,
194
196
  (
195
- SELECT ccu.column_name::text
196
- FROM information_schema.table_constraints tc
197
- JOIN information_schema.key_column_usage kcu
198
- ON tc.constraint_name = kcu.constraint_name
199
- AND tc.table_schema = kcu.table_schema
200
- JOIN information_schema.constraint_column_usage ccu
201
- ON ccu.constraint_name = tc.constraint_name
202
- AND ccu.table_schema = tc.table_schema
203
- WHERE tc.constraint_type = 'FOREIGN KEY'
204
- AND tc.table_schema = 'public'
205
- AND tc.table_name = p_table_name
206
- AND kcu.column_name = c.column_name
197
+ SELECT ref_att.attname::text
198
+ FROM pg_constraint con
199
+ JOIN pg_attribute att ON att.attrelid = con.conrelid AND att.attnum = ANY(con.conkey)
200
+ JOIN pg_class tbl ON tbl.oid = con.conrelid
201
+ JOIN pg_attribute ref_att ON ref_att.attrelid = con.confrelid AND ref_att.attnum = ANY(con.confkey)
202
+ WHERE con.contype = 'f'
203
+ AND tbl.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')
204
+ AND tbl.relname = p_table_name
205
+ AND att.attname = c.column_name
207
206
  LIMIT 1
208
207
  ) as foreign_column,
209
208
  pgd.description::text
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lastbrain/app",
3
- "version": "0.1.33",
3
+ "version": "0.1.36",
4
4
  "description": "Framework modulaire Next.js avec CLI et système de modules",
5
5
  "private": false,
6
6
  "type": "module",
@@ -115,11 +115,34 @@ function parseEnvFile(filePath: string) {
115
115
  }
116
116
 
117
117
  function ensureEnvFile(values: Record<string, string>) {
118
- const content = Object.entries(values)
119
- .map(([key, value]) => `${key}=${value}`)
120
- .join("\n");
121
-
122
118
  envTargets.forEach((target) => {
119
+ let existingVars: Record<string, string> = {};
120
+
121
+ // Lire le fichier .env.local existant pour préserver les variables personnalisées
122
+ if (fs.existsSync(target)) {
123
+ try {
124
+ const existingContent = fs.readFileSync(target, "utf-8");
125
+ existingVars = Object.fromEntries(
126
+ existingContent
127
+ .split("\n")
128
+ .filter((line) => line.includes("=") && !line.startsWith("#"))
129
+ .map((line) => {
130
+ const [key, ...value] = line.split("=");
131
+ return [key, value.join("=")];
132
+ }),
133
+ );
134
+ } catch (error) {
135
+ console.warn(`⚠️ Erreur lors de la lecture de ${target}:`, error);
136
+ }
137
+ }
138
+
139
+ // Fusionner les nouvelles valeurs avec les existantes (nouvelles valeurs prioritaires)
140
+ const mergedValues = { ...existingVars, ...values };
141
+
142
+ const content = Object.entries(mergedValues)
143
+ .map(([key, value]) => `${key}=${value}`)
144
+ .join("\n");
145
+
123
146
  fs.writeFileSync(target, content);
124
147
  console.log(`📝 Wrote env to ${target}`);
125
148
  });