web/docs/history/2026-07-23-login-form-functionality.md

3.0 KiB

Login Form Functionality - Session 1

Tanggal: 2026-07-23 Status: Selesai

Tujuan

Menambahkan fungsionalitas login pada web2/app/components/LoginForm.vue dengan referensi dari web/app/pages/auth/login.vue.

Yang Dikerjakan

1. Install vue-sonner

  • Awalnya install sonner, tapi paket tersebut menarik React sebagai dependency dan menyebabkan error Invalid hook call / Cannot read properties of null (reading 'useState').
  • Solusi: ganti dengan vue-sonner (Vue-only fork).

2. Update nuxt.config.ts

  • Tambah runtimeConfig untuk apiBase dan googleClientId.
  • Tambah app.head untuk title template.

3. Buat app/composables/useGoogleAuth.ts

  • Composable untuk Google Identity Services (GIS) One Tap.
  • Load script https://accounts.google.com/gsi/client secara dinamis.
  • Panggil POST /auth/google-login ke backend setelah credential diterima.
  • Return loading, error, dan signInWithGoogle().

4. Buat app/components/ui/sonner/Sonner.vue

  • Wrapper component untuk vue-sonner's Toaster.
  • Di-render di app.vue dengan <ClientOnly> (hanya di client, bukan SSR).

5. Update app/app.vue

  • Import dan render <Toaster /> di dalam <ClientOnly>.

6. Update app/components/LoginForm.vue

  • Validasi form dengan Zod (login wajib, password min 8 karakter).
  • Submit handler: POST /auth/login via $fetch.
  • Google login handler: useGoogleAuth().signInWithGoogle().
  • Loading state pada tombol Masuk dan tombol Google.
  • Error handling: field-level errors + toast notification (success/error).
  • Navigasi: <NuxtLink> untuk "Daftar", "Lupa kata sandi?", "Ketentuan Layanan", "Kebijakan Privasi".

File yang Diubah/Dibuat

File Aksi
nuxt.config.ts Diubah - tambah runtimeConfig + app.head
app/composables/useGoogleAuth.ts Dibuat
app/components/ui/sonner/Sonner.vue Dibuat
app/components/ui/sonner/index.ts Dibuat (auto)
app/app.vue Diubah - tambah <Toaster />
app/components/LoginForm.vue Diubah - tambah fungsionalitas
package.json Diubah - tambah vue-sonner

Issues yang Dihadapi

1. Cannot read properties of null (reading 'useState')

  • Penyebab: sonner (multi-framework) menarik React ke dalam project Vue.
  • Solusi: Ganti dengan vue-sonner.

2. Invalid hook call (React hooks error)

  • Penyebab: Sisa dependency React dari paket sonner masih ada di node_modules/.
  • Solusi: Hapus manual node_modules/react, node_modules/react-dom, node_modules/@types/react.

3. Build error Could not load Toaster.vue

  • Penyebab: File di direktori sonner/ bernama Sonner.vue tapi import di app.vue mencari Toaster.vue.
  • Solusi: Update import path di app.vue ke Sonner.vue.

API yang Digunakan

  • POST /v1/auth/login - Body: { login, password }
  • POST /v1/auth/google-login - Body: { credential } (Google JWT)

Environment Variables

NUXT_PUBLIC_API_BASE=http://localhost:8000/v1
NUXT_PUBLIC_GOOGLE_CLIENT_ID=