@betterstart/cli 0.1.4 → 0.1.6

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.
package/dist/cli.js CHANGED
@@ -8395,91 +8395,178 @@ import fs25 from "fs-extra";
8395
8395
 
8396
8396
  // src/init/templates/components/cms-globals.ts
8397
8397
  function cmsGlobalsCssTemplate() {
8398
- return `/* CMS-scoped design tokens \u2014 does NOT import Tailwind (host app provides it) */
8399
-
8400
- @layer cms {
8401
- .cms-root {
8402
- --radius: 0.625rem;
8403
- --background: oklch(1 0 0);
8404
- --foreground: oklch(0.145 0 0);
8405
- --card: oklch(1 0 0);
8406
- --card-foreground: oklch(0.145 0 0);
8407
- --popover: oklch(1 0 0);
8408
- --popover-foreground: oklch(0.145 0 0);
8409
- --primary: oklch(0.205 0 0);
8410
- --primary-foreground: oklch(0.985 0 0);
8411
- --secondary: oklch(0.97 0 0);
8412
- --secondary-foreground: oklch(0.205 0 0);
8413
- --muted: oklch(0.97 0 0);
8414
- --muted-foreground: oklch(0.556 0 0);
8415
- --accent: oklch(0.97 0 0);
8416
- --accent-foreground: oklch(0.205 0 0);
8417
- --destructive: oklch(0.577 0.245 27.325);
8418
- --destructive-foreground: oklch(0.577 0.245 27.325);
8419
- --border: oklch(0.922 0 0);
8420
- --input: oklch(98.5% 0 0);
8421
- --input-border: oklch(96.7% 0.001 286.375);
8422
- --ring: oklch(0.708 0 0);
8423
- --chart-1: oklch(0.646 0.222 41.116);
8424
- --chart-2: oklch(0.6 0.118 184.704);
8425
- --chart-3: oklch(0.398 0.07 227.392);
8426
- --chart-4: oklch(0.828 0.189 84.429);
8427
- --chart-5: oklch(0.769 0.188 70.08);
8428
- --sidebar: oklch(0.985 0 0);
8429
- --sidebar-foreground: oklch(0.145 0 0);
8430
- --sidebar-primary: oklch(0.205 0 0);
8431
- --sidebar-primary-foreground: oklch(0.985 0 0);
8432
- --sidebar-accent: oklch(0.97 0 0);
8433
- --sidebar-accent-foreground: oklch(0.205 0 0);
8434
- --sidebar-border: oklch(0.922 0 0);
8435
- --sidebar-ring: oklch(0.708 0 0);
8436
- }
8437
-
8438
- .cms-root.dark {
8439
- --background: oklch(0.145 0 0);
8440
- --foreground: oklch(0.985 0 0);
8441
- --card: oklch(0.145 0 0);
8442
- --card-foreground: oklch(0.985 0 0);
8443
- --popover: oklch(0.145 0 0);
8444
- --popover-foreground: oklch(0.985 0 0);
8445
- --primary: oklch(0.985 0 0);
8446
- --primary-foreground: oklch(0.205 0 0);
8447
- --secondary: oklch(0.269 0 0);
8448
- --secondary-foreground: oklch(0.985 0 0);
8449
- --muted: oklch(0.269 0 0);
8450
- --muted-foreground: oklch(0.708 0 0);
8451
- --accent: oklch(0.269 0 0);
8452
- --accent-foreground: oklch(0.985 0 0);
8453
- --destructive: oklch(0.396 0.141 25.723);
8454
- --destructive-foreground: oklch(0.637 0.237 25.331);
8455
- --border: oklch(0.269 0 0);
8456
- --input: oklch(26.9% 0 0);
8457
- --input-border: oklch(25.1% 0.001 286.375);
8458
- --ring: oklch(0.439 0 0);
8459
- --chart-1: oklch(0.488 0.243 264.376);
8460
- --chart-2: oklch(0.696 0.17 162.48);
8461
- --chart-3: oklch(0.769 0.188 70.08);
8462
- --chart-4: oklch(0.627 0.265 303.9);
8463
- --chart-5: oklch(0.645 0.246 16.439);
8464
- --sidebar: oklch(0.205 0 0);
8465
- --sidebar-foreground: oklch(0.985 0 0);
8466
- --sidebar-primary: oklch(0.488 0.243 264.376);
8467
- --sidebar-primary-foreground: oklch(0.985 0 0);
8468
- --sidebar-accent: oklch(0.269 0 0);
8469
- --sidebar-accent-foreground: oklch(0.985 0 0);
8470
- --sidebar-border: oklch(0.269 0 0);
8471
- --sidebar-ring: oklch(0.439 0 0);
8472
- }
8473
- }
8474
-
8475
- /* CMS base styles */
8476
- .cms-root * {
8477
- border-color: var(--border);
8478
- }
8479
-
8480
- .cms-root {
8481
- background-color: var(--background);
8482
- color: var(--foreground);
8398
+ return `@import "tailwindcss";
8399
+
8400
+ @custom-variant dark (&:is(.dark *));
8401
+
8402
+ :root {
8403
+ --background: oklch(0.9850 0 0);
8404
+ --foreground: oklch(0 0 0);
8405
+ --card: oklch(1 0 0);
8406
+ --card-foreground: oklch(0 0 0);
8407
+ --popover: oklch(0.9900 0 0);
8408
+ --popover-foreground: oklch(0 0 0);
8409
+ --primary: oklch(0 0 0);
8410
+ --primary-foreground: oklch(1 0 0);
8411
+ --secondary: oklch(0.9700 0 0);
8412
+ --secondary-foreground: oklch(0 0 0);
8413
+ --muted: oklch(0.9700 0 0);
8414
+ --muted-foreground: oklch(0.4400 0 0);
8415
+ --accent: oklch(0.9700 0 0);
8416
+ --accent-foreground: oklch(0 0 0);
8417
+ --destructive: oklch(0.6300 0.1900 23.0300);
8418
+ --destructive-foreground: oklch(1 0 0);
8419
+ --border: oklch(0.9200 0 0);
8420
+ --input: oklch(0.9400 0 0);
8421
+ --ring: oklch(0 0 0);
8422
+ --chart-1: oklch(0.8100 0.1700 75.3500);
8423
+ --chart-2: oklch(0.5500 0.2200 264.5300);
8424
+ --chart-3: oklch(0.7200 0 0);
8425
+ --chart-4: oklch(0.9200 0 0);
8426
+ --chart-5: oklch(0.5600 0 0);
8427
+ --sidebar: oklch(1 0 0);
8428
+ --sidebar-foreground: oklch(0 0 0);
8429
+ --sidebar-primary: oklch(0 0 0);
8430
+ --sidebar-primary-foreground: oklch(1 0 0);
8431
+ --sidebar-accent: oklch(0.9400 0 0);
8432
+ --sidebar-accent-foreground: oklch(0 0 0);
8433
+ --sidebar-border: oklch(0.9400 0 0);
8434
+ --sidebar-ring: oklch(0 0 0);
8435
+ --font-sans: Geist, sans-serif;
8436
+ --font-serif: Georgia, serif;
8437
+ --font-mono: Geist Mono, monospace;
8438
+ --radius: 0.4rem;
8439
+ --shadow-x: 0px;
8440
+ --shadow-y: 1px;
8441
+ --shadow-blur: 3px;
8442
+ --shadow-spread: 0px;
8443
+ --shadow-opacity: 0.02;
8444
+ --shadow-color: hsl(0 0% 0%);
8445
+ --shadow-2xs: 0px 1px 3px 0px hsl(0 0% 0% / 0.01);
8446
+ --shadow-xs: 0px 1px 3px 0px hsl(0 0% 0% / 0.01);
8447
+ --shadow-sm: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 1px 2px -1px hsl(0 0% 0% / 0.02);
8448
+ --shadow: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 1px 2px -1px hsl(0 0% 0% / 0.02);
8449
+ --shadow-md: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 2px 4px -1px hsl(0 0% 0% / 0.02);
8450
+ --shadow-lg: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 4px 6px -1px hsl(0 0% 0% / 0.02);
8451
+ --shadow-xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 8px 10px -1px hsl(0 0% 0% / 0.02);
8452
+ --shadow-2xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.05);
8453
+ --tracking-normal: 0em;
8454
+ --spacing: 0.25rem;
8455
+ }
8456
+
8457
+ .dark {
8458
+ --background: oklch(0 0 0);
8459
+ --foreground: oklch(1 0 0);
8460
+ --card: oklch(0.1400 0 0);
8461
+ --card-foreground: oklch(1 0 0);
8462
+ --popover: oklch(0.1800 0 0);
8463
+ --popover-foreground: oklch(1 0 0);
8464
+ --primary: oklch(1 0 0);
8465
+ --primary-foreground: oklch(0 0 0);
8466
+ --secondary: oklch(0.2500 0 0);
8467
+ --secondary-foreground: oklch(1 0 0);
8468
+ --muted: oklch(0.2300 0 0);
8469
+ --muted-foreground: oklch(0.7200 0 0);
8470
+ --accent: oklch(0.3200 0 0);
8471
+ --accent-foreground: oklch(1 0 0);
8472
+ --destructive: oklch(0.6900 0.2000 23.9100);
8473
+ --destructive-foreground: oklch(0 0 0);
8474
+ --border: oklch(0.2600 0 0);
8475
+ --input: oklch(0.3200 0 0);
8476
+ --ring: oklch(0.7200 0 0);
8477
+ --chart-1: oklch(0.8100 0.1700 75.3500);
8478
+ --chart-2: oklch(0.5800 0.2100 260.8400);
8479
+ --chart-3: oklch(0.5600 0 0);
8480
+ --chart-4: oklch(0.4400 0 0);
8481
+ --chart-5: oklch(0.9200 0 0);
8482
+ --sidebar: oklch(0.1800 0 0);
8483
+ --sidebar-foreground: oklch(1 0 0);
8484
+ --sidebar-primary: oklch(1 0 0);
8485
+ --sidebar-primary-foreground: oklch(0 0 0);
8486
+ --sidebar-accent: oklch(0.3200 0 0);
8487
+ --sidebar-accent-foreground: oklch(1 0 0);
8488
+ --sidebar-border: oklch(0.3200 0 0);
8489
+ --sidebar-ring: oklch(0.7200 0 0);
8490
+ --font-sans: Geist, sans-serif;
8491
+ --font-serif: Georgia, serif;
8492
+ --font-mono: Geist Mono, monospace;
8493
+ --radius: 0.4rem;
8494
+ --shadow-x: 0px;
8495
+ --shadow-y: 1px;
8496
+ --shadow-blur: 3px;
8497
+ --shadow-spread: 0px;
8498
+ --shadow-opacity: 0.02;
8499
+ --shadow-color: hsl(0 0% 0%);
8500
+ --shadow-2xs: 0px 1px 3px 0px hsl(0 0% 0% / 0.01);
8501
+ --shadow-xs: 0px 1px 3px 0px hsl(0 0% 0% / 0.01);
8502
+ --shadow-sm: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 1px 2px -1px hsl(0 0% 0% / 0.02);
8503
+ --shadow: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 1px 2px -1px hsl(0 0% 0% / 0.02);
8504
+ --shadow-md: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 2px 4px -1px hsl(0 0% 0% / 0.02);
8505
+ --shadow-lg: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 4px 6px -1px hsl(0 0% 0% / 0.02);
8506
+ --shadow-xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.02), 0px 8px 10px -1px hsl(0 0% 0% / 0.02);
8507
+ --shadow-2xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.05);
8508
+ }
8509
+
8510
+ @theme inline {
8511
+ --color-background: var(--background);
8512
+ --color-foreground: var(--foreground);
8513
+ --color-card: var(--card);
8514
+ --color-card-foreground: var(--card-foreground);
8515
+ --color-popover: var(--popover);
8516
+ --color-popover-foreground: var(--popover-foreground);
8517
+ --color-primary: var(--primary);
8518
+ --color-primary-foreground: var(--primary-foreground);
8519
+ --color-secondary: var(--secondary);
8520
+ --color-secondary-foreground: var(--secondary-foreground);
8521
+ --color-muted: var(--muted);
8522
+ --color-muted-foreground: var(--muted-foreground);
8523
+ --color-accent: var(--accent);
8524
+ --color-accent-foreground: var(--accent-foreground);
8525
+ --color-destructive: var(--destructive);
8526
+ --color-destructive-foreground: var(--destructive-foreground);
8527
+ --color-border: var(--border);
8528
+ --color-input: var(--input);
8529
+ --color-ring: var(--ring);
8530
+ --color-chart-1: var(--chart-1);
8531
+ --color-chart-2: var(--chart-2);
8532
+ --color-chart-3: var(--chart-3);
8533
+ --color-chart-4: var(--chart-4);
8534
+ --color-chart-5: var(--chart-5);
8535
+ --color-sidebar: var(--sidebar);
8536
+ --color-sidebar-foreground: var(--sidebar-foreground);
8537
+ --color-sidebar-primary: var(--sidebar-primary);
8538
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
8539
+ --color-sidebar-accent: var(--sidebar-accent);
8540
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
8541
+ --color-sidebar-border: var(--sidebar-border);
8542
+ --color-sidebar-ring: var(--sidebar-ring);
8543
+
8544
+ --font-sans: var(--font-sans);
8545
+ --font-mono: var(--font-mono);
8546
+ --font-serif: var(--font-serif);
8547
+
8548
+ --radius-sm: calc(var(--radius) - 4px);
8549
+ --radius-md: calc(var(--radius) - 2px);
8550
+ --radius-lg: var(--radius);
8551
+ --radius-xl: calc(var(--radius) + 4px);
8552
+
8553
+ --shadow-2xs: var(--shadow-2xs);
8554
+ --shadow-xs: var(--shadow-xs);
8555
+ --shadow-sm: var(--shadow-sm);
8556
+ --shadow: var(--shadow);
8557
+ --shadow-md: var(--shadow-md);
8558
+ --shadow-lg: var(--shadow-lg);
8559
+ --shadow-xl: var(--shadow-xl);
8560
+ --shadow-2xl: var(--shadow-2xl);
8561
+ }
8562
+
8563
+ @layer base {
8564
+ * {
8565
+ @apply border-border outline-ring/50;
8566
+ }
8567
+ body {
8568
+ @apply bg-background text-foreground;
8569
+ }
8483
8570
  }
