generator-kodly-react-app 1.0.14 → 1.0.16

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 (92) hide show
  1. package/generators/app/index.js +4 -0
  2. package/generators/app/templates/.env.dev +1 -1
  3. package/generators/app/templates/.env.sandbox +2 -2
  4. package/generators/app/templates/I18N_MIGRATION.md +28 -35
  5. package/generators/app/templates/STRUCTURE.md +26 -26
  6. package/generators/app/templates/index.html +6 -14
  7. package/generators/app/templates/openapi-ts.config.ts +12 -12
  8. package/generators/app/templates/postcss.config.js +0 -1
  9. package/generators/app/templates/src/app.tsx +20 -20
  10. package/generators/app/templates/src/components/layout/language-switcher.tsx +20 -16
  11. package/generators/app/templates/src/components/layout/page-layout.tsx +31 -0
  12. package/generators/app/templates/src/components/layout/theme-switcher.tsx +15 -14
  13. package/generators/app/templates/src/components/theme/theme-provider.tsx +20 -13
  14. package/generators/app/templates/src/components/ui/button.tsx +15 -14
  15. package/generators/app/templates/src/components/ui/card.tsx +23 -16
  16. package/generators/app/templates/src/components/ui/field.tsx +35 -35
  17. package/generators/app/templates/src/components/ui/form.tsx +66 -30
  18. package/generators/app/templates/src/components/ui/input-group.tsx +24 -24
  19. package/generators/app/templates/src/components/ui/input.tsx +8 -8
  20. package/generators/app/templates/src/components/ui/label.tsx +9 -9
  21. package/generators/app/templates/src/components/ui/select.tsx +0 -1
  22. package/generators/app/templates/src/components/ui/separator.tsx +10 -10
  23. package/generators/app/templates/src/components/ui/textarea.tsx +7 -7
  24. package/generators/app/templates/src/index.css +12 -2
  25. package/generators/app/templates/src/lib/i18n.ts +16 -14
  26. package/generators/app/templates/src/lib/routes.ts +2 -3
  27. package/generators/app/templates/src/lib/utils/error-handler.ts +21 -14
  28. package/generators/app/templates/src/lib/utils.ts +3 -3
  29. package/generators/app/templates/src/locales/index.ts +12 -12
  30. package/generators/app/templates/src/locales/ja/theme.json +0 -1
  31. package/generators/app/templates/src/main.tsx +10 -12
  32. package/generators/app/templates/src/modules/app/layouts/app-layout.tsx +14 -25
  33. package/generators/app/templates/src/modules/app/locales/app-en.json +0 -1
  34. package/generators/app/templates/src/modules/app/locales/app-ja.json +0 -1
  35. package/generators/app/templates/src/modules/auth/components/auth-form.tsx +83 -0
  36. package/generators/app/templates/src/modules/auth/components/forgot-password-form.tsx +27 -52
  37. package/generators/app/templates/src/modules/auth/components/login-form.tsx +42 -72
  38. package/generators/app/templates/src/modules/auth/components/login-link.tsx +12 -0
  39. package/generators/app/templates/src/modules/auth/components/reset-password-form.tsx +46 -92
  40. package/generators/app/templates/src/modules/auth/components/signup-form.tsx +35 -71
  41. package/generators/app/templates/src/modules/auth/contexts/auth-context.tsx +10 -6
  42. package/generators/app/templates/src/modules/auth/hooks/use-auth-hook.ts +51 -36
  43. package/generators/app/templates/src/modules/auth/layouts/auth-layout.tsx +12 -15
  44. package/generators/app/templates/src/modules/auth/locales/auth-en.json +0 -1
  45. package/generators/app/templates/src/modules/auth/locales/auth-ja.json +0 -1
  46. package/generators/app/templates/src/modules/auth/schemas/form-schemas.ts +14 -10
  47. package/generators/app/templates/src/modules/landing/components/auth-hero.tsx +20 -18
  48. package/generators/app/templates/src/modules/landing/components/welcome-hero.tsx +13 -11
  49. package/generators/app/templates/src/modules/landing/landing-page-layout.tsx +1 -24
  50. package/generators/app/templates/src/modules/landing/landing-page.tsx +11 -6
  51. package/generators/app/templates/src/modules/landing/layouts/landing-page-layout.tsx +2 -21
  52. package/generators/app/templates/src/modules/landing/locales/landing-en.json +0 -1
  53. package/generators/app/templates/src/openapi-client-config.ts +1 -1
  54. package/generators/app/templates/src/routeTree.gen.ts +188 -188
  55. package/generators/app/templates/src/router.tsx +2 -2
  56. package/generators/app/templates/src/routes/$.tsx +0 -1
  57. package/generators/app/templates/src/routes/__root.tsx +2 -2
  58. package/generators/app/templates/src/routes/_landing/index.tsx +3 -3
  59. package/generators/app/templates/src/routes/_landing/route.tsx +3 -3
  60. package/generators/app/templates/src/routes/app/index.tsx +6 -6
  61. package/generators/app/templates/src/routes/app/route.tsx +4 -4
  62. package/generators/app/templates/src/routes/auth/forgot-password.tsx +1 -1
  63. package/generators/app/templates/src/routes/auth/login.tsx +3 -3
  64. package/generators/app/templates/src/routes/auth/reset-password.tsx +3 -3
  65. package/generators/app/templates/src/routes/auth/route.tsx +12 -7
  66. package/generators/app/templates/src/routes/auth/signup.tsx +1 -2
  67. package/generators/app/templates/src/sdk/@tanstack/react-query.gen.ts +157 -76
  68. package/generators/app/templates/src/sdk/client/client.gen.ts +35 -37
  69. package/generators/app/templates/src/sdk/client/index.ts +8 -8
  70. package/generators/app/templates/src/sdk/client/types.gen.ts +22 -19
  71. package/generators/app/templates/src/sdk/client/utils.gen.ts +53 -45
  72. package/generators/app/templates/src/sdk/client.gen.ts +18 -5
  73. package/generators/app/templates/src/sdk/core/auth.gen.ts +6 -6
  74. package/generators/app/templates/src/sdk/core/bodySerializer.gen.ts +25 -27
  75. package/generators/app/templates/src/sdk/core/params.gen.ts +12 -12
  76. package/generators/app/templates/src/sdk/core/pathSerializer.gen.ts +40 -41
  77. package/generators/app/templates/src/sdk/core/queryKeySerializer.gen.ts +12 -29
  78. package/generators/app/templates/src/sdk/core/serverSentEvents.gen.ts +26 -24
  79. package/generators/app/templates/src/sdk/core/types.gen.ts +17 -15
  80. package/generators/app/templates/src/sdk/core/utils.gen.ts +18 -18
  81. package/generators/app/templates/src/sdk/index.ts +40 -2
  82. package/generators/app/templates/src/sdk/schemas.gen.ts +108 -166
  83. package/generators/app/templates/src/sdk/sdk.gen.ts +145 -63
  84. package/generators/app/templates/src/sdk/types.gen.ts +90 -84
  85. package/generators/app/templates/src/sdk/zod.gen.ts +57 -74
  86. package/generators/app/templates/src/types/i18n.d.ts +0 -1
  87. package/generators/app/templates/tailwind.config.js +0 -1
  88. package/generators/app/templates/tsconfig.app.json +0 -1
  89. package/generators/app/templates/tsconfig.json +0 -1
  90. package/generators/app/templates/tsr.config.json +4 -0
  91. package/generators/app/templates/vite.config.js +13 -12
  92. package/package.json +2 -4
