nodejs-quickstart-structure 2.0.1 → 2.1.1

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