Add customer/manager access UI and tighten customers filters.
Business and super-admin can set Customer vs Manager roles (Admin only for super-admin), and the customers page drops clutter while filtering by all/customers/managers. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
404c008ced
commit
f622e6d605
@@ -17,6 +17,10 @@ export interface BusinessCustomerListItem extends BusinessCustomer {
|
||||
orderCount?: number | null
|
||||
/** Placeholder until orders stats API exists */
|
||||
totalTransactionsIrt?: number | null
|
||||
/** Present when this customer is also staff/owner on the business. */
|
||||
businessMemberId?: string | null
|
||||
isBusinessOwner?: boolean
|
||||
teamRole?: string | null
|
||||
}
|
||||
|
||||
export interface CustomersListResponse {
|
||||
@@ -26,11 +30,14 @@ export interface CustomersListResponse {
|
||||
pageSize: number
|
||||
}
|
||||
|
||||
export type CustomerAccessFilter = 'all' | 'customers' | 'managers'
|
||||
|
||||
export interface ListCustomersParams {
|
||||
page?: number
|
||||
pageSize?: number
|
||||
name?: string
|
||||
cellNumber?: string
|
||||
access?: CustomerAccessFilter
|
||||
}
|
||||
|
||||
function businessPath(suffix = '') {
|
||||
@@ -50,6 +57,7 @@ export async function listCustomers(
|
||||
if (params.pageSize !== undefined) q.set('pageSize', String(params.pageSize))
|
||||
if (params.name) q.set('name', params.name)
|
||||
if (params.cellNumber) q.set('cellNumber', params.cellNumber)
|
||||
if (params.access) q.set('access', params.access)
|
||||
|
||||
const query = q.toString()
|
||||
const path = `${businessPath()}${query ? `?${query}` : ''}`
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { apiRequest } from '../lib/api'
|
||||
import { getActiveBusinessId } from '../lib/businessContext'
|
||||
|
||||
export type BusinessAccess = 'customer' | 'staff'
|
||||
|
||||
export interface AssignBusinessAccessPayload {
|
||||
userId: string
|
||||
access: BusinessAccess
|
||||
roleSlug?: string
|
||||
}
|
||||
|
||||
export interface AssignBusinessAccessResult {
|
||||
message: string
|
||||
access: BusinessAccess
|
||||
member: {
|
||||
id: string | number
|
||||
userId: string | number
|
||||
isOwner: boolean
|
||||
teamRole: string | null
|
||||
} | null
|
||||
}
|
||||
|
||||
function teamPath(suffix = '') {
|
||||
const businessId = getActiveBusinessId()
|
||||
if (!businessId) {
|
||||
throw new Error('No active business selected. Please sign in again.')
|
||||
}
|
||||
return `/businesses/${businessId}/team${suffix}`
|
||||
}
|
||||
|
||||
/** Set customer vs manager (admin/editor/viewer) for a user on this business. */
|
||||
export async function assignBusinessAccess(payload: AssignBusinessAccessPayload) {
|
||||
return apiRequest<AssignBusinessAccessResult>(teamPath('/access'), {
|
||||
method: 'PATCH',
|
||||
auth: true,
|
||||
body: {
|
||||
userId: String(payload.userId),
|
||||
access: payload.access,
|
||||
...(payload.access === 'staff' && payload.roleSlug
|
||||
? { roleSlug: payload.roleSlug }
|
||||
: {}),
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user