@@ -0,0 +1,83 @@
1
+ import type { ReactNode } from "react";
2
+ import type {
3
+ FieldPath,
4
+ FieldValues,
5
+ SubmitHandler,
6
+ UseFormReturn,
7
+ } from "react-hook-form";
8
+ import { Button } from "@/components/ui/button";
9
+ import { Input } from "@/components/ui/input";
10
+ import {
11
+ Form,
12
+ FormControl,
13
+ FormField,
14
+ FormItem,
15
+ FormLabel,
16
+ FormMessage,
17
+ } from "@/components/ui/form";
18
+
19
+ type AuthField<T extends FieldValues> = {
20
+ name: FieldPath<T>;
21
+ label: string;
22
+ placeholder: string;
23
+ type: "text" | "email" | "password";
24
+ autoComplete: string;
25
+ autoFocus?: boolean;
26
+ readOnly?: boolean;
27
+ };
28
+
29
+ export function AuthForm<T extends FieldValues>({
30
+ form,
31
+ title,
32
+ fields,
33
+ onSubmit,
34
+ isPending,
35
+ submitLabel,
36
+ children,
37
+ }: {
38
+ form: UseFormReturn<T>;
39
+ title: string;
40
+ fields: AuthField<T>[];
41
+ onSubmit: SubmitHandler<T>;
42
+ isPending: boolean;
43
+ submitLabel: string;
44
+ children?: ReactNode;
45
+ }) {
46
+ return (
47
+ <div className="flex flex-col gap-6">
48
+ <h1 className="text-2xl font-semibold">{title}</h1>
49
+ <Form {...form}>
50
+ <form
51
+ noValidate
52
+ className="flex flex-col gap-4"
53
+ onSubmit={form.handleSubmit(onSubmit)}
54
+ >
55
+ {fields.map(({ name, label, ...input }) => (
56
+ <FormField
57
+ key={name}
58
+ control={form.control}
59
+ name={name}
60
+ render={({ field }) => (
61
+ <FormItem>
62
+ <FormLabel>{label} *</FormLabel>
63
+ <FormControl>
64
+ <Input
65
+ {...input}
66
+ {...field}
67
+ value={typeof field.value === "string" ? field.value : ""}
68
+ />
69
+ </FormControl>
70
+ <FormMessage />
71
+ </FormItem>
72
+ )}
73
+ />
74
+ ))}
75
+ <Button type="submit" disabled={isPending}>
76
+ {submitLabel}
77
+ </Button>
78
+ </form>
79
+ </Form>
80
+ {children}
81
+ </div>
82
+ );
83
+ }
@@ -1,14 +1,11 @@
1
- import { Button } from '@/components/ui/button';
2
- import { Input } from '@/components/ui/input';
3
- import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
4
- import { useSendOtp } from '@/modules/auth/hooks/use-auth-hook';
5
- import { z } from 'zod';
6
- import { zodResolver } from '@hookform/resolvers/zod';
7
- import { useForm } from 'react-hook-form';
8
- import { useTranslation } from 'react-i18next';
9
- import { Link } from '@tanstack/react-router';
10
- import { Route as LoginRoute } from '@/routes/auth/login';
11
- import { forgotPasswordFormDefaults } from '@/modules/auth/schemas/form-schemas';
1
+ import { AuthForm } from "./auth-form";
2
+ import { useSendOtp } from "@/modules/auth/hooks/use-auth-hook";
3
+ import { z } from "zod";
4
+ import { zodResolver } from "@hookform/resolvers/zod";
5
+ import { useForm } from "react-hook-form";
6
+ import { useTranslation } from "react-i18next";
7
+ import { LoginLink } from "./login-link";
8
+ import { forgotPasswordFormDefaults } from "@/modules/auth/schemas/form-schemas";
12
9
 
