+
+
+
+
+
diff --git a/docs/history/2026-07-25-modul-user-pengguna.md b/docs/history/2026-07-25-modul-user-pengguna.md
new file mode 100644
index 0000000..f657fff
--- /dev/null
+++ b/docs/history/2026-07-25-modul-user-pengguna.md
@@ -0,0 +1,48 @@
+# Modul User / Pengguna
+
+**Tanggal:** 2026-07-25
+**Status:** Selesai
+
+## Tujuan
+Membuat halaman manajemen pengguna (user) dengan CRUD, mengikuti pola halaman jenis bisnis dan paket.
+
+## Yang Dikerjakan
+
+### 1. Halaman List Pengguna
+- `/admin/users` — DataTable dengan columns: Email, Username, Nama Lengkap, Status, Actions
+- Search (email/nama), filter status, reset filter
+- Delete dengan konfirmasi dialog
+
+### 2. Halaman Tambah Pengguna
+- `/admin/users/create` — Form: email, username, password, full_name, phone, address, pob, dob
+- Validasi required fields, submit POST ke API, redirect ke list
+
+### 3. Halaman Edit Pengguna
+- `/admin/users/{id}/edit` — Form pre-filled dari API, sama dengan create
+- Password opsional (kosongkan jika tidak diubah)
+- Submit PUT ke API, redirect ke list
+
+### 4. Sidebar
+- Tambah menu "Pengguna" di grup Master dengan icon Users
+
+## File yang Diubah/Dibuat
+
+| File | Aksi | Detail |
+|------|------|--------|
+| `core/app/pages/admin/users/columns.ts` | Dibuat | Column definitions + interface User |
+| `core/app/pages/admin/users/index.vue` | Dibuat/Ditulis ulang | Halaman list dengan delete dialog |
+| `core/app/pages/admin/users/create.vue` | Dibuat | Halaman tambah pengguna |
+| `core/app/pages/admin/users/[id]/edit.vue` | Dibuat | Halaman edit pengguna |
+| `core/app/components/AppSidebar.vue` | Diubah | Tambah menu "Pengguna" |
+
+## Routing
+
+| Path | File |
+|------|------|
+| `/admin/users` | `pages/admin/users/index.vue` |
+| `/admin/users/create` | `pages/admin/users/create.vue` |
+| `/admin/users/:id/edit` | `pages/admin/users/[id]/edit.vue` |
+
+## Notes
+- Menggunakan field `status` dari API (ACTIVE/INACTIVE) untuk badge status
+- API endpoint: `GET /v1/users`, `POST /v1/users`, `PUT /v1/users/{id}`, `DELETE /v1/users/{id}`
diff --git a/docs/history/2026-07-25-perbaikan-user-form-dan-filter.md b/docs/history/2026-07-25-perbaikan-user-form-dan-filter.md
new file mode 100644
index 0000000..8dcbd3b
--- /dev/null
+++ b/docs/history/2026-07-25-perbaikan-user-form-dan-filter.md
@@ -0,0 +1,70 @@
+# Perbaikan Form User dan Filter Status
+
+**Tanggal:** 2026-07-25
+**Status:** Selesai
+
+## Tujuan
+- Validasi form menggunakan pesan dari server (422 validation)
+- Filter status tabel menggunakan API query param
+- PhoneInput component reusable dengan format otomatis
+- Kalender popover untuk input tanggal lahir
+- Layout form diseragamkan antara create dan edit
+
+## Yang Dikerjakan
+
+### 1. Validasi Form dari Server
+- `errors` diubah dari `Record` menjadi `Record` untuk menyimpan pesan error
+- Template menggunakan `{{ errors.email }}` dinamis, bukan hardcode
+- Catch block parsing response 422 FastAPI: `err.loc.at(-1)` sebagai field name, `err.msg` sebagai pesan
+- Untuk response error lain, tetap parsing `detail.message` dan map ke field berdasarkan keyword
+
+### 2. Filter Status via API
+- Sebelum: filter status client-side (DataTable column filter)
+- Sesudah: `statusFilter` reactive ref dikirim sebagai query param `?status=` ke endpoint API
+- `useFetch` dengan `watch: [statusFilter]` otomatis refetch saat filter berubah
+- Opsi filter: Semua Status, Aktif, Onboarding, Nonaktif, Ditangguhkan, Dinonaktifkan
+
+### 3. PhoneInput Component
+- Dibuat `components/ui/phone-input/PhoneInput.vue`
+- Format otomatis `xxxx xxxx xxxx` (13 digit, spasi tiap 4 digit)
+- Menggunakan native `` dengan `:value` + `@input` untuk menghindari konflik v-model shadcn
+- Menerima prop `class` untuk validasi red border
+- Digunakan di create.vue dan edit.vue, nomor dikirim tanpa spasi ke API
+
+### 4. Kalender Popover untuk Tanggal Lahir
+- Input `type="date"` diganti dengan Popover + Calendar component
+- `dob` dipisah dari form object, menggunakan `ref()`
+- Format tampilan: "25 Juli 2026" (locale id-ID)
+- Konversi `CalendarDate.toString()` → YYYY-MM-DD untuk dikirim ke API
+- Parsing string YYYY-MM-DD → `new CalendarDate(y, m, d)` saat load edit
+
+### 5. Layout Form Diseragamkan
+- Edit page sekarang mengikuti layout create page:
+ - Baris 1: email + username (2 kolom)
+ - Baris 2: full_name (1 baris penuh)
+ - Baris 3: phone + pob + dob (3 kolom)
+ - Baris 4: alamat (1 baris penuh)
+- Info alert password default ditambahkan ke edit page
+
+### 6. Badge Status User
+- Badge sekarang menggunakan `statusConfig` untuk 5 status:
+ - ACTIVE → hijau "Aktif"
+ - ONBOARDING → biru "Onboarding"
+ - INACTIVE → abu "Nonaktif"
+ - SUSPENDED → oranye "Ditangguhkan"
+ - DISABLED → merah "Dinonaktifkan"
+
+## File yang Diubah
+
+| File | Aksi | Detail |
+|------|------|--------|
+| `components/ui/phone-input/PhoneInput.vue` | Dibuat | Component input telepon dengan format otomatis |
+| `components/ui/phone-input/index.ts` | Dibuat | Export PhoneInput |
+| `pages/admin/users/create.vue` | Diubah | Calendar popover, PhoneInput, validasi dinamis, status dihapus dari body |
+| `pages/admin/users/[id]/edit.vue` | Diubah | Layout disamakan dengan create, Calendar popover, PhoneInput, validasi dinamis, info alert |
+| `pages/admin/users/index.vue` | Diubah | Filter status via API query param, 5 opsi status |
+| `pages/admin/users/columns.ts` | Diubah | statusConfig untuk badge 5 status, hapus statusFilter |
+
+## Notes
+- Create page tidak lagi mengirim `status` ke API (default ONBOARDING dari schema)
+- Phone component hanya menerima input digit, max 13 digit