@lucifer91299/create-portal-app 1.0.6 → 1.0.8

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/README.md CHANGED
@@ -216,6 +216,15 @@ See the full component and theming documentation at:
216
216
 
217
217
  ## Changelog
218
218
 
219
+ ### v1.0.7
220
+ - Removed `PageFooter` from generated dashboard layout — no double footer
221
+ - Template generates cleaner layout; `PageFooter` can be added manually where needed
222
+
223
+ ### v1.0.6
224
+ - Generated project now includes Users and Settings pages
225
+ - Fixed Windows folder creation bug (`path.dirname` instead of `lastIndexOf('/')`)
226
+ - CLI help text corrected to `npx @lucifer91299/create-portal-app`
227
+
219
228
  ### v1.0.3
220
229
  - Added `workflow_dispatch` to GitHub Actions — manual publish trigger from Actions tab
221
230
  - README improvements: badges, changelog
package/dist/cli/index.js CHANGED
@@ -37,11 +37,12 @@ function closePrompt() {
37
37
  // src/templates/index.ts
38
38
  function genPackageJson(o) {
39
39
  const deps = {
40
- "@lucifer91299/ui": o.localUiPath ? `file:${o.localUiPath}` : "^1.0.0",
40
+ "@lucifer91299/ui": o.localUiPath ? `file:${o.localUiPath}` : "^1.0.7",
41
41
  "next": "^15.3.0",
42
42
  "react": "^19.0.0",
43
43
  "react-dom": "^19.0.0",
44
44
  "framer-motion": "^12.0.0",
45
+ "recharts": "^3.8.1",
45
46
  "axios": "^1.7.9",
46
47
  "@tanstack/react-query": "^5.64.1",
47
48
  "jose": "^5.9.6",
@@ -424,7 +425,7 @@ export const navGroups: NavGroup[] = [
424
425
  function genDashboardLayout(o) {
425
426
  return `'use client'
426
427
 
427
- import { DashboardLayout, PageFooter, use${o.authMode === "multi-role" ? "MultiRoleAuth" : "JwtAuth"} } from '@lucifer91299/ui'
428
+ import { DashboardLayout, use${o.authMode === "multi-role" ? "MultiRoleAuth" : "JwtAuth"} } from '@lucifer91299/ui'
428
429
  import { usePathname } from 'next/navigation'
429
430
  import { navGroups } from '@/components/layout/nav-config'
430
431
 
@@ -450,15 +451,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
450
451
  pathname={pathname}
451
452
  onLogout={logout}
452
453
  >
453
- <div className="flex flex-col min-h-full">
454
- <div className="flex-1">{children}</div>
455
- <PageFooter
456
- organizationName="${o.projectName}"
457
- logoSrc="/brand/logo.svg"
458
- poweredByText="Powered by"
459
- poweredByHref="#"
460
- />
461
- </div>
454
+ {children}
462
455
  </DashboardLayout>
463
456
  )
464
457
  }
@@ -525,14 +518,33 @@ export default function Home() {
525
518
  function genDashboardHomePage(o) {
526
519
  return `'use client'
527
520
 
528
- import { PageShell, DataTable, StatusBadge, useJwtAuth } from '@lucifer91299/ui'
521
+ import { useState } from 'react'
522
+ import { PageShell, DataTable, StatusBadge, useJwtAuth, PortalBarChart, PortalAreaChart, PortalDonutChart, DatePicker } from '@lucifer91299/ui'
529
523
  import { TrendingUp, Users, ShoppingCart, Activity } from 'lucide-react'
530
524
 
531
525
  const stats = [
532
- { label: 'Total Users', value: '2,847', change: '+12%', icon: Users, color: 'bg-blue-50 text-blue-600' },
533
- { label: 'Revenue', value: '\u20B948,295', change: '+8.2%', icon: TrendingUp, color: 'bg-green-50 text-green-600' },
534
- { label: 'Orders', value: '1,429', change: '+5.1%', icon: ShoppingCart, color: 'bg-orange-50 text-orange-600' },
535
- { label: 'Active Now', value: '94', change: '+3', icon: Activity, color: 'bg-purple-50 text-purple-600' },
526
+ { label: 'Total Users', value: '2,847', change: '+12%', icon: Users, bg: 'bg-blue-50', fg: 'text-blue-600' },
527
+ { label: 'Revenue', value: '\u20B948,295', change: '+8.2%', icon: TrendingUp, bg: 'bg-green-50', fg: 'text-green-600' },
528
+ { label: 'Orders', value: '1,429', change: '+5.1%', icon: ShoppingCart, bg: 'bg-orange-50', fg: 'text-orange-600' },
529
+ { label: 'Active Now', value: '94', change: '+3', icon: Activity, bg: 'bg-purple-50', fg: 'text-purple-600' },
530
+ ]
531
+
532
+ const MONTHLY = [
533
+ { month: 'Jan', orders: 38, members: 120, revenue: 48 },
534
+ { month: 'Feb', orders: 52, members: 134, revenue: 62 },
535
+ { month: 'Mar', orders: 47, members: 128, revenue: 55 },
536
+ { month: 'Apr', orders: 65, members: 156, revenue: 78 },
537
+ { month: 'May', orders: 71, members: 172, revenue: 85 },
538
+ { month: 'Jun', orders: 60, members: 160, revenue: 72 },
539
+ { month: 'Jul', orders: 84, members: 198, revenue: 96 },
540
+ { month: 'Aug', orders: 79, members: 185, revenue: 92 },
541
+ ]
542
+
543
+ const STATUS_DONUT = [
544
+ { name: 'Completed', value: 384, color: '#138808' },
545
+ { name: 'Approved', value: 213, color: '#000080' },
546
+ { name: 'Pending', value: 97, color: '#FF9933' },
547
+ { name: 'Rejected', value: 42, color: '#ef4444' },
536
548
  ]
537
549
 
538
550
  const activity = [
@@ -545,40 +557,88 @@ const activity = [
545
557
 
546
558
  export default function DashboardHome() {
547
559
  const { user } = useJwtAuth()
560
+ const [fromDate, setFromDate] = useState('')
561
+ const [toDate, setToDate] = useState('')
548
562
 
549
563
  return (
550
- <div className="p-6 space-y-6">
551
- <PageShell
552
- title={\`Welcome back, \${String(user?.name ?? 'Admin')}\`}
553
- subtitle="Here's what's happening today."
554
- />
564
+ <div className="p-4 sm:p-6 space-y-6 max-w-7xl mx-auto">
565
+ <div className="flex items-start justify-between gap-4 flex-wrap">
566
+ <div>
567
+ <h1 className="text-title1 text-label-primary font-semibold">
568
+ Welcome back, {String(user?.name ?? 'Admin')} \u{1F44B}
569
+ </h1>
570
+ <p className="text-body text-label-secondary mt-0.5">Here&apos;s what&apos;s happening today.</p>
571
+ </div>
572
+ <div className="flex items-center gap-2 flex-wrap">
573
+ <DatePicker value={fromDate} onChange={setFromDate} placeholder="From date" className="w-36" disableFuture />
574
+ <span className="text-label-tertiary">\u2013</span>
575
+ <DatePicker value={toDate} onChange={setToDate} placeholder="To date" className="w-36" disableFuture />
576
+ </div>
577
+ </div>
555
578
 
556
579
  <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
557
- {stats.map(({ label, value, change, icon: Icon, color }) => (
558
- <div key={label} className="bg-white rounded-xl p-5 shadow-sm border border-separator">
580
+ {stats.map(({ label, value, change, icon: Icon, bg, fg }) => (
581
+ <div key={label} className="bg-white rounded-2xl p-5 shadow-sm border border-separator">
559
582
  <div className="flex items-center justify-between mb-3">
560
583
  <p className="text-subhead text-label-secondary">{label}</p>
561
- <div className={\`w-8 h-8 rounded-lg flex items-center justify-center \${color}\`}>
584
+ <div className={\`w-9 h-9 rounded-xl flex items-center justify-center \${bg} \${fg}\`}>
562
585
  <Icon className="w-4 h-4" />
563
586
  </div>
564
587
  </div>
565
588
  <p className="text-title1 font-bold text-label-primary">{value}</p>
566
- <p className="text-footnote text-green-600 mt-1">{change} this month</p>
589
+ <p className="text-footnote text-green-600 mt-0.5 font-medium">{change} this month</p>
567
590
  </div>
568
591
  ))}
569
592
  </div>
570
593
 
571
- <div className="bg-white rounded-xl shadow-sm border border-separator overflow-hidden">
594
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-5">
595
+ <div className="lg:col-span-2 bg-white rounded-2xl border border-separator shadow-sm p-5">
596
+ <p className="text-headline font-semibold text-label-primary mb-1">Orders &amp; Members per Month</p>
597
+ <p className="text-footnote text-label-tertiary mb-4">Current year overview</p>
598
+ <PortalBarChart
599
+ data={MONTHLY}
600
+ xKey="month"
601
+ series={[
602
+ { key: 'orders', name: 'Orders' },
603
+ { key: 'members', name: 'Members' },
604
+ ]}
605
+ height={220}
606
+ />
607
+ </div>
608
+ <div className="bg-white rounded-2xl border border-separator shadow-sm p-5">
609
+ <p className="text-headline font-semibold text-label-primary mb-1">Order Status</p>
610
+ <p className="text-footnote text-label-tertiary mb-2">All time</p>
611
+ <PortalDonutChart
612
+ data={STATUS_DONUT}
613
+ height={230}
614
+ centerValue="764"
615
+ centerLabel="Orders"
616
+ />
617
+ </div>
618
+ </div>
619
+
620
+ <div className="bg-white rounded-2xl border border-separator shadow-sm p-5">
621
+ <p className="text-headline font-semibold text-label-primary mb-1">Revenue Trend (\u20B9 thousands)</p>
622
+ <p className="text-footnote text-label-tertiary mb-4">Monthly revenue</p>
623
+ <PortalAreaChart
624
+ data={MONTHLY}
625
+ xKey="month"
626
+ series={[{ key: 'revenue', name: 'Revenue (\u20B9K)' }]}
627
+ height={200}
628
+ />
629
+ </div>
630
+
631
+ <div className="bg-white rounded-2xl shadow-sm border border-separator overflow-hidden">
572
632
  <div className="px-5 py-4 border-b border-separator">
573
633
  <h2 className="text-callout font-semibold text-label-primary">Recent Activity</h2>
574
634
  </div>
575
635
  <DataTable
576
636
  columns={[
577
- { key: 'id', header: 'ID', className: 'font-mono text-xs text-label-secondary' },
578
- { key: 'user', header: 'User', render: (r) => <span className="font-medium text-label-primary">{r.user}</span> },
579
- { key: 'action', header: 'Action', render: (r) => <span className="text-label-secondary">{r.action}</span> },
580
- { key: 'time', header: 'Time', render: (r) => <span className="text-label-tertiary">{r.time}</span> },
581
- { key: 'status', header: 'Status', render: (r) => <StatusBadge status={r.status} /> },
637
+ { key: 'id', header: 'ID', render: (r) => <span className="font-mono text-xs text-label-tertiary">{r.id}</span> },
638
+ { key: 'user', header: 'User', render: (r) => <span className="font-medium text-label-primary">{r.user}</span> },
639
+ { key: 'action', header: 'Action', render: (r) => <span className="text-label-secondary">{r.action}</span> },
640
+ { key: 'time', header: 'Time', render: (r) => <span className="text-label-tertiary">{r.time}</span> },
641
+ { key: 'status', header: 'Status', render: (r) => <StatusBadge status={r.status} /> },
582
642
  ]}
583
643
  data={activity}
584
644
  keyExtractor={(r) => r.id}
@@ -733,7 +793,7 @@ export default function SettingsPage() {
733
793
  actions={<Button variant="primary" onClick={handleSave}>Save changes</Button>}
734
794
  />
735
795
 
736
- {saved && <AlertBanner variant="success" message="Settings saved successfully." />}
796
+ {saved && <AlertBanner variant="success">Settings saved successfully.</AlertBanner>}
737
797
 
738
798
  <Card className="p-6">
739
799
  <h3 className="text-callout font-semibold text-label-primary mb-4">Appearance</h3>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucifer91299/create-portal-app",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Scaffold a Next.js authenticated portal with full design system in one command",
5
5
  "license": "MIT",
6
6
  "author": "Aakash Kanojiya",