diff --git a/apps/dimentorin/public/image/33978ce5bed2da9bf9d73acad802182a.webp b/apps/dimentorin/public/image/33978ce5bed2da9bf9d73acad802182a.webp new file mode 100644 index 0000000..bf62262 Binary files /dev/null and b/apps/dimentorin/public/image/33978ce5bed2da9bf9d73acad802182a.webp differ diff --git a/apps/dimentorin/public/image/9261045e09137f3fcb925a78c55b6ddb.webp b/apps/dimentorin/public/image/9261045e09137f3fcb925a78c55b6ddb.webp new file mode 100644 index 0000000..1817b4f Binary files /dev/null and b/apps/dimentorin/public/image/9261045e09137f3fcb925a78c55b6ddb.webp differ diff --git a/apps/dimentorin/public/image/95319c4f9953dfe6180200e529dfcea5.webp b/apps/dimentorin/public/image/95319c4f9953dfe6180200e529dfcea5.webp new file mode 100644 index 0000000..31a61c3 Binary files /dev/null and b/apps/dimentorin/public/image/95319c4f9953dfe6180200e529dfcea5.webp differ diff --git a/apps/dimentorin/src/app/auth/forgot/layout.tsx b/apps/dimentorin/src/app/auth/forgot/layout.tsx new file mode 100644 index 0000000..2d8a74d --- /dev/null +++ b/apps/dimentorin/src/app/auth/forgot/layout.tsx @@ -0,0 +1,12 @@ +import { FC, ReactElement } from 'react'; +import { Outlet } from 'react-router-dom'; + +export const AppLayout: FC = (): ReactElement => { + return ( +
+ +
+ ); +}; + +export default AppLayout; diff --git a/apps/dimentorin/src/app/auth/forgot/otp/layout.tsx b/apps/dimentorin/src/app/auth/forgot/otp/layout.tsx new file mode 100644 index 0000000..2d8a74d --- /dev/null +++ b/apps/dimentorin/src/app/auth/forgot/otp/layout.tsx @@ -0,0 +1,12 @@ +import { FC, ReactElement } from 'react'; +import { Outlet } from 'react-router-dom'; + +export const AppLayout: FC = (): ReactElement => { + return ( +
+ +
+ ); +}; + +export default AppLayout; diff --git a/apps/dimentorin/src/app/auth/forgot/otp/page.tsx b/apps/dimentorin/src/app/auth/forgot/otp/page.tsx new file mode 100644 index 0000000..99d2daf --- /dev/null +++ b/apps/dimentorin/src/app/auth/forgot/otp/page.tsx @@ -0,0 +1,23 @@ +import { FC, ReactElement } from 'react'; +import { RegisterResetBanner } from "@imphnen-frontend-service/ui/organisms"; +import { ForgotStep, OtpForm } from "@imphnen-frontend-service/ui/molecules"; +import { Button } from '@imphnen-frontend-service/ui/atoms'; + +export const Components: FC = (): ReactElement => { + return ( +
+
+ +
+ +

Forgot Password

+
Yeay~! Pesan dari dunia lain (a.k.a email-mu) sudah tiba!
+ + +
+
+
+ ); +}; + +export default Components; \ No newline at end of file diff --git a/apps/dimentorin/src/app/auth/forgot/page.tsx b/apps/dimentorin/src/app/auth/forgot/page.tsx new file mode 100644 index 0000000..31e9668 --- /dev/null +++ b/apps/dimentorin/src/app/auth/forgot/page.tsx @@ -0,0 +1,24 @@ +import { FC, ReactElement } from 'react'; +import { RegisterResetBanner } from "@imphnen-frontend-service/ui/organisms"; +import { ForgotStep } from "@imphnen-frontend-service/ui/molecules"; +import { Button, Input } from '@imphnen-frontend-service/ui/atoms'; + +export const Components: FC = (): ReactElement => { + return ( +
+
+ +
+ +

Forgot Password

+
Masukkan email-mu, dan biarkan kami memanggil password-mu kembali dari dunia lain!
+
Email
+ + +
+
+
+ ); +}; + +export default Components; \ No newline at end of file diff --git a/apps/dimentorin/src/app/auth/forgot/summon/layout.tsx b/apps/dimentorin/src/app/auth/forgot/summon/layout.tsx new file mode 100644 index 0000000..2d8a74d --- /dev/null +++ b/apps/dimentorin/src/app/auth/forgot/summon/layout.tsx @@ -0,0 +1,12 @@ +import { FC, ReactElement } from 'react'; +import { Outlet } from 'react-router-dom'; + +export const AppLayout: FC = (): ReactElement => { + return ( +
+ +
+ ); +}; + +export default AppLayout; diff --git a/apps/dimentorin/src/app/auth/forgot/summon/page.tsx b/apps/dimentorin/src/app/auth/forgot/summon/page.tsx new file mode 100644 index 0000000..913a04f --- /dev/null +++ b/apps/dimentorin/src/app/auth/forgot/summon/page.tsx @@ -0,0 +1,34 @@ +import { FC, ReactElement } from 'react'; +import { RegisterResetBanner } from "@imphnen-frontend-service/ui/organisms"; +import { ForgotStep } from "@imphnen-frontend-service/ui/molecules"; +import { Button, Input } from '@imphnen-frontend-service/ui/atoms'; + +export const Components: FC = (): ReactElement => { + return ( +
+
+ +
+ +

Forgot Password

+
Sekarang, buatlah password baru yang lebih kuat, seperti jurus andalanmu!🔥⚡
+
+
Password Baru
+ +
Ulang Password Baru
+ +
+
+
💡 Tips dari kami:
+
✅ Buat kombinasi huruf besar, kecil, angka, dan simbol untuk kekuatan maksimal!
+
✅ Pastikan kamu ingat password-mu atau simpan di tempat aman~
+
Masukkan password baru dan bersiaplah untuk kembali bertualang!
+
+ +
+
+
+ ); +}; + +export default Components; \ No newline at end of file diff --git a/apps/dimentorin/src/app/auth/login/layout.tsx b/apps/dimentorin/src/app/auth/login/layout.tsx new file mode 100644 index 0000000..2d8a74d --- /dev/null +++ b/apps/dimentorin/src/app/auth/login/layout.tsx @@ -0,0 +1,12 @@ +import { FC, ReactElement } from 'react'; +import { Outlet } from 'react-router-dom'; + +export const AppLayout: FC = (): ReactElement => { + return ( +
+ +
+ ); +}; + +export default AppLayout; diff --git a/apps/dimentorin/src/app/auth/login/page.tsx b/apps/dimentorin/src/app/auth/login/page.tsx new file mode 100644 index 0000000..fe113e4 --- /dev/null +++ b/apps/dimentorin/src/app/auth/login/page.tsx @@ -0,0 +1,45 @@ +import { FC, ReactElement } from 'react'; +import { LoginBanner } from "@imphnen-frontend-service/ui/organisms" +import { Button } from '@imphnen-frontend-service/ui/atoms'; +import { useSearchParams } from 'react-router-dom'; +import { InputForm } from '@imphnen-frontend-service/ui/molecules'; + +export const Components: FC = (): ReactElement => { + const [searchParams] = useSearchParams(); + const error = searchParams.get("error"); // Ambil nilai ?error= + + return ( +
+
+ +
+
+

Hallo Minna-san

+
Welcome to Dimentorin by IMPHNEN
+ + + + +
+
Belum Punya akun ?
+ Daftar Disini +
+
+
+ Or +
+
+ +
+
+
+
+ ); +}; + +export default Components; \ No newline at end of file diff --git a/apps/dimentorin/src/app/auth/register/layout.tsx b/apps/dimentorin/src/app/auth/register/layout.tsx new file mode 100644 index 0000000..2d8a74d --- /dev/null +++ b/apps/dimentorin/src/app/auth/register/layout.tsx @@ -0,0 +1,12 @@ +import { FC, ReactElement } from 'react'; +import { Outlet } from 'react-router-dom'; + +export const AppLayout: FC = (): ReactElement => { + return ( +
+ +
+ ); +}; + +export default AppLayout; diff --git a/apps/dimentorin/src/app/auth/register/page.tsx b/apps/dimentorin/src/app/auth/register/page.tsx new file mode 100644 index 0000000..45b335c --- /dev/null +++ b/apps/dimentorin/src/app/auth/register/page.tsx @@ -0,0 +1,19 @@ +import { FC, ReactElement } from 'react'; +import { RegisterResetBanner } from "@imphnen-frontend-service/ui/organisms"; +import { Button, Input } from '@imphnen-frontend-service/ui/atoms'; + +export const Components: FC = (): ReactElement => { + return ( +
+
+ +
+
+
+
+
+
+ ); +}; + +export default Components; \ No newline at end of file diff --git a/libs/ui/src/molecules/forgot-step/forgot-step.tsx b/libs/ui/src/molecules/forgot-step/forgot-step.tsx new file mode 100644 index 0000000..10cd7d8 --- /dev/null +++ b/libs/ui/src/molecules/forgot-step/forgot-step.tsx @@ -0,0 +1,30 @@ +import { DetailedHTMLProps, FC, InputHTMLAttributes, ReactElement } from "react" + +type TForgotStepProps = Omit< + DetailedHTMLProps, HTMLInputElement>, + 'size' | 'type' +> & { + step: number +}; + +export const ForgotStep: FC = ({ + step = 1, + ...rest +}): ReactElement => { + return ( +
+
+
+

Masukkan Email

+
+
+
+

Verifikasi OTP

+
+
+
+

Summon Password ^^

+
+
+ ) +} diff --git a/libs/ui/src/molecules/forgot-step/index.ts b/libs/ui/src/molecules/forgot-step/index.ts new file mode 100644 index 0000000..e0c2455 --- /dev/null +++ b/libs/ui/src/molecules/forgot-step/index.ts @@ -0,0 +1 @@ +export * from './forgot-step'; diff --git a/libs/ui/src/molecules/index.ts b/libs/ui/src/molecules/index.ts index a0c6132..7349f9a 100644 --- a/libs/ui/src/molecules/index.ts +++ b/libs/ui/src/molecules/index.ts @@ -1,3 +1,5 @@ +export * from "./forgot-step"; +export * from "./otp-form"; export * from './input-form'; export * from './pagination'; export * from './modal/modal'; diff --git a/libs/ui/src/molecules/otp-form/index.ts b/libs/ui/src/molecules/otp-form/index.ts new file mode 100644 index 0000000..d901133 --- /dev/null +++ b/libs/ui/src/molecules/otp-form/index.ts @@ -0,0 +1 @@ +export * from "./otp-form" \ No newline at end of file diff --git a/libs/ui/src/molecules/otp-form/otp-form.tsx b/libs/ui/src/molecules/otp-form/otp-form.tsx new file mode 100644 index 0000000..6c62c7b --- /dev/null +++ b/libs/ui/src/molecules/otp-form/otp-form.tsx @@ -0,0 +1,61 @@ +// eslint-disable-next-line @nx/enforce-module-boundaries +import { Input } from "@imphnen-frontend-service/ui/atoms"; +import { ChangeEvent, DetailedHTMLProps, FC, InputHTMLAttributes, ReactElement, useRef, useState } from "react" + +type TForgotStepProps = Omit< + DetailedHTMLProps, HTMLInputElement>, + 'size' | 'type' +> & { + +}; + +export const OtpForm: FC = ({ + step = 1, + ...rest +}): ReactElement => { + const [cell, setCell] = useState(new Array(6).fill("")) + const inputRef = useRef([]) + + const handleChange = (index: number, e: ChangeEvent) => { + const value = e.target.value + if (!(/^[0-9]?$/.test(value))) return; + + const newCell = [...cell] + newCell[index] = value + setCell(newCell) + + if(value && index < 6 - 1){ + (inputRef.current[index + 1] as HTMLInputElement).focus() + } + } + + const handleKeyDown = (index: number, e: React.KeyboardEvent) => { + if(e.key === "Backspace" && !cell[index] && index > 0){ + const newCell = [...cell] + newCell[index] = "" + setCell(newCell) + + const ref = (inputRef.current[index - 1] as HTMLInputElement) + ref.focus() + } + } + + return ( +
+ {cell.map((v, i) => ( + { + inputRef.current.push(el as never) + return inputRef.current[i] + }} + onChange={(e) => handleChange(i, e)} + onKeyDown={(e) => handleKeyDown(i, e)} + size="lg" + value={cell[i]} + className="sm:min-w-[10px]" + /> + ))} +
+ ) +} diff --git a/libs/ui/src/organisms/auth-banner/auth-banner.tsx b/libs/ui/src/organisms/auth-banner/auth-banner.tsx new file mode 100644 index 0000000..fbd5927 --- /dev/null +++ b/libs/ui/src/organisms/auth-banner/auth-banner.tsx @@ -0,0 +1,29 @@ +import { ArrowLeftOutlined } from "@ant-design/icons"; +// eslint-disable-next-line @nx/enforce-module-boundaries +import { Button } from "@imphnen-frontend-service/ui/atoms"; +import { FC, ReactElement } from "react"; + +function AuthBanner({text, href}: {text: string, href: string}){ + return ( +
+ Banner +
+ +
+
+ Logo +
+
+ ) +} + +export const LoginBanner: FC = (): ReactElement => { + return AuthBanner({text: "Back To Homepage", href: "/"}) +} + +export const RegisterResetBanner: FC = (): ReactElement => { + return AuthBanner({text: "Back To Login", href: "/auth/login"}) +} \ No newline at end of file diff --git a/libs/ui/src/organisms/auth-banner/index.ts b/libs/ui/src/organisms/auth-banner/index.ts new file mode 100644 index 0000000..ece96a0 --- /dev/null +++ b/libs/ui/src/organisms/auth-banner/index.ts @@ -0,0 +1 @@ +export * from './auth-banner'; diff --git a/libs/ui/src/organisms/index.ts b/libs/ui/src/organisms/index.ts index f43e18d..b8af5de 100644 --- a/libs/ui/src/organisms/index.ts +++ b/libs/ui/src/organisms/index.ts @@ -1,5 +1,6 @@ export * from './navbar'; -export * from './modals-gacha'; +export * from "./modals-gacha"; +export * from "./auth-banner"; export * from './backoffice-sidebar' export * from './datatable' export * from './filter'