@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,191 @@
1
+ import {
2
+ Button,
3
+ Input,
4
+ Select,
5
+ Card,
6
+ CardHeader,
7
+ CardTitle,
8
+ CardContent,
9
+ Table,
10
+ Badge,
11
+ DonutChart,
12
+ } from '@elsapiens/ui';
13
+ import { Search, Filter, Plus, FileText, MoreVertical } from 'lucide-react';
14
+
15
+ // Sample data - replace with your data source
16
+ const items = [
17
+ { id: '1', name: 'Item One', type: 'Type A', status: 'active', date: '2024-01-15' },
18
+ { id: '2', name: 'Item Two', type: 'Type B', status: 'pending', date: '2024-01-14' },
19
+ { id: '3', name: 'Item Three', type: 'Type A', status: 'active', date: '2024-01-13' },
20
+ { id: '4', name: 'Item Four', type: 'Type C', status: 'inactive', date: '2024-01-12' },
21
+ { id: '5', name: 'Item Five', type: 'Type B', status: 'active', date: '2024-01-11' },
22
+ { id: '6', name: 'Item Six', type: 'Type A', status: 'pending', date: '2024-01-10' },
23
+ { id: '7', name: 'Item Seven', type: 'Type C', status: 'active', date: '2024-01-09' },
24
+ { id: '8', name: 'Item Eight', type: 'Type B', status: 'inactive', date: '2024-01-08' },
25
+ ];
26
+
27
+ const itemStats = [
28
+ { name: 'Type A', value: 3, color: 'primary' as const },
29
+ { name: 'Type B', value: 3, color: 'success' as const },
30
+ { name: 'Type C', value: 2, color: 'warning' as const },
31
+ ];
32
+
33
+ const getStatusBadgeVariant = (status: string): 'default' | 'success' | 'warning' | 'info' => {
34
+ switch (status) {
35
+ case 'active':
36
+ return 'success';
37
+ case 'pending':
38
+ return 'warning';
39
+ case 'inactive':
40
+ return 'default';
41
+ default:
42
+ return 'default';
43
+ }
44
+ };
45
+
46
+ export default function <%= pascalName %>() {
47
+ return (
48
+ <div className="p-6">
49
+ {/* Page Header - pl-6 to align with table spacer */}
50
+ <div className="flex items-center justify-between mb-8 pl-6">
51
+ <div>
52
+ <h1 className="text-2xl font-bold text-foreground"><%= title %></h1>
53
+ <p className="text-muted-foreground"><%= description %></p>
54
+ </div>
55
+ <Button>
56
+ <Plus className="w-4 h-4 mr-2" />
57
+ Add New
58
+ </Button>
59
+ </div>
60
+
61
+ {/* Stats Row */}
62
+ <div className="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-8">
63
+ {/* Quick Stats */}
64
+ <Card padding="none">
65
+ <CardContent className="p-6">
66
+ <div className="text-center">
67
+ <p className="text-3xl font-bold text-foreground">{items.length}</p>
68
+ <p className="text-sm text-muted-foreground">Total Items</p>
69
+ </div>
70
+ </CardContent>
71
+ </Card>
72
+ <Card padding="none">
73
+ <CardContent className="p-6">
74
+ <div className="text-center">
75
+ <p className="text-3xl font-bold text-foreground">
76
+ {items.filter(i => i.status === 'active').length}
77
+ </p>
78
+ <p className="text-sm text-muted-foreground">Active</p>
79
+ </div>
80
+ </CardContent>
81
+ </Card>
82
+ <Card padding="none">
83
+ <CardContent className="p-6">
84
+ <div className="text-center">
85
+ <p className="text-3xl font-bold text-foreground">
86
+ {items.filter(i => i.status === 'pending').length}
87
+ </p>
88
+ <p className="text-sm text-muted-foreground">Pending</p>
89
+ </div>
90
+ </CardContent>
91
+ </Card>
92
+ {/* Distribution Chart */}
93
+ <Card padding="none">
94
+ <CardContent className="p-6">
95
+ <DonutChart
96
+ data={itemStats}
97
+ height={100}
98
+ showLegend={false}
99
+ centerValue={String(items.length)}
100
+ centerSubtext="Items"
101
+ />
102
+ </CardContent>
103
+ </Card>
104
+ </div>
105
+
106
+ {/* Filters - pl-6 to align with table spacer */}
107
+ <div className="flex items-center gap-4 mb-6 pl-6">
108
+ <div className="flex-1 max-w-md">
109
+ <div className="relative">
110
+ <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
111
+ <Input placeholder="Search..." className="pl-10" hideMessage />
112
+ </div>
113
+ </div>
114
+ <Select
115
+ options={[
116
+ { value: 'all', label: 'All Types' },
117
+ { value: 'type-a', label: 'Type A' },
118
+ { value: 'type-b', label: 'Type B' },
119
+ { value: 'type-c', label: 'Type C' },
120
+ ]}
121
+ placeholder="Filter by type"
122
+ hideMessage
123
+ />
124
+ <Button variant="outline">
125
+ <Filter className="w-4 h-4 mr-2" />
126
+ Filters
127
+ </Button>
128
+ </div>
129
+
130
+ {/* Table */}
131
+ <div>
132
+ <Card padding="none">
133
+ <CardHeader className="p-6">
134
+ <CardTitle>All Items</CardTitle>
135
+ </CardHeader>
136
+ <CardContent className="p-6">
137
+ <Table
138
+ data={items}
139
+ columns={[
140
+ {
141
+ key: 'name',
142
+ header: 'Name',
143
+ render: (item) => (
144
+ <div className="flex items-center gap-3">
145
+ <div className="w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center">
146
+ <FileText className="w-5 h-5 text-primary" />
147
+ </div>
148
+ <span className="font-medium text-foreground">{item.name}</span>
149
+ </div>
150
+ ),
151
+ },
152
+ {
153
+ key: 'type',
154
+ header: 'Type',
155
+ render: (item) => (
156
+ <Badge variant="info" size="sm">
157
+ {item.type}
158
+ </Badge>
159
+ ),
160
+ },
161
+ {
162
+ key: 'status',
163
+ header: 'Status',
164
+ render: (item) => (
165
+ <Badge variant={getStatusBadgeVariant(item.status)} size="sm">
166
+ {item.status}
167
+ </Badge>
168
+ ),
169
+ },
170
+ { key: 'date', header: 'Date' },
171
+ {
172
+ key: 'actions',
173
+ header: 'Actions',
174
+ align: 'right',
175
+ render: () => (
176
+ <button className="p-2 rounded-md hover:bg-muted transition-colors">
177
+ <MoreVertical className="w-4 h-4 text-muted-foreground" />
178
+ </button>
179
+ ),
180
+ },
181
+ ]}
182
+ striped={false}
183
+ inCard="full"
184
+ cardPadding="lg"
185
+ />
186
+ </CardContent>
187
+ </Card>
188
+ </div>
189
+ </div>
190
+ );
191
+ }
@@ -0,0 +1,163 @@
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, Shield, Palette } from 'lucide-react';
12
+ import { useState } from 'react';
13
+
14
+ export default function <%= pascalName %>() {
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"><%= title %></h1>
23
+ <p className="text-muted-foreground"><%= description %></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 for updates</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 weekly 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
+ <div>
112
+ <label className="block text-sm font-medium text-foreground mb-1">
113
+ Language
114
+ </label>
115
+ <Select
116
+ options={[
117
+ { value: 'en', label: 'English' },
118
+ { value: 'es', label: 'Spanish' },
119
+ { value: 'fr', label: 'French' },
120
+ ]}
121
+ value="en"
122
+ hideMessage
123
+ />
124
+ </div>
125
+ </CardContent>
126
+ </Card>
127
+
128
+ {/* Security Section */}
129
+ <Card padding="none">
130
+ <CardHeader className="p-6">
131
+ <CardTitle className="flex items-center gap-3">
132
+ <Shield className="w-5 h-5 text-muted-foreground" />
133
+ Security
134
+ </CardTitle>
135
+ </CardHeader>
136
+ <CardContent className="p-6 pt-0 space-y-4">
137
+ <div>
138
+ <label className="block text-sm font-medium text-foreground mb-1">
139
+ Current Password
140
+ </label>
141
+ <Input type="password" placeholder="Enter current password" hideMessage />
142
+ </div>
143
+ <div>
144
+ <label className="block text-sm font-medium text-foreground mb-1">
145
+ New Password
146
+ </label>
147
+ <Input type="password" placeholder="Enter new password" hideMessage />
148
+ </div>
149
+ <div>
150
+ <label className="block text-sm font-medium text-foreground mb-1">
151
+ Confirm New Password
152
+ </label>
153
+ <Input type="password" placeholder="Confirm new password" hideMessage />
154
+ </div>
155
+ <div className="pt-2">
156
+ <Button>Update Password</Button>
157
+ </div>
158
+ </CardContent>
159
+ </Card>
160
+ </div>
161
+ </div>
162
+ );
163
+ }
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@elsapiens/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI scaffolding tool for elSapiens SDK projects",
5
+ "type": "module",
6
+ "bin": {
7
+ "elsapiens": "./dist/index.js",
8
+ "el": "./dist/index.js"
9
+ },
10
+ "main": "./dist/index.js",
11
+ "exports": {
12
+ ".": "./dist/index.js"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "dependencies": {
18
+ "commander": "^12.0.0",
19
+ "@clack/prompts": "^0.7.0",
20
+ "ejs": "^3.1.9",
21
+ "fs-extra": "^11.2.0",
22
+ "picocolors": "^1.0.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/ejs": "^3.1.5",
26
+ "@types/fs-extra": "^11.0.4",
27
+ "@types/node": "^20.0.0",
28
+ "tsup": "^8.0.1",
29
+ "typescript": "^5.3.3"
30
+ },
31
+ "keywords": [
32
+ "elsapiens",
33
+ "cli",
34
+ "scaffolding",
35
+ "react",
36
+ "vite",
37
+ "typescript"
38
+ ],
39
+ "author": "elSapiens",
40
+ "license": "MIT",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/elsapiens/sdk.git",
44
+ "directory": "packages/cli"
45
+ },
46
+ "homepage": "https://github.com/elsapiens/sdk#readme",
47
+ "bugs": {
48
+ "url": "https://github.com/elsapiens/sdk/issues"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "engines": {
54
+ "node": ">=18.0.0"
55
+ },
56
+ "scripts": {
57
+ "build": "tsup",
58
+ "dev": "tsup --watch",
59
+ "clean": "rm -rf dist",
60
+ "typecheck": "tsc --noEmit"
61
+ }
62
+ }