create-flexireact 3.0.7 → 4.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.
- package/README.md +5 -4
- package/dist/templates/app-router.js +1 -1
- package/dist/templates/default.d.ts +5 -3
- package/dist/templates/default.d.ts.map +1 -1
- package/dist/templates/default.js +208 -168
- package/dist/templates/default.js.map +1 -1
- package/dist/templates/fullstack.d.ts +5 -0
- package/dist/templates/fullstack.d.ts.map +1 -0
- package/dist/templates/fullstack.js +606 -0
- package/dist/templates/fullstack.js.map +1 -0
- package/dist/templates/index.d.ts +4 -4
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +13 -8
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/minimal.d.ts +3 -1
- package/dist/templates/minimal.d.ts.map +1 -1
- package/dist/templates/minimal.js +42 -10
- package/dist/templates/minimal.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
export function fullstackTemplate(projectName, options = {}) {
|
|
2
|
+
const isTailwind = options.styling !== 'css'; // Default to Tailwind
|
|
3
|
+
return {
|
|
4
|
+
// ========================================================================
|
|
5
|
+
// Config Files
|
|
6
|
+
// ========================================================================
|
|
7
|
+
'package.json': JSON.stringify({
|
|
8
|
+
name: projectName,
|
|
9
|
+
version: '1.0.0',
|
|
10
|
+
private: true,
|
|
11
|
+
type: 'module',
|
|
12
|
+
scripts: {
|
|
13
|
+
dev: isTailwind ? 'npm run css && flexireact dev' : 'flexireact dev',
|
|
14
|
+
build: isTailwind ? 'npm run css && flexireact build' : 'flexireact build',
|
|
15
|
+
start: 'flexireact start',
|
|
16
|
+
...(isTailwind ? { css: 'tailwindcss -i ./app/styles/globals.css -o ./public/styles.css --minify' } : {}),
|
|
17
|
+
'db:generate': 'drizzle-kit generate',
|
|
18
|
+
'db:migrate': 'drizzle-kit migrate',
|
|
19
|
+
'db:studio': 'drizzle-kit studio',
|
|
20
|
+
},
|
|
21
|
+
dependencies: {
|
|
22
|
+
react: '^19.0.0',
|
|
23
|
+
'react-dom': '^19.0.0',
|
|
24
|
+
'@flexireact/core': '^4.1.0',
|
|
25
|
+
'@flexireact/flexiguard': '^1.0.0',
|
|
26
|
+
'drizzle-orm': '^0.30.0',
|
|
27
|
+
'better-sqlite3': '^9.4.0',
|
|
28
|
+
'lucide-react': '^0.344.0',
|
|
29
|
+
clsx: '^2.1.0',
|
|
30
|
+
'tailwind-merge': '^2.2.0',
|
|
31
|
+
},
|
|
32
|
+
devDependencies: {
|
|
33
|
+
'@types/react': '^19.0.0',
|
|
34
|
+
'@types/react-dom': '^19.0.0',
|
|
35
|
+
'@types/better-sqlite3': '^7.6.9',
|
|
36
|
+
typescript: '^5.3.0',
|
|
37
|
+
'drizzle-kit': '^0.20.14',
|
|
38
|
+
...(isTailwind ? {
|
|
39
|
+
tailwindcss: '^4.0.0',
|
|
40
|
+
'@tailwindcss/cli': '^4.0.0',
|
|
41
|
+
'@tailwindcss/postcss': '^4.0.0',
|
|
42
|
+
} : {}),
|
|
43
|
+
},
|
|
44
|
+
}, null, 2),
|
|
45
|
+
'tsconfig.json': JSON.stringify({
|
|
46
|
+
compilerOptions: {
|
|
47
|
+
target: 'ES2022',
|
|
48
|
+
lib: ['DOM', 'DOM.Iterable', 'ES2022'],
|
|
49
|
+
module: 'ESNext',
|
|
50
|
+
moduleResolution: 'bundler',
|
|
51
|
+
jsx: 'react-jsx',
|
|
52
|
+
strict: true,
|
|
53
|
+
skipLibCheck: true,
|
|
54
|
+
esModuleInterop: true,
|
|
55
|
+
resolveJsonModule: true,
|
|
56
|
+
isolatedModules: true,
|
|
57
|
+
noEmit: true,
|
|
58
|
+
baseUrl: '.',
|
|
59
|
+
paths: {
|
|
60
|
+
'@/*': ['./*'],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
include: ['**/*.ts', '**/*.tsx'],
|
|
64
|
+
exclude: ['node_modules', '.flexi', 'public'],
|
|
65
|
+
}, null, 2),
|
|
66
|
+
'drizzle.config.ts': `import type { Config } from 'drizzle-kit';
|
|
67
|
+
|
|
68
|
+
export default {
|
|
69
|
+
schema: './schema.ts',
|
|
70
|
+
out: './drizzle',
|
|
71
|
+
driver: 'better-sqlite',
|
|
72
|
+
dbCredentials: {
|
|
73
|
+
url: 'sqlite.db',
|
|
74
|
+
},
|
|
75
|
+
} satisfies Config;
|
|
76
|
+
`,
|
|
77
|
+
...(isTailwind ? {
|
|
78
|
+
'postcss.config.js': `export default {
|
|
79
|
+
plugins: {
|
|
80
|
+
"@tailwindcss/postcss": {},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
`,
|
|
84
|
+
} : {}),
|
|
85
|
+
'flexireact.config.js': `/** @type {import('@flexireact/core').FlexiConfig} */
|
|
86
|
+
const config = {
|
|
87
|
+
styles: [
|
|
88
|
+
'/styles.css',
|
|
89
|
+
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap'
|
|
90
|
+
],
|
|
91
|
+
server: {
|
|
92
|
+
port: 3000,
|
|
93
|
+
},
|
|
94
|
+
islands: { enabled: true },
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export default config;
|
|
98
|
+
`,
|
|
99
|
+
// ========================================================================
|
|
100
|
+
// Database & Auth
|
|
101
|
+
// ========================================================================
|
|
102
|
+
'schema.ts': `import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
|
|
103
|
+
|
|
104
|
+
export const users = sqliteTable('users', {
|
|
105
|
+
id: text('id').primaryKey(),
|
|
106
|
+
email: text('email').notNull().unique(),
|
|
107
|
+
passwordHash: text('password_hash').notNull(),
|
|
108
|
+
name: text('name'),
|
|
109
|
+
avatar: text('avatar'),
|
|
110
|
+
role: text('role').default('user'),
|
|
111
|
+
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().default(new Date()),
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
export const sessions = sqliteTable('sessions', {
|
|
115
|
+
id: text('id').primaryKey(),
|
|
116
|
+
userId: text('user_id').notNull().references(() => users.id),
|
|
117
|
+
token: text('token').notNull().unique(),
|
|
118
|
+
expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
export const items = sqliteTable('items', {
|
|
122
|
+
id: text('id').primaryKey(), // We'll manage IDs in app or use default random
|
|
123
|
+
userId: text('user_id').notNull().references(() => users.id),
|
|
124
|
+
content: text('content').notNull(),
|
|
125
|
+
completed: integer('completed', { mode: 'boolean' }).default(false),
|
|
126
|
+
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().default(new Date()),
|
|
127
|
+
});
|
|
128
|
+
`,
|
|
129
|
+
'lib/db.ts': `import { drizzle } from 'drizzle-orm/better-sqlite3';
|
|
130
|
+
import Database from 'better-sqlite3';
|
|
131
|
+
import * as schema from '../schema';
|
|
132
|
+
|
|
133
|
+
const sqlite = new Database('sqlite.db');
|
|
134
|
+
export const db = drizzle(sqlite, { schema });
|
|
135
|
+
`,
|
|
136
|
+
'lib/auth.ts': `import { createAuth } from '@flexireact/flexiguard';
|
|
137
|
+
import { DrizzleAdapter } from '@flexireact/flexiguard/adapters/drizzle';
|
|
138
|
+
import { db } from './db';
|
|
139
|
+
import * as schema from '../schema';
|
|
140
|
+
|
|
141
|
+
export const auth = createAuth({
|
|
142
|
+
adapter: DrizzleAdapter({ db, schema }),
|
|
143
|
+
session: {
|
|
144
|
+
strategy: 'database',
|
|
145
|
+
maxAge: 30 * 24 * 60 * 60, // 30 days
|
|
146
|
+
},
|
|
147
|
+
password: {
|
|
148
|
+
minLength: 8,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
`,
|
|
152
|
+
// ========================================================================
|
|
153
|
+
// App Structure
|
|
154
|
+
// ========================================================================
|
|
155
|
+
'app/layout.tsx': `import React from 'react';
|
|
156
|
+
import { Navbar } from './components/layout/Navbar';
|
|
157
|
+
import { Footer } from './components/layout/Footer';
|
|
158
|
+
|
|
159
|
+
interface RootLayoutProps {
|
|
160
|
+
children: React.ReactNode;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export default function RootLayout({ children }: RootLayoutProps) {
|
|
164
|
+
return (
|
|
165
|
+
<html lang="en" className="dark">
|
|
166
|
+
<head>
|
|
167
|
+
<meta charSet="UTF-8" />
|
|
168
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
169
|
+
<link rel="stylesheet" href="/styles.css" />
|
|
170
|
+
</head>
|
|
171
|
+
<body className="${isTailwind ? 'bg-background text-foreground min-h-screen antialiased flex flex-col' : 'app-body'}">
|
|
172
|
+
<Navbar />
|
|
173
|
+
<main className="${isTailwind ? 'flex-1' : 'main-content'}">{children}</main>
|
|
174
|
+
<Footer />
|
|
175
|
+
</body>
|
|
176
|
+
</html>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
`,
|
|
180
|
+
// ========================================================================
|
|
181
|
+
// Routes
|
|
182
|
+
// ========================================================================
|
|
183
|
+
'routes/(public)/home.tsx': `import React from 'react';
|
|
184
|
+
import { Button } from '@/app/components/ui/Button';
|
|
185
|
+
import { Shield, Database, Zap } from 'lucide-react';
|
|
186
|
+
|
|
187
|
+
export const metadata = {
|
|
188
|
+
title: 'FlexiStack - Production Ready Starter',
|
|
189
|
+
description: 'Fullstack React framework with Auth, Database, and API routes.',
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export default function HomePage() {
|
|
193
|
+
return (
|
|
194
|
+
<div className="${isTailwind ? 'flex flex-col items-center justify-center min-h-[calc(100vh-8rem)] px-4 py-16' : 'home-page'}">
|
|
195
|
+
<div className="${isTailwind ? 'max-w-4xl mx-auto text-center space-y-8' : 'container'}">
|
|
196
|
+
<div className="${isTailwind ? 'inline-flex items-center gap-2 px-3 py-1 rounded-full bg-primary/10 border border-primary/20 text-primary text-sm font-medium' : 'badge'}">
|
|
197
|
+
<span>🚀 Production Ready</span>
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<h1 className="${isTailwind ? 'text-5xl md:text-7xl font-bold tracking-tight' : 'page-title'}">
|
|
201
|
+
Build faster with
|
|
202
|
+
<br />
|
|
203
|
+
<span className="${isTailwind ? 'text-primary' : 'highlight'}">FlexiStack</span>
|
|
204
|
+
</h1>
|
|
205
|
+
|
|
206
|
+
<p className="${isTailwind ? 'text-xl text-muted-foreground max-w-2xl mx-auto' : 'subtitle'}">
|
|
207
|
+
The ultimate starter with FlexiReact v4, FlexiGuard Auth, Drizzle ORM, and CRUD API examples.
|
|
208
|
+
</p>
|
|
209
|
+
|
|
210
|
+
<div className="${isTailwind ? 'flex gap-4 justify-center pt-4' : 'actions'}">
|
|
211
|
+
<Button size="lg" href="/login">Get Started</Button>
|
|
212
|
+
<Button variant="outline" size="lg" href="/dashboard">View Dashboard</Button>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<div className="${isTailwind ? 'grid grid-cols-1 md:grid-cols-3 gap-8 pt-16 text-left' : 'features-grid'}">
|
|
216
|
+
<Feature
|
|
217
|
+
icon={<Shield className="w-6 h-6 text-primary" />}
|
|
218
|
+
title="Authentication"
|
|
219
|
+
desc="Secure auth powered by FlexiGuard. Login, register, and session management ready to go."
|
|
220
|
+
/>
|
|
221
|
+
<Feature
|
|
222
|
+
icon={<Database className="w-6 h-6 text-primary" />}
|
|
223
|
+
title="Database"
|
|
224
|
+
desc="Drizzle ORM with SQLite. Type-safe database queries, schemas, and migrations."
|
|
225
|
+
/>
|
|
226
|
+
<Feature
|
|
227
|
+
icon={<Zap className="w-6 h-6 text-primary" />}
|
|
228
|
+
title="API Routes"
|
|
229
|
+
desc="Integrated API routes with CRUD operations. Build your backend alongside your UI."
|
|
230
|
+
/>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function Feature({ icon, title, desc }: any) {
|
|
238
|
+
return (
|
|
239
|
+
<div className="${isTailwind ? 'p-6 rounded-xl border border-border bg-card' : 'feature-card'}">
|
|
240
|
+
<div className="${isTailwind ? 'mb-4' : 'feature-icon'}">{icon}</div>
|
|
241
|
+
<h3 className="${isTailwind ? 'text-lg font-semibold mb-2' : 'feature-title'}">{title}</h3>
|
|
242
|
+
<p className="${isTailwind ? 'text-muted-foreground' : 'feature-desc'}">{desc}</p>
|
|
243
|
+
</div>
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
`,
|
|
247
|
+
'routes/(auth)/login.tsx': `import React from 'react';
|
|
248
|
+
import { Button } from '@/app/components/ui/Button';
|
|
249
|
+
|
|
250
|
+
export const metadata = {
|
|
251
|
+
title: 'Login - FlexiStack',
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
export default function LoginPage() {
|
|
255
|
+
return (
|
|
256
|
+
<div className="${isTailwind ? 'flex items-center justify-center min-h-[calc(100vh-16rem)]' : 'auth-page'}">
|
|
257
|
+
<div className="${isTailwind ? 'w-full max-w-md p-8 rounded-xl border border-border bg-card' : 'auth-card'}">
|
|
258
|
+
<h1 className="${isTailwind ? 'text-2xl font-bold mb-6 text-center' : 'auth-title'}">Welcome Back</h1>
|
|
259
|
+
<form className="space-y-4" action="/api/auth/login" method="POST">
|
|
260
|
+
<div>
|
|
261
|
+
<label className="${isTailwind ? 'block text-sm font-medium mb-1' : 'label'}">Email</label>
|
|
262
|
+
<input
|
|
263
|
+
type="email"
|
|
264
|
+
name="email"
|
|
265
|
+
className="${isTailwind ? 'w-full px-3 py-2 rounded-lg bg-background border border-border focus:ring-2 focus:ring-primary/50 outline-none' : 'input'}"
|
|
266
|
+
placeholder="john@example.com"
|
|
267
|
+
required
|
|
268
|
+
/>
|
|
269
|
+
</div>
|
|
270
|
+
<div>
|
|
271
|
+
<label className="${isTailwind ? 'block text-sm font-medium mb-1' : 'label'}">Password</label>
|
|
272
|
+
<input
|
|
273
|
+
type="password"
|
|
274
|
+
name="password"
|
|
275
|
+
className="${isTailwind ? 'w-full px-3 py-2 rounded-lg bg-background border border-border focus:ring-2 focus:ring-primary/50 outline-none' : 'input'}"
|
|
276
|
+
placeholder="••••••••"
|
|
277
|
+
required
|
|
278
|
+
/>
|
|
279
|
+
</div>
|
|
280
|
+
<Button type="submit" className="w-full">Sign In</Button>
|
|
281
|
+
</form>
|
|
282
|
+
<p className="${isTailwind ? 'mt-4 text-center text-sm text-muted-foreground' : 'auth-footer'}">
|
|
283
|
+
Don't have an account? <a href="/register" className="text-primary hover:underline">Sign up</a>
|
|
284
|
+
</p>
|
|
285
|
+
</div>
|
|
286
|
+
</div>
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
`,
|
|
290
|
+
'routes/(app)/dashboard.tsx': `import React from 'react';
|
|
291
|
+
import { Button } from '@/app/components/ui/Button';
|
|
292
|
+
|
|
293
|
+
// Mock data fetch - in real implementation this uses internal API or DB call
|
|
294
|
+
async function getItems() {
|
|
295
|
+
// In a real SSR environment, you would call your DB here directly
|
|
296
|
+
// const items = await db.select().from(schema.items).where(...)
|
|
297
|
+
return [
|
|
298
|
+
{ id: '1', content: 'Review pull requests', completed: true },
|
|
299
|
+
{ id: '2', content: 'Update documentation', completed: false },
|
|
300
|
+
{ id: '3', content: 'Launch v4.0', completed: false },
|
|
301
|
+
];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export const metadata = {
|
|
305
|
+
title: 'Dashboard - FlexiStack',
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
export default async function DashboardPage() {
|
|
309
|
+
// const session = await auth.getSession();
|
|
310
|
+
// if (!session) return redirect('/login');
|
|
311
|
+
|
|
312
|
+
const user = { name: 'Demo User', email: 'demo@example.com' };
|
|
313
|
+
const items = await getItems();
|
|
314
|
+
|
|
315
|
+
return (
|
|
316
|
+
<div className="${isTailwind ? 'container mx-auto px-4 py-8' : 'dashboard-page'}">
|
|
317
|
+
<div className="${isTailwind ? 'flex items-center justify-between mb-8' : 'dashboard-header'}">
|
|
318
|
+
<div>
|
|
319
|
+
<h1 className="text-3xl font-bold">Dashboard</h1>
|
|
320
|
+
<p className="text-muted-foreground">Welcome back, {user.name}</p>
|
|
321
|
+
</div>
|
|
322
|
+
<form action="/api/auth/logout" method="POST">
|
|
323
|
+
<Button variant="outline">Sign Out</Button>
|
|
324
|
+
</form>
|
|
325
|
+
</div>
|
|
326
|
+
|
|
327
|
+
<div className="${isTailwind ? 'grid grid-cols-1 lg:grid-cols-3 gap-8' : 'dashboard-grid'}">
|
|
328
|
+
{/* Profile Card */}
|
|
329
|
+
<div className="${isTailwind ? 'p-6 rounded-xl border border-border bg-card h-fit' : 'dashboard-card'}">
|
|
330
|
+
<h2 className="text-xl font-semibold mb-4">Profile</h2>
|
|
331
|
+
<div className="space-y-4">
|
|
332
|
+
<div className="flex items-center gap-4">
|
|
333
|
+
<div className="w-12 h-12 rounded-full bg-primary/20 flex items-center justify-center text-primary font-bold text-xl">
|
|
334
|
+
{user.name.charAt(0)}
|
|
335
|
+
</div>
|
|
336
|
+
<div>
|
|
337
|
+
<div className="font-medium">{user.name}</div>
|
|
338
|
+
<div className="text-sm text-muted-foreground">{user.email}</div>
|
|
339
|
+
</div>
|
|
340
|
+
</div>
|
|
341
|
+
<div className="pt-4 border-t border-border">
|
|
342
|
+
<div className="text-sm text-muted-foreground mb-1">Role</div>
|
|
343
|
+
<div className="inline-flex items-center px-2 py-1 rounded bg-primary/10 text-primary text-xs font-medium">
|
|
344
|
+
Admin
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
349
|
+
|
|
350
|
+
{/* Todo List / Items (CRUD Example) */}
|
|
351
|
+
<div className="${isTailwind ? 'col-span-1 lg:col-span-2 p-6 rounded-xl border border-border bg-card' : 'dashboard-card'}">
|
|
352
|
+
<div className="flex items-center justify-between mb-6">
|
|
353
|
+
<h2 className="text-xl font-semibold">Your Tasks</h2>
|
|
354
|
+
<form action="/api/items" method="POST" className="flex gap-2">
|
|
355
|
+
<input
|
|
356
|
+
type="text"
|
|
357
|
+
name="content"
|
|
358
|
+
placeholder="New task..."
|
|
359
|
+
className="${isTailwind ? 'px-3 py-1.5 rounded-lg bg-background border border-border text-sm focus:ring-1 focus:ring-primary outline-none' : 'input'}"
|
|
360
|
+
required
|
|
361
|
+
/>
|
|
362
|
+
<Button size="sm">Add</Button>
|
|
363
|
+
</form>
|
|
364
|
+
</div>
|
|
365
|
+
|
|
366
|
+
<div className="space-y-2">
|
|
367
|
+
{items.length > 0 ? (
|
|
368
|
+
items.map((item) => (
|
|
369
|
+
<div key={item.id} className="${isTailwind ? 'flex items-center justify-between p-3 rounded-lg border border-border bg-background/50 hover:bg-background transition-colors' : 'list-item'}">
|
|
370
|
+
<div className="flex items-center gap-3">
|
|
371
|
+
<form action={\`/api/items/\${item.id}/toggle\`} method="POST">
|
|
372
|
+
<button className={\`w-5 h-5 rounded border flex items-center justify-center transition-colors \${item.completed ? 'bg-primary border-primary text-black' : 'border-muted-foreground'}\`}>
|
|
373
|
+
{item.completed && '✓'}
|
|
374
|
+
</button>
|
|
375
|
+
</form>
|
|
376
|
+
<span className={item.completed ? 'line-through text-muted-foreground' : ''}>
|
|
377
|
+
{item.content}
|
|
378
|
+
</span>
|
|
379
|
+
</div>
|
|
380
|
+
<form action={\`/api/items/\${item.id}/delete\`} method="POST">
|
|
381
|
+
<button className="text-muted-foreground hover:text-red-500 transition-colors">
|
|
382
|
+
<TrashIcon />
|
|
383
|
+
</button>
|
|
384
|
+
</form>
|
|
385
|
+
</div>
|
|
386
|
+
))
|
|
387
|
+
) : (
|
|
388
|
+
<p className="text-muted-foreground text-center py-8">No tasks yet.</p>
|
|
389
|
+
)}
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
</div>
|
|
393
|
+
</div>
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function TrashIcon() {
|
|
398
|
+
return (
|
|
399
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
400
|
+
<path d="M3 6h18M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2" />
|
|
401
|
+
</svg>
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
`,
|
|
405
|
+
// API Routes
|
|
406
|
+
'routes/api/items/index.ts': `import { db } from '@/lib/db';
|
|
407
|
+
import { items } from '@/schema';
|
|
408
|
+
// import { getSession } from '@/lib/auth';
|
|
409
|
+
|
|
410
|
+
export async function POST(req: Request) {
|
|
411
|
+
// const session = await getSession(req);
|
|
412
|
+
// if (!session) return new Response('Unauthorized', { status: 401 });
|
|
413
|
+
|
|
414
|
+
const formData = await req.formData();
|
|
415
|
+
const content = formData.get('content') as string;
|
|
416
|
+
const userId = 'demo-user-id'; // session.user.id
|
|
417
|
+
|
|
418
|
+
if (!content) return new Response('Content required', { status: 400 });
|
|
419
|
+
|
|
420
|
+
await db.insert(items).values({
|
|
421
|
+
id: crypto.randomUUID(),
|
|
422
|
+
userId,
|
|
423
|
+
content,
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// Redirect back to dashboard to refresh
|
|
427
|
+
return new Response(null, { status: 302, headers: { Location: '/dashboard' } });
|
|
428
|
+
}
|
|
429
|
+
`,
|
|
430
|
+
'routes/api/items/[id]/toggle.ts': `import { db } from '@/lib/db';
|
|
431
|
+
import { items } from '@/schema';
|
|
432
|
+
import { eq } from 'drizzle-orm';
|
|
433
|
+
|
|
434
|
+
export async function POST(req: Request, { params }: { params: { id: string } }) {
|
|
435
|
+
// In real app, check user ID match
|
|
436
|
+
const item = await db.select().from(items).where(eq(items.id, params.id)).get();
|
|
437
|
+
|
|
438
|
+
if (item) {
|
|
439
|
+
await db.update(items)
|
|
440
|
+
.set({ completed: !item.completed })
|
|
441
|
+
.where(eq(items.id, params.id));
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return new Response(null, { status: 302, headers: { Location: '/dashboard' } });
|
|
445
|
+
}
|
|
446
|
+
`,
|
|
447
|
+
'routes/api/items/[id]/delete.ts': `import { db } from '@/lib/db';
|
|
448
|
+
import { items } from '@/schema';
|
|
449
|
+
import { eq } from 'drizzle-orm';
|
|
450
|
+
|
|
451
|
+
export async function POST(req: Request, { params }: { params: { id: string } }) {
|
|
452
|
+
await db.delete(items).where(eq(items.id, params.id));
|
|
453
|
+
return new Response(null, { status: 302, headers: { Location: '/dashboard' } });
|
|
454
|
+
}
|
|
455
|
+
`,
|
|
456
|
+
// ========================================================================
|
|
457
|
+
// Components
|
|
458
|
+
// ========================================================================
|
|
459
|
+
'app/components/ui/Button.tsx': `import React from 'react';
|
|
460
|
+
import { cn } from '@/lib/utils'; // Keep utility usage, fallback implementation below if not tailwind
|
|
461
|
+
|
|
462
|
+
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
463
|
+
variant?: 'primary' | 'secondary' | 'outline' | 'ghost';
|
|
464
|
+
size?: 'sm' | 'md' | 'lg';
|
|
465
|
+
href?: string;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export function Button({
|
|
469
|
+
className,
|
|
470
|
+
variant = 'primary',
|
|
471
|
+
size = 'md',
|
|
472
|
+
href,
|
|
473
|
+
children,
|
|
474
|
+
...props
|
|
475
|
+
}: ButtonProps) {
|
|
476
|
+
const baseStyles = ${isTailwind
|
|
477
|
+
? "'inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none'"
|
|
478
|
+
: "'btn'"};
|
|
479
|
+
|
|
480
|
+
const variants = {
|
|
481
|
+
primary: ${isTailwind ? "'bg-primary text-black hover:bg-primary/90 focus:ring-primary'" : "'btn-primary'"},
|
|
482
|
+
secondary: ${isTailwind ? "'bg-secondary text-secondary-foreground hover:bg-secondary/80'" : "'btn-secondary'"},
|
|
483
|
+
outline: ${isTailwind ? "'border border-input hover:bg-accent hover:text-accent-foreground'" : "'btn-outline'"},
|
|
484
|
+
ghost: ${isTailwind ? "'hover:bg-accent hover:text-accent-foreground'" : "'btn-ghost'"},
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
const sizes = {
|
|
488
|
+
sm: ${isTailwind ? "'h-9 px-3 text-sm'" : "'btn-sm'"},
|
|
489
|
+
md: ${isTailwind ? "'h-10 px-4 py-2'" : "'btn-md'"},
|
|
490
|
+
lg: ${isTailwind ? "'h-11 px-8 text-lg'" : "'btn-lg'"},
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
const classes = cn(
|
|
494
|
+
baseStyles,
|
|
495
|
+
variants[variant],
|
|
496
|
+
sizes[size],
|
|
497
|
+
className
|
|
498
|
+
);
|
|
499
|
+
|
|
500
|
+
if (href) {
|
|
501
|
+
return <a href={href} className={classes}>{children}</a>;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return (
|
|
505
|
+
<button className={classes} {...props}>
|
|
506
|
+
{children}
|
|
507
|
+
</button>
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
`,
|
|
511
|
+
'app/components/layout/Navbar.tsx': `import React from 'react';
|
|
512
|
+
import { Zap } from 'lucide-react';
|
|
513
|
+
|
|
514
|
+
export function Navbar() {
|
|
515
|
+
return (
|
|
516
|
+
<nav className="${isTailwind ? 'border-b border-border bg-background' : 'navbar'}">
|
|
517
|
+
<div className="${isTailwind ? 'container mx-auto px-4 h-16 flex items-center justify-between' : 'navbar-container'}">
|
|
518
|
+
<a href="/" className="${isTailwind ? 'flex items-center gap-2 font-bold text-xl' : 'navbar-brand'}">
|
|
519
|
+
<Zap className="text-primary" />
|
|
520
|
+
<span>FlexiStack</span>
|
|
521
|
+
</a>
|
|
522
|
+
<div className="${isTailwind ? 'flex items-center gap-6' : 'navbar-links'}">
|
|
523
|
+
<a href="/login" className="${isTailwind ? 'text-sm font-medium hover:text-primary transition-colors' : 'nav-link'}">Login</a>
|
|
524
|
+
<a href="/register" className="${isTailwind ? 'text-sm font-medium hover:text-primary transition-colors' : 'nav-link'}">Register</a>
|
|
525
|
+
</div>
|
|
526
|
+
</div>
|
|
527
|
+
</nav>
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
`,
|
|
531
|
+
'app/components/layout/Footer.tsx': `import React from 'react';
|
|
532
|
+
|
|
533
|
+
export function Footer() {
|
|
534
|
+
return (
|
|
535
|
+
<footer className="${isTailwind ? 'border-t border-border py-8 text-center text-sm text-muted-foreground' : 'footer'}">
|
|
536
|
+
<p>© {new Date().getFullYear()} FlexiStack. Built with FlexiReact v4.</p>
|
|
537
|
+
</footer>
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
`,
|
|
541
|
+
// ========================================================================
|
|
542
|
+
// Styles & Utils
|
|
543
|
+
// ========================================================================
|
|
544
|
+
'app/styles/globals.css': isTailwind ? `@import "tailwindcss";
|
|
545
|
+
|
|
546
|
+
@theme {
|
|
547
|
+
--color-background: #0a0a0a;
|
|
548
|
+
--color-foreground: #ffffff;
|
|
549
|
+
--color-primary: #00FF9C;
|
|
550
|
+
--color-primary-foreground: #000000;
|
|
551
|
+
--color-secondary: #27272a;
|
|
552
|
+
--color-secondary-foreground: #ffffff;
|
|
553
|
+
--color-muted: #27272a;
|
|
554
|
+
--color-muted-foreground: #a1a1aa;
|
|
555
|
+
--color-accent: #27272a;
|
|
556
|
+
--color-accent-foreground: #ffffff;
|
|
557
|
+
--color-border: #27272a;
|
|
558
|
+
--color-input: #27272a;
|
|
559
|
+
--color-card: #18181b;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
body {
|
|
563
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
564
|
+
background-color: var(--color-background);
|
|
565
|
+
color: var(--color-foreground);
|
|
566
|
+
}
|
|
567
|
+
` : `/* Modern CSS Variables */
|
|
568
|
+
:root {
|
|
569
|
+
--bg-color: #0a0a0a;
|
|
570
|
+
--text-color: #ffffff;
|
|
571
|
+
--primary-color: #00FF9C;
|
|
572
|
+
--border-color: #333;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
body {
|
|
576
|
+
background: var(--bg-color);
|
|
577
|
+
color: var(--text-color);
|
|
578
|
+
margin: 0;
|
|
579
|
+
font-family: system-ui, sans-serif;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.container { max-width: 1200px; margin: 0 auto; padding: 0 20px; }
|
|
583
|
+
.btn { display: inline-flex; padding: 10px 20px; border-radius: 6px; font-weight: 600; text-decoration: none; cursor: pointer; border: none; }
|
|
584
|
+
.btn-primary { background: var(--primary-color); color: #000; }
|
|
585
|
+
.btn-outline { border: 1px solid var(--border-color); color: white; background: transparent; }
|
|
586
|
+
.home-page { text-align: center; padding: 80px 20px; }
|
|
587
|
+
.page-title { font-size: 4rem; line-height: 1.1; margin-bottom: 20px; }
|
|
588
|
+
.highlight { color: var(--primary-color); }
|
|
589
|
+
.features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin-top: 60px; }
|
|
590
|
+
.feature-card { padding: 20px; border: 1px solid var(--border-color); border-radius: 10px; background: #111; }
|
|
591
|
+
.navbar { border-bottom: 1px solid var(--border-color); padding: 15px 0; }
|
|
592
|
+
.navbar-container { display: flex; justify-content: space-between; align-items: center; max-width: 1200px; margin: 0 auto; padding: 0 20px; }
|
|
593
|
+
.navbar-brand { display: flex; align-items: center; gap: 10px; font-weight: bold; font-size: 1.2rem; color: white; text-decoration: none; }
|
|
594
|
+
.nav-link { color: #888; text-decoration: none; font-weight: 500; }
|
|
595
|
+
.nav-link:hover { color: var(--primary-color); }
|
|
596
|
+
`,
|
|
597
|
+
'lib/utils.ts': `import { clsx, type ClassValue } from 'clsx';
|
|
598
|
+
import { twMerge } from 'tailwind-merge';
|
|
599
|
+
|
|
600
|
+
export function cn(...inputs: ClassValue[]) {
|
|
601
|
+
return twMerge(clsx(inputs));
|
|
602
|
+
}
|
|
603
|
+
`,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
//# sourceMappingURL=fullstack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fullstack.js","sourceRoot":"","sources":["../../src/templates/fullstack.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Template definitions for create-flexireact
|
|
3
|
-
*/
|
|
4
1
|
export interface Template {
|
|
5
2
|
name: string;
|
|
6
3
|
description: string;
|
|
@@ -8,5 +5,8 @@ export interface Template {
|
|
|
8
5
|
}
|
|
9
6
|
export declare const TEMPLATES: Record<string, Template>;
|
|
10
7
|
export type TemplateFiles = Record<string, string>;
|
|
11
|
-
export
|
|
8
|
+
export interface TemplateOptions {
|
|
9
|
+
styling?: 'tailwind' | 'css';
|
|
10
|
+
}
|
|
11
|
+
export declare function getTemplateFiles(templateKey: string, projectName: string, options?: TemplateOptions): TemplateFiles;
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAqB9C,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC;CAC9B;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,aAAa,CAWvH"}
|