From cca999baf9a3fa5e9a5c15bccc19e82dc05805c4 Mon Sep 17 00:00:00 2001 From: Mahdi Date: Sun, 24 May 2026 11:41:13 +0330 Subject: [PATCH] Add service templates admin UI per business category --- src/api/service-templates.ts | 35 ++++ src/api/types.ts | 26 +++ src/router/index.ts | 6 + src/views/CategoriesView.vue | 11 +- src/views/ServiceTemplatesView.vue | 283 +++++++++++++++++++++++++++++ 5 files changed, 360 insertions(+), 1 deletion(-) create mode 100644 src/api/service-templates.ts create mode 100644 src/views/ServiceTemplatesView.vue diff --git a/src/api/service-templates.ts b/src/api/service-templates.ts new file mode 100644 index 0000000..05542ee --- /dev/null +++ b/src/api/service-templates.ts @@ -0,0 +1,35 @@ +import { api } from './client'; +import type { + CreateServiceTemplatePayload, + ServiceTemplate, + UpdateServiceTemplatePayload, +} from './types'; + +export function fetchServiceTemplates(categoryId?: string) { + const search = new URLSearchParams(); + if (categoryId) { + search.set('categoryId', categoryId); + } + const qs = search.toString(); + return api(`/service-templates${qs ? `?${qs}` : ''}`); +} + +export function createServiceTemplate(payload: CreateServiceTemplatePayload) { + return api('/service-templates', { + method: 'POST', + body: JSON.stringify(payload), + }); +} + +export function updateServiceTemplate(id: string, payload: UpdateServiceTemplatePayload) { + return api(`/service-templates/${id}`, { + method: 'PATCH', + body: JSON.stringify(payload), + }); +} + +export function deleteServiceTemplate(id: string) { + return api<{ success: true }>(`/service-templates/${id}`, { + method: 'DELETE', + }); +} diff --git a/src/api/types.ts b/src/api/types.ts index b053ec5..fbbe686 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -77,6 +77,32 @@ export type CreateCategoryPayload = { export type UpdateCategoryPayload = Partial; +export type ServiceTemplate = { + id: string; + title: string; + slug: string; + description: string | null; + defaultDurationMinutes: number; + isActive: boolean; + categoryId: string; + category?: BusinessCategory; + createdAt?: string; + updatedAt?: string; +}; + +export type CreateServiceTemplatePayload = { + title: string; + slug: string; + categoryId: string; + description?: string; + defaultDurationMinutes?: number; + isActive?: boolean; +}; + +export type UpdateServiceTemplatePayload = Partial< + Omit +>; + export type UpdateUserPayload = { fullName?: string | null; role?: UserRole; diff --git a/src/router/index.ts b/src/router/index.ts index 7d1f7a9..ca04c79 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -28,6 +28,12 @@ const router = createRouter({ component: () => import('@/views/CategoriesView.vue'), meta: { requiresAuth: true, requiresAdmin: true }, }, + { + path: '/service-templates', + name: 'service-templates', + component: () => import('@/views/ServiceTemplatesView.vue'), + meta: { requiresAuth: true, requiresAdmin: true }, + }, { path: '/businesses', name: 'businesses', diff --git a/src/views/CategoriesView.vue b/src/views/CategoriesView.vue index fe6c8b8..d5b4469 100644 --- a/src/views/CategoriesView.vue +++ b/src/views/CategoriesView.vue @@ -2,7 +2,15 @@ @@ -75,6 +83,7 @@