13
10
  const zForgotPasswordDto = z.object({
14
11
  email: z.email().min(1).max(256),
@@ -29,46 +26,24 @@ export function ForgotPasswordForm() {
29
26
  };
30
27
 
31
28
  return (
32
- <div className='flex flex-col gap-6'>
33
- <h1 className='text-2xl font-semibold'>{t('auth.forgotPassword.title')}</h1>
34
- <Form {...form}>
35
- <form
36
- noValidate
37
- className='flex flex-col gap-4'
38
- onSubmit={form.handleSubmit(onSubmit)}>
39
- <FormField
40
- control={form.control}
41
- name='email'
42
- render={({ field }) => (
43
- <FormItem>
44
- <FormLabel>{t('auth.forgotPassword.email')} *</FormLabel>
45
- <FormControl>
46
- <Input
47
- type='email'
48
- placeholder={t('auth.forgotPassword.emailPlaceholder')}
49
- autoComplete='email'
50
- autoFocus
51
- {...field}
52
- />
53
- </FormControl>
54
- <FormMessage />
55
- </FormItem>
56
- )}
57
- />
58
- <Button
59
- type='submit'
60
- disabled={isPending}>
61
- {t('auth.forgotPassword.submit')}
62
- </Button>
63
- </form>
64
- </Form>
65
- <div className='text-sm text-center'>
66
- <Link
67
- to={LoginRoute.to}
68
- className='text-primary hover:underline'>
69
- {t('auth.forgotPassword.loginLink')}
70
- </Link>
71
- </div>
72
- </div>
29
+ <AuthForm
30
+ form={form}
31
+ title={t("auth.forgotPassword.title")}
32
+ onSubmit={onSubmit}
33
+ isPending={isPending}
34
+ submitLabel={t("auth.forgotPassword.submit")}
35
+ fields={[
36
+ {
37
+ name: "email",
38
+ label: t("auth.forgotPassword.email"),
39
+ placeholder: t("auth.forgotPassword.emailPlaceholder"),
40
+ type: "email",
41
+ autoComplete: "email",
42
+ autoFocus: true,
43
+ },
44
+ ]}
45
+ >
46
+ <LoginLink label={t("auth.forgotPassword.loginLink")} />
47
+ </AuthForm>
73
48
  );
74
49
  }
@@ -1,16 +1,14 @@
1
- import { Button } from '@/components/ui/button';
2
- import { Input } from '@/components/ui/input';
3
- import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
4
- import { useLogin } from '@/modules/auth/hooks/use-auth-hook';
5
- import { zUserLoginDto } from '@/sdk/zod.gen';
6
- import { zodResolver } from '@hookform/resolvers/zod';
7
- import { useForm } from 'react-hook-form';
8
- import { useTranslation } from 'react-i18next';
9
- import type { z } from 'zod';
10
- import { Link } from '@tanstack/react-router';
11
- import { Route as SignupRoute } from '@/routes/auth/signup';
12
- import { Route as ForgotPasswordRoute } from '@/routes/auth/forgot-password';
13
- import { loginFormDefaults } from '@/modules/auth/schemas/form-schemas';
1
+ import { AuthForm } from "./auth-form";
2
+ import { useLogin } from "@/modules/auth/hooks/use-auth-hook";
3
+ import { zUserLoginDto } from "@/sdk/zod.gen";
4
+ import { zodResolver } from "@hookform/resolvers/zod";
5
+ import { useForm } from "react-hook-form";
6
+ import { useTranslation } from "react-i18next";
7
+ import type { z } from "zod";
8
+ import { Link } from "@tanstack/react-router";
9
+ import { Route as SignupRoute } from "@/routes/auth/signup";
10
+ import { Route as ForgotPasswordRoute } from "@/routes/auth/forgot-password";
11
+ import { loginFormDefaults } from "@/modules/auth/schemas/form-schemas";
14
12
 
15
13
  type LoginFormData = z.infer<typeof zUserLoginDto>;
16
14
 
@@ -27,69 +25,41 @@ export function LoginForm() {
27
25
  };
28
26
 
29
27
  return (
30
- <div className='flex flex-col gap-6'>
31
- <h1 className='text-2xl font-semibold'>{t('auth.login.title')}</h1>
32
- <Form {...form}>
33
- <form
34
- noValidate
35
- className='flex flex-col gap-4'
36
- onSubmit={form.handleSubmit(onSubmit)}>
37
- <FormField
38
- control={form.control}
39
- name='email'
40
- render={({ field }) => (
41
- <FormItem>
42
- <FormLabel>{t('auth.login.email')} *</FormLabel>
43
- <FormControl>
44
- <Input
45
- type='email'
46
- placeholder={t('auth.login.emailPlaceholder')}
47
- autoComplete='email'
48
- autoFocus
49
- {...field}
50
- />
51
- </FormControl>
52
- <FormMessage />
53
- </FormItem>
54
- )}
55
- />
56
- <FormField
57
- control={form.control}
58
- name='password'
59
- render={({ field }) => (
60
- <FormItem>
61
- <FormLabel>{t('auth.login.password')} *</FormLabel>
62
- <FormControl>
63
- <Input
64
- type='password'
65
- placeholder={t('auth.login.passwordPlaceholder')}
66
- autoComplete='current-password'
67
- {...field}
68
- />
69
- </FormControl>
70
- <FormMessage />
71
- </FormItem>
72
- )}
73
- />
74
- <Button
75
- type='submit'
76
- disabled={isPending}>
77
- {t('auth.login.submit')}
78
- </Button>
79
- </form>
80
- </Form>
81
- <div className='flex flex-col gap-2 text-sm text-center'>
28
+ <AuthForm
29
+ form={form}
30
+ title={t("auth.login.title")}
31
+ onSubmit={onSubmit}
32
+ isPending={isPending}
33
+ submitLabel={t("auth.login.submit")}
34
+ fields={[
35
+ {
36
+ name: "email",
37
+ label: t("auth.login.email"),
38
+ placeholder: t("auth.login.emailPlaceholder"),
39
+ type: "email",
40
+ autoComplete: "email",
41
+ autoFocus: true,
42
+ },
43
+ {
44
+ name: "password",
45
+ label: t("auth.login.password"),
46
+ placeholder: t("auth.login.passwordPlaceholder"),
47
+ type: "password",
48
+ autoComplete: "current-password",
49
+ },
50
+ ]}
51
+ >
52
+ <div className="flex flex-col gap-2 text-sm text-center">
82
53
  <Link
83
54
  to={ForgotPasswordRoute.to}
84
- className='text-primary hover:underline'>
85
- {t('auth.login.forgotPasswordLink')}
55
+ className="text-primary hover:underline"
56
+ >
57
+ {t("auth.login.forgotPasswordLink")}
86
58
  </Link>
87
- <Link
88
- to={SignupRoute.to}
89
- className='text-primary hover:underline'>
90
- {t('auth.login.signupLink')}
59
+ <Link to={SignupRoute.to} className="text-primary hover:underline">
60
+ {t("auth.login.signupLink")}
91
61
  </Link>
92
62
  </div>
93
- </div>
63
+ </AuthForm>
94
64
  );
95
65
  }
