Files
webMontime/src/components/profile/ProfilePanel.vue
T
2026-07-16 17:53:19 +03:30

168 lines
5.6 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div v-if="auth.user" class="space-y-4">
<p
v-if="message"
class="rounded-xl border border-brand-500/40 bg-brand-500/10 px-4 py-3 text-sm text-brand-700 dark:text-brand-500"
>
{{ message }}
</p>
<p
v-if="error"
class="rounded-xl border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm text-red-600"
>
{{ error }}
</p>
<dl class="space-y-3 rounded-2xl border border-border bg-surface-2 p-4">
<div class="flex items-center justify-between gap-4">
<dt class="shrink-0 text-xs text-muted">موبایل</dt>
<dd class="font-medium" dir="ltr">{{ auth.user.mobile }}</dd>
</div>
<div class="flex items-center justify-between gap-4">
<dt class="shrink-0 text-xs text-muted">نقش</dt>
<dd class="font-medium">{{ roleLabel }}</dd>
</div>
</dl>
<RouterLink
to="/guide"
class="flex w-full items-center justify-between rounded-2xl border border-border bg-surface-2 px-4 py-3 text-sm font-semibold text-text transition hover:border-brand-500/40"
@click="profileModal.close()"
>
<span>راهنمای کاربری</span>
<span class="text-xs font-normal text-muted">مشاهده</span>
</RouterLink>
<section
v-if="auth.isCustomer"
class="rounded-2xl border border-border bg-surface-2 p-4"
>
<h2 class="text-sm font-semibold text-text">کسب‌وکار من</h2>
<p class="mt-1 text-xs text-muted">
می‌توانید درخواست ثبت کسب‌وکار دهید تا پس از تأیید مدیریت، پنل صاحب کسب‌وکار فعال شود.
</p>
<RouterLink
to="/app/register-business"
class="mt-3 inline-flex w-full items-center justify-center rounded-xl bg-brand-600 px-4 py-3 text-sm font-semibold text-white"
@click="profileModal.close()"
>
ثبت کسب‌وکار من
</RouterLink>
</section>
<section
v-else-if="auth.isBusinessOwner"
class="rounded-2xl border border-border bg-surface-2 p-4"
>
<h2 class="text-sm font-semibold text-text">مدیریت کسب‌وکار</h2>
<RouterLink
to="/app/owner"
class="mt-3 inline-flex w-full items-center justify-center rounded-xl border border-border px-4 py-3 text-sm font-semibold text-text hover:bg-surface-3"
@click="profileModal.close()"
>
ورود به پنل کسب‌وکار
</RouterLink>
</section>
<section class="space-y-3 rounded-2xl border border-border bg-surface-2 p-4">
<h2 class="text-sm font-semibold text-text">
{{ auth.user.hasPassword ? 'تغییر رمز عبور' : 'تنظیم رمز عبور' }}
</h2>
<p class="text-xs text-muted">
پس از تنظیم رمز، ورود با رمز عبور یا کد یکبارمصرف هر دو ممکن است.
</p>
<AppInput id="profileNewPassword" v-model="newPassword" label="رمز جدید" type="password" ltr />
<AppInput
id="profileConfirmPassword"
v-model="confirmPassword"
label="تکرار رمز جدید"
type="password"
ltr
/>
<AppButton :loading="saving" @click="onSavePassword">
{{ auth.user.hasPassword ? 'به‌روزرسانی رمز' : 'ذخیره رمز' }}
</AppButton>
</section>
<section class="rounded-2xl border border-border bg-surface-2 p-4">
<h2 class="text-sm font-semibold text-text">خروج از حساب</h2>
<p class="mt-1 text-xs text-muted">
با خروج، برای رزرو مجدد باید دوباره وارد شوید.
</p>
<AppButton variant="danger" class="mt-3" @click="onLogout">
خروج
</AppButton>
</section>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import { RouterLink, useRouter } from 'vue-router';
import { setPassword } from '@/api/auth';
import { ApiError } from '@/api/client';
import AppButton from '@/components/ui/AppButton.vue';
import AppInput from '@/components/ui/AppInput.vue';
import { useAuthStore } from '@/stores/auth';
import { useProfileModalStore } from '@/stores/profile-modal';
const auth = useAuthStore();
const profileModal = useProfileModalStore();
const router = useRouter();
const newPassword = ref('');
const confirmPassword = ref('');
const saving = ref(false);
const error = ref('');
const message = ref('');
const roleLabel = computed(() => {
switch (auth.user?.role) {
case 'admin':
return 'مدیر سیستم';
case 'business_owner':
return 'صاحب کسب‌وکار';
default:
return 'مشتری';
}
});
function onLogout() {
profileModal.close();
auth.logout();
void router.push({ name: 'app-home' });
}
async function onSavePassword() {
if (!auth.user) return;
error.value = '';
message.value = '';
if (newPassword.value.length < 8) {
error.value = 'رمز باید حداقل ۸ کاراکتر باشد.';
return;
}
if (newPassword.value !== confirmPassword.value) {
error.value = 'تکرار رمز با رمز جدید یکسان نیست.';
return;
}
saving.value = true;
try {
const updated = await setPassword({
password: newPassword.value,
confirmPassword: confirmPassword.value,
});
auth.setUser(updated);
newPassword.value = '';
confirmPassword.value = '';
message.value = 'رمز عبور ذخیره شد.';
} catch (e) {
error.value = e instanceof ApiError ? e.message : 'خطا در ذخیره رمز';
} finally {
saving.value = false;
}
}
</script>