feat: add withdraw request functionality and UI components
This commit is contained in:
@@ -118,17 +118,17 @@ const removeHistoryFile = (index) => {
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="submitted_at" initialValue="" class="flex flex-col gap-1">
|
||||
<label>تاریخ ثبت</label>
|
||||
<CustomDatePicker v-model="documentStore.createForm.submitted_at" class="!text-xs" type="datetime" compact-time></CustomDatePicker>
|
||||
<CustomDatePicker v-model="documentStore.createForm.submitted_at" type="datetime" compact-time></CustomDatePicker>
|
||||
<Message v-if="documentStore.errorsCreateForm?.submitted_at" severity="error" size="small" variant="simple">{{ documentStore.errorsCreateForm?.submitted_at[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="processing_deadline" initialValue="" class="flex flex-col gap-1">
|
||||
<label>مهلت پردازش</label>
|
||||
<CustomDatePicker v-model="documentStore.createForm.processing_deadline" class="!text-xs" type="datetime" compact-time></CustomDatePicker>
|
||||
<CustomDatePicker v-model="documentStore.createForm.processing_deadline" type="datetime" compact-time></CustomDatePicker>
|
||||
<Message v-if="documentStore.errorsCreateForm?.processing_deadline" severity="error" size="small" variant="simple">{{ documentStore.errorsCreateForm?.processing_deadline[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="note" initialValue="" class="flex flex-col col-span-2 gap-1">
|
||||
<label>متن درخواست</label>
|
||||
<Textarea type="text" class="placeholder:!text-sm" v-model="documentStore.createForm.note" placeholder="متن درخواست را وارد کنید" />
|
||||
<Textarea type="text" v-model="documentStore.createForm.note" placeholder="متن درخواست را وارد کنید" />
|
||||
</FormField>
|
||||
<div class="grid grid-cols-2 col-span-2 gap-4">
|
||||
<Card class="mt-4">
|
||||
@@ -155,7 +155,7 @@ const removeHistoryFile = (index) => {
|
||||
<div class="p-4 grid grid-cols-1 gap-4 rounded-2xl">
|
||||
<div class="grid grid-cols-1 justify-between items-center">
|
||||
<span>زمان انتشار:</span>
|
||||
<CustomDatePicker v-model="documentStore.createForm.datetime" class="!text-xs mt-2" type="datetime" compact-time></CustomDatePicker>
|
||||
<CustomDatePicker v-model="documentStore.createForm.datetime" class="mt-2" type="datetime" compact-time></CustomDatePicker>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 justify-start">
|
||||
<Button :loading="documentStore.loaderCreateForm" @click="documentStore.update_and_store" type="button" severity="secondary" :label="documentStore.buttonLabel" />
|
||||
@@ -166,29 +166,3 @@ const removeHistoryFile = (index) => {
|
||||
</section>
|
||||
</master>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.p-multiselect {
|
||||
height: auto;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.p-multiselect-label {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-header {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-filter {
|
||||
max-height: calc(100px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-item {
|
||||
font-size: 0.875rem;
|
||||
line-height: 44px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -56,24 +56,18 @@ onUnmounted(() => {
|
||||
<Form ref="formRef" v-slot="$form" class="flex flex-col gap-4 !w-full">
|
||||
<FormField v-slot="$field" name="name" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام سطح</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm',
|
||||
permissionStore.errorsCreateForm?.name && !permissionStore.createForm.name ? 'p-invalid' : ''
|
||||
]" v-model="permissionStore.createForm.name" placeholder="نام سطح را وارد کنید" />
|
||||
<InputText type="text" :class="permissionStore.errorsCreateForm?.name && !permissionStore.createForm.name ? 'p-invalid' : ''" v-model="permissionStore.createForm.name" placeholder="نام سطح را وارد کنید" />
|
||||
<Message v-if="permissionStore.errorsCreateForm?.name"
|
||||
severity="error" size="small" variant="simple">{{ permissionStore.errorsCreateForm?.name[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="label" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام فارسی سطح</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm',
|
||||
permissionStore.errorsCreateForm?.label && !permissionStore.createForm.label ? 'p-invalid' : ''
|
||||
]" v-model="permissionStore.createForm.label" placeholder="نام فارسی سطح را وارد کنید" />
|
||||
<InputText type="text" :class="permissionStore.errorsCreateForm?.label && !permissionStore.createForm.label ? 'p-invalid' : ''" v-model="permissionStore.createForm.label" placeholder="نام فارسی سطح را وارد کنید" />
|
||||
<Message v-if="permissionStore.errorsCreateForm?.label" severity="error" size="small" variant="simple">{{ permissionStore.errorsCreateForm?.label[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="parent_id" initialValue="" class="flex flex-col gap-1">
|
||||
<label> والد (مرتبط با) </label>
|
||||
<Select v-model="permissionStore.createForm.parent_id" optionLabel="label" optionValue="id" :pt="{option : '!text-sm'}"
|
||||
<Select v-model="permissionStore.createForm.parent_id" optionLabel="label" optionValue="id"
|
||||
:options="permissions.data" filter
|
||||
placeholder="انتخاب سطح" class="w-full">
|
||||
<template #empty>
|
||||
|
||||
@@ -54,41 +54,38 @@ onUnmounted(() => {
|
||||
<Form ref="formRef" v-slot="$form" class=" p-4 grid grid-cols-2 gap-4 !w-full">
|
||||
<FormField v-slot="$field" name="name" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام کیس</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm',
|
||||
petStore.errorsCreateForm?.name && !petStore.createForm.name ? 'p-invalid' : ''
|
||||
]" v-model="petStore.createForm.name" placeholder="نام کیس خود را وارد کنید" />
|
||||
<InputText type="text" :class="petStore.errorsCreateForm?.name && !petStore.createForm.name ? 'p-invalid' : ''" v-model="petStore.createForm.name" placeholder="نام کیس خود را وارد کنید" />
|
||||
<Message v-if="petStore.errorsCreateForm?.name"
|
||||
severity="error" size="small" variant="simple">{{ petStore.errorsCreateForm?.name[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="email" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نوع کیس</label>
|
||||
<Select class="!text-xs !h-full" placeholder="انتخاب نوع کیس" v-model="petStore.createForm.type" :options="petStore.typeOptions" optionValue="value" optionLabel="label" :pt="{ option : '!text-sm' , placeholder : '!text-sm' , label : '!pt-3' }" />
|
||||
<Select placeholder="انتخاب نوع کیس" v-model="petStore.createForm.type" :options="petStore.typeOptions" optionValue="value" optionLabel="label" />
|
||||
<Message v-if="petStore.errorsCreateForm?.type" severity="error" size="small" variant="simple">{{ petStore.errorsCreateForm?.type[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="breed" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نژاد</label>
|
||||
<InputText type="text" class="placeholder:!text-sm" v-model="petStore.createForm.breed" placeholder="نژاد را وارد کنید" />
|
||||
<InputText type="text" v-model="petStore.createForm.breed" placeholder="نژاد را وارد کنید" />
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="weight" initialValue="" class="flex flex-col gap-1">
|
||||
<label>وزن</label>
|
||||
<InputText type="text" class="placeholder:!text-sm" v-model="petStore.createForm.weight" placeholder="وزن را وارد کنید" />
|
||||
<InputText type="text" v-model="petStore.createForm.weight" placeholder="وزن را وارد کنید" />
|
||||
<Message v-if="$field?.invalid" severity="error" size="small" variant="simple">{{ $field.error?.message }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="sterilized" initialValue="" class="flex flex-col gap-1">
|
||||
<label>عقیم سازی</label>
|
||||
<Select class="!text-xs !h-full" placeholder="انتخاب عقیم سازی" v-model="petStore.createForm.sterilized" optionLabel="label" optionValue="value" :options="petStore.sterilizedOptions" :pt="{ option : '!text-sm' , placeholder : '!text-sm' , label : '!pt-3' }" />
|
||||
<Select placeholder="انتخاب عقیم سازی" v-model="petStore.createForm.sterilized" optionLabel="label" optionValue="value" :options="petStore.sterilizedOptions" />
|
||||
<Message v-if="petStore.errorsCreateForm?.sterilized"
|
||||
severity="error" size="small" variant="simple">{{ petStore.errorsCreateForm?.sterilized[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="gender" initialValue="" class="flex flex-col gap-1">
|
||||
<label>جنسیت</label>
|
||||
<Select class="!text-xs !h-full" placeholder="انتخاب جنسیت" v-model="petStore.createForm.gender" optionLabel="label" optionValue="value" :options="petStore.genderOptions" :pt="{ option : '!text-sm' , placeholder : '!text-sm' , label : '!pt-3' }" />
|
||||
<Select placeholder="انتخاب جنسیت" v-model="petStore.createForm.gender" optionLabel="label" optionValue="value" :options="petStore.genderOptions" />
|
||||
<Message v-if="petStore.errorsCreateForm?.gender" severity="error" size="small" variant="simple">{{ petStore.errorsCreateForm?.gender[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="birthday" initialValue="" class="flex flex-col gap-1">
|
||||
<label>تاریخ تولد</label>
|
||||
<CustomDatePicker v-model="petStore.createForm.birthday" class="!text-xs mt-2" type="datetime" compact-time></CustomDatePicker>
|
||||
<CustomDatePicker v-model="petStore.createForm.birthday" type="datetime" compact-time></CustomDatePicker>
|
||||
<Message v-if="petStore.errorsCreateForm?.birthday" severity="error" size="small" variant="simple">{{ petStore.errorsCreateForm?.birthday[0] }}</Message>
|
||||
</FormField>
|
||||
</Form>
|
||||
@@ -105,7 +102,7 @@ onUnmounted(() => {
|
||||
<div class="p-4 grid grid-cols-1 gap-4 rounded-2xl">
|
||||
<div class="grid grid-cols-1 justify-between items-center">
|
||||
<span>زمان انتشار:</span>
|
||||
<CustomDatePicker v-model="petStore.createForm.datetime" class="!text-xs mt-2" type="datetime" compact-time></CustomDatePicker>
|
||||
<CustomDatePicker v-model="petStore.createForm.datetime" class="mt-2" type="datetime" compact-time></CustomDatePicker>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 justify-start">
|
||||
<Button :loading="petStore.loaderCreateForm" @click="petStore.update_and_store" type="button" severity="secondary" :label="petStore.buttonLabel" />
|
||||
@@ -116,29 +113,3 @@ onUnmounted(() => {
|
||||
</section>
|
||||
</master>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.p-multiselect {
|
||||
height: auto;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.p-multiselect-label {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-header {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-filter {
|
||||
max-height: calc(100px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-item {
|
||||
font-size: 0.875rem;
|
||||
line-height: 44px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -74,19 +74,13 @@ const selectAllWithOwn = () => {
|
||||
<Form ref="formRef" v-slot="$form" class="bg-white p-4 rounded-2xl flex flex-col gap-4 !w-full">
|
||||
<FormField v-slot="$field" name="name" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام مقام</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm',
|
||||
roleStore.errorsCreateForm?.name && !roleStore.createForm.name ? 'p-invalid' : ''
|
||||
]" v-model="roleStore.createForm.name" placeholder="نام مقام را وارد کنید" />
|
||||
<InputText type="text" :class="roleStore.errorsCreateForm?.name && !roleStore.createForm.name ? 'p-invalid' : ''" v-model="roleStore.createForm.name" placeholder="نام مقام را وارد کنید" />
|
||||
<Message v-if="roleStore.errorsCreateForm?.name"
|
||||
severity="error" size="small" variant="simple">{{ roleStore.errorsCreateForm?.name[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="label" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام فارسی مقام</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm',
|
||||
roleStore.errorsCreateForm?.label && !roleStore.createForm.label ? 'p-invalid' : ''
|
||||
]" v-model="roleStore.createForm.label" placeholder="نام فارسی مقام را وارد کنید" />
|
||||
<InputText type="text" :class="roleStore.errorsCreateForm?.label && !roleStore.createForm.label ? 'p-invalid' : ''" v-model="roleStore.createForm.label" placeholder="نام فارسی مقام را وارد کنید" />
|
||||
<Message v-if="roleStore.errorsCreateForm?.label" severity="error" size="small" variant="simple">{{ roleStore.errorsCreateForm?.label[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="permissions_parent" initialValue="" class="flex flex-col gap-1">
|
||||
@@ -109,7 +103,7 @@ const selectAllWithOwn = () => {
|
||||
<div class="p-4 bg-white grid grid-cols-1 gap-4 rounded-2xl">
|
||||
<div class="grid grid-cols-1 justify-between items-center">
|
||||
<span>زمان انتشار:</span>
|
||||
<CustomDatePicker v-model="roleStore.createForm.datetime" class="!text-xs mt-2" type="datetime" compact-time></CustomDatePicker>
|
||||
<CustomDatePicker v-model="roleStore.createForm.datetime" class="mt-2" type="datetime" compact-time></CustomDatePicker>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-x-3 mt-1 justify-between items-center">
|
||||
<span class="col-span-2 mb-2">عملیات سریع:</span>
|
||||
|
||||
@@ -98,34 +98,25 @@ const uploadProfile = () => {
|
||||
<Form @submit="onFormSubmit" class="grid grid-cols-1 gap-4 w-full !border-0 !text-sm">
|
||||
<FormField v-slot="$field" name="name" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام کاربری</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm !text-sm',
|
||||
errors?.name && !errors.name ? 'p-invalid' : ''
|
||||
]" v-model="user_form.name" placeholder="نام کاربری را وارد کنید" />
|
||||
<InputText type="text" :class="errors?.name && !errors.name ? 'p-invalid' : ''" v-model="user_form.name" placeholder="نام کاربری را وارد کنید" />
|
||||
<Message v-if="errors?.name"
|
||||
severity="error" size="small" variant="simple">{{ errors?.name[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="first_name" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام کوچک</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm !text-sm',
|
||||
errors?.first_name && !errors.first_name ? 'p-invalid' : ''
|
||||
]" v-model="user_form.first_name" placeholder="نام کوچک خود را وارد کنید" />
|
||||
<InputText type="text" :class="errors?.first_name && !errors.first_name ? 'p-invalid' : ''" v-model="user_form.first_name" placeholder="نام کوچک خود را وارد کنید" />
|
||||
<Message v-if="errors?.first_name"
|
||||
severity="error" size="small" variant="simple">{{ errors?.first_name[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="last_name" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام خانوادگی</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm !text-sm',
|
||||
errors?.last_name && !errors.last_name ? 'p-invalid' : ''
|
||||
]" v-model="user_form.last_name" placeholder="نام کوچک خود را وارد کنید" />
|
||||
<InputText type="text" :class="errors?.last_name && !errors.last_name ? 'p-invalid' : ''" v-model="user_form.last_name" placeholder="نام کوچک خود را وارد کنید" />
|
||||
<Message v-if="errors?.last_name"
|
||||
severity="error" size="small" variant="simple">{{ errors?.last_name[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" asChild name="email" :initialValue="globalStore.current_user.email">
|
||||
<section class="flex flex-col gap-2">
|
||||
<InputText type="email" class="flex pt-2 !text-sm !font-light" disabled id="email" fluid />
|
||||
<InputText type="email" class="!font-light" disabled id="email" fluid />
|
||||
</section>
|
||||
</FormField>
|
||||
<Button type="submit" :loading="loading" severity="secondary" label="ذخیره اطلاعات" />
|
||||
|
||||
@@ -60,7 +60,7 @@ const ChangePasswordHandler = () => {
|
||||
<Password id="password" type="password" :feedback="false"
|
||||
appendTo="self" toggleMask
|
||||
v-model="ChangePasswordForm.password"
|
||||
class="placeholder:!font-light !text-sm !bg-white h-12 !border-gray-500/20 !text-client-Fontcolor"/>
|
||||
class="placeholder:!font-light !bg-white !border-gray-500/20 !text-client-Fontcolor"/>
|
||||
<label for="on_label" class="!text-client-Fontcolor !bg-white !text-sm font-light">کلمه عبور فعلی</label>
|
||||
</FloatLabel>
|
||||
<Message
|
||||
@@ -74,7 +74,7 @@ const ChangePasswordHandler = () => {
|
||||
<Password id="password" type="password" :feedback="false"
|
||||
appendTo="self" toggleMask
|
||||
v-model="ChangePasswordForm.newPassword"
|
||||
class="placeholder:!font-light !text-sm !bg-white h-12 !border-gray-500/20 !text-client-Fontcolor"/>
|
||||
class="placeholder:!font-light !bg-white !border-gray-500/20 !text-client-Fontcolor"/>
|
||||
<label for="on_label" class="!text-client-Fontcolor !bg-white !text-sm font-light"> کلمه عبور جدید</label>
|
||||
</FloatLabel>
|
||||
<Message
|
||||
@@ -88,7 +88,7 @@ const ChangePasswordHandler = () => {
|
||||
<Password id="password" type="password" :feedback="false"
|
||||
appendTo="self" toggleMask
|
||||
v-model="ChangePasswordForm.newPassword_confirmation"
|
||||
class="placeholder:!font-light !text-sm !bg-white h-12 !border-gray-500/20 !text-client-Fontcolor"/>
|
||||
class="placeholder:!font-light !bg-white !border-gray-500/20 !text-client-Fontcolor"/>
|
||||
<label for="on_label" class="!text-client-Fontcolor !bg-white !text-sm font-light">تکرار کلمه عبور جدید</label>
|
||||
</FloatLabel>
|
||||
<Message
|
||||
|
||||
@@ -4,6 +4,8 @@ import {onMounted , onUnmounted} from 'vue';
|
||||
import {useShiftStore} from "../../store/Shift.js";
|
||||
import {Link} from "@inertiajs/inertia-vue3";
|
||||
import Card from "../../components/ui/Card.vue";
|
||||
import ShiftCalendar from "../../components/shifts/ShiftCalendar.vue";
|
||||
import { weekdayName } from "../../../Shared/shiftCalendarEvents";
|
||||
|
||||
const shiftStore = useShiftStore();
|
||||
|
||||
@@ -18,8 +20,22 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const pad = (value) => String(value).padStart(2, '0');
|
||||
|
||||
const onRangeSelect = ({ start, end }) => {
|
||||
shiftStore.createForm.start_time = `${pad(start.getHours())}:${pad(start.getMinutes())}`;
|
||||
shiftStore.createForm.end_time = `${pad(end.getHours())}:${pad(end.getMinutes())}`;
|
||||
|
||||
if (shiftStore.createForm.schedule_type === 'date') {
|
||||
shiftStore.createForm.date = `${start.getFullYear()}-${pad(start.getMonth() + 1)}-${pad(start.getDate())}`;
|
||||
} else {
|
||||
shiftStore.createForm.day_of_week = weekdayName(start.getDay());
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
shiftStore.fetchDoctorOptions();
|
||||
shiftStore.fetchCalendarData();
|
||||
if (props.is_edit) {
|
||||
shiftStore.setEditData(props.shift);
|
||||
}
|
||||
@@ -52,36 +68,36 @@ onUnmounted(() => {
|
||||
<Form ref="formRef" v-slot="$form" class=" p-4 grid grid-cols-2 gap-4 !w-full">
|
||||
<FormField v-slot="$field" name="user_id" initialValue="" class="flex flex-col gap-1">
|
||||
<label>پزشک</label>
|
||||
<Select class="!text-xs !h-full" placeholder="انتخاب پزشک (خالی = شیفت آزاد)" v-model="shiftStore.createForm.user_id" :options="shiftStore.doctorOptions" optionValue="value" optionLabel="label" showClear :pt="{ option : '!text-sm' , placeholder : '!text-sm' , label : '!pt-3' }" />
|
||||
<Select placeholder="انتخاب پزشک (خالی = شیفت آزاد)" v-model="shiftStore.createForm.user_id" :options="shiftStore.doctorOptions" optionValue="value" optionLabel="label" showClear />
|
||||
<Message v-if="shiftStore.errorsCreateForm?.user_id" severity="error" size="small" variant="simple">{{ shiftStore.errorsCreateForm?.user_id[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="schedule_type" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نوع زمانبندی</label>
|
||||
<Select class="!text-xs !h-full" placeholder="انتخاب نوع زمانبندی" v-model="shiftStore.createForm.schedule_type" :options="shiftStore.scheduleTypeOptions" optionValue="value" optionLabel="label" :pt="{ option : '!text-sm' , placeholder : '!text-sm' , label : '!pt-3' }" />
|
||||
<Select placeholder="انتخاب نوع زمانبندی" v-model="shiftStore.createForm.schedule_type" :options="shiftStore.scheduleTypeOptions" optionValue="value" optionLabel="label" />
|
||||
</FormField>
|
||||
<FormField v-if="shiftStore.createForm.schedule_type === 'weekly'" v-slot="$field" name="day_of_week" initialValue="" class="flex flex-col gap-1">
|
||||
<label>روز هفته</label>
|
||||
<Select class="!text-xs !h-full" placeholder="انتخاب روز هفته" v-model="shiftStore.createForm.day_of_week" :options="shiftStore.dayOptions" optionValue="value" optionLabel="label" :pt="{ option : '!text-sm' , placeholder : '!text-sm' , label : '!pt-3' }" />
|
||||
<Select placeholder="انتخاب روز هفته" v-model="shiftStore.createForm.day_of_week" :options="shiftStore.dayOptions" optionValue="value" optionLabel="label" />
|
||||
<Message v-if="shiftStore.errorsCreateForm?.day_of_week" severity="error" size="small" variant="simple">{{ shiftStore.errorsCreateForm?.day_of_week[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-else v-slot="$field" name="date" initialValue="" class="flex flex-col gap-1">
|
||||
<label>تاریخ</label>
|
||||
<CustomDatePicker v-model="shiftStore.createForm.date" class="!text-xs mt-2" type="date" format="YYYY-MM-DD" placeholder="تاریخ شیفت را انتخاب کنید"></CustomDatePicker>
|
||||
<CustomDatePicker v-model="shiftStore.createForm.date" type="date" format="YYYY-MM-DD" placeholder="تاریخ شیفت را انتخاب کنید"></CustomDatePicker>
|
||||
<Message v-if="shiftStore.errorsCreateForm?.date" severity="error" size="small" variant="simple">{{ shiftStore.errorsCreateForm?.date[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="start_time" initialValue="" class="flex flex-col gap-1">
|
||||
<label>ساعت شروع</label>
|
||||
<CustomDatePicker v-model="shiftStore.createForm.start_time" class="!text-xs mt-2" type="time" format="HH:mm" display-format="HH:mm" placeholder="ساعت شروع را انتخاب کنید"></CustomDatePicker>
|
||||
<CustomDatePicker v-model="shiftStore.createForm.start_time" type="time" format="HH:mm" display-format="HH:mm" placeholder="ساعت شروع را انتخاب کنید"></CustomDatePicker>
|
||||
<Message v-if="shiftStore.errorsCreateForm?.start_time" severity="error" size="small" variant="simple">{{ shiftStore.errorsCreateForm?.start_time[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="end_time" initialValue="" class="flex flex-col gap-1">
|
||||
<label>ساعت پایان</label>
|
||||
<CustomDatePicker v-model="shiftStore.createForm.end_time" class="!text-xs mt-2" type="time" format="HH:mm" display-format="HH:mm" placeholder="ساعت پایان را انتخاب کنید"></CustomDatePicker>
|
||||
<CustomDatePicker v-model="shiftStore.createForm.end_time" type="time" format="HH:mm" display-format="HH:mm" placeholder="ساعت پایان را انتخاب کنید"></CustomDatePicker>
|
||||
<Message v-if="shiftStore.errorsCreateForm?.end_time" severity="error" size="small" variant="simple">{{ shiftStore.errorsCreateForm?.end_time[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="is_active" initialValue="" class="flex flex-col gap-1">
|
||||
<label>وضعیت</label>
|
||||
<Select class="!text-xs !h-full" placeholder="انتخاب وضعیت" v-model="shiftStore.createForm.is_active" :options="shiftStore.statusOptions" optionValue="value" optionLabel="label" :pt="{ option : '!text-sm' , placeholder : '!text-sm' , label : '!pt-3' }" />
|
||||
<Select placeholder="انتخاب وضعیت" v-model="shiftStore.createForm.is_active" :options="shiftStore.statusOptions" optionValue="value" optionLabel="label" />
|
||||
<Message v-if="shiftStore.errorsCreateForm?.is_active" severity="error" size="small" variant="simple">{{ shiftStore.errorsCreateForm?.is_active[0] }}</Message>
|
||||
</FormField>
|
||||
</Form>
|
||||
@@ -97,5 +113,18 @@ onUnmounted(() => {
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
<Card class="mt-4">
|
||||
<div class="p-4 rounded-2xl">
|
||||
<div class="flex items-center justify-between pb-2">
|
||||
<h5 class="font-bold text-client-Fontcolor">برنامه فعلی شیفتها</h5>
|
||||
<span class="text-xs text-client-Fontcolor/60">برای تنظیم سریع زمان شیفت، بازه مورد نظر را روی تقویم بکشید</span>
|
||||
</div>
|
||||
<ShiftCalendar
|
||||
:shifts="shiftStore.calendarShifts"
|
||||
selectable
|
||||
@select-range="onRangeSelect"
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</master>
|
||||
</template>
|
||||
|
||||
@@ -58,41 +58,32 @@ onUnmounted(() => {
|
||||
<Form ref="formRef" v-slot="$form" class=" p-4 flex flex-col gap-4 !w-full">
|
||||
<FormField v-slot="$field" name="username" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام کاربری</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm',
|
||||
userStore.errorsCreateForm?.username && !userStore.createForm.username ? 'p-invalid' : ''
|
||||
]" v-model="userStore.createForm.username" placeholder="نام کاربری خود را وارد کنید" />
|
||||
<InputText type="text" :class="userStore.errorsCreateForm?.username && !userStore.createForm.username ? 'p-invalid' : ''" v-model="userStore.createForm.username" placeholder="نام کاربری خود را وارد کنید" />
|
||||
<Message v-if="userStore.errorsCreateForm?.username"
|
||||
severity="error" size="small" variant="simple">{{ userStore.errorsCreateForm?.username[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="email" initialValue="" class="flex flex-col gap-1">
|
||||
<label>ایمیل کاربری</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm',
|
||||
userStore.errorsCreateForm?.email && !userStore.createForm.email ? 'p-invalid' : ''
|
||||
]" v-model="userStore.createForm.email" placeholder="ایمیل خود را وارد کنید" />
|
||||
<InputText type="text" :class="userStore.errorsCreateForm?.email && !userStore.createForm.email ? 'p-invalid' : ''" v-model="userStore.createForm.email" placeholder="ایمیل خود را وارد کنید" />
|
||||
<Message v-if="userStore.errorsCreateForm?.email" severity="error" size="small" variant="simple">{{ userStore.errorsCreateForm?.email[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="national_code" initialValue="" class="flex flex-col gap-1">
|
||||
<label>کد ملی</label>
|
||||
<InputText type="text" :class="[
|
||||
'placeholder:!text-sm',
|
||||
userStore.errorsCreateForm?.national_code && !userStore.createForm.national_code ? 'p-invalid' : ''
|
||||
]" v-model="userStore.createForm.national_code" placeholder="کد ملی خود را وارد کنید" />
|
||||
<InputText type="text" :class="userStore.errorsCreateForm?.national_code && !userStore.createForm.national_code ? 'p-invalid' : ''" v-model="userStore.createForm.national_code" placeholder="کد ملی خود را وارد کنید" />
|
||||
<Message v-if="userStore.errorsCreateForm?.national_code" severity="error" size="small" variant="simple">{{ userStore.errorsCreateForm?.national_code[0] }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="phone" initialValue="" class="flex flex-col gap-1">
|
||||
<label>شماره تماس</label>
|
||||
<InputText type="text" class="placeholder:!text-sm" v-model="userStore.createForm.phone" placeholder="شماره تماس خود را وارد کنید" />
|
||||
<InputText type="text" v-model="userStore.createForm.phone" placeholder="شماره تماس خود را وارد کنید" />
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="fullname" initialValue="" class="flex flex-col gap-1">
|
||||
<label>نام خانوادگی</label>
|
||||
<InputText type="text" class="placeholder:!text-sm" v-model="userStore.createForm.fullname" placeholder="نام خانوادگی خود را وارد کنید" />
|
||||
<InputText type="text" v-model="userStore.createForm.fullname" placeholder="نام خانوادگی خود را وارد کنید" />
|
||||
<Message v-if="$field?.invalid" severity="error" size="small" variant="simple">{{ $field.error?.message }}</Message>
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="password" initialValue="" class="flex flex-col gap-1">
|
||||
<label>کلمه عبور</label>
|
||||
<Password type="text" :inputClass="['placeholder:!text-sm' , { 'p-invalid' : userStore.errorsCreateForm?.password && !userStore.createForm.password}]"
|
||||
<Password type="text" :inputClass="{ 'p-invalid' : userStore.errorsCreateForm?.password && !userStore.createForm.password}"
|
||||
v-model="userStore.createForm.password" placeholder="کلمه عبور خود را وارد کنید" :feedback="false" toggleMask fluid />
|
||||
<Message v-if="userStore.errorsCreateForm?.password"
|
||||
severity="error" size="small" variant="simple">{{ userStore.errorsCreateForm?.password[0] }}</Message>
|
||||
@@ -100,7 +91,7 @@ onUnmounted(() => {
|
||||
</FormField>
|
||||
<FormField v-slot="$field" name="password_confirmation" initialValue="" class="flex flex-col gap-1">
|
||||
<label>تکرار کلمه عبور</label>
|
||||
<Password type="text" inputClass="placeholder:!text-sm" v-model="userStore.createForm.password_confirmation" placeholder="تکرار کلمه عبور خود را وارد کنید" :feedback="false" toggleMask fluid />
|
||||
<Password type="text" v-model="userStore.createForm.password_confirmation" placeholder="تکرار کلمه عبور خود را وارد کنید" :feedback="false" toggleMask fluid />
|
||||
<Message v-if="$field?.invalid" severity="error" size="small" variant="simple">{{ $field.error?.message }}</Message>
|
||||
</FormField>
|
||||
</Form>
|
||||
@@ -117,7 +108,7 @@ onUnmounted(() => {
|
||||
<div class="mt-4 p-4 grid grid-cols-1 gap-4 rounded-2xl">
|
||||
<div class="grid grid-cols-1 justify-between items-center">
|
||||
<span>زمان انتشار:</span>
|
||||
<CustomDatePicker v-model="userStore.createForm.datetime" class="!text-xs mt-2" type="datetime" compact-time></CustomDatePicker>
|
||||
<CustomDatePicker v-model="userStore.createForm.datetime" class="mt-2" type="datetime" compact-time></CustomDatePicker>
|
||||
</div>
|
||||
<div class="grid grid-cols-2a justify-between items-center">
|
||||
<span class="flex">سطح:</span>
|
||||
@@ -125,9 +116,7 @@ onUnmounted(() => {
|
||||
</div>
|
||||
<div class="grid grid-cols-2a justify-between items-center">
|
||||
<span class="flex">مقام:</span>
|
||||
<MultiSelect class="!text-xs"
|
||||
v-model="userStore.createForm.role"
|
||||
:pt="{ option : '!text-sm' }"
|
||||
<MultiSelect v-model="userStore.createForm.role"
|
||||
placeholder="انتخاب مقام"
|
||||
optionLabel="label"
|
||||
optionValue="id"
|
||||
@@ -142,29 +131,3 @@ onUnmounted(() => {
|
||||
</section>
|
||||
</master>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.p-multiselect {
|
||||
height: auto;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.p-multiselect-label {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-header {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-filter {
|
||||
max-height: calc(100px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.p-multiselect .p-multiselect-item {
|
||||
font-size: 0.875rem;
|
||||
line-height: 44px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
<script setup>
|
||||
import Master from "../../layouts/master.vue";
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import TableGeneric from "../../components/TableGeneric.vue";
|
||||
import { useConfirm } from 'primevue/useconfirm';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import { useWithdrawRequestStore } from "../../store/WithdrawRequest.js";
|
||||
import UIModal from "../../components/ui/UIModal.vue";
|
||||
|
||||
const withdrawRequestStore = useWithdrawRequestStore();
|
||||
const toast = useToast();
|
||||
|
||||
const props = defineProps({
|
||||
withdrawRequests: {
|
||||
type: Object,
|
||||
},
|
||||
stats: {
|
||||
type: Object,
|
||||
},
|
||||
search: {
|
||||
type: String
|
||||
},
|
||||
status: {
|
||||
type: String
|
||||
},
|
||||
})
|
||||
|
||||
const withdrawRequests = ref(props.withdrawRequests ?? []);
|
||||
const searchLoader = ref(false);
|
||||
const actionLoader = ref(false);
|
||||
|
||||
const columns = ref(withdrawRequestStore.columns)
|
||||
|
||||
const statusOptions = [
|
||||
'همه وضعیت ها',
|
||||
'در انتظار بررسی',
|
||||
'تایید شده',
|
||||
'رد شده',
|
||||
];
|
||||
|
||||
const queryParams = reactive({
|
||||
search: props.search ?? '',
|
||||
status: props.status ?? 'همه وضعیت ها',
|
||||
})
|
||||
|
||||
const confirm = useConfirm();
|
||||
|
||||
watch(() => props.withdrawRequests, (newRequests) => {
|
||||
if (newRequests) {
|
||||
withdrawRequests.value = newRequests;
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
|
||||
const onPageChange = (event) => {
|
||||
withdrawRequestStore.navigateToPage(event.page + 1);
|
||||
};
|
||||
|
||||
const searchData = () => {
|
||||
searchLoader.value = true;
|
||||
withdrawRequestStore.search(queryParams).then(() => {
|
||||
searchLoader.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
const onSearchChange = (value) => {
|
||||
queryParams.search = value;
|
||||
searchData();
|
||||
};
|
||||
|
||||
const formatCardNumber = (cardNumber) => cardNumber.replace(/(\d{4})(?=\d)/g, '$1-');
|
||||
|
||||
const showApproveConfirm = (data) => {
|
||||
confirm.require({
|
||||
group: 'deleteTemplate',
|
||||
header: 'تایید درخواست برداشت',
|
||||
message: `مبلغ ${Number(data.amount).toLocaleString('fa-IR')} تومان از کیف پول «${data.user?.fullname}» کسر و به ولت سایت منتقل میشود.`,
|
||||
icon: 'fi fi-rr-info',
|
||||
rejectProps: {
|
||||
label: 'انصراف',
|
||||
icon: 'fi fi-rr-ban',
|
||||
outlined: true,
|
||||
size: 'small',
|
||||
class: '!text-xs !flex pt-1 !item-center',
|
||||
iconClass: '!flex !text-xs',
|
||||
},
|
||||
acceptProps: {
|
||||
label: 'تایید برداشت',
|
||||
icon: 'fi fi-rr-check',
|
||||
size: 'small',
|
||||
class: '!text-xs !flex pt-1 !item-center',
|
||||
iconClass: '!flex !text-xs',
|
||||
},
|
||||
accept: () => {
|
||||
actionLoader.value = true;
|
||||
withdrawRequestStore.approve(data.id)
|
||||
.catch((error) => {
|
||||
toast.add({ severity: 'error', summary: 'خطا', detail: error.response?.data?.message || 'خطا در تایید درخواست', life: 4000 });
|
||||
})
|
||||
.finally(() => {
|
||||
actionLoader.value = false;
|
||||
});
|
||||
},
|
||||
reject: () => {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const rejectModalVisible = ref(false);
|
||||
const rejectingRequest = ref(null);
|
||||
const rejectNote = ref('');
|
||||
|
||||
const openRejectModal = (data) => {
|
||||
rejectingRequest.value = data;
|
||||
rejectNote.value = '';
|
||||
rejectModalVisible.value = true;
|
||||
}
|
||||
|
||||
const submitReject = () => {
|
||||
actionLoader.value = true;
|
||||
withdrawRequestStore.reject(rejectingRequest.value.id, rejectNote.value)
|
||||
.then(() => {
|
||||
rejectModalVisible.value = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.add({ severity: 'error', summary: 'خطا', detail: error.response?.data?.message || 'خطا در رد درخواست', life: 4000 });
|
||||
})
|
||||
.finally(() => {
|
||||
actionLoader.value = false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<master>
|
||||
<div class="mb-4 grid grid-cols-2a justify-between items-center bg-white border-[1px] border-client-gray/20 py-4 px-4 rounded-2xl">
|
||||
<h2 class="font-bold text-client-Fontcolor">{{ withdrawRequestStore.indexPageTitle }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 grid grid-cols-3 max-lg:grid-cols-1 gap-4">
|
||||
<div class="bg-white border-[1px] border-client-gray/20 rounded-2xl p-4 flex flex-col gap-2">
|
||||
<span class="text-xs text-gray-500">درخواستهای در انتظار بررسی</span>
|
||||
<strong class="text-lg text-client-Fontcolor">{{ Number(stats.pending_count).toLocaleString('fa-IR') }} درخواست</strong>
|
||||
</div>
|
||||
<div class="bg-white border-[1px] border-client-gray/20 rounded-2xl p-4 flex flex-col gap-2">
|
||||
<span class="text-xs text-gray-500">مجموع مبلغ در انتظار برداشت</span>
|
||||
<strong class="text-lg text-client-Fontcolor">{{ Number(stats.pending_amount).toLocaleString('fa-IR') }} تومان</strong>
|
||||
</div>
|
||||
<div class="bg-white border-[1px] border-client-gray/20 rounded-2xl p-4 flex flex-col gap-2">
|
||||
<span class="text-xs text-gray-500">موجودی ولت سایت</span>
|
||||
<strong class="text-lg text-client-Fontcolor">{{ Number(stats.system_wallet_balance).toLocaleString('fa-IR') }} تومان</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-[1px] border-client-gray/20 bg-white rounded-2xl">
|
||||
<TableGeneric
|
||||
:data="withdrawRequests.data"
|
||||
:columns="columns"
|
||||
:selectable="false"
|
||||
:pagination="withdrawRequests.meta"
|
||||
:searchable="true"
|
||||
:searchValue="queryParams.search"
|
||||
:model-value="[]"
|
||||
@page-change="onPageChange"
|
||||
@search-change="onSearchChange"
|
||||
>
|
||||
<template #toolbar-actions>
|
||||
<div class="grid grid-cols-a gap-4 justify-start">
|
||||
<Dropdown
|
||||
v-model="queryParams.status"
|
||||
:options="statusOptions"
|
||||
placeholder="انتخاب وضعیت..."
|
||||
class="!text-xs"
|
||||
@change="searchData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #column-user="{ data }">
|
||||
<div class="flex flex-col gap-1">
|
||||
<span class="text-sm">{{ data.user?.fullname }}</span>
|
||||
<span class="text-xs text-gray-500">{{ data.user?.level }} - {{ data.user?.phone }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #column-bank_card="{ data }">
|
||||
<div v-if="data.bank_card" class="flex flex-col gap-1">
|
||||
<pre dir="ltr" class="text-right text-xs">{{ formatCardNumber(data.bank_card.card_number) }}</pre>
|
||||
<span class="text-xs text-gray-500">{{ data.bank_card.holder_name }}</span>
|
||||
</div>
|
||||
<span v-else class="text-xs text-gray-500">حذف شده</span>
|
||||
</template>
|
||||
|
||||
<template #column-status="{ data }">
|
||||
<div class="flex flex-col gap-1 items-start">
|
||||
<Tag
|
||||
class="!text-xs"
|
||||
:value="data.status"
|
||||
:severity="withdrawRequestStore.getStatusSeverity(data.status)"
|
||||
/>
|
||||
<span v-if="data.admin_note" class="text-xs text-gray-500">{{ data.admin_note }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #column-actions="{ data }">
|
||||
<div v-if="data.status === 'در انتظار بررسی'" class="grid grid-cols-2a justify-start gap-2">
|
||||
<Button
|
||||
label="تایید"
|
||||
size="small"
|
||||
severity="success"
|
||||
class="!text-xs"
|
||||
:disabled="actionLoader"
|
||||
@click="showApproveConfirm(data)"
|
||||
/>
|
||||
<Button
|
||||
label="رد"
|
||||
size="small"
|
||||
severity="danger"
|
||||
variant="outlined"
|
||||
class="!text-xs"
|
||||
:disabled="actionLoader"
|
||||
@click="openRejectModal(data)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</TableGeneric>
|
||||
</div>
|
||||
|
||||
<UIModal
|
||||
v-model:visible="rejectModalVisible"
|
||||
title="رد درخواست برداشت"
|
||||
size="small"
|
||||
>
|
||||
<div class="flex flex-col gap-3">
|
||||
<p class="text-sm text-gray-600">
|
||||
درخواست برداشت «{{ rejectingRequest ? Number(rejectingRequest.amount).toLocaleString('fa-IR') : '' }} تومان» کاربر «{{ rejectingRequest?.user?.fullname }}» رد میشود.
|
||||
</p>
|
||||
<textarea
|
||||
v-model="rejectNote"
|
||||
rows="4"
|
||||
placeholder="توضیح برای کاربر (اختیاری)"
|
||||
class="w-full border border-gray-200 rounded-xl p-3 text-sm outline-none focus:border-gray-400 resize-y"
|
||||
></textarea>
|
||||
<div class="flex items-center justify-start gap-2">
|
||||
<Button
|
||||
label="رد درخواست"
|
||||
size="small"
|
||||
severity="danger"
|
||||
class="!text-xs"
|
||||
:loading="actionLoader"
|
||||
:disabled="actionLoader"
|
||||
@click="submitReject"
|
||||
/>
|
||||
<Button
|
||||
label="انصراف"
|
||||
size="small"
|
||||
severity="secondary"
|
||||
variant="outlined"
|
||||
class="!text-xs"
|
||||
:disabled="actionLoader"
|
||||
@click="rejectModalVisible = false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</UIModal>
|
||||
</master>
|
||||
</template>
|
||||
Reference in New Issue
Block a user