diff --git a/PROGRESS.md b/PROGRESS.md
deleted file mode 100644
index 682a116..0000000
--- a/PROGRESS.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Progress
-
-Catatan sementara untuk melanjutkan pekerjaan di komputer lain. Hapus file ini kalau halaman
-login sudah selesai.
-
-Terakhir diperbarui: 2026-10-20.
-
-## Sudah selesai
-
-- Drizzle ORM + `pg` ke Postgres (`db/`, `drizzle.config.ts`, script `db:*`).
-- Better Auth 1.7: login pakai username, tabel auth sudah di-migrate, sign-up publik ditutup.
- Endpoint di `app/api/auth/[...all]/route.ts`.
-- shadcn/ui preset `base-nova`, komponen: button, input, label, card, field, separator.
-- `old-source/` di-commit tanpa `db_login.inc.php` (kredensial).
-- Halaman login, langkah 1 sampai 3 dari 7:
- 1. `zod` terpasang.
- 2. `data/auth.ts`: `getCurrentUser()` cek session, redirect ke `/login` kalau belum login.
- 3. `app/(auth)/login/actions.ts`: server action `login` (validasi zod, lalu
- `auth.api.signInUsername`, lalu `redirect("/")`).
-
-## Berikutnya: halaman login, langkah 4 sampai 7
-
-4. **Form login (client component)**
- `app/(auth)/login/_components/login-form.tsx`, diawali `"use client"`.
- Pakai `useActionState(login, {})`. Isinya `Card` berisi `FieldGroup` dengan dua `Field`
- (username dan password, `name="username"` / `name="password"`), `FieldError` untuk
- `state.error`, dan `Button type="submit"` yang `disabled` saat `pending`.
- Input username diberi `defaultValue={state.username}` supaya tidak kosong setelah gagal login.
-
-5. **Halaman login**
- `app/(auth)/login/page.tsx`: Server Component yang menampilkan `` di tengah layar.
-
-6. **Pindahkan halaman utama ke grup dashboard**
- Hapus `app/page.tsx` (bawaan create-next-app), lalu buat `app/(dashboard)/page.tsx`.
- Komponen yang memanggil `getCurrentUser()` harus dibungkus `` karena
- `cacheComponents` aktif (tanpa itu build gagal). Tampilkan nama user yang login.
-
-7. **Logout**
- `app/(dashboard)/actions.ts` dengan `"use server"`: action `logout` memanggil
- `auth.api.signOut({ headers: await headers() })` lalu `redirect("/login")`.
- Pasang lewat `` di
- halaman dashboard.
-
-Cek akhir: buka `/` saat belum login, harus diarahkan ke `/login`. Login sebagai `admin`,
-nama tampil di `/`. Klik Keluar, kembali ke `/login`. Lalu `pnpm exec tsc --noEmit` dan `pnpm lint`.
-
-Setelah itu: commit, lalu rencana berikutnya (belum dimulai):
-
-- User read-only (hanya `SELECT`) di MariaDB untuk `AMIGO_DATABASE_URL`, menggantikan `root`.
-- Koneksi Drizzle ke MariaDB di `db/amigo/` dengan `drizzle-kit pull` (jangan pernah migrate/push).
-- `proxy.ts` untuk redirect cepat ke `/login` kalau tidak ada cookie session.
-
-## Menyiapkan komputer lain
-
-Ikuti bagian "Setup di laptop baru" di `README.md` (`docker compose up -d`, `pnpm db:migrate`,
-`pnpm db:seed`).
diff --git a/app/(auth)/login/_components/login-form.tsx b/app/(auth)/login/_components/login-form.tsx
new file mode 100644
index 0000000..2176b81
--- /dev/null
+++ b/app/(auth)/login/_components/login-form.tsx
@@ -0,0 +1,64 @@
+"use client";
+
+import { useActionState } from "react";
+import { Button } from "@/components/ui/button";
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card";
+import {
+ Field,
+ FieldError,
+ FieldGroup,
+ FieldLabel,
+} from "@/components/ui/field";
+import { Input } from "@/components/ui/input";
+import { login, type LoginState } from "../actions";
+
+const initialState: LoginState = {};
+
+export function LoginForm() {
+ const [state, formAction, pending] = useActionState(login, initialState);
+
+ return (
+
+
+ Masuk
+ Cleo Minimarket back-office
+
+
+
+
+
+ );
+}
diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx
new file mode 100644
index 0000000..800582f
--- /dev/null
+++ b/app/(auth)/login/page.tsx
@@ -0,0 +1,16 @@
+import type { Metadata } from "next";
+import { LoginForm } from "./_components/login-form";
+
+export const metadata: Metadata = {
+ title: "Masuk",
+};
+
+export default function LoginPage() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/app/(dashboard)/actions.ts b/app/(dashboard)/actions.ts
new file mode 100644
index 0000000..c61d876
--- /dev/null
+++ b/app/(dashboard)/actions.ts
@@ -0,0 +1,10 @@
+"use server";
+
+import { headers } from "next/headers";
+import { redirect } from "next/navigation";
+import { auth } from "@/lib/auth";
+
+export async function logout() {
+ await auth.api.signOut({ headers: await headers() });
+ redirect("/login");
+}
diff --git a/app/(dashboard)/page.tsx b/app/(dashboard)/page.tsx
new file mode 100644
index 0000000..f3a383c
--- /dev/null
+++ b/app/(dashboard)/page.tsx
@@ -0,0 +1,25 @@
+import { Suspense } from "react";
+import { getCurrentUser } from "@/data/auth";
+import { logout } from "./actions";
+import { Button } from "@/components/ui/button";
+
+export default function DashboardPage() {
+ return (
+
+ Loading...
}>
+
+
+
+
+ );
+}
+
+async function Greeting() {
+ const user = await getCurrentUser();
+
+ return Halo, {user.name}!
;
+}
diff --git a/app/page.tsx b/app/page.tsx
deleted file mode 100644
index c887311..0000000
--- a/app/page.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import Image from "next/image";
-
-export default function Home() {
- return (
-
-
-
-
-
- To get started, edit the{" "}
-
- page.tsx
- {" "}
- file.
-
-
- Looking for a starting point or more instructions? Head over to{" "}
-
- Templates
- {" "}
- or the{" "}
-
- Learning
- {" "}
- center.
-
-
-
-
-
- );
-}