nodejs-quickstart-structure 2.0.1 → 2.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.
Files changed (154) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +43 -39
  3. package/bin/index.js +5 -2
  4. package/lib/generator.js +10 -4
  5. package/lib/modules/app-setup.js +76 -6
  6. package/lib/modules/auth-setup.js +143 -0
  7. package/lib/modules/caching-setup.js +8 -1
  8. package/lib/modules/database-setup.js +2 -1
  9. package/lib/modules/project-setup.js +1 -0
  10. package/lib/prompts.js +39 -0
  11. package/package.json +5 -4
  12. package/templates/clean-architecture/js/src/domain/models/User.js +3 -1
  13. package/templates/clean-architecture/js/src/index.js.ejs +2 -0
  14. package/templates/clean-architecture/js/src/infrastructure/config/env.js.ejs +12 -3
  15. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +25 -2
  16. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.spec.js.ejs +27 -0
  17. package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +3 -0
  18. package/templates/clean-architecture/js/src/infrastructure/webserver/server.spec.js.ejs +49 -0
  19. package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.spec.js.ejs +14 -0
  20. package/templates/clean-architecture/js/src/interfaces/controllers/userController.js.ejs +41 -4
  21. package/templates/clean-architecture/js/src/interfaces/controllers/userController.spec.js.ejs +69 -4
  22. package/templates/clean-architecture/js/src/interfaces/graphql/context.js.ejs +13 -6
  23. package/templates/clean-architecture/js/src/interfaces/graphql/context.spec.js.ejs +38 -21
  24. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +10 -5
  25. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.spec.js.ejs +32 -10
  26. package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +1 -1
  27. package/templates/clean-architecture/js/src/interfaces/routes/api.js.ejs +15 -0
  28. package/templates/clean-architecture/js/src/interfaces/routes/api.spec.js.ejs +4 -0
  29. package/templates/clean-architecture/js/src/usecases/CreateUser.js.ejs +34 -0
  30. package/templates/clean-architecture/js/src/usecases/CreateUser.spec.js.ejs +3 -2
  31. package/templates/clean-architecture/js/src/usecases/DeleteUser.js.ejs +27 -0
  32. package/templates/clean-architecture/js/src/usecases/GetAllUsers.js.ejs +36 -0
  33. package/templates/clean-architecture/js/src/usecases/GetAllUsers.spec.js.ejs +14 -0
  34. package/templates/clean-architecture/js/src/usecases/GetUserById.js.ejs +36 -0
  35. package/templates/clean-architecture/js/src/usecases/GetUserById.spec.js.ejs +48 -0
  36. package/templates/clean-architecture/js/src/usecases/UpdateUser.js.ejs +28 -0
  37. package/templates/clean-architecture/js/src/utils/errorMessages.js +1 -0
  38. package/templates/clean-architecture/js/src/utils/httpCodes.js +2 -0
  39. package/templates/clean-architecture/ts/src/config/env.ts.ejs +12 -3
  40. package/templates/clean-architecture/ts/src/domain/user.ts +3 -1
  41. package/templates/clean-architecture/ts/src/index.ts.ejs +4 -0
  42. package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.spec.ts.ejs +55 -9
  43. package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +32 -3
  44. package/templates/clean-architecture/ts/src/interfaces/controllers/userController.spec.ts.ejs +26 -6
  45. package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts.ejs +57 -15
  46. package/templates/clean-architecture/ts/src/interfaces/graphql/context.spec.ts.ejs +38 -23
  47. package/templates/clean-architecture/ts/src/interfaces/graphql/context.ts.ejs +14 -8
  48. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.spec.ts.ejs +33 -10
  49. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +15 -5
  50. package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +1 -1
  51. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.spec.ts.ejs +9 -1
  52. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts.ejs +16 -0
  53. package/templates/clean-architecture/ts/src/usecases/createUser.spec.ts.ejs +3 -2
  54. package/templates/clean-architecture/ts/src/usecases/createUser.ts.ejs +35 -0
  55. package/templates/clean-architecture/ts/src/usecases/deleteUser.spec.ts.ejs +1 -0
  56. package/templates/clean-architecture/ts/src/usecases/deleteUser.ts.ejs +24 -0
  57. package/templates/clean-architecture/ts/src/usecases/getAllUsers.ts.ejs +21 -0
  58. package/templates/clean-architecture/ts/src/usecases/getUserById.spec.ts.ejs +47 -0
  59. package/templates/clean-architecture/ts/src/usecases/getUserById.ts.ejs +23 -0
  60. package/templates/clean-architecture/ts/src/usecases/updateUser.spec.ts.ejs +1 -0
  61. package/templates/clean-architecture/ts/src/usecases/updateUser.ts.ejs +25 -0
  62. package/templates/clean-architecture/ts/src/utils/errorMessages.ts +1 -0
  63. package/templates/clean-architecture/ts/src/utils/httpCodes.ts +1 -0
  64. package/templates/common/.cursorrules.ejs +9 -0
  65. package/templates/common/.env.example.ejs +17 -10
  66. package/templates/common/README.md.ejs +63 -18
  67. package/templates/common/auth/js/controllers/authController.js.ejs +168 -0
  68. package/templates/common/auth/js/controllers/authController.spec.js.ejs +148 -0
  69. package/templates/common/auth/js/middleware/authMiddleware.js.ejs +58 -0
  70. package/templates/common/auth/js/middleware/authMiddleware.spec.js.ejs +108 -0
  71. package/templates/common/auth/js/routes/authRoutes.js.ejs +16 -0
  72. package/templates/common/auth/js/services/jwtService.js.ejs +54 -0
  73. package/templates/common/auth/js/services/jwtService.spec.js.ejs +84 -0
  74. package/templates/common/auth/ts/controllers/authController.spec.ts.ejs +161 -0
  75. package/templates/common/auth/ts/controllers/authController.ts.ejs +165 -0
  76. package/templates/common/auth/ts/middleware/authMiddleware.spec.ts.ejs +128 -0
  77. package/templates/common/auth/ts/middleware/authMiddleware.ts.ejs +59 -0
  78. package/templates/common/auth/ts/routes/authRoutes.ts.ejs +20 -0
  79. package/templates/common/auth/ts/services/jwtService.spec.ts.ejs +89 -0
  80. package/templates/common/auth/ts/services/jwtService.ts.ejs +60 -0
  81. package/templates/common/caching/clean/js/CreateUser.js.ejs +14 -5
  82. package/templates/common/caching/clean/js/DeleteUser.js.ejs +2 -1
  83. package/templates/common/caching/clean/js/GetUserById.js.ejs +39 -0
  84. package/templates/common/caching/clean/js/UpdateUser.js.ejs +2 -1
  85. package/templates/common/caching/clean/ts/createUser.ts.ejs +14 -6
  86. package/templates/common/caching/clean/ts/deleteUser.ts.ejs +2 -1
  87. package/templates/common/caching/clean/ts/getUserById.ts.ejs +32 -0
  88. package/templates/common/caching/clean/ts/updateUser.ts.ejs +2 -1
  89. package/templates/common/database/js/models/User.js.ejs +14 -1
  90. package/templates/common/database/js/models/User.js.mongoose.ejs +7 -0
  91. package/templates/common/database/js/models/User.spec.js.ejs +12 -0
  92. package/templates/common/database/ts/models/User.spec.ts.ejs +10 -0
  93. package/templates/common/database/ts/models/User.ts.ejs +17 -0
  94. package/templates/common/database/ts/models/User.ts.mongoose.ejs +8 -0
  95. package/templates/common/docker-compose.yml.ejs +12 -0
  96. package/templates/common/ecosystem.config.js.ejs +9 -3
  97. package/templates/common/eslint.config.mjs.ejs +3 -0
  98. package/templates/common/jest.config.js.ejs +11 -9
  99. package/templates/common/kafka/js/messaging/baseConsumer.js.ejs +1 -1
  100. package/templates/common/kafka/js/services/kafkaService.js.ejs +1 -1
  101. package/templates/common/migrations/init.js.ejs +5 -4
  102. package/templates/common/package.json.ejs +8 -1
  103. package/templates/common/prompts/project-context.md.ejs +8 -1
  104. package/templates/common/src/tests/e2e/e2e.users.test.js.ejs +149 -107
  105. package/templates/common/src/tests/e2e/e2e.users.test.ts.ejs +88 -47
  106. package/templates/common/swagger.yml.ejs +148 -0
  107. package/templates/common/tsconfig.eslint.json +15 -0
  108. package/templates/common/tsconfig.json +2 -1
  109. package/templates/common/views/ejs/index.ejs +264 -30
  110. package/templates/common/views/ejs/login.ejs.ejs +244 -0
  111. package/templates/common/views/ejs/signup.ejs.ejs +282 -0
  112. package/templates/common/views/pug/index.pug +269 -38
  113. package/templates/common/views/pug/login.pug.ejs +195 -0
  114. package/templates/common/views/pug/signup.pug.ejs +241 -0
  115. package/templates/db/mysql/V1__Initial_Setup.sql.ejs +6 -0
  116. package/templates/db/postgres/V1__Initial_Setup.sql.ejs +6 -0
  117. package/templates/mvc/js/src/config/env.js.ejs +12 -3
  118. package/templates/mvc/js/src/controllers/userController.js.ejs +29 -5
  119. package/templates/mvc/js/src/controllers/userController.spec.js.ejs +27 -12
  120. package/templates/mvc/js/src/graphql/context.js.ejs +14 -3
  121. package/templates/mvc/js/src/graphql/context.spec.js.ejs +36 -21
  122. package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +10 -5
  123. package/templates/mvc/js/src/graphql/resolvers/user.resolvers.spec.js.ejs +32 -10
  124. package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +1 -1
  125. package/templates/mvc/js/src/index.js.ejs +16 -3
  126. package/templates/mvc/js/src/routes/api.js.ejs +14 -0
  127. package/templates/mvc/js/src/routes/api.spec.js.ejs +3 -0
  128. package/templates/mvc/js/src/utils/errorMessages.js +1 -0
  129. package/templates/mvc/js/src/utils/httpCodes.js +1 -0
  130. package/templates/mvc/ts/src/config/env.ts.ejs +12 -3
  131. package/templates/mvc/ts/src/controllers/userController.spec.ts.ejs +95 -7
  132. package/templates/mvc/ts/src/controllers/userController.ts.ejs +68 -11
  133. package/templates/mvc/ts/src/graphql/context.spec.ts.ejs +36 -23
  134. package/templates/mvc/ts/src/graphql/context.ts.ejs +15 -6
  135. package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.spec.ts.ejs +32 -10
  136. package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +15 -5
  137. package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +1 -1
  138. package/templates/mvc/ts/src/index.ts.ejs +15 -3
  139. package/templates/mvc/ts/src/routes/api.spec.ts.ejs +6 -0
  140. package/templates/mvc/ts/src/routes/api.ts.ejs +15 -0
  141. package/templates/mvc/ts/src/utils/errorMessages.ts +1 -0
  142. package/templates/mvc/ts/src/utils/httpCodes.ts +1 -0
  143. package/templates/clean-architecture/js/src/interfaces/routes/api.js +0 -12
  144. package/templates/clean-architecture/js/src/usecases/CreateUser.js +0 -14
  145. package/templates/clean-architecture/js/src/usecases/DeleteUser.js +0 -11
  146. package/templates/clean-architecture/js/src/usecases/GetAllUsers.js +0 -12
  147. package/templates/clean-architecture/js/src/usecases/UpdateUser.js +0 -11
  148. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +0 -13
  149. package/templates/clean-architecture/ts/src/usecases/createUser.ts +0 -13
  150. package/templates/clean-architecture/ts/src/usecases/deleteUser.ts +0 -9
  151. package/templates/clean-architecture/ts/src/usecases/getAllUsers.ts +0 -10
  152. package/templates/clean-architecture/ts/src/usecases/updateUser.ts +0 -9
  153. package/templates/mvc/js/src/routes/api.js +0 -10
  154. package/templates/mvc/ts/src/routes/api.ts +0 -12
