fix
Deploy banu-front / deploy (push) Successful in 1m27s

This commit is contained in:
sajjadtalkhabi
2026-07-07 17:36:43 +03:30
parent b9ef684b51
commit 38a396ba21
89 changed files with 1815 additions and 478 deletions
@@ -21,25 +21,25 @@
<div class="verification-item__date">
<span class="verification-item__date-label">تاریخ ثبت نام:</span>
<span class="verification-item__date-value">
{{ formatJalaaliDate(user.createdAt) || '—' }}
{{ formatJalaaliDateTime(user.createdAt) || '—' }}
</span>
</div>
<div
v-if="user.status === 'verified'"
class="verification-item__badge verification-item__badge--pending"
>
<span class="verification-item__dot" />
<span>در انتظار تایید</span>
</div>
<button
v-else-if="user.status === 'rejected'"
type="button"
class="verification-item__badge verification-item__badge--rejected"
<Badge
v-if="user.status === 'rejected'"
variant="danger"
:dot="true"
value="رد شده"
:clickable="true"
@click="emit('show-reject-reason', user)"
>
<span class="verification-item__dot" />
<span>رد شده</span>
</button>
/>
<Badge
v-else-if="statusLabel"
:variant="statusVariant"
:dot="true"
:value="statusLabel"
:clickable="user.status === 'blocked'"
@click="emit('show-reject-reason', user)"
/>
</div>
<div class="verification-item__actions">
@@ -54,11 +54,11 @@
</template>
</CircleButton>
<CircleButton
v-if="user.status !== 'rejected'"
v-if="user.status !== 'blocked'"
tooltip="عدم تایید"
bg-color="rgba(204, 40, 49, 0.08)"
size="2.5rem"
@click="emit('verify-user', { id: user.id, status: 'rejected' })"
@click="emit('verify-user', { id: user.id, status: 'blocked' })"
>
<template #icon>
<SvgIcon name="close" :size="20" color="var(--color-error)" />
@@ -80,10 +80,12 @@
<script setup>
import { computed } from 'vue'
import { USER_STATUS } from '@/enums'
import Badge from '@/components/Badge.vue'
import BaseButton from '@/components/BaseButton.vue'
import SvgIcon from '@/components/icons/SvgIcon.vue'
import { formatJalaaliDate } from '@/utils/date-utils'
import CircleButton from '@/components/CircleButton.vue'
import { formatJalaaliDateTime } from '@/utils/date-utils'
const props = defineProps({
user: { type: Object, required: true },
@@ -92,7 +94,16 @@ const props = defineProps({
const emit = defineEmits(['show-details', 'show-reject-reason', 'verify-user'])
const STATUS_VARIANTS = {
pending: 'neutral',
verified: 'warning',
approved: 'success',
blocked: 'danger',
}
const fullName = computed(() => `${props.user.name || ''}`.trim() || '—')
const statusLabel = computed(() => USER_STATUS[props.user.status] || '')
const statusVariant = computed(() => STATUS_VARIANTS[props.user.status] || 'neutral')
</script>
<style lang="scss" scoped>
@@ -202,37 +213,6 @@ const fullName = computed(() => `${props.user.name || ''}`.trim() || '—')
font-size: 0.75rem;
}
&__badge {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.25rem 1rem;
border-radius: 0.875rem;
font-family: var(--font-family-fa);
font-size: 0.7rem;
line-height: 1.5;
border: none;
cursor: default;
&--pending {
background: rgba(0, 255, 68, 6%);
color: #009a12;
}
&--rejected {
background: rgba(204, 40, 49, 6%);
color: var(--color-error);
cursor: pointer;
}
}
&__dot {
width: 0.375rem;
height: 0.375rem;
border-radius: 9999px;
background: currentcolor;
}
&__actions {
display: flex;
justify-content: flex-end;
@@ -31,7 +31,7 @@
@click="onReset"
>
<template #icon>
<SvgIcon name="close" :size="20" />
<SvgIcon name="close" color="black" :size="20" />
</template>
</CircleButton>
<CircleButton
@@ -11,7 +11,7 @@
<div class="reject-reason-details">
<div class="reject-reason-details__grid">
<div class="reject-reason-details__cell--full">
<LineInfoBlock title="توضیحات" :desc="verification(data).adminNote || ''" />
<LineInfoBlock title="توضیحات" :desc="data?.user?.blockReason || ''" />
</div>
</div>
@@ -34,8 +34,6 @@ import SvgIcon from '@/components/icons/SvgIcon.vue'
import LineInfoBlock from '@/components/blocks/LineInfoBlock.vue'
defineOptions({ name: 'RejectReasonDetailsModal' })
const verification = (data) => data?.verification || {}
</script>
<style lang="scss" scoped>
@@ -9,31 +9,13 @@
>
<template #default="{ data, close }">
<form class="reject-reason-modal" @submit.prevent="onSubmit(data, close)">
<div class="reject-reason-modal__row">
<TextField
v-model="form.rejectionReason"
name="rejectionReason"
label="علت رد"
:error="errors.rejectionReason"
@blur="validateAt('rejectionReason', form.rejectionReason)"
/>
<SelectField
:model-value="form.priority?.id"
name="priority"
label="وضعیت تیکت"
:options="statusOptions"
option-label="label"
option-value="value"
:error="errors.priority"
@update:model-value="(e) => handleChange('priority', { id: e })"
/>
</div>
<TextareaField
v-model="form.adminNote"
name="adminNote"
v-model="form.reason"
name="reason"
label="لطفا علت رد را توضیح دهید"
:row="4"
:error="errors.adminNote"
:error="errors.reason"
@blur="validateAt('reason', form.reason)"
/>
<div class="reject-reason-modal__divider" />
@@ -68,14 +50,11 @@
<script setup>
import { ref } from 'vue'
import useYup from '@/composables/useYup'
import { PRIORITY_STATUS } from '@/enums'
import { useQueryClient } from '@tanstack/vue-query'
import BasicModal from '@/components/BasicModal.vue'
import BaseButton from '@/components/BaseButton.vue'
import SvgIcon from '@/components/icons/SvgIcon.vue'
import TextField from '@/components/form/TextField.vue'
import { rejectionReasonSchema } from '../../../schema'
import SelectField from '@/components/form/SelectField.vue'
import TextareaField from '@/components/form/TextareaField.vue'
import { adminUsersKeys, useChangeAdminUserStatusMutation } from '@/services/query/admin-users'
@@ -84,22 +63,12 @@ defineOptions({ name: 'RejectReasonModal' })
const queryClient = useQueryClient()
const changeStatusMutation = useChangeAdminUserStatusMutation()
const DEFAULT_FORM = { rejectionReason: '', adminNote: '' }
const DEFAULT_FORM = { reason: '' }
const { validate, validateAt, errors, resetErrors } = useYup(rejectionReasonSchema)
const form = ref(structuredClone({ ...DEFAULT_FORM }))
const statusOptions = Object.entries(PRIORITY_STATUS).map(([value, label]) => ({
value,
label,
}))
const handleChange = (key, value) => {
form.value = { ...form.value, [key]: value }
validateAt(key, value)
}
const onSubmit = async (data, close) => {
const { isValid, payload } = await validate(form.value)
if (!isValid) return
@@ -107,7 +76,7 @@ const onSubmit = async (data, close) => {
if (!id) return
await changeStatusMutation.mutateAsync({
id,
payload: { status: 'blocked', ...payload },
payload: { status: 'blocked', reason: payload.reason },
})
await queryClient.invalidateQueries({ queryKey: adminUsersKeys.all })
form.value = structuredClone({ ...DEFAULT_FORM })
@@ -122,11 +91,6 @@ const onSubmit = async (data, close) => {
text-align: start;
padding: 0.5rem;
&__row {
display: flex;
gap: 1rem;
}
&__divider {
border-block-end: 1px solid var(--color-thd-gray);
margin-block: 1rem;
@@ -21,10 +21,7 @@
/>
<LineInfoBlock title="شماره تماس" :numeric-desc="personal.phone" />
<LineInfoBlock title="کد ملی" :numeric-desc="personal.nationalCode" />
<LineInfoBlock
title="وضعیت تاهل"
:desc="MARITAL_STATUS[personal.maritalStatus] || ''"
/>
<LineInfoBlock title="وضعیت" :desc="MARITAL_STATUS[personal.maritalStatus] || ''" />
<LineInfoBlock title="جنسیت" :desc="GENDER[personal.gender] || ''" />
<LineInfoBlock title="استان" :desc="personal.province || '-'" />
<LineInfoBlock title="شهر" :desc="personal.city || '-'" />