@@ -0,0 +1,12 @@
1
+ import { Link } from "@tanstack/react-router";
2
+ import { Route as LoginRoute } from "@/routes/auth/login";
3
+
4
+ export function LoginLink({ label }: { label: string }) {
5
+ return (
6
+ <div className="text-sm text-center">
7
+ <Link to={LoginRoute.to} className="text-primary hover:underline">
8
+ {label}
9
+ </Link>
10
+ </div>
11
+ );
12
+ }
@@ -1,27 +1,25 @@
1
- import { Button } from '@/components/ui/button';
2
- import { Input } from '@/components/ui/input';
3
- import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
4
- import { useResetPassword } from '@/modules/auth/hooks/use-auth-hook';
5
- import { zUserResetPasswordDto } from '@/sdk/zod.gen';
6
- import { zodResolver } from '@hookform/resolvers/zod';
7
- import { useForm } from 'react-hook-form';
8
- import { useTranslation } from 'react-i18next';
9
- import type { z } from 'zod';
10
- import { Link, useSearch } from '@tanstack/react-router';
11
- import { Route as LoginRoute } from '@/routes/auth/login';
12
- import { resetPasswordFormDefaults } from '@/modules/auth/schemas/form-schemas';
1
+ import { AuthForm } from "./auth-form";
2
+ import { useResetPassword } from "@/modules/auth/hooks/use-auth-hook";
3
+ import { zUserResetPasswordDto } from "@/sdk/zod.gen";
4
+ import { zodResolver } from "@hookform/resolvers/zod";
5
+ import { useForm } from "react-hook-form";
6
+ import { useTranslation } from "react-i18next";
7
+ import type { z } from "zod";
8
+ import { useSearch } from "@tanstack/react-router";
9
+ import { LoginLink } from "./login-link";
10
+ import { resetPasswordFormDefaults } from "@/modules/auth/schemas/form-schemas";
13
11
 
