@elsapiens/cli 0.1.0

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.
@@ -0,0 +1,5 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ /* Custom styles can be added here */
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title><%= pascalName %></title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import { BrowserRouter } from 'react-router-dom';
4
+ import App from './App';
5
+ import '@elsapiens/styles/variables.css';
6
+ import '@elsapiens/styles/components.css';
7
+ import './index.css';
8
+
9
+ ReactDOM.createRoot(document.getElementById('root')!).render(
10
+ <React.StrictMode>
11
+ <BrowserRouter>
12
+ <App />
13
+ </BrowserRouter>
14
+ </React.StrictMode>
15
+ );
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "<%= projectName %>",
3
+ "private": true,
4
+ "version": "0.1.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc && vite build",
9
+ "preview": "vite preview",
10
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
11
+ },
12
+ "dependencies": {
13
+ "@elsapiens/ui": "latest",
14
+ "@elsapiens/utils": "latest",
15
+ "@elsapiens/styles": "latest",
16
+ "lucide-react": "^0.300.0",
17
+ "react": "^18.2.0",
18
+ "react-dom": "^18.2.0",
19
+ "react-router-dom": "^6.21.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/react": "^18.2.0",
23
+ "@types/react-dom": "^18.2.0",
24
+ "@vitejs/plugin-react": "^4.2.0",
25
+ "autoprefixer": "^10.4.16",
26
+ "postcss": "^8.4.32",
27
+ "tailwindcss": "^3.4.0",
28
+ "typescript": "^5.3.0",
29
+ "vite": "^5.0.0"
30
+ }
31
+ }
@@ -0,0 +1,108 @@
1
+ import {
2
+ Button,
3
+ Card,
4
+ CardHeader,
5
+ CardTitle,
6
+ CardContent,
7
+ } from '@elsapiens/ui';
8
+ import { Plus, TrendingUp, TrendingDown, Users, FileText, DollarSign } from 'lucide-react';
9
+
10
+ interface StatCardProps {
11
+ title: string;
12
+ value: string;
13
+ change?: string;
14
+ changeType?: 'positive' | 'negative';
15
+ icon: React.ElementType;
16
+ }
17
+
18
+ function StatCard({ title, value, change, changeType, icon: Icon }: StatCardProps) {
19
+ const isPositive = changeType === 'positive';
20
+ return (
21
+ <Card padding="none">
22
+ <CardContent className="p-6">
23
+ <div className="flex items-start justify-between">
24
+ <div className="flex-1">
25
+ <p className="text-sm text-muted-foreground">{title}</p>
26
+ <p className="text-2xl font-bold text-foreground mt-1">{value}</p>
27
+ {change && (
28
+ <p className={`text-sm mt-1 flex items-center gap-1 ${isPositive ? 'text-success' : 'text-error'}`}>
29
+ {isPositive ? <TrendingUp className="w-4 h-4" /> : <TrendingDown className="w-4 h-4" />}
30
+ {change}
31
+ </p>
32
+ )}
33
+ </div>
34
+ <div className="w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center">
35
+ <Icon className="w-5 h-5 text-primary" />
36
+ </div>
37
+ </div>
38
+ </CardContent>
39
+ </Card>
40
+ );
41
+ }
42
+
43
+ export default function Dashboard() {
44
+ return (
45
+ <div className="p-6">
46
+ {/* Page Header - pl-6 to align with content */}
47
+ <div className="flex items-center justify-between mb-8 pl-6">
48
+ <div>
49
+ <h1 className="text-2xl font-bold text-foreground">Dashboard</h1>
50
+ <p className="text-muted-foreground">Welcome back! Here's what's happening.</p>
51
+ </div>
52
+ <div className="flex items-center gap-4">
53
+ <Button>
54
+ <Plus className="w-4 h-4 mr-2" />
55
+ New Item
56
+ </Button>
57
+ </div>
58
+ </div>
59
+
60
+ {/* Stats Grid */}
61
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
62
+ <StatCard
63
+ title="Total Revenue"
64
+ value="$45,231"
65
+ change="+20.1% from last month"
66
+ changeType="positive"
67
+ icon={DollarSign}
68
+ />
69
+ <StatCard
70
+ title="Documents"
71
+ value="2,345"
72
+ change="+15% from last month"
73
+ changeType="positive"
74
+ icon={FileText}
75
+ />
76
+ <StatCard
77
+ title="Active Users"
78
+ value="1,234"
79
+ change="+5.2% from last month"
80
+ changeType="positive"
81
+ icon={Users}
82
+ />
83
+ <StatCard
84
+ title="Bounce Rate"
85
+ value="24.5%"
86
+ change="-3.2% from last month"
87
+ changeType="negative"
88
+ icon={TrendingDown}
89
+ />
90
+ </div>
91
+
92
+ {/* Content Area */}
93
+ <div>
94
+ <Card padding="none">
95
+ <CardHeader className="p-6">
96
+ <CardTitle>Getting Started</CardTitle>
97
+ </CardHeader>
98
+ <CardContent className="p-6 pt-0">
99
+ <p className="text-muted-foreground">
100
+ Welcome to your new elSapiens project! Edit this page at{' '}
101
+ <code className="text-sm bg-muted px-1 py-0.5 rounded">src/pages/Dashboard.tsx</code>
102
+ </p>
103
+ </CardContent>
104
+ </Card>
105
+ </div>
106
+ </div>
107
+ );
108
+ }
@@ -0,0 +1,116 @@
1
+ import {
2
+ Button,
3
+ Input,
4
+ Toggle,
5
+ Select,
6
+ Card,
7
+ CardHeader,
8
+ CardTitle,
9
+ CardContent,
10
+ } from '@elsapiens/ui';
11
+ import { User, Bell, Palette } from 'lucide-react';
12
+ import { useState } from 'react';
13
+
14
+ export default function Settings() {
15
+ const [notifications, setNotifications] = useState(true);
16
+ const [emailUpdates, setEmailUpdates] = useState(false);
17
+
18
+ return (
19
+ <div className="p-6 max-w-4xl">
20
+ {/* Page Header - pl-6 to align with card content */}
21
+ <div className="mb-8 pl-6">
22
+ <h1 className="text-2xl font-bold text-foreground">Settings</h1>
23
+ <p className="text-muted-foreground">Manage your account and preferences</p>
24
+ </div>
25
+
26
+ <div className="space-y-6">
27
+ {/* Profile Section */}
28
+ <Card padding="none">
29
+ <CardHeader className="p-6">
30
+ <CardTitle className="flex items-center gap-3">
31
+ <User className="w-5 h-5 text-muted-foreground" />
32
+ Profile
33
+ </CardTitle>
34
+ </CardHeader>
35
+ <CardContent className="p-6 pt-0 space-y-4">
36
+ <div className="grid grid-cols-2 gap-4">
37
+ <div>
38
+ <label className="block text-sm font-medium text-foreground mb-1">
39
+ First Name
40
+ </label>
41
+ <Input defaultValue="John" hideMessage />
42
+ </div>
43
+ <div>
44
+ <label className="block text-sm font-medium text-foreground mb-1">
45
+ Last Name
46
+ </label>
47
+ <Input defaultValue="Doe" hideMessage />
48
+ </div>
49
+ </div>
50
+ <div>
51
+ <label className="block text-sm font-medium text-foreground mb-1">
52
+ Email
53
+ </label>
54
+ <Input type="email" defaultValue="john.doe@example.com" hideMessage />
55
+ </div>
56
+ <div className="pt-2">
57
+ <Button>Save Changes</Button>
58
+ </div>
59
+ </CardContent>
60
+ </Card>
61
+
62
+ {/* Notifications Section */}
63
+ <Card padding="none">
64
+ <CardHeader className="p-6">
65
+ <CardTitle className="flex items-center gap-3">
66
+ <Bell className="w-5 h-5 text-muted-foreground" />
67
+ Notifications
68
+ </CardTitle>
69
+ </CardHeader>
70
+ <CardContent className="p-6 pt-0 space-y-4">
71
+ <div className="flex items-center justify-between">
72
+ <div>
73
+ <p className="font-medium text-foreground">Push Notifications</p>
74
+ <p className="text-sm text-muted-foreground">Receive push notifications</p>
75
+ </div>
76
+ <Toggle checked={notifications} onChange={setNotifications} />
77
+ </div>
78
+ <div className="flex items-center justify-between">
79
+ <div>
80
+ <p className="font-medium text-foreground">Email Updates</p>
81
+ <p className="text-sm text-muted-foreground">Receive email summaries</p>
82
+ </div>
83
+ <Toggle checked={emailUpdates} onChange={setEmailUpdates} />
84
+ </div>
85
+ </CardContent>
86
+ </Card>
87
+
88
+ {/* Appearance Section */}
89
+ <Card padding="none">
90
+ <CardHeader className="p-6">
91
+ <CardTitle className="flex items-center gap-3">
92
+ <Palette className="w-5 h-5 text-muted-foreground" />
93
+ Appearance
94
+ </CardTitle>
95
+ </CardHeader>
96
+ <CardContent className="p-6 pt-0 space-y-4">
97
+ <div>
98
+ <label className="block text-sm font-medium text-foreground mb-1">
99
+ Theme
100
+ </label>
101
+ <Select
102
+ options={[
103
+ { value: 'light', label: 'Light' },
104
+ { value: 'dark', label: 'Dark' },
105
+ { value: 'system', label: 'System' },
106
+ ]}
107
+ value="light"
108
+ hideMessage
109
+ />
110
+ </div>
111
+ </CardContent>
112
+ </Card>
113
+ </div>
114
+ </div>
115
+ );
116
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "bundler",
9
+ "allowImportingTsExtensions": true,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true,
12
+ "noEmit": true,
13
+ "jsx": "react-jsx",
14
+ "strict": true,
15
+ "noUnusedLocals": true,
16
+ "noUnusedParameters": true,
17
+ "noFallthroughCasesInSwitch": true
18
+ },
19
+ "include": ["src"],
20
+ "references": [{ "path": "./tsconfig.node.json" }]
21
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: {
7
+ port: 3000,
8
+ },
9
+ });
@@ -0,0 +1,16 @@
1
+ import { cn } from '@elsapiens/utils';
2
+
3
+ export interface <%= pascalName %>Props {
4
+ className?: string;
5
+ children?: React.ReactNode;
6
+ }
7
+
8
+ export function <%= pascalName %>({ className, children }: <%= pascalName %>Props) {
9
+ return (
10
+ <div className={cn('', className)}>
11
+ {children}
12
+ </div>
13
+ );
14
+ }
15
+
16
+ export default <%= pascalName %>;
@@ -0,0 +1,30 @@
1
+ import { useState } from 'react';
2
+ import { cn } from '@elsapiens/utils';
3
+
4
+ export interface <%= pascalName %>Props {
5
+ className?: string;
6
+ initialValue?: string;
7
+ onChange?: (value: string) => void;
8
+ }
9
+
10
+ export function <%= pascalName %>({
11
+ className,
12
+ initialValue = '',
13
+ onChange,
14
+ }: <%= pascalName %>Props) {
15
+ const [value, setValue] = useState(initialValue);
16
+
17
+ const handleChange = (newValue: string) => {
18
+ setValue(newValue);
19
+ onChange?.(newValue);
20
+ };
21
+
22
+ return (
23
+ <div className={cn('', className)}>
24
+ {/* Component content */}
25
+ <p>Current value: {value}</p>
26
+ </div>
27
+ );
28
+ }
29
+
30
+ export default <%= pascalName %>;
@@ -0,0 +1,203 @@
1
+ import {
2
+ Button,
3
+ Card,
4
+ CardHeader,
5
+ CardTitle,
6
+ CardContent,
7
+ Table,
8
+ Badge,
9
+ AreaChart,
10
+ DonutChart,
11
+ TrendSparkline,
12
+ } from '@elsapiens/ui';
13
+ import { Plus, TrendingUp, TrendingDown, Users, FileText, DollarSign } from 'lucide-react';
14
+ import { useState } from 'react';
15
+
16
+ // Sample data - replace with your data source
17
+ const chartData = [
18
+ { month: 'Jan', value: 32000, secondary: 24000 },
19
+ { month: 'Feb', value: 38000, secondary: 26000 },
20
+ { month: 'Mar', value: 35000, secondary: 25000 },
21
+ { month: 'Apr', value: 42000, secondary: 28000 },
22
+ { month: 'May', value: 48000, secondary: 30000 },
23
+ { month: 'Jun', value: 45231, secondary: 29000 },
24
+ ];
25
+
26
+ const donutData = [
27
+ { name: 'Direct', value: 4500, color: 'primary' as const },
28
+ { name: 'Organic', value: 3200, color: 'success' as const },
29
+ { name: 'Referral', value: 2100, color: 'warning' as const },
30
+ { name: 'Social', value: 1800, color: 'info' as const },
31
+ ];
32
+
33
+ const recentActivity = [
34
+ { id: '1', action: 'Created new item', user: 'John Doe', time: '2 min ago', status: 'success' },
35
+ { id: '2', action: 'Updated settings', user: 'Jane Smith', time: '1 hour ago', status: 'info' },
36
+ { id: '3', action: 'Generated report', user: 'Mike Johnson', time: '3 hours ago', status: 'warning' },
37
+ ];
38
+
39
+ interface StatCardProps {
40
+ title: string;
41
+ value: string;
42
+ change?: string;
43
+ changeType?: 'positive' | 'negative';
44
+ icon: React.ElementType;
45
+ sparklineData?: number[];
46
+ }
47
+
48
+ function StatCard({ title, value, change, changeType, icon: Icon, sparklineData }: StatCardProps) {
49
+ const isPositive = changeType === 'positive';
50
+ return (
51
+ <Card padding="none">
52
+ <CardContent className="p-6">
53
+ <div className="flex items-start justify-between">
54
+ <div className="flex-1">
55
+ <p className="text-sm text-muted-foreground">{title}</p>
56
+ <p className="text-2xl font-bold text-foreground mt-1">{value}</p>
57
+ {change && (
58
+ <p className={`text-sm mt-1 flex items-center gap-1 ${isPositive ? 'text-success' : 'text-error'}`}>
59
+ {isPositive ? <TrendingUp className="w-4 h-4" /> : <TrendingDown className="w-4 h-4" />}
60
+ {change}
61
+ </p>
62
+ )}
63
+ </div>
64
+ <div className="flex flex-col items-end gap-2">
65
+ <div className="w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center">
66
+ <Icon className="w-5 h-5 text-primary" />
67
+ </div>
68
+ {sparklineData && (
69
+ <TrendSparkline data={sparklineData} type="area" width={80} height={32} />
70
+ )}
71
+ </div>
72
+ </div>
73
+ </CardContent>
74
+ </Card>
75
+ );
76
+ }
77
+
78
+ export default function <%= pascalName %>() {
79
+ return (
80
+ <div className="p-6">
81
+ {/* Page Header - pl-6 to align with table spacer */}
82
+ <div className="flex items-center justify-between mb-8 pl-6">
83
+ <div>
84
+ <h1 className="text-2xl font-bold text-foreground"><%= title %></h1>
85
+ <p className="text-muted-foreground"><%= description %></p>
86
+ </div>
87
+ <div className="flex items-center gap-4">
88
+ <Button>
89
+ <Plus className="w-4 h-4 mr-2" />
90
+ New Item
91
+ </Button>
92
+ </div>
93
+ </div>
94
+
95
+ {/* Stats Grid */}
96
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
97
+ <StatCard
98
+ title="Total Revenue"
99
+ value="$45,231"
100
+ change="+20.1% from last month"
101
+ changeType="positive"
102
+ icon={DollarSign}
103
+ sparklineData={[32, 38, 35, 42, 48, 45]}
104
+ />
105
+ <StatCard
106
+ title="Documents"
107
+ value="2,345"
108
+ change="+15% from last month"
109
+ changeType="positive"
110
+ icon={FileText}
111
+ sparklineData={[180, 200, 195, 220, 235, 234]}
112
+ />
113
+ <StatCard
114
+ title="Active Users"
115
+ value="1,234"
116
+ change="+5.2% from last month"
117
+ changeType="positive"
118
+ icon={Users}
119
+ sparklineData={[100, 110, 108, 115, 120, 123]}
120
+ />
121
+ <StatCard
122
+ title="Bounce Rate"
123
+ value="24.5%"
124
+ change="-3.2% from last month"
125
+ changeType="negative"
126
+ icon={TrendingDown}
127
+ sparklineData={[30, 28, 27, 26, 25, 24]}
128
+ />
129
+ </div>
130
+
131
+ {/* Charts Row */}
132
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
133
+ {/* Main Chart */}
134
+ <Card padding="none" className="lg:col-span-2">
135
+ <CardHeader className="p-6">
136
+ <CardTitle>Overview</CardTitle>
137
+ </CardHeader>
138
+ <CardContent className="p-6 pt-0">
139
+ <AreaChart
140
+ data={chartData}
141
+ xAxisKey="month"
142
+ areas={[
143
+ { dataKey: 'value', name: 'Primary', color: 'primary' },
144
+ { dataKey: 'secondary', name: 'Secondary', color: 'error' },
145
+ ]}
146
+ height={300}
147
+ />
148
+ </CardContent>
149
+ </Card>
150
+
151
+ {/* Donut Chart */}
152
+ <Card padding="none">
153
+ <CardHeader className="p-6">
154
+ <CardTitle>Distribution</CardTitle>
155
+ </CardHeader>
156
+ <CardContent className="p-6 pt-0">
157
+ <DonutChart
158
+ data={donutData}
159
+ height={260}
160
+ centerValue="11.6K"
161
+ centerSubtext="Total"
162
+ />
163
+ </CardContent>
164
+ </Card>
165
+ </div>
166
+
167
+ {/* Recent Activity */}
168
+ <div>
169
+ <Card padding="none">
170
+ <CardHeader className="p-6">
171
+ <CardTitle>Recent Activity</CardTitle>
172
+ </CardHeader>
173
+ <CardContent className="p-6">
174
+ <Table
175
+ data={recentActivity}
176
+ columns={[
177
+ { key: 'action', header: 'Action' },
178
+ { key: 'user', header: 'User' },
179
+ { key: 'time', header: 'Time', align: 'right' },
180
+ {
181
+ key: 'status',
182
+ header: 'Status',
183
+ align: 'right',
184
+ render: (item) => (
185
+ <Badge
186
+ variant={item.status as 'default' | 'success' | 'warning' | 'info'}
187
+ size="sm"
188
+ >
189
+ {item.status}
190
+ </Badge>
191
+ ),
192
+ },
193
+ ]}
194
+ striped={false}
195
+ inCard="full"
196
+ cardPadding="lg"
197
+ />
198
+ </CardContent>
199
+ </Card>
200
+ </div>
201
+ </div>
202
+ );
203
+ }