8484
8571
 
8485
8572
  /* Editor styles */
@@ -8899,21 +8986,19 @@ export function ReorderControls({
8899
8986
  function cmsHeaderTemplate() {
8900
8987
  return `'use client'
8901
8988
 
8902
- import { Moon, Sun } from 'lucide-react'
8903
- import { useTheme } from '@cms/hooks/use-cms-theme'
8904
8989
  import { Button } from '@cms/components/ui/button'
8990
+ import { SidebarTrigger, useSidebar } from '@cms/components/ui/sidebar'
8991
+ import { useTheme } from '@cms/hooks/use-cms-theme'
8992
+ import { Moon, Sun } from 'lucide-react'
8905
8993
 
8906
8994
  export function CmsHeader() {
8907
8995
  const { theme, setTheme } = useTheme()
8996
+ const { state } = useSidebar()
8908
8997
 
8909
8998
  return (
8910
- <header className="flex h-14 shrink-0 items-center gap-2 border-b border-border justify-between w-full sticky top-0 z-50 bg-background">
8911
- <div className="flex items-center gap-3 px-5 w-full">
8912
- <span className="text-sm font-medium text-muted-foreground block md:hidden">
8913
- CMS
8914
- </span>
8915
- </div>
8916
- <div className="flex items-center px-5 gap-1">
8999
+ <header className="flex h-14 shrink-0 items-center gap-2 border-b border-border w-full sticky top-0 z-50 bg-sidebar">
9000
+ <div className="flex items-center px-5 gap-1 flex-1 w-full justify-between">
9001
+ {state === 'collapsed' && <SidebarTrigger />}
8917
9002
  <Button
8918
9003
  variant="ghost"
8919
9004
  size="icon"
@@ -8970,7 +9055,14 @@ export function CmsProviders({ children }: { children: React.ReactNode }) {
8970
9055
 
8971
9056
  // src/init/templates/components/layout/cms-sidebar.ts
8972
9057
  function cmsSidebarTemplate() {
8973
- return `import {
9058
+ return `import { getSession } from '@cms/auth/middleware'
9059
+ import { Avatar, AvatarFallback, AvatarImage } from '@cms/components/ui/avatar'
9060
+ import {
9061
+ Collapsible,
9062
+ CollapsibleContent,
9063
+ CollapsibleTrigger,
9064
+ } from '@cms/components/ui/collapsible'
9065
+ import {
8974
9066
  Sidebar,
8975
9067
  SidebarContent,
8976
9068
  SidebarFooter,
@@ -8984,15 +9076,9 @@ function cmsSidebarTemplate() {
8984
9076
  SidebarRail,
8985
9077
  SidebarTrigger,
8986
9078
  } from '@cms/components/ui/sidebar'
8987
- import {
8988
- Collapsible,
8989
- CollapsibleContent,
8990
- CollapsibleTrigger,
8991
- } from '@cms/components/ui/collapsible'
8992
- import { cmsNavigation, type CmsNavigationItem } from '@cms/data/navigation'
8993
- import { getSession } from '@cms/auth/middleware'
8994
- import Link from 'next/link'
9079
+ import { type CmsNavigationItem, cmsNavigation } from '@cms/data/navigation'
8995
9080
  import { ChevronRight } from 'lucide-react'
9081
+ import Link from 'next/link'
8996
9082
 
8997
9083
  function NavItem({ item }: { item: CmsNavigationItem }) {
8998
9084
  if (item.children && item.children.length > 0) {
@@ -9043,10 +9129,18 @@ export async function CmsSidebar(props: React.ComponentProps<typeof Sidebar>) {
9043
9129
 
9044
9130
  return (
9045
9131
  <Sidebar collapsible="icon" {...props}>
9046
- <SidebarHeader className="border-b border-border h-13 items-center flex w-full">
9132
+ <SidebarHeader className="border-b border-border h-14 items-center flex w-full">
9047
9133
  <div className="flex items-center gap-2 w-full relative h-full">
9048
- <div className="flex items-center pl-2 gap-1 w-full group-data-[collapsible=icon]:hidden">
9049
- <span className="text-base font-bold">CMS</span>
9134
+ <div className="flex items-center gap-2 w-full">
9135
+ <Avatar className="size-8">
9136
+ <AvatarImage src={user?.image ?? ''} />
9137
+ <AvatarFallback className="text-sm font-semibold">
9138
+ {user?.name?.charAt(0)}
9139
+ </AvatarFallback>
9140
+ </Avatar>
9141
+ <div className="flex items-center gap-1 w-full group-data-[collapsible=icon]:hidden">
9142
+ <span className="text-base font-bold">CMS</span>
9143
+ </div>
9050
9144
  </div>
9051
9145
  <SidebarTrigger className="hidden md:flex" />
9052
9146
  </div>
@@ -11389,6 +11483,7 @@ export default function CmsLayout({ children }: { children: React.ReactNode }) {
11389
11483
  function dashboardPageTemplate() {
11390
11484
  return `import { PageHeader } from '@cms/components/shared/page-header'
11391
11485
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@cms/components/ui/card'
11486
+ import { Badge } from '@cms/components/ui/badge'
11392
11487
  import { FileText, Settings, Users } from 'lucide-react'
11393
11488
  import Link from 'next/link'
11394
11489
 
@@ -11446,6 +11541,38 @@ export default function DashboardPage() {
11446
11541
  </Link>
11447
11542
  ))}
11448
11543
  </div>
11544
+ <Card>
11545
+ <CardHeader>
11546
+ <CardTitle className="text-sm font-medium">Environment</CardTitle>
11547
+ <CardDescription>Current configuration status</CardDescription>
11548
+ </CardHeader>
11549
+ <CardContent className="space-y-3">
11550
+ <div className="flex items-center justify-between">
11551
+ <span className="text-sm text-muted-foreground">Environment</span>
11552
+ <Badge variant="outline">
11553
+ {process.env.NODE_ENV === 'production' ? 'Production' : 'Development'}
11554
+ </Badge>
11555
+ </div>
11556
+ <div className="flex items-center justify-between">
11557
+ <span className="text-sm text-muted-foreground">Database</span>
11558
+ <Badge variant="outline">
11559
+ {process.env.BETTERSTART_DATABASE_URL ? 'Connected' : 'Not configured'}
11560
+ </Badge>
11561
+ </div>
11562
+ <div className="flex items-center justify-between">
11563
+ <span className="text-sm text-muted-foreground">Storage (R2)</span>
11564
+ <Badge variant="outline">
11565
+ {process.env.BETTERSTART_R2_BUCKET_NAME ? 'Configured' : 'Not configured'}
11566
+ </Badge>
11567
+ </div>
11568
+ <div className="flex items-center justify-between">
11569
+ <span className="text-sm text-muted-foreground">Email (Resend)</span>
11570
+ <Badge variant="outline">
11571
+ {process.env.BETTERSTART_RESEND_API_KEY ? 'Configured' : 'Not configured'}
11572
+ </Badge>
11573
+ </div>
11574
+ </CardContent>
11575
+ </Card>
11449
11576
  </div>
11450
11577
  </div>
11451
11578
  )
@@ -11567,67 +11694,6 @@ export function LoginForm() {
11567
11694
  `;
11568
11695
  }
11569
11696
 
11570
- // src/init/templates/pages/settings-page.ts
11571
- function settingsPageTemplate() {
11572
- return `import { PageHeader } from '@cms/components/shared/page-header'
11573
- import {
11574
- Card,
11575
- CardContent,
11576
- CardDescription,
11577
- CardHeader,
11578
- CardTitle
11579
- } from '@cms/components/ui/card'
11580
- import { Badge } from '@cms/components/ui/badge'
11581
-
11582
- export default function SettingsPage() {
11583
- return (
11584
- <div className="flex flex-col">
11585
- <div className="flex items-center justify-between bg-card px-6 py-4 border-b">
11586
- <PageHeader
11587
- title="Settings"
11588
- description="Manage your CMS configuration"
11589
- />
11590
- </div>
11591
- <div className="p-6 space-y-6 max-w-2xl">
11592
- <Card>
11593
- <CardHeader>
11594
- <CardTitle className="text-sm font-medium">General</CardTitle>
11595
- <CardDescription>CMS environment information</CardDescription>
11596
- </CardHeader>
11597
- <CardContent className="space-y-3">
11598
- <div className="flex items-center justify-between">
11599
- <span className="text-sm text-muted-foreground">Environment</span>
11600
- <Badge variant="outline">
11601
- {process.env.NODE_ENV === 'production' ? 'Production' : 'Development'}
11602
- </Badge>
11603
- </div>
11604
- <div className="flex items-center justify-between">
11605
- <span className="text-sm text-muted-foreground">Database</span>
11606
- <Badge variant="outline">
11607
- {process.env.BETTERSTART_DATABASE_URL ? 'Connected' : 'Not configured'}
11608
- </Badge>
11609
- </div>
11610
- <div className="flex items-center justify-between">
11611
- <span className="text-sm text-muted-foreground">Storage (R2)</span>
11612
- <Badge variant="outline">
11613
- {process.env.BETTERSTART_R2_BUCKET_NAME ? 'Configured' : 'Not configured'}
11614
- </Badge>
11615
- </div>
11616
- <div className="flex items-center justify-between">
11617
- <span className="text-sm text-muted-foreground">Email (Resend)</span>
11618
- <Badge variant="outline">
11619
- {process.env.BETTERSTART_RESEND_API_KEY ? 'Configured' : 'Not configured'}
11620
- </Badge>
11621
- </div>
11622
- </CardContent>
11623
- </Card>
11624
- </div>
11625
- </div>
11626
- )
11627
- }
11628
- `;
11629
- }
11630
-
11631
11697
  // src/init/templates/pages/users/create-user-dialog.ts
11632
11698
  function createUserDialogTemplate() {
11633
11699
  return `'use client'
@@ -12212,7 +12278,6 @@ function scaffoldLayout({ cwd, config }) {
12212
12278
  write(path31.join(usersDir, "columns.tsx"), usersColumnsTemplate());
12213
12279
  write(path31.join(usersDir, "create-user-dialog.tsx"), createUserDialogTemplate());
12214
12280
  write(path31.join(usersDir, "edit-role-dialog.tsx"), editRoleDialogTemplate());
12215
- write(path31.join(config.paths.pages, "settings", "page.tsx"), settingsPageTemplate());
12216
12281
  return created;
12217
12282
  }
12218
12283
 
@@ -12394,6 +12459,34 @@ function blogPostsSchema() {
12394
12459
  );
12395
12460
  }
12396
12461
 
12462
+ // src/init/templates/presets/default-settings.ts
12463
+ function defaultSettingsSchema() {
12464
+ return JSON.stringify(
12465
+ {
12466
+ name: "settings",
12467
+ type: "single",
12468
+ label: "Settings",
12469
+ description: "General site settings",
12470
+ icon: "Settings",
12471
+ fields: [
12472
+ { name: "siteName", type: "string", label: "Site Name", required: true },
12473
+ { name: "tagline", type: "string", label: "Tagline" },
12474
+ { name: "separator1", type: "separator" },
12475
+ { name: "logo", type: "image", label: "Logo" },
12476
+ { name: "favicon", type: "image", label: "Favicon" },
12477
+ { name: "separator2", type: "separator" },
12478
+ { name: "contactEmail", type: "string", label: "Contact Email" },
12479
+ { name: "socialTwitter", type: "string", label: "Twitter / X URL" },
12480
+ { name: "socialInstagram", type: "string", label: "Instagram URL" },
12481
+ { name: "socialLinkedin", type: "string", label: "LinkedIn URL" },
12482
+ { name: "socialGithub", type: "string", label: "GitHub URL" }
12483
+ ]
12484
+ },
12485
+ null,
12486
+ 2
12487
+ );
12488
+ }
12489
+
12397
12490
  // src/init/templates/presets/full-contact.ts
12398
12491
  function fullContactSchema() {
12399
12492
  return JSON.stringify(
@@ -12551,16 +12644,25 @@ function fullNavigationSchema() {
12551
12644
 
12552
12645
  // src/init/scaffolders/preset.ts
12553
12646
  function getPresetSchemas(preset) {
12554
- if (preset === "blank") return [];
12555
12647
  const schemas = [
12556
12648
  {
12557
- filename: "categories.json",
12558
- content: blogCategoriesSchema(),
12649
+ filename: "settings.json",
12650
+ content: defaultSettingsSchema(),
12559
12651
  isForm: false,
12560
- isSingle: false
12561
- },
12562
- { filename: "posts.json", content: blogPostsSchema(), isForm: false, isSingle: false }
12652
+ isSingle: true
12653
+ }
12563
12654
  ];
12655
+ if (preset !== "blank") {
12656
+ schemas.push(
12657
+ {
12658
+ filename: "categories.json",
12659
+ content: blogCategoriesSchema(),
12660
+ isForm: false,
12661
+ isSingle: false
12662
+ },
12663
+ { filename: "posts.json", content: blogPostsSchema(), isForm: false, isSingle: false }
12664
+ );
12665
+ }
12564
12666
  if (preset === "full") {
12565
12667
  schemas.push(
12566
12668
  {
@@ -12589,7 +12691,6 @@ function scaffoldPreset({
12589
12691
  generatedFiles: [],
12590
12692
  errors: []
12591
12693
  };
12592
- if (preset === "blank") return result;
12593
12694
  const schemasDir = path32.join(cwd, config.paths?.schemas ?? "./cms/schemas");
12594
12695
  const presetSchemas = getPresetSchemas(preset);
12595
12696
  for (const ps of presetSchemas) {
@@ -13097,19 +13198,17 @@ var initCommand = new Command2("init").description("Scaffold CMS into a new or e
13097
13198
  ${pc.cyan(`${pm} add -D ${depsResult.devDeps.join(" ")}`)}`
13098
13199
  );
13099
13200
  }
13100
- if (features.preset !== "blank") {
13101
- s.start(`Applying ${features.preset} preset...`);
13102
- const presetResult = scaffoldPreset({ cwd, config, preset: features.preset });
13103
- if (presetResult.errors.length > 0) {
13104
- s.stop(`Preset applied with ${presetResult.errors.length} warning(s)`);
13105
- for (const err of presetResult.errors) {
13106
- p3.log.warning(` ${err}`);
13107
- }
13108
- } else {
13109
- s.stop(
13110
- `Created ${presetResult.schemas.length} schemas, generated ${presetResult.generatedFiles.length} files`
13111
- );
13201
+ s.start(`Applying ${features.preset} preset...`);
13202
+ const presetResult = scaffoldPreset({ cwd, config, preset: features.preset });
13203
+ if (presetResult.errors.length > 0) {
13204
+ s.stop(`Preset applied with ${presetResult.errors.length} warning(s)`);
13205
+ for (const err of presetResult.errors) {
13206
+ p3.log.warning(` ${err}`);
13112
13207
  }
13208
+ } else {
13209
+ s.stop(
13210
+ `Created ${presetResult.schemas.length} schemas, generated ${presetResult.generatedFiles.length} files`
13211
+ );
13113
13212
  }
13114
13213
  if (depsResult.success && hasDbUrl(cwd)) {
13115
13214
  s.start("Pushing database schema (drizzle-kit push)...");