chore: initial project import
Some checks failed
CI - Production Readiness / Verify (push) Has been cancelled

This commit is contained in:
Wira Basalamah
2026-04-21 09:29:29 +07:00
commit adde003fba
222 changed files with 37657 additions and 0 deletions

121
app/login/page.tsx Normal file
View File

@ -0,0 +1,121 @@
import Link from "next/link";
import Image from "next/image";
import { Button } from "@/components/ui";
import { getLocale, getTranslator } from "@/lib/i18n";
import { getSession } from "@/lib/auth";
export default async function LoginPage({
searchParams
}: {
searchParams?: Promise<{ error?: string; next?: string }>;
}) {
const locale = await getLocale();
const t = getTranslator(locale);
const params = await (searchParams ?? Promise.resolve({ error: undefined, next: undefined }));
const error = params?.error;
const next = params?.next ?? "";
const session = await getSession();
const errorMessage = error === "credentials_required"
? t("login", "error_credentials_required")
: error === "invalid_credentials"
? t("login", "error_invalid_credentials")
: error === "rate_limited"
? t("login", "error_rate_limited")
: null;
return (
<main className="flex min-h-screen items-center justify-center bg-background px-6 py-14">
<div className="grid w-full max-w-5xl overflow-hidden rounded-[2rem] bg-surface-container-lowest shadow-floating">
<section className="bg-surface-container-lowest border-b border-line px-10 py-16 text-center md:border-r md:border-b-0 md:px-14 md:py-20">
<Image
src="/logo_zappcare.png"
alt="ZappCare"
width={56}
height={56}
className="mx-auto h-14 w-auto rounded-full"
priority
/>
<h1 className="mt-8 text-4xl font-extrabold font-headline text-on-surface">{t("login", "title")}</h1>
<p className="mx-auto mt-3 max-w-sm text-sm text-on-surface-variant">
{t("login", "signin_subtitle")}
</p>
<div className="mx-auto mt-10 flex w-full max-w-sm flex-col gap-3">
<div className="rounded-[1.5rem] bg-surface-container-low p-4">
<p className="text-2xl font-black text-on-surface">3</p>
<p className="mt-1 text-sm text-on-surface-variant">Role aktif saat ini</p>
</div>
<div className="rounded-[1.5rem] bg-surface-container-low p-4">
<p className="text-2xl font-black text-on-surface">10+</p>
<p className="mt-1 text-sm text-on-surface-variant">Modul operasi aktif</p>
</div>
</div>
</section>
<section className="px-8 py-10 md:px-12 md:py-16">
<div className="mx-auto max-w-md">
<p className="text-sm font-black uppercase tracking-[0.22em] text-primary">{t("login", "signin_label")}</p>
<h2 className="mt-3 text-3xl font-black font-headline text-on-surface">{t("login", "signin_subtitle")}</h2>
<p className="mt-3 text-sm text-on-surface-variant">{t("login", "signin_help")}</p>
{session ? (
<p className="mt-4 rounded-[1rem] border border-outline-variant bg-surface-container-high p-4 text-sm text-on-surface-variant">
Session aktif: {session.fullName} {session.role} {session.tenantName}
</p>
) : null}
{errorMessage ? (
<p className="mt-4 rounded-[1rem] border border-error-container bg-error-container p-3 text-sm text-on-error-container">
{errorMessage}
</p>
) : null}
<form action="/auth/login" method="post" className="mt-8 space-y-4">
<input type="hidden" name="next" value={next} />
<label className="block text-sm text-on-surface-variant">
{t("login", "email_label")}
<div className="mt-1.5">
<input
name="email"
autoComplete="email"
required
className="h-12 w-full rounded-full border-none bg-surface-container-highest px-4 text-sm outline-none ring-1 ring-outline/40 focus:ring-2 focus:ring-primary"
placeholder={t("login", "work_email_placeholder")}
/>
</div>
</label>
<label className="block text-sm text-on-surface-variant">
{t("login", "password_label")}
<div className="mt-1.5 relative">
<input
name="password"
type="password"
autoComplete="current-password"
required
className="h-12 w-full rounded-full border-none bg-surface-container-highest px-4 text-sm outline-none ring-1 ring-outline/40 focus:ring-2 focus:ring-primary"
placeholder={t("login", "password_placeholder")}
/>
<span className="material-symbols-outlined absolute right-4 top-1/2 -translate-y-1/2 text-outline">visibility</span>
</div>
</label>
<Button className="w-full">{t("login", "sign_in_button")}</Button>
<button
type="button"
className="inline-flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-line bg-surface-container-low px-4 py-2 text-sm font-semibold text-on-surface transition hover:bg-surface-container-high"
>
<span className="material-symbols-outlined text-[20px]">fingerprint</span>
<span>{t("login", "sso_button")}</span>
</button>
<p className="text-center text-sm text-on-surface-variant">
{t("login", "no_account_label")} <Link href="/" className="font-bold text-primary hover:text-on-primary-container">{t("login", "contact_admin")}</Link>
</p>
<div className="flex flex-wrap gap-4 text-sm text-on-surface-variant">
<Link href="/forgot-password" className="font-semibold text-primary hover:text-on-primary-container">
{t("login", "remember_label")}
</Link>
</div>
</form>
</div>
</section>
</div>
</main>
);
}