@@ -4,48 +4,282 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title><%= projectName %></title>
7
- <link rel="stylesheet" href="/css/style.css">
7
+ <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap" rel="stylesheet">
8
+ <style>
9
+ :root {
10
+ --primary: #6366f1;
11
+ --primary-glow: rgba(99, 102, 241, 0.4);
12
+ --bg-dark: #0f172a;
13
+ --card-bg: rgba(255, 255, 255, 0.03);
14
+ --card-border: rgba(255, 255, 255, 0.08);
15
+ --text-main: #f8fafc;
16
+ --text-muted: #94a3b8;
17
+ --success: #22c55e;
18
+ }
19
+
20
+ * {
21
+ margin: 0;
22
+ padding: 0;
23
+ box-sizing: border-box;
24
+ font-family: 'Poppins', sans-serif;
25
+ }
26
+
27
+ body {
28
+ background-color: var(--bg-dark);
29
+ color: var(--text-main);
30
+ min-height: 100vh;
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: center;
34
+ overflow-x: hidden;
35
+ position: relative;
36
+ padding: 40px 20px;
37
+ }
38
+
39
+ /* Animated Background Blobs */
40
+ .background-blobs {
41
+ position: absolute;
42
+ width: 100%;
43
+ height: 100%;
44
+ z-index: -1;
45
+ filter: blur(100px);
46
+ }
47
+
48
+ .blob {
49
+ position: absolute;
50
+ width: 500px;
51
+ height: 500px;
52
+ border-radius: 50%;
53
+ opacity: 0.3;
54
+ animation: float 25s infinite alternate;
55
+ }
56
+
57
+ .blob-1 {
58
+ background: radial-gradient(circle, #6366f1 0%, transparent 70%);
59
+ top: -200px;
60
+ left: -100px;
61
+ }
62
+
63
+ .blob-2 {
64
+ background: radial-gradient(circle, #ec4899 0%, transparent 70%);
65
+ bottom: -200px;
66
+ right: -100px;
67
+ animation-delay: -5s;
68
+ }
69
+
70
+ @keyframes float {
71
+ 0% { transform: translate(0, 0) scale(1); }
72
+ 100% { transform: translate(150px, 80px) scale(1.3); }
73
+ }
74
+
75
+ .container {
76
+ width: 100%;
77
+ max-width: 1000px;
78
+ z-index: 1;
79
+ animation: fadeIn 0.8s ease-out;
80
+ }
81
+
82
+ @keyframes fadeIn {
83
+ from { opacity: 0; transform: translateY(20px); }
84
+ to { opacity: 1; transform: translateY(0); }
85
+ }
86
+
87
+ .hero-card {
88
+ background: var(--card-bg);
89
+ backdrop-filter: blur(16px);
90
+ -webkit-backdrop-filter: blur(16px);
91
+ border: 1px solid var(--card-border);
92
+ border-radius: 32px;
93
+ padding: 60px 40px;
94
+ text-align: center;
95
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.6);
96
+ margin-bottom: 40px;
97
+ }
98
+
99
+ .logo {
100
+ font-size: 64px;
101
+ margin-bottom: 24px;
102
+ display: inline-block;
103
+ animation: bounce 3s infinite ease-in-out;
104
+ }
105
+
106
+ @keyframes bounce {
107
+ 0%, 100% { transform: translateY(0); }
108
+ 50% { transform: translateY(-10px); }
109
+ }
110
+
111
+ h1 {
112
+ font-size: 48px;
113
+ font-weight: 600;
114
+ margin-bottom: 12px;
115
+ background: linear-gradient(to right, #fff, #94a3b8);
116
+ -webkit-background-clip: text;
117
+ -webkit-text-fill-color: transparent;
118
+ }
119
+
120
+ .subtitle {
121
+ font-size: 18px;
122
+ color: var(--text-muted);
123
+ margin-bottom: 40px;
124
+ max-width: 600px;
125
+ margin-left: auto;
126
+ margin-right: auto;
127
+ }
128
+
129
+ .btn-group {
130
+ display: flex;
131
+ gap: 16px;
132
+ justify-content: center;
133
+ flex-wrap: wrap;
134
+ }
135
+
136
+ .btn {
137
+ padding: 14px 28px;
138
+ border-radius: 14px;
139
+ font-size: 16px;
140
+ font-weight: 600;
141
+ text-decoration: none;
142
+ transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
143
+ display: flex;
144
+ align-items: center;
145
+ gap: 8px;
146
+ }
147
+
148
+ .btn-primary {
149
+ background: var(--primary);
150
+ color: white;
151
+ box-shadow: 0 10px 15px -3px rgba(99, 102, 241, 0.3);
152
+ }
153
+
154
+ .btn-primary:hover {
155
+ transform: scale(1.05);
156
+ background: #4f46e5;
157
+ box-shadow: 0 15px 25px -5px rgba(99, 102, 241, 0.4);
158
+ }
159
+
160
+ .btn-secondary {
161
+ background: rgba(255, 255, 255, 0.05);
162
+ color: white;
163
+ border: 1px solid var(--card-border);
164
+ }
165
+
166
+ .btn-secondary:hover {
167
+ background: rgba(255, 255, 255, 0.1);
168
+ transform: scale(1.05);
169
+ }
170
+
171
+ .feature-grid {
172
+ display: grid;
173
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
174
+ gap: 24px;
175
+ }
176
+
177
+ .feature-card {
178
+ background: var(--card-bg);
179
+ backdrop-filter: blur(8px);
180
+ border: 1px solid var(--card-border);
181
+ border-radius: 20px;
182
+ padding: 24px;
183
+ transition: all 0.3s ease;
184
+ }
185
+
186
+ .feature-card:hover {
187
+ transform: translateY(-5px);
188
+ background: rgba(255, 255, 255, 0.06);
189
+ border-color: var(--primary);
190
+ }
191
+
192
+ .feature-card h3 {
193
+ font-size: 14px;
194
+ text-transform: uppercase;
195
+ letter-spacing: 1px;
196
+ color: var(--text-muted);
197
+ margin-bottom: 8px;
198
+ }
199
+
200
+ .feature-card p {
201
+ font-size: 20px;
202
+ font-weight: 600;
203
+ color: #fff;
204
+ }
205
+
206
+ .status-badge {
207
+ display: inline-flex;
208
+ align-items: center;
209
+ gap: 8px;
210
+ background: rgba(34, 197, 94, 0.1);
211
+ border: 1px solid rgba(34, 197, 94, 0.2);
212
+ color: var(--success);
213
+ padding: 8px 16px;
214
+ border-radius: 99px;
215
+ font-size: 14px;
216
+ font-weight: 500;
217
+ margin-top: 32px;
218
+ }
219
+
220
+ footer {
221
+ margin-top: 60px;
222
+ text-align: center;
223
+ font-size: 14px;
224
+ color: var(--text-muted);
225
+ }
226
+
227
+ /* Responsive */
228
+ @media (max-width: 640px) {
229
+ h1 { font-size: 32px; }
230
+ .hero-card { padding: 40px 20px; }
231
+ }
232
+ </style>
8
233
  </head>
9
234
  <body>
235
+ <div class="background-blobs">
236
+ <div class="blob blob-1"></div>
237
+ <div class="blob blob-2"></div>
238
+ </div>
239
+
10
240
  <div class="container">
11
- <header class="header">
241
+ <div class="hero-card">
12
242
  <div class="logo">🚀</div>
13
243
  <h1>Welcome to <%= projectName %></h1>
14
- <p class="subtitle">A production-ready Node.js microservice starter.</p>
15
- </header>
244
+ <p class="subtitle">Your enterprise-grade Node.js microservice is live and ready for production.</p>
16
245
 
17
- <div class="card-grid">
18
- <div class="card">
19
- <h3>Architecture</h3>
20
- <p><%= architecture %></p>
21
- </div>
22
- <div class="card">
23
- <h3>Database</h3>
24
- <p><%= database %></p>
25
- </div>
26
- <div class="card">
27
- <h3>Communication</h3>
28
- <p><%= communication %></p>
246
+ <div class="btn-group">
247
+ <% if (typeof auth !== 'undefined' && auth.includes('JWT')) { %>
248
+ <a href="/login" class="btn btn-primary">Sign In</a>
249
+ <a href="/signup" class="btn btn-secondary">Create Account</a>
250
+ <% } %>
251
+ <a href="<%= communication === 'GraphQL' ? '/graphql' : '/api-docs' %>" class="btn btn-secondary">
252
+ <span>Explore Docs</span>
253
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>
254
+ </a>
29
255
  </div>
256
+
257
+ <% if (communication === 'Kafka') { %>
258
+ <div class="status-badge">
259
+ <span class="dot"></span>
260
+ 🔄 Kafka Connected
261
+ </div>
262
+ <% } else { %>
263
+ <div class="status-badge">
264
+ ✅ API Service Active
265
+ </div>
266
+ <% } %>
30
267
  </div>
31
268
 
32
- <% if (communication === 'Kafka') { %>
33
- <div class="status-card">
34
- <div class="status-icon">🔄</div>
35
- <div class="status-content">
36
- <h3>Kafka Connected</h3>
37
- <p>Connection to broker established successfully.</p>
269
+ <div class="feature-grid">
270
+ <div class="feature-card">
271
+ <h3>Architecture</h3>
272
+ <p><%= architecture %></p>
38
273
  </div>
39
- </div>
40
- <% } else { %>
41
- <div class="status-card">
42
- <div class="status-icon">✅</div>
43
- <div class="status-content">
44
- <h3>API Active</h3>
45
- <p>REST API is running and ready to accept requests.</p>
274
+ <div class="feature-card">
275
+ <h3>Core Stack</h3>
276
+ <p><%= database %> & <%= communication %></p>
277
+ </div>
278
+ <div class="feature-card">
279
+ <h3>Environment</h3>
280
+ <p>Node.js & Docker Ready</p>
46
281
  </div>
47
282
  </div>
48
- <% } %>
49
283
 
50
284
  <footer>
51
285
  <p>Generated with ❤️ by Node.js Quickstart Generator</p>
@@ -0,0 +1,244 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Login - <%= projectName %></title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap" rel="stylesheet">
8
+ <style>
9
+ :root {
10
+ --primary: #6366f1;
11
+ --primary-glow: rgba(99, 102, 241, 0.5);
12
+ --bg-dark: #0f172a;
13
+ --card-bg: rgba(255, 255, 255, 0.03);
14
+ --card-border: rgba(255, 255, 255, 0.08);
15
+ --text-main: #f8fafc;
16
+ --text-muted: #94a3b8;
17
+ }
18
+
19
+ * {
20
+ margin: 0;
21
+ padding: 0;
22
+ box-sizing: border-box;
23
+ font-family: 'Poppins', sans-serif;
24
+ }
25
+
26
+ body {
27
+ background-color: var(--bg-dark);
28
+ color: var(--text-main);
29
+ min-height: 100vh;
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: center;
33
+ overflow: hidden;
34
+ position: relative;
35
+ }
36
+
37
+ /* Animated Background Blobs */
38
+ .background-blobs {
39
+ position: absolute;
40
+ width: 100%;
41
+ height: 100%;
42
+ z-index: -1;
43
+ filter: blur(80px);
44
+ }
45
+
46
+ .blob {
47
+ position: absolute;
48
+ width: 400px;
49
+ height: 400px;
50
+ border-radius: 50%;
51
+ opacity: 0.4;
52
+ animation: float 20s infinite alternate;
53
+ }
54
+
55
+ .blob-1 {
56
+ background: radial-gradient(circle, #6366f1 0%, transparent 70%);
57
+ top: -100px;
58
+ left: -100px;
59
+ }
60
+
61
+ .blob-2 {
62
+ background: radial-gradient(circle, #ec4899 0%, transparent 70%);
63
+ bottom: -150px;
64
+ right: -100px;
65
+ animation-delay: -5s;
66
+ }
67
+
68
+ @keyframes float {
69
+ 0% { transform: translate(0, 0) scale(1); }
70
+ 100% { transform: translate(100px, 50px) scale(1.2); }
71
+ }
72
+
73
+ .auth-card {
74
+ background: var(--card-bg);
75
+ backdrop-filter: blur(12px);
76
+ -webkit-backdrop-filter: blur(12px);
77
+ border: 1px solid var(--card-border);
78
+ border-radius: 24px;
79
+ padding: 48px;
80
+ width: 100%;
81
+ max-width: 440px;
82
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
83
+ z-index: 1;
84
+ animation: slideUp 0.6s cubic-bezier(0.16, 1, 0.3, 1);
85
+ }
86
+
87
+ @keyframes slideUp {
88
+ from { opacity: 0; transform: translateY(20px); }
89
+ to { opacity: 1; transform: translateY(0); }
90
+ }
91
+
92
+ .auth-card h2 {
93
+ font-size: 32px;
94
+ font-weight: 600;
95
+ margin-bottom: 8px;
96
+ text-align: center;
97
+ background: linear-gradient(to right, #fff, #94a3b8);
98
+ -webkit-background-clip: text;
99
+ -webkit-text-fill-color: transparent;
100
+ }
101
+
102
+ .subtitle {
103
+ text-align: center;
104
+ color: var(--text-muted);
105
+ font-size: 14px;
106
+ margin-bottom: 32px;
107
+ }
108
+
109
+ .form-group {
110
+ margin-bottom: 24px;
111
+ }
112
+
113
+ .form-group label {
114
+ display: block;
115
+ margin-bottom: 8px;
116
+ font-size: 14px;
117
+ font-weight: 500;
118
+ color: var(--text-muted);
119
+ transition: color 0.3s;
120
+ }
121
+
122
+ .input-wrapper {
123
+ position: relative;
124
+ }
125
+
126
+ .form-group input {
127
+ width: 100%;
128
+ background: rgba(255, 255, 255, 0.05);
129
+ border: 1px solid var(--card-border);
130
+ border-radius: 12px;
131
+ padding: 12px 16px;
132
+ color: #fff;
133
+ font-size: 15px;
134
+ transition: all 0.3s ease;
135
+ outline: none;
136
+ }
137
+
138
+ .form-group input:focus {
139
+ background: rgba(255, 255, 255, 0.08);
140
+ border-color: var(--primary);
141
+ box-shadow: 0 0 0 4px var(--primary-glow);
142
+ }
143
+
144
+ .form-group input:focus + label {
145
+ color: var(--primary);
146
+ }
147
+
148
+ .btn-primary {
149
+ width: 100%;
150
+ background: var(--primary);
151
+ color: white;
152
+ border: none;
153
+ border-radius: 12px;
154
+ padding: 14px;
155
+ font-size: 16px;
156
+ font-weight: 600;
157
+ cursor: pointer;
158
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
159
+ margin-top: 8px;
160
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
161
+ }
162
+
163
+ .btn-primary:hover {
164
+ transform: translateY(-2px);
165
+ background: #4f46e5;
166
+ box-shadow: 0 10px 15px -3px rgba(99, 102, 241, 0.4);
167
+ }
168
+
169
+ .btn-primary:active {
170
+ transform: translateY(0);
171
+ }
172
+
173
+ .footer {
174
+ margin-top: 32px;
175
+ text-align: center;
176
+ font-size: 14px;
177
+ color: var(--text-muted);
178
+ }
179
+
180
+ .footer a {
181
+ color: var(--primary);
182
+ text-decoration: none;
183
+ font-weight: 500;
184
+ transition: color 0.3s;
185
+ }
186
+
187
+ .footer a:hover {
188
+ color: #818cf8;
189
+ text-decoration: underline;
190
+ }
191
+
192
+ .back-link {
193
+ display: inline-block;
194
+ margin-top: 16px;
195
+ font-size: 13px;
196
+ opacity: 0.6;
197
+ transition: opacity 0.3s;
198
+ }
199
+
200
+ .back-link:hover {
201
+ opacity: 1;
202
+ }
203
+
204
+ /* Responsive adjustments */
205
+ @media (max-width: 480px) {
206
+ .auth-card {
207
+ padding: 32px 24px;
208
+ margin: 20px;
209
+ border-radius: 20px;
210
+ }
211
+ }
212
+ </style>
213
+ </head>
214
+ <body>
215
+ <div class="background-blobs">
216
+ <div class="blob blob-1"></div>
217
+ <div class="blob blob-2"></div>
218
+ </div>
219
+
220
+ <div class="auth-card">
221
+ <h2>Welcome Back</h2>
222
+ <p class="subtitle">Please enter your details to sign in</p>
223
+
224
+ <form action="/api/auth/login" method="POST">
225
+ <div class="form-group">
226
+ <label for="email">Email Address</label>
227
+ <input type="email" id="email" name="email" placeholder="name@example.com" required>
228
+ </div>
229
+
230
+ <div class="form-group">
231
+ <label for="password">Password</label>
232
+ <input type="password" id="password" name="password" placeholder="••••••••" required>
233
+ </div>
234
+
235
+ <button type="submit" class="btn-primary">Sign In</button>
236
+ </form>
237
+
238
+ <div class="footer">
239
+ <p>Don't have an account? <a href="/signup">Create account</a></p>
240
+ <a href="/" class="back-link">← Back to home</a>
241
+ </div>
242
+ </div>
243
+ </body>
244
+ </html>