Files
dashboards/apps/customer/src/services/authService.ts
T
Alireza HassaniandCursor 6d85a217e1 Add OTP-first customer signup and product catalog PDF field.
Registration collects name and phone, verifies SMS, then asks for a password only for new Meshkee accounts. Product add/edit supports an optional catalog PDF.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-27 08:57:08 +03:30

158 lines
3.7 KiB
TypeScript

import { apiRequest, setTokens, clearTokens } from '../lib/api'
import { clearActiveBusiness } from '../lib/businessContext'
import type {
AuthUser,
LoginResponse,
MeResponse,
OtpSendResponse,
OtpVerifyResponse,
RegisterResponse,
SignupStartResponse,
SignupVerifyResponse,
HandoffCreateResponse,
UserProfile,
} from '../types/auth'
export async function login(
cellNumber: string,
password: string,
domain?: string,
) {
const data = await apiRequest<LoginResponse>('/auth/login', {
method: 'POST',
body: domain ? { cellNumber, password, domain } : { cellNumber, password },
})
setTokens(data.accessToken, data.refreshToken)
return data
}
export async function register(input: {
cellNumber: string
password: string
firstName: string
lastName: string
email?: string
domain: string
acknowledgeExistingAccount?: boolean
}) {
const data = await apiRequest<RegisterResponse>('/auth/register', {
method: 'POST',
body: input,
})
if (data.accessToken && data.refreshToken) {
setTokens(data.accessToken, data.refreshToken)
}
return data
}
export async function startSignup(input: {
cellNumber: string
firstName: string
lastName: string
domain: string
}) {
return apiRequest<SignupStartResponse>('/auth/signup/start', {
method: 'POST',
body: input,
})
}
export async function verifySignupOtp(cellNumber: string, code: string) {
return apiRequest<SignupVerifyResponse>('/auth/signup/verify-otp', {
method: 'POST',
body: { cellNumber, code },
})
}
export async function completeSignup(input: {
registrationToken: string
password?: string
}) {
const data = await apiRequest<RegisterResponse>('/auth/signup/complete', {
method: 'POST',
body: input,
})
if (data.accessToken && data.refreshToken) {
setTokens(data.accessToken, data.refreshToken)
}
return data
}
export async function fetchCurrentUser(signal?: AbortSignal) {
return apiRequest<MeResponse>('/auth/me', { auth: true, signal })
}
export async function updateProfile(
payload: Partial<UserProfile> & {
firstName?: string
lastName?: string
firstNameEn?: string
lastNameEn?: string
email?: string
},
) {
return apiRequest<{ message: string; user: AuthUser }>('/auth/profile', {
method: 'PATCH',
auth: true,
body: payload,
})
}
export async function changePassword(currentPassword: string, newPassword: string) {
return apiRequest<{ message: string }>('/auth/change-password', {
method: 'POST',
auth: true,
body: { currentPassword, newPassword },
})
}
export async function sendOtp(cellNumber: string, domain?: string) {
return apiRequest<OtpSendResponse>('/auth/send-otp', {
method: 'POST',
body: domain ? { cellNumber, domain } : { cellNumber },
})
}
export async function verifyOtp(cellNumber: string, code: string) {
return apiRequest<OtpVerifyResponse>('/auth/verify-otp', {
method: 'POST',
body: { cellNumber, code },
})
}
export async function loginWithOtp(
cellNumber: string,
code: string,
domain?: string,
) {
const data = await apiRequest<LoginResponse>('/auth/login-otp', {
method: 'POST',
body: domain ? { cellNumber, code, domain } : { cellNumber, code },
})
setTokens(data.accessToken, data.refreshToken)
return data
}
export async function resetPassword(cellNumber: string, code: string, newPassword: string) {
return apiRequest<{ message: string }>('/auth/reset-password', {
method: 'POST',
body: { cellNumber, code, newPassword },
})
}
export async function createHandoff() {
return apiRequest<HandoffCreateResponse>('/auth/handoff', {
method: 'POST',
auth: true,
})
}
export function logout() {
clearTokens()
clearActiveBusiness()
}