diff --git a/src/frontend/routes/index.tsx b/src/frontend/routes/index.tsx index a325f74..a1c3740 100644 --- a/src/frontend/routes/index.tsx +++ b/src/frontend/routes/index.tsx @@ -1,7 +1,6 @@ -import { Button, Container, Group, Stack, Text, Title } from '@mantine/core' +import { Button, Box, Center, Stack, Text, Title } from '@mantine/core' import { Link, createFileRoute } from '@tanstack/react-router' -import { SiBun } from 'react-icons/si' -import { TbBrandReact, TbLogin, TbRocket } from 'react-icons/tb' +import { TbLogin } from 'react-icons/tb' export const Route = createFileRoute('/')({ component: HomePage, @@ -9,28 +8,67 @@ export const Route = createFileRoute('/')({ function HomePage() { return ( - - - - - - + + {/* background blobs */} + + + - Bun + Elysia + Vite + React +
+ + logo - - Full-stack starter template with Mantine UI, TanStack Router, and session-based auth. - + + + Monitoring System + + + Pantau semua aplikasi dalam satu tempat, real-time. + + - - - - - - + +
+
) } diff --git a/src/frontend/routes/login.tsx b/src/frontend/routes/login.tsx index ff41ee9..e3d595b 100644 --- a/src/frontend/routes/login.tsx +++ b/src/frontend/routes/login.tsx @@ -1,10 +1,10 @@ import { useLogin } from '@/frontend/hooks/useAuth' import { Alert, + Box, Button, Center, Divider, - Paper, PasswordInput, Stack, Text, @@ -38,6 +38,14 @@ export const Route = createFileRoute('/login')({ component: LoginPage, }) +const OAUTH_ERRORS: Record = { + google_denied: 'Login dengan Google dibatalkan.', + invalid_state: 'Sesi OAuth tidak valid, silakan coba lagi.', + token_failed: 'Gagal menukar token Google, silakan coba lagi.', + userinfo_failed: 'Gagal mengambil info akun Google, silakan coba lagi.', + account_disabled: 'Akun Anda telah dinonaktifkan. Hubungi admin untuk informasi lebih lanjut.', +} + function LoginPage() { const login = useLogin() const { error: searchError } = Route.useSearch() @@ -49,69 +57,117 @@ function LoginPage() { login.mutate({ email, password }) } + const errorMessage = login.isError + ? login.error.message + : searchError + ? (OAUTH_ERRORS[searchError] ?? 'Login dengan Google gagal, silakan coba lagi.') + : null + return ( -
- -
- - - Login - + + {/* background blobs */} + + + - {(login.isError || searchError) && ( - } color="red" variant="light"> - {login.isError ? login.error.message : ( - { - google_denied: 'Login dengan Google dibatalkan.', - invalid_state: 'Sesi OAuth tidak valid, silakan coba lagi.', - token_failed: 'Gagal menukar token Google, silakan coba lagi.', - userinfo_failed: 'Gagal mengambil info akun Google, silakan coba lagi.', - account_disabled: 'Akun Anda telah dinonaktifkan. Hubungi admin untuk informasi lebih lanjut.', - }[searchError ?? ''] ?? 'Login dengan Google gagal, silakan coba lagi.' - )} - - )} +
+ + + + {/* header */} + + logo + + Monitoring System + + + Masuk untuk melanjutkan + + - } - value={email} - onChange={(e) => setEmail(e.currentTarget.value)} - required - /> + {errorMessage && ( + } color="red" variant="light"> + {errorMessage} + + )} - } - value={password} - onChange={(e) => setPassword(e.currentTarget.value)} - required - /> + } + value={email} + onChange={(e) => setEmail(e.currentTarget.value)} + required + /> - + } + value={password} + onChange={(e) => setPassword(e.currentTarget.value)} + required + /> - + - - - - -
+ + + +
+ + +
+
) }