14
12
  type ResetPasswordFormData = z.infer<typeof zUserResetPasswordDto>;
15
13
 
16
14
  export function ResetPasswordForm() {
17
15
  const { t } = useTranslation();
18
16
  const { mutate, isPending } = useResetPassword();
19
- const search = useSearch({ from: '/auth/reset-password' });
17
+ const search = useSearch({ from: "/auth/reset-password" });
20
18
  const form = useForm<ResetPasswordFormData>({
21
19
  resolver: zodResolver(zUserResetPasswordDto),
22
20
  defaultValues: {
23
21
  ...resetPasswordFormDefaults,
24
- email: search.email || '',
22
+ email: search.email || "",
25
23
  },
26
24
  });
27
25
 
@@ -30,83 +28,39 @@ export function ResetPasswordForm() {
30
28
  };
31
29
 
32
30
  return (
33
- <div className='flex flex-col gap-6'>
34
- <h1 className='text-2xl font-semibold'>{t('auth.resetPassword.title')}</h1>
35
- <Form {...form}>
36
- <form
37
- noValidate
38
- className='flex flex-col gap-4'
39
- onSubmit={form.handleSubmit(onSubmit)}>
40
- <FormField
41
- control={form.control}
42
- name='email'
43
- render={({ field }) => (
44
- <FormItem>
45
- <FormLabel>{t('auth.resetPassword.email')} *</FormLabel>
46
- <FormControl>
47
- <Input
48
- type='email'
49
- placeholder={t('auth.resetPassword.emailPlaceholder')}
50
- autoComplete='email'
51
- readOnly
52
- {...field}
53
- />
54
- </FormControl>
55
- <FormMessage />
56
- </FormItem>
57
- )}
58
- />
59
- <FormField
60
- control={form.control}
61
- name='otp'
62
- render={({ field }) => (
63
- <FormItem>
64
- <FormLabel>{t('auth.resetPassword.otp')} *</FormLabel>
65
- <FormControl>
66
- <Input
67
- type='text'
68
- placeholder={t('auth.resetPassword.otpPlaceholder')}
69
- autoComplete='one-time-code'
70
- autoFocus
71
- {...field}
72
- />
73
- </FormControl>
74
- <FormMessage />
75
- </FormItem>
76
- )}
77
- />
78
- <FormField
79
- control={form.control}
80
- name='password'
81
- render={({ field }) => (
82
- <FormItem>
83
- <FormLabel>{t('auth.resetPassword.password')} *</FormLabel>
84
- <FormControl>
85
- <Input
86
- type='password'
87
- placeholder={t('auth.resetPassword.passwordPlaceholder')}
88
- autoComplete='new-password'
89
- {...field}
90
- />
91
- </FormControl>
92
- <FormMessage />
93
- </FormItem>
94
- )}
95
- />
96
- <Button
97
- type='submit'
98
- disabled={isPending}>
99
- {t('auth.resetPassword.submit')}
100
- </Button>
101
- </form>
102
- </Form>
103
- <div className='text-sm text-center'>
104
- <Link
105
- to={LoginRoute.to}
106
- className='text-primary hover:underline'>
107
- {t('auth.forgotPassword.loginLink')}
108
- </Link>
109
- </div>
110
- </div>
31
+ <AuthForm
32
+ form={form}
33
+ title={t("auth.resetPassword.title")}
34
+ onSubmit={onSubmit}
35
+ isPending={isPending}
36
+ submitLabel={t("auth.resetPassword.submit")}
37
+ fields={[
38
+ {
39
+ name: "email",
40
+ label: t("auth.resetPassword.email"),
41
+ placeholder: t("auth.resetPassword.emailPlaceholder"),
42
+ type: "email",
43
+ autoComplete: "email",
44
+ readOnly: true,
45
+ },
46
+ {
47
+ name: "otp",
48
+ label: t("auth.resetPassword.otp"),
49
+ placeholder: t("auth.resetPassword.otpPlaceholder"),
50
+ type: "text",
51
+ autoComplete: "one-time-code",
52
+ autoFocus: true,
53
+ },
54
+ {
55
+ name: "password",
56
+ label: t("auth.resetPassword.password"),
57
+ placeholder: t("auth.resetPassword.passwordPlaceholder"),
58
+ type: "password",
59
+ autoComplete: "new-password",
60
+ },
61
+ ]}
62
+ >
63
+ <LoginLink label={t("auth.forgotPassword.loginLink")} />
64
+ </AuthForm>
111
65
  );
112
66
  }
@@ -1,15 +1,12 @@
1
- import { Button } from '@/components/ui/button';
2
- import { Input } from '@/components/ui/input';
3
- import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
4
- import { useSignup } from '@/modules/auth/hooks/use-auth-hook';
5
- import { zUserSignupDto } from '@/sdk/zod.gen';
6
- import { zodResolver } from '@hookform/resolvers/zod';
7
- import { useForm } from 'react-hook-form';
8
- import { useTranslation } from 'react-i18next';
9
- import { Link } from '@tanstack/react-router';
10
- import { Route as LoginRoute } from '@/routes/auth/login';
11
- import { z } from 'zod';
12
- import { signupFormDefaults } from '@/modules/auth/schemas/form-schemas';
1
+ import { AuthForm } from "./auth-form";
2
+ import { useSignup } from "@/modules/auth/hooks/use-auth-hook";
3
+ import { zUserSignupDto } from "@/sdk/zod.gen";
4
+ import { zodResolver } from "@hookform/resolvers/zod";
5
+ import { useForm } from "react-hook-form";
6
+ import { useTranslation } from "react-i18next";
7
+ import { LoginLink } from "./login-link";
8
+ import { z } from "zod";
9
+ import { signupFormDefaults } from "@/modules/auth/schemas/form-schemas";
13
10
 
