Skip to content

Commit

Permalink
Merge pull request #138 from chingu-x/dev
Browse files Browse the repository at this point in the history
end of sprint merge
  • Loading branch information
Dan-Y-Ko authored May 16, 2024
2 parents e6fb425 + 8a31c2c commit 20df868
Show file tree
Hide file tree
Showing 115 changed files with 1,689 additions and 756 deletions.
9 changes: 8 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,21 @@
}
}
],
"@typescript-eslint/consistent-type-imports": [
"error",
{
"prefer": "type-imports"
}
],
"dot-notation": "off",
"@typescript-eslint/dot-notation": "error"
},
"overrides": [
{
"files": ["src/stories/**/*.{js,ts,tsx}"],
"rules": {
"no-console": "off"
"no-console": "off",
"@typescript-eslint/consistent-type-imports": "off"
}
}
]
Expand Down
4 changes: 2 additions & 2 deletions src/app/(auth)/AuthProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import { useEffect } from "react";
import { clientSignIn, clientSignOut } from "@/store/features/auth/authSlice";
import { useAppDispatch } from "@/store/hooks";
import { User, getUserState } from "@/store/features/user/userSlice";
import { AppError } from "@/types/types";
import { type User, getUserState } from "@/store/features/user/userSlice";
import { type AppError } from "@/types/types";

