@asynx/create-asynx-next-app 1.0.3 → 1.0.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.
Files changed (76) hide show
  1. package/CONTRIBUTING.md +16 -15
  2. package/README.md +3 -3
  3. package/create-asynx-next-app-wrapper/index.js +3 -0
  4. package/create-asynx-next-app-wrapper/package.json +12 -0
  5. package/dist/cli.js +6 -6
  6. package/dist/constants/template.js +5 -5
  7. package/package.json +2 -2
  8. package/src/cli.ts +6 -6
  9. package/src/constants/template.ts +6 -6
  10. package/templates/advanced/.env.example +23 -0
  11. package/templates/advanced/README.md +148 -0
  12. package/templates/advanced/next.config.mjs +14 -0
  13. package/templates/{simple → advanced}/package.json +4 -0
  14. package/templates/advanced/postcss.config.mjs +6 -0
  15. package/templates/advanced/src/app/app/billing/page.tsx +57 -0
  16. package/templates/advanced/src/app/app/layout.tsx +25 -0
  17. package/templates/advanced/src/app/app/page.tsx +36 -0
  18. package/templates/advanced/src/app/app/settings/page.tsx +50 -0
  19. package/templates/advanced/src/app/auth/login/page.tsx +41 -0
  20. package/templates/advanced/src/app/auth/signup/page.tsx +45 -0
  21. package/templates/advanced/src/app/globals.css +151 -0
  22. package/templates/advanced/src/app/layout.tsx +19 -0
  23. package/templates/advanced/src/app/page.tsx +25 -0
  24. package/templates/advanced/src/lib/api/client.ts +67 -0
  25. package/templates/advanced/src/lib/api/config/app.ts +19 -0
  26. package/templates/advanced/src/lib/api/config/constants.ts +38 -0
  27. package/templates/advanced/src/lib/api/features/analytics/lib/analytics-service.ts +26 -0
  28. package/templates/advanced/src/lib/api/features/app-shell/components/app-header.tsx +18 -0
  29. package/templates/advanced/src/lib/api/features/app-shell/components/app-sidebar.tsx +38 -0
  30. package/templates/advanced/src/lib/api/features/auth/lib/auth-service.ts +36 -0
  31. package/templates/advanced/src/lib/api/features/billing/lib/billing-service.ts +38 -0
  32. package/templates/advanced/src/types/index.ts +21 -0
  33. package/templates/advanced/tsconfig.json +29 -0
  34. package/templates/standard/README.md +53 -0
  35. package/templates/{moderate → standard}/package.json +4 -0
  36. package/templates/standard/postcss.config.mjs +6 -0
  37. package/templates/standard/src/app/(dashboard)/dashboard/page.tsx +45 -0
  38. package/templates/standard/src/app/(dashboard)/layout.tsx +30 -0
  39. package/templates/standard/src/app/(public)/layout.tsx +16 -0
  40. package/templates/standard/src/app/(public)/login/page.tsx +33 -0
  41. package/templates/standard/src/app/globals.css +158 -0
  42. package/templates/standard/src/app/layout.tsx +38 -0
  43. package/templates/standard/src/app/page.tsx +27 -0
  44. package/templates/standard/src/lib/api.ts +37 -0
  45. package/templates/standard/src/lib/constants.ts +14 -0
  46. package/templates/{simple → standard}/tsconfig.json +12 -5
  47. package/templates/{saas → starter}/package.json +4 -0
  48. package/templates/{saas → starter}/src/app/globals.css +1 -0
  49. package/templates/{moderate → starter}/tsconfig.json +10 -4
  50. package/templates/moderate/src/app/globals.css +0 -8
  51. package/templates/saas/src/app/layout.tsx +0 -18
  52. package/templates/saas/src/app/page.tsx +0 -8
  53. package/templates/saas/tsconfig.json +0 -20
  54. package/templates/simple/next-env.d.ts +0 -4
  55. package/templates/simple/src/app/globals.css +0 -8
  56. package/templates/simple/src/app/layout.tsx +0 -18
  57. package/templates/simple/src/app/page.tsx +0 -8
  58. /package/templates/{moderate → advanced}/utils/async.ts +0 -0
  59. /package/templates/{moderate → advanced}/utils/date.ts +0 -0
  60. /package/templates/{moderate → advanced}/utils/index.ts +0 -0
  61. /package/templates/{moderate → advanced}/utils/number.ts +0 -0
  62. /package/templates/{moderate → advanced}/utils/string.ts +0 -0
  63. /package/templates/{moderate → standard}/next-env.d.ts +0 -0
  64. /package/templates/{saas → standard}/utils/async.ts +0 -0
  65. /package/templates/{saas → standard}/utils/date.ts +0 -0
  66. /package/templates/{saas → standard}/utils/index.ts +0 -0
  67. /package/templates/{saas → standard}/utils/number.ts +0 -0
  68. /package/templates/{saas → standard}/utils/string.ts +0 -0
  69. /package/templates/{saas → starter}/next-env.d.ts +0 -0
  70. /package/templates/{moderate → starter}/src/app/layout.tsx +0 -0
  71. /package/templates/{moderate → starter}/src/app/page.tsx +0 -0
  72. /package/templates/{simple → starter}/utils/async.ts +0 -0
  73. /package/templates/{simple → starter}/utils/date.ts +0 -0
  74. /package/templates/{simple → starter}/utils/index.ts +0 -0
  75. /package/templates/{simple → starter}/utils/number.ts +0 -0
  76. /package/templates/{simple → starter}/utils/string.ts +0 -0