14
11
  type SignupFormData = z.infer<typeof zUserSignupDto>;
15
12
 
@@ -29,64 +26,31 @@ export function SignupForm() {
29
26
  };
30
27
 
31
28
  return (
32
- <div className='flex flex-col gap-6'>
33
- <h1 className='text-2xl font-semibold'>{t('auth.signup.title')}</h1>
34
- <Form {...form}>
35
- <form
36
- noValidate
37
- className='flex flex-col gap-4'
38
- onSubmit={form.handleSubmit(onSubmit)}>
39
- <FormField
40
- control={form.control}
41
- name='email'
42
- render={({ field }) => (
43
- <FormItem>
44
- <FormLabel>{t('auth.signup.email')} *</FormLabel>
45
- <FormControl>
46
- <Input
47
- type='email'
48
- placeholder={t('auth.signup.emailPlaceholder')}
49
- autoComplete='email'
50
- autoFocus
51
- {...field}
52
- />
53
- </FormControl>
54
- <FormMessage />
55
- </FormItem>
56
- )}
57
- />
58
- <FormField
59
- control={form.control}
60
- name='password'
61
- render={({ field }) => (
62
- <FormItem>
63
- <FormLabel>{t('auth.signup.password')} *</FormLabel>
64
- <FormControl>
65
- <Input
66
- type='password'
67
- placeholder={t('auth.signup.passwordPlaceholder')}
68
- autoComplete='new-password'
69
- {...field}
70
- />
71
- </FormControl>
72
- <FormMessage />
73
- </FormItem>
74
- )}
75
- />
76
- <Button
77
- type='submit'
78
- disabled={isPending}>
79
- {t('auth.signup.submit')}
80
- </Button>
81
- </form>
82
- </Form>
83
- <div className='text-sm text-center'>
84
- <Link
85
- to={LoginRoute.to}
86
- className='text-primary hover:underline'>
87
- {t('auth.signup.loginLink')}
88
- </Link>
89
- </div>
90
- </div>
29
+ <AuthForm
30
+ form={form}
31
+ title={t("auth.signup.title")}
32
+ onSubmit={onSubmit}
33
+ isPending={isPending}
34
+ submitLabel={t("auth.signup.submit")}
35
+ fields={[
36
+ {
37
+ name: "email",
38
+ label: t("auth.signup.email"),
39
+ placeholder: t("auth.signup.emailPlaceholder"),
40
+ type: "email",
41
+ autoComplete: "email",
42
+ autoFocus: true,
43
+ },
44
+ {
45
+ name: "password",
46
+ label: t("auth.signup.password"),
47
+ placeholder: t("auth.signup.passwordPlaceholder"),
48
+ type: "password",
49
+ autoComplete: "new-password",
50
+ },
51
+ ]}
52
+ >
53
+ <LoginLink label={t("auth.signup.loginLink")} />
54
+ </AuthForm>
91
55
  );
92
56
  }
@@ -1,11 +1,15 @@
1
- import { createContext } from 'react';
2
- import { currentUserDetailsAtom } from '@/modules/auth/hooks/use-auth-hook';
3
- import type { AuthResponseDtoUserDetailDto } from '@/sdk';
4
- import { useAtomValue } from 'jotai';
1
+ import { createContext } from "react";
2
+ import { currentUserDetailsAtom } from "@/modules/auth/hooks/use-auth-hook";
3
+ import type { AuthResponseDtoUserDetailDto } from "@/sdk";
4
+ import { useAtomValue } from "jotai";
5
5
 
6
- export const AuthContext = createContext<AuthResponseDtoUserDetailDto | undefined>(undefined);
6
+ export const AuthContext = createContext<
7
+ AuthResponseDtoUserDetailDto | undefined
8
+ >(undefined);
7
9
 
8
10
  export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
9
11
  const authData = useAtomValue(currentUserDetailsAtom);
10
- return <AuthContext.Provider value={authData}>{children}</AuthContext.Provider>;
12
+ return (
13
+ <AuthContext.Provider value={authData}>{children}</AuthContext.Provider>
14
+ );
11
15
  };