Deploy
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
'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
|
||||
address_line1: string | null
|
||||
address_line2: string | null
|
||||
city: string | null
|
||||
province: string | null
|
||||
postal_code: 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 sync = () => {
|
||||
const saved = typeof window !== 'undefined' ? localStorage.getItem(TOKEN_KEY) : null
|
||||
if (!saved) { setCustomer(null); setToken(null); 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); setCustomer(null); setToken(null) }
|
||||
})
|
||||
.catch(() => { localStorage.removeItem(TOKEN_KEY); setCustomer(null); setToken(null) })
|
||||
.finally(() => setLoading(false))
|
||||
}
|
||||
sync()
|
||||
window.addEventListener('vula-auth-updated', sync)
|
||||
return () => window.removeEventListener('vula-auth-updated', sync)
|
||||
}, [])
|
||||
|
||||
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)
|
||||
window.dispatchEvent(new CustomEvent('vula-auth-updated'))
|
||||
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)
|
||||
window.dispatchEvent(new CustomEvent('vula-auth-updated'))
|
||||
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)
|
||||
window.dispatchEvent(new CustomEvent('vula-auth-updated'))
|
||||
}, [])
|
||||
|
||||
const updateProfile = useCallback(async (data: Partial<Pick<Customer, 'first_name' | 'last_name' | 'phone' | 'address_line1' | 'address_line2' | 'city' | 'province' | 'postal_code'>> & { 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 }
|
||||
}
|
||||
Reference in New Issue
Block a user