interface AuthProviderProps {
user: User | null;
Expand Down
62 changes: 54 additions & 8 deletions src/app/(auth)/authService.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"use server";

import { cookies } from "next/headers";
import { AsyncActionResponse, handleAsync } from "@/utils/handleAsync";
import { type AsyncActionResponse, handleAsync } from "@/utils/handleAsync";
import { getAccessToken, getRefreshToken } from "@/utils/getCookie";
import { POST } from "@/utils/requests";
import { POST, UNAUTHPOST } from "@/utils/requests";

interface AuthResponse {
message: string;
Expand All @@ -13,12 +13,23 @@ interface ServerSignInResponse extends AuthResponse {}

interface ServerSignOutResponse extends AuthResponse {}

interface ServerSignInProps {
email: string;
password: string;
}

interface ResetPasswordRequestProps {
email?: string;
token?: string;
password?: string;
}

// prettier-ignore
// prettier causing issues here with eslint rules
export async function serverSignIn(): Promise<
export async function serverSignIn({ email, password }: ServerSignInProps ): Promise<
AsyncActionResponse<ServerSignInResponse>
> {
const userOrError = async () => asyncSignIn();
const userOrError = async () => asyncSignIn(email, password);

return handleAsync(userOrError);
}
Expand Down Expand Up @@ -46,9 +57,44 @@ export async function serverSignOut(): Promise<

}

export async function resetPasswordRequestEmail(
email: string,
): Promise<AsyncActionResponse<void>> {
const asyncPasswordResetEmail = async () =>
UNAUTHPOST<ResetPasswordRequestProps, void>(
"api/v1/auth/reset-password/request",
"no-store",
{
email,
},
);

return handleAsync(asyncPasswordResetEmail);
}

export async function resetPassword({
password,
token,
}: ResetPasswordRequestProps): Promise<AsyncActionResponse<void>> {
const asyncResetPassword = async () =>
UNAUTHPOST<ResetPasswordRequestProps, void>(
"api/v1/auth/reset-password",
"no-store",
{
password,
token,
},
);

return handleAsync(asyncResetPassword);
}

/////////////////////////////////////////////////////////////////////////////

async function asyncSignIn(): Promise<ServerSignInResponse> {
async function asyncSignIn(
email: string,
password: string,
): Promise<ServerSignInResponse> {
try {
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/api/v1/auth/login`,
Expand All @@ -59,12 +105,12 @@ async function asyncSignIn(): Promise<ServerSignInResponse> {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "[email protected]",
password: "password",
email,
password,
}),
credentials: "include",
cache: "no-store",
}
},
);

if (!res.ok) {
Expand Down
2 changes: 1 addition & 1 deletion src/app/(auth)/components/AuthBannerContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Banner from "@/components/banner/Banner";

export default function AuthBannerContainer() {
return (
<div className="flex min-h-[486px] flex-col justify-center">
<div className="flex h-[486px] flex-col justify-center">
<div>
<Banner
imageLight="/img/login_image_light.png"
Expand Down
10 changes: 8 additions & 2 deletions src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ModeToggle from "@/components/ModeToggle";
import Navbar from "@/components/navbar/Navbar";
import AuthBannerContainer from "@/app/(auth)/components/AuthBannerContainer";

interface LayoutProps {
children: React.ReactNode;
Expand All @@ -13,8 +14,13 @@ export default function Layout({ children }: LayoutProps) {
<ModeToggle />
</div>
</Navbar>
<main className="flex flex-col items-center w-full p-10 overflow-y-auto">
<div className="gap-y-9">{children}</div>
<main className="flex flex-col items-center w-full p-10 overflow-y-auto h-full">
<div className="gap-y-9 h-full xl:flex">
<div className="flex items-center justify-center">
<AuthBannerContainer />
{children}
</div>
</div>
</main>
</div>
);
Expand Down
95 changes: 65 additions & 30 deletions src/app/(auth)/sign-in/components/EmailCheckContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,92 @@
import Image from "next/image";
import { type Dispatch, type SetStateAction } from "react";
import { ContainerState } from "./SignInContainer";
import Button from "@/components/Button";
import Banner from "@/components/banner/Banner";
import { useAppDispatch } from "@/store/hooks";
import useServerAction from "@/hooks/useServerAction";
import { resetPasswordRequestEmail } from "@/app/(auth)/authService";
import { onOpenModal } from "@/store/features/modal/modalSlice";
import Spinner from "@/components/Spinner";

type ResendEmailContainerProp = {
email: string;
setContainerState: Dispatch<SetStateAction<ContainerState>>;
};

function EmailCheckContainer({
email,
setContainerState,
}: ResendEmailContainerProp) {
const dispatch = useAppDispatch();

const {
runAction: resetPwdReqEmailAction,
isLoading: resetPwdReqEmailLoading,
setIsLoading: setResetPwdReqEmailLoading,
} = useServerAction(resetPasswordRequestEmail);

async function handleResendEmail() {
const [, error] = await resetPwdReqEmailAction(email);

if (error) {
dispatch(
onOpenModal({ type: "error", content: { message: error.message } }),
);
}

setResetPwdReqEmailLoading(false);
}

function renderButtonContent() {
if (resetPwdReqEmailLoading) {
return <Spinner />;
}
return "Resend Email";
}

function handleClick() {
setContainerState(ContainerState.SignIn);
}

function EmailCheckContainer() {
return (
<div className="flex flex-col items-center w-[400px] min-h-[652px] bg-base-200 rounded-2xl xl:ml-60 px-6 py-9">
<p className="text-base-300 text-2xl text-center mb-[26px] font-medium">
Welcome to Chingu
Reset Link Sent
</p>
<div
data-hide-on-theme="dark"
className="flex h-[171px] w-[168px] relative shrink-0"
>
<Image
src="/img/link_retro_mac_light.png"
alt="Light login image"
fill={true}
style={{ objectFit: "contain" }}
priority={true}
/>
</div>
<div
data-hide-on-theme="light"
className="flex h-[171px] w-[168px] relative shrink-0"
>
<Image
src="/img/link_retro_mac_dark.png"
alt="Light login image"
fill={true}
style={{ objectFit: "contain" }}
priority={true}
<div>
<Banner
imageLight="/img/link_retro_mac_light.png"
imageDark="/img/link_retro_mac_dark.png"
height="h-[171px]"
width="w-[168px]"
alt="Email confirmation image"
/>
</div>
<div className="flex flex-col items-center">
<p className="text-base-300 text-xl font-medium mt-8">
<p className="text-base-300 text-xl font-medium mt-8 mb-2">
Check Your Email Address
</p>
<p className="text-base-300 text-base font-medium">
If that email address exists, we will send an email to it with a link
to reset your password. Please open it and click on the link in it to
reset your password.
</p>
<p className="text-base-300 text-base font-medium mt-6 mb-[166px]">
<p className="text-base-300 text-base font-medium mt-6 mb-[60px] 3xl:mb-[166px]">
If you have not received an email shortly, then please check your
spam/trash folders or click the button below to request a new reset
email.
</p>
</div>
<Button
type="button"
title="Resend Email"
className="text-base gap-x-0 border-none font-semibold capitalize bg-base-100 text-base-300 hover:bg-base-100 w-full"
onClick={handleResendEmail}
variant="outline"
className="w-full"
>
Resend Email
{renderButtonContent()}
</Button>
<Button type="button" variant="link" onClick={handleClick}>
Go Back
</Button>
</div>
);
Expand Down
75 changes: 0 additions & 75 deletions src/app/(auth)/sign-in/components/NewPasswordContainer.tsx

This file was deleted.

Loading

0 comments on commit 20df868

Please sign in to comment.