Skip to content

Commit 89580a1

Browse files
committed
home left sidebar links changed to text-forground
1 parent 3c250f8 commit 89580a1

File tree

8 files changed

+228
-11
lines changed

8 files changed

+228
-11
lines changed

.todo

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
- [] tag diye article filter korar somoy case insensitive vabe filter korte hobe
55
- [] jemnon `time & space complexity` ke `time-space-complexity` slug diye filter e aste hobe
66

7+
- [] Show a email is not verified yet ribbon under navbar. Make email verified during oauth signup
8+
79
## Dashboard
810

911
- [] Put a empty article graphics
@@ -25,3 +27,4 @@
2527
- [] PATCH /api/profile: db error on empty string
2628
- [] Study about token previleages
2729
- [] Check cascade behabour of tags
30+
- [] Check for fortify with latest version

src/app/auth/login/page.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ import {
1717
getHookFormErrorMessage,
1818
getServerErrorMessage,
1919
} from "@/utils/form-error";
20+
import { useTranslation } from "@/i18n/use-translation";
2021

2122
const LoginPage = () => {
23+
const { _t } = useTranslation();
2224
const api = new AuthRepository();
2325
const loginMutation = useMutation({
2426
mutationFn: (payload: ILoginFormPayload) => api.login(payload),
@@ -40,14 +42,14 @@ const LoginPage = () => {
4042

4143
return (
4244
<BaseLayout>
43-
<div className="max-w-96 mx-auto my-10">
45+
<div className="max-w-96 mx-auto my-10 px-2">
4446
<form
4547
className="flex flex-col gap-4"
4648
onSubmit={form.handleSubmit(onSubmit)}
4749
method="post"
4850
>
4951
{loginMutation.isError && (
50-
<Alert color="red" title="কিছু ভুল হয়েছে">
52+
<Alert color="red" title={_t("Hands Up")}>
5153
{getServerErrorMessage(loginMutation.error)}
5254
</Alert>
5355
)}
@@ -56,36 +58,38 @@ const LoginPage = () => {
5658
error={getHookFormErrorMessage("email", form?.formState?.errors)}
5759
>
5860
<Input
59-
placeholder="Email"
61+
placeholder={_t("Email")}
6062
type="email"
6163
size="lg"
6264
variant="filled"
6365
{...form.register("email")}
6466
/>
6567
</Input.Wrapper>
68+
6669
<Input.Wrapper
6770
error={getHookFormErrorMessage("password", form?.formState?.errors)}
6871
>
6972
<Input
70-
placeholder="Password"
73+
placeholder={_t("Password")}
7174
type="password"
7275
size="lg"
7376
variant="filled"
7477
{...form.register("password")}
7578
/>
7679
</Input.Wrapper>
80+
7781
<Button type="submit" size="lg" loading={loginMutation?.isPending}>
78-
লগইন
82+
{_t("Login")}
7983
</Button>
8084
</form>
8185

8286
<div className="mt-10 flex flex-col gap-3">
8387
<Link className="text-lg" href={"/auth/forgot-password"}>
84-
পাসসোয়ার্ড ভুলে গেছেন?
88+
{_t("Forgot password?")}
8589
</Link>
8690

8791
<Link className="text-lg" href={"/auth/register"}>
88-
একাউন্ট নিবন্ধন করুন
92+
{_t("Create an account")}
8993
</Link>
9094
</div>
9195
</div>

src/app/auth/register/page.tsx

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
"use client";
2+
import { useForm } from "react-hook-form";
3+
import * as yup from "yup";
4+
import { yupResolver } from "@hookform/resolvers/yup";
5+
import { ErrorMessage } from "@hookform/error-message";
6+
import BaseLayout from "@/components/layout/BaseLayout";
7+
import { Alert, Button, Input, Text } from "@mantine/core";
8+
import Link from "next/link";
9+
import React from "react";
10+
import { AuthRepository } from "@/http/repositories/auth.repository";
11+
import { useMutation } from "@tanstack/react-query";
12+
import { ensureCSRF } from "@/utils/ensureCSRF";
13+
import { showNotification } from "@mantine/notifications";
14+
import { AxiosError } from "axios";
15+
16+
import {
17+
getHookFormErrorMessage,
18+
getServerErrorMessage,
19+
} from "@/utils/form-error";
20+
import { useTranslation } from "@/i18n/use-translation";
21+
import { useDebouncedCallback } from "@mantine/hooks";
22+
import { ProfileApiRepository } from "@/http/repositories/profile.repository";
23+
24+
const RegisterPage = () => {
25+
const { _t } = useTranslation();
26+
const api = new AuthRepository();
27+
const api__profile = new ProfileApiRepository();
28+
const registrationMutation = useMutation({
29+
mutationFn: (payload: IRegistrationFormPayload) => api.register(payload),
30+
});
31+
32+
const form = useForm<IRegistrationFormPayload>({
33+
resolver: yupResolver(formValidationSchema),
34+
});
35+
36+
const handleOnChangeUsernameDebounce = useDebouncedCallback(
37+
(username: string) => {
38+
ensureCSRF(async () => {
39+
await api__profile.getPublicUniqueUsername(username).then((res) => {
40+
if (res?.data?.username) {
41+
form.setValue("username", res?.data?.username);
42+
}
43+
});
44+
});
45+
},
46+
500
47+
);
48+
49+
const onSubmit = async (data: IRegistrationFormPayload) => {
50+
await ensureCSRF(() => {
51+
registrationMutation.mutate(data, {
52+
onSuccess: () => {
53+
window.location.href = "/";
54+
},
55+
});
56+
});
57+
};
58+
59+
return (
60+
<BaseLayout>
61+
<div className="max-w-96 mx-auto my-10 px-2">
62+
<form
63+
className="flex flex-col gap-4"
64+
onSubmit={form.handleSubmit(onSubmit)}
65+
method="post"
66+
>
67+
{registrationMutation.isError && (
68+
<Alert color="red" title="কিছু ভুল হয়েছে">
69+
{getServerErrorMessage(registrationMutation.error)}
70+
</Alert>
71+
)}
72+
73+
<Input.Wrapper
74+
label={_t("Name")}
75+
error={getHookFormErrorMessage("name", form?.formState?.errors)}
76+
>
77+
<Input
78+
placeholder={_t("Your name")}
79+
size="lg"
80+
variant="filled"
81+
{...form.register("name")}
82+
/>
83+
</Input.Wrapper>
84+
85+
<Input.Wrapper
86+
label={_t("Username")}
87+
error={getHookFormErrorMessage("username", form?.formState?.errors)}
88+
>
89+
<Input
90+
placeholder={_t("Your username")}
91+
size="lg"
92+
variant="filled"
93+
value={form.watch("username") || ""}
94+
onChange={(e) => {
95+
form.setValue("username", e.target.value);
96+
handleOnChangeUsernameDebounce(e.target.value);
97+
}}
98+
/>
99+
</Input.Wrapper>
100+
101+
<Input.Wrapper
102+
label={_t("Email")}
103+
error={getHookFormErrorMessage("email", form?.formState?.errors)}
104+
>
105+
<Input
106+
placeholder={_t("Your email")}
107+
size="lg"
108+
variant="filled"
109+
{...form.register("email")}
110+
/>
111+
</Input.Wrapper>
112+
113+
<Input.Wrapper
114+
label={_t("Password")}
115+
error={getHookFormErrorMessage("password", form?.formState?.errors)}
116+
>
117+
<Input
118+
placeholder="***********"
119+
type="password"
120+
size="lg"
121+
variant="filled"
122+
{...form.register("password")}
123+
/>
124+
</Input.Wrapper>
125+
126+
<Input.Wrapper
127+
label={_t("Confirm password")}
128+
error={getHookFormErrorMessage(
129+
"password_confirmation",
130+
form?.formState?.errors
131+
)}
132+
>
133+
<Input
134+
placeholder="***********"
135+
type="password"
136+
size="lg"
137+
variant="filled"
138+
{...form.register("password_confirmation")}
139+
/>
140+
</Input.Wrapper>
141+
<Button
142+
type="submit"
143+
size="lg"
144+
loading={registrationMutation?.isPending}
145+
>
146+
{_t("Register")}
147+
</Button>
148+
</form>
149+
150+
<div className="mt-10 flex gap-3">
151+
{_t("Already have an account?")}{" "}
152+
<Link className="text-lg" href={"/auth/login"}>
153+
{_t("Login")}
154+
</Link>
155+
</div>
156+
</div>
157+
</BaseLayout>
158+
);
159+
};
160+
161+
const formValidationSchema = yup.object({
162+
name: yup.string().required().label("Name"),
163+
username: yup.string().required().label("Username"),
164+
email: yup.string().email().required().label("Email"),
165+
password: yup.string().min(6).max(32).required().label("Password"),
166+
password_confirmation: yup
167+
.string()
168+
.min(6)
169+
.max(32)
170+
.required()
171+
.label("Password"),
172+
});
173+
174+
type IRegistrationFormPayload = yup.InferType<typeof formValidationSchema>;
175+
176+
export default RegisterPage;

src/app/dashboard/settings/_components/SettingGeneralTab.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const SettingGeneralTab = () => {
2626
mutationFn: (payload: UpdateProfilePayload) => {
2727
return api.updateProfile(payload);
2828
},
29-
onSuccess(data, variables, context) {
29+
onSuccess() {
3030
showNotification({
3131
title: "Updated successfully",
3232
message: "",

src/components/asides/HomeLeftSidebar.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,20 @@ const HomeLeftSidebar = () => {
88
return (
99
<div className="flex flex-col gap-3">
1010
<div className="mb-2 mt-4 flex flex-col gap-4">
11-
<Link href={"/"} className="flex items-center gap-2">
11+
<Link href={"/"} className="flex items-center gap-2 text-forground">
1212
<AiOutlineHome />
1313
<span className="text-sm">{_t("Home")}</span>
1414
</Link>
15-
<Link href={"/dashboard/bookmarks"} className="flex items-center gap-2">
15+
<Link
16+
href={"/dashboard/bookmarks"}
17+
className="flex items-center gap-2 text-forground"
18+
>
1619
<HiOutlineBookmark />
1720
<span className="text-sm">{_t("Bookmarks")}</span>
1821
</Link>
1922
<Link
2023
href={"/dashboard/articles/new"}
21-
className="flex items-center gap-2"
24+
className="flex items-center gap-2 text-forground"
2225
>
2326
<HiPlus />
2427
<span className="text-sm">{_t("New diary")}</span>

src/http/repositories/auth.repository.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ export class AuthRepository extends ApiRepository {
1010
return this.http.post("/api/auth/login", payload);
1111
}
1212

13+
/**
14+
* Login user by email and password
15+
* @param payload
16+
* @returns
17+
*/
18+
register(payload: IRegistrationPayload) {
19+
return this.http.post("/api/auth/register", payload);
20+
}
21+
1322
/**
1423
* Forgot password
1524
* @param payload
@@ -41,3 +50,11 @@ export class AuthRepository extends ApiRepository {
4150
return this.http.post("/api/auth/logout");
4251
}
4352
}
53+
54+
interface IRegistrationPayload {
55+
name?: string;
56+
username?: string;
57+
email?: string;
58+
password?: string;
59+
password_confirmation?: string;
60+
}

src/http/repositories/profile.repository.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ export class ProfileApiRepository extends ApiRepository {
4343
}
4444
);
4545
}
46+
47+
getPublicUniqueUsername(username: string) {
48+
return this.http.post<{ username: string }>(
49+
"/api/profile/public-unique-username",
50+
{ username }
51+
);
52+
}
4653
}
4754

4855
export interface UpdateProfilePayload {

src/i18n/bn.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
"Login with Github": "Github দিয়ে লগইন করুন",
44
"Connect with us": "আমাদের সাথে যুক্ত হোন",
55
"Login using email": "ইমেল দিয়ে লগইন করুন",
6+
"Forgot password?": "পাসওয়ার্ড ভুলে গেছেন?",
7+
"Login": "লগইন করুন",
8+
"Create an account": "একাউন্ট তৈরি করুন",
9+
"Register": "নিবন্ধন",
10+
"Already have an account?": "ইতিপুর্বেই আপনার একাউন্ট আছে?",
11+
"Password": "পাসওয়ার্ড",
12+
"Email": "ইমেইল",
613
"Facebook": "ফেসবুক",
714
"Instagram": "ইনস্টাগ্রাম",
815
"Discord": "ডিসকর্ড",

0 commit comments

Comments
 (0)