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.
- package/generators/app/index.js +4 -0
- package/generators/app/templates/.env.dev +1 -1
- package/generators/app/templates/.env.sandbox +2 -2
- package/generators/app/templates/I18N_MIGRATION.md +28 -35
- package/generators/app/templates/STRUCTURE.md +26 -26
- package/generators/app/templates/index.html +6 -14
- package/generators/app/templates/openapi-ts.config.ts +12 -12
- package/generators/app/templates/postcss.config.js +0 -1
- package/generators/app/templates/src/app.tsx +20 -20
- package/generators/app/templates/src/components/layout/language-switcher.tsx +20 -16
- package/generators/app/templates/src/components/layout/page-layout.tsx +31 -0
- package/generators/app/templates/src/components/layout/theme-switcher.tsx +15 -14
- package/generators/app/templates/src/components/theme/theme-provider.tsx +20 -13
- package/generators/app/templates/src/components/ui/button.tsx +15 -14
- package/generators/app/templates/src/components/ui/card.tsx +23 -16
- package/generators/app/templates/src/components/ui/field.tsx +35 -35
- package/generators/app/templates/src/components/ui/form.tsx +66 -30
- package/generators/app/templates/src/components/ui/input-group.tsx +24 -24
- package/generators/app/templates/src/components/ui/input.tsx +8 -8
- package/generators/app/templates/src/components/ui/label.tsx +9 -9
- package/generators/app/templates/src/components/ui/select.tsx +0 -1
- package/generators/app/templates/src/components/ui/separator.tsx +10 -10
- package/generators/app/templates/src/components/ui/textarea.tsx +7 -7
- package/generators/app/templates/src/index.css +12 -2
- package/generators/app/templates/src/lib/i18n.ts +16 -14
- package/generators/app/templates/src/lib/routes.ts +2 -3
- package/generators/app/templates/src/lib/utils/error-handler.ts +21 -14
- package/generators/app/templates/src/lib/utils.ts +3 -3
- package/generators/app/templates/src/locales/index.ts +12 -12
- package/generators/app/templates/src/locales/ja/theme.json +0 -1
- package/generators/app/templates/src/main.tsx +10 -12
- package/generators/app/templates/src/modules/app/layouts/app-layout.tsx +14 -25
- package/generators/app/templates/src/modules/app/locales/app-en.json +0 -1
- package/generators/app/templates/src/modules/app/locales/app-ja.json +0 -1
- package/generators/app/templates/src/modules/auth/components/auth-form.tsx +83 -0
- package/generators/app/templates/src/modules/auth/components/forgot-password-form.tsx +27 -52
- package/generators/app/templates/src/modules/auth/components/login-form.tsx +42 -72
- package/generators/app/templates/src/modules/auth/components/login-link.tsx +12 -0
- package/generators/app/templates/src/modules/auth/components/reset-password-form.tsx +46 -92
- package/generators/app/templates/src/modules/auth/components/signup-form.tsx +35 -71
- package/generators/app/templates/src/modules/auth/contexts/auth-context.tsx +10 -6
- package/generators/app/templates/src/modules/auth/hooks/use-auth-hook.ts +51 -36
- package/generators/app/templates/src/modules/auth/layouts/auth-layout.tsx +12 -15
- package/generators/app/templates/src/modules/auth/locales/auth-en.json +0 -1
- package/generators/app/templates/src/modules/auth/locales/auth-ja.json +0 -1
- package/generators/app/templates/src/modules/auth/schemas/form-schemas.ts +14 -10
- package/generators/app/templates/src/modules/landing/components/auth-hero.tsx +20 -18
- package/generators/app/templates/src/modules/landing/components/welcome-hero.tsx +13 -11
- package/generators/app/templates/src/modules/landing/landing-page-layout.tsx +1 -24
- package/generators/app/templates/src/modules/landing/landing-page.tsx +11 -6
- package/generators/app/templates/src/modules/landing/layouts/landing-page-layout.tsx +2 -21
- package/generators/app/templates/src/modules/landing/locales/landing-en.json +0 -1
- package/generators/app/templates/src/openapi-client-config.ts +1 -1
- package/generators/app/templates/src/routeTree.gen.ts +188 -188
- package/generators/app/templates/src/router.tsx +2 -2
- package/generators/app/templates/src/routes/$.tsx +0 -1
- package/generators/app/templates/src/routes/__root.tsx +2 -2
- package/generators/app/templates/src/routes/_landing/index.tsx +3 -3
- package/generators/app/templates/src/routes/_landing/route.tsx +3 -3
- package/generators/app/templates/src/routes/app/index.tsx +6 -6
- package/generators/app/templates/src/routes/app/route.tsx +4 -4
- package/generators/app/templates/src/routes/auth/forgot-password.tsx +1 -1
- package/generators/app/templates/src/routes/auth/login.tsx +3 -3
- package/generators/app/templates/src/routes/auth/reset-password.tsx +3 -3
- package/generators/app/templates/src/routes/auth/route.tsx +12 -7
- package/generators/app/templates/src/routes/auth/signup.tsx +1 -2
- package/generators/app/templates/src/sdk/@tanstack/react-query.gen.ts +157 -76
- package/generators/app/templates/src/sdk/client/client.gen.ts +35 -37
- package/generators/app/templates/src/sdk/client/index.ts +8 -8
- package/generators/app/templates/src/sdk/client/types.gen.ts +22 -19
- package/generators/app/templates/src/sdk/client/utils.gen.ts +53 -45
- package/generators/app/templates/src/sdk/client.gen.ts +18 -5
- package/generators/app/templates/src/sdk/core/auth.gen.ts +6 -6
- package/generators/app/templates/src/sdk/core/bodySerializer.gen.ts +25 -27
- package/generators/app/templates/src/sdk/core/params.gen.ts +12 -12
- package/generators/app/templates/src/sdk/core/pathSerializer.gen.ts +40 -41
- package/generators/app/templates/src/sdk/core/queryKeySerializer.gen.ts +12 -29
- package/generators/app/templates/src/sdk/core/serverSentEvents.gen.ts +26 -24
- package/generators/app/templates/src/sdk/core/types.gen.ts +17 -15
- package/generators/app/templates/src/sdk/core/utils.gen.ts +18 -18
- package/generators/app/templates/src/sdk/index.ts +40 -2
- package/generators/app/templates/src/sdk/schemas.gen.ts +108 -166
- package/generators/app/templates/src/sdk/sdk.gen.ts +145 -63
- package/generators/app/templates/src/sdk/types.gen.ts +90 -84
- package/generators/app/templates/src/sdk/zod.gen.ts +57 -74
- package/generators/app/templates/src/types/i18n.d.ts +0 -1
- package/generators/app/templates/tailwind.config.js +0 -1
- package/generators/app/templates/tsconfig.app.json +0 -1
- package/generators/app/templates/tsconfig.json +0 -1
- package/generators/app/templates/tsr.config.json +4 -0
- package/generators/app/templates/vite.config.js +13 -12
- package/package.json +2 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Route as LoginRoute } from
|
|
1
|
+
import { Route as LoginRoute } from "@/routes/auth/login";
|
|
2
2
|
import type {
|
|
3
3
|
AuthResponseDtoUserDetailDto,
|
|
4
4
|
LoginUserAuthResponse,
|
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
ResetPasswordUserAuthResponse,
|
|
7
7
|
SendOtpUserAuthResponse,
|
|
8
8
|
ValidateTokenUserAuthResponse,
|
|
9
|
-
} from
|
|
9
|
+
} from "@/sdk";
|
|
10
10
|
import {
|
|
11
11
|
loginUserAuthMutation,
|
|
12
12
|
logoutUserAuthMutation,
|
|
@@ -14,31 +14,38 @@ import {
|
|
|
14
14
|
resetPasswordUserAuthMutation,
|
|
15
15
|
sendOtpUserAuthMutation,
|
|
16
16
|
validateTokenUserAuthMutation,
|
|
17
|
-
} from
|
|
18
|
-
import { client } from
|
|
19
|
-
import { useMutation } from
|
|
20
|
-
import { useNavigate } from
|
|
21
|
-
import { atom, useAtomValue, useSetAtom } from
|
|
22
|
-
import { atomWithStorage } from
|
|
23
|
-
import { useTranslation } from
|
|
24
|
-
import { toast } from
|
|
25
|
-
import { SupportedLanguages } from
|
|
26
|
-
import { DEFAULT_NON_LOGGED_IN_ROUTE } from
|
|
17
|
+
} from "@/sdk/@tanstack/react-query.gen";
|
|
18
|
+
import { client } from "@/sdk/client.gen";
|
|
19
|
+
import { useMutation } from "@tanstack/react-query";
|
|
20
|
+
import { useNavigate } from "@tanstack/react-router";
|
|
21
|
+
import { atom, useAtomValue, useSetAtom } from "jotai";
|
|
22
|
+
import { atomWithStorage } from "jotai/utils";
|
|
23
|
+
import { useTranslation } from "react-i18next";
|
|
24
|
+
import { toast } from "sonner";
|
|
25
|
+
import { SupportedLanguages } from "@/lib/i18n";
|
|
26
|
+
import { DEFAULT_NON_LOGGED_IN_ROUTE } from "@/lib/routes";
|
|
27
27
|
|
|
28
28
|
export const HEADER_KEYS = {
|
|
29
|
-
AUTH_TOKEN:
|
|
30
|
-
ACCEPT_LANGUAGE:
|
|
29
|
+
AUTH_TOKEN: "x-auth-token",
|
|
30
|
+
ACCEPT_LANGUAGE: "accept-language",
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export const LOCAL_STORAGE_KEYS = {
|
|
34
|
-
AUTH_TOKEN:
|
|
34
|
+
AUTH_TOKEN: "authTokenAtom",
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
export const authTokenAtom = atomWithStorage<string>(
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
export const authTokenAtom = atomWithStorage<string>(
|
|
38
|
+
LOCAL_STORAGE_KEYS.AUTH_TOKEN,
|
|
39
|
+
"",
|
|
40
|
+
undefined,
|
|
41
|
+
{
|
|
42
|
+
getOnInit: true,
|
|
43
|
+
},
|
|
44
|
+
);
|
|
40
45
|
|
|
41
|
-
export const currentUserDetailsAtom = atom<
|
|
46
|
+
export const currentUserDetailsAtom = atom<
|
|
47
|
+
AuthResponseDtoUserDetailDto | undefined
|
|
48
|
+
>();
|
|
42
49
|
|
|
43
50
|
export const setTokenInClient = (token?: string | null) => {
|
|
44
51
|
if (token) {
|
|
@@ -72,13 +79,13 @@ export const useLogin = () => {
|
|
|
72
79
|
...loginUserAuthMutation({}),
|
|
73
80
|
onSuccess: (response: LoginUserAuthResponse) => {
|
|
74
81
|
const authData = response.data;
|
|
75
|
-
setAuthToken(authData?.token ||
|
|
82
|
+
setAuthToken(authData?.token || "");
|
|
76
83
|
setCurrentUser(authData);
|
|
77
84
|
setTokenInClient(authData?.token);
|
|
78
85
|
},
|
|
79
86
|
onError: (err) => {
|
|
80
|
-
console.error(
|
|
81
|
-
toast.error(err.response?.data.message || t(
|
|
87
|
+
console.error("Login error:", err);
|
|
88
|
+
toast.error(err.response?.data.message || t("auth.messages.loginFailed"));
|
|
82
89
|
},
|
|
83
90
|
});
|
|
84
91
|
};
|
|
@@ -91,13 +98,15 @@ export const useSignup = () => {
|
|
|
91
98
|
...registerUserAuthMutation({}),
|
|
92
99
|
onSuccess: (response: RegisterUserAuthResponse) => {
|
|
93
100
|
const authData = response.data;
|
|
94
|
-
setAuthToken(authData?.token ||
|
|
101
|
+
setAuthToken(authData?.token || "");
|
|
95
102
|
setCurrentUser(authData);
|
|
96
103
|
setTokenInClient(authData?.token);
|
|
97
104
|
},
|
|
98
105
|
onError: (err) => {
|
|
99
|
-
console.error(
|
|
100
|
-
toast.error(
|
|
106
|
+
console.error("Signup error:", err);
|
|
107
|
+
toast.error(
|
|
108
|
+
err.response?.data.message || t("auth.messages.signupFailed"),
|
|
109
|
+
);
|
|
101
110
|
},
|
|
102
111
|
});
|
|
103
112
|
};
|
|
@@ -113,13 +122,13 @@ export const useValidateToken = () => {
|
|
|
113
122
|
onSuccess: (response: ValidateTokenUserAuthResponse) => {
|
|
114
123
|
const authData = response.data;
|
|
115
124
|
setCurrentUser(authData);
|
|
116
|
-
setAuthToken(authData?.token ||
|
|
125
|
+
setAuthToken(authData?.token || "");
|
|
117
126
|
setTokenInClient(authData?.token);
|
|
118
127
|
},
|
|
119
128
|
onError: (err) => {
|
|
120
|
-
console.error(
|
|
129
|
+
console.error("Validate token error:", err);
|
|
121
130
|
setCurrentUser(undefined);
|
|
122
|
-
setAuthToken(
|
|
131
|
+
setAuthToken("");
|
|
123
132
|
setTokenInClient();
|
|
124
133
|
},
|
|
125
134
|
});
|
|
@@ -132,7 +141,7 @@ export const useLogout = () => {
|
|
|
132
141
|
return useMutation({
|
|
133
142
|
...logoutUserAuthMutation({}),
|
|
134
143
|
onSuccess: () => {
|
|
135
|
-
setAuthToken(
|
|
144
|
+
setAuthToken("");
|
|
136
145
|
setCurrentUser(undefined);
|
|
137
146
|
setTokenInClient();
|
|
138
147
|
navigate({ to: DEFAULT_NON_LOGGED_IN_ROUTE });
|
|
@@ -146,19 +155,21 @@ export const useSendOtp = () => {
|
|
|
146
155
|
return useMutation({
|
|
147
156
|
...sendOtpUserAuthMutation({}),
|
|
148
157
|
onSuccess: (response: SendOtpUserAuthResponse, variables) => {
|
|
149
|
-
toast.success(response.message || t(
|
|
158
|
+
toast.success(response.message || t("auth.messages.otpSentSuccess"));
|
|
150
159
|
// Extract email from the mutation variables and navigate to reset-password
|
|
151
160
|
const email = variables.query?.authId;
|
|
152
161
|
if (email) {
|
|
153
162
|
navigate({
|
|
154
|
-
to:
|
|
163
|
+
to: "/auth/reset-password",
|
|
155
164
|
search: { email },
|
|
156
165
|
});
|
|
157
166
|
}
|
|
158
167
|
},
|
|
159
168
|
onError: (err) => {
|
|
160
|
-
console.error(
|
|
161
|
-
toast.error(
|
|
169
|
+
console.error("Send OTP error:", err);
|
|
170
|
+
toast.error(
|
|
171
|
+
err.response?.data.message || t("auth.messages.otpSendFailed"),
|
|
172
|
+
);
|
|
162
173
|
},
|
|
163
174
|
});
|
|
164
175
|
};
|
|
@@ -169,12 +180,16 @@ export const useResetPassword = () => {
|
|
|
169
180
|
return useMutation({
|
|
170
181
|
...resetPasswordUserAuthMutation({}),
|
|
171
182
|
onSuccess: (response: ResetPasswordUserAuthResponse) => {
|
|
172
|
-
toast.success(
|
|
183
|
+
toast.success(
|
|
184
|
+
response.message || t("auth.messages.passwordResetSuccess"),
|
|
185
|
+
);
|
|
173
186
|
navigate({ to: LoginRoute.to });
|
|
174
187
|
},
|
|
175
188
|
onError: (err) => {
|
|
176
|
-
console.error(
|
|
177
|
-
toast.error(
|
|
189
|
+
console.error("Reset password error:", err);
|
|
190
|
+
toast.error(
|
|
191
|
+
err.response?.data.message || t("auth.messages.passwordResetFailed"),
|
|
192
|
+
);
|
|
178
193
|
},
|
|
179
194
|
});
|
|
180
195
|
};
|
|
@@ -1,28 +1,25 @@
|
|
|
1
|
-
import { LanguageSwitcher } from
|
|
2
|
-
import { ThemeSwitcher } from
|
|
3
|
-
import { Button } from
|
|
4
|
-
import { Home } from
|
|
5
|
-
import { Link } from
|
|
6
|
-
import { DEFAULT_NON_LOGGED_IN_ROUTE } from
|
|
1
|
+
import { LanguageSwitcher } from "@/components/layout/language-switcher";
|
|
2
|
+
import { ThemeSwitcher } from "@/components/layout/theme-switcher";
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
import { Home } from "lucide-react";
|
|
5
|
+
import { Link } from "@tanstack/react-router";
|
|
6
|
+
import { DEFAULT_NON_LOGGED_IN_ROUTE } from "@/lib/routes";
|
|
7
7
|
|
|
8
8
|
export function AuthLayout({ children }: { children: React.ReactNode }) {
|
|
9
9
|
return (
|
|
10
|
-
<div className=
|
|
11
|
-
<div className=
|
|
10
|
+
<div className="flex h-screen items-center justify-center bg-background relative">
|
|
11
|
+
<div className="absolute top-4 left-4">
|
|
12
12
|
<Link to={DEFAULT_NON_LOGGED_IN_ROUTE}>
|
|
13
|
-
<Button
|
|
14
|
-
|
|
15
|
-
size='icon'
|
|
16
|
-
aria-label='Go to home'>
|
|
17
|
-
<Home className='h-4 w-4' />
|
|
13
|
+
<Button variant="outline" size="icon" aria-label="Go to home">
|
|
14
|
+
<Home className="h-4 w-4" />
|
|
18
15
|
</Button>
|
|
19
16
|
</Link>
|
|
20
17
|
</div>
|
|
21
|
-
<div className=
|
|
18
|
+
<div className="absolute top-4 right-4 flex gap-2">
|
|
22
19
|
<ThemeSwitcher />
|
|
23
20
|
<LanguageSwitcher />
|
|
24
21
|
</div>
|
|
25
|
-
<div className=
|
|
22
|
+
<div className="w-full max-w-md p-8">{children}</div>
|
|
26
23
|
</div>
|
|
27
24
|
);
|
|
28
25
|
}
|
|
@@ -1,26 +1,30 @@
|
|
|
1
|
-
import type { z } from
|
|
2
|
-
import {
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import {
|
|
3
|
+
zUserLoginDto,
|
|
4
|
+
zUserSignupDto,
|
|
5
|
+
zUserResetPasswordDto,
|
|
6
|
+
} from "@/sdk/zod.gen";
|
|
3
7
|
|
|
4
8
|
type LoginFormData = z.infer<typeof zUserLoginDto>;
|
|
5
9
|
type SignupFormData = z.infer<typeof zUserSignupDto>;
|
|
6
10
|
type ResetPasswordFormData = z.infer<typeof zUserResetPasswordDto>;
|
|
7
11
|
|
|
8
12
|
export const loginFormDefaults: LoginFormData = {
|
|
9
|
-
email:
|
|
10
|
-
password:
|
|
13
|
+
email: "",
|
|
14
|
+
password: "",
|
|
11
15
|
};
|
|
12
16
|
|
|
13
17
|
export const signupFormDefaults: SignupFormData = {
|
|
14
|
-
email:
|
|
15
|
-
password:
|
|
18
|
+
email: "",
|
|
19
|
+
password: "",
|
|
16
20
|
};
|
|
17
21
|
|
|
18
22
|
export const forgotPasswordFormDefaults = {
|
|
19
|
-
email:
|
|
23
|
+
email: "",
|
|
20
24
|
};
|
|
21
25
|
|
|
22
26
|
export const resetPasswordFormDefaults: ResetPasswordFormData = {
|
|
23
|
-
email:
|
|
24
|
-
password:
|
|
25
|
-
otp:
|
|
27
|
+
email: "",
|
|
28
|
+
password: "",
|
|
29
|
+
otp: "",
|
|
26
30
|
};
|
|
@@ -1,34 +1,36 @@
|
|
|
1
|
-
import { Link } from
|
|
2
|
-
import { Button } from
|
|
3
|
-
import { useTranslation } from
|
|
4
|
-
import { Route as LoginRoute } from
|
|
5
|
-
import { Route as SignupRoute } from
|
|
1
|
+
import { Link } from "@tanstack/react-router";
|
|
2
|
+
import { Button } from "@/components/ui/button";
|
|
3
|
+
import { useTranslation } from "react-i18next";
|
|
4
|
+
import { Route as LoginRoute } from "@/routes/auth/login";
|
|
5
|
+
import { Route as SignupRoute } from "@/routes/auth/signup";
|
|
6
6
|
|
|
7
7
|
export function AuthHero() {
|
|
8
|
-
const { t } = useTranslation(
|
|
8
|
+
const { t } = useTranslation("landing");
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
11
|
<>
|
|
12
|
-
<h1 className=
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6">
|
|
13
|
+
{t("hero.title")}
|
|
14
|
+
</h1>
|
|
15
|
+
<p className="text-xl md:text-2xl text-muted-foreground mb-12 max-w-2xl mx-auto">
|
|
16
|
+
{t("hero.description")}
|
|
17
|
+
</p>
|
|
18
|
+
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
|
|
15
19
|
<Link to={LoginRoute.to}>
|
|
16
|
-
<Button
|
|
17
|
-
|
|
18
|
-
className='w-full sm:w-auto min-w-[150px]'>
|
|
19
|
-
{t('hero.loginButton')}
|
|
20
|
+
<Button size="lg" className="w-full sm:w-auto min-w-[150px]">
|
|
21
|
+
{t("hero.loginButton")}
|
|
20
22
|
</Button>
|
|
21
23
|
</Link>
|
|
22
24
|
<Link to={SignupRoute.to}>
|
|
23
25
|
<Button
|
|
24
|
-
size=
|
|
25
|
-
variant=
|
|
26
|
-
className=
|
|
27
|
-
|
|
26
|
+
size="lg"
|
|
27
|
+
variant="outline"
|
|
28
|
+
className="w-full sm:w-auto min-w-[150px]"
|
|
29
|
+
>
|
|
30
|
+
{t("hero.signupButton")}
|
|
28
31
|
</Button>
|
|
29
32
|
</Link>
|
|
30
33
|
</div>
|
|
31
34
|
</>
|
|
32
35
|
);
|
|
33
36
|
}
|
|
34
|
-
|
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import { Link } from
|
|
2
|
-
import { Button } from
|
|
3
|
-
import { useTranslation } from
|
|
4
|
-
import { DEFAULT_LOGGED_IN_ROUTE } from
|
|
1
|
+
import { Link } from "@tanstack/react-router";
|
|
2
|
+
import { Button } from "@/components/ui/button";
|
|
3
|
+
import { useTranslation } from "react-i18next";
|
|
4
|
+
import { DEFAULT_LOGGED_IN_ROUTE } from "@/lib/routes";
|
|
5
5
|
|
|
6
6
|
export function WelcomeHero() {
|
|
7
7
|
const { t } = useTranslation();
|
|
8
8
|
|
|
9
9
|
return (
|
|
10
10
|
<>
|
|
11
|
-
<h1 className=
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6">
|
|
12
|
+
{t("landing.hero.welcomeTitle")}
|
|
13
|
+
</h1>
|
|
14
|
+
<p className="text-xl md:text-2xl text-muted-foreground mb-12 max-w-2xl mx-auto">
|
|
15
|
+
{t("landing.hero.welcomeDescription")}
|
|
16
|
+
</p>
|
|
17
|
+
<div className="flex justify-center items-center">
|
|
14
18
|
<Link to={DEFAULT_LOGGED_IN_ROUTE}>
|
|
15
|
-
<Button
|
|
16
|
-
|
|
17
|
-
className='w-full sm:w-auto min-w-[150px]'>
|
|
18
|
-
{t('landing.hero.getStartedButton')}
|
|
19
|
+
<Button size="lg" className="w-full sm:w-auto min-w-[150px]">
|
|
20
|
+
{t("landing.hero.getStartedButton")}
|
|
19
21
|
</Button>
|
|
20
22
|
</Link>
|
|
21
23
|
</div>
|
|
@@ -1,24 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { ThemeSwitcher } from '@/components/layout/theme-switcher';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
4
|
-
|
|
5
|
-
export function LandingPageLayout({ children }: { children: React.ReactNode }) {
|
|
6
|
-
const { t } = useTranslation();
|
|
7
|
-
|
|
8
|
-
return (
|
|
9
|
-
<div className='min-h-screen bg-background'>
|
|
10
|
-
<header className='border-b'>
|
|
11
|
-
<div className='container mx-auto flex h-16 items-center justify-between px-4'>
|
|
12
|
-
<div className='flex items-center gap-4'>
|
|
13
|
-
<h1 className='text-xl font-semibold'>{t('app.title')}</h1>
|
|
14
|
-
</div>
|
|
15
|
-
<div className='flex items-center gap-4'>
|
|
16
|
-
<ThemeSwitcher />
|
|
17
|
-
<LanguageSwitcher />
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
</header>
|
|
21
|
-
<main>{children}</main>
|
|
22
|
-
</div>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
1
|
+
export { LandingPageLayout } from "./layouts/landing-page-layout";
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { useAtomValue } from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { useAtomValue } from "jotai";
|
|
2
|
+
import {
|
|
3
|
+
authTokenAtom,
|
|
4
|
+
currentUserDetailsAtom,
|
|
5
|
+
} from "@/modules/auth/hooks/use-auth-hook";
|
|
6
|
+
import { WelcomeHero } from "./components/welcome-hero";
|
|
7
|
+
import { AuthHero } from "./components/auth-hero";
|
|
5
8
|
|
|
6
9
|
export function LandingPage() {
|
|
7
10
|
const token = useAtomValue(authTokenAtom);
|
|
@@ -10,8 +13,10 @@ export function LandingPage() {
|
|
|
10
13
|
const isAuthenticated = token && userData;
|
|
11
14
|
|
|
12
15
|
return (
|
|
13
|
-
<div className=
|
|
14
|
-
<div className=
|
|
16
|
+
<div className="container mx-auto px-4 py-16">
|
|
17
|
+
<div className="max-w-4xl mx-auto text-center">
|
|
18
|
+
{isAuthenticated ? <WelcomeHero /> : <AuthHero />}
|
|
19
|
+
</div>
|
|
15
20
|
</div>
|
|
16
21
|
);
|
|
17
22
|
}
|
|
@@ -1,24 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ThemeSwitcher } from '@/components/layout/theme-switcher';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
1
|
+
import { PageLayout } from "@/components/layout/page-layout";
|
|
4
2
|
|
|
5
3
|
export function LandingPageLayout({ children }: { children: React.ReactNode }) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return (
|
|
9
|
-
<div className='min-h-screen bg-background'>
|
|
10
|
-
<header className='border-b'>
|
|
11
|
-
<div className='container mx-auto flex h-16 items-center justify-between px-4'>
|
|
12
|
-
<div className='flex items-center gap-4'>
|
|
13
|
-
<h1 className='text-xl font-semibold'>{t('app.title')}</h1>
|
|
14
|
-
</div>
|
|
15
|
-
<div className='flex items-center gap-4'>
|
|
16
|
-
<ThemeSwitcher />
|
|
17
|
-
<LanguageSwitcher />
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
</header>
|
|
21
|
-
<main>{children}</main>
|
|
22
|
-
</div>
|
|
23
|
-
);
|
|
4
|
+
return <PageLayout>{children}</PageLayout>;
|
|
24
5
|
}
|