@onexapis/cli 1.1.34 → 1.1.37

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 (45) hide show
  1. package/dist/cli.js +5 -1
  2. package/dist/cli.js.map +1 -1
  3. package/dist/cli.mjs +5 -1
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/preview/preview-app.tsx +13 -5
  6. package/package.json +1 -1
  7. package/templates/default/AUTH_AND_PROFILE.md +167 -0
  8. package/templates/default/CLAUDE.md +78 -24
  9. package/templates/default/LAYOUT.md +195 -0
  10. package/templates/default/bundle-entry.ts +5 -0
  11. package/templates/default/hooks/index.ts +26 -0
  12. package/templates/default/hooks/use-forgot-password-form.ts +90 -0
  13. package/templates/default/hooks/use-login-form.ts +102 -0
  14. package/templates/default/hooks/use-profile-form.ts +255 -0
  15. package/templates/default/hooks/use-register-form.ts +154 -0
  16. package/templates/default/hooks/use-verify-code-form.ts +224 -0
  17. package/templates/default/index.ts +21 -1
  18. package/templates/default/pages/forgot-password.ts +41 -0
  19. package/templates/default/pages/login.ts +41 -0
  20. package/templates/default/pages/profile.ts +39 -0
  21. package/templates/default/pages/register.ts +41 -0
  22. package/templates/default/pages/verify-code.ts +41 -0
  23. package/templates/default/sections/auth-forgot-password/auth-forgot-password-default.tsx +192 -0
  24. package/templates/default/sections/auth-forgot-password/auth-forgot-password.schema.ts +150 -0
  25. package/templates/default/sections/auth-forgot-password/index.ts +14 -0
  26. package/templates/default/sections/auth-login/auth-login-default.tsx +238 -0
  27. package/templates/default/sections/auth-login/auth-login.schema.ts +171 -0
  28. package/templates/default/sections/auth-login/index.ts +14 -0
  29. package/templates/default/sections/auth-register/auth-register-default.tsx +327 -0
  30. package/templates/default/sections/auth-register/auth-register.schema.ts +188 -0
  31. package/templates/default/sections/auth-register/index.ts +14 -0
  32. package/templates/default/sections/auth-verify-code/auth-verify-code-default.tsx +209 -0
  33. package/templates/default/sections/auth-verify-code/auth-verify-code.schema.ts +150 -0
  34. package/templates/default/sections/auth-verify-code/index.ts +14 -0
  35. package/templates/default/sections/footer/footer-default.tsx +214 -0
  36. package/templates/default/sections/footer/footer.schema.ts +170 -0
  37. package/templates/default/sections/footer/index.ts +14 -0
  38. package/templates/default/sections/header/header-default.tsx +322 -0
  39. package/templates/default/sections/header/header.schema.ts +168 -0
  40. package/templates/default/sections/header/index.ts +14 -0
  41. package/templates/default/sections/profile/index.ts +14 -0
  42. package/templates/default/sections/profile/profile-default.tsx +522 -0
  43. package/templates/default/sections/profile/profile.schema.ts +228 -0
  44. package/templates/default/sections-registry.ts +28 -0
  45. package/templates/default/theme.layout.ts +53 -2
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Auth Register - Default Template
3
+ * Clean registration form with customizable settings
4
+ */
5
+
6
+ "use client";
7
+
8
+ import type { SectionComponentProps } from "@onexapis/core/types";
9
+ import coreUtils from "@onexapis/core/utils";
10
+ import { useRegisterForm } from "../../hooks/use-register-form";
11
+
12
+ const { getSectionValues } = coreUtils;
13
+
14
+ export function AuthRegisterDefault({
15
+ section,
16
+ schema,
17
+ isEditing,
18
+ }: SectionComponentProps) {
19
+ const { settings } = getSectionValues(section, schema);
20
+ const {
21
+ heading,
22
+ subheading,
23
+ emailLabel,
24
+ emailPlaceholder,
25
+ usernameLabel,
26
+ usernamePlaceholder,
27
+ passwordLabel,
28
+ passwordPlaceholder,
29
+ confirmPasswordLabel,
30
+ confirmPasswordPlaceholder,
31
+ submitButtonText,
32
+ loadingText,
33
+ loginPromptText,
34
+ loginLinkText,
35
+ loginUrl,
36
+ passwordRequirementText,
37
+ backgroundColor,
38
+ cardBackground,
39
+ primaryColor,
40
+ textColor,
41
+ cardBorderRadius,
42
+ } = settings;
43
+
44
+ const {
45
+ formData,
46
+ errors,
47
+ showPassword,
48
+ showConfirmPassword,
49
+ isPending,
50
+ handleInputChange,
51
+ handleSubmit,
52
+ toggleShowPassword,
53
+ toggleShowConfirmPassword,
54
+ } = useRegisterForm();
55
+
56
+ const bgColor = String(backgroundColor || "#F9FAFB");
57
+ const cardBg = String(cardBackground || "#FFFFFF");
58
+ const btnColor = String(primaryColor || "#2563EB");
59
+ const headingColor = String(textColor || "#111827");
60
+ const radiusClass = `rounded-${String(cardBorderRadius || "2xl")}`;
61
+
62
+ return (
63
+ <section
64
+ className="min-h-screen w-full flex items-center justify-center p-4"
65
+ style={{ backgroundColor: bgColor }}
66
+ data-section-id={section.id}
67
+ data-section-type={section.type}
68
+ data-section-template="default"
69
+ >
70
+ <div
71
+ className={`w-full max-w-md shadow-lg p-8 ${radiusClass}`}
72
+ style={{ backgroundColor: cardBg }}
73
+ >
74
+ {/* Header */}
75
+ <div className="text-center mb-8">
76
+ <h1 className="text-2xl font-bold" style={{ color: headingColor }}>
77
+ {String(heading)}
78
+ </h1>
79
+ {subheading && (
80
+ <p className="mt-2 text-sm text-gray-500">{String(subheading)}</p>
81
+ )}
82
+ </div>
83
+
84
+ {/* Error Message */}
85
+ {errors.form && (
86
+ <div className="mb-4 rounded-lg bg-red-50 border border-red-200 p-3 text-sm text-red-600">
87
+ {errors.form}
88
+ </div>
89
+ )}
90
+
91
+ {/* Form */}
92
+ <form onSubmit={handleSubmit} className="space-y-4">
93
+ {/* Email */}
94
+ <div className="flex flex-col gap-1.5">
95
+ <label
96
+ htmlFor="email"
97
+ className="text-sm font-medium text-gray-700"
98
+ >
99
+ {String(emailLabel)} <span className="text-red-500">*</span>
100
+ </label>
101
+ <input
102
+ id="email"
103
+ name="email"
104
+ type="text"
105
+ value={formData.email}
106
+ onChange={handleInputChange}
107
+ placeholder={String(emailPlaceholder)}
108
+ disabled={isPending || isEditing}
109
+ className={`h-11 w-full rounded-lg border px-4 text-sm text-gray-900 placeholder:text-gray-400 outline-none transition-colors focus:border-blue-500 focus:ring-1 focus:ring-blue-500 disabled:opacity-50 ${
110
+ errors.email ? "border-red-400" : "border-gray-300"
111
+ }`}
112
+ />
113
+ {errors.email && (
114
+ <p className="text-xs text-red-500">{errors.email}</p>
115
+ )}
116
+ </div>
117
+
118
+ {/* Username */}
119
+ <div className="flex flex-col gap-1.5">
120
+ <label
121
+ htmlFor="username"
122
+ className="text-sm font-medium text-gray-700"
123
+ >
124
+ {String(usernameLabel)} <span className="text-red-500">*</span>
125
+ </label>
126
+ <input
127
+ id="username"
128
+ name="username"
129
+ type="text"
130
+ value={formData.username}
131
+ onChange={handleInputChange}
132
+ placeholder={String(usernamePlaceholder)}
133
+ disabled={isPending || isEditing}
134
+ className={`h-11 w-full rounded-lg border px-4 text-sm text-gray-900 placeholder:text-gray-400 outline-none transition-colors focus:border-blue-500 focus:ring-1 focus:ring-blue-500 disabled:opacity-50 ${
135
+ errors.username ? "border-red-400" : "border-gray-300"
136
+ }`}
137
+ />
138
+ {errors.username && (
139
+ <p className="text-xs text-red-500">{errors.username}</p>
140
+ )}
141
+ </div>
142
+
143
+ {/* Password */}
144
+ <div className="flex flex-col gap-1.5">
145
+ <label
146
+ htmlFor="password"
147
+ className="text-sm font-medium text-gray-700"
148
+ >
149
+ {String(passwordLabel)} <span className="text-red-500">*</span>
150
+ </label>
151
+ <div className="relative">
152
+ <input
153
+ id="password"
154
+ name="password"
155
+ type={showPassword ? "text" : "password"}
156
+ value={formData.password}
157
+ onChange={handleInputChange}
158
+ placeholder={String(passwordPlaceholder)}
159
+ disabled={isPending || isEditing}
160
+ className={`h-11 w-full rounded-lg border px-4 pr-10 text-sm text-gray-900 placeholder:text-gray-400 outline-none transition-colors focus:border-blue-500 focus:ring-1 focus:ring-blue-500 disabled:opacity-50 ${
161
+ errors.password ? "border-red-400" : "border-gray-300"
162
+ }`}
163
+ />
164
+ <button
165
+ type="button"
166
+ onClick={toggleShowPassword}
167
+ className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 transition-colors"
168
+ tabIndex={-1}
169
+ >
170
+ {showPassword ? (
171
+ <svg
172
+ className="h-4 w-4"
173
+ fill="none"
174
+ viewBox="0 0 24 24"
175
+ stroke="currentColor"
176
+ strokeWidth={2}
177
+ >
178
+ <path d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
179
+ </svg>
180
+ ) : (
181
+ <svg
182
+ className="h-4 w-4"
183
+ fill="none"
184
+ viewBox="0 0 24 24"
185
+ stroke="currentColor"
186
+ strokeWidth={2}
187
+ >
188
+ <path d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
189
+ <path d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
190
+ </svg>
191
+ )}
192
+ </button>
193
+ </div>
194
+ {errors.password ? (
195
+ <p className="text-xs text-red-500">{errors.password}</p>
196
+ ) : (
197
+ <p className="text-xs text-gray-400 flex items-start gap-1">
198
+ <svg
199
+ className="h-3 w-3 mt-0.5 shrink-0"
200
+ fill="none"
201
+ viewBox="0 0 24 24"
202
+ stroke="currentColor"
203
+ strokeWidth={2}
204
+ >
205
+ <path d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
206
+ </svg>
207
+ {String(passwordRequirementText)}
208
+ </p>
209
+ )}
210
+ </div>
211
+
212
+ {/* Confirm Password */}
213
+ <div className="flex flex-col gap-1.5">
214
+ <label
215
+ htmlFor="confirmPassword"
216
+ className="text-sm font-medium text-gray-700"
217
+ >
218
+ {String(confirmPasswordLabel)}{" "}
219
+ <span className="text-red-500">*</span>
220
+ </label>
221
+ <div className="relative">
222
+ <input
223
+ id="confirmPassword"
224
+ name="confirmPassword"
225
+ type={showConfirmPassword ? "text" : "password"}
226
+ value={formData.confirmPassword}
227
+ onChange={handleInputChange}
228
+ placeholder={String(confirmPasswordPlaceholder)}
229
+ disabled={isPending || isEditing}
230
+ className={`h-11 w-full rounded-lg border px-4 pr-10 text-sm text-gray-900 placeholder:text-gray-400 outline-none transition-colors focus:border-blue-500 focus:ring-1 focus:ring-blue-500 disabled:opacity-50 ${
231
+ errors.confirmPassword ? "border-red-400" : "border-gray-300"
232
+ }`}
233
+ />
234
+ <button
235
+ type="button"
236
+ onClick={toggleShowConfirmPassword}
237
+ className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 transition-colors"
238
+ tabIndex={-1}
239
+ >
240
+ {showConfirmPassword ? (
241
+ <svg
242
+ className="h-4 w-4"
243
+ fill="none"
244
+ viewBox="0 0 24 24"
245
+ stroke="currentColor"
246
+ strokeWidth={2}
247
+ >
248
+ <path d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
249
+ </svg>
250
+ ) : (
251
+ <svg
252
+ className="h-4 w-4"
253
+ fill="none"
254
+ viewBox="0 0 24 24"
255
+ stroke="currentColor"
256
+ strokeWidth={2}
257
+ >
258
+ <path d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
259
+ <path d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
260
+ </svg>
261
+ )}
262
+ </button>
263
+ </div>
264
+ {errors.confirmPassword && (
265
+ <p className="text-xs text-red-500">{errors.confirmPassword}</p>
266
+ )}
267
+ </div>
268
+
269
+ {/* Submit Button */}
270
+ <div className="pt-1">
271
+ <button
272
+ type="submit"
273
+ disabled={isPending || isEditing}
274
+ className="h-11 w-full rounded-lg text-sm font-medium text-white transition-colors hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
275
+ style={{ backgroundColor: btnColor }}
276
+ >
277
+ {isPending && (
278
+ <svg
279
+ className="h-4 w-4 animate-spin"
280
+ fill="none"
281
+ viewBox="0 0 24 24"
282
+ >
283
+ <circle
284
+ className="opacity-25"
285
+ cx="12"
286
+ cy="12"
287
+ r="10"
288
+ stroke="currentColor"
289
+ strokeWidth="4"
290
+ />
291
+ <path
292
+ className="opacity-75"
293
+ fill="currentColor"
294
+ d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
295
+ />
296
+ </svg>
297
+ )}
298
+ {isPending ? String(loadingText) : String(submitButtonText)}
299
+ </button>
300
+ </div>
301
+ </form>
302
+
303
+ {/* Login Link */}
304
+ <div className="mt-6 text-center">
305
+ <p className="text-sm text-gray-500">
306
+ {String(loginPromptText)}{" "}
307
+ {isEditing ? (
308
+ <span className="font-medium" style={{ color: btnColor }}>
309
+ {String(loginLinkText)}
310
+ </span>
311
+ ) : (
312
+ <a
313
+ href={String(loginUrl)}
314
+ className="font-medium hover:opacity-80 transition-colors"
315
+ style={{ color: btnColor }}
316
+ >
317
+ {String(loginLinkText)}
318
+ </a>
319
+ )}
320
+ </p>
321
+ </div>
322
+ </div>
323
+ </section>
324
+ );
325
+ }
326
+
327
+ export default AuthRegisterDefault;
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Auth Register Section Schema
3
+ * Registration form with editable labels and settings
4
+ */
5
+
6
+ import type { SectionSchema, FieldDefinition } from "@onexapis/core/types";
7
+
8
+ const commonSettings: FieldDefinition[] = [
9
+ {
10
+ id: "heading",
11
+ type: "text",
12
+ label: "Heading",
13
+ default: "Create Account",
14
+ required: true,
15
+ },
16
+ {
17
+ id: "subheading",
18
+ type: "text",
19
+ label: "Subheading",
20
+ default: "Create an account to get exclusive offers and track your orders",
21
+ },
22
+ {
23
+ id: "emailLabel",
24
+ type: "text",
25
+ label: "Email Label",
26
+ default: "Email",
27
+ },
28
+ {
29
+ id: "emailPlaceholder",
30
+ type: "text",
31
+ label: "Email Placeholder",
32
+ default: "example@email.com",
33
+ },
34
+ {
35
+ id: "usernameLabel",
36
+ type: "text",
37
+ label: "Username Label",
38
+ default: "Username",
39
+ },
40
+ {
41
+ id: "usernamePlaceholder",
42
+ type: "text",
43
+ label: "Username Placeholder",
44
+ default: "Enter a username",
45
+ },
46
+ {
47
+ id: "passwordLabel",
48
+ type: "text",
49
+ label: "Password Label",
50
+ default: "Password",
51
+ },
52
+ {
53
+ id: "passwordPlaceholder",
54
+ type: "text",
55
+ label: "Password Placeholder",
56
+ default: "At least 8 characters",
57
+ },
58
+ {
59
+ id: "confirmPasswordLabel",
60
+ type: "text",
61
+ label: "Confirm Password Label",
62
+ default: "Confirm Password",
63
+ },
64
+ {
65
+ id: "confirmPasswordPlaceholder",
66
+ type: "text",
67
+ label: "Confirm Password Placeholder",
68
+ default: "Re-enter your password",
69
+ },
70
+ {
71
+ id: "submitButtonText",
72
+ type: "text",
73
+ label: "Submit Button Text",
74
+ default: "Sign Up",
75
+ },
76
+ {
77
+ id: "loadingText",
78
+ type: "text",
79
+ label: "Loading Text",
80
+ default: "Creating account...",
81
+ },
82
+ {
83
+ id: "loginPromptText",
84
+ type: "text",
85
+ label: "Login Prompt Text",
86
+ default: "Already have an account?",
87
+ },
88
+ {
89
+ id: "loginLinkText",
90
+ type: "text",
91
+ label: "Login Link Text",
92
+ default: "Sign in",
93
+ },
94
+ {
95
+ id: "loginUrl",
96
+ type: "url",
97
+ label: "Login URL",
98
+ default: "/login",
99
+ },
100
+ {
101
+ id: "passwordRequirementText",
102
+ type: "text",
103
+ label: "Password Requirement",
104
+ default:
105
+ "Password must be at least 8 characters with uppercase, lowercase, and a number",
106
+ },
107
+ {
108
+ id: "backgroundColor",
109
+ type: "color",
110
+ label: "Background Color",
111
+ default: "#F9FAFB",
112
+ },
113
+ {
114
+ id: "cardBackground",
115
+ type: "color",
116
+ label: "Card Background",
117
+ default: "#FFFFFF",
118
+ },
119
+ {
120
+ id: "primaryColor",
121
+ type: "color",
122
+ label: "Primary Color (buttons)",
123
+ default: "#2563EB",
124
+ },
125
+ {
126
+ id: "textColor",
127
+ type: "color",
128
+ label: "Heading Text Color",
129
+ default: "#111827",
130
+ },
131
+ {
132
+ id: "cardBorderRadius",
133
+ type: "select",
134
+ label: "Card Border Radius",
135
+ default: "2xl",
136
+ options: [
137
+ { label: "Small", value: "lg" },
138
+ { label: "Medium", value: "xl" },
139
+ { label: "Large", value: "2xl" },
140
+ { label: "Extra Large", value: "3xl" },
141
+ ],
142
+ },
143
+ ];
144
+
145
+ export const authRegisterSchema: SectionSchema = {
146
+ type: "my-simple-auth-register",
147
+ name: "Auth Register",
148
+ description: "Registration form with email, username, and password",
149
+ category: "auth",
150
+ icon: "user-plus",
151
+ settings: commonSettings,
152
+ templates: [
153
+ {
154
+ id: "default",
155
+ name: "Default Register",
156
+ description: "Clean registration form with validation",
157
+ isDefault: true,
158
+ },
159
+ ],
160
+ defaults: {
161
+ settings: {
162
+ heading: "Create Account",
163
+ subheading:
164
+ "Create an account to get exclusive offers and track your orders",
165
+ emailLabel: "Email",
166
+ emailPlaceholder: "example@email.com",
167
+ usernameLabel: "Username",
168
+ usernamePlaceholder: "Enter a username",
169
+ passwordLabel: "Password",
170
+ passwordPlaceholder: "At least 8 characters",
171
+ confirmPasswordLabel: "Confirm Password",
172
+ confirmPasswordPlaceholder: "Re-enter your password",
173
+ submitButtonText: "Sign Up",
174
+ loadingText: "Creating account...",
175
+ loginPromptText: "Already have an account?",
176
+ loginLinkText: "Sign in",
177
+ loginUrl: "/login",
178
+ passwordRequirementText:
179
+ "Password must be at least 8 characters with uppercase, lowercase, and a number",
180
+ backgroundColor: "#F9FAFB",
181
+ cardBackground: "#FFFFFF",
182
+ primaryColor: "#2563EB",
183
+ textColor: "#111827",
184
+ cardBorderRadius: "2xl",
185
+ },
186
+ },
187
+ tags: ["auth", "register", "sign-up"],
188
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Auth Register Section
3
+ * Exports schema and component templates
4
+ */
5
+
6
+ import type { SectionComponentProps } from "@onexapis/core/types";
7
+ import { AuthRegisterDefault } from "./auth-register-default";
8
+
9
+ export const authRegisterComponents: Record<
10
+ string,
11
+ React.ComponentType<SectionComponentProps>
12
+ > = { default: AuthRegisterDefault };
13
+
14
+ export { authRegisterSchema } from "./auth-register.schema";