@@ -0,0 +1,45 @@
1
+ // Auth feature - signup page
2
+
3
+ export default function SignupPage() {
4
+ return (
5
+ <main className="min-h-screen flex items-center justify-center p-6">
6
+ <div className="w-full max-w-md">
7
+ <h1 className="text-3xl font-bold mb-2 text-center">Create Account</h1>
8
+ <p className="text-muted-foreground text-center mb-8">Get started with your free account</p>
9
+
10
+ <div className="border rounded-lg p-8">
11
+ <form className="space-y-6">
12
+ <div>
13
+ <label className="block text-sm font-medium mb-2">Full Name</label>
14
+ <input type="text" className="w-full px-4 py-2 border rounded-md" placeholder="John Doe" />
15
+ </div>
16
+
17
+ <div>
18
+ <label className="block text-sm font-medium mb-2">Email Address</label>
19
+ <input type="email" className="w-full px-4 py-2 border rounded-md" placeholder="you@example.com" />
20
+ </div>
21
+
22
+ <div>
23
+ <label className="block text-sm font-medium mb-2">Password</label>
24
+ <input type="password" className="w-full px-4 py-2 border rounded-md" placeholder="••••••••" />
25
+ </div>
26
+
27
+ <button
28
+ type="submit"
29
+ className="w-full bg-foreground text-background py-3 rounded-md hover:opacity-90 font-medium"
30
+ >
31
+ Create Account
32
+ </button>
33
+ </form>
34
+
35
+ <p className="text-center text-sm text-muted-foreground mt-6">
36
+ Already have an account?{" "}
37
+ <a href="/auth/login" className="underline">
38
+ Sign in
39
+ </a>
40
+ </p>
41
+ </div>
42
+ </div>
43
+ </main>
44
+ )
45
+ }
@@ -0,0 +1,151 @@
1
+ @import "tailwindcss";
2
+ @import "tw-animate-css";
3
+
4
+ @custom-variant dark (&:is(.dark *));
5
+
6
+ :root {
7
+ --background: 0 0% 100%;
8
+ --foreground: 0 0% 3.9%;
9
+ --card: oklch(1 0 0);
10
+ --card-foreground: oklch(0.145 0 0);
11
+ --popover: oklch(1 0 0);
12
+ --popover-foreground: oklch(0.145 0 0);
13
+ --primary: 221.2 83.2% 53.3%;
14
+ --primary-foreground: 0 0% 100%;
15
+ --secondary: oklch(0.97 0 0);
16
+ --secondary-foreground: oklch(0.205 0 0);
17
+ --muted: 0 0% 96.1%;
18
+ --muted-foreground: 0 0% 45.1%;
19
+ --accent: oklch(0.97 0 0);
20
+ --accent-foreground: oklch(0.205 0 0);
21
+ --destructive: oklch(0.577 0.245 27.325);
22
+ --destructive-foreground: oklch(0.577 0.245 27.325);
23
+ --border: 0 0% 89.8%;
24
+ --input: oklch(0.922 0 0);
25
+ --ring: oklch(0.708 0 0);
26
+ --chart-1: oklch(0.646 0.222 41.116);
27
+ --chart-2: oklch(0.6 0.118 184.704);
28
+ --chart-3: oklch(0.398 0.07 227.392);
29
+ --chart-4: oklch(0.828 0.189 84.429);
30
+ --chart-5: oklch(0.769 0.188 70.08);
31
+ --radius: 0.5rem;
32
+ --sidebar: oklch(0.985 0 0);
33
+ --sidebar-foreground: oklch(0.145 0 0);
34
+ --sidebar-primary: oklch(0.205 0 0);
35
+ --sidebar-primary-foreground: oklch(0.985 0 0);
36
+ --sidebar-accent: oklch(0.97 0 0);
37
+ --sidebar-accent-foreground: oklch(0.205 0 0);
38
+ --sidebar-border: oklch(0.922 0 0);
39
+ --sidebar-ring: oklch(0.708 0 0);
40
+ }
41
+
42
+ .dark {
43
+ --background: 0 0% 3.9%;
44
+ --foreground: 0 0% 98%;
45
+ --card: oklch(0.145 0 0);
46
+ --card-foreground: oklch(0.985 0 0);
47
+ --popover: oklch(0.145 0 0);
48
+ --popover-foreground: oklch(0.985 0 0);
49
+ --primary: 217.2 91.2% 59.8%;
50
+ --primary-foreground: 0 0% 100%;
51
+ --secondary: oklch(0.269 0 0);
52
+ --secondary-foreground: oklch(0.985 0 0);
53
+ --muted: 0 0% 14.9%;
54
+ --muted-foreground: 0 0% 63.9%;
55
+ --accent: oklch(0.269 0 0);
56
+ --accent-foreground: oklch(0.985 0 0);
57
+ --destructive: oklch(0.396 0.141 25.723);
58
+ --destructive-foreground: oklch(0.637 0.237 25.331);
59
+ --border: 0 0% 14.9%;
60
+ --input: oklch(0.269 0 0);
61
+ --ring: oklch(0.439 0 0);
62
+ --chart-1: oklch(0.488 0.243 264.376);
63
+ --chart-2: oklch(0.696 0.17 162.48);
64
+ --chart-3: oklch(0.769 0.188 70.08);
65
+ --chart-4: oklch(0.627 0.265 303.9);
66
+ --chart-5: oklch(0.645 0.246 16.439);
67
+ --sidebar: oklch(0.205 0 0);
68
+ --sidebar-foreground: oklch(0.985 0 0);
69
+ --sidebar-primary: oklch(0.488 0.243 264.376);
70
+ --sidebar-primary-foreground: oklch(0.985 0 0);
71
+ --sidebar-accent: oklch(0.269 0 0);
72
+ --sidebar-accent-foreground: oklch(0.985 0 0);
73
+ --sidebar-border: oklch(0.269 0 0);
74
+ --sidebar-ring: oklch(0.439 0 0);
75
+ }
76
+
77
+ @theme inline {
78
+ /* optional: --font-sans, --font-serif, --font-mono if they are applied in the layout.tsx */
79
+ --color-background: var(--background);
80
+ --color-foreground: var(--foreground);
81
+ --color-card: var(--card);
82
+ --color-card-foreground: var(--card-foreground);
83
+ --color-popover: var(--popover);
84
+ --color-popover-foreground: var(--popover-foreground);
85
+ --color-primary: var(--primary);
86
+ --color-primary-foreground: var(--primary-foreground);
87
+ --color-secondary: var(--secondary);
88
+ --color-secondary-foreground: var(--secondary-foreground);
89
+ --color-muted: var(--muted);
90
+ --color-muted-foreground: var(--muted-foreground);
91
+ --color-accent: var(--accent);
92
+ --color-accent-foreground: var(--accent-foreground);
93
+ --color-destructive: var(--destructive);
94
+ --color-destructive-foreground: var(--destructive-foreground);
95
+ --color-border: var(--border);
96
+ --color-input: var(--input);
97
+ --color-ring: var(--ring);
98
+ --color-chart-1: var(--chart-1);
99
+ --color-chart-2: var(--chart-2);
100
+ --color-chart-3: var(--chart-3);
101
+ --color-chart-4: var(--chart-4);
102
+ --color-chart-5: var(--chart-5);
103
+ --radius-sm: calc(var(--radius) - 4px);
104
+ --radius-md: calc(var(--radius) - 2px);
105
+ --radius-lg: var(--radius);
106
+ --radius-xl: calc(var(--radius) + 4px);
107
+ --color-sidebar: var(--sidebar);
108
+ --color-sidebar-foreground: var(--sidebar-foreground);
109
+ --color-sidebar-primary: var(--sidebar-primary);
110
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
111
+ --color-sidebar-accent: var(--sidebar-accent);
112
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
113
+ --color-sidebar-border: var(--sidebar-border);
114
+ --color-sidebar-ring: var(--sidebar-ring);
115
+ }
116
+
117
+ @layer base {
118
+ * {
119
+ @apply border-border outline-ring/50;
120
+ }
121
+ body {
122
+ @apply bg-background text-foreground;
123
+ }
124
+ }
125
+
126
+ * {
127
+ box-sizing: border-box;
128
+ }
129
+
130
+ body {
131
+ margin: 0;
132
+ font-family: system-ui, -apple-system, sans-serif;
133
+ -webkit-font-smoothing: antialiased;
134
+ }
135
+
136
+ .container {
137
+ width: 100%;
138
+ max-width: 1280px;
139
+ }
140
+
141
+ .text-muted-foreground {
142
+ color: hsl(var(--muted-foreground));
143
+ }
144
+
145
+ .border {
146
+ border: 1px solid hsl(var(--border));
147
+ }
148
+
149
+ .bg-muted {
150
+ background: hsl(var(--muted));
151
+ }
@@ -0,0 +1,19 @@
1
+ import type React from "react"
2
+ import "./globals.css"
3
+
4
+ export const metadata = {
5
+ title: "Asynx SaaS",
6
+ description: "Production-ready SaaS template",
7
+ }
8
+
9
+ export default function RootLayout({
10
+ children,
11
+ }: {
12
+ children: React.ReactNode
13
+ }) {
14
+ return (
15
+ <html lang="en">
16
+ <body>{children}</body>
17
+ </html>
18
+ )
19
+ }
@@ -0,0 +1,25 @@
1
+ // Landing page - public facing
2
+ // In advanced apps, this is often separate from the app shell
3
+
4
+ import Link from "next/link"
5
+
6
+ export default function LandingPage() {
7
+ return (
8
+ <main className="min-h-screen">
9
+ <section className="container mx-auto px-6 py-20 text-center">
10
+ <h1 className="text-5xl font-bold mb-6">Welcome to Your SaaS Platform</h1>
11
+ <p className="text-xl text-muted-foreground mb-8 max-w-2xl mx-auto">
12
+ Built with a scalable, production-ready architecture
13
+ </p>
14
+ <div className="flex gap-4 justify-center">
15
+ <Link href="/app" className="px-6 py-3 bg-foreground text-background rounded-md hover:opacity-90">
16
+ Get Started
17
+ </Link>
18
+ <Link href="/auth/login" className="px-6 py-3 border rounded-md hover:bg-muted">
19
+ Sign In
20
+ </Link>
21
+ </div>
22
+ </section>
23
+ </main>
24
+ )
25
+ }
@@ -0,0 +1,67 @@
1
+ // Shared infrastructure - API client
2
+ // Centralized HTTP client for all features
3
+
4
+ export class ApiError extends Error {
5
+ constructor(message: string, public status: number, public data?: unknown) {
6
+ super(message);
7
+ this.name = 'ApiError';
8
+ }
9
+ }
10
+
11
+ export class ApiClient {
12
+ private baseUrl: string;
13
+
14
+ constructor(baseUrl = '/api') {
15
+ this.baseUrl = baseUrl;
16
+ }
17
+
18
+ private async request<T>(
19
+ endpoint: string,
20
+ options?: RequestInit,
21
+ ): Promise<T> {
22
+ const url = `${this.baseUrl}${endpoint}`;
23
+
24
+ const response = await fetch(url, {
25
+ ...options,
26
+ headers: {
27
+ 'Content-Type': 'application/json',
28
+ ...options?.headers,
29
+ },
30
+ });
31
+
32
+ if (!response.ok) {
33
+ const error = await response.json().catch(() => ({}));
34
+ throw new ApiError(
35
+ error.message || 'Request failed',
36
+ response.status,
37
+ error,
38
+ );
39
+ }
40
+
41
+ return response.json();
42
+ }
43
+
44
+ async get<T>(endpoint: string): Promise<T> {
45
+ return this.request<T>(endpoint, { method: 'GET' });
46
+ }
47
+
48
+ async post<T>(endpoint: string, data?: unknown): Promise<T> {
49
+ return this.request<T>(endpoint, {
50
+ method: 'POST',
51
+ body: data ? JSON.stringify(data) : undefined,
52
+ });
53
+ }
54
+
55
+ async put<T>(endpoint: string, data?: unknown): Promise<T> {
56
+ return this.request<T>(endpoint, {
57
+ method: 'PUT',
58
+ body: data ? JSON.stringify(data) : undefined,
59
+ });
60
+ }
61
+
62
+ async delete<T>(endpoint: string): Promise<T> {
63
+ return this.request<T>(endpoint, { method: 'DELETE' });
64
+ }
65
+ }
66
+
67
+ export const apiClient = new ApiClient();
@@ -0,0 +1,19 @@
1
+ // Shared infrastructure - App configuration
2
+ // Environment-aware configuration
3
+
4
+ export const appConfig = {
5
+ name: 'Your SaaS',
6
+ description: 'Production-ready SaaS template',
7
+ url: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
8
+ api: {
9
+ baseUrl: process.env.NEXT_PUBLIC_API_URL || '/api',
10
+ },
11
+ features: {
12
+ auth: true,
13
+ billing: true,
14
+ analytics: true,
15
+ },
16
+ } as const;
17
+
18
+ export const isProduction = process.env.NODE_ENV === 'production';
19
+ export const isDevelopment = process.env.NODE_ENV === 'development';
@@ -0,0 +1,38 @@
1
+ // Shared infrastructure - Constants
2
+ // Application-wide constants
3
+
4
+ export const ROUTES = {
5
+ // Public routes
6
+ HOME: '/',
7
+ LOGIN: '/auth/login',
8
+ SIGNUP: '/auth/signup',
9
+
10
+ // App routes
11
+ APP: '/app',
12
+ DASHBOARD: '/app',
13
+ BILLING: '/app/billing',
14
+ SETTINGS: '/app/settings',
15
+ ANALYTICS: '/app/analytics',
16
+ } as const;
17
+
18
+ export const API_ROUTES = {
19
+ AUTH_LOGIN: '/api/auth/login',
20
+ AUTH_SIGNUP: '/api/auth/signup',
21
+ AUTH_LOGOUT: '/api/auth/logout',
22
+ USER_PROFILE: '/api/user/profile',
23
+ BILLING_SUBSCRIPTION: '/api/billing/subscription',
24
+ } as const;
25
+
26
+ export const SUBSCRIPTION_PLANS = {
27
+ FREE: { name: 'Free', price: 0, features: ['Basic features'] },
28
+ PRO: {
29
+ name: 'Pro',
30
+ price: 49,
31
+ features: ['All features', 'Priority support'],
32
+ },
33
+ ENTERPRISE: {
34
+ name: 'Enterprise',
35
+ price: 199,
36
+ features: ['Custom everything'],
37
+ },
38
+ } as const;
@@ -0,0 +1,26 @@
1
+ // Analytics feature - Service layer
2
+ // Track events and metrics
3
+
4
+ export type AnalyticsEvent = {
5
+ name: string
6
+ properties?: Record<string, unknown>
7
+ }
8
+
9
+ export class AnalyticsService {
10
+ track(event: AnalyticsEvent) {
11
+ // TODO: Send to analytics provider
12
+ console.log("Analytics event:", event)
13
+ }
14
+
15
+ identify(userId: string, traits?: Record<string, unknown>) {
16
+ // TODO: Identify user
17
+ console.log("Identify user:", userId, traits)
18
+ }
19
+
20
+ page(name: string) {
21
+ // TODO: Track page view
22
+ console.log("Page view:", name)
23
+ }
24
+ }
25
+
26
+ export const analytics = new AnalyticsService()
@@ -0,0 +1,18 @@
1
+ // App shell feature - Header component
2
+
3
+ export function AppHeader() {
4
+ return (
5
+ <header className="border-b px-6 py-4">
6
+ <div className="flex items-center justify-between">
7
+ <div>
8
+ <input type="search" placeholder="Search..." className="px-4 py-2 border rounded-md w-80" />
9
+ </div>
10
+
11
+ <div className="flex items-center gap-4">
12
+ <button className="p-2 hover:bg-muted rounded-md">🔔</button>
13
+ <button className="p-2 hover:bg-muted rounded-md">👤</button>
14
+ </div>
15
+ </div>
16
+ </header>
17
+ )
18
+ }
@@ -0,0 +1,38 @@
1
+ // App shell feature - Sidebar component
2
+ // This is part of the core app navigation infrastructure
3
+
4
+ import Link from "next/link"
5
+
6
+ export function AppSidebar() {
7
+ const navigation = [
8
+ { name: "Dashboard", href: "/app", icon: "📊" },
9
+ { name: "Analytics", href: "/app/analytics", icon: "📈" },
10
+ { name: "Billing", href: "/app/billing", icon: "💳" },
11
+ { name: "Settings", href: "/app/settings", icon: "⚙️" },
12
+ ]
13
+
14
+ return (
15
+ <aside className="w-64 border-r flex flex-col">
16
+ <div className="p-6 border-b">
17
+ <h1 className="text-xl font-bold">Your SaaS</h1>
18
+ </div>
19
+
20
+ <nav className="flex-1 p-4">
21
+ <ul className="space-y-2">
22
+ {navigation.map((item) => (
23
+ <li key={item.name}>
24
+ <Link href={item.href} className="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-muted">
25
+ <span>{item.icon}</span>
26
+ <span>{item.name}</span>
27
+ </Link>
28
+ </li>
29
+ ))}
30
+ </ul>
31
+ </nav>
32
+
33
+ <div className="p-4 border-t">
34
+ <button className="w-full px-3 py-2 text-left hover:bg-muted rounded-md">Sign Out</button>
35
+ </div>
36
+ </aside>
37
+ )
38
+ }
@@ -0,0 +1,36 @@
1
+ // Auth feature - Service layer
2
+ // Business logic for authentication
3
+
4
+ export class AuthService {
5
+ async login(email: string, password: string) {
6
+ // TODO: Implement actual authentication
7
+ // This is a placeholder structure
8
+ console.log("Login attempt:", email)
9
+
10
+ // Example: call your auth API
11
+ // const response = await fetch('/api/auth/login', {
12
+ // method: 'POST',
13
+ // body: JSON.stringify({ email, password })
14
+ // });
15
+
16
+ return { success: true }
17
+ }
18
+
19
+ async signup(email: string, password: string, name: string) {
20
+ // TODO: Implement signup
21
+ console.log("Signup attempt:", email, name)
22
+ return { success: true }
23
+ }
24
+
25
+ async logout() {
26
+ // TODO: Implement logout
27
+ console.log("Logout")
28
+ }
29
+
30
+ async getCurrentUser() {
31
+ // TODO: Get current user session
32
+ return null
33
+ }
34
+ }
35
+
36
+ export const authService = new AuthService()
@@ -0,0 +1,38 @@
1
+ // Billing feature - Service layer
2
+ // Business logic for subscription and payments
3
+
4
+ export type SubscriptionPlan = "free" | "pro" | "enterprise"
5
+
6
+ export interface Subscription {
7
+ plan: SubscriptionPlan
8
+ status: "active" | "canceled" | "past_due"
9
+ currentPeriodEnd: Date
10
+ }
11
+
12
+ export class BillingService {
13
+ async getSubscription(): Promise<Subscription | null> {
14
+ // TODO: Fetch from your billing provider (Stripe, etc.)
15
+ return {
16
+ plan: "pro",
17
+ status: "active",
18
+ currentPeriodEnd: new Date("2024-01-01"),
19
+ }
20
+ }
21
+
22
+ async updateSubscription(plan: SubscriptionPlan) {
23
+ // TODO: Update subscription via API
24
+ console.log("Updating to plan:", plan)
25
+ }
26
+
27
+ async cancelSubscription() {
28
+ // TODO: Cancel subscription
29
+ console.log("Canceling subscription")
30
+ }
31
+
32
+ async getInvoices() {
33
+ // TODO: Fetch invoice history
34
+ return []
35
+ }
36
+ }
37
+
38
+ export const billingService = new BillingService()
@@ -0,0 +1,21 @@
1
+ export type User = {
2
+ id: string;
3
+ email: string;
4
+ name: string;
5
+ role: 'user' | 'admin';
6
+ createdAt: Date;
7
+ };
8
+
9
+ export type ApiResponse<T> = {
10
+ data: T;
11
+ message?: string;
12
+ };
13
+
14
+ export type PaginatedResponse<T> = {
15
+ data: T[];
16
+ pagination: {
17
+ page: number;
18
+ limit: number;
19
+ total: number;
20
+ };
21
+ };
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./src/*"],
23
+ "@/features/*": ["./src/features/*"],
24
+ "@/lib/*": ["./src/lib/*"]
25
+ }
26
+ },
27
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
28
+ "exclude": ["node_modules"]
29
+ }
@@ -0,0 +1,53 @@
1
+ # Standard Template
2
+
3
+ This template is designed for **dashboards, content platforms, and early-stage startups**.
4
+
5
+ ## Structure
6
+
7
+ ```
8
+ src/
9
+ ├── app/
10
+ │ ├── (public)/ # Public routes (landing, login, signup)
11
+ │ │ ├── login/
12
+ │ │ └── layout.tsx
13
+ │ ├── (dashboard)/ # Authenticated routes
14
+ │ │ ├── dashboard/
15
+ │ │ └── layout.tsx
16
+ │ ├── layout.tsx # Root layout
17
+ │ ├── page.tsx # Homepage
18
+ │ └── globals.css
19
+ ├── components/
20
+ │ ├── ui/ # Reusable UI components
21
+ │ │ ├── button.tsx
22
+ │ │ └── card.tsx
23
+ │ └── layout/ # Layout components
24
+ │ ├── header.tsx
25
+ │ └── footer.tsx
26
+ ├── lib/
27
+ │ ├── api.ts # API client utilities
28
+ │ └── constants.ts # App constants
29
+ └── utils/ # Utility functions
30
+ ```
31
+
32
+ ## Key Features
33
+
34
+ - **Route Groups**: Separate public and authenticated layouts
35
+ - **Component Library**: Basic UI components to get started
36
+ - **API Client**: Centralized API utilities
37
+ - **Layout Hierarchy**: Header, footer, and sidebar examples
38
+ - **TypeScript**: Full type safety
39
+
40
+ ## Getting Started
41
+
42
+ 1. Customize the layouts in \`app/(public)\` and \`app/(dashboard)\`
43
+ 2. Add your UI components in \`components/ui\`
44
+ 3. Configure API endpoints in \`lib/constants.ts\`
45
+ 4. Build your features!
46
+
47
+ ## Auth-Ready Structure
48
+
49
+ This template is structured to easily integrate authentication:
50
+ - Public routes for unauthenticated users
51
+ - Dashboard routes for authenticated users
52
+ - Add middleware for route protection when ready
53
+ ```
@@ -13,7 +13,11 @@
13
13
  "react-dom": "latest"
14
14
  },
15
15
  "devDependencies": {
16
+ "tailwindcss": "^4.0.0",
17
+ "postcss": "^8.4.0",
18
+ "autoprefixer": "^10.4.0",
16
19
  "typescript": "^5.0.0",
20
+ "@types/node": "^20.0.0",
17
21
  "@types/react": "^18.0.0",
18
22
  "@types/react-dom": "^18.0.0"
19
23
  }
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ };