-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from uninus-opensource/feat/tourism-login-page
Feat/tourism login page : Slicing login page for dashboard tourism
- Loading branch information
Showing
8 changed files
with
286 additions
and
5 deletions.
There are no files selected for viewing
149 changes: 149 additions & 0 deletions
149
apps/web/tourism/app/(auth)/auth/login/_modules/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
'use client'; | ||
import { Button } from '@psu/web-component-atoms'; | ||
import { Form } from '@psu/web-component-templates'; | ||
import { ControlledFieldText } from '@psu/web-component-organisms'; | ||
import { useForm } from 'react-hook-form'; | ||
import { TLoginRequest } from '@psu/entities'; | ||
import { FC, ReactElement, useEffect, useState } from 'react'; | ||
import z from 'zod'; | ||
import { zodResolver } from '@hookform/resolvers/zod'; | ||
import Link from 'next/link'; | ||
import { useRouter } from 'next/navigation'; | ||
import { signIn } from 'next-auth/react'; | ||
import { FaEye, FaEyeSlash } from 'react-icons/fa'; | ||
import Image from 'next/image'; | ||
|
||
const schema = z.object({ | ||
email: z.string().email({ message: 'Email tidak valid' }), | ||
password: z | ||
.string({ required_error: 'Kata sandi wajib diisi' }) | ||
.min(1, { message: 'Kata sandi wajib diisi' }), | ||
}); | ||
|
||
export const AuthLoginModule: FC = (): ReactElement => { | ||
const { | ||
control, | ||
handleSubmit, | ||
formState: { errors, isValid }, | ||
} = useForm<TLoginRequest>({ | ||
resolver: zodResolver(schema), | ||
mode: 'all', | ||
defaultValues: { | ||
email: '', | ||
password: '', | ||
}, | ||
}); | ||
|
||
const [error, setError] = useState<string | undefined>(undefined); | ||
const [isLoading, setIsLoading] = useState<boolean>(false); | ||
const [isVisible, setIsVisible] = useState<boolean>(false); | ||
|
||
const router = useRouter(); | ||
|
||
const onSubmit = handleSubmit(async (data) => { | ||
setIsLoading(true); | ||
try { | ||
const res = await signIn('credentials', { | ||
email: data.email, | ||
password: data.password, | ||
redirect: false, | ||
}); | ||
|
||
if (res?.ok) { | ||
router.push('/dashboard'); | ||
} | ||
|
||
if (res?.error) { | ||
setError(res?.error); | ||
console.log(res?.error); | ||
} | ||
} catch (err) { | ||
console.log(err); | ||
} | ||
setIsLoading(false); | ||
}); | ||
|
||
useEffect(() => { | ||
setTimeout(() => { | ||
setError(undefined); | ||
}, 5000); | ||
}, [error]); | ||
|
||
const TogglePassword: FC = (): ReactElement => { | ||
return ( | ||
<span | ||
className="cursor-pointer" | ||
onClick={() => { | ||
setIsVisible(!isVisible); | ||
}} | ||
> | ||
{isVisible ? <FaEye /> : <FaEyeSlash />} | ||
</span> | ||
); | ||
}; | ||
|
||
return ( | ||
<section className="bg-white rounded-l-2xl p-2 md:p-6 min-h-screen flex flex-col justify-center items-center"> | ||
<div className="flex flex-col items-center gap-2 mb-10 lg:hidden"> | ||
<Image | ||
src="/assets/logo.svg" | ||
alt="logo" | ||
width={75} | ||
height={75} | ||
priority | ||
/> | ||
<h1 className="text-2xl md:text-3xl font-bold text-black text-center"> | ||
WISATA DESA BOJONGSARI | ||
</h1> | ||
</div> | ||
<Form | ||
onSubmit={onSubmit} | ||
className="shadow-none w-full sm:w-[50dvw] lg:w-[35dvw] border p-3 md:p-10 rounded-lg" | ||
> | ||
<h1 className="text-center text-3xl font-semibold">Login</h1> | ||
{error && ( | ||
<span className="text-error bg-error-50 border-error border rounded-lg p-3"> | ||
{error} | ||
</span> | ||
)} | ||
<section className="flex flex-col gap-y-3 mt-[18px]"> | ||
<ControlledFieldText | ||
control={control} | ||
name="email" | ||
type="email" | ||
size="md" | ||
placeholder="Email" | ||
status={errors.email ? 'error' : 'default'} | ||
message={errors.email?.message} | ||
/> | ||
<ControlledFieldText | ||
control={control} | ||
name="password" | ||
size="md" | ||
type={isVisible ? 'text' : 'password'} | ||
placeholder="Kata Sandi" | ||
append={<TogglePassword />} | ||
/> | ||
</section> | ||
<div className="w-full my-4 flex justify-start"> | ||
<Link | ||
href="/auth/forgot" | ||
className="font-semibold text-sm text-gray hover:text-black" | ||
> | ||
Lupa Kata Sandi? | ||
</Link> | ||
</div> | ||
<div className="flex justify-center px-8"> | ||
<Button | ||
disabled={isValid || isLoading} | ||
type="submit" | ||
size="lg" | ||
className="w-full" | ||
> | ||
Masuk | ||
</Button> | ||
</div> | ||
</Form> | ||
</section> | ||
); | ||
}; |
78 changes: 78 additions & 0 deletions
78
apps/web/tourism/app/(auth)/auth/login/_modules/login.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { PropsWithChildren } from 'react'; | ||
import { AuthLoginModule } from '.'; | ||
import { render } from '@testing-library/react'; | ||
|
||
jest.mock('react-avatar', () => ({ | ||
Avatar: jest.fn(() => <></>), | ||
})); | ||
|
||
jest.mock('next/image', () => ({ | ||
Image: jest.fn(() => <></>), | ||
})); | ||
|
||
jest.mock('react-hook-form', () => ({ | ||
...jest.requireActual('react-hook-form'), | ||
Controller: () => <></>, | ||
useFormContext: () => ({}), | ||
useContext: () => ({}), | ||
useForm: () => ({ | ||
control: { | ||
register: jest.fn(), | ||
unregister: jest.fn(), | ||
getFieldState: jest.fn(), | ||
_names: { | ||
array: new Set('test'), | ||
mount: new Set('test'), | ||
unMount: new Set('test'), | ||
watch: new Set('test'), | ||
focus: 'test', | ||
watchAll: false, | ||
}, | ||
_subjects: { | ||
watch: jest.fn(), | ||
array: jest.fn(), | ||
state: jest.fn(), | ||
}, | ||
_getWatch: jest.fn(), | ||
_formValues: ['test'], | ||
_defaultValues: ['test'], | ||
}, | ||
formState: { | ||
errors: { | ||
email: { | ||
message: 'Email tidak valid', | ||
}, | ||
password: { | ||
message: 'Kata sandi wajib diisi', | ||
}, | ||
}, | ||
}, | ||
handleSubmit: () => jest.fn(), | ||
}), | ||
})); | ||
|
||
jest.mock('react'); | ||
jest.mock( | ||
'next/link', | ||
() => | ||
({ children }: PropsWithChildren) => | ||
children | ||
); | ||
jest.mock( | ||
'react-select', | ||
() => | ||
({ children }: PropsWithChildren) => | ||
children | ||
); | ||
|
||
jest.mock('next/navigation', () => ({ | ||
useRouter: jest.fn(), | ||
usePathname: jest.fn(), | ||
})); | ||
|
||
describe('Auth Login Module', () => { | ||
it('Should render successfully', () => { | ||
const { baseElement } = render(<AuthLoginModule />); | ||
expect(baseElement).toBeTruthy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { FC, ReactElement } from 'react'; | ||
import { BiLoaderAlt } from 'react-icons/bi'; | ||
|
||
const DashboardLoading: FC = (): ReactElement => { | ||
return <BiLoaderAlt className="animate-spin" />; | ||
}; | ||
|
||
export default DashboardLoading; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import type { NextPage } from 'next'; | ||
import type { ReactElement } from 'react'; | ||
import { AuthLoginModule } from './_modules'; | ||
import Image from 'next/image'; | ||
|
||
const AuthLoginPage: NextPage = (): ReactElement => { | ||
return ( | ||
<section className="flex overflow-y-hidden md:flex-row flex-col gap-y-5 lg:justify-between justify-center items-center w-full h-full min-h-screen"> | ||
<div className="hidden w-1/4 lg:flex flex-col shrink-0 justify-center item-center lg:items-center gap-y-4"> | ||
<Image | ||
src="/assets/logo-desa.png" | ||
alt="logo" | ||
width={250} | ||
height={219} | ||
priority | ||
/> | ||
<h1 className="text-2xl md:text-3xl font-bold text-white text-center"> | ||
WISATA DESA BOJONGSARI | ||
</h1> | ||
</div> | ||
<div className="md:w-3/4 w-full h-full md:pl-6"> | ||
<AuthLoginModule /> | ||
</div> | ||
</section> | ||
); | ||
}; | ||
|
||
export default AuthLoginPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { FC, PropsWithChildren, ReactElement } from 'react'; | ||
|
||
const AuthTemplate: FC<Readonly<PropsWithChildren>> = (props): ReactElement => { | ||
return ( | ||
<main className="flex overflow-hidden items-center w-full bg-white lg:bg-primary-50%"> | ||
<div className="z-10 w-full overflow-y-hidden h-full"> | ||
{props.children} | ||
</div> | ||
</main> | ||
); | ||
}; | ||
|
||
export default AuthTemplate; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters