Files
webMontime/src/views/app/AppOwnerView.vue
T

131 lines
4.6 KiB
Vue
Raw Normal View History

2026-05-18 20:18:28 +03:30
<template>
2026-06-12 20:16:14 +03:30
<ResponsiveAppLayout>
<h1 class="mb-1 text-xl font-bold text-text">مدیریت کسب‌وکار</h1>
<p class="mb-6 text-sm text-muted">تنظیمات کسب‌وکار، خدمات و ساعات کاری</p>
2026-06-03 16:35:09 +03:30
<FormPageSkeleton v-if="loading" />
2026-06-12 20:16:14 +03:30
<p
v-else-if="error"
class="rounded-xl border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm text-red-600 dark:text-red-400"
>
2026-06-12 20:16:14 +03:30
{{ error }}
</p>
2026-06-12 20:16:14 +03:30
<div v-else-if="business" class="mx-auto max-w-3xl space-y-6">
<form class="space-y-4 rounded-2xl border border-border bg-surface-2 p-4" @submit.prevent="saveBusiness">
<AppInput id="ownerTitle" v-model="form.title" label="نام کسب‌وکار" required />
2026-06-12 20:16:14 +03:30
<AppInput id="ownerSubtitle" v-model="form.subtitle" label="زیرعنوان" />
<AppTextarea id="ownerDescription" v-model="form.description" label="توضیحات" />
<AppInput id="ownerAddress" v-model="form.address" label="آدرس" />
2026-06-12 20:16:14 +03:30
<AppInput id="ownerPhone" v-model="form.phone" label="تلفن" ltr />
<p v-if="saveMessage" class="text-sm text-brand-700 dark:text-brand-500">{{ saveMessage }}</p>
<AppButton type="submit" :loading="saving">ذخیره اطلاعات</AppButton>
</form>
2026-05-31 21:38:09 +03:30
<ServiceClassManager
:business-id="business.id"
2026-06-12 20:16:14 +03:30
:enabled="serviceClassesEnabled"
@update:enabled="setServiceClassesEnabled"
2026-05-31 21:38:09 +03:30
/>
2026-06-12 20:16:14 +03:30
<BusinessAvailabilityEditor :business-id="business.id" />
</div>
2026-06-12 20:16:14 +03:30
</ResponsiveAppLayout>
2026-05-18 20:18:28 +03:30
</template>
<script setup lang="ts">
2026-06-12 20:16:14 +03:30
import { onMounted, ref } from 'vue';
import { fetchMyBusinesses, updateBusiness } from '@/api/businesses';
import { ApiError } from '@/api/client';
2026-06-12 20:16:14 +03:30
import type { Business } from '@/api/types';
2026-05-25 19:13:28 +03:30
import BusinessAvailabilityEditor from '@/components/owner/BusinessAvailabilityEditor.vue';
2026-05-31 21:38:09 +03:30
import ServiceClassManager from '@/components/owner/ServiceClassManager.vue';
import AppButton from '@/components/ui/AppButton.vue';
import AppInput from '@/components/ui/AppInput.vue';
2026-06-12 20:16:14 +03:30
import AppTextarea from '@/components/ui/AppTextarea.vue';
import FormPageSkeleton from '@/components/ui/FormPageSkeleton.vue';
import ResponsiveAppLayout from '@/layouts/ResponsiveAppLayout.vue';
import { useTenantStore } from '@/stores/tenant';
2026-06-12 20:16:14 +03:30
const tenant = useTenantStore();
const business = ref<Business | null>(null);
const loading = ref(true);
const saving = ref(false);
const error = ref('');
2026-06-12 20:16:14 +03:30
const saveMessage = ref('');
const serviceClassesEnabled = ref(false);
const form = ref({
title: '',
2026-06-12 20:16:14 +03:30
subtitle: '',
description: '',
address: '',
2026-06-12 20:16:14 +03:30
phone: '',
});
2026-06-12 20:16:14 +03:30
async function loadBusiness() {
loading.value = true;
2026-05-31 21:38:09 +03:30
error.value = '';
2026-06-12 20:16:14 +03:30
try {
const items = await fetchMyBusinesses();
business.value = items[0] ?? null;
if (!business.value) {
error.value = 'کسب‌وکاری برای مدیریت یافت نشد.';
return;
}
form.value = {
title: business.value.title,
subtitle: business.value.subtitle ?? '',
description: business.value.description ?? '',
address: business.value.address ?? '',
phone: business.value.phone ?? '',
};
serviceClassesEnabled.value = business.value.serviceClassesEnabled ?? false;
} catch (e) {
error.value = e instanceof ApiError ? e.message : 'بارگذاری کسب‌وکار ناموفق بود.';
} finally {
loading.value = false;
}
}
async function setServiceClassesEnabled(value: boolean) {
if (!business.value) return;
const previous = serviceClassesEnabled.value;
serviceClassesEnabled.value = value;
2026-05-31 21:38:09 +03:30
try {
business.value = await updateBusiness(business.value.id, {
serviceClassesEnabled: value,
});
2026-06-12 20:16:14 +03:30
tenant.syncSingleBusiness(business.value);
2026-05-31 21:38:09 +03:30
} catch (e) {
2026-06-12 20:16:14 +03:30
serviceClassesEnabled.value = previous;
error.value =
e instanceof ApiError ? e.message : 'ذخیره وضعیت کلاس‌بندی ناموفق بود.';
2026-05-31 21:38:09 +03:30
}
}
2026-06-12 20:16:14 +03:30
async function saveBusiness() {
if (!business.value) return;
saving.value = true;
2026-06-12 20:16:14 +03:30
saveMessage.value = '';
try {
business.value = await updateBusiness(business.value.id, {
title: form.value.title.trim(),
2026-06-12 20:16:14 +03:30
subtitle: form.value.subtitle.trim() || null,
description: form.value.description.trim() || null,
address: form.value.address.trim() || null,
2026-06-12 20:16:14 +03:30
phone: form.value.phone.trim() || null,
});
2026-06-12 20:16:14 +03:30
tenant.syncSingleBusiness(business.value);
saveMessage.value = 'تغییرات ذخیره شد.';
} catch (e) {
2026-06-12 20:16:14 +03:30
error.value = e instanceof ApiError ? e.message : 'ذخیره ناموفق بود.';
} finally {
saving.value = false;
}
}
2026-06-12 20:16:14 +03:30
onMounted(() => {
void loadBusiness();
});
2026-05-18 20:18:28 +03:30
</script>