This commit is contained in:
Vula Builder
2026-07-29 18:15:18 +00:00
parent da0c3397ce
commit e797eaa016
+89
View File
@@ -0,0 +1,89 @@
'use client'
import { useState, useEffect, useCallback } from 'react'
const COMMERCE_URL = process.env.NEXT_PUBLIC_VULA_COMMERCE_URL || 'https://ide.vulai.co.za'
const PROJECT_ID = process.env.NEXT_PUBLIC_VULA_PROJECT_ID || ''
const TOKEN_KEY = `vula_customer_${PROJECT_ID}`
export interface Customer {
id: string
email: string
first_name: string | null
last_name: string | null
phone: string | null
created_at: string
}
export function useCustomerAuth() {
const [customer, setCustomer] = useState<Customer | null>(null)
const [token, setToken] = useState<string | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
const saved = typeof window !== 'undefined' ? localStorage.getItem(TOKEN_KEY) : null
if (!saved) { setLoading(false); return }
fetch(`${COMMERCE_URL}/api/commerce/${PROJECT_ID}/customers/me`, {
headers: { Authorization: `Bearer ${saved}` }
})
.then(r => r.json())
.then(d => {
if (d.success) { setCustomer(d.customer); setToken(saved) }
else { localStorage.removeItem(TOKEN_KEY) }
})
.catch(() => localStorage.removeItem(TOKEN_KEY))
.finally(() => setLoading(false))
}, [])
const register = useCallback(async (data: {
email: string; password: string; first_name?: string; last_name?: string; phone?: string
}) => {
setError(null); setLoading(true)
try {
const r = await fetch(`${COMMERCE_URL}/api/commerce/${PROJECT_ID}/customers/register`, {
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data)
})
const d = await r.json()
if (!d.success) throw new Error(d.error || 'Registration failed')
localStorage.setItem(TOKEN_KEY, d.token)
setCustomer(d.customer); setToken(d.token)
return d.customer as Customer
} catch (e: any) { setError(e.message); throw e }
finally { setLoading(false) }
}, [])
const login = useCallback(async (email: string, password: string) => {
setError(null); setLoading(true)
try {
const r = await fetch(`${COMMERCE_URL}/api/commerce/${PROJECT_ID}/customers/login`, {
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password })
})
const d = await r.json()
if (!d.success) throw new Error(d.error || 'Login failed')
localStorage.setItem(TOKEN_KEY, d.token)
setCustomer(d.customer); setToken(d.token)
return d.customer as Customer
} catch (e: any) { setError(e.message); throw e }
finally { setLoading(false) }
}, [])
const logout = useCallback(() => {
localStorage.removeItem(TOKEN_KEY)
setCustomer(null); setToken(null)
}, [])
const updateProfile = useCallback(async (data: Partial<Pick<Customer, 'first_name' | 'last_name' | 'phone'>> & { password?: string; new_password?: string }) => {
const t = typeof window !== 'undefined' ? localStorage.getItem(TOKEN_KEY) : null
if (!t) throw new Error('Not authenticated')
const r = await fetch(`${COMMERCE_URL}/api/commerce/${PROJECT_ID}/customers/me`, {
method: 'PUT', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${t}` },
body: JSON.stringify(data)
})
const d = await r.json()
if (!d.success) throw new Error(d.error || 'Update failed')
setCustomer(d.customer)
return d.customer as Customer
}, [])
return { customer, token, loading, error, isAuthenticated: !!customer, register, login, logout, updateProfile }
}