complete Complete User Request Submission section RAD-1
@@ -0,0 +1,56 @@
|
||||
<script setup>
|
||||
import AuthLayout from '../../layouts/AuthLayout.vue'
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import { Link } from '@inertiajs/inertia-vue3';
|
||||
|
||||
const props = defineProps({
|
||||
phone: String,
|
||||
availableLevels: Array
|
||||
})
|
||||
|
||||
const getLevelLabel = (level) => {
|
||||
return level === 'supervisor' ? 'پورتال کاربران' : level === 'doctor' ? 'پورتال پزشکان' : 'پورتال کاربران'
|
||||
}
|
||||
|
||||
const getLevelRoute = (level) => {
|
||||
return `/auth/login/choose-portal/${level}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthLayout>
|
||||
<main class="p-9 h-auto w-[450px] max-sm:w-[90%] m-auto bg-white rounded-xl">
|
||||
<div class="grid grid-cols-a justify-start">
|
||||
<h1 class="text-[16px] font-semibold !text-dominant-800">
|
||||
{{ $t('auth.ChoosePortal.title') }}
|
||||
</h1>
|
||||
<p class="!text-dominant-800 mt-1 text-[11px] font-normal">
|
||||
{{ $t('auth.ChoosePortal.subtitle').replace('%phone%', phone) }}
|
||||
</p>
|
||||
<Link href="/auth/login/phone" class="!text-dominant-600 text-[11px] font-normal">
|
||||
(تغییر شماره)
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2 mt-6">
|
||||
<Link
|
||||
v-for="level in availableLevels"
|
||||
:key="level"
|
||||
:href="getLevelRoute(level)"
|
||||
class="no-underline"
|
||||
>
|
||||
<UiButton
|
||||
severity="secondary"
|
||||
:label="getLevelLabel(level)"
|
||||
size="large"
|
||||
full-width
|
||||
outlined
|
||||
height="40px"
|
||||
icon-position="start"
|
||||
icon-class="!text-sm mt-1"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</main>
|
||||
</AuthLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,59 @@
|
||||
<script setup>
|
||||
import AuthLayout from '../../layouts/AuthLayout.vue';
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import { Inertia } from '@inertiajs/inertia'
|
||||
import { inject } from 'vue';
|
||||
|
||||
const route = inject('route');
|
||||
|
||||
const props = defineProps({
|
||||
phone: String
|
||||
})
|
||||
|
||||
const handleRegisterSupervisor = () => {
|
||||
Inertia.visit(route('register.supervisor'))
|
||||
}
|
||||
|
||||
const handleRegisterVet = () => {
|
||||
Inertia.visit(route('register.veterinarian'))
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthLayout>
|
||||
<main class="p-9 h-auto w-[450px] max-sm:w-[90%] m-auto bg-white rounded-xl">
|
||||
<div class="grid grid-cols-a justify-start">
|
||||
<h1 class="text-[16px] font-semibold !text-dominant-800">
|
||||
{{ $t('auth.ChooseRegisterType.title') }}
|
||||
</h1>
|
||||
<p class="!text-dominant-800 text-[11px] font-normal">
|
||||
{{ $t('auth.ChooseRegisterType.subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 mt-6">
|
||||
<UiButton
|
||||
severity="secondary"
|
||||
label="ثبتنام به عنوان سرپرست"
|
||||
size="large"
|
||||
full-width
|
||||
outlined
|
||||
height="40px"
|
||||
icon-position="start"
|
||||
icon-class="!text-sm mt-1"
|
||||
@click="handleRegisterSupervisor"
|
||||
/>
|
||||
<UiButton
|
||||
severity="secondary"
|
||||
label="ثبتنام به عنوان دامپزشک"
|
||||
size="large"
|
||||
full-width
|
||||
outlined
|
||||
height="40px"
|
||||
icon-position="start"
|
||||
icon-class="!text-sm mt-1"
|
||||
@click="handleRegisterVet"
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
</AuthLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,15 @@
|
||||
<script setup>
|
||||
import AuthLayout from '../../layouts/AuthLayout.vue'
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthLayout>
|
||||
<div class="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
|
||||
<h1 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
||||
{{ $t('auth.forgot_password.title') }}
|
||||
</h1>
|
||||
</div>
|
||||
</AuthLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,78 @@
|
||||
<script setup>
|
||||
import AuthLayout from '../../layouts/AuthLayout.vue'
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import UiInput from '../../components/ui/UiInput.vue'
|
||||
import { Link } from '@inertiajs/inertia-vue3';
|
||||
import { Inertia } from '@inertiajs/inertia'
|
||||
import { ref } from 'vue';
|
||||
import { inject } from 'vue';
|
||||
import { toast } from 'vue3-toastify';
|
||||
|
||||
const route = inject('route');
|
||||
|
||||
const code = ref('');
|
||||
const isLoading = ref(false);
|
||||
|
||||
const handleVerifyOtp = () => {
|
||||
isLoading.value = true
|
||||
Inertia.post(route('verifyOtp'), {
|
||||
otp_code: code.value
|
||||
}, {
|
||||
onError: (errors) => {
|
||||
toast.error(errors.otp_code || 'خطا در تایید کد تایید', {
|
||||
position: 'top-right',
|
||||
rtl: true,
|
||||
theme: 'colored',
|
||||
autoClose: 3000,
|
||||
})
|
||||
},
|
||||
onFinish: () => {
|
||||
isLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthLayout>
|
||||
<main class="p-9 h-auto w-[450px] max-sm:w-[90%] m-auto bg-white rounded-xl">
|
||||
<div class="grid grid-cols-a justify-start">
|
||||
<h1 class="text-[16px] font-semibold !text-dominant-800">
|
||||
{{ $t('auth.OtpVerification.title').replace('%userType%', 'پزشکان') }}
|
||||
</h1>
|
||||
<p class="!text-dominant-800 mt-1 text-[11px] font-normal">
|
||||
{{ $t('auth.OtpVerification.subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2 mt-6">
|
||||
<UiInput
|
||||
prefix-end="کد تایید موقت"
|
||||
type="text"
|
||||
custom-class="!pl-3"
|
||||
direction="ltr"
|
||||
v-model="code"
|
||||
/>
|
||||
<UiButton
|
||||
severity="dominant"
|
||||
class="!mt-4"
|
||||
:label="isLoading ? 'در حال تایید...' : 'تایید و بازیابی گذرواژه'"
|
||||
size="large"
|
||||
full-width
|
||||
outlined
|
||||
height="40px"
|
||||
icon-position="start"
|
||||
icon-class="!text-sm mt-1"
|
||||
:loading="isLoading"
|
||||
@click="handleVerifyOtp"
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
<template #footer>
|
||||
<Link class="text-center text-[13px] font-normal text-dominant-700 mt-6" :href="route('login')">
|
||||
تغییر شماره موبایل
|
||||
</Link>
|
||||
</template>
|
||||
</AuthLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,89 @@
|
||||
<script setup>
|
||||
import AuthLayout from '../../layouts/AuthLayout.vue'
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import UiInput from '../../components/ui/UiInput.vue'
|
||||
import { Link } from '@inertiajs/inertia-vue3';
|
||||
import { Inertia } from '@inertiajs/inertia';
|
||||
import { ref } from 'vue'
|
||||
import { toast } from 'vue3-toastify';
|
||||
|
||||
const props = defineProps({
|
||||
phone: String,
|
||||
level: String
|
||||
})
|
||||
|
||||
|
||||
const password = ref('');
|
||||
const isLoading = ref(false)
|
||||
|
||||
const handleLogin = () => {
|
||||
if (!password.value) {
|
||||
toast.error('لطفاً گذرواژه را وارد کنید', {
|
||||
position: 'top-right',
|
||||
rtl: true,
|
||||
theme: 'colored',
|
||||
autoClose: 3000,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
isLoading.value = true
|
||||
|
||||
Inertia.post('/auth/login/authenticate', {
|
||||
password: password.value
|
||||
}, {
|
||||
onSuccess: () => {
|
||||
isLoading.value = false
|
||||
},
|
||||
onError: (errors) => {
|
||||
isLoading.value = false
|
||||
toast.error(errors.password || 'خطا در ورود')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthLayout>
|
||||
<main class="p-9 h-auto w-[450px] max-sm:w-[90%] m-auto bg-white rounded-xl">
|
||||
<div class="grid grid-cols-a justify-start">
|
||||
<h1 class="text-[16px] font-semibold !text-dominant-800">
|
||||
{{ $t('auth.Password.title').replace('%userType%', level === 'supervisor' ? 'سرپرست' : level === 'doctor' ? 'پزشک' : 'دانپزشک') }}
|
||||
</h1>
|
||||
<p class="!text-dominant-800 mt-1 text-[11px] font-normal">
|
||||
{{ $t('auth.Password.subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2 mt-6">
|
||||
<UiInput
|
||||
v-model="password"
|
||||
prefix-end="گذرواژه"
|
||||
type="password"
|
||||
password-display-type="asterisks"
|
||||
direction="ltr"
|
||||
/>
|
||||
|
||||
<UiButton
|
||||
severity="dominant"
|
||||
class="!mt-4"
|
||||
:label="isLoading ? 'در حال ورود...' : 'تایید و ورود به حساب'"
|
||||
size="large"
|
||||
full-width
|
||||
outlined
|
||||
height="40px"
|
||||
icon-position="start"
|
||||
icon-class="!text-sm mt-1"
|
||||
:loading="isLoading"
|
||||
@click="handleLogin"
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
<template #footer>
|
||||
<Link method="post" class="text-center text-[13px] font-normal text-dominant-700 mt-6" :href="route('sendOtp')">
|
||||
رمز خود را فراموش کردهاید؟
|
||||
</Link>
|
||||
</template>
|
||||
</AuthLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,124 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import AuthLayout from '../../layouts/AuthLayout.vue';
|
||||
import UiInputWithDropdown from '../../components/ui/UiInputWithDropdown.vue'
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import { countries } from '../../data/countries.js'
|
||||
import { Inertia } from '@inertiajs/inertia'
|
||||
import { inject } from 'vue';
|
||||
import { convertPersianToEnglish } from '../../utils/numberUtils.js'
|
||||
import { toast } from 'vue3-toastify'
|
||||
|
||||
const route = inject('route');
|
||||
|
||||
const selectedCountry = ref(countries[0])
|
||||
const phoneNumber = ref('')
|
||||
const isLoading = ref(false)
|
||||
|
||||
const handlePrefixChange = (country) => {
|
||||
selectedCountry.value = country
|
||||
}
|
||||
|
||||
const validatePhone = (phone) => {
|
||||
const phoneRegex = /^[0-9۰-۹]{10,15}$/
|
||||
return phoneRegex.test(phone.replace(/\s/g, ''))
|
||||
}
|
||||
|
||||
const handleLogin = async () => {
|
||||
if (!phoneNumber.value) {
|
||||
toast.error('لطفاً شماره موبایل را وارد کنید', {
|
||||
position: 'top-right',
|
||||
rtl: true,
|
||||
theme: 'colored',
|
||||
autoClose: 3000,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!validatePhone(phoneNumber.value)) {
|
||||
toast.error('لطفاً شماره موبایل معتبر وارد کنید', {
|
||||
position: 'top-right',
|
||||
rtl: true,
|
||||
theme: 'colored',
|
||||
autoClose: 3000,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
isLoading.value = true
|
||||
|
||||
try {
|
||||
let processedPhone = convertPersianToEnglish(phoneNumber.value)
|
||||
if (processedPhone.startsWith('0')) {
|
||||
processedPhone = processedPhone.substring(1)
|
||||
}
|
||||
|
||||
Inertia.post(route('checkPhone'), {
|
||||
prefix: selectedCountry.value.prefix,
|
||||
phone: processedPhone
|
||||
}, {
|
||||
onSuccess: (page) => {
|
||||
|
||||
},
|
||||
onError: (errors) => {
|
||||
},
|
||||
onFinish: () => {
|
||||
isLoading.value = false
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthLayout>
|
||||
<main class="p-9 h-auto w-[450px] max-sm:w-[90%] m-auto bg-white rounded-xl">
|
||||
<div class="grid grid-cols-a justify-start">
|
||||
<h1 class="text-[16px] font-semibold !text-dominant-800">
|
||||
{{ $t('auth.phone.title') }}
|
||||
</h1>
|
||||
<p class="!text-dominant-800 text-[11px] font-normal">
|
||||
{{ $t('auth.phone.subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="my-6">
|
||||
<UiInputWithDropdown
|
||||
search-placeholder="Search Country Name or Phone Code ..."
|
||||
dropdown-search-input-class="!text-dominant-200 !bg-dominant-50 !border-0 !pt-3 !font-normal !text-sm"
|
||||
type="tel"
|
||||
v-model="phoneNumber"
|
||||
prefix-end="شماره موبایل"
|
||||
dropdown-direction="ltr"
|
||||
:prefix-options="countries"
|
||||
:default-prefix-value="selectedCountry.value"
|
||||
direction="ltr"
|
||||
@prefix-change="handlePrefixChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<UiButton
|
||||
severity="dominant"
|
||||
:label="isLoading ? 'در حال بررسی...' : 'ورود و ثبتنام'"
|
||||
size="large"
|
||||
class="!mt-4"
|
||||
full-width
|
||||
outlined
|
||||
height="40px"
|
||||
icon-position="start"
|
||||
icon-class="!text-sm mt-1"
|
||||
:loading="isLoading"
|
||||
@click="handleLogin"
|
||||
/>
|
||||
</main>
|
||||
<template #footer>
|
||||
<p class="text-center text-[13px] font-normal text-dominant-500 mt-6">
|
||||
Change Language to English
|
||||
</p>
|
||||
</template>
|
||||
</AuthLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,208 @@
|
||||
<script setup>
|
||||
import AuthLayout from '../../layouts/AuthLayout.vue'
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import UiInput from '../../components/ui/UiInput.vue'
|
||||
import UiInputWithDropdown from '../../components/ui/UiInputWithDropdown.vue'
|
||||
import { Link } from '@inertiajs/inertia-vue3';
|
||||
import { inject } from 'vue';
|
||||
import { countries } from '../../data/countries.js'
|
||||
import { ref, onMounted } from 'vue';
|
||||
import UiSelect from '../../components/ui/UiSelect.vue';
|
||||
import provinces from '../../data/provinces.json'
|
||||
import cities from '../../data/cities.json'
|
||||
import { Inertia } from '@inertiajs/inertia';
|
||||
import { toast } from 'vue3-toastify';
|
||||
|
||||
const props = defineProps({
|
||||
phone: String
|
||||
})
|
||||
|
||||
const errors = ref([])
|
||||
const isLoading = ref(false)
|
||||
const route = inject('route');
|
||||
|
||||
const selectedCountry = ref(countries[0])
|
||||
|
||||
const handlePrefixChange = (country) => {
|
||||
selectedCountry.value = country
|
||||
}
|
||||
|
||||
const selectedCity = ref(null)
|
||||
const selectedProvince = ref(null)
|
||||
const citiesList = ref([])
|
||||
const provincesList = ref(provinces);
|
||||
|
||||
const formData = ref({
|
||||
fullName: '',
|
||||
nationalCode: '',
|
||||
phone: props.phone || '',
|
||||
address: '',
|
||||
province: '',
|
||||
city: '',
|
||||
address: '',
|
||||
level: 'سرپرست',
|
||||
})
|
||||
|
||||
const handleProvinceChange = (province) => {
|
||||
if (province) {
|
||||
const provinceId = province.id
|
||||
const filteredCities = cities.filter(city => city.province_id === provinceId)
|
||||
citiesList.value = filteredCities
|
||||
} else {
|
||||
citiesList.value = []
|
||||
}
|
||||
selectedCity.value = null
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
if (props.phone) {
|
||||
if (props.phone.startsWith('+')) {
|
||||
const match = countries.find(c => props.phone.startsWith(c.prefix))
|
||||
if (match) {
|
||||
selectedCountry.value = match
|
||||
formData.value.phone = props.phone.replace(match.prefix, '')
|
||||
} else {
|
||||
formData.value.phone = props.phone
|
||||
}
|
||||
} else {
|
||||
formData.value.phone = props.phone
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!selectedProvince.value) {
|
||||
toast.error('لطفاً استان را انتخاب کنید')
|
||||
return
|
||||
}
|
||||
|
||||
if (!selectedCity.value) {
|
||||
toast.error('لطفاً شهر را انتخاب کنید')
|
||||
return
|
||||
}
|
||||
if (!formData.value.nationalCode) {
|
||||
toast.error('لطفاً کد ملی را وارد کنید')
|
||||
return
|
||||
}
|
||||
isLoading.value = true
|
||||
const fullPhone = selectedCountry.value.prefix + formData.value.phone
|
||||
|
||||
const submitData = {
|
||||
fullName: formData.value.fullName,
|
||||
national_code: formData.value.nationalCode,
|
||||
phone: fullPhone,
|
||||
province: selectedProvince.value.name,
|
||||
city: selectedCity.value.name,
|
||||
address: formData.value.address,
|
||||
level: formData.value.level,
|
||||
}
|
||||
|
||||
Inertia.post(route('register.store'), submitData, {
|
||||
onSuccess: () => {
|
||||
},
|
||||
onError: (errors) => {
|
||||
errors.value = errors
|
||||
isLoading.value = false
|
||||
},
|
||||
onFinish: () => {
|
||||
isLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthLayout>
|
||||
<main class="p-9 h-auto w-[700px] max-sm:w-[90%] m-auto bg-white rounded-xl">
|
||||
<div class="grid grid-cols-a justify-start">
|
||||
<h1 class="text-[16px] font-semibold !text-dominant-800">
|
||||
{{ $t('auth.RegisterSupervisor.title').replace('%userType%', 'سرپرستان') }}
|
||||
</h1>
|
||||
<p class="!text-dominant-800 mt-1 text-[11px] font-normal">
|
||||
{{ $t('auth.RegisterSupervisor.subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-2 content-start items-start mt-6">
|
||||
<UiInput
|
||||
prefix-start="نام و نام خانوادگی"
|
||||
type="text"
|
||||
class="!my-0 max-sm:!col-span-2"
|
||||
v-model="formData.fullName"
|
||||
/>
|
||||
<UiInput
|
||||
prefix-end="کد ملی"
|
||||
type="text"
|
||||
convert-persian-numbers
|
||||
direction="ltr"
|
||||
class="!my-0 max-sm:!col-span-2"
|
||||
custom-class="!font-yekanBakh !text-sm"
|
||||
v-model="formData.nationalCode"
|
||||
:error="errors.national_code"
|
||||
/>
|
||||
<UiInputWithDropdown
|
||||
search-placeholder="Search Country Name or Phone Code ..."
|
||||
dropdown-search-input-class="!text-dominant-200 !bg-dominant-50 !border-0 !pt-3 !font-normal !text-sm"
|
||||
type="tel"
|
||||
class="!my-0 !col-span-2"
|
||||
prefix-end="شماره موبایل"
|
||||
dropdown-direction="ltr"
|
||||
:prefix-options="countries"
|
||||
:default-prefix-value="selectedCountry.value"
|
||||
direction="ltr"
|
||||
v-model="formData.phone"
|
||||
@prefix-change="handlePrefixChange"
|
||||
/>
|
||||
<UiSelect
|
||||
v-model="selectedProvince"
|
||||
:options="provincesList"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
prefix-start="استان"
|
||||
:filter="true"
|
||||
filter-placeholder="جستجو در استانها..."
|
||||
:show-clear="false"
|
||||
class="!my-0 max-sm:col-span-2"
|
||||
@change="handleProvinceChange"
|
||||
/>
|
||||
<UiSelect
|
||||
v-model="selectedCity"
|
||||
:options="citiesList"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
prefix-start="شهر"
|
||||
:filter="true"
|
||||
class="!my-0 max-sm:col-span-2"
|
||||
filter-placeholder="جستجو در شهرها..."
|
||||
:show-clear="false"
|
||||
/>
|
||||
|
||||
<UiInput
|
||||
prefix-start="آدرس"
|
||||
type="text"
|
||||
class="!my-0 col-span-2"
|
||||
v-model="formData.address"
|
||||
/>
|
||||
<UiButton
|
||||
severity="dominant"
|
||||
:label="isLoading ? 'در حال ثبت...' : 'تایید اطلاعات و ثبتنام'"
|
||||
size="large"
|
||||
full-width
|
||||
outlined
|
||||
class="col-span-2 mt-4 max-sm:!mt-0"
|
||||
height="40px"
|
||||
icon-position="start"
|
||||
icon-class="!text-sm"
|
||||
:loading="isLoading"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
<template #footer>
|
||||
<Link class="text-center text-[13px] font-normal text-dominant-700 mt-6" :href="route('register.chooseType')">
|
||||
بازگشت
|
||||
</Link>
|
||||
</template>
|
||||
</AuthLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,253 @@
|
||||
<script setup>
|
||||
import AuthLayout from '../../layouts/AuthLayout.vue'
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import UiInput from '../../components/ui/UiInput.vue'
|
||||
import { Link } from '@inertiajs/inertia-vue3';
|
||||
import provinces from '../../data/provinces.json'
|
||||
import cities from '../../data/cities.json'
|
||||
import UiInputWithDropdown from '../../components/ui/UiInputWithDropdown.vue';
|
||||
import UiSelect from '../../components/ui/UiSelect.vue';
|
||||
import { inject } from 'vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { countries } from '../../data/countries.js'
|
||||
import { Inertia } from '@inertiajs/inertia';
|
||||
import { toast } from 'vue3-toastify';
|
||||
|
||||
const props = defineProps({
|
||||
phone: String
|
||||
})
|
||||
|
||||
const route = inject('route');
|
||||
|
||||
const selectedCountry = ref(countries[0])
|
||||
const handlePrefixChange = (country) => {
|
||||
selectedCountry.value = country
|
||||
}
|
||||
|
||||
const selectedSpecialty = ref(null)
|
||||
const selectedCity = ref(null)
|
||||
const selectedProvince = ref(null)
|
||||
const citiesList = ref([])
|
||||
const provincesList = ref(provinces)
|
||||
const specialtiesList = ref([
|
||||
{ id: 1, name: 'جراح عمومی' },
|
||||
{ id: 2, name: 'جراح حیوانات' },
|
||||
{ id: 3, name: 'جراح حیوانات و طبیعت' }
|
||||
])
|
||||
|
||||
const formData = ref({
|
||||
fullName: '',
|
||||
nationalCode: '',
|
||||
phone: props.phone || '',
|
||||
clinicName: '',
|
||||
clinicPhone: '',
|
||||
address: '',
|
||||
specialty: '',
|
||||
province: '',
|
||||
city: '',
|
||||
address: '',
|
||||
level: 'دانپزشک',
|
||||
})
|
||||
|
||||
const errors = ref({})
|
||||
const isLoading = ref(false)
|
||||
|
||||
const handleProvinceChange = (province) => {
|
||||
if (province) {
|
||||
const provinceId = province.id
|
||||
const filteredCities = cities.filter(city => city.province_id === provinceId)
|
||||
citiesList.value = filteredCities
|
||||
} else {
|
||||
citiesList.value = []
|
||||
}
|
||||
selectedCity.value = null
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (props.phone) {
|
||||
if (props.phone.startsWith('+')) {
|
||||
const match = countries.find(c => props.phone.startsWith(c.prefix))
|
||||
if (match) {
|
||||
selectedCountry.value = match
|
||||
formData.value.phone = props.phone.replace(match.prefix, '')
|
||||
} else {
|
||||
formData.value.phone = props.phone
|
||||
}
|
||||
} else {
|
||||
formData.value.phone = props.phone
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!selectedSpecialty.value) {
|
||||
toast.error('لطفاً تخصص را انتخاب کنید')
|
||||
return
|
||||
}
|
||||
|
||||
if (!selectedProvince.value) {
|
||||
toast.error('لطفاً استان را انتخاب کنید')
|
||||
return
|
||||
}
|
||||
|
||||
if (!selectedCity.value) {
|
||||
toast.error('لطفاً شهر را انتخاب کنید')
|
||||
return
|
||||
}
|
||||
if (!formData.value.nationalCode) {
|
||||
toast.error('لطفاً کد ملی را وارد کنید')
|
||||
return
|
||||
}
|
||||
|
||||
isLoading.value = true
|
||||
|
||||
const fullPhone = selectedCountry.value.prefix + formData.value.phone
|
||||
|
||||
const submitData = {
|
||||
fullName: formData.value.fullName,
|
||||
national_code: formData.value.nationalCode,
|
||||
specialty: selectedSpecialty.value.name,
|
||||
phone: fullPhone,
|
||||
clinic_name: formData.value.clinicName,
|
||||
clinic_phone: formData.value.clinicPhone,
|
||||
province: selectedProvince.value.name,
|
||||
city: selectedCity.value.name,
|
||||
address: formData.value.address,
|
||||
level: 'دانپزشک'
|
||||
}
|
||||
|
||||
Inertia.post(route('register.store'), submitData, {
|
||||
onSuccess: () => {
|
||||
},
|
||||
onError: (errors) => {
|
||||
errors.value = errors
|
||||
isLoading.value = false
|
||||
},
|
||||
onFinish: () => {
|
||||
isLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthLayout>
|
||||
<main class="p-9 h-auto w-[700px] max-sm:w-[90%] m-auto bg-white rounded-xl">
|
||||
<div class="grid grid-cols-a justify-start">
|
||||
<h1 class="text-[16px] font-semibold !text-dominant-800">
|
||||
{{ $t('auth.RegisterVet.title').replace('%userType%', 'پزشکان') }}
|
||||
</h1>
|
||||
<p class="!text-dominant-800 mt-1 text-[11px] font-normal">
|
||||
{{ $t('auth.RegisterVet.subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-2 content-start items-start mt-6">
|
||||
<UiInput
|
||||
prefix-start="نام و نام خانوادگی"
|
||||
type="text"
|
||||
class="!my-0 max-sm:!col-span-2"
|
||||
v-model="formData.fullName"
|
||||
:error="errors.first_name"
|
||||
/>
|
||||
<UiInput
|
||||
prefix-end="کد ملی"
|
||||
type="text"
|
||||
convert-persian-numbers
|
||||
class="!my-0 max-sm:!col-span-2"
|
||||
direction="ltr"
|
||||
custom-class="!font-yekanBakh !text-sm"
|
||||
v-model="formData.nationalCode"
|
||||
:error="errors.national_code"
|
||||
/>
|
||||
<UiSelect
|
||||
v-model="selectedSpecialty"
|
||||
:options="specialtiesList"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
prefix-start="تخصص"
|
||||
class="!my-0 max-sm:!col-span-2"
|
||||
:filter="true"
|
||||
filter-placeholder="جستجو در تخصصها..."
|
||||
:show-clear="false"
|
||||
/>
|
||||
<UiInputWithDropdown
|
||||
search-placeholder="Search Country Name or Phone Code ..."
|
||||
dropdown-search-input-class="!text-dominant-200 !bg-dominant-50 !border-0 !pt-3 !font-normal !text-sm"
|
||||
type="tel"
|
||||
class="!my-0 max-sm:!col-span-2"
|
||||
prefix-end="شماره موبایل"
|
||||
dropdown-direction="ltr"
|
||||
v-model="formData.phone"
|
||||
:prefix-options="countries"
|
||||
:default-prefix-value="selectedCountry.value"
|
||||
direction="ltr"
|
||||
@prefix-change="handlePrefixChange"
|
||||
/>
|
||||
<UiInput
|
||||
prefix-start="نام کلینیک"
|
||||
class="!mb-0 max-sm:!col-span-2"
|
||||
type="text"
|
||||
custom-class="!font-yekanBakh !text-sm"
|
||||
v-model="formData.clinicName"
|
||||
/>
|
||||
<UiInput
|
||||
prefix-end="تلفن کلینیک"
|
||||
type="text"
|
||||
direction="ltr"
|
||||
class="!mb-0 max-sm:!col-span-2"
|
||||
convert-persian-numbers
|
||||
v-model="formData.clinicPhone"
|
||||
/>
|
||||
<UiSelect
|
||||
v-model="selectedProvince"
|
||||
:options="provincesList"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
prefix-start="استان"
|
||||
:filter="true"
|
||||
filter-placeholder="جستجو در استانها..."
|
||||
:show-clear="false"
|
||||
class="!my-0"
|
||||
@change="handleProvinceChange"
|
||||
/>
|
||||
<UiSelect
|
||||
v-model="selectedCity"
|
||||
:options="citiesList"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
prefix-start="شهر"
|
||||
class="!my-0 "
|
||||
:filter="true"
|
||||
filter-placeholder="جستجو در شهرها..."
|
||||
:show-clear="false"
|
||||
/>
|
||||
|
||||
<UiInput
|
||||
prefix-start="آدرس"
|
||||
type="text"
|
||||
class="col-span-2 !mb-0"
|
||||
v-model="formData.address"
|
||||
/>
|
||||
<UiButton
|
||||
severity="dominant"
|
||||
:label="isLoading ? 'در حال ثبت...' : 'تایید اطلاعات و ثبتنام'"
|
||||
size="large"
|
||||
full-width
|
||||
outlined
|
||||
class="col-span-2 mt-4 max-sm:!mt-0"
|
||||
height="40px"
|
||||
icon-position="start"
|
||||
icon-class="!text-sm"
|
||||
:loading="isLoading"
|
||||
@click="handleSubmit"
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
<template #footer>
|
||||
<Link class="text-center text-[13px] font-normal text-dominant-700 mt-6" :href="route('register.chooseType')">
|
||||
بازگشت
|
||||
</Link>
|
||||
</template>
|
||||
</AuthLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,110 @@
|
||||
<script setup>
|
||||
import AuthLayout from '../../layouts/AuthLayout.vue'
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import UiInput from '../../components/ui/UiInput.vue'
|
||||
import { Link } from '@inertiajs/inertia-vue3';
|
||||
import { ref } from 'vue';
|
||||
import { Inertia } from '@inertiajs/inertia';
|
||||
import { inject } from 'vue';
|
||||
import { toast } from 'vue3-toastify';
|
||||
const route = inject('route');
|
||||
const isLoading = ref(false);
|
||||
const password = ref('');
|
||||
const confirmPassword = ref('');
|
||||
|
||||
const updatePassword = () => {
|
||||
if (!password.value) {
|
||||
toast.error('لطفاً گذرواژه را وارد کنید', {
|
||||
position: 'top-right',
|
||||
rtl: true,
|
||||
theme: 'colored',
|
||||
autoClose: 3000,
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!confirmPassword.value) {
|
||||
toast.error('لطفاً تکرار گذرواژه را وارد کنید', {
|
||||
position: 'top-right',
|
||||
rtl: true,
|
||||
theme: 'colored',
|
||||
autoClose: 3000,
|
||||
})
|
||||
return
|
||||
}
|
||||
if (password.value !== confirmPassword.value) {
|
||||
toast.error('گذرواژه و تکرار گذرواژه مطابقت ندارند', {
|
||||
position: 'top-right',
|
||||
rtl: true,
|
||||
theme: 'colored',
|
||||
autoClose: 3000,
|
||||
})
|
||||
return
|
||||
}
|
||||
isLoading.value = true
|
||||
Inertia.post(route('updatePassword'), { password: password.value, password_confirmation: confirmPassword.value }, {
|
||||
onError: (errors) => {
|
||||
toast.error(errors.password || 'خطا در تغییر گذرواژه', {
|
||||
position: 'top-right',
|
||||
rtl: true,
|
||||
theme: 'colored',
|
||||
autoClose: 3000,
|
||||
})
|
||||
},
|
||||
onFinish: () => {
|
||||
isLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthLayout>
|
||||
<main class="p-9 h-auto w-[450px] max-sm:w-[90%] m-auto bg-white rounded-xl">
|
||||
<div class="grid grid-cols-a justify-start">
|
||||
<h1 class="text-[16px] font-semibold !text-dominant-800">
|
||||
{{ $t('auth.ResetPassword.title').replace('%userType%', 'پزشکان') }}
|
||||
</h1>
|
||||
<p class="!text-dominant-800 mt-1 text-[11px] font-normal">
|
||||
{{ $t('auth.ResetPassword.subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex content-start flex-col mt-6">
|
||||
<UiInput
|
||||
prefix-end="گذرواژه"
|
||||
type="password"
|
||||
password-display-type="asterisks"
|
||||
direction="ltr"
|
||||
class="!mb-2"
|
||||
v-model="password"
|
||||
/>
|
||||
<UiInput
|
||||
prefix-end="تکرار گذرواژه"
|
||||
type="password"
|
||||
password-display-type="asterisks"
|
||||
direction="ltr"
|
||||
v-model="confirmPassword"
|
||||
/>
|
||||
<UiButton
|
||||
severity="dominant"
|
||||
class="!mt-4"
|
||||
label="تایید و بازیابی گذرواژه"
|
||||
size="large"
|
||||
full-width
|
||||
outlined
|
||||
height="40px"
|
||||
icon-position="start"
|
||||
icon-class="!text-sm"
|
||||
:loading="isLoading"
|
||||
@click="updatePassword"
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
<template #footer>
|
||||
<Link :href="route('login')" class="text-center text-[13px] font-normal text-dominant-700 mt-6">
|
||||
بازگشت به صفحه ورود
|
||||
</Link>
|
||||
</template>
|
||||
</AuthLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
import ClientLayout from '../../../layouts/ClientLayout.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientLayout>
|
||||
<h1 class="text-2xl font-bold">
|
||||
Cases
|
||||
</h1>
|
||||
</ClientLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,142 @@
|
||||
<script setup>
|
||||
import ClientLayout from '../../layouts/ClientLayout.vue'
|
||||
import ActivitiesWidget from '../../components/dashboard/ActivitiesWidget.vue'
|
||||
import ActivitiesChart from '../../components/dashboard/ActivitiesChart.vue'
|
||||
import TableGeneric from '../../components/ui/TableGeneric.vue'
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import EyeSvg from '../../components/svg/eye.svg'
|
||||
import UiCard from '../../components/ui/UiCard.vue'
|
||||
import RequestCard from '../../components/dashboard/RequestCard.vue'
|
||||
import { ref } from 'vue'
|
||||
import { Link } from '@inertiajs/inertia-vue3'
|
||||
defineProps({
|
||||
user: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const data = ref([
|
||||
{
|
||||
id: 1,
|
||||
file_number: '1234567890',
|
||||
status: 'مشاهده نشد',
|
||||
request_type: 'CT',
|
||||
requester: 'محراب اسماعیلنیا',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'اتمام فرصت رسیدگی'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
file_number: '1234567891',
|
||||
status: 'مشاهده نشد',
|
||||
request_type: 'CT',
|
||||
requester: 'رضا گلیان',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: '۵۳ دقیقه'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
file_number: '1234567892',
|
||||
status: 'مشاهده نشد',
|
||||
request_type: 'MRI',
|
||||
requester: 'دکتر مریم مهدیپور',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۳۲ ساعت'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
file_number: '1234567893',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'دکتر مریم مهدیپور',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۲۴ ساعت'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
file_number: '1234567894',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'نام شخص و یا پزشک',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۵ ساعت'
|
||||
}
|
||||
])
|
||||
|
||||
const columns = ref([
|
||||
{
|
||||
title: 'شماره پرونده',
|
||||
key: 'file_number'
|
||||
},
|
||||
{
|
||||
title: 'وضعیت',
|
||||
key: 'status'
|
||||
},
|
||||
{
|
||||
title: 'نوع درخواست',
|
||||
key: 'request_type'
|
||||
},
|
||||
{
|
||||
title: 'درخواستکننده',
|
||||
key: 'requester'
|
||||
},
|
||||
{
|
||||
title: 'تاریخ ثبت',
|
||||
key: 'registration_date'
|
||||
},
|
||||
{
|
||||
title: 'فرصت رسیدگی',
|
||||
key: 'processing_deadline'
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
key: 'actions',
|
||||
width: 80,
|
||||
style: 'grid grid-cols-1',
|
||||
slot: true,
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientLayout>
|
||||
<ActivitiesWidget />
|
||||
<UiCard title="ثبت آنی درخواست جدید" variant="default" class="mt-4">
|
||||
<p class="w-full flex items-center justify-start font-[400] text-[11px]">فقط چند قدم ساده برای ثبت درخواست کافیه.</p>
|
||||
<div class="w-full h-[179px] grid grid-cols-5 gap-3 justify-start pt-[10px]">
|
||||
<RequestCard title="CT Scan" icon="ct-scan" severity="primary"/>
|
||||
<RequestCard title="MRI" icon="mri" severity="primary"/>
|
||||
<RequestCard title="سونوگرافی" icon="sonography" severity="primary"/>
|
||||
<RequestCard title="اکوکاردیوگرافی" icon="echo" severity="primary"/>
|
||||
<RequestCard title="رادیولوژی" icon="radiology" severity="primary"/>
|
||||
</div>
|
||||
</UiCard>
|
||||
<UiCard title="آخرین کیسهای در انتظار بررسی" variant="default" class="mt-4">
|
||||
<TableGeneric
|
||||
class="bg-white !rounded-2xl"
|
||||
:data="data"
|
||||
customStyle="!text-[11px] !font-normal"
|
||||
:searchable="false"
|
||||
:columns="columns"
|
||||
:selectable="false"
|
||||
:pagination="null"
|
||||
:model-value="[]"
|
||||
>
|
||||
<template #column-actions="{ data }" class="">
|
||||
<div class="flex items-center justify-end">
|
||||
<Link to="/dashboard/doctor/cases/1"
|
||||
class="text-primary-500 bg-complement-100 flex items-center justify-end p-1.5 rounded-md"
|
||||
>
|
||||
<EyeSvg class="w-4 h-4 text-primary-500" />
|
||||
</Link>
|
||||
</div>
|
||||
</template>
|
||||
</TableGeneric>
|
||||
</UiCard>
|
||||
<UiCard title="خلاصه عملکرد شما" variant="default" class="mt-4">
|
||||
<ActivitiesChart />
|
||||
</UiCard>
|
||||
|
||||
</ClientLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,185 @@
|
||||
<script setup>
|
||||
import ClientLayout from '../../../layouts/ClientLayout.vue'
|
||||
import UiCard from '../../../components/ui/UiCard.vue'
|
||||
import TableGeneric from '../../../components/ui/TableGeneric.vue'
|
||||
import EyeSvg from '../../../components/svg/eye.svg'
|
||||
import { Link } from '@inertiajs/inertia-vue3'
|
||||
import { ref } from 'vue'
|
||||
import { useDocumentStore } from '../../../store/Document'
|
||||
|
||||
const documentStore = useDocumentStore();
|
||||
|
||||
const selectedItems = ref([])
|
||||
|
||||
const data = ref([
|
||||
{
|
||||
id: 1,
|
||||
file_number: '1234567890',
|
||||
status: 'مشاهده نشد',
|
||||
request_type: 'CT',
|
||||
requester: 'محراب اسماعیلنیا',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'اتمام فرصت رسیدگی'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
file_number: '1234567891',
|
||||
status: 'مشاهده نشد',
|
||||
request_type: 'CT',
|
||||
requester: 'رضا گلیان',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: '۵۳ دقیقه'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
file_number: '1234567892',
|
||||
status: 'مشاهده نشد',
|
||||
request_type: 'MRI',
|
||||
requester: 'دکتر مریم مهدیپور',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۳۲ ساعت'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
file_number: '1234567893',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'دکتر مریم مهدیپور',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۲۴ ساعت'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
file_number: '1234567894',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'نام شخص و یا پزشک',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۵ ساعت'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
file_number: '1234567893',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'دکتر مریم مهدیپور',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۲۴ ساعت'
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
file_number: '1234567894',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'نام شخص و یا پزشک',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۵ ساعت'
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
file_number: '1234567893',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'دکتر مریم مهدیپور',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۲۴ ساعت'
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
file_number: '1234567894',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'نام شخص و یا پزشک',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۵ ساعت'
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
file_number: '1234567894',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'نام شخص و یا پزشک',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۵ ساعت'
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
file_number: '1234567893',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'دکتر مریم مهدیپور',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۲۴ ساعت'
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
file_number: '1234567894',
|
||||
status: 'در انتظار ثبت گزارش',
|
||||
request_type: 'MRI',
|
||||
requester: 'نام شخص و یا پزشک',
|
||||
registration_date: '۱۴۰۴/۰۳/۰۲ ۱۴:۱۸',
|
||||
processing_deadline: 'کمتر از ۵ ساعت'
|
||||
}
|
||||
])
|
||||
|
||||
const columns = ref([
|
||||
{
|
||||
title: 'شماره پرونده',
|
||||
key: 'file_number'
|
||||
},
|
||||
{
|
||||
title: 'وضعیت',
|
||||
key: 'status'
|
||||
},
|
||||
{
|
||||
title: 'نوع درخواست',
|
||||
key: 'request_type'
|
||||
},
|
||||
{
|
||||
title: 'درخواستکننده',
|
||||
key: 'requester'
|
||||
},
|
||||
{
|
||||
title: 'تاریخ ثبت',
|
||||
key: 'registration_date'
|
||||
},
|
||||
{
|
||||
title: 'فرصت رسیدگی',
|
||||
key: 'processing_deadline'
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
key: 'actions',
|
||||
width: 80,
|
||||
style: 'grid grid-cols-1',
|
||||
slot: true,
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientLayout>
|
||||
<UiCard title="کیسهای در انتظار بررسی" variant="default" class="">
|
||||
<TableGeneric
|
||||
class="bg-white !rounded-2xl"
|
||||
:data="data"
|
||||
customStyle="!text-[11px] !font-normal"
|
||||
:searchable="false"
|
||||
:columns="columns"
|
||||
:selectable="false"
|
||||
:pagination="null"
|
||||
:model-value="selectedItems"
|
||||
>
|
||||
<template #column-actions="{ data }" class="">
|
||||
<div class="flex items-center justify-end">
|
||||
<Link :href="documentStore.endpoints.show(data.id)"
|
||||
class="text-primary-500 bg-complement-100 flex items-center justify-end p-1.5 rounded-md"
|
||||
>
|
||||
<EyeSvg class="w-4 h-4 text-primary-500" />
|
||||
</Link>
|
||||
</div>
|
||||
</template>
|
||||
</TableGeneric>
|
||||
</UiCard>
|
||||
</ClientLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script setup>
|
||||
import ClientLayout from '../../../layouts/ClientLayout.vue';
|
||||
|
||||
const props = defineProps({
|
||||
document: {
|
||||
type: Object,
|
||||
required: true,
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<ClientLayout>
|
||||
<h1>{{ document.title }}</h1>
|
||||
<p>{{ document.description }}</p>
|
||||
<p>{{ document.created_at }}</p>
|
||||
<p>{{ document.updated_at }}</p>
|
||||
<p>{{ document.status }}</p>
|
||||
<p>{{ document.priority }}</p>
|
||||
<p>{{ document.note }}</p>
|
||||
<p>{{ document.modality }}</p>
|
||||
<p>{{ document.pet_id }}</p>
|
||||
<p>{{ document.requester_id }}</p>
|
||||
</ClientLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
import ClientLayout from '../../../layouts/ClientLayout.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientLayout>
|
||||
<h1 class="text-2xl font-bold">
|
||||
Reports
|
||||
</h1>
|
||||
</ClientLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
import ClientLayout from '../../../layouts/ClientLayout.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientLayout>
|
||||
<h1 class="text-2xl font-bold">
|
||||
Shifts
|
||||
</h1>
|
||||
</ClientLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,39 @@
|
||||
<script setup>
|
||||
import { Link } from '@inertiajs/inertia-vue3'
|
||||
import { usePage } from '@inertiajs/inertia-vue3'
|
||||
|
||||
const {url ,props} = usePage();
|
||||
const user = props.value.auth.User || null;
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="max-w-2xl w-full space-y-8">
|
||||
<h1 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
||||
پروژه رادیکال
|
||||
</h1>
|
||||
|
||||
<div class="bg-white p-6 rounded-lg space-y-6">
|
||||
<p>
|
||||
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی و فرهنگ پیشرو در زبان فارسی ایجاد کرد. در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-center gap-4" v-if="!user">
|
||||
<Link :href="route('login')" class="text-center bg-primary text-white px-4 py-2 rounded-md hover:bg-primary-active transition-all duration-300">
|
||||
ورود
|
||||
</Link>
|
||||
<Link :href="route('login')" class="text-center bg-primary text-white px-4 py-2 rounded-md hover:bg-primary-active transition-all duration-300">
|
||||
ثبت نام
|
||||
</Link>
|
||||
</div>
|
||||
<div class="flex items-center justify-center gap-4" v-if="user">
|
||||
<a :href="route('dashboard.index')" class="text-center bg-primary text-white px-4 py-2 rounded-md hover:bg-primary-active transition-all duration-300">
|
||||
داشبورد
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import Chart from 'primevue/chart';
|
||||
import { convertEnglishToPersian } from '../../utils/numberUtils';
|
||||
|
||||
const chartData = ref({
|
||||
labels: ['۱۴۰۴/۰۱/۰۱', '۱۴۰۴/۰۱/۰۲', '۱۴۰۴/۰۱/۰۳', '۱۴۰۴/۰۱/۰۴', '۱۴۰۴/۰۱/۰۵', '۱۴۰۴/۰۱/۰۶', '۱۴۰۴/۰۱/۰۷'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'فعالیتهای روزانه',
|
||||
backgroundColor: 'rgba(87, 105, 137, 0.2)',
|
||||
borderColor: '#576989',
|
||||
borderWidth: 2,
|
||||
fill: true,
|
||||
tension: 0,
|
||||
data: [65, 59, 80, 81, 56, 55, 40]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const chartOptions = ref({
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
labels: {
|
||||
font: {
|
||||
family: 'yekanBakh, sans-serif',
|
||||
size: 12
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
titleFont: {
|
||||
family: 'yekanBakh, sans-serif'
|
||||
},
|
||||
bodyFont: {
|
||||
family: 'yekanBakh, sans-serif'
|
||||
},
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return `${context.dataset.label}: ${context.parsed.y} مورد`;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
ticks: {
|
||||
font: {
|
||||
family: 'yekanBakh, sans-serif',
|
||||
size: 11
|
||||
}
|
||||
}
|
||||
},
|
||||
y: {
|
||||
position: 'right',
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
maxTicks: 8,
|
||||
font: {
|
||||
family: 'yekanBakh, sans-serif',
|
||||
size: 11
|
||||
},
|
||||
callback: function(value) {
|
||||
return convertEnglishToPersian(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Chart type="line" :data="chartData" :options="chartOptions" class="h-[15rem]" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,18 @@
|
||||
<script setup>
|
||||
import { Link } from '@inertiajs/inertia-vue3'
|
||||
import ActivityCard from './ActivityCard.vue'
|
||||
import { formatPrice } from '../../utils/numberUtils'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="grid grid-cols-4 max-lg:grid-cols-2 max-sm:grid-cols-1 gap-4">
|
||||
<ActivityCard title="کیس در انتظار بررسی"
|
||||
:count="5" link="/dashboard/doctor/cases" label-link="مشاهده و بررسی" />
|
||||
<ActivityCard title="کیس بررسی شده در ماه"
|
||||
:count="999" link="/dashboard/doctor/cases" label-link="مشاهده گزارشات کیسها" />
|
||||
<ActivityCard title="تومان درآمد"
|
||||
:count="formatPrice(50000000)" link="/dashboard/doctor/cases" label-link="مشاهده گزارشات مالی " />
|
||||
<ActivityCard title="ساعت تا شیت بعدی"
|
||||
:count="4" link="/dashboard/doctor/cases" label-link="مشاهده شیفتها" />
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,36 @@
|
||||
<script setup>
|
||||
import { Link } from '@inertiajs/inertia-vue3'
|
||||
import PetBoldSvg from '../../components/svg/petBold.svg'
|
||||
import { convertEnglishToPersian } from '../../utils/numberUtils'
|
||||
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
count: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
labelLink: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
link: {
|
||||
type: String,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-white px-4 h-20 border-[1px] border-complement-50 items-center justify-center rounded-xl grid grid-cols-[auto_1fr] gap-2">
|
||||
<div class="w-14 h-14 bg-danger-100 rounded-md flex items-center justify-center">
|
||||
<PetBoldSvg/>
|
||||
</div>
|
||||
<div class="text-complement-700 text-center grid grid-cols-1 gap-2 text-sm font-normal">
|
||||
<p class="font-semibold text-[11px]"><span class="font-bold text-[13px]">{{ convertEnglishToPersian(count) }}</span> {{ title }}</p>
|
||||
<Link v-if="link" :href="link" class="text-complement-700 bg-complement-50 text-center px-2 py-2 rounded-md text-[11px] font-semibold"> {{ labelLink }} </Link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,48 @@
|
||||
<script setup>
|
||||
import { convertEnglishToPersian } from '../../utils/numberUtils'
|
||||
import UiButton from '../../components/ui/UiButton.vue'
|
||||
import CtScanIcon from '../../components/svg/ctScanIcon.svg'
|
||||
import MriIcon from '../../components/svg/mriIcon.svg'
|
||||
import SonographyIcon from '../../components/svg/sonographyIcon.svg'
|
||||
import ECOIcon from '../../components/svg/ecoIcon.svg'
|
||||
import RadiologyIcon from '../../components/svg/radiologyIcon.svg'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const iconComponent = computed(() => {
|
||||
switch (props.icon) {
|
||||
case 'ct-scan':
|
||||
return CtScanIcon
|
||||
case 'mri':
|
||||
return MriIcon
|
||||
case 'sonography':
|
||||
return SonographyIcon
|
||||
case 'echo':
|
||||
return ECOIcon
|
||||
case 'radiology':
|
||||
return RadiologyIcon
|
||||
default:
|
||||
return null
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full h-[169px] p-[12px] flex flex-col gap-1 items-center justify-center border-[1px] border-[#DEE3EB] rounded-[12px]">
|
||||
<component :is="iconComponent" class="w-[87px] h-[80px]" />
|
||||
<div class="w-full flex flex-col gap-1">
|
||||
<p class="w-full flex items-center justify-center font-[700] text-[14px]">{{ title }}</p>
|
||||
<ui-button label="ثبت درخواست" severity="secondary" size="small" full-width="true"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useGlobalStore } from '../../store/Global';
|
||||
import UiInput from '../ui/UiInput.vue';
|
||||
import ArrowDownSvg from '../svg/arrowDown.svg';
|
||||
import GlobalSvg from '../svg/global.svg';
|
||||
const globalStore = useGlobalStore();
|
||||
|
||||
const toggleSidebar = () => {
|
||||
globalStore.sidebarOpen = !globalStore.sidebarOpen;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header class="grid items-center
|
||||
shadow-client-gray/10 grid-cols-2a pe-4 justify-between !ps-[16rem] max-sm:!ps-4 fixed top-0 left-0 right-0 z-20 w-full h-[4.5rem] bg-white">
|
||||
<div class="grid grid-cols-2a justify-start items-center gap-4">
|
||||
<div class="grid grid-cols-1 max-sm:!grid-cols-2a justify-start items-center">
|
||||
<Button
|
||||
icon="fi-rr-menu-burger"
|
||||
class="!hidden !invisible !px-0 !w-0 !h-0 max-sm:!w-10 max-sm:!h-10 max-sm:!visible max-sm:!block items-center !border-dominant-50"
|
||||
pt:icon="flex !text-dominant-300 justify-center items-center"
|
||||
variant="outlined"
|
||||
size="large"
|
||||
@click="toggleSidebar"
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div class="grid grid-cols-1 h-[4rem] content-center justify-start items-center">
|
||||
<UiInput
|
||||
placeholder="جستجو سریع: نام سرپرست، نام حیوان و یا شماره پرونده"
|
||||
variant="outlined"
|
||||
prefixClasses="!border-dominant-50"
|
||||
class="!w-[30rem] max-lg:!w-[22rem] max-md:!w-[26rem] max-sm:!w-[15rem] max-xs:!w-[14rem]"
|
||||
prefixColor="dominant-700"
|
||||
iconStart="svg:SearchSvg"
|
||||
wrapperBorderClass="!border-dominant-50"
|
||||
customClass="placeholder:!text-dominant-300 !border-dominant-50 !font-normal !text-[11px]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4">
|
||||
<div class="flex items-center justify-center border-l-[1px] !border-dominant-50 pl-4">
|
||||
<GlobalSvg />
|
||||
</div>
|
||||
<div class="grid grid-cols-2a justify-start items-center gap-2">
|
||||
<span class="text-dominant-300 text-[12px] font-normal">
|
||||
{{ globalStore.current_user.fullname }}
|
||||
</span>
|
||||
<ArrowDownSvg class="!w-4 !h-4 flex -mt-0.5"/>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
<script setup lang="ts">
|
||||
import {ref, computed, onMounted, watch} from 'vue';
|
||||
import {Link, usePage, useForm} from '@inertiajs/inertia-vue3';
|
||||
import type { Ref } from 'vue';
|
||||
import type { MenuItem } from 'primevue/menuitem';
|
||||
import {useGlobalStore} from '../../store/Global';
|
||||
import HomeSvg from "../svg/home.svg"
|
||||
import documentTextSvg from "../svg/documentText.svg"
|
||||
import LogoutSvg from "../svg/logout.svg"
|
||||
import CalendarSvg from "../svg/calendar.svg"
|
||||
import StatusUpSvg from "../svg/statusUp.svg"
|
||||
import PetSvg from "../svg/pet.svg"
|
||||
|
||||
interface SidebarItem extends MenuItem {
|
||||
label: string;
|
||||
icon?: any;
|
||||
to?: string;
|
||||
expanded?: boolean;
|
||||
items?: SidebarItem[];
|
||||
permission?: string | null;
|
||||
}
|
||||
|
||||
const globalStore = useGlobalStore();
|
||||
const {url ,props} = usePage();
|
||||
const currentUser = ref(props.value.auth.User);
|
||||
|
||||
const userPermissions = computed(() => props.value.auth.permissions ?? []);
|
||||
|
||||
function hasPermission(permission) {
|
||||
if (!permission) return true;
|
||||
return userPermissions.value.includes(permission);
|
||||
}
|
||||
|
||||
function filterSidebarItems(items) {
|
||||
return items
|
||||
.filter(item => hasPermission(item.permission))
|
||||
.map(item => {
|
||||
if (item.items) {
|
||||
const filteredChildren = filterSidebarItems(item.items);
|
||||
if (filteredChildren.length > 0) {
|
||||
return { ...item, items: filteredChildren };
|
||||
} else if (!item.permission) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return item;
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
const filteredItems = computed(() => filterSidebarItems(items.value));
|
||||
|
||||
// @ts-ignore
|
||||
const items: Ref<SidebarItem[]> = ref([
|
||||
{
|
||||
label: "داشبورد",
|
||||
icon: HomeSvg,
|
||||
to: "/dashboard",
|
||||
key: 'dashboard',
|
||||
expanded: false,
|
||||
permission: null,
|
||||
},
|
||||
{
|
||||
label: "پرونده های باز",
|
||||
icon: documentTextSvg,
|
||||
to: "/dashboard/documents",
|
||||
key: 'documents',
|
||||
permission: null,
|
||||
},
|
||||
{
|
||||
label: "کیس ها",
|
||||
icon: PetSvg,
|
||||
to: "/dashboard/cases",
|
||||
key: 'cases',
|
||||
permission: null,
|
||||
},
|
||||
{
|
||||
label: "گزارشات",
|
||||
icon: StatusUpSvg,
|
||||
to: "/dashboard/reports",
|
||||
key: 'reports',
|
||||
permission: null,
|
||||
},
|
||||
{
|
||||
label: "شیفت ها",
|
||||
icon: CalendarSvg,
|
||||
to: "/dashboard/shifts",
|
||||
key: 'shifts',
|
||||
permission: null,
|
||||
},
|
||||
// {
|
||||
// label: "خروج از سامانه",
|
||||
// icon: LogoutSvg,
|
||||
// to: "/auth/logout",
|
||||
// permission: null,
|
||||
// },
|
||||
]);
|
||||
const toggleSubmenu = (item: SidebarItem) => {
|
||||
// expandedKeys.value = {};
|
||||
// item.expanded = !item.expanded;
|
||||
};
|
||||
|
||||
const closeSidebarOnClick = () => {
|
||||
globalStore.sidebarOpen = false;
|
||||
};
|
||||
|
||||
const expandedKeys = ref<Record<string, boolean>>({});
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
globalStore.current_user = currentUser;
|
||||
const saved = localStorage.getItem('expandedKeys')
|
||||
if (saved) expandedKeys.value = JSON.parse(saved)
|
||||
updateExpandedKeys()
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
if (e.target.closest('.p-panelmenu-content a')) {
|
||||
globalStore.sidebarOpen = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
watch(expandedKeys, v => {
|
||||
localStorage.setItem('expandedKeys', JSON.stringify(v))
|
||||
})
|
||||
watch(() => url.value, () => {
|
||||
updateExpandedKeys()
|
||||
})
|
||||
|
||||
const isActive = (item: SidebarItem): boolean => {
|
||||
return expandedKeys.value[item.key] === true;
|
||||
};
|
||||
|
||||
const loadSvgContent = async (svgName) => {
|
||||
try {
|
||||
const svgModule = await import(`../../components/svg/${svgName}.svg?raw`)
|
||||
return svgModule.default
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const updateExpandedKeys = () => {
|
||||
const newKeys = {}
|
||||
items.value.forEach(item => {
|
||||
if (item.to === url.value || item.items?.some(c => url.value.startsWith(c.to || ''))) {
|
||||
newKeys[item.key] = true
|
||||
}
|
||||
})
|
||||
expandedKeys.value = newKeys
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="globalStore.sidebarOpen"
|
||||
class="fixed inset-0 bg-black/10 backdrop-blur-sm bg-opacity-50 z-10 sm:hidden"
|
||||
@click="globalStore.sidebarOpen = false">
|
||||
</div>
|
||||
<aside class="shadow-client-gray/5 w-[16rem] bg-white
|
||||
py-4 pt-0 pb-8 fixed h-full top-0 z-30 inset-y-0 right-0 sm:inset-auto transition-transform duration-300"
|
||||
:class="[globalStore.sidebarOpen ? 'translate-x-0' : 'translate-x-full sm:translate-x-0']">
|
||||
<figure class="w-[16rem] h-[5rem] flex justify-center">
|
||||
<img class="!w-full h-full object-contain" src="@/images/SidebarPanelLogo.png" alt="">
|
||||
</figure>
|
||||
<section class="">
|
||||
<div class="grid grid-rows-[1fr_auto] h-[calc(100svh-6.5rem)]">
|
||||
<PanelMenu
|
||||
:pt="{
|
||||
header: 'custom-header',
|
||||
headerAction: 'custom-header-action',
|
||||
menuContent: 'custom-menu-content',
|
||||
menuitem: 'custom-menuitem',
|
||||
action: 'custom-action',
|
||||
icon: 'custom-icon',
|
||||
submenuIcon: 'custom-submenu-icon !text-xl',
|
||||
}"
|
||||
v-model:expanded-keys="expandedKeys"
|
||||
:model="filteredItems"
|
||||
class="custom-menu px-4">
|
||||
<template #item="{ item, root, hasSubmenu, toggle }">
|
||||
<div
|
||||
:class="url === item.to ? 'active' : 'text-client-Fontcolor'"
|
||||
class="flex items-center h-10 justify-between pl-2 text-client-Fontcolor rounded-lg cursor-pointer w-full"
|
||||
@click="hasSubmenu ? toggleSubmenu(item) : null">
|
||||
<div class="px-2 flex w-full items-center">
|
||||
<Link v-if="item.to" :href="item.to" class="flex items-center h-10 w-full" @click="globalStore.sidebarOpen = false">
|
||||
<component v-if="typeof item.icon === 'object'" :is="item.icon" class="flex w-7 items-center justify-start"></component>
|
||||
<i v-else-if="item.icon" :class="item.icon" class="flex !text-[1.2rem] -mt-0.5"></i>
|
||||
<div class="flex items-center font-semibold text-sm p-2 text-dominant-300 gap-2 w-full">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
</Link>
|
||||
<div v-else class="flex items-center h-10 w-full">
|
||||
<component v-if="typeof item.icon === 'object'" :is="item.icon" class="flex !text-[1.2rem] -mt-0.5"></component>
|
||||
<i v-else-if="item.icon" :class="item.icon" class="flex !text-[1.2rem] -mt-0.5"></i>
|
||||
<span class="w-full p-2 text-sm text-client-Fontcolor">{{ item.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<i v-if="hasSubmenu"
|
||||
class="fi fi-rr-angle-small-left !text-sm flex transition-transform duration-300"
|
||||
:class="[{ 'rotate-90': item.expanded || isActive }]">
|
||||
</i>
|
||||
</div>
|
||||
</template>
|
||||
</PanelMenu>
|
||||
<Link :href="route('dashboard.logout')" method="get" class="grid grid-cols-2a items-center h-10 justify-start p-4 px-6">
|
||||
<LogoutSvg class="" />
|
||||
<span class="flex items-center font-semibold text-sm p-2 text-dominant-300 gap-2 w-full">
|
||||
خروج از سامانه
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</aside>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<svg width="87" height="80" viewBox="0 0 87 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M24.2907 27.6819C23.4935 27.6819 22.837 27.0283 22.837 26.2264C22.837 25.4245 23.4868 24.7709 24.2907 24.7709C25.0945 24.7709 25.7376 25.4245 25.7376 26.2264C25.7376 27.0283 25.0878 27.6819 24.2907 27.6819ZM24.2907 25.4447C23.8619 25.4447 23.5069 25.7951 23.5069 26.2264C23.5069 26.6577 23.8552 27.0081 24.2907 27.0081C24.7261 27.0081 25.0677 26.6577 25.0677 26.2264C25.0677 25.7951 24.7194 25.4447 24.2907 25.4447Z" fill="#D5203E"/>
|
||||
<path d="M48.2597 10.6469C47.4625 10.6469 46.806 9.99325 46.806 9.19137C46.806 8.38948 47.4558 7.73584 48.2597 7.73584C49.0636 7.73584 49.7067 8.38948 49.7067 9.19137C49.7067 9.99325 49.0569 10.6469 48.2597 10.6469ZM48.2597 8.40296C47.831 8.40296 47.4759 8.75336 47.4759 9.18463C47.4759 9.61589 47.8243 9.9663 48.2597 9.9663C48.6951 9.9663 49.0368 9.61589 49.0368 9.18463C49.0368 8.75336 48.6885 8.40296 48.2597 8.40296Z" fill="#D5203E"/>
|
||||
<path d="M78.0703 40.9569C77.2731 40.9569 76.6166 40.3032 76.6166 39.5013C76.6166 38.6994 77.2664 38.0458 78.0703 38.0458C78.8741 38.0458 79.5172 38.6994 79.5172 39.5013C79.5172 40.3032 78.8674 40.9569 78.0703 40.9569ZM78.0703 38.7129C77.6415 38.7129 77.2865 39.0633 77.2865 39.4946C77.2865 39.9259 77.6348 40.2763 78.0703 40.2763C78.5057 40.2763 78.8473 39.9259 78.8473 39.4946C78.8473 39.0633 78.499 38.7129 78.0703 38.7129Z" fill="#D5203E"/>
|
||||
<path d="M19.6215 56.2129C18.8243 56.2129 18.1678 55.5593 18.1678 54.7574C18.1678 53.9555 18.8176 53.3019 19.6215 53.3019C20.4254 53.3019 21.0685 53.9555 21.0685 54.7574C21.0685 55.5593 20.4187 56.2129 19.6215 56.2129ZM19.6215 53.9757C19.1927 53.9757 18.8377 54.3261 18.8377 54.7574C18.8377 55.1887 19.186 55.5391 19.6215 55.5391C20.0569 55.5391 20.3986 55.1887 20.3986 54.7574C20.3986 54.3261 20.0502 53.9757 19.6215 53.9757Z" fill="#D5203E"/>
|
||||
<path d="M51.9374 77.318C51.1403 77.318 50.4838 76.6644 50.4838 75.8625C50.4838 75.0606 51.1336 74.407 51.9374 74.407C52.7413 74.407 53.3844 75.0606 53.3844 75.8625C53.3844 76.6644 52.7346 77.318 51.9374 77.318ZM51.9374 75.0741C51.5087 75.0741 51.1537 75.4245 51.1537 75.8558C51.1537 76.287 51.502 76.6374 51.9374 76.6374C52.3729 76.6374 52.7145 76.287 52.7145 75.8558C52.7145 75.4245 52.3662 75.0741 51.9374 75.0741Z" fill="#D5203E"/>
|
||||
<path d="M11.6764 30.5121L10.9194 29.8248L11.663 29.1779C11.8372 29.0296 11.8573 28.7601 11.7099 28.5849C11.5558 28.4097 11.2946 28.3895 11.1204 28.5377L10.2964 29.252L9.52604 28.5445C9.35856 28.3895 9.0906 28.403 8.93652 28.5714C8.78245 28.7466 8.79584 29.0094 8.96332 29.1644L9.66002 29.7978L8.84944 30.4986C8.67526 30.6469 8.65517 30.9164 8.80254 31.0916C8.88293 31.186 9.00351 31.2399 9.1174 31.2399C9.21118 31.2399 9.31167 31.2062 9.39206 31.1388L10.283 30.3706L11.1204 31.1321C11.2008 31.2062 11.3013 31.2399 11.4018 31.2399C11.5156 31.2399 11.6295 31.1927 11.7099 31.0984C11.864 30.9232 11.8506 30.6604 11.6831 30.5054L11.6764 30.5121Z" fill="#D5203E"/>
|
||||
<path d="M63.9823 17.2574L63.2253 16.5701L63.9689 15.9232C64.143 15.7749 64.1631 15.5054 64.0158 15.3302C63.8617 15.155 63.6004 15.1348 63.4262 15.283L62.6023 15.9973L61.8319 15.2897C61.6644 15.1348 61.3964 15.1482 61.2424 15.3167C61.0883 15.4919 61.1017 15.7547 61.2692 15.9097L61.9659 16.5431L61.1553 17.2439C60.9811 17.3922 60.961 17.6617 61.1084 17.8369C61.1888 17.9313 61.3094 17.9852 61.4232 17.9852C61.517 17.9852 61.6175 17.9515 61.6979 17.8841L62.5889 17.1159L63.4262 17.8773C63.5066 17.9515 63.6071 17.9852 63.7076 17.9852C63.8215 17.9852 63.9354 17.938 64.0158 17.8437C64.1698 17.6685 64.1564 17.4057 63.989 17.2507L63.9823 17.2574Z" fill="#D5203E"/>
|
||||
<path d="M28.0555 70.6065L27.2985 69.9191L28.0421 69.2722C28.2163 69.124 28.2364 68.8544 28.089 68.6792C27.9349 68.504 27.6737 68.4838 27.4995 68.6321L26.6755 69.3464L25.9051 68.6388C25.7376 68.4838 25.4697 68.4973 25.3156 68.6658C25.1615 68.841 25.1749 69.1038 25.3424 69.2588L26.0391 69.8922L25.2285 70.593C25.0544 70.7412 25.0343 71.0108 25.1816 71.186C25.262 71.2803 25.3826 71.3342 25.4965 71.3342C25.5903 71.3342 25.6908 71.3005 25.7711 71.2331L26.6621 70.465L27.4995 71.2264C27.5799 71.3005 27.6804 71.3342 27.7808 71.3342C27.8947 71.3342 28.0086 71.2871 28.089 71.1927C28.2431 71.0175 28.2297 70.7547 28.0622 70.5997L28.0555 70.6065Z" fill="#D5203E"/>
|
||||
<path d="M69.1137 61.4555L68.3567 60.7682L69.1003 60.1213C69.2745 59.973 69.2945 59.7035 69.1472 59.5283C68.9931 59.3531 68.7318 59.3329 68.5577 59.4811L67.7337 60.1954L66.9633 59.4879C66.7958 59.3329 66.5279 59.3464 66.3738 59.5148C66.2197 59.69 66.2331 59.9528 66.4006 60.1078L67.0973 60.7412L66.2867 61.442C66.1125 61.5903 66.0924 61.8598 66.2398 62.035C66.3202 62.1294 66.4408 62.1833 66.5547 62.1833C66.6484 62.1833 66.7489 62.1496 66.8293 62.0822L67.7203 61.314L68.5577 62.0755C68.638 62.1496 68.7385 62.1833 68.839 62.1833C68.9529 62.1833 69.0668 62.1361 69.1472 62.0418C69.3012 61.8666 69.2878 61.6038 69.1204 61.4488L69.1137 61.4555Z" fill="#D5203E"/>
|
||||
<path d="M43.6374 20.3032C32.3965 20.3032 23.2791 29.5957 23.2791 41.0579C23.2791 48.1941 26.8095 54.4879 32.1888 58.221C32.0883 56.907 32.6912 55.4178 32.986 54.252C33.3075 52.965 33.6291 51.6711 34.0042 50.3976C34.299 49.38 34.7277 48.3895 34.9354 47.3517C35.2301 45.8625 35.3373 43.9218 36.9518 43.2682C37.6887 42.9717 38.7538 42.8773 39.4773 43.248C39.5711 43.2951 39.6515 43.3558 39.7252 43.4097C40.1807 42.4393 40.797 41.5701 41.7617 41.1792C43.5972 40.438 45.8682 41.1792 46.9735 42.7965C46.9802 42.81 46.9869 42.8234 46.9936 42.8369C47.5563 42.9515 48.0453 43.1738 48.521 43.4501C48.6483 43.376 48.8023 43.3221 48.9765 43.3019C49.5258 43.2345 49.9144 43.4434 50.189 43.7668C50.5106 43.7803 50.8254 43.9353 50.9527 44.2318C51.4216 45.3167 51.5556 46.4286 51.6025 47.6078C51.6159 47.9447 51.6293 48.2884 51.6561 48.6253C51.6695 48.686 51.6829 48.7534 51.6963 48.814C51.8705 48.9218 52.0112 49.0903 52.0781 49.3598C52.4667 50.9906 52.3528 52.8167 53.0093 54.38C53.0964 54.5822 53.1165 54.7844 53.0897 54.9663C53.4447 56.3342 53.505 57.7763 53.5452 59.1914C59.782 55.6401 63.9957 48.8544 63.9957 41.0579C63.9957 29.5957 54.8783 20.3032 43.6374 20.3032Z" fill="#D5203E"/>
|
||||
<path d="M35.2168 44.973C35.6589 44.1981 36.3623 43.4164 37.2131 43.1065C38.037 42.8032 38.9883 43.1941 39.7587 42.8302C40.6162 42.4326 41.2459 41.6105 42.11 41.1994C42.9474 40.8019 43.8585 40.6806 44.7561 40.9569C45.2519 41.1118 45.7275 41.3544 46.1428 41.6644C46.4912 41.9272 46.8194 42.2776 47.2415 42.4124C47.7707 42.5876 48.3736 42.4461 48.9296 42.5202C49.345 42.5741 49.7268 42.7224 50.0752 42.9582C51.2006 43.7197 51.5958 45.0943 51.7097 46.4151C52.7682 44.8922 53.3845 43.0593 53.3845 41.0849C53.3845 35.8288 49.01 31.5701 43.6173 31.5701C38.2246 31.5701 33.8502 35.8288 33.8502 41.0849C33.8502 42.6819 34.2588 44.1779 34.9689 45.4986C35.0359 45.3167 35.1163 45.1415 35.2101 44.973H35.2168Z" fill="white"/>
|
||||
<path d="M31.8002 62.5943C30.9763 62.2844 32.1888 59.5485 31.8538 58.8881C31.7734 58.7331 29.5494 57.3046 29.1005 56.88C13.2105 41.9879 27.5196 15.5323 48.742 20.8154C66.1394 25.1415 70.554 49.4811 55.019 58.8747C54.7108 59.407 56.064 61.9609 55.2736 62.5943H31.8002ZM55.287 25.3706C46.2299 18.6658 33.5554 20.6738 27.1578 30C21.0751 38.8679 23.0312 51.8261 32.2625 57.5337C32.3764 54.3194 34.3459 49.5552 34.299 46.5364C34.2454 43.0256 31.9141 41.8935 34.0913 36.9744C39.6984 24.3396 59.2327 33.6995 52.6208 46.3477L54.6238 57.5337C55.0123 57.9784 58.469 54.535 58.7972 54.1442C66.1193 45.4515 64.3105 32.0552 55.287 25.3773V25.3706ZM49.3248 34.3666C42.2708 28.6455 32.6309 35.1887 34.6875 43.8477C35.4311 43.5243 35.5785 42.8706 36.4494 42.5269C37.6485 42.0552 38.6466 42.5809 39.5845 42.3046C40.5224 42.0283 41.2592 40.0135 43.7178 40.0876C45.8548 40.155 46.4979 41.9407 47.496 42.2978C48.8224 42.7695 51.1336 41.7116 52.1987 44.0296C53.2237 40.6267 52.0781 36.597 49.3248 34.3666ZM42.8402 41.4623C39.7788 41.9744 38.2045 48.3221 42.2507 48.8949C44.18 49.1644 46.9802 48.9488 47.1611 46.5364C47.362 43.8612 45.8816 40.9501 42.8402 41.4623ZM38.9682 43.4771C37.7758 43.6927 36.4895 43.3423 35.8933 44.7844L32.852 61.0377L33.1333 61.4353L34.3124 61.469C34.5334 61.2062 34.3928 55.5189 34.4999 54.6294C34.922 51.1725 37.9298 50.6738 40.8372 50.411C41.0717 49.4407 40.0735 49.4879 39.5309 48.8207C38.3586 47.3854 38.8007 45.1954 38.9749 43.4771H38.9682ZM54.061 61.469L51.0331 44.7439C50.3431 43.3895 49.3315 43.6792 48.1056 43.4771C48.2597 45.1954 48.6482 47.0148 47.7238 48.5782C47.2549 49.3733 45.9887 49.4811 46.2366 50.411C53.371 50.3908 52.8083 55.438 52.5873 60.9771L54.061 61.469ZM38.7873 55.1887V61.469H48.2865C48.588 60.3976 47.7238 55.4313 48.4741 54.9933L49.4052 55.1011V61.004L49.7201 61.4757H51.4551C51.3546 56.0108 52.6877 51.4488 45.493 51.442L45.1246 50.0337H42.0631C42.11 52.1968 39.7587 51.5296 38.2246 51.9946C36.5699 52.5 35.9134 53.3356 35.679 55.0539C35.5718 55.8356 35.3373 60.1819 35.4244 60.8086C35.5718 61.9003 36.6436 61.3612 37.481 61.4555C37.9298 60.3302 37.213 55.1482 38.1777 54.9326L38.8007 55.1887H38.7873Z" fill="black"/>
|
||||
<path d="M58.9781 42.8167H56.533C56.2592 42.8167 56.0372 43.0399 56.0372 43.3153V43.3221C56.0372 43.5975 56.2592 43.8207 56.533 43.8207H58.9781C59.2519 43.8207 59.4738 43.5975 59.4738 43.3221V43.3153C59.4738 43.0399 59.2519 42.8167 58.9781 42.8167Z" fill="black"/>
|
||||
<path d="M58.9781 44.252H56.533C56.2592 44.252 56.0372 44.4753 56.0372 44.7507V44.7574C56.0372 45.0328 56.2592 45.2561 56.533 45.2561H58.9781C59.2519 45.2561 59.4738 45.0328 59.4738 44.7574V44.7507C59.4738 44.4753 59.2519 44.252 58.9781 44.252Z" fill="black"/>
|
||||
<path d="M30.4135 42.8167H27.9684C27.6946 42.8167 27.4727 43.0399 27.4727 43.3153V43.3221C27.4727 43.5975 27.6946 43.8207 27.9684 43.8207H30.4135C30.6873 43.8207 30.9092 43.5975 30.9092 43.3221V43.3153C30.9092 43.0399 30.6873 42.8167 30.4135 42.8167Z" fill="black"/>
|
||||
<path d="M30.4135 44.252H27.9684C27.6946 44.252 27.4727 44.4753 27.4727 44.7507V44.7574C27.4727 45.0328 27.6946 45.2561 27.9684 45.2561H30.4135C30.6873 45.2561 30.9092 45.0328 30.9092 44.7574V44.7507C30.9092 44.4753 30.6873 44.252 30.4135 44.252Z" fill="black"/>
|
||||
<path d="M57.7589 39.097C58.2814 39.097 58.7035 39.5216 58.7035 40.0472C58.7035 40.5728 58.2814 40.9973 57.7589 40.9973C57.2364 40.9973 56.8143 40.5728 56.8143 40.0472C56.8143 39.5216 57.2364 39.097 57.7589 39.097ZM57.7589 37.7493C56.4995 37.7493 55.4745 38.7803 55.4745 40.0472C55.4745 41.314 56.4995 42.345 57.7589 42.345C59.0183 42.345 60.0433 41.314 60.0433 40.0472C60.0433 38.7803 59.0183 37.7493 57.7589 37.7493Z" fill="white"/>
|
||||
<path d="M29.1943 39.097C29.7169 39.097 30.1389 39.5216 30.1389 40.0472C30.1389 40.5728 29.7169 40.9973 29.1943 40.9973C28.6718 40.9973 28.2498 40.5728 28.2498 40.0472C28.2498 39.5216 28.6718 39.097 29.1943 39.097ZM29.1943 37.7493C27.9349 37.7493 26.91 38.7803 26.91 40.0472C26.91 41.314 27.9349 42.345 29.1943 42.345C30.4538 42.345 31.4787 41.314 31.4787 40.0472C31.4787 38.7803 30.4538 37.7493 29.1943 37.7493Z" fill="white"/>
|
||||
<path d="M29.7034 36.1927C29.7034 36.1927 29.9915 31.058 35.6321 28.2952" stroke="black" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M66.903 34.2992C66.903 34.2992 72.9723 50.027 59.0652 58.7736" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M66.1327 31.9811C66.1327 31.9811 64.2502 26.4757 61.0012 24.0701" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M38.8878 17.9919C38.8878 17.9919 33.1468 18.7129 30.1322 21.4151" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M40.73 17.7426C40.73 17.7426 42.3847 17.2844 43.5972 17.6011" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M45.7342 18.4164C46.1374 18.4164 46.4644 18.0876 46.4644 17.6819C46.4644 17.2763 46.1374 16.9474 45.7342 16.9474C45.3309 16.9474 45.004 17.2763 45.004 17.6819C45.004 18.0876 45.3309 18.4164 45.7342 18.4164Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,29 @@
|
||||
<svg width="87" height="80" viewBox="0 0 87 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M69.9912 65.6199C70.7884 65.6199 71.4449 66.2736 71.4449 67.0755C71.4449 67.8773 70.7951 68.531 69.9912 68.531C69.1873 68.531 68.5442 67.8773 68.5442 67.0755C68.5442 66.2736 69.194 65.6199 69.9912 65.6199ZM69.9912 67.8571C70.4199 67.8571 70.775 67.5067 70.775 67.0755C70.775 66.6442 70.4266 66.2938 69.9912 66.2938C69.5558 66.2938 69.2141 66.6442 69.2141 67.0755C69.2141 67.5067 69.5625 67.8571 69.9912 67.8571Z" fill="#D5203E"/>
|
||||
<path d="M53.1469 11C53.9441 11 54.6006 11.6536 54.6006 12.4555C54.6006 13.2574 53.9508 13.9111 53.1469 13.9111C52.3431 13.9111 51.7 13.2574 51.7 12.4555C51.7 11.6536 52.3498 11 53.1469 11ZM53.1469 13.2439C53.5757 13.2439 53.9307 12.8935 53.9307 12.4623C53.9307 12.031 53.5824 11.6806 53.1469 11.6806C52.7115 11.6806 52.3699 12.031 52.3699 12.4623C52.3699 12.8935 52.7182 13.2439 53.1469 13.2439Z" fill="#D5203E"/>
|
||||
<path d="M76.812 29C77.4283 29 77.924 29.5054 77.924 30.1186C77.924 30.7318 77.4216 31.2372 76.812 31.2372C76.2024 31.2372 75.7 30.7318 75.7 30.1186C75.7 29.5054 76.2024 29 76.812 29ZM76.812 30.7251C77.1402 30.7251 77.4149 30.4555 77.4149 30.1186C77.4149 29.7817 77.1469 29.5121 76.812 29.5121C76.477 29.5121 76.2091 29.7817 76.2091 30.1186C76.2091 30.4555 76.477 30.7251 76.812 30.7251Z" fill="#D5203E"/>
|
||||
<path d="M7.81199 50C8.4283 50 8.92402 50.5054 8.92402 51.1186C8.92402 51.7318 8.4216 52.2372 7.81199 52.2372C7.20238 52.2372 6.69995 51.7318 6.69995 51.1186C6.69995 50.5054 7.20238 50 7.81199 50ZM7.81199 51.7251C8.14024 51.7251 8.4149 51.4555 8.4149 51.1186C8.4149 50.7817 8.14694 50.5121 7.81199 50.5121C7.47704 50.5121 7.20908 50.7817 7.20908 51.1186C7.20908 51.4555 7.47704 51.7251 7.81199 51.7251Z" fill="#D5203E"/>
|
||||
<path d="M77.8411 50.7278L78.5981 51.4151L77.8545 52.062C77.6803 52.2102 77.6602 52.4798 77.8076 52.655C77.9617 52.8302 78.2229 52.8504 78.3971 52.7022L79.2211 51.9879L79.9915 52.6954C80.159 52.8504 80.4269 52.8369 80.581 52.6685C80.7351 52.4933 80.7217 52.2305 80.5542 52.0755L79.8575 51.442L80.6681 50.7412C80.8423 50.593 80.8624 50.3235 80.715 50.1482C80.6346 50.0539 80.514 50 80.4001 50C80.3063 50 80.2058 50.0337 80.1255 50.1011L79.2345 50.8693L78.3971 50.1078C78.3167 50.0337 78.2162 50 78.1158 50C78.0019 50 77.888 50.0472 77.8076 50.1415C77.6535 50.3167 77.6669 50.5795 77.8344 50.7345L77.8411 50.7278Z" fill="#D5203E"/>
|
||||
<path d="M25.9787 68.9555L26.7357 69.6428L25.9921 70.2897C25.818 70.438 25.7979 70.7075 25.9452 70.8827C26.0993 71.0579 26.3606 71.0782 26.5348 70.9299L27.3587 70.2156L28.1291 70.9232C28.2966 71.0782 28.5646 71.0647 28.7186 70.8962C28.8727 70.721 28.8593 70.4582 28.6918 70.3032L27.9951 69.6698L28.8057 68.969C28.9799 68.8207 29 68.5512 28.8526 68.376C28.7722 68.2817 28.6516 68.2278 28.5378 68.2278C28.444 68.2278 28.3435 68.2614 28.2631 68.3288L27.3721 69.097L26.5348 68.3356C26.4544 68.2614 26.3539 68.2278 26.2534 68.2278C26.1395 68.2278 26.0256 68.2749 25.9452 68.3693C25.7912 68.5445 25.8046 68.8073 25.972 68.9623L25.9787 68.9555Z" fill="#D5203E"/>
|
||||
<path d="M76.7572 14.2251L77.5142 14.9124L76.7706 15.5593C76.5964 15.7075 76.5763 15.9771 76.7237 16.1523C76.8778 16.3275 77.1391 16.3477 77.3132 16.1995L78.1372 15.4852L78.9076 16.1927C79.0751 16.3477 79.343 16.3342 79.4971 16.1658C79.6512 15.9906 79.6378 15.7278 79.4703 15.5728L78.7736 14.9393L79.5842 14.2385C79.7584 14.0903 79.7785 13.8207 79.6311 13.6455C79.5507 13.5512 79.4301 13.4973 79.3162 13.4973C79.2224 13.4973 79.122 13.531 79.0416 13.5984L78.1506 14.3666L77.3132 13.6051C77.2328 13.531 77.1324 13.4973 77.0319 13.4973C76.918 13.4973 76.8041 13.5445 76.7237 13.6388C76.5696 13.814 76.583 14.0768 76.7505 14.2318L76.7572 14.2251Z" fill="#D5203E"/>
|
||||
<path d="M22.167 11.8329L22.924 12.5202L22.1804 13.1671C22.0062 13.3154 21.9861 13.5849 22.1335 13.7601C22.2876 13.9353 22.5488 13.9555 22.723 13.8073L23.547 13.093L24.3174 13.8005C24.4849 13.9555 24.7528 13.942 24.9069 13.7736C25.061 13.5984 25.0476 13.3356 24.8801 13.1806L24.1834 12.5472L24.994 11.8464C25.1682 11.6981 25.1883 11.4286 25.0409 11.2534C24.9605 11.159 24.8399 11.1051 24.726 11.1051C24.6322 11.1051 24.5317 11.1388 24.4514 11.2062L23.5604 11.9744L22.723 11.2129C22.6426 11.1388 22.5421 11.1051 22.4417 11.1051C22.3278 11.1051 22.2139 11.1523 22.1335 11.2466C21.9794 11.4218 21.9928 11.6846 22.1603 11.8396L22.167 11.8329Z" fill="#D5203E"/>
|
||||
<path d="M41.1797 26.3534C41.1797 26.3534 43.6877 23.0103 47.2496 26.3534" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M39.8179 24.1169C39.8179 24.1169 44.1262 20.2476 48.2728 24.1169" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M38.1793 22.7781C38.1793 22.7781 43.6415 16.5949 49.6961 22.6775" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M46.5573 31.2675C46.2034 31.5538 45.4879 32.4824 45.2109 32.614C43.9415 33.1944 43.3876 31.9098 42.5875 31.2675C38.2562 27.7541 31.3092 29.9441 29.4321 35.1058C27.2395 41.142 32.5786 47.627 36.8561 51.2642C37.887 52.1386 42.3106 55.6288 43.3338 55.8532C43.5338 55.8996 43.5492 56.3407 43.7569 56.333L45.2109 56.4568C45.7033 56.5419 46.0495 55.7294 46.4649 55.5127C51.3963 52.9048 58.4049 46.1799 59.8589 40.6622C62.013 32.4592 52.8196 26.2064 46.5573 31.2752V31.2675ZM37.987 37.1643C38.1408 36.0886 39.5102 35.2761 40.5027 35.1368C42.7029 34.8272 46.1649 34.8505 48.3806 35.1136C49.6653 35.2683 51.0424 35.9261 51.1501 37.381C48.5498 37.4042 46.0495 37.0095 43.4338 37.0869C42.3183 37.1179 41.0258 37.3423 39.9026 37.381C39.4256 37.4042 38.6409 37.4352 38.1947 37.381C38.01 37.3578 37.9408 37.4584 37.9793 37.1643H37.987ZM49.6346 41.9081C49.3807 42.7594 49.4653 43.9047 49.273 44.8101C48.9037 46.5513 47.6805 47.7121 46.088 48.3699L45.7879 51.2642C45.5341 51.5892 43.5953 51.5737 43.3569 51.2642C43.0799 50.9159 43.2645 48.958 43.0568 48.3622C41.7874 47.8127 40.7565 47.0853 40.1872 45.7697C39.6256 44.4928 39.8872 43.1386 39.5025 41.9004C39.1256 40.7009 37.3638 39.8342 38.1254 38.2864C39.1333 38.1317 40.1718 38.2709 41.1874 38.2323C43.5954 38.1317 45.5571 38.1317 47.9651 38.2323C48.4883 38.2555 50.9116 38.1007 51.0963 38.3561C51.6887 39.927 50.0038 40.7241 49.6423 41.8926L49.6346 41.9081Z" fill="#D5203E"/>
|
||||
<path d="M46.088 48.3699L45.7879 51.2719C45.534 51.5969 43.5953 51.5737 43.3569 51.2719C43.0876 50.9237 43.2645 48.9658 43.0568 48.3699C41.7874 47.8282 40.7565 47.093 40.1872 45.7775C39.6179 44.4619 39.8872 43.1463 39.5025 41.9159C39.1179 40.6854 37.3638 39.8496 38.1254 38.3019C39.1332 38.1471 40.1718 38.2864 41.1797 38.2477C43.5876 38.1471 45.5494 38.1471 47.9574 38.2477C48.4806 38.271 50.9039 38.1162 51.0886 38.3716C51.681 39.9425 49.9961 40.7396 49.6346 41.9081C49.373 42.7594 49.4576 43.9047 49.273 44.8179C48.9037 46.5591 47.6805 47.7199 46.088 48.3777V48.3699Z" fill="white"/>
|
||||
<path d="M51.1501 37.381C48.5498 37.4042 46.0495 37.0096 43.4338 37.0947C42.3183 37.1256 41.0258 37.3501 39.9103 37.3888C39.4333 37.4042 38.6486 37.4429 38.2024 37.3888C38.0177 37.3655 37.9485 37.4662 37.9947 37.1798C38.1485 36.1041 39.5179 35.2916 40.5027 35.1523C42.7029 34.8427 46.1649 34.8737 48.3806 35.1368C49.6653 35.2916 51.0347 35.9494 51.1578 37.3965L51.1501 37.381Z" fill="white"/>
|
||||
<path d="M45.2109 55.8842V56.0854C45.2109 56.0854 45.1801 56.0699 45.1648 56.0699C44.9878 56.0622 44.8109 56.1086 44.6339 56.1473C44.5339 56.1705 44.4262 56.1782 44.3262 56.1705C44.2954 56.1628 44.2723 56.155 44.2493 56.1473C44.2108 56.1241 44.1723 56.1163 44.1339 56.1163C44.1031 56.1009 44.0723 56.0854 44.0415 56.0699C44.0108 56.0467 43.9723 56.0389 43.9338 56.0312V55.8842H45.2032H45.2109Z" fill="#D5203E"/>
|
||||
<path d="M43.3261 51.6124V56.5884H45.8264V51.6434C45.8264 51.6434 44.4032 52.3166 43.3261 51.6124Z" fill="white"/>
|
||||
<path d="M60.0128 32.8075C57.0124 28.1333 50.327 26.7094 45.8495 30.1221C45.5187 30.3698 44.8494 31.3139 44.4493 31.2365C39.5102 25.7421 30.0244 28.2649 28.0165 35.2451C25.8008 42.9529 33.2787 50.4052 38.8486 54.5144C41.0181 56.1163 43.3953 58.1206 46.1957 57.0837C48.9114 56.0854 54.789 50.9779 56.7508 48.7027C60.4205 44.4387 63.444 38.1394 60.0128 32.7997V32.8075ZM46.4649 55.505C45.1417 56.3794 43.5338 55.8919 43.3338 55.8455C42.3106 55.6211 37.8869 52.1309 36.8637 51.2564C32.5863 47.6193 27.2549 41.1343 29.4397 35.0981C31.3169 29.9287 38.2562 27.7464 42.5952 31.2597C43.3876 31.902 43.9492 33.1867 45.2109 32.6063C45.4879 32.4824 46.2034 31.5461 46.5573 31.2597C52.8119 26.1909 62.013 32.4437 59.8589 40.6545C58.4049 46.1721 51.1271 52.4327 46.4649 55.505Z" fill="black"/>
|
||||
<path d="M58.0125 24.2717H52.2272C51.781 24.7592 51.3117 25.2313 50.8732 25.7266C50.7501 25.8659 50.6347 25.9974 50.5116 26.1367C50.4654 26.1986 50.4116 26.2528 50.3654 26.3147H58.0125C62.7131 26.3147 66.5443 30.1608 66.5443 34.8969V49.1747C66.5443 53.9031 62.7208 57.7569 58.0125 57.7569H31.0861C26.3855 57.7569 22.5543 53.9108 22.5543 49.1747V34.8969C22.5543 30.1686 26.3778 26.3147 31.0861 26.3147H38.8178C38.2947 25.7807 37.8331 25.1771 37.2561 24.6973C37.0715 24.5658 36.8791 24.4419 36.6714 24.3568C36.6945 24.3646 36.7176 24.38 36.7483 24.3878C36.6714 24.3568 36.6099 24.3181 36.5406 24.2717H31.0938C25.27 24.2717 20.5309 29.0387 20.5309 34.8969V49.1747C20.5309 55.0329 25.27 59.7999 31.0938 59.7999H58.0202C63.844 59.7999 68.5831 55.0329 68.5831 49.1747V34.8969C68.5831 29.0387 63.844 24.2717 58.0202 24.2717H58.0125Z" fill="#231F20"/>
|
||||
<path d="M33.1633 61.5876H29.4167C23.5005 61.5876 18.7 56.689 18.7 50.6374V45.4757" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M40.1795 61.5876H35.202" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M43.88 61.5876H42.4106" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M70.5141 44.8333V46.0793" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M70.5141 39.2538V42.6046" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M60.3051 21.9424C65.9981 22.2906 70.5064 27.0421 70.5064 32.8539V36.6071" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M53.9889 21.9192H57.7894" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M18.7 35.3999V34.1076" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M18.7 43.1076V37.5745" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg width="88" height="80" viewBox="0 0 88 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.5014 14.3682C18.5684 14.3682 17.8 13.6119 17.8 12.6841C17.8 11.7563 18.5605 11 19.5014 11C20.4422 11 21.1948 11.7563 21.1948 12.6841C21.1948 13.6119 20.4343 14.3682 19.5014 14.3682ZM19.5014 11.7719C18.9996 11.7719 18.5841 12.1773 18.5841 12.6763C18.5841 13.1753 18.9918 13.5807 19.5014 13.5807C20.011 13.5807 20.4108 13.1753 20.4108 12.6763C20.4108 12.1773 20.0031 11.7719 19.5014 11.7719Z" fill="#D5203E"/>
|
||||
<path d="M72.5479 24.0051C71.615 24.0051 70.8466 23.2488 70.8466 22.321C70.8466 21.3932 71.6071 20.6369 72.5479 20.6369C73.4888 20.6369 74.2414 21.3932 74.2414 22.321C74.2414 23.2488 73.4809 24.0051 72.5479 24.0051ZM72.5479 21.4088C72.0462 21.4088 71.6306 21.8142 71.6306 22.3132C71.6306 22.8122 72.0383 23.2176 72.5479 23.2176C73.0575 23.2176 73.4574 22.8122 73.4574 22.3132C73.4574 21.8142 73.0497 21.4088 72.5479 21.4088Z" fill="#D5203E"/>
|
||||
<path d="M19.5014 43.5049C18.5684 43.5049 17.8 42.7487 17.8 41.8208C17.8 40.893 18.5605 40.1367 19.5014 40.1367C20.4422 40.1367 21.1948 40.893 21.1948 41.8208C21.1948 42.7487 20.4343 43.5049 19.5014 43.5049ZM19.5014 40.9086C18.9996 40.9086 18.5841 41.314 18.5841 41.813C18.5841 42.312 18.9918 42.7175 19.5014 42.7175C20.011 42.7175 20.4108 42.312 20.4108 41.813C20.4108 41.314 20.0031 40.9086 19.5014 40.9086Z" fill="#D5203E"/>
|
||||
<path d="M54.641 74.3881C53.708 74.3881 52.9396 73.6318 52.9396 72.704C52.9396 71.7762 53.7001 71.0199 54.641 71.0199C55.5818 71.0199 56.3344 71.7762 56.3344 72.704C56.3344 73.6318 55.5739 74.3881 54.641 74.3881ZM54.641 71.7918C54.1392 71.7918 53.7237 72.1972 53.7237 72.6962C53.7237 73.1952 54.1313 73.6007 54.641 73.6007C55.1506 73.6007 55.5504 73.1952 55.5504 72.6962C55.5504 72.1972 55.1427 71.7918 54.641 71.7918Z" fill="#D5203E"/>
|
||||
<path d="M60.7383 8.40197L59.8524 7.60669L60.7227 6.8582C60.9265 6.68667 60.95 6.3748 60.7775 6.17208C60.5972 5.96936 60.2915 5.94597 60.0876 6.1175L59.1233 6.94396L58.2217 6.1253C58.0256 5.94597 57.712 5.96156 57.5317 6.15648C57.3514 6.3592 57.3671 6.66328 57.5631 6.8426L58.3785 7.5755L57.4298 8.38637C57.226 8.5579 57.2024 8.86977 57.3749 9.07249C57.469 9.18165 57.6101 9.24402 57.7434 9.24402C57.8532 9.24402 57.9708 9.20504 58.0649 9.12707L59.1076 8.23823L60.0876 9.11927C60.1817 9.20504 60.2993 9.24402 60.4169 9.24402C60.5502 9.24402 60.6835 9.18945 60.7775 9.08029C60.9579 8.87757 60.9422 8.5735 60.7462 8.39417L60.7383 8.40197Z" fill="#D5203E"/>
|
||||
<path d="M22.8648 67.2774L21.9789 66.4822L22.8491 65.7337C23.053 65.5621 23.0765 65.2503 22.904 65.0475C22.7237 64.8448 22.4179 64.8214 22.2141 64.993L21.2497 65.8194L20.3481 65.0008C20.1521 64.8214 19.8385 64.837 19.6582 65.0319C19.4779 65.2347 19.4935 65.5387 19.6895 65.7181L20.5049 66.451L19.5563 67.2618C19.3524 67.4334 19.3289 67.7452 19.5014 67.9479C19.5955 68.0571 19.7366 68.1195 19.8699 68.1195C19.9796 68.1195 20.0972 68.0805 20.1913 68.0025L21.2341 67.1137L22.2141 67.9947C22.3082 68.0805 22.4258 68.1195 22.5434 68.1195C22.6766 68.1195 22.8099 68.0649 22.904 67.9557C23.0843 67.753 23.0687 67.449 22.8727 67.2696L22.8648 67.2774Z" fill="#D5203E"/>
|
||||
<path d="M66.7618 51.8086L65.8759 51.0133L66.7462 50.2648C66.95 50.0932 66.9735 49.7814 66.801 49.5787C66.6207 49.3759 66.315 49.3526 66.1111 49.5241L65.1468 50.3505L64.2451 49.5319C64.0491 49.3526 63.7355 49.3681 63.5552 49.5631C63.3749 49.7658 63.3906 50.0699 63.5866 50.2492L64.402 50.9821L63.4533 51.793C63.2495 51.9645 63.2259 52.2764 63.3984 52.4791C63.4925 52.5882 63.6336 52.6506 63.7669 52.6506C63.8767 52.6506 63.9943 52.6116 64.0883 52.5337L65.1311 51.6448L66.1111 52.5259C66.2052 52.6116 66.3228 52.6506 66.4404 52.6506C66.5737 52.6506 66.707 52.596 66.801 52.4869C66.9814 52.2842 66.9657 51.9801 66.7697 51.8008L66.7618 51.8086Z" fill="#D5203E"/>
|
||||
<path d="M24.4731 30.0455V19.985L30.6659 16.3024L38.1508 15.1741H44.8793L51.2218 15.4797L56.3667 16.6785L60.44 17.9556L62.1813 19.7578L63.1661 22.6098L62.6382 30.0455L59.6128 28.3295L54.8539 27.1229L49.9375 26.3002L42.3817 25.8458L36.4096 25.9241L32.4859 26.2219L29.3817 27.1229L26.8919 28.4784L24.4731 30.0455Z" fill="#D5203E"/>
|
||||
<path d="M33.7701 32.9837V37.348L29.3107 36.1257L25.8361 34.1668L24.0949 31.7849L25.6076 29.3011L30.6659 27.2718L35.5823 26.3002L42.0823 25.6969H47.6684L51.2217 26.4491L56.666 27.4285L61.8345 29.5832L62.7879 31.5185L61.8345 34.1668L58.1788 35.8122L54.6254 36.9719L52.963 37.348L52.8842 30.8055L51.0011 29.6067L48.2041 29.4578L44.5011 29.3011L41.8538 28.972H39.2853L36.9768 29.3795L35.8816 29.6067L34.3689 30.3511L33.7701 32.9837Z" fill="white"/>
|
||||
<path d="M61.6612 18.0262C54.9169 12.9802 35.8422 13.4112 28.2313 16.4669C27.3804 16.8039 26.4664 17.2191 25.6549 17.7519C24.2682 18.6608 23.4409 20.2044 23.4331 21.8576C23.4331 24.2317 23.4173 28.7135 23.4252 31.1581C23.4252 32.7408 24.1737 34.2374 25.4579 35.1698C27.6167 36.7446 30.6501 37.3323 33.1555 37.9669C33.1792 37.9669 33.2028 37.9826 33.2265 37.9826V61.0575C33.2265 64.1995 35.7871 66.7459 38.9465 66.7459H47.9835C51.1429 66.7459 53.7036 64.1995 53.7036 61.0575V37.9826C53.7036 37.8024 56.7448 37.2853 57.1702 37.1599C58.8248 36.6428 60.6527 35.9141 62.0078 34.7388C62.9848 33.9004 63.5048 32.6468 63.5127 31.3618C63.5285 28.9956 63.5442 24.4511 63.5521 21.9203C63.5521 20.4159 62.8982 18.9586 61.6927 18.0418C61.6848 18.0418 61.6769 18.0262 61.6691 18.0183L61.6612 18.0262ZM51.986 60.7911C51.986 63.032 50.166 64.8498 47.9047 64.8498H39.1671C36.9216 64.8498 35.1016 63.0477 35.0859 60.8146L34.9283 31.2521C34.9834 31.0327 38.2295 30.3276 38.7732 30.3511C38.718 31.1659 38.6235 34.2687 40.4277 35.0836C40.7113 35.2794 40.9398 35.4988 40.6089 35.6555C40.1913 35.8514 39.0016 35.9063 38.4107 36.0786C36.7089 36.6036 35.5901 38.0061 35.4089 39.7769C35.2119 41.7749 35.1646 46.9854 35.4483 48.905C35.6531 50.3467 36.701 51.4828 38.0719 51.9216L38.1035 61.3082C38.1035 61.7862 38.1901 62.2641 38.4265 62.6794C39.0568 63.7842 40.341 64.27 41.6883 63.7528C42.2714 63.5256 43.2247 62.46 43.2247 61.8567V51.1302C43.2247 50.903 43.6896 50.903 43.6896 51.1302V61.8567C44.1623 64.6931 48.5587 64.8733 48.8502 61.0889C49.0787 58.1428 48.6769 54.9068 48.8344 51.9372C50.1108 51.522 51.3005 50.2918 51.4896 48.9442C51.7575 46.9932 51.6866 41.9708 51.5054 39.9336C51.3005 37.5282 49.8744 36.3842 47.6368 35.8514C47.3847 35.7966 46.2659 35.7417 46.195 35.6555C46.0926 35.5458 46.2423 35.3578 46.455 35.1776C48.3223 34.347 48.1647 31.0562 48.1096 30.3746C48.149 30.3589 48.2041 30.3746 48.2987 30.3746C48.7478 30.3746 51.9308 31.0249 51.9781 31.26V60.799L51.986 60.7911ZM47.1326 40.7015L47.1011 60.8381C47.1011 61.2926 46.7308 61.6608 46.2738 61.6608C45.8168 61.6608 45.4544 61.2926 45.4465 60.846L45.4071 50.9892C45.0999 48.7326 42.232 48.5524 41.5544 50.6993L41.5229 61.0732C41.5229 61.512 41.1683 61.8802 40.7192 61.8881H40.7035C40.2465 61.8881 39.8683 61.5198 39.8762 61.0653C39.8998 57.8529 39.9865 46.2488 39.7895 40.5604C39.5847 39.4557 38.0798 39.8788 38.0798 40.7171V49.9628C37.5756 49.665 37.2131 49.2341 37.1422 48.6464C36.9137 46.7268 36.9453 41.8846 37.1422 39.9258C37.2289 39.0561 37.8198 38.2098 38.655 37.8573C40.0259 37.2539 42.6889 37.7554 42.4683 35.8201H44.4065C44.4696 38.1785 47.8102 36.9484 49.1023 38.3195C49.315 38.5468 49.6223 39.1109 49.709 39.4243C50.0163 40.6074 49.9769 47.0794 49.8193 48.4897C49.7563 49.0695 49.4963 49.7982 48.8817 49.9706V41.0305C48.8817 39.6672 47.3217 39.4321 47.1562 40.7093L47.1326 40.7015ZM40.7665 32.9054C40.6326 32.4744 40.3489 30.1944 40.8059 30.116C41.9483 30.1708 43.1065 29.9906 44.2568 30.0612C44.5405 30.0768 46.132 30.2335 46.2108 30.2884C46.5811 30.5391 46.2659 32.78 46.0296 33.2344C45.3835 34.4802 41.3101 34.5821 40.7744 32.9054H40.7665ZM53.7036 36.1257V33.8691C53.7036 33.7124 55.0193 33.305 55.1217 32.1532C55.2005 31.2443 54.7908 30.735 54.0739 30.2335C50.3866 27.6871 37.7174 27.9456 33.6677 29.7948C32.4386 30.3511 31.0125 31.589 32.0683 32.9994C32.2968 33.3128 33.2265 33.7202 33.2265 33.7907V36.1257C31.4537 36.016 25.3555 34.0885 25.0955 32.1453C24.9143 30.7977 27.081 29.6851 28.0895 29.2228C35.3143 25.9163 52.4114 25.7753 59.4866 29.5127C65.9394 32.9132 56.7999 35.7026 53.6957 36.1257H53.7036ZM61.8345 28.8153C60.7551 28.306 59.7545 27.6949 58.6357 27.264C50.7253 24.169 35.0622 24.1298 27.3016 27.6557C26.5058 28.0161 25.7652 28.4079 25.1034 28.972V20.8077C25.1034 20.2671 26.6397 19.1623 27.0888 18.9037C33.9828 14.8921 52.2538 15.0566 59.3133 18.6608C59.9436 18.9821 61.8345 20.0477 61.8345 20.8077V28.8153Z" fill="black"/>
|
||||
<path d="M37.7907 69.2323C37.7907 69.6898 37.2938 70.0481 36.7407 69.9947C32.2782 69.5678 28.8 66.4725 28.8 62.7292V54.7624C28.8 54.3431 29.2219 54 29.7375 54C30.2532 54 30.675 54.3431 30.675 54.7624V62.7292C30.675 65.7025 33.4407 68.1574 36.9844 68.4852C37.4532 68.531 37.8 68.8512 37.8 69.2323H37.7907Z" fill="black"/>
|
||||
<path d="M28.8 46.7438V49.2562C28.8 49.667 29.2455 50 29.795 50H29.8051C30.3546 50 30.8 49.667 30.8 49.2562V46.7438C30.8 46.333 30.3546 46 29.8051 46H29.795C29.2455 46 28.8 46.333 28.8 46.7438Z" fill="black"/>
|
||||
<path d="M46.3614 64.1833H46.3547C45.9879 64.1833 45.6906 64.479 45.6906 64.8437V64.8504C45.6906 65.2151 45.9879 65.5108 46.3547 65.5108H46.3614C46.7282 65.5108 47.0255 65.2151 47.0255 64.8504V64.8437C47.0255 64.479 46.7282 64.1833 46.3614 64.1833Z" fill="black"/>
|
||||
<path d="M29.8051 51H29.795C29.2455 51 28.8 51.4454 28.8 51.9949V52.0051C28.8 52.5546 29.2455 53 29.795 53H29.8051C30.3546 53 30.8 52.5546 30.8 52.0051V51.9949C30.8 51.4454 30.3546 51 29.8051 51Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.3 KiB |
@@ -0,0 +1,33 @@
|
||||
<svg width="88" height="80" viewBox="0 0 88 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M54.521 31.7036H34.925C31.9164 31.7036 29.4774 34.1586 29.4774 37.1869V47.2536C29.4774 50.2819 31.9164 52.7369 34.925 52.7369H54.521C57.5296 52.7369 59.9686 50.2819 59.9686 47.2536V37.1869C59.9686 34.1586 57.5296 31.7036 54.521 31.7036Z" fill="#D5203E"/>
|
||||
<path d="M55.1057 33.3514C56.9697 33.3514 58.4898 34.8814 58.4898 36.7577V47.7313C58.4898 49.6075 56.9697 51.1376 55.1057 51.1376H34.5535C32.6895 51.1376 31.1695 49.6075 31.1695 47.7313V36.7577C31.1695 34.8814 32.6895 33.3514 34.5535 33.3514H55.1057ZM55.1057 31.2743H34.5535C31.5478 31.2743 29.106 33.7321 29.106 36.7577V47.7313C29.106 50.7568 31.5478 53.2146 34.5535 53.2146H55.1057C58.1115 53.2146 60.5532 50.7568 60.5532 47.7313V36.7577C60.5532 33.7321 58.1115 31.2743 55.1057 31.2743Z" fill="black"/>
|
||||
<path d="M45.5381 48.5482V36.3077C45.5381 35.7399 43.9423 35.7261 43.9423 36.4877V48.5482C41.7826 47.7244 38.8731 49.019 38.6117 51.3938C38.5429 51.3938 38.4535 51.3799 38.3572 51.373C38.3572 51.373 38.3572 51.3868 38.3572 51.3938H40.2212C40.3175 49.8983 42.2021 49.4829 43.4265 49.8706C44.2037 50.1199 44.2587 51.2345 45.2561 50.6599C46.0264 50.2099 45.7926 49.8083 47.0513 49.7737C48.31 49.7529 49.0872 50.1475 49.4518 51.3938H51.1507C50.4904 48.929 47.9661 47.7174 45.545 48.5413L45.5381 48.5482Z" fill="black"/>
|
||||
<path d="M39.9323 54.4608V60.4427C39.9323 61.502 42.9519 61.4812 42.9519 60.8027V54.4608H44.3688V61.2527H46.1434V54.4608H47.3883V59.9096C47.3883 61.2527 48.2412 61.4119 49.4174 61.2389C49.5206 61.225 50.401 60.9412 50.401 60.8927V54.4608H51.8179V60.9827C51.8179 61.0381 51.5909 61.1212 51.6391 61.2527H70.3616C70.6436 61.2527 70.9875 62.2497 70.788 62.4851C70.7468 62.5405 69.8526 62.672 69.66 62.6859H20.6664C18.8162 62.5197 19.7654 61.2458 19.9648 61.2458H38.6874V54.4539H39.9323V54.4608Z" fill="black"/>
|
||||
<path d="M18.314 61.2042H15.3633C14.9758 61.2042 14.6617 61.5204 14.6617 61.9104V61.9173C14.6617 62.3074 14.9758 62.6235 15.3633 62.6235H18.314C18.7015 62.6235 19.0156 62.3074 19.0156 61.9173V61.9104C19.0156 61.5204 18.7015 61.2042 18.314 61.2042Z" fill="black"/>
|
||||
<path d="M64.1987 63.9667H26.279C25.8916 63.9667 25.5775 64.2828 25.5775 64.6729V64.6798C25.5775 65.0698 25.8916 65.386 26.279 65.386H64.1987C64.5862 65.386 64.9003 65.0698 64.9003 64.6798V64.6729C64.9003 64.2828 64.5862 63.9667 64.1987 63.9667Z" fill="black"/>
|
||||
<path d="M57.9876 66.5837H33.0197C32.6322 66.5837 32.3181 66.8999 32.3181 67.2899V67.2968C32.3181 67.6869 32.6322 68.003 33.0197 68.003H57.9876C58.3751 68.003 58.6892 67.6869 58.6892 67.2968V67.2899C58.6892 66.8999 58.3751 66.5837 57.9876 66.5837Z" fill="black"/>
|
||||
<path d="M13.5406 61.2735H13.5337C13.1462 61.2735 12.8321 61.5896 12.8321 61.9797V61.9866C12.8321 62.3766 13.1462 62.6928 13.5337 62.6928H13.5406C13.928 62.6928 14.2421 62.3766 14.2421 61.9866V61.9797C14.2421 61.5896 13.928 61.2735 13.5406 61.2735Z" fill="black"/>
|
||||
<path d="M76.834 61.2042H73.8832C73.4958 61.2042 73.1816 61.5204 73.1816 61.9104V61.9173C73.1816 62.3074 73.4958 62.6235 73.8832 62.6235H76.834C77.2215 62.6235 77.5356 62.3074 77.5356 61.9173V61.9104C77.5356 61.5204 77.2215 61.2042 76.834 61.2042Z" fill="black"/>
|
||||
<path d="M72.0536 61.2735H72.0467C71.6593 61.2735 71.3452 61.5896 71.3452 61.9797V61.9866C71.3452 62.3766 71.6593 62.6928 72.0467 62.6928H72.0536C72.4411 62.6928 72.7552 62.3766 72.7552 61.9866V61.9797C72.7552 61.5896 72.4411 61.2735 72.0536 61.2735Z" fill="black"/>
|
||||
<path d="M65.877 58.5733H55.8485C55.4611 58.5733 55.1469 58.8895 55.1469 59.2795V59.2864C55.1469 59.6765 55.4611 59.9926 55.8485 59.9926H65.877C66.2644 59.9926 66.5786 59.6765 66.5786 59.2864V59.2795C66.5786 58.8895 66.2644 58.5733 65.877 58.5733Z" fill="black"/>
|
||||
<path d="M54.0189 58.6426H54.012C53.6246 58.6426 53.3105 58.9587 53.3105 59.3488V59.3557C53.3105 59.7457 53.6246 60.0619 54.012 60.0619H54.0189C54.4064 60.0619 54.7205 59.7457 54.7205 59.3557V59.3488C54.7205 58.9587 54.4064 58.6426 54.0189 58.6426Z" fill="black"/>
|
||||
<path d="M68.0092 58.6426H68.0023C67.6149 58.6426 67.3008 58.9587 67.3008 59.3488V59.3557C67.3008 59.7457 67.6149 60.0619 68.0023 60.0619H68.0092C68.3967 60.0619 68.7108 59.7457 68.7108 59.3557V59.3488C68.7108 58.9587 68.3967 58.6426 68.0092 58.6426Z" fill="black"/>
|
||||
<path d="M33.9895 58.5733H23.9611C23.5736 58.5733 23.2595 58.8895 23.2595 59.2795V59.2864C23.2595 59.6765 23.5736 59.9926 23.9611 59.9926H33.9895C34.377 59.9926 34.6911 59.6765 34.6911 59.2864V59.2795C34.6911 58.8895 34.377 58.5733 33.9895 58.5733Z" fill="black"/>
|
||||
<path d="M22.1315 58.6426H22.1246C21.7371 58.6426 21.423 58.9587 21.423 59.3488V59.3557C21.423 59.7457 21.7371 60.0619 22.1246 60.0619H22.1315C22.5189 60.0619 22.833 59.7457 22.833 59.3557V59.3488C22.833 58.9587 22.5189 58.6426 22.1315 58.6426Z" fill="black"/>
|
||||
<path d="M36.1218 58.6426H36.1149C35.7274 58.6426 35.4133 58.9587 35.4133 59.3488V59.3557C35.4133 59.7457 35.7274 60.0619 36.1149 60.0619H36.1218C36.5092 60.0619 36.8234 59.7457 36.8234 59.3557V59.3488C36.8234 58.9587 36.5092 58.6426 36.1218 58.6426Z" fill="black"/>
|
||||
<path d="M30.1109 24.8871C29.2924 24.8871 28.6183 24.2155 28.6183 23.3916C28.6183 22.5677 29.2855 21.8961 30.1109 21.8961C30.9363 21.8961 31.5966 22.5677 31.5966 23.3916C31.5966 24.2155 30.9294 24.8871 30.1109 24.8871ZM30.1109 22.5816C29.6707 22.5816 29.3061 22.9416 29.3061 23.3847C29.3061 23.8278 29.6638 24.1878 30.1109 24.1878C30.558 24.1878 30.9088 23.8278 30.9088 23.3847C30.9088 22.9416 30.5511 22.5816 30.1109 22.5816Z" fill="#D5203E"/>
|
||||
<path d="M58.6899 8.99091C57.8714 8.99091 57.1973 8.31934 57.1973 7.49546C57.1973 6.67157 57.8645 6 58.6899 6C59.5153 6 60.1756 6.67157 60.1756 7.49546C60.1756 8.31934 59.5084 8.99091 58.6899 8.99091ZM58.6899 6.68542C58.2497 6.68542 57.8851 7.04543 57.8851 7.48853C57.8851 7.93163 58.2428 8.29165 58.6899 8.29165C59.137 8.29165 59.4878 7.93163 59.4878 7.48853C59.4878 7.04543 59.1301 6.68542 58.6899 6.68542Z" fill="#D5203E"/>
|
||||
<path d="M63.5116 32.759C62.6931 32.759 62.019 32.0874 62.019 31.2635C62.019 30.4396 62.6862 29.7681 63.5116 29.7681C64.3369 29.7681 64.9973 30.4396 64.9973 31.2635C64.9973 32.0874 64.3301 32.759 63.5116 32.759ZM63.5116 30.4535C63.0714 30.4535 62.7068 30.8135 62.7068 31.2566C62.7068 31.6997 63.0645 32.0597 63.5116 32.0597C63.9586 32.0597 64.3094 31.6997 64.3094 31.2566C64.3094 30.8135 63.9518 30.4535 63.5116 30.4535Z" fill="#D5203E"/>
|
||||
<path d="M18.3216 54.6923C17.5031 54.6923 16.829 54.0208 16.829 53.1969C16.829 52.373 17.4962 51.7014 18.3216 51.7014C19.147 51.7014 19.8073 52.373 19.8073 53.1969C19.8073 54.0208 19.1401 54.6923 18.3216 54.6923ZM18.3216 52.3868C17.8814 52.3868 17.5169 52.7469 17.5169 53.19C17.5169 53.6331 17.8745 53.9931 18.3216 53.9931C18.7687 53.9931 19.1195 53.6331 19.1195 53.19C19.1195 52.7469 18.7618 52.3868 18.3216 52.3868Z" fill="#D5203E"/>
|
||||
<path d="M65.802 73.4894C64.9835 73.4894 64.3094 72.8178 64.3094 71.9939C64.3094 71.17 64.9766 70.4985 65.802 70.4985C66.6274 70.4985 67.2877 71.17 67.2877 71.9939C67.2877 72.8178 66.6205 73.4894 65.802 73.4894ZM65.802 71.1839C65.3618 71.1839 64.9972 71.5439 64.9972 71.987C64.9972 72.4301 65.3549 72.7901 65.802 72.7901C66.2491 72.7901 66.5999 72.4301 66.5999 71.987C66.5999 71.5439 66.2422 71.1839 65.802 71.1839Z" fill="#D5203E"/>
|
||||
<path d="M13.4518 28.598L12.6746 27.8918L13.4381 27.2272C13.6169 27.0749 13.6375 26.7979 13.4862 26.6179C13.328 26.4379 13.0598 26.4171 12.8809 26.5695L12.0349 27.3033L11.2439 26.5764C11.072 26.4171 10.7968 26.431 10.6386 26.6041C10.4804 26.7841 10.4942 27.0541 10.6661 27.2133L11.3815 27.8641L10.5492 28.5842C10.3704 28.7365 10.3497 29.0134 10.5011 29.1934C10.5836 29.2904 10.7074 29.3457 10.8243 29.3457C10.9206 29.3457 11.0238 29.3111 11.1064 29.2419L12.0212 28.4526L12.8809 29.235C12.9635 29.3111 13.0666 29.3457 13.1698 29.3457C13.2868 29.3457 13.4037 29.2973 13.4862 29.2004C13.6444 29.0203 13.6307 28.7503 13.4587 28.5911L13.4518 28.598Z" fill="#D5203E"/>
|
||||
<path d="M72.3088 48.579L71.5315 47.8728L72.295 47.2081C72.4739 47.0558 72.4945 46.7789 72.3432 46.5989C72.185 46.4189 71.9167 46.3981 71.7379 46.5504L70.8919 47.2843L70.1009 46.5573C69.9289 46.3981 69.6538 46.4119 69.4956 46.585C69.3374 46.765 69.3512 47.0351 69.5231 47.1943L70.2384 47.8451L69.4062 48.5651C69.2273 48.7174 69.2067 48.9944 69.358 49.1744C69.4406 49.2713 69.5644 49.3267 69.6813 49.3267C69.7776 49.3267 69.8808 49.2921 69.9633 49.2229L70.8781 48.4336L71.7379 49.2159C71.8204 49.2921 71.9236 49.3267 72.0268 49.3267C72.1437 49.3267 72.2606 49.2782 72.3432 49.1813C72.5014 49.0013 72.4876 48.7313 72.3157 48.572L72.3088 48.579Z" fill="#D5203E"/>
|
||||
<path d="M43.2476 45.7858V47.1705C42.9037 47.1982 42.5735 47.2051 42.2503 47.2051C40.4413 47.2051 38.9006 46.9074 37.6625 46.312C36.0736 45.5573 35.2551 44.2765 34.8768 43.4665C34.698 43.0788 34.9112 42.6218 35.317 42.518H35.3514C35.6609 42.4279 35.9842 42.5803 36.1218 42.871C36.3969 43.4734 37.0159 44.4773 38.254 45.0658C39.5196 45.6681 41.1979 45.9104 43.2476 45.7858Z" fill="black"/>
|
||||
<path d="M43.2476 42.6426V44.0273C42.9794 44.048 42.7249 44.055 42.4773 44.055C37.8482 44.055 36.3213 41.3133 35.8467 39.9286C35.7091 39.527 35.9911 39.0978 36.4038 39.0493H36.4382C36.7546 39.0078 37.0435 39.2016 37.1466 39.5063C37.5043 40.5933 38.8043 42.9403 43.2476 42.6426Z" fill="black"/>
|
||||
<path d="M43.2476 40.6209C39.0863 40.344 37.6006 37.9485 37.0985 36.6677C36.9403 36.2592 37.1948 35.8092 37.6281 35.7469H37.6419C37.9583 35.6984 38.2609 35.8784 38.371 36.1761C38.7218 37.1108 39.8429 38.9801 43.2476 39.2363V40.6209Z" fill="black"/>
|
||||
<path d="M46.4116 45.855V47.2397C46.7555 47.2674 47.0857 47.2743 47.4089 47.2743C49.2179 47.2743 50.7586 46.9766 51.9967 46.3812C53.5856 45.6266 54.4041 44.3457 54.7824 43.5357C54.9612 43.148 54.748 42.691 54.3422 42.5872H54.3078C53.9983 42.4972 53.675 42.6495 53.5374 42.9403C53.2623 43.5426 52.6433 44.5465 51.4052 45.135C50.1396 45.7373 48.4613 45.9797 46.4116 45.855Z" fill="black"/>
|
||||
<path d="M46.4116 42.7118V44.0965C46.6798 44.1173 46.9343 44.1242 47.182 44.1242C51.811 44.1242 53.338 41.3825 53.8126 39.9978C53.9501 39.5963 53.6681 39.167 53.2554 39.1186H53.221C52.9046 39.077 52.6158 39.2709 52.5126 39.5755C52.1549 40.6625 50.8549 43.0095 46.4116 42.7118Z" fill="black"/>
|
||||
<path d="M46.4116 39.3055C49.8163 39.0493 50.9375 37.18 51.2882 36.2453C51.3983 35.9476 51.7009 35.7676 52.0173 35.8161H52.0311C52.4644 35.8784 52.7189 36.3284 52.5607 36.7369C52.0586 38.0177 50.5729 40.4132 46.4116 40.6902V39.3055Z" fill="black"/>
|
||||
<path d="M44.8502 27.9303C47.7639 27.9303 50.1258 25.2367 50.1258 21.9139C50.1258 18.5911 47.7639 15.8974 44.8502 15.8974C41.9366 15.8974 39.5746 18.5911 39.5746 21.9139C39.5746 25.2367 41.9366 27.9303 44.8502 27.9303Z" fill="white"/>
|
||||
<path d="M49.1354 28.325C48.8052 28.0619 48.7364 27.5911 48.9703 27.238C49.438 26.5387 50.1465 25.4448 50.3184 24.974C51.5771 21.45 49.9608 16.0498 45.9095 15.3366C40.3519 14.3674 37.5387 20.7854 39.4783 25.3894C39.6641 25.8325 40.3931 26.8918 40.7921 27.4665C40.9572 27.6949 40.9365 28.0134 40.7508 28.2211C40.4894 28.5188 37.7313 30.4435 37.7313 30.4435H40.4826L42.3534 28.6919C42.8349 28.8165 43.4264 29.405 44.7402 29.3842C46.2328 29.3635 47.237 28.6988 47.237 28.6988C47.237 28.6988 48.647 30.4435 49.0047 30.4435H51.756L49.1354 28.325ZM44.1143 27.8611C40.4482 27.0926 39.4715 22.0247 41.0741 19.0684C42.4704 16.4859 45.3523 15.6551 47.6153 17.8222C49.438 19.5669 49.8163 22.9247 48.7089 25.1402C47.8904 26.781 46.0058 28.2627 44.1143 27.8611Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 121 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.6666 4.16667H16.6666" stroke="#AF8587" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11.6666 6.66667H14.1666" stroke="#AF8587" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M17.5 9.58333C17.5 13.9583 13.9583 17.5 9.58329 17.5C5.20829 17.5 1.66663 13.9583 1.66663 9.58333C1.66663 5.20833 5.20829 1.66667 9.58329 1.66667" stroke="#AF8587" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M18.3333 18.3333L16.6666 16.6667" stroke="#AF8587" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 712 B |
@@ -0,0 +1,28 @@
|
||||
<svg width="90" height="80" viewBox="0 0 90 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.9298 16.9204C12.1092 16.9204 11.4333 16.2441 11.4333 15.4145C11.4333 14.5848 12.1023 13.9086 12.9298 13.9086C13.7574 13.9086 14.4195 14.5848 14.4195 15.4145C14.4195 16.2441 13.7505 16.9204 12.9298 16.9204ZM12.9298 14.6058C12.4885 14.6058 12.1229 14.9683 12.1229 15.4145C12.1229 15.8607 12.4816 16.2232 12.9298 16.2232C13.3781 16.2232 13.7299 15.8607 13.7299 15.4145C13.7299 14.9683 13.3712 14.6058 12.9298 14.6058Z" fill="#D5203E"/>
|
||||
<path d="M42.599 20.0367C41.7783 20.0367 41.1024 19.3605 41.1024 18.5308C41.1024 17.7012 41.7714 17.0249 42.599 17.0249C43.4266 17.0249 44.0886 17.7012 44.0886 18.5308C44.0886 19.3605 43.4197 20.0367 42.599 20.0367ZM42.599 17.7151C42.1576 17.7151 41.7921 18.0777 41.7921 18.5239C41.7921 18.97 42.1507 19.3326 42.599 19.3326C43.0473 19.3326 43.399 18.97 43.399 18.5239C43.399 18.0777 43.0404 17.7151 42.599 17.7151Z" fill="#D5203E"/>
|
||||
<path d="M68.7232 41.2447C67.9026 41.2447 67.2267 40.5684 67.2267 39.7388C67.2267 38.9092 67.8957 38.2329 68.7232 38.2329C69.5508 38.2329 70.2129 38.9092 70.2129 39.7388C70.2129 40.5684 69.5439 41.2447 68.7232 41.2447ZM68.7232 38.9231C68.2819 38.9231 67.9163 39.2856 67.9163 39.7318C67.9163 40.178 68.275 40.5406 68.7232 40.5406C69.1715 40.5406 69.5233 40.178 69.5233 39.7318C69.5233 39.2856 69.1646 38.9231 68.7232 38.9231Z" fill="#D5203E"/>
|
||||
<path d="M15.2264 54.0796C14.4057 54.0796 13.7298 53.4034 13.7298 52.5737C13.7298 51.7441 14.3988 51.0679 15.2264 51.0679C16.0539 51.0679 16.716 51.7441 16.716 52.5737C16.716 53.4034 16.0471 54.0796 15.2264 54.0796ZM15.2264 51.7581C14.785 51.7581 14.4195 52.1206 14.4195 52.5668C14.4195 53.013 14.7781 53.3755 15.2264 53.3755C15.6746 53.3755 16.0264 53.013 16.0264 52.5668C16.0264 52.1206 15.6677 51.7581 15.2264 51.7581Z" fill="#D5203E"/>
|
||||
<path d="M78.7302 62.1599C78.0957 62.1599 77.5853 61.637 77.5853 61.0026C77.5853 60.3681 78.1026 59.8453 78.7302 59.8453C79.3577 59.8453 79.875 60.3681 79.875 61.0026C79.875 61.637 79.3577 62.1599 78.7302 62.1599ZM78.7302 60.3751C78.3922 60.3751 78.1095 60.654 78.1095 61.0026C78.1095 61.3512 78.3853 61.63 78.7302 61.63C79.075 61.63 79.3509 61.3512 79.3509 61.0026C79.3509 60.654 79.075 60.3751 78.7302 60.3751Z" fill="#D5203E"/>
|
||||
<path d="M35.1506 57.6422C34.5161 57.6422 34.0058 57.1193 34.0058 56.4849C34.0058 55.8505 34.523 55.3276 35.1506 55.3276C35.7782 55.3276 36.2955 55.8505 36.2955 56.4849C36.2955 57.1193 35.7782 57.6422 35.1506 57.6422ZM35.1506 55.8574C34.8127 55.8574 34.5299 56.1363 34.5299 56.4849C34.5299 56.8335 34.8058 57.1123 35.1506 57.1123C35.4955 57.1123 35.7713 56.8335 35.7713 56.4849C35.7713 56.1363 35.4955 55.8574 35.1506 55.8574Z" fill="#D5203E"/>
|
||||
<path d="M16.6885 30.6825L15.9091 29.9714L16.6747 29.3021C16.854 29.1488 16.8747 28.8699 16.7229 28.6886C16.5643 28.5074 16.2954 28.4864 16.116 28.6398L15.2678 29.3788L14.4747 28.6468C14.3022 28.4864 14.0264 28.5004 13.8678 28.6747C13.7091 28.8559 13.7229 29.1278 13.8953 29.2882L14.6126 29.9435L13.7781 30.6686C13.5988 30.822 13.5781 31.1008 13.7298 31.2821C13.8126 31.3797 13.9367 31.4355 14.054 31.4355C14.1505 31.4355 14.254 31.4006 14.3367 31.3309L15.254 30.5361L16.116 31.3239C16.1988 31.4006 16.3023 31.4355 16.4057 31.4355C16.5229 31.4355 16.6402 31.3867 16.7229 31.2891C16.8816 31.1078 16.8678 30.8359 16.6954 30.6756L16.6885 30.6825Z" fill="#D5203E"/>
|
||||
<path d="M65.4611 11.1478L64.6818 10.4367L65.4473 9.76738C65.6266 9.614 65.6473 9.33513 65.4956 9.15387C65.337 8.9726 65.068 8.95169 64.8887 9.10507L64.0404 9.84407L63.2473 9.11204C63.0749 8.95169 62.799 8.96563 62.6404 9.13992C62.4818 9.32119 62.4956 9.59309 62.668 9.75344L63.3852 10.4088L62.5507 11.1338C62.3714 11.2872 62.3507 11.5661 62.5025 11.7473C62.5852 11.845 62.7094 11.9007 62.8266 11.9007C62.9232 11.9007 63.0266 11.8659 63.1094 11.7961L64.0266 11.0014L64.8887 11.7892C64.9714 11.8659 65.0749 11.9007 65.1783 11.9007C65.2956 11.9007 65.4128 11.8519 65.4956 11.7543C65.6542 11.5731 65.6404 11.3012 65.468 11.1408L65.4611 11.1478Z" fill="#D5203E"/>
|
||||
<path d="M13.185 69.8287L12.4057 69.1176L13.1712 68.4483C13.3505 68.295 13.3712 68.0161 13.2195 67.8348C13.0608 67.6536 12.7919 67.6327 12.6126 67.786L11.7643 68.525L10.9712 67.793C10.7988 67.6327 10.5229 67.6466 10.3643 67.8209C10.2057 68.0022 10.2194 68.2741 10.3919 68.4344L11.1091 69.0897L10.2746 69.8148C10.0953 69.9682 10.0746 70.2471 10.2263 70.4283C10.3091 70.5259 10.4332 70.5817 10.5505 70.5817C10.647 70.5817 10.7505 70.5468 10.8332 70.4771L11.7505 69.6823L12.6126 70.4701C12.6953 70.5468 12.7988 70.5817 12.9022 70.5817C13.0195 70.5817 13.1367 70.5329 13.2195 70.4353C13.3781 70.254 13.3643 69.9821 13.1919 69.8218L13.185 69.8287Z" fill="#D5203E"/>
|
||||
<path d="M69.3853 70.2471L68.606 69.536L69.3715 68.8667C69.5508 68.7133 69.5715 68.4344 69.4198 68.2532C69.2612 68.0719 68.9922 68.051 68.8129 68.2044L67.9646 68.9434L67.1715 68.2113C66.9991 68.051 66.7232 68.0649 66.5646 68.2392C66.406 68.4205 66.4198 68.6924 66.5922 68.8527L67.3094 69.5081L66.4749 70.2331C66.2956 70.3865 66.2749 70.6654 66.4267 70.8466C66.5094 70.9442 66.6336 71 66.7508 71C66.8474 71 66.9508 70.9652 67.0336 70.8954L67.9508 70.1007L68.8129 70.8885C68.8956 70.9652 68.9991 71 69.1025 71C69.2198 71 69.337 70.9512 69.4198 70.8536C69.5784 70.6723 69.5646 70.4004 69.3922 70.2401L69.3853 70.2471Z" fill="#D5203E"/>
|
||||
<path d="M17.9367 41.175V41.1959C17.9367 41.1959 17.8815 41.182 17.8539 41.175H17.9367Z" fill="black"/>
|
||||
<path d="M35.2817 48.2304C35.2817 48.2304 25.4402 46.592 22.7781 43.9009L32.7851 21.0337C32.7851 21.0337 44.2541 28.8002 56.3714 20.6293L66.2129 44.1868C66.2129 44.1868 57.0059 48.0909 53.93 48.3698" fill="white"/>
|
||||
<path d="M26.3436 50.8936C26.3436 50.8936 23.0678 49.9384 20.3574 48.3768C18.9298 47.5541 18.4057 45.7275 19.116 44.2286L23.3505 35.3187" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M24.3505 33.1017L25.7919 29.9087" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M28.6472 51.5907L30.0816 51.9184" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M32.454 52.3785L32.8885 52.4343" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M54.8128 55.1533C54.8128 55.1533 58.3921 53.3755 61.9715 56.1014" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M63.9921 57.6422C63.9921 57.6422 64.9301 58.416 65.1645 59.1829" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M66.2266 61.2953L66.399 61.9716" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M48.9646 49.4016C48.7922 49.5898 48.0197 50.6774 47.8887 50.9145C46.6956 53.1175 48.1784 58.5485 47.3508 61.1001C46.3577 64.1607 41.6887 63.7006 41.0611 60.8422C40.4335 57.9838 41.8542 52.7201 40.3231 50.5101C39.6197 49.4852 38.1369 48.6974 37.4955 47.4774C36.8266 46.2016 36.7714 44.7026 36.93 43.2944L37.0748 42.5344C39.9714 40.7497 43.537 40.1571 46.9094 40.5893C48.3921 40.7845 50.5508 41.9209 51.9577 42.4926C52.3646 44.2983 51.7577 46.6059 50.5922 48.0979C50.068 48.7672 49.337 49.0112 48.9715 49.4016H48.9646Z" fill="#D5203E"/>
|
||||
<path d="M52.5646 40.4429C52.7301 40.6939 52.9025 42.2904 52.0404 42.0116C51.4818 41.8303 50.3301 41.3283 49.6197 41.0355C46.4611 39.7179 43.7576 39.3693 40.4404 40.2826L36.2955 42.0185L36.3369 40.4499C38.599 39.5994 41.0611 37.6194 43.4749 37.4381C44.5094 37.3614 46.7439 38.219 47.7784 38.4769C48.399 38.6303 52.4129 40.2268 52.5646 40.4499V40.4429Z" fill="white"/>
|
||||
<path d="M35.0748 49.046C35.0748 49.046 25.2334 47.4077 22.5713 44.7166L32.5782 21.8494C32.5782 21.8494 44.0473 29.6158 56.1646 21.445L66.006 45.0024C66.006 45.0024 56.7991 48.9066 53.7232 49.1855" stroke="black" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M45.1025 64.5441C45.6059 66.2592 47.4404 66.8169 48.8611 65.7433C50.2818 64.6696 49.9508 62.9476 50.4059 61.4208C52.8818 53.0687 64.9439 55.6343 63.937 64.1956L62.9301 64.1816C62.4957 62.6618 62.6543 61.4069 61.7025 60.0544C59.7784 57.3215 56.3508 56.8892 53.6818 58.8413C50.6542 61.0583 52.2473 64.4256 50.2542 66.4544C48.7714 67.9603 46.4266 68.0788 44.7783 66.7821C43.7714 65.9873 43.8818 64.7742 43.6955 64.586C43.6266 64.5163 42.33 64.2235 41.7921 63.9167C38.2886 61.881 40.1576 55.7807 39.5576 52.3227C39.2404 50.4752 37.6817 49.9314 36.7369 48.5929C35.2265 46.4525 36.1093 43.6917 35.8334 41.1959C35.7507 40.4499 36.0748 39.7109 36.6817 39.2786C40.4404 36.6154 45.3094 36.0926 49.6542 37.947C50.4197 38.2747 52.5439 39.3902 52.6473 40.1152C52.8128 41.2725 52.8059 45.5392 52.5784 46.6338C52.0404 49.2133 49.1508 50.4055 48.8818 52.246C48.2611 56.5476 50.8473 63.101 45.1025 64.5302V64.5441ZM51.5715 40.3453C51.5715 40.3453 44.4749 35.8555 36.9162 40.5196L36.8817 41.6909C36.8817 41.6909 44.0128 36.9431 51.4473 41.7187L51.5715 40.3453ZM48.9645 49.4016C49.3714 48.9624 52.6059 47.7214 51.4887 42.7366C50.1577 41.7118 48.4542 41.2237 46.9714 41.0146C39.6059 39.9619 36.93 43.2874 36.93 43.2874C36.7783 44.7026 36.8265 46.1946 37.4955 47.4704C38.1645 48.7462 39.6128 49.4783 40.3231 50.5031C41.8473 52.7201 40.461 58.1023 41.061 60.8352C41.6611 63.5681 46.3576 64.1537 47.3507 61.0932C48.1783 58.5415 46.6956 53.1105 47.8887 50.9075C48.0197 50.6704 48.3852 50.0151 48.9645 49.3946V49.4016Z" fill="black"/>
|
||||
<path d="M41.2335 35.3187C41.2335 35.3187 43.7852 31.9026 47.4128 35.3187" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M39.8541 33.032C39.8541 33.032 44.2404 29.079 48.4542 33.032" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
<path d="M38.1783 31.6655C38.1783 31.6655 43.7369 25.3422 49.9025 31.5679" stroke="#231F20" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.7 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.625 7.66499V14.25C14.625 15.75 14.25 16.5 12.375 16.5H5.625C3.75 16.5 3.375 15.75 3.375 14.25V7.66499" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3.75 1.5H14.25C15.75 1.5 16.5 2.25 16.5 3.75V5.25C16.5 6.75 15.75 7.5 14.25 7.5H3.75C2.25 7.5 1.5 6.75 1.5 5.25V3.75C1.5 2.25 2.25 1.5 3.75 1.5Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7.63501 10.5H10.365" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 661 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.94 6.7125L10.05 11.6025C9.4725 12.18 8.5275 12.18 7.95 11.6025L3.06 6.7125" stroke="#965457" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 300 B |
@@ -0,0 +1,9 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 1.5V3.75" stroke="#965457" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 1.5V3.75" stroke="#965457" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.625 6.8175H15.375" stroke="#965457" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M15.75 6.375V12.75C15.75 15 14.625 16.5 12 16.5H6C3.375 16.5 2.25 15 2.25 12.75V6.375C2.25 4.125 3.375 2.625 6 2.625H12C14.625 2.625 15.75 4.125 15.75 6.375Z" stroke="#965457" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M8.99661 10.275H9.00335" stroke="#965457" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.22073 10.275H6.22747" stroke="#965457" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.22073 12.525H6.22747" stroke="#965457" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16.5 7.5V11.25C16.5 15 15 16.5 11.25 16.5H6.75C3 16.5 1.5 15 1.5 11.25V6.75C1.5 3 3 1.5 6.75 1.5H10.5" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16.5 7.5H13.5C11.25 7.5 10.5 6.75 10.5 4.5V1.5L16.5 7.5Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.25 9.75H9.75" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.25 12.75H8.25" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 677 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.3867 8.50001C10.3867 9.82001 9.31999 10.8867 7.99999 10.8867C6.67999 10.8867 5.61333 9.82001 5.61333 8.50001C5.61333 7.18001 6.67999 6.11334 7.99999 6.11334C9.31999 6.11334 10.3867 7.18001 10.3867 8.50001Z" stroke="#576989" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M8 14.0133C10.3533 14.0133 12.5467 12.6267 14.0733 10.2267C14.6733 9.28668 14.6733 7.70668 14.0733 6.76668C12.5467 4.36668 10.3533 2.98001 8 2.98001C5.64667 2.98001 3.45334 4.36668 1.92667 6.76668C1.32667 7.70668 1.32667 9.28668 1.92667 10.2267C3.45334 12.6267 5.64667 14.0133 8 14.0133Z" stroke="#576989" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 791 B |
@@ -0,0 +1,7 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.00001 2.25H6.75001C5.28751 6.63 5.28751 11.37 6.75001 15.75H6.00001" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11.25 2.25C12.7125 6.63 12.7125 11.37 11.25 15.75" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.25 12V11.25C6.63 12.7125 11.37 12.7125 15.75 11.25V12" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.25 6.75C6.63 5.2875 11.37 5.2875 15.75 6.75" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 939 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.765 2.13L2.7225 5.28C2.0475 5.805 1.5 6.9225 1.5 7.77V13.3275C1.5 15.0675 2.9175 16.4925 4.6575 16.4925H13.3425C15.0825 16.4925 16.5 15.0675 16.5 13.335V7.875C16.5 6.9675 15.8925 5.805 15.15 5.2875L10.515 2.04C9.465 1.305 7.7775 1.3425 6.765 2.13Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9 13.4925V11.2425" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 563 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.91005 9.0525C5.91005 8.745 6.16505 8.49 6.47255 8.49H10.5826V2.145C10.5751 1.785 10.2901 1.5 9.93005 1.5C5.51255 1.5 2.43005 4.5825 2.43005 9C2.43005 13.4175 5.51255 16.5 9.93005 16.5C10.2826 16.5 10.5751 16.215 10.5751 15.855V9.6075H6.47255C6.15755 9.615 5.91005 9.36 5.91005 9.0525Z" fill="#965457"/>
|
||||
<path d="M15.405 8.655L13.275 6.5175C13.0575 6.3 12.6975 6.3 12.48 6.5175C12.2625 6.735 12.2625 7.095 12.48 7.3125L13.65 8.4825H10.575V9.6075H13.6425L12.4724 10.7775C12.255 10.995 12.255 11.355 12.4724 11.5725C12.5849 11.685 12.7275 11.7375 12.87 11.7375C13.0125 11.7375 13.155 11.685 13.2675 11.5725L15.3975 9.435C15.6225 9.225 15.6225 8.8725 15.405 8.655Z" fill="#965457"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 794 B |
@@ -0,0 +1,7 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.30749 12.5625C3.12749 14.73 4.76249 16.5 6.93749 16.5H10.53C12.975 16.5 14.655 14.5275 14.25 12.1125C13.8225 9.5775 11.3775 7.5 8.80499 7.5C6.01499 7.5 3.53999 9.78 3.30749 12.5625Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7.85254 5.625C8.88807 5.625 9.72754 4.78553 9.72754 3.75C9.72754 2.71447 8.88807 1.875 7.85254 1.875C6.81701 1.875 5.97754 2.71447 5.97754 3.75C5.97754 4.78553 6.81701 5.625 7.85254 5.625Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12.975 6.52499C13.8034 6.52499 14.475 5.85342 14.475 5.02499C14.475 4.19657 13.8034 3.52499 12.975 3.52499C12.1465 3.52499 11.475 4.19657 11.475 5.02499C11.475 5.85342 12.1465 6.52499 12.975 6.52499Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M15.75 9.52499C16.3713 9.52499 16.875 9.02131 16.875 8.39999C16.875 7.77867 16.3713 7.27499 15.75 7.27499C15.1287 7.27499 14.625 7.77867 14.625 8.39999C14.625 9.02131 15.1287 9.52499 15.75 9.52499Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.97754 8.02499C3.80597 8.02499 4.47754 7.35342 4.47754 6.52499C4.47754 5.69657 3.80597 5.02499 2.97754 5.02499C2.14911 5.02499 1.47754 5.69657 1.47754 6.52499C1.47754 7.35342 2.14911 8.02499 2.97754 8.02499Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M23.85 19.65C23.1125 15.2375 18.875 11.65 14.4 11.65C9.53748 11.65 5.26248 15.5875 4.84998 20.4375C4.68748 22.3125 5.28748 24.0875 6.52498 25.425C7.74998 26.7625 9.47498 27.5 11.35 27.5H17.2C19.3125 27.5 21.1625 26.675 22.425 25.1875C23.6875 23.7 24.1875 21.725 23.85 19.65Z" fill="#7A1419"/>
|
||||
<path d="M12.85 9.825C14.8727 9.825 16.5125 8.18524 16.5125 6.1625C16.5125 4.13976 14.8727 2.5 12.85 2.5C10.8273 2.5 9.1875 4.13976 9.1875 6.1625C9.1875 8.18524 10.8273 9.825 12.85 9.825Z" fill="#7A1419"/>
|
||||
<path d="M21.175 11.2875C22.8595 11.2875 24.225 9.92197 24.225 8.2375C24.225 6.55303 22.8595 5.1875 21.175 5.1875C19.4905 5.1875 18.125 6.55303 18.125 8.2375C18.125 9.92197 19.4905 11.2875 21.175 11.2875Z" fill="#7A1419"/>
|
||||
<path d="M25.6875 16.1625C27.0337 16.1625 28.125 15.0712 28.125 13.725C28.125 12.3788 27.0337 11.2875 25.6875 11.2875C24.3413 11.2875 23.25 12.3788 23.25 13.725C23.25 15.0712 24.3413 16.1625 25.6875 16.1625Z" fill="#7A1419"/>
|
||||
<path d="M4.925 13.725C6.60947 13.725 7.975 12.3595 7.975 10.675C7.975 8.99053 6.60947 7.625 4.925 7.625C3.24053 7.625 1.875 8.99053 1.875 10.675C1.875 12.3595 3.24053 13.725 4.925 13.725Z" fill="#7A1419"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.16003 13.6125V12.06" stroke="#965457" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M9 13.6125V10.5075" stroke="#965457" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M12.84 13.6125V8.94749" stroke="#965457" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M12.84 4.3875L12.495 4.7925C10.5825 7.0275 8.01753 8.61 5.16003 9.3225" stroke="#965457" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M10.6425 4.3875H12.84V6.5775" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.75 16.5H11.25C15 16.5 16.5 15 16.5 11.25V6.75C16.5 3 15 1.5 11.25 1.5H6.75C3 1.5 1.5 3 1.5 6.75V11.25C1.5 15 3 16.5 6.75 16.5Z" stroke="#965457" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 872 B |
@@ -0,0 +1,56 @@
|
||||
<script setup>
|
||||
import {Link} from "@inertiajs/inertia-vue3";
|
||||
const props = defineProps([
|
||||
'currentPage',
|
||||
'lastPage',
|
||||
'total',
|
||||
'perPage',
|
||||
'links',
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="pagination" v-if="lastPage > 1">
|
||||
<template v-for="(link , index) in links" :key="index">
|
||||
<div class="paginate" v-if="link.label == 'قبلی'">
|
||||
<Link v-if="link.url" :href="link.url">
|
||||
<i class="fi fi-rr-angle-small-right flex text-xl"></i>
|
||||
</Link>
|
||||
</div>
|
||||
<div class="paginate" v-else-if="link.label == 'بعدی'">
|
||||
<Link v-if="link.url" :href="link.url">
|
||||
<i class="fi fi-rr-angle-small-left flex text-xl"></i>
|
||||
</Link>
|
||||
</div>
|
||||
<div class="paginate flex items-center" :class="{'!text-white !bg-client-primary' : currentPage == link.label }" v-else>
|
||||
<Link v-if="link.url" :href="link.url" class="flex pt-1">{{link.label}}</Link>
|
||||
<Link v-else href="" class="flex">{{link.label}}</Link>
|
||||
</div>
|
||||
</template>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style lang="postcss">
|
||||
section.pagination{
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
section.pagination div.paginate:first-child a{
|
||||
border-top-right-radius: .4rem;
|
||||
border-bottom-right-radius: .4rem;
|
||||
}
|
||||
section.pagination div.paginate:last-child a{
|
||||
border-top-left-radius: .4rem;
|
||||
border-bottom-left-radius: .4rem;
|
||||
}
|
||||
section.pagination div.paginate a{
|
||||
display: flex;
|
||||
height: 2.2rem;
|
||||
width: 2.2rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid #e6e6e6;
|
||||
@apply text-client-Fontcolor
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,179 @@
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue';
|
||||
import Pagination from './Pagination.vue';
|
||||
import DataTable from 'primevue/datatable';
|
||||
import Column from 'primevue/column';
|
||||
import Button from 'primevue/button';
|
||||
import InputText from 'primevue/inputtext';
|
||||
import Toolbar from 'primevue/toolbar';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
},
|
||||
selectable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
modelValue: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
pagination: {
|
||||
type: Object,
|
||||
default: () => null
|
||||
},
|
||||
searchable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
searchValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'selection-change', 'page-change', 'search-change']);
|
||||
|
||||
const localSelection = ref(props.modelValue);
|
||||
|
||||
watch(() => props.modelValue, (newValue) => {
|
||||
localSelection.value = newValue;
|
||||
}, { immediate: true });
|
||||
|
||||
const handleSelectionChange = (event) => {
|
||||
localSelection.value = event;
|
||||
emit('update:modelValue', event);
|
||||
emit('selection-change', event);
|
||||
};
|
||||
|
||||
const localSearchValue = ref(props.searchValue);
|
||||
|
||||
watch(() => props.searchValue, (newValue) => {
|
||||
localSearchValue.value = newValue;
|
||||
}, { immediate: true });
|
||||
|
||||
|
||||
const handleSearchClick = () => {
|
||||
emit('search-change', localSearchValue.value);
|
||||
};
|
||||
|
||||
const renderColumnContent = (column, data) => {
|
||||
let content = '';
|
||||
if (column.render && typeof column.render === 'function') {
|
||||
content = column.render(data);
|
||||
} else {
|
||||
content = data[column.key];
|
||||
}
|
||||
|
||||
const defaultStyle = '!text-[11px] !font-normal';
|
||||
const customStyle = column.style || defaultStyle;
|
||||
|
||||
return `<span class="${customStyle} text-right wrap-break-word text-sm">${content}</span>`;
|
||||
};
|
||||
|
||||
const getColumnStyle = (column) => {
|
||||
const baseStyle = { minWidth: '120px' };
|
||||
|
||||
if (column.width) {
|
||||
baseStyle.width = column.width + 'px';
|
||||
baseStyle.minWidth = column.width + 'px';
|
||||
baseStyle.maxWidth = column.width + 'px';
|
||||
}
|
||||
|
||||
return baseStyle;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="table-generic">
|
||||
<div v-if="searchable" class="p-4">
|
||||
<Toolbar class="">
|
||||
<template #start>
|
||||
<div class="grid grid-cols-2a justify-start gap-2">
|
||||
<InputText
|
||||
size="small"
|
||||
class="placeholder:!font-light placeholder:!text-xs"
|
||||
placeholder="جستجو..."
|
||||
type="text"
|
||||
v-model="localSearchValue"
|
||||
/>
|
||||
<Button
|
||||
:pt="{icon : 'flex'}"
|
||||
icon="fi fi-rr-search"
|
||||
class="!text-xs"
|
||||
severity="secondary"
|
||||
@click="handleSearchClick"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="localSelection && localSelection.length > 0" class="mr-2 !h-9 grid grid-cols-1">
|
||||
<slot name="bulk-action" :selection="localSelection"></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #end>
|
||||
<slot name="toolbar-actions"></slot>
|
||||
</template>
|
||||
</Toolbar>
|
||||
</div>
|
||||
<DataTable
|
||||
:value="data"
|
||||
dataKey="id"
|
||||
v-model:selection="localSelection"
|
||||
:showGridlines="false"
|
||||
:stripedRows="false"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<template #empty>
|
||||
<div class="flex justify-center py-4 items-center h-full">
|
||||
<span class="text-center text-sm">هیچ دادهای پیدا نشده!</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<Column
|
||||
v-if="selectable"
|
||||
selectionMode="multiple"
|
||||
headerStyle="width: 4rem"
|
||||
/>
|
||||
|
||||
<Column
|
||||
v-for="column in columns"
|
||||
:key="column.key"
|
||||
:field="column.key"
|
||||
:header="column.title"
|
||||
:sortable="column.hasSort === true"
|
||||
:style="getColumnStyle(column)"
|
||||
>
|
||||
<template #body="{ data }">
|
||||
<slot v-if="column.slot" :name="`column-${column.key}`" :data="data" :column="column">
|
||||
<div v-html="renderColumnContent(column, data)"></div>
|
||||
</slot>
|
||||
<div v-else v-html="renderColumnContent(column, data)"></div>
|
||||
</template>
|
||||
</Column>
|
||||
</DataTable>
|
||||
|
||||
<Pagination
|
||||
v-if="pagination && pagination.total"
|
||||
:total="pagination.total"
|
||||
:current-page="pagination.current_page"
|
||||
:perPage="pagination.per_page"
|
||||
:lastPage="pagination.last_page"
|
||||
:links="pagination.links"
|
||||
@page-change="(page) => emit('page-change', page)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.table-generic {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div class="ui-button">
|
||||
<Button
|
||||
:class="buttonClasses"
|
||||
:style="buttonStyle"
|
||||
:disabled="disabled"
|
||||
:loading="loading"
|
||||
:label="buttonLabel"
|
||||
:size="size"
|
||||
:severity="severity"
|
||||
:outlined="outlined"
|
||||
:text="text"
|
||||
:raised="raised"
|
||||
:rounded="rounded"
|
||||
:link="link"
|
||||
:plain="plain"
|
||||
:pt="pt"
|
||||
@click="handleClick"
|
||||
>
|
||||
<template v-if="icon && iconPosition === 'start'" #icon>
|
||||
<i :class="[icon, iconClass]" class="ui-button-icon"></i>
|
||||
</template>
|
||||
|
||||
<template v-if="icon && iconPosition === 'end'" #default>
|
||||
{{ label }}
|
||||
<i :class="[icon, iconClass]" class="ui-button-icon-end"></i>
|
||||
</template>
|
||||
|
||||
<slot />
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import Button from 'primevue/button'
|
||||
|
||||
const props = defineProps({
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconPosition: {
|
||||
type: String,
|
||||
default: 'start',
|
||||
validator: (value) => ['start', 'end'].includes(value)
|
||||
},
|
||||
iconClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
validator: (value) => ['small', 'default', 'large'].includes(value)
|
||||
},
|
||||
severity: {
|
||||
type: String,
|
||||
default: 'primary',
|
||||
validator: (value) => ['primary', 'secondary', 'success', 'info', 'warning', 'danger', 'dominant'].includes(value)
|
||||
},
|
||||
variant: {
|
||||
type: String,
|
||||
default: 'filled',
|
||||
validator: (value) => ['filled', 'outlined', 'text', 'link', 'plain'].includes(value)
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
outlined: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
text: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
raised: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
rounded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
link: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
plain: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
fullWidth: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
pt: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['click'])
|
||||
|
||||
const buttonClasses = computed(() => {
|
||||
const classes = []
|
||||
|
||||
if (props.fullWidth) {
|
||||
classes.push('ui-button--full-width')
|
||||
}
|
||||
|
||||
if (props.severity === 'dominant') {
|
||||
classes.push('ui-button--dominant')
|
||||
}
|
||||
if (props.severity === 'secondary') {
|
||||
classes.push('!font-[600] !text-[11px] !rounded-[6px]')
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
|
||||
const buttonLabel = computed(() => {
|
||||
if (props.icon && props.iconPosition === 'end') {
|
||||
return ''
|
||||
}
|
||||
return props.label
|
||||
})
|
||||
|
||||
const buttonStyle = computed(() => {
|
||||
const style = {}
|
||||
|
||||
if (props.height) {
|
||||
style.height = props.height
|
||||
}
|
||||
|
||||
return style
|
||||
})
|
||||
|
||||
const handleClick = (event) => {
|
||||
emit('click', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<Card :class="[cardClasses, 'border-[1px] border-complement-50']" :pt="pt">
|
||||
<template #header>
|
||||
<div class="ui-card-header grid grid-cols-a pb-2 justify-start items-center">
|
||||
<h1 class="font-bold text-[11px] text-complement-700 title-generic">{{ title }}</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<slot />
|
||||
</template>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import Card from 'primevue/card'
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
subtitle: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
variant: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
validator: (value) => ['default', 'elevated', 'outlined', 'filled'].includes(value)
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
validator: (value) => ['small', 'default', 'large'].includes(value)
|
||||
},
|
||||
shadow: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
validator: (value) => ['none', 'sm', 'default', 'md', 'lg', 'xl'].includes(value)
|
||||
},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
rounded: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
hover: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
pt: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const cardClasses = computed(() => {
|
||||
const classes = ['ui-card']
|
||||
|
||||
switch (props.size) {
|
||||
case 'small':
|
||||
classes.push('ui-card--small')
|
||||
break
|
||||
case 'large':
|
||||
classes.push('ui-card--large')
|
||||
break
|
||||
default:
|
||||
classes.push('ui-card--default')
|
||||
}
|
||||
|
||||
switch (props.variant) {
|
||||
case 'elevated':
|
||||
classes.push('ui-card--elevated')
|
||||
break
|
||||
case 'outlined':
|
||||
classes.push('ui-card--outlined')
|
||||
break
|
||||
case 'filled':
|
||||
classes.push('ui-card--filled')
|
||||
break
|
||||
default:
|
||||
classes.push('ui-card--default')
|
||||
}
|
||||
|
||||
if (props.shadow !== 'none') {
|
||||
switch (props.shadow) {
|
||||
case 'sm':
|
||||
classes.push('ui-card--shadow-sm')
|
||||
break
|
||||
case 'md':
|
||||
classes.push('ui-card--shadow-md')
|
||||
break
|
||||
case 'lg':
|
||||
classes.push('ui-card--shadow-lg')
|
||||
break
|
||||
case 'xl':
|
||||
classes.push('ui-card--shadow-xl')
|
||||
break
|
||||
default:
|
||||
classes.push('ui-card--shadow')
|
||||
}
|
||||
}
|
||||
|
||||
if (!props.border) {
|
||||
classes.push('ui-card--no-border')
|
||||
}
|
||||
|
||||
if (props.rounded) {
|
||||
classes.push('ui-card--rounded')
|
||||
}
|
||||
|
||||
if (props.hover) {
|
||||
classes.push('ui-card--hover')
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,515 @@
|
||||
<template>
|
||||
<div class="ui-input-wrapper" :class="directionClass">
|
||||
<label v-if="label" :for="id" class="ui-input-label">
|
||||
{{ label }}
|
||||
<span v-if="required" class="ui-input-required-indicator">*</span>
|
||||
</label>
|
||||
|
||||
<div class="ui-input">
|
||||
<div v-if="hasPrefixes" :class="['.ui-input-wrapper-border', prefixClasses]">
|
||||
<i v-if="actualIconEnd" :class="[actualIconEnd, iconColorClass]" class="ui-input-icon-end !mt-2"></i>
|
||||
<div
|
||||
v-if="isSvgIconEnd && svgIconEndContent"
|
||||
class="ui-input-icon-end has-svg"
|
||||
:class="iconColorClass"
|
||||
v-html="svgIconEndContent"
|
||||
/>
|
||||
<span v-if="prefixEnd" class="ui-input-prefix-end" :class="prefixColorClass">{{ prefixEnd }}</span>
|
||||
<InputText
|
||||
:id="id"
|
||||
:model-value="displayValue"
|
||||
:class="inputClassesNoBorder"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
:type="inputType"
|
||||
:maxlength="maxlength"
|
||||
:minlength="minlength"
|
||||
:autocomplete="autocomplete"
|
||||
:autofocus="autofocus"
|
||||
:spellcheck="spellcheck"
|
||||
:tabindex="tabindex"
|
||||
@input="handleInput"
|
||||
@change="handleChange"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
@keyup="handleKeyup"
|
||||
@keydown="handleKeydown"
|
||||
/>
|
||||
<span v-if="prefixStart" class="ui-input-prefix-start" :class="prefixColorClass">{{ prefixStart }}</span>
|
||||
<i v-if="actualIconStart" :class="[actualIconStart, iconColorClass]" class="ui-input-icon-start !mt-2"></i>
|
||||
<div
|
||||
v-if="isSvgIconStart && svgIconStartContent"
|
||||
class="ui-input-icon-start has-svg"
|
||||
:class="iconColorClass"
|
||||
v-html="svgIconStartContent"
|
||||
/>
|
||||
<i
|
||||
v-if="showPasswordToggle"
|
||||
:class="[passwordToggleIcon, iconColorClass]"
|
||||
class="ui-input-password-toggle !mt-2 cursor-pointer"
|
||||
@click="togglePasswordVisibility"
|
||||
></i>
|
||||
</div>
|
||||
<div v-else-if="prefix" :class="['.ui-input-wrapper-border', props.wrapperBorderClass, directionClass]">
|
||||
<span class="ui-input-prefix">{{ prefix }}</span>
|
||||
<InputText
|
||||
:id="id"
|
||||
:model-value="displayValue"
|
||||
:class="inputClassesNoBorder"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
:type="inputType"
|
||||
:maxlength="maxlength"
|
||||
:minlength="minlength"
|
||||
:autocomplete="autocomplete"
|
||||
:autofocus="autofocus"
|
||||
:spellcheck="spellcheck"
|
||||
:tabindex="tabindex"
|
||||
@input="handleInput"
|
||||
@change="handleChange"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
@keyup="handleKeyup"
|
||||
@keydown="handleKeydown"
|
||||
/>
|
||||
<i
|
||||
v-if="showPasswordToggle"
|
||||
:class="[passwordToggleIcon, iconColorClass]"
|
||||
class="ui-input-password-toggle !mt-2 cursor-pointer"
|
||||
@click="togglePasswordVisibility"
|
||||
></i>
|
||||
</div>
|
||||
<div v-else class="relative">
|
||||
<InputText
|
||||
:id="id"
|
||||
:model-value="displayValue"
|
||||
:class="inputClasses"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
:type="inputType"
|
||||
:maxlength="maxlength"
|
||||
:minlength="minlength"
|
||||
:autocomplete="autocomplete"
|
||||
:autofocus="autofocus"
|
||||
:spellcheck="spellcheck"
|
||||
:tabindex="tabindex"
|
||||
@input="handleInput"
|
||||
@change="handleChange"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
@keyup="handleKeyup"
|
||||
@keydown="handleKeydown"
|
||||
/>
|
||||
<i
|
||||
v-if="showPasswordToggle"
|
||||
:class="[passwordToggleIcon, iconColorClass]"
|
||||
class="ui-input-password-toggle absolute top-1/2 left-3 transform -translate-y-1/2 cursor-pointer"
|
||||
@click="togglePasswordVisibility"
|
||||
></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<small v-if="error" class="ui-input-error-message">
|
||||
{{ error }}
|
||||
</small>
|
||||
|
||||
<small v-if="hint" class="ui-input-hint-message">
|
||||
{{ hint }}
|
||||
</small>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import InputText from 'primevue/inputtext'
|
||||
import { convertPersianToEnglish } from '../../utils/numberUtils.js'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text',
|
||||
validator: (value) => ['text', 'password', 'email', 'number', 'tel', 'url', 'search'].includes(value)
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: () => `input-${Math.random().toString(36).substr(2, 9)}`
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
error: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
hint: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
maxlength: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
minlength: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
autocomplete: {
|
||||
type: String,
|
||||
default: 'off'
|
||||
},
|
||||
autofocus: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
spellcheck: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
tabindex: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
validator: (value) => ['small', 'default', 'large'].includes(value)
|
||||
},
|
||||
variant: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
validator: (value) => ['default', 'outlined', 'filled'].includes(value)
|
||||
},
|
||||
customClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
prefix: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
prefixStart: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
prefixEnd: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconStart: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconEnd: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'rtl',
|
||||
validator: (value) => ['rtl', 'ltr'].includes(value)
|
||||
},
|
||||
prefixColor: {
|
||||
type: String,
|
||||
default: 'dominant-700'
|
||||
},
|
||||
iconColor: {
|
||||
type: String,
|
||||
default: 'dominant-700'
|
||||
},
|
||||
passwordDisplayType: {
|
||||
type: String,
|
||||
default: 'dots',
|
||||
validator: (value) => ['default', 'dots', 'asterisks'].includes(value)
|
||||
},
|
||||
convertPersianNumbers: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
wrapperBorderClass: {
|
||||
type: String,
|
||||
default: 'ui-input-wrapper-border'
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:modelValue',
|
||||
'input',
|
||||
'change',
|
||||
'focus',
|
||||
'blur',
|
||||
'keyup',
|
||||
'keydown'
|
||||
])
|
||||
|
||||
const inputValue = ref(props.modelValue)
|
||||
const passwordVisible = ref(false)
|
||||
|
||||
watch(() => props.modelValue, (newValue) => {
|
||||
inputValue.value = newValue
|
||||
})
|
||||
|
||||
watch(inputValue, (newValue) => {
|
||||
emit('update:modelValue', newValue)
|
||||
})
|
||||
|
||||
const directionClass = computed(() => {
|
||||
return props.direction === 'ltr' ? 'ui-input--ltr' : 'ui-input--rtl'
|
||||
})
|
||||
|
||||
const hasPrefixes = computed(() => {
|
||||
return props.prefixStart || props.prefixEnd || props.iconStart || props.iconEnd
|
||||
})
|
||||
|
||||
const isSvgIconStart = computed(() => {
|
||||
return props.iconStart && props.iconStart.startsWith('svg:')
|
||||
})
|
||||
|
||||
const isSvgIconEnd = computed(() => {
|
||||
return props.iconEnd && props.iconEnd.startsWith('svg:')
|
||||
})
|
||||
|
||||
const svgIconStartName = computed(() => {
|
||||
return isSvgIconStart.value ? props.iconStart.replace('svg:', '') : ''
|
||||
})
|
||||
|
||||
const svgIconEndName = computed(() => {
|
||||
return isSvgIconEnd.value ? props.iconEnd.replace('svg:', '') : ''
|
||||
})
|
||||
|
||||
const actualIconStart = computed(() => {
|
||||
return isSvgIconStart.value ? '' : props.iconStart
|
||||
})
|
||||
|
||||
const actualIconEnd = computed(() => {
|
||||
return isSvgIconEnd.value ? '' : props.iconEnd
|
||||
})
|
||||
|
||||
const showPasswordToggle = computed(() => {
|
||||
return props.type === 'password'
|
||||
})
|
||||
|
||||
const inputType = computed(() => {
|
||||
if (props.type === 'password') {
|
||||
if (passwordVisible.value || props.passwordDisplayType !== 'default') {
|
||||
return 'text'
|
||||
}
|
||||
return 'password'
|
||||
}
|
||||
return props.type
|
||||
})
|
||||
|
||||
const displayValue = computed(() => {
|
||||
if (props.type === 'password' && !passwordVisible.value && inputValue.value) {
|
||||
if (props.passwordDisplayType === 'dots') {
|
||||
return '•'.repeat(inputValue.value.length)
|
||||
} else if (props.passwordDisplayType === 'asterisks') {
|
||||
return '*'.repeat(inputValue.value.length)
|
||||
}
|
||||
}
|
||||
return inputValue.value
|
||||
})
|
||||
|
||||
const passwordToggleIcon = computed(() => {
|
||||
return passwordVisible.value ? 'fi-rr-eye-crossed' : 'fi-rr-eye'
|
||||
})
|
||||
|
||||
const prefixClasses = computed(() => {
|
||||
const classes = [directionClass.value]
|
||||
|
||||
if (props.prefixStart) classes.push('ui-input-with-prefix-start')
|
||||
if (props.prefixEnd) classes.push('ui-input-with-prefix-end')
|
||||
if (props.iconStart || isSvgIconStart.value) classes.push('ui-input-with-icon-start')
|
||||
if (props.iconEnd || isSvgIconEnd.value) classes.push('ui-input-with-icon-end')
|
||||
if (showPasswordToggle.value) classes.push('ui-input-with-password-toggle')
|
||||
|
||||
if (props.wrapperBorderClass) {
|
||||
classes.push(props.wrapperBorderClass + ' ui-input-wrapper-border')
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
|
||||
const prefixColorClass = computed(() => {
|
||||
return `text-${props.prefixColor}`
|
||||
})
|
||||
|
||||
const iconColorClass = computed(() => {
|
||||
return `text-${props.iconColor}`
|
||||
})
|
||||
|
||||
const loadSvgContent = async (svgName) => {
|
||||
try {
|
||||
const svgModule = await import(`../../components/svg/${svgName}.svg?raw`)
|
||||
return svgModule.default
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const svgIconStartContent = ref('')
|
||||
const svgIconEndContent = ref('')
|
||||
|
||||
watch(() => svgIconStartName.value, async (newName) => {
|
||||
if (newName) {
|
||||
const content = await loadSvgContent(newName)
|
||||
svgIconStartContent.value = content
|
||||
} else {
|
||||
svgIconStartContent.value = ''
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
watch(() => svgIconEndName.value, async (newName) => {
|
||||
if (newName) {
|
||||
const content = await loadSvgContent(newName)
|
||||
svgIconEndContent.value = content
|
||||
} else {
|
||||
svgIconEndContent.value = ''
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
const togglePasswordVisibility = () => {
|
||||
passwordVisible.value = !passwordVisible.value
|
||||
}
|
||||
|
||||
const inputClassesNoBorder = computed(() => {
|
||||
const classes = []
|
||||
|
||||
switch (props.size) {
|
||||
case 'small':
|
||||
classes.push('p-2', 'text-xs')
|
||||
break
|
||||
case 'large':
|
||||
classes.push('p-4', 'text-base')
|
||||
break
|
||||
default:
|
||||
classes.push('p-3', 'text-sm')
|
||||
}
|
||||
|
||||
if (props.variant === 'filled') {
|
||||
classes.push('bg-gray-100')
|
||||
}
|
||||
|
||||
if (props.error) {
|
||||
classes.push('border-red-500')
|
||||
}
|
||||
|
||||
if (props.disabled) {
|
||||
classes.push('opacity-50', 'cursor-not-allowed')
|
||||
}
|
||||
|
||||
if (props.customClass) {
|
||||
classes.push(props.customClass)
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
|
||||
const inputClasses = computed(() => {
|
||||
const classes = []
|
||||
|
||||
switch (props.size) {
|
||||
case 'small':
|
||||
classes.push('p-2', 'text-xs')
|
||||
break
|
||||
case 'large':
|
||||
classes.push('p-4', 'text-base')
|
||||
break
|
||||
default:
|
||||
classes.push('p-3', 'text-sm')
|
||||
}
|
||||
|
||||
switch (props.variant) {
|
||||
case 'outlined':
|
||||
classes.push('border-2')
|
||||
break
|
||||
case 'filled':
|
||||
classes.push('bg-gray-100')
|
||||
break
|
||||
default:
|
||||
classes.push('border')
|
||||
}
|
||||
|
||||
if (props.error) {
|
||||
classes.push('border-red-500')
|
||||
}
|
||||
|
||||
if (props.disabled) {
|
||||
classes.push('opacity-50', 'cursor-not-allowed')
|
||||
}
|
||||
|
||||
if (props.customClass) {
|
||||
classes.push(props.customClass)
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
|
||||
const handleInput = (event) => {
|
||||
let newValue = event.target.value
|
||||
|
||||
if (props.convertPersianNumbers) {
|
||||
newValue = convertPersianToEnglish(newValue)
|
||||
event.target.value = newValue
|
||||
}
|
||||
|
||||
if (props.type === 'password' && !passwordVisible.value && props.passwordDisplayType !== 'default') {
|
||||
const currentLength = inputValue.value.length
|
||||
const newLength = newValue.length
|
||||
|
||||
if (newLength > currentLength) {
|
||||
inputValue.value = inputValue.value + newValue.slice(currentLength)
|
||||
} else if (newLength < currentLength) {
|
||||
inputValue.value = inputValue.value.slice(0, newLength)
|
||||
}
|
||||
} else {
|
||||
inputValue.value = newValue
|
||||
}
|
||||
emit('input', event)
|
||||
}
|
||||
|
||||
const handleChange = (event) => {
|
||||
emit('change', event)
|
||||
}
|
||||
|
||||
const handleFocus = (event) => {
|
||||
emit('focus', event)
|
||||
}
|
||||
|
||||
const handleBlur = (event) => {
|
||||
emit('blur', event)
|
||||
}
|
||||
|
||||
const handleKeyup = (event) => {
|
||||
emit('keyup', event)
|
||||
}
|
||||
|
||||
const handleKeydown = (event) => {
|
||||
emit('keydown', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,613 @@
|
||||
<template>
|
||||
<div class="ui-input-dropdown-wrapper" :class="directionClass" ref="wrapperEl">
|
||||
<label v-if="label" :for="id" class="ui-input-label">
|
||||
{{ label }}
|
||||
<span v-if="required" class="ui-input-required-indicator">*</span>
|
||||
</label>
|
||||
|
||||
<div class="ui-input">
|
||||
<div v-if="hasPrefixes" class="ui-input-wrapper-border" :class="prefixClasses">
|
||||
<i v-if="iconEnd" :class="[iconEnd, iconColorClass]" class="ui-input-icon-end !mt-2"></i>
|
||||
<span v-if="prefixEnd" class="ui-input-prefix-end" :class="prefixColorClass">{{ prefixEnd }}</span>
|
||||
|
||||
<InputText
|
||||
:id="id"
|
||||
v-model="inputValue"
|
||||
:class="inputClassesNoBorder"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
:type="type"
|
||||
:maxlength="maxlength"
|
||||
:minlength="minlength"
|
||||
:autocomplete="autocomplete"
|
||||
:autofocus="autofocus"
|
||||
:spellcheck="spellcheck"
|
||||
:tabindex="tabindex"
|
||||
@input="handleInput"
|
||||
@change="handleChange"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
@keyup="handleKeyup"
|
||||
@keydown="handleKeydown"
|
||||
/>
|
||||
|
||||
<button
|
||||
v-if="props.prefixOptions.length > 0"
|
||||
ref="buttonRef"
|
||||
type="button"
|
||||
class="ui-input-prefix-dropdown-button"
|
||||
:class="prefixColorClass"
|
||||
@click="toggleDropdown"
|
||||
>
|
||||
|
||||
<pre class="ui-input-prefix-text">{{ selectedPrefix.prefix }}</pre>
|
||||
<i v-if="selectedPrefix.icon" :class="selectedPrefix.icon" class="ui-input-prefix-icon"></i>
|
||||
</button>
|
||||
|
||||
<i v-if="iconStart" :class="[iconStart, iconColorClass]" class="ui-input-icon-start !mt-2"></i>
|
||||
</div>
|
||||
|
||||
<InputText
|
||||
v-else
|
||||
:id="id"
|
||||
v-model="inputValue"
|
||||
:class="inputClasses"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
:type="type"
|
||||
:maxlength="maxlength"
|
||||
:minlength="minlength"
|
||||
:autocomplete="autocomplete"
|
||||
:autofocus="autofocus"
|
||||
:spellcheck="spellcheck"
|
||||
:tabindex="tabindex"
|
||||
@input="handleInput"
|
||||
@change="handleChange"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
@keyup="handleKeyup"
|
||||
@keydown="handleKeydown"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Transition
|
||||
name="dropdown"
|
||||
@enter="onDropdownEnter"
|
||||
@leave="onDropdownLeave"
|
||||
@after-leave="onDropdownAfterLeave"
|
||||
>
|
||||
<div
|
||||
v-if="isDropdownOpen && props.prefixOptions.length > 0"
|
||||
ref="dropdownRef"
|
||||
class="ui-input-dropdown-menu"
|
||||
:class="[ `ui-input-dropdown-menu--${dropdownPosition}`, dropdownDirectionClass, dropdownTextAlignClass, dropdownClass ]"
|
||||
>
|
||||
<div v-if="showSearch" class="ui-input-dropdown-search" :class="dropdownSearchWrapperClass">
|
||||
<InputText
|
||||
v-model="searchQuery"
|
||||
:placeholder="searchPlaceholder"
|
||||
class="ui-input-dropdown-search-input"
|
||||
:class="dropdownSearchInputClass"
|
||||
@input="handleSearch"
|
||||
/>
|
||||
</div>
|
||||
<div class="ui-input-dropdown-list">
|
||||
<button
|
||||
v-for="item in filteredOptions"
|
||||
:key="item.value"
|
||||
type="button"
|
||||
class="ui-input-dropdown-item"
|
||||
:class="[ selectedPrefix.value === item.value ? 'ui-input-dropdown-item-selected' : '', dropdownItemClass, selectedPrefix.value === item.value ? dropdownItemSelectedClass : '' ]"
|
||||
@click="selectOption(item)"
|
||||
>
|
||||
<i v-if="item.icon" :class="item.icon" class="ui-input-dropdown-item-icon"></i>
|
||||
|
||||
<span class="ui-input-dropdown-item-label">{{ item.enLabel }}</span>
|
||||
<span class="ui-input-dropdown-item-prefix">({{ item.prefix }})</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<small v-if="error" class="ui-input-error-message">
|
||||
{{ error }}
|
||||
</small>
|
||||
|
||||
<small v-if="hint" class="ui-input-hint-message">
|
||||
{{ hint }}
|
||||
</small>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
|
||||
import InputText from 'primevue/inputtext'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium',
|
||||
validator: (value) => ['small', 'medium', 'large'].includes(value)
|
||||
},
|
||||
variant: {
|
||||
type: String,
|
||||
default: 'outlined',
|
||||
validator: (value) => ['outlined', 'filled'].includes(value)
|
||||
},
|
||||
error: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
hint: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
maxlength: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
minlength: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
autocomplete: {
|
||||
type: String,
|
||||
default: 'off'
|
||||
},
|
||||
autofocus: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
spellcheck: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
tabindex: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
customClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
prefixEnd: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconStart: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconEnd: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
prefixStart: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'rtl',
|
||||
validator: (value) => ['rtl', 'ltr'].includes(value)
|
||||
},
|
||||
prefixColor: {
|
||||
type: String,
|
||||
default: 'dominant-700'
|
||||
},
|
||||
iconColor: {
|
||||
type: String,
|
||||
default: 'dominant-700'
|
||||
},
|
||||
showSearch: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
searchPlaceholder: {
|
||||
type: String,
|
||||
default: 'جستجو...'
|
||||
},
|
||||
dropdownDirection: {
|
||||
type: String,
|
||||
default: '',
|
||||
validator: (value) => ['', 'rtl', 'ltr'].includes(value)
|
||||
},
|
||||
dropdownTextAlign: {
|
||||
type: String,
|
||||
default: '',
|
||||
validator: (value) => ['', 'left', 'right', 'start', 'end'].includes(value)
|
||||
},
|
||||
dropdownClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dropdownSearchWrapperClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dropdownSearchInputClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dropdownItemClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dropdownItemSelectedClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
prefixOptions: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
validator: (value) => {
|
||||
return value.every(item =>
|
||||
typeof item === 'object' &&
|
||||
item.value &&
|
||||
item.prefix &&
|
||||
item.label
|
||||
)
|
||||
}
|
||||
},
|
||||
defaultPrefixValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:modelValue',
|
||||
'input',
|
||||
'change',
|
||||
'focus',
|
||||
'blur',
|
||||
'keyup',
|
||||
'keydown',
|
||||
'prefix-change'
|
||||
])
|
||||
|
||||
const inputValue = ref(props.modelValue)
|
||||
const isDropdownOpen = ref(false)
|
||||
const isDropdownClosing = ref(false)
|
||||
const searchQuery = ref('')
|
||||
const dropdownPosition = ref('bottom')
|
||||
const dropdownRef = ref(null)
|
||||
const buttonRef = ref(null)
|
||||
const wrapperEl = ref(null)
|
||||
|
||||
const id = `input-${Math.random().toString(36).substr(2, 9)}`
|
||||
|
||||
const directionClass = computed(() => {
|
||||
return `ui-input--${props.direction}`
|
||||
})
|
||||
|
||||
const hasPrefixes = computed(() => {
|
||||
return props.prefixOptions.length > 0 || props.prefixEnd || props.prefixStart || props.iconStart || props.iconEnd
|
||||
})
|
||||
|
||||
const prefixClasses = computed(() => {
|
||||
const classes = []
|
||||
|
||||
if (props.prefixOptions.length > 0) {
|
||||
classes.push('ui-input-with-prefixes')
|
||||
}
|
||||
|
||||
if (props.prefixEnd) {
|
||||
classes.push('ui-input-with-prefix-end')
|
||||
}
|
||||
|
||||
if (props.iconStart) {
|
||||
classes.push('ui-input-with-icon-start')
|
||||
}
|
||||
|
||||
if (props.iconEnd) {
|
||||
classes.push('ui-input-with-icon-end')
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
|
||||
const prefixColorClass = computed(() => {
|
||||
return `text-${props.prefixColor}`
|
||||
})
|
||||
|
||||
const iconColorClass = computed(() => {
|
||||
return `text-${props.iconColor}`
|
||||
})
|
||||
|
||||
const effectiveDropdownDirection = computed(() => {
|
||||
return props.dropdownDirection || props.direction
|
||||
})
|
||||
|
||||
const dropdownDirectionClass = computed(() => {
|
||||
return `ui-input-dropdown--${effectiveDropdownDirection.value}`
|
||||
})
|
||||
|
||||
const dropdownTextAlignClass = computed(() => {
|
||||
if (props.dropdownTextAlign === 'left') return 'text-left'
|
||||
if (props.dropdownTextAlign === 'right') return 'text-right'
|
||||
if (props.dropdownTextAlign === 'start') {
|
||||
return effectiveDropdownDirection.value === 'rtl' ? 'text-right' : 'text-left'
|
||||
}
|
||||
if (props.dropdownTextAlign === 'end') {
|
||||
return effectiveDropdownDirection.value === 'rtl' ? 'text-left' : 'text-right'
|
||||
}
|
||||
return effectiveDropdownDirection.value === 'rtl' ? 'text-right' : 'text-left'
|
||||
})
|
||||
|
||||
const selectedPrefix = computed(() => {
|
||||
if (props.defaultPrefixValue) {
|
||||
const found = props.prefixOptions.find(option => option.value === props.defaultPrefixValue)
|
||||
if (found) return found
|
||||
}
|
||||
return props.prefixOptions[0] || { value: '', prefix: '', label: '', icon: '' }
|
||||
})
|
||||
|
||||
const filteredOptions = computed(() => {
|
||||
if (!searchQuery.value) return props.prefixOptions
|
||||
|
||||
const query = searchQuery.value.toLowerCase().trim()
|
||||
|
||||
if (query.length <= 2) {
|
||||
return props.prefixOptions.filter(option =>
|
||||
option.prefix.startsWith(query) ||
|
||||
option.value.toLowerCase().startsWith(query)
|
||||
)
|
||||
}
|
||||
|
||||
return props.prefixOptions.filter(option => {
|
||||
if (option.prefix === query ||
|
||||
option.value.toLowerCase() === query ||
|
||||
option.label.toLowerCase() === query ||
|
||||
(option.enLabel && option.enLabel.toLowerCase() === query)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (option.prefix.startsWith(query) ||
|
||||
option.label.toLowerCase().startsWith(query) ||
|
||||
(option.enLabel && option.enLabel.toLowerCase().startsWith(query))) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (option.label.toLowerCase().includes(query) ||
|
||||
(option.enLabel && option.enLabel.toLowerCase().includes(query)) ||
|
||||
option.prefix.includes(query) ||
|
||||
option.value.toLowerCase().includes(query)) {
|
||||
return true
|
||||
}
|
||||
|
||||
const cleanQuery = query.replace(/[\s\-_\-]/g, '')
|
||||
const cleanLabel = option.label.replace(/[\s\-_\-]/g, '').toLowerCase()
|
||||
const cleanEnLabel = option.enLabel ? option.enLabel.replace(/[\s\-_\-]/g, '').toLowerCase() : ''
|
||||
|
||||
if (cleanLabel.includes(cleanQuery) ||
|
||||
cleanEnLabel.includes(cleanQuery)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
})
|
||||
|
||||
const inputClasses = computed(() => {
|
||||
const classes = []
|
||||
|
||||
switch (props.size) {
|
||||
case 'small':
|
||||
classes.push('p-2', 'text-xs')
|
||||
break
|
||||
case 'large':
|
||||
classes.push('p-4', 'text-base')
|
||||
break
|
||||
default:
|
||||
classes.push('p-3', 'text-sm')
|
||||
}
|
||||
|
||||
if (props.variant === 'filled') {
|
||||
classes.push('bg-gray-100')
|
||||
}
|
||||
|
||||
if (props.error) {
|
||||
classes.push('border-red-500')
|
||||
}
|
||||
|
||||
if (props.disabled) {
|
||||
classes.push('opacity-50', 'cursor-not-allowed')
|
||||
}
|
||||
|
||||
if (props.customClass) {
|
||||
classes.push(props.customClass)
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
|
||||
const inputClassesNoBorder = computed(() => {
|
||||
const classes = []
|
||||
|
||||
switch (props.size) {
|
||||
case 'small':
|
||||
classes.push('p-2', 'text-xs')
|
||||
break
|
||||
case 'large':
|
||||
classes.push('p-4', 'text-base')
|
||||
break
|
||||
default:
|
||||
classes.push('p-3', 'text-sm')
|
||||
}
|
||||
|
||||
if (props.variant === 'filled') {
|
||||
classes.push('bg-gray-100')
|
||||
}
|
||||
|
||||
if (props.error) {
|
||||
classes.push('border-red-500')
|
||||
}
|
||||
|
||||
if (props.disabled) {
|
||||
classes.push('opacity-50', 'cursor-not-allowed')
|
||||
}
|
||||
|
||||
if (props.customClass) {
|
||||
classes.push(props.customClass)
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
|
||||
watch(() => props.modelValue, (newValue) => {
|
||||
inputValue.value = newValue
|
||||
})
|
||||
|
||||
watch(inputValue, (newValue) => {
|
||||
emit('update:modelValue', newValue)
|
||||
})
|
||||
|
||||
const calculateDropdownPosition = () => {
|
||||
if (!buttonRef.value || !dropdownRef.value) return 'bottom'
|
||||
|
||||
const buttonRect = buttonRef.value.getBoundingClientRect()
|
||||
const dropdownHeight = 300 // تقریبی ارتفاع dropdown
|
||||
const windowHeight = window.innerHeight
|
||||
const spaceBelow = windowHeight - buttonRect.bottom
|
||||
const spaceAbove = buttonRect.top
|
||||
|
||||
if (spaceBelow < dropdownHeight && spaceAbove > spaceBelow) {
|
||||
return 'top'
|
||||
}
|
||||
return 'bottom'
|
||||
}
|
||||
|
||||
const toggleDropdown = () => {
|
||||
if (props.disabled) return
|
||||
|
||||
if (isDropdownOpen.value) {
|
||||
closeDropdown()
|
||||
} else {
|
||||
openDropdown()
|
||||
}
|
||||
}
|
||||
|
||||
const openDropdown = () => {
|
||||
isDropdownClosing.value = false
|
||||
isDropdownOpen.value = true
|
||||
searchQuery.value = ''
|
||||
nextTick(() => {
|
||||
dropdownPosition.value = calculateDropdownPosition()
|
||||
const searchInput = document.querySelector('.ui-input-dropdown-search-input')
|
||||
if (searchInput) searchInput.focus()
|
||||
})
|
||||
}
|
||||
|
||||
const closeDropdown = () => {
|
||||
isDropdownClosing.value = true
|
||||
isDropdownOpen.value = false
|
||||
searchQuery.value = ''
|
||||
}
|
||||
|
||||
const onDropdownEnter = (el) => {
|
||||
el.style.animation = 'dropdownSlideIn 0.3s cubic-bezier(0.4, 0, 0.2, 1)'
|
||||
}
|
||||
|
||||
const onDropdownLeave = (el) => {
|
||||
el.style.animation = 'dropdownSlideOut 0.2s cubic-bezier(0.4, 0, 0.2, 1)'
|
||||
}
|
||||
|
||||
const onDropdownAfterLeave = () => {
|
||||
isDropdownClosing.value = false
|
||||
}
|
||||
|
||||
const closeOnOutsideClick = (event) => {
|
||||
const root = event.target.closest('.ui-input-dropdown-wrapper')
|
||||
if (!root || root !== wrapperEl.value) {
|
||||
closeDropdown()
|
||||
}
|
||||
}
|
||||
|
||||
const onKeydown = (event) => {
|
||||
if (event.key === 'Escape') {
|
||||
closeDropdown()
|
||||
}
|
||||
}
|
||||
|
||||
const selectOption = (option) => {
|
||||
emit('prefix-change', option)
|
||||
closeDropdown()
|
||||
}
|
||||
|
||||
const handleSearch = () => {
|
||||
|
||||
}
|
||||
|
||||
const handleInput = (event) => {
|
||||
emit('input', event)
|
||||
}
|
||||
|
||||
const handleChange = (event) => {
|
||||
emit('change', event)
|
||||
}
|
||||
|
||||
const handleFocus = (event) => {
|
||||
emit('focus', event)
|
||||
}
|
||||
|
||||
const handleBlur = (event) => {
|
||||
emit('blur', event)
|
||||
}
|
||||
|
||||
const handleKeyup = (event) => {
|
||||
emit('keyup', event)
|
||||
}
|
||||
|
||||
const handleKeydown = (event) => {
|
||||
emit('keydown', event)
|
||||
}
|
||||
|
||||
const handleWindowResize = () => {
|
||||
if (isDropdownOpen.value) {
|
||||
dropdownPosition.value = calculateDropdownPosition()
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', handleWindowResize)
|
||||
document.addEventListener('click', closeOnOutsideClick, true)
|
||||
document.addEventListener('keydown', onKeydown)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleWindowResize)
|
||||
document.removeEventListener('click', closeOnOutsideClick, true)
|
||||
document.removeEventListener('keydown', onKeydown)
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,300 @@
|
||||
<template>
|
||||
<div class="ui-select-wrapper" :class="directionClass">
|
||||
<label v-if="label" :for="id" class="ui-select-label">
|
||||
{{ label }}
|
||||
<span v-if="required" class="ui-select-required-indicator">*</span>
|
||||
</label>
|
||||
|
||||
<div class="ui-select">
|
||||
<div v-if="hasPrefixes" class="ui-select-wrapper-border" :class="prefixClasses">
|
||||
<template v-if="direction === 'rtl'">
|
||||
<i v-if="iconEnd" :class="[iconEnd, iconColorClass]" class="ui-select-icon-end !mt-2"></i>
|
||||
<span v-if="prefixEnd" class="ui-select-prefix-end" :class="prefixColorClass">{{ prefixEnd }}</span>
|
||||
<Dropdown
|
||||
:id="id"
|
||||
:model-value="internalModelValue"
|
||||
:options="options"
|
||||
:option-label="optionLabel"
|
||||
:option-value="optionValue"
|
||||
:dataKey="optionValue"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:class="selectClassesNoBorder"
|
||||
empty-filter-message="نتیجهای یافت نشد"
|
||||
:empty-message="emptyMessage"
|
||||
:filter="filter"
|
||||
:reset-filter-on-hide="true"
|
||||
:filter-placeholder="filterPlaceholder"
|
||||
:auto-filter-focus="false"
|
||||
:show-clear="showClear"
|
||||
class="ui-select-dropdown"
|
||||
@update:model-value="handleUpdate"
|
||||
@change="handleUpdate"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
/>
|
||||
<span v-if="prefixStart" class="ui-select-prefix-start" :class="prefixColorClass">{{ prefixStart }}</span>
|
||||
<i v-if="iconStart" :class="[iconStart, iconColorClass]" class="ui-select-icon-start !mt-2"></i>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<i v-if="iconStart" :class="[iconStart, iconColorClass]" class="ui-select-icon-start !mt-2"></i>
|
||||
<span v-if="prefixStart" class="ui-select-prefix-start" :class="prefixColorClass">{{ prefixStart }}</span>
|
||||
<Dropdown
|
||||
:id="id"
|
||||
:model-value="internalModelValue"
|
||||
:options="options"
|
||||
:option-label="optionLabel"
|
||||
:option-value="optionValue"
|
||||
:dataKey="optionValue"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:class="selectClassesNoBorder"
|
||||
empty-filter-message="نتیجهای یافت نشد"
|
||||
:empty-message="emptyMessage"
|
||||
:filter="filter"
|
||||
:reset-filter-on-hide="true"
|
||||
:filter-placeholder="filterPlaceholder"
|
||||
:auto-filter-focus="false"
|
||||
:show-clear="showClear"
|
||||
class="ui-select-dropdown"
|
||||
@update:model-value="handleUpdate"
|
||||
@change="handleUpdate"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
/>
|
||||
<span v-if="prefixEnd" class="ui-select-prefix-end" :class="prefixColorClass">{{ prefixEnd }}</span>
|
||||
<i v-if="iconEnd" :class="[iconEnd, iconColorClass]" class="ui-select-icon-end !mt-2"></i>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div v-else-if="prefix" class="ui-select-wrapper-border" :class="directionClass">
|
||||
<span class="ui-select-prefix">{{ prefix }}</span>
|
||||
<Dropdown
|
||||
:id="id"
|
||||
:model-value="internalModelValue"
|
||||
:options="options"
|
||||
:option-label="optionLabel"
|
||||
:option-value="optionValue"
|
||||
:dataKey="optionValue"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:class="selectClassesNoBorder"
|
||||
empty-filter-message="نتیجهای یافت نشد"
|
||||
:empty-message="emptyMessage"
|
||||
:filter="filter"
|
||||
:reset-filter-on-hide="true"
|
||||
:filter-placeholder="filterPlaceholder"
|
||||
:show-clear="showClear"
|
||||
:auto-filter-focus="false"
|
||||
class="ui-select-dropdown"
|
||||
@update:model-value="handleUpdate"
|
||||
@change="handleUpdate"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-else class="relative select">
|
||||
<Dropdown
|
||||
:id="id"
|
||||
:model-value="internalModelValue"
|
||||
:options="options"
|
||||
:option-label="optionLabel"
|
||||
:option-value="optionValue"
|
||||
:dataKey="optionValue"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:class="selectClasses"
|
||||
empty-filter-message="نتیجهای یافت نشد"
|
||||
:empty-message="emptyMessage"
|
||||
:filter="filter"
|
||||
:reset-filter-on-hide="true"
|
||||
:filter-placeholder="filterPlaceholder"
|
||||
:show-clear="showClear"
|
||||
class="ui-select-dropdown"
|
||||
@update:model-value="handleUpdate"
|
||||
@change="handleUpdate"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<small v-if="error" class="ui-select-error-message">{{ error }}</small>
|
||||
<small v-if="hint" class="ui-select-hint-message">{{ hint }}</small>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import Dropdown from 'primevue/dropdown'
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: () => `ui-select-${Math.random().toString(36).substr(2, 9)}`
|
||||
},
|
||||
modelValue: { type: [String, Number, Object, null], default: null },
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
optionLabel: { type: String, default: 'name' },
|
||||
optionValue: { type: String, default: undefined },
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
error: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
hint: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'rtl',
|
||||
validator: (value) => ['rtl', 'ltr'].includes(value)
|
||||
},
|
||||
prefix: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
prefixStart: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
prefixEnd: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
prefixColor: {
|
||||
type: String,
|
||||
default: 'dominant-600'
|
||||
},
|
||||
iconStart: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconEnd: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconColor: {
|
||||
type: String,
|
||||
default: 'dominant-600'
|
||||
},
|
||||
filter: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
filterPlaceholder: {
|
||||
type: String,
|
||||
default: 'جستجو...'
|
||||
},
|
||||
emptyMessage: {
|
||||
type: String,
|
||||
default: 'نتیجهای یافت نشد'
|
||||
},
|
||||
showClear: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue','change','focus','blur'])
|
||||
|
||||
const internalModelValue = computed(() => {
|
||||
if (props.optionValue && props.modelValue && typeof props.modelValue === 'object') {
|
||||
return props.modelValue[props.optionValue]
|
||||
}
|
||||
return props.modelValue
|
||||
})
|
||||
|
||||
const extractValue = (e) => (e && typeof e === 'object' && 'value' in e) ? e.value : e
|
||||
|
||||
const handleUpdate = (e) => {
|
||||
const val = extractValue(e)
|
||||
if (props.optionValue && val !== null && val !== undefined) {
|
||||
const selectedOption = props.options.find(o => o[props.optionValue] === val) ?? null
|
||||
emit('update:modelValue', selectedOption)
|
||||
emit('change', selectedOption)
|
||||
} else {
|
||||
emit('update:modelValue', val)
|
||||
emit('change', val)
|
||||
}
|
||||
}
|
||||
|
||||
const handleFocus = (e) => emit('focus', e)
|
||||
const handleBlur = (e) => emit('blur', e)
|
||||
|
||||
const directionClass = computed(() => {
|
||||
return props.direction === 'ltr' ? 'ui-select--ltr' : 'ui-select--rtl'
|
||||
})
|
||||
|
||||
const hasPrefixes = computed(() => {
|
||||
return props.prefixStart || props.prefixEnd || props.iconStart || props.iconEnd
|
||||
})
|
||||
|
||||
const prefixClasses = computed(() => {
|
||||
const classes = [directionClass.value]
|
||||
|
||||
if (props.prefixStart) classes.push('ui-select-with-prefix-start')
|
||||
if (props.prefixEnd) classes.push('ui-select-with-prefix-end')
|
||||
if (props.iconStart) classes.push('ui-select-with-icon-start')
|
||||
if (props.iconEnd) classes.push('ui-select-with-icon-end')
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
|
||||
const prefixColorClass = computed(() => {
|
||||
return `text-${props.prefixColor}`
|
||||
})
|
||||
|
||||
const iconColorClass = computed(() => {
|
||||
return `text-${props.iconColor}`
|
||||
})
|
||||
|
||||
const selectClassesNoBorder = computed(() => {
|
||||
const classes = []
|
||||
|
||||
if (props.error) {
|
||||
classes.push('has-error')
|
||||
}
|
||||
|
||||
if (props.disabled) {
|
||||
classes.push('disabled')
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
|
||||
const selectClasses = computed(() => {
|
||||
const classes = []
|
||||
|
||||
if (props.error) {
|
||||
classes.push('has-error')
|
||||
}
|
||||
|
||||
if (props.disabled) {
|
||||
classes.push('disabled')
|
||||
}
|
||||
|
||||
return classes.join(' ')
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,284 @@
|
||||
export const countries = [
|
||||
{ value: 'ir', prefix: '+98', label: 'ایران', enLabel: 'Iran', icon: 'fi fi-ir' },
|
||||
{ value: 'af', prefix: '+93', label: 'افغانستان', enLabel: 'Afghanistan', icon: 'fi fi-af' },
|
||||
{ value: 'al', prefix: '+355', label: 'آلبانی', enLabel: 'Albania', icon: 'fi fi-al' },
|
||||
{ value: 'dz', prefix: '+213', label: 'الجزایر', enLabel: 'Algeria', icon: 'fi fi-dz' },
|
||||
{ value: 'ad', prefix: '+376', label: 'آندورا', enLabel: 'Andorra', icon: 'fi fi-ad' },
|
||||
{ value: 'ao', prefix: '+244', label: 'آنگولا', enLabel: 'Angola', icon: 'fi fi-ao' },
|
||||
{ value: 'ag', prefix: '+1268', label: 'آنتیگوا و باربودا', enLabel: 'Antigua and Barbuda', icon: 'fi fi-ag' },
|
||||
{ value: 'ar', prefix: '+54', label: 'آرژانتین', enLabel: 'Argentina', icon: 'fi fi-ar' },
|
||||
{ value: 'am', prefix: '+374', label: 'ارمنستان', enLabel: 'Armenia', icon: 'fi fi-am' },
|
||||
{ value: 'au', prefix: '+61', label: 'استرالیا', enLabel: 'Australia', icon: 'fi fi-au' },
|
||||
{ value: 'at', prefix: '+43', label: 'اتریش', enLabel: 'Austria', icon: 'fi fi-at' },
|
||||
{ value: 'az', prefix: '+994', label: 'جمهوری آذربایجان', enLabel: 'Azerbaijan', icon: 'fi fi-az' },
|
||||
{ value: 'bs', prefix: '+1242', label: 'باهاما', enLabel: 'Bahamas', icon: 'fi fi-bs' },
|
||||
{ value: 'bh', prefix: '+973', label: 'بحرین', enLabel: 'Bahrain', icon: 'fi fi-bh' },
|
||||
{ value: 'bd', prefix: '+880', label: 'بنگلادش', enLabel: 'Bangladesh', icon: 'fi fi-bd' },
|
||||
{ value: 'bb', prefix: '+1246', label: 'باربادوس', enLabel: 'Barbados', icon: 'fi fi-bb' },
|
||||
{ value: 'by', prefix: '+375', label: 'بلاروس', enLabel: 'Belarus', icon: 'fi fi-by' },
|
||||
{ value: 'be', prefix: '+32', label: 'بلژیک', enLabel: 'Belgium', icon: 'fi fi-be' },
|
||||
{ value: 'bz', prefix: '+501', label: 'بلیز', enLabel: 'Belize', icon: 'fi fi-bz' },
|
||||
{ value: 'bj', prefix: '+229', label: 'بنین', enLabel: 'Benin', icon: 'fi fi-bj' },
|
||||
{ value: 'bt', prefix: '+975', label: 'بوتان', enLabel: 'Bhutan', icon: 'fi fi-bt' },
|
||||
{ value: 'bo', prefix: '+591', label: 'بولیوی', enLabel: 'Bolivia', icon: 'fi fi-bo' },
|
||||
{ value: 'ba', prefix: '+387', label: 'بوسنی و هرزگوین', enLabel: 'Bosnia and Herzegovina', icon: 'fi fi-ba' },
|
||||
{ value: 'bw', prefix: '+267', label: 'بوتسوانا', enLabel: 'Botswana', icon: 'fi fi-bw' },
|
||||
{ value: 'br', prefix: '+55', label: 'برزیل', enLabel: 'Brazil', icon: 'fi fi-br' },
|
||||
{ value: 'bn', prefix: '+673', label: 'برونئی', enLabel: 'Brunei', icon: 'fi fi-bn' },
|
||||
{ value: 'bg', prefix: '+359', label: 'بلغارستان', enLabel: 'Bulgaria', icon: 'fi fi-bg' },
|
||||
{ value: 'bf', prefix: '+226', label: 'بورکینافاسو', enLabel: 'Burkina Faso', icon: 'fi fi-bf' },
|
||||
{ value: 'bi', prefix: '+257', label: 'بوروندی', enLabel: 'Burundi', icon: 'fi fi-bi' },
|
||||
{ value: 'kh', prefix: '+855', label: 'کامبوج', enLabel: 'Cambodia', icon: 'fi fi-kh' },
|
||||
{ value: 'cm', prefix: '+237', label: 'کامرون', enLabel: 'Cameroon', icon: 'fi fi-cm' },
|
||||
{ value: 'ca', prefix: '+1', label: 'کانادا', enLabel: 'Canada', icon: 'fi fi-ca' },
|
||||
{ value: 'cv', prefix: '+238', label: 'کیپ ورد', enLabel: 'Cape Verde', icon: 'fi fi-cv' },
|
||||
{ value: 'cf', prefix: '+236', label: 'جمهوری آفریقای مرکزی', enLabel: 'Central African Republic', icon: 'fi fi-cf' },
|
||||
{ value: 'td', prefix: '+235', label: 'چاد', enLabel: 'Chad', icon: 'fi fi-td' },
|
||||
{ value: 'cl', prefix: '+56', label: 'شیلی', enLabel: 'Chile', icon: 'fi fi-cl' },
|
||||
{ value: 'cn', prefix: '+86', label: 'چین', enLabel: 'China', icon: 'fi fi-cn' },
|
||||
{ value: 'co', prefix: '+57', label: 'کلمبیا', enLabel: 'Colombia', icon: 'fi fi-co' },
|
||||
{ value: 'km', prefix: '+269', label: 'کومور', enLabel: 'Comoros', icon: 'fi fi-km' },
|
||||
{ value: 'cg', prefix: '+242', label: 'جمهوری کنگو', enLabel: 'Republic of the Congo', icon: 'fi fi-cg' },
|
||||
{ value: 'cr', prefix: '+506', label: 'کاستاریکا', enLabel: 'Costa Rica', icon: 'fi fi-cr' },
|
||||
{ value: 'hr', prefix: '+385', label: 'کرواسی', enLabel: 'Croatia', icon: 'fi fi-hr' },
|
||||
{ value: 'cu', prefix: '+53', label: 'کوبا', enLabel: 'Cuba', icon: 'fi fi-cu' },
|
||||
{ value: 'cy', prefix: '+357', label: 'قبرس', enLabel: 'Cyprus', icon: 'fi fi-cy' },
|
||||
{ value: 'cz', prefix: '+420', label: 'جمهوری چک', enLabel: 'Czech Republic', icon: 'fi fi-cz' },
|
||||
{ value: 'dk', prefix: '+45', label: 'دانمارک', enLabel: 'Denmark', icon: 'fi fi-dk' },
|
||||
{ value: 'dj', prefix: '+253', label: 'جیبوتی', enLabel: 'Djibouti', icon: 'fi fi-dj' },
|
||||
{ value: 'dm', prefix: '+1767', label: 'دومینیکا', enLabel: 'Dominica', icon: 'fi fi-dm' },
|
||||
{ value: 'do', prefix: '+1809', label: 'جمهوری دومینیکن', enLabel: 'Dominican Republic', icon: 'fi fi-do' },
|
||||
{ value: 'ec', prefix: '+593', label: 'اکوادور', enLabel: 'Ecuador', icon: 'fi fi-ec' },
|
||||
{ value: 'eg', prefix: '+20', label: 'مصر', enLabel: 'Egypt', icon: 'fi fi-eg' },
|
||||
{ value: 'sv', prefix: '+503', label: 'السالوادور', enLabel: 'El Salvador', icon: 'fi fi-sv' },
|
||||
{ value: 'gq', prefix: '+240', label: 'گینه استوایی', enLabel: 'Equatorial Guinea', icon: 'fi fi-gq' },
|
||||
{ value: 'er', prefix: '+291', label: 'اریتره', enLabel: 'Eritrea', icon: 'fi fi-er' },
|
||||
{ value: 'ee', prefix: '+372', label: 'استونی', enLabel: 'Estonia', icon: 'fi fi-ee' },
|
||||
{ value: 'et', prefix: '+251', label: 'اتیوپی', enLabel: 'Ethiopia', icon: 'fi fi-et' },
|
||||
{ value: 'fj', prefix: '+679', label: 'فیجی', enLabel: 'Fiji', icon: 'fi fi-fj' },
|
||||
{ value: 'fi', prefix: '+358', label: 'فنلاند', enLabel: 'Finland', icon: 'fi fi-fi' },
|
||||
{ value: 'fr', prefix: '+33', label: 'فرانسه', enLabel: 'France', icon: 'fi fi-fr' },
|
||||
{ value: 'ga', prefix: '+241', label: 'گابن', enLabel: 'Gabon', icon: 'fi fi-ga' },
|
||||
{ value: 'gm', prefix: '+220', label: 'گامبیا', enLabel: 'Gambia', icon: 'fi fi-gm' },
|
||||
{ value: 'ge', prefix: '+995', label: 'گرجستان', enLabel: 'Georgia', icon: 'fi fi-ge' },
|
||||
{ value: 'de', prefix: '+49', label: 'آلمان', enLabel: 'Germany', icon: 'fi fi-de' },
|
||||
{ value: 'gh', prefix: '+233', label: 'غنا', enLabel: 'Ghana', icon: 'fi fi-gh' },
|
||||
{ value: 'gr', prefix: '+30', label: 'یونان', enLabel: 'Greece', icon: 'fi fi-gr' },
|
||||
{ value: 'gd', prefix: '+1473', label: 'گرنادا', enLabel: 'Grenada', icon: 'fi fi-gd' },
|
||||
{ value: 'gt', prefix: '+502', label: 'گواتمالا', enLabel: 'Guatemala', icon: 'fi fi-gt' },
|
||||
{ value: 'gn', prefix: '+224', label: 'گینه', enLabel: 'Guinea', icon: 'fi fi-gn' },
|
||||
{ value: 'gw', prefix: '+245', label: 'گینه بیسائو', enLabel: 'Guinea-Bissau', icon: 'fi fi-gw' },
|
||||
{ value: 'gy', prefix: '+592', label: 'گویان', enLabel: 'Guyana', icon: 'fi fi-gy' },
|
||||
{ value: 'ht', prefix: '+509', label: 'هائیتی', enLabel: 'Haiti', icon: 'fi fi-ht' },
|
||||
{ value: 'hn', prefix: '+504', label: 'هندوراس', enLabel: 'Honduras', icon: 'fi fi-hn' },
|
||||
{ value: 'hu', prefix: '+36', label: 'مجارستان', enLabel: 'Hungary', icon: 'fi fi-hu' },
|
||||
{ value: 'is', prefix: '+354', label: 'ایسلند', enLabel: 'Iceland', icon: 'fi fi-is' },
|
||||
{ value: 'in', prefix: '+91', label: 'هند', enLabel: 'India', icon: 'fi fi-in' },
|
||||
{ value: 'id', prefix: '+62', label: 'اندونزی', enLabel: 'Indonesia', icon: 'fi fi-id' },
|
||||
{ value: 'iq', prefix: '+964', label: 'عراق', enLabel: 'Iraq', icon: 'fi fi-iq' },
|
||||
{ value: 'ie', prefix: '+353', label: 'ایرلند', enLabel: 'Ireland', icon: 'fi fi-ie' },
|
||||
{ value: 'il', prefix: '+972', label: 'اسرائیل', enLabel: 'Israel', icon: 'fi fi-il' },
|
||||
{ value: 'it', prefix: '+39', label: 'ایتالیا', enLabel: 'Italy', icon: 'fi fi-it' },
|
||||
{ value: 'jm', prefix: '+1876', label: 'جامائیکا', enLabel: 'Jamaica', icon: 'fi fi-jm' },
|
||||
{ value: 'jp', prefix: '+81', label: 'ژاپن', enLabel: 'Japan', icon: 'fi fi-jp' },
|
||||
{ value: 'jo', prefix: '+962', label: 'اردن', enLabel: 'Jordan', icon: 'fi fi-jo' },
|
||||
{ value: 'kz', prefix: '+7', label: 'قزاقستان', enLabel: 'Kazakhstan', icon: 'fi fi-kz' },
|
||||
{ value: 'ke', prefix: '+254', label: 'کنیا', enLabel: 'Kenya', icon: 'fi fi-ke' },
|
||||
{ value: 'ki', prefix: '+686', label: 'کیریباتی', enLabel: 'Kiribati', icon: 'fi fi-ki' },
|
||||
{ value: 'kw', prefix: '+965', label: 'کویت', enLabel: 'Kuwait', icon: 'fi fi-kw' },
|
||||
{ value: 'kg', prefix: '+996', label: 'قرقیزستان', enLabel: 'Kyrgyzstan', icon: 'fi fi-kg' },
|
||||
{ value: 'la', prefix: '+856', label: 'لائوس', enLabel: 'Laos', icon: 'fi fi-la' },
|
||||
{ value: 'lv', prefix: '+371', label: 'لتونی', enLabel: 'Latvia', icon: 'fi fi-lv' },
|
||||
{ value: 'lb', prefix: '+961', label: 'لبنان', enLabel: 'Lebanon', icon: 'fi fi-lb' },
|
||||
{ value: 'ls', prefix: '+266', label: 'لسوتو', enLabel: 'Lesotho', icon: 'fi fi-ls' },
|
||||
{ value: 'lr', prefix: '+231', label: 'لیبریا', enLabel: 'Liberia', icon: 'fi fi-lr' },
|
||||
{ value: 'ly', prefix: '+218', label: 'لیبی', enLabel: 'Libya', icon: 'fi fi-ly' },
|
||||
{ value: 'li', prefix: '+423', label: 'لیختناشتاین', enLabel: 'Liechtenstein', icon: 'fi fi-li' },
|
||||
{ value: 'lt', prefix: '+370', label: 'لیتوانی', enLabel: 'Lithuania', icon: 'fi fi-lt' },
|
||||
{ value: 'lu', prefix: '+352', label: 'لوکزامبورگ', enLabel: 'Luxembourg', icon: 'fi fi-lu' },
|
||||
{ value: 'mg', prefix: '+261', label: 'ماداگاسکار', enLabel: 'Madagascar', icon: 'fi fi-mg' },
|
||||
{ value: 'mw', prefix: '+265', label: 'مالاوی', enLabel: 'Malawi', icon: 'fi fi-mw' },
|
||||
{ value: 'my', prefix: '+60', label: 'مالزی', enLabel: 'Malaysia', icon: 'fi fi-my' },
|
||||
{ value: 'mv', prefix: '+960', label: 'مالدیو', enLabel: 'Maldives', icon: 'fi fi-mv' },
|
||||
{ value: 'ml', prefix: '+223', label: 'مالی', enLabel: 'Mali', icon: 'fi fi-ml' },
|
||||
{ value: 'mt', prefix: '+356', label: 'مالت', enLabel: 'Malta', icon: 'fi fi-mt' },
|
||||
{ value: 'mh', prefix: '+692', label: 'جزایر مارشال', enLabel: 'Marshall Islands', icon: 'fi fi-mh' },
|
||||
{ value: 'mr', prefix: '+222', label: 'موریتانی', enLabel: 'Mauritania', icon: 'fi fi-mr' },
|
||||
{ value: 'mu', prefix: '+230', label: 'موریس', enLabel: 'Mauritius', icon: 'fi fi-mu' },
|
||||
{ value: 'mx', prefix: '+52', label: 'مکزیک', enLabel: 'Mexico', icon: 'fi fi-mx' },
|
||||
{ value: 'fm', prefix: '+691', label: 'میکرونزی', enLabel: 'Micronesia', icon: 'fi fi-fm' },
|
||||
{ value: 'md', prefix: '+373', label: 'مولداوی', enLabel: 'Moldova', icon: 'fi fi-md' },
|
||||
{ value: 'mc', prefix: '+377', label: 'موناکو', enLabel: 'Monaco', icon: 'fi fi-mc' },
|
||||
{ value: 'mn', prefix: '+976', label: 'مغولستان', enLabel: 'Mongolia', icon: 'fi fi-mn' },
|
||||
{ value: 'me', prefix: '+382', label: 'مونتهنگرو', enLabel: 'Montenegro', icon: 'fi fi-me' },
|
||||
{ value: 'ma', prefix: '+212', label: 'مراکش', enLabel: 'Morocco', icon: 'fi fi-ma' },
|
||||
{ value: 'mz', prefix: '+258', label: 'موزامبیک', enLabel: 'Mozambique', icon: 'fi fi-mz' },
|
||||
{ value: 'mm', prefix: '+95', label: 'میانمار', enLabel: 'Myanmar', icon: 'fi fi-mm' },
|
||||
{ value: 'na', prefix: '+264', label: 'نامیبیا', enLabel: 'Namibia', icon: 'fi fi-na' },
|
||||
{ value: 'nr', prefix: '+674', label: 'نائورو', enLabel: 'Nauru', icon: 'fi fi-nr' },
|
||||
{ value: 'np', prefix: '+977', label: 'نپال', enLabel: 'Nepal', icon: 'fi fi-np' },
|
||||
{ value: 'nl', prefix: '+31', label: 'هلند', enLabel: 'Netherlands', icon: 'fi fi-nl' },
|
||||
{ value: 'nz', prefix: '+64', label: 'نیوزیلند', enLabel: 'New Zealand', icon: 'fi fi-nz' },
|
||||
{ value: 'ni', prefix: '+505', label: 'نیکاراگوئه', enLabel: 'Nicaragua', icon: 'fi fi-ni' },
|
||||
{ value: 'ne', prefix: '+227', label: 'نیجر', enLabel: 'Niger', icon: 'fi fi-ne' },
|
||||
{ value: 'ng', prefix: '+234', label: 'نیجریه', enLabel: 'Nigeria', icon: 'fi fi-ng' },
|
||||
{ value: 'no', prefix: '+47', label: 'نروژ', enLabel: 'Norway', icon: 'fi fi-no' },
|
||||
{ value: 'om', prefix: '+968', label: 'عمان', enLabel: 'Oman', icon: 'fi fi-om' },
|
||||
{ value: 'pk', prefix: '+92', label: 'پاکستان', enLabel: 'Pakistan', icon: 'fi fi-pk' },
|
||||
{ value: 'pw', prefix: '+680', label: 'پالائو', enLabel: 'Palau', icon: 'fi fi-pw' },
|
||||
{ value: 'pa', prefix: '+507', label: 'پاناما', enLabel: 'Panama', icon: 'fi fi-pa' },
|
||||
{ value: 'pg', prefix: '+675', label: 'پاپوآ گینه نو', enLabel: 'Papua New Guinea', icon: 'fi fi-pg' },
|
||||
{ value: 'py', prefix: '+595', label: 'پاراگوئه', enLabel: 'Paraguay', icon: 'fi fi-py' },
|
||||
{ value: 'pe', prefix: '+51', label: 'پرو', enLabel: 'Peru', icon: 'fi fi-pe' },
|
||||
{ value: 'ph', prefix: '+63', label: 'فیلیپین', enLabel: 'Philippines', icon: 'fi fi-ph' },
|
||||
{ value: 'pl', prefix: '+48', label: 'لهستان', enLabel: 'Poland', icon: 'fi fi-pl' },
|
||||
{ value: 'pt', prefix: '+351', label: 'پرتغال', enLabel: 'Portugal', icon: 'fi fi-pt' },
|
||||
{ value: 'qa', prefix: '+974', label: 'قطر', enLabel: 'Qatar', icon: 'fi fi-qa' },
|
||||
{ value: 'ro', prefix: '+40', label: 'رومانی', enLabel: 'Romania', icon: 'fi fi-ro' },
|
||||
{ value: 'ru', prefix: '+7', label: 'روسیه', enLabel: 'Russia', icon: 'fi fi-ru' },
|
||||
{ value: 'rw', prefix: '+250', label: 'رواندا', enLabel: 'Rwanda', icon: 'fi fi-rw' },
|
||||
{ value: 'kn', prefix: '+1869', label: 'سنت کیتس و نویس', enLabel: 'Saint Kitts and Nevis', icon: 'fi fi-kn' },
|
||||
{ value: 'lc', prefix: '+1758', label: 'سنت لوسیا', enLabel: 'Saint Lucia', icon: 'fi fi-lc' },
|
||||
{ value: 'vc', prefix: '+1784', label: 'سنت وینسنت و گرنادینها', enLabel: 'Saint Vincent and the Grenadines', icon: 'fi fi-vc' },
|
||||
{ value: 'ws', prefix: '+685', label: 'ساموآ', enLabel: 'Samoa', icon: 'fi fi-ws' },
|
||||
{ value: 'sm', prefix: '+378', label: 'سان مارینو', enLabel: 'San Marino', icon: 'fi fi-sm' },
|
||||
{ value: 'st', prefix: '+239', label: 'سائوتومه و پرینسیپ', enLabel: 'Sao Tome and Principe', icon: 'fi fi-st' },
|
||||
{ value: 'sa', prefix: '+966', label: 'عربستان سعودی', enLabel: 'Saudi Arabia', icon: 'fi fi-sa' },
|
||||
{ value: 'sn', prefix: '+221', label: 'سنگال', enLabel: 'Senegal', icon: 'fi fi-sn' },
|
||||
{ value: 'rs', prefix: '+381', label: 'صربستان', enLabel: 'Serbia', icon: 'fi fi-rs' },
|
||||
{ value: 'sc', prefix: '+248', label: 'سیشل', enLabel: 'Seychelles', icon: 'fi fi-sc' },
|
||||
{ value: 'sl', prefix: '+232', label: 'سیرالئون', enLabel: 'Sierra Leone', icon: 'fi fi-sl' },
|
||||
{ value: 'sg', prefix: '+65', label: 'سنگاپور', enLabel: 'Singapore', icon: 'fi fi-sg' },
|
||||
{ value: 'sk', prefix: '+421', label: 'اسلواکی', enLabel: 'Slovakia', icon: 'fi fi-sk' },
|
||||
{ value: 'si', prefix: '+386', label: 'اسلوونی', enLabel: 'Slovenia', icon: 'fi fi-si' },
|
||||
{ value: 'sb', prefix: '+677', label: 'جزایر سلیمان', enLabel: 'Solomon Islands', icon: 'fi fi-sb' },
|
||||
{ value: 'so', prefix: '+252', label: 'سومالی', enLabel: 'Somalia', icon: 'fi fi-so' },
|
||||
{ value: 'za', prefix: '+27', label: 'آفریقای جنوبی', enLabel: 'South Africa', icon: 'fi fi-za' },
|
||||
{ value: 'kr', prefix: '+82', label: 'کره جنوبی', enLabel: 'South Korea', icon: 'fi fi-kr' },
|
||||
{ value: 'es', prefix: '+34', label: 'اسپانیا', enLabel: 'Spain', icon: 'fi fi-es' },
|
||||
{ value: 'lk', prefix: '+94', label: 'سریلانکا', enLabel: 'Sri Lanka', icon: 'fi fi-lk' },
|
||||
{ value: 'sd', prefix: '+249', label: 'سودان', enLabel: 'Sudan', icon: 'fi fi-sd' },
|
||||
{ value: 'sr', prefix: '+597', label: 'سورینام', enLabel: 'Suriname', icon: 'fi fi-sr' },
|
||||
{ value: 'sz', prefix: '+268', label: 'اسواتینی', enLabel: 'Eswatini', icon: 'fi fi-sz' },
|
||||
{ value: 'se', prefix: '+46', label: 'سوئد', enLabel: 'Sweden', icon: 'fi fi-se' },
|
||||
{ value: 'ch', prefix: '+41', label: 'سوئیس', enLabel: 'Switzerland', icon: 'fi fi-ch' },
|
||||
{ value: 'sy', prefix: '+963', label: 'سوریه', enLabel: 'Syria', icon: 'fi fi-sy' },
|
||||
{ value: 'tw', prefix: '+886', label: 'تایوان', enLabel: 'Taiwan', icon: 'fi fi-tw' },
|
||||
{ value: 'tj', prefix: '+992', label: 'تاجیکستان', enLabel: 'Tajikistan', icon: 'fi fi-tj' },
|
||||
{ value: 'tz', prefix: '+255', label: 'تانزانیا', enLabel: 'Tanzania', icon: 'fi fi-tz' },
|
||||
{ value: 'th', prefix: '+66', label: 'تایلند', enLabel: 'Thailand', icon: 'fi fi-th' },
|
||||
{ value: 'tl', prefix: '+670', label: 'تیمور شرقی', enLabel: 'Timor-Leste', icon: 'fi fi-tl' },
|
||||
{ value: 'tg', prefix: '+228', label: 'توگو', enLabel: 'Togo', icon: 'fi fi-tg' },
|
||||
{ value: 'to', prefix: '+676', label: 'تونگا', enLabel: 'Tonga', icon: 'fi fi-to' },
|
||||
{ value: 'tt', prefix: '+1868', label: 'ترینیداد و توباگو', enLabel: 'Trinidad and Tobago', icon: 'fi fi-tt' },
|
||||
{ value: 'tn', prefix: '+216', label: 'تونس', enLabel: 'Tunisia', icon: 'fi fi-tn' },
|
||||
{ value: 'tr', prefix: '+90', label: 'ترکیه', enLabel: 'Turkey', icon: 'fi fi-tr' },
|
||||
{ value: 'tm', prefix: '+993', label: 'ترکمنستان', enLabel: 'Turkmenistan', icon: 'fi fi-tm' },
|
||||
{ value: 'tv', prefix: '+688', label: 'تووالو', enLabel: 'Tuvalu', icon: 'fi fi-tv' },
|
||||
{ value: 'ug', prefix: '+256', label: 'اوگاندا', enLabel: 'Uganda', icon: 'fi fi-ug' },
|
||||
{ value: 'ua', prefix: '+380', label: 'اوکراین', enLabel: 'Ukraine', icon: 'fi fi-ua' },
|
||||
{ value: 'ae', prefix: '+971', label: 'امارات متحده عربی', enLabel: 'United Arab Emirates', icon: 'fi fi-ae' },
|
||||
{ value: 'gb', prefix: '+44', label: 'انگلیس', enLabel: 'United Kingdom', icon: 'fi fi-gb' },
|
||||
{ value: 'us', prefix: '+1', label: 'آمریکا', enLabel: 'United States', icon: 'fi fi-us' },
|
||||
{ value: 'uy', prefix: '+598', label: 'اروگوئه', enLabel: 'Uruguay', icon: 'fi fi-uy' },
|
||||
{ value: 'uz', prefix: '+998', label: 'ازبکستان', enLabel: 'Uzbekistan', icon: 'fi fi-uz' },
|
||||
{ value: 'vu', prefix: '+678', label: 'وانواتو', enLabel: 'Vanuatu', icon: 'fi fi-vu' },
|
||||
{ value: 'va', prefix: '+379', label: 'واتیکان', enLabel: 'Vatican City', icon: 'fi fi-va' },
|
||||
{ value: 've', prefix: '+58', label: 'ونزوئلا', enLabel: 'Venezuela', icon: 'fi fi-ve' },
|
||||
{ value: 'vn', prefix: '+84', label: 'ویتنام', enLabel: 'Vietnam', icon: 'fi fi-vn' },
|
||||
{ value: 'ye', prefix: '+967', label: 'یمن', enLabel: 'Yemen', icon: 'fi fi-ye' },
|
||||
{ value: 'zm', prefix: '+260', label: 'زامبیا', enLabel: 'Zambia', icon: 'fi fi-zm' },
|
||||
{ value: 'zw', prefix: '+263', label: 'زیمبابوه', enLabel: 'Zimbabwe', icon: 'fi fi-zw' },
|
||||
|
||||
]
|
||||
|
||||
export const searchCountries = (query) => {
|
||||
if (!query) return countries
|
||||
|
||||
const searchTerm = query.toLowerCase().trim()
|
||||
|
||||
return countries.filter(country => {
|
||||
if (country.label.toLowerCase().includes(searchTerm)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (country.enLabel && country.enLabel.toLowerCase().includes(searchTerm)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (country.prefix.includes(searchTerm)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (country.value.toLowerCase().includes(searchTerm)) {
|
||||
return true
|
||||
}
|
||||
|
||||
const persianSearchTerm = searchTerm.replace(/[\s\-_]/g, '')
|
||||
const persianLabel = country.label.replace(/[\s\-_]/g, '').toLowerCase()
|
||||
if (persianLabel.includes(persianSearchTerm)) {
|
||||
return true
|
||||
}
|
||||
|
||||
const englishSearchTerm = searchTerm.replace(/[\s\-_]/g, '')
|
||||
const englishLabel = country.enLabel.replace(/[\s\-_]/g, '').toLowerCase()
|
||||
if (englishLabel.includes(englishSearchTerm)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
export const searchCountriesEnhanced = (query) => {
|
||||
if (!query) return countries
|
||||
|
||||
const searchTerm = query.toLowerCase().trim()
|
||||
|
||||
if (searchTerm.length <= 2) {
|
||||
return countries.filter(country =>
|
||||
country.prefix.startsWith(searchTerm) ||
|
||||
country.value.toLowerCase().startsWith(searchTerm)
|
||||
)
|
||||
}
|
||||
|
||||
return countries.filter(country => {
|
||||
if (country.prefix === searchTerm ||
|
||||
country.value.toLowerCase() === searchTerm ||
|
||||
country.label.toLowerCase() === searchTerm ||
|
||||
country.enLabel.toLowerCase() === searchTerm) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (country.prefix.startsWith(searchTerm) ||
|
||||
country.label.toLowerCase().startsWith(searchTerm) ||
|
||||
country.enLabel.toLowerCase().startsWith(searchTerm)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (country.label.toLowerCase().includes(searchTerm) ||
|
||||
country.enLabel.toLowerCase().includes(searchTerm) ||
|
||||
country.prefix.includes(searchTerm) ||
|
||||
country.value.toLowerCase().includes(searchTerm)) {
|
||||
return true
|
||||
}
|
||||
|
||||
const cleanSearchTerm = searchTerm.replace(/[\s\-_\-]/g, '')
|
||||
const cleanPersianLabel = country.label.replace(/[\s\-_\-]/g, '').toLowerCase()
|
||||
const cleanEnglishLabel = country.enLabel.replace(/[\s\-_\-]/g, '').toLowerCase()
|
||||
|
||||
if (cleanPersianLabel.includes(cleanSearchTerm) ||
|
||||
cleanEnglishLabel.includes(cleanSearchTerm)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
export const findCountryByCode = (code) => {
|
||||
return countries.find(country => country.value === code.toLowerCase())
|
||||
}
|
||||
|
||||
export const findCountryByPrefix = (prefix) => {
|
||||
return countries.find(country => country.prefix === prefix)
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
[
|
||||
{
|
||||
"id": 100,
|
||||
"name": "مرکزی",
|
||||
"slug": "مرکزی",
|
||||
"tel_prefix": "086"
|
||||
},
|
||||
{
|
||||
"id": 101,
|
||||
"name": "گیلان",
|
||||
"slug": "گیلان",
|
||||
"tel_prefix": "013"
|
||||
},
|
||||
{
|
||||
"id": 102,
|
||||
"name": "مازندران",
|
||||
"slug": "مازندران",
|
||||
"tel_prefix": "011"
|
||||
},
|
||||
{
|
||||
"id": 103,
|
||||
"name": "آذربایجان شرقی",
|
||||
"slug": "آذربایجان-شرقی",
|
||||
"tel_prefix": "041"
|
||||
},
|
||||
{
|
||||
"id": 104,
|
||||
"name": "آذربایجان غربی",
|
||||
"slug": "آذربایجان-غربی",
|
||||
"tel_prefix": "044"
|
||||
},
|
||||
{
|
||||
"id": 105,
|
||||
"name": "کرمانشاه",
|
||||
"slug": "کرمانشاه",
|
||||
"tel_prefix": "083"
|
||||
},
|
||||
{
|
||||
"id": 106,
|
||||
"name": "خوزستان",
|
||||
"slug": "خوزستان",
|
||||
"tel_prefix": "061"
|
||||
},
|
||||
{
|
||||
"id": 107,
|
||||
"name": "فارس",
|
||||
"slug": "فارس",
|
||||
"tel_prefix": "071"
|
||||
},
|
||||
{
|
||||
"id": 108,
|
||||
"name": "کرمان",
|
||||
"slug": "کرمان",
|
||||
"tel_prefix": "034"
|
||||
},
|
||||
{
|
||||
"id": 109,
|
||||
"name": "خراسان رضوی",
|
||||
"slug": "خراسان-رضوی",
|
||||
"tel_prefix": "051"
|
||||
},
|
||||
{
|
||||
"id": 110,
|
||||
"name": "اصفهان",
|
||||
"slug": "اصفهان",
|
||||
"tel_prefix": "031"
|
||||
},
|
||||
{
|
||||
"id": 111,
|
||||
"name": "سیستان و بلوچستان",
|
||||
"slug": "سیستان-و-بلوچستان",
|
||||
"tel_prefix": "054"
|
||||
},
|
||||
{
|
||||
"id": 112,
|
||||
"name": "کردستان",
|
||||
"slug": "کردستان",
|
||||
"tel_prefix": "087"
|
||||
},
|
||||
{
|
||||
"id": 113,
|
||||
"name": "همدان",
|
||||
"slug": "همدان",
|
||||
"tel_prefix": "081"
|
||||
},
|
||||
{
|
||||
"id": 114,
|
||||
"name": "چهارمحال و بختیاری",
|
||||
"slug": "چهارمحال-و-بختیاری",
|
||||
"tel_prefix": "038"
|
||||
},
|
||||
{
|
||||
"id": 115,
|
||||
"name": "لرستان",
|
||||
"slug": "لرستان",
|
||||
"tel_prefix": "066"
|
||||
},
|
||||
{
|
||||
"id": 116,
|
||||
"name": "ایلام",
|
||||
"slug": "ایلام",
|
||||
"tel_prefix": "084"
|
||||
},
|
||||
{
|
||||
"id": 117,
|
||||
"name": "کهگیلویه و بویراحمد",
|
||||
"slug": "کهگیلویه-و-بویراحمد",
|
||||
"tel_prefix": "074"
|
||||
},
|
||||
{
|
||||
"id": 118,
|
||||
"name": "بوشهر",
|
||||
"slug": "بوشهر",
|
||||
"tel_prefix": "077"
|
||||
},
|
||||
{
|
||||
"id": 119,
|
||||
"name": "زنجان",
|
||||
"slug": "زنجان",
|
||||
"tel_prefix": "024"
|
||||
},
|
||||
{
|
||||
"id": 120,
|
||||
"name": "سمنان",
|
||||
"slug": "سمنان",
|
||||
"tel_prefix": "023"
|
||||
},
|
||||
{
|
||||
"id": 121,
|
||||
"name": "یزد",
|
||||
"slug": "یزد",
|
||||
"tel_prefix": "035"
|
||||
},
|
||||
{
|
||||
"id": 122,
|
||||
"name": "هرمزگان",
|
||||
"slug": "هرمزگان",
|
||||
"tel_prefix": "076"
|
||||
},
|
||||
{
|
||||
"id": 123,
|
||||
"name": "تهران",
|
||||
"slug": "تهران",
|
||||
"tel_prefix": "021"
|
||||
},
|
||||
{
|
||||
"id": 124,
|
||||
"name": "اردبیل",
|
||||
"slug": "اردبیل",
|
||||
"tel_prefix": "045"
|
||||
},
|
||||
{
|
||||
"id": 125,
|
||||
"name": "قم",
|
||||
"slug": "قم",
|
||||
"tel_prefix": "025"
|
||||
},
|
||||
{
|
||||
"id": 126,
|
||||
"name": "قزوین",
|
||||
"slug": "قزوین",
|
||||
"tel_prefix": "028"
|
||||
},
|
||||
{
|
||||
"id": 127,
|
||||
"name": "گلستان",
|
||||
"slug": "گلستان",
|
||||
"tel_prefix": "017"
|
||||
},
|
||||
{
|
||||
"id": 128,
|
||||
"name": "خراسان شمالی",
|
||||
"slug": "خراسان-شمالی",
|
||||
"tel_prefix": "058"
|
||||
},
|
||||
{
|
||||
"id": 129,
|
||||
"name": "خراسان جنوبی",
|
||||
"slug": "خراسان-جنوبی",
|
||||
"tel_prefix": "056"
|
||||
},
|
||||
{
|
||||
"id": 130,
|
||||
"name": "البرز",
|
||||
"slug": "البرز",
|
||||
"tel_prefix": "026"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,50 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import enAuth from './locales/en/auth.json'
|
||||
import enDashboard from './locales/en/dashboard.json'
|
||||
import enHome from './locales/en/home.json'
|
||||
import enValidation from './locales/en/validation.json'
|
||||
import enErrors from './locales/en/errors.json'
|
||||
import enEnums from './locales/en/enums.json'
|
||||
import enCommon from './locales/en/common.json'
|
||||
|
||||
import faAuth from './locales/fa/auth.json'
|
||||
import faDashboard from './locales/fa/dashboard.json'
|
||||
import faHome from './locales/fa/home.json'
|
||||
import faValidation from './locales/fa/validation.json'
|
||||
import faErrors from './locales/fa/errors.json'
|
||||
import faEnums from './locales/fa/enums.json'
|
||||
import faCommon from './locales/fa/common.json'
|
||||
|
||||
const en = {
|
||||
auth: enAuth,
|
||||
dashboard: enDashboard,
|
||||
home: enHome,
|
||||
validation: enValidation,
|
||||
errors: enErrors,
|
||||
enums: enEnums,
|
||||
common: enCommon
|
||||
}
|
||||
|
||||
const fa = {
|
||||
auth: faAuth,
|
||||
dashboard: faDashboard,
|
||||
home: faHome,
|
||||
validation: faValidation,
|
||||
errors: faErrors,
|
||||
enums: faEnums,
|
||||
common: faCommon
|
||||
}
|
||||
|
||||
const messages = {
|
||||
en,
|
||||
fa
|
||||
}
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'fa',
|
||||
fallbackLocale: 'en',
|
||||
messages,
|
||||
})
|
||||
|
||||
export default i18n
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "Name",
|
||||
"email": "Email",
|
||||
"password": "Password",
|
||||
"password_confirmation": "Confirm Password",
|
||||
"login": {
|
||||
"title": "Sign in to your account",
|
||||
"subtitle": "Enter your credentials to access your account",
|
||||
"remember_me": "Remember me",
|
||||
"forgot_password": "Forgot your password?",
|
||||
"sign_in": "Sign in",
|
||||
"no_account": "Don't have an account?",
|
||||
"sign_up": "Sign up"
|
||||
},
|
||||
"register": {
|
||||
"title": "Create your account",
|
||||
"subtitle": "Join us and start your journey",
|
||||
"agree_terms": "I agree to the",
|
||||
"terms_link": "Terms and Conditions",
|
||||
"sign_up": "Sign up",
|
||||
"already_have_account": "Already have an account?",
|
||||
"sign_in": "Sign in"
|
||||
},
|
||||
"forgot_password": {
|
||||
"title": "Reset your password",
|
||||
"subtitle": "Enter your email address and we'll send you a link to reset your password",
|
||||
"send_reset_link": "Send reset link",
|
||||
"remember_password": "Remember your password?",
|
||||
"back_to_login": "Back to login"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"actions": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"edit": "Edit",
|
||||
"create": "Create",
|
||||
"update": "Update",
|
||||
"submit": "Submit",
|
||||
"reset": "Reset",
|
||||
"back": "Back",
|
||||
"next": "Next",
|
||||
"previous": "Previous",
|
||||
"close": "Close",
|
||||
"open": "Open",
|
||||
"search": "Search",
|
||||
"filter": "Filter",
|
||||
"sort": "Sort",
|
||||
"export": "Export",
|
||||
"import": "Import",
|
||||
"download": "Download",
|
||||
"upload": "Upload"
|
||||
},
|
||||
"status": {
|
||||
"active": "Active",
|
||||
"inactive": "Inactive",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"online": "Online",
|
||||
"offline": "Offline",
|
||||
"available": "Available",
|
||||
"unavailable": "Unavailable"
|
||||
},
|
||||
"messages": {
|
||||
"success": "Success",
|
||||
"error": "Error",
|
||||
"warning": "Warning",
|
||||
"info": "Information",
|
||||
"loading": "Loading...",
|
||||
"no_data": "No data available",
|
||||
"no_results": "No results found"
|
||||
},
|
||||
"time": {
|
||||
"today": "Today",
|
||||
"yesterday": "Yesterday",
|
||||
"tomorrow": "Tomorrow",
|
||||
"this_week": "This week",
|
||||
"last_week": "Last week",
|
||||
"this_month": "This month",
|
||||
"last_month": "Last month",
|
||||
"this_year": "This year",
|
||||
"last_year": "Last year"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"doctor": {
|
||||
"title": "Doctor Dashboard",
|
||||
"subtitle": "Welcome back! Here's what's happening with your patients today.",
|
||||
"total_patients": "Total Patients",
|
||||
"today_appointments": "Today's Appointments",
|
||||
"pending_reports": "Pending Reports",
|
||||
"recent_activity": "Recent Activity",
|
||||
"activity": {
|
||||
"appointment_completed": "Appointment completed with",
|
||||
"report_submitted": "Report submitted for"
|
||||
}
|
||||
},
|
||||
"supervisor": {
|
||||
"title": "Supervisor Dashboard",
|
||||
"subtitle": "Overview of your medical facility and staff performance.",
|
||||
"total_doctors": "Total Doctors",
|
||||
"total_patients": "Total Patients",
|
||||
"today_appointments": "Today's Appointments",
|
||||
"pending_reports": "Pending Reports",
|
||||
"appointments_chart": "Appointments Overview",
|
||||
"doctor_performance": "Doctor Performance",
|
||||
"satisfaction": "Satisfaction Rate",
|
||||
"chart_placeholder": "Chart will be displayed here",
|
||||
"recent_activity": "Recent Activity",
|
||||
"activity": {
|
||||
"new_doctor_joined": "New doctor joined:",
|
||||
"monthly_report_generated": "Monthly report generated"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"user_roles": {
|
||||
"admin": "Administrator",
|
||||
"doctor": "Doctor",
|
||||
"supervisor": "Supervisor",
|
||||
"patient": "Patient"
|
||||
},
|
||||
"appointment_status": {
|
||||
"scheduled": "Scheduled",
|
||||
"confirmed": "Confirmed",
|
||||
"completed": "Completed",
|
||||
"cancelled": "Cancelled",
|
||||
"no_show": "No Show"
|
||||
},
|
||||
"report_status": {
|
||||
"draft": "Draft",
|
||||
"pending": "Pending",
|
||||
"approved": "Approved",
|
||||
"rejected": "Rejected"
|
||||
},
|
||||
"gender": {
|
||||
"male": "Male",
|
||||
"female": "Female",
|
||||
"other": "Other"
|
||||
},
|
||||
"blood_type": {
|
||||
"a_positive": "A+",
|
||||
"a_negative": "A-",
|
||||
"b_positive": "B+",
|
||||
"b_negative": "B-",
|
||||
"ab_positive": "AB+",
|
||||
"ab_negative": "AB-",
|
||||
"o_positive": "O+",
|
||||
"o_negative": "O-"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"general": {
|
||||
"something_went_wrong": "Something went wrong",
|
||||
"try_again": "Please try again",
|
||||
"not_found": "Not found",
|
||||
"unauthorized": "Unauthorized",
|
||||
"forbidden": "Forbidden",
|
||||
"server_error": "Server error"
|
||||
},
|
||||
"auth": {
|
||||
"invalid_credentials": "Invalid email or password",
|
||||
"account_locked": "Your account has been locked",
|
||||
"email_not_verified": "Please verify your email address",
|
||||
"password_reset_sent": "Password reset link has been sent to your email",
|
||||
"password_reset_success": "Password has been reset successfully",
|
||||
"logout_success": "You have been logged out successfully"
|
||||
},
|
||||
"form": {
|
||||
"validation_failed": "Please check the form for errors",
|
||||
"submission_failed": "Failed to submit form",
|
||||
"network_error": "Network error, please check your connection"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"title": "Welcome to Radical Medical System",
|
||||
"subtitle": "A comprehensive healthcare management platform for doctors and supervisors",
|
||||
"get_started": "Get Started",
|
||||
"sign_up": "Sign Up",
|
||||
"for_doctors": {
|
||||
"title": "For Doctors",
|
||||
"description": "Manage your patients, appointments, and medical reports efficiently",
|
||||
"cta": "Access Doctor Dashboard"
|
||||
},
|
||||
"for_supervisors": {
|
||||
"title": "For Supervisors",
|
||||
"description": "Monitor facility performance, staff management, and generate reports",
|
||||
"cta": "Access Supervisor Dashboard"
|
||||
},
|
||||
"multi_language": {
|
||||
"title": "Multi-language Support",
|
||||
"description": "Available in English and Persian languages"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"required": "This field is required",
|
||||
"email": "Please enter a valid email address",
|
||||
"min": "This field must be at least {min} characters",
|
||||
"max": "This field must not exceed {max} characters",
|
||||
"confirmed": "The confirmation does not match",
|
||||
"unique": "This value has already been taken",
|
||||
"numeric": "This field must be a number",
|
||||
"string": "This field must be a string",
|
||||
"date": "This field must be a valid date",
|
||||
"between": {
|
||||
"numeric": "This field must be between {min} and {max}",
|
||||
"string": "This field must be between {min} and {max} characters"
|
||||
},
|
||||
"password": {
|
||||
"min": "Password must be at least {min} characters",
|
||||
"mixed": "Password must contain at least one uppercase and one lowercase letter",
|
||||
"numbers": "Password must contain at least one number",
|
||||
"symbols": "Password must contain at least one symbol"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "نام",
|
||||
"email": "ایمیل",
|
||||
"password": "رمز عبور",
|
||||
"password_confirmation": "تکرار رمز عبور",
|
||||
"phone": {
|
||||
"title": "ورود و ثبتنام",
|
||||
"subtitle": "جهت ادامه، شماره موبایل خود را وارد نمایید."
|
||||
},
|
||||
"ChoosePortal": {
|
||||
"title": "انتخاب پورتال",
|
||||
"subtitle": "جهت ورود با شماره %phone% پورتال مورد نظر را انتخاب نمایید."
|
||||
},
|
||||
"Password": {
|
||||
"title": "ورود به پورتال %userType%",
|
||||
"subtitle": "جهت ادامه، گذرواژه مربوط به پورتال خود را وارد نمایید."
|
||||
},
|
||||
"OtpVerification": {
|
||||
"title": "فرایند بازیابی گذرواژه",
|
||||
"subtitle": "جهت ادامه، کد ارسال شده به شماره موبایل خود را وارد نمایید."
|
||||
},
|
||||
"ResetPassword": {
|
||||
"title": "تنظیم مجدد گذرواژه",
|
||||
"subtitle": "گذرواژه جدید خود را با استفاده از حروف و اعداد وارد و تایید نمایید."
|
||||
},
|
||||
"RegisterSupervisor": {
|
||||
"title": "ثبتنام به عنوان سرپرست",
|
||||
"subtitle": "برای ثبتنام لطفا اطلاعات زیر رو با دقت وارد نمایید."
|
||||
},
|
||||
"RegisterVet": {
|
||||
"title": "ثبتنام به عنوان دامپزشک",
|
||||
"subtitle": "برای ثبتنام لطفا اطلاعات زیر رو با دقت وارد نمایید."
|
||||
},
|
||||
"ChooseRegisterType": {
|
||||
"title": "ثبت نام",
|
||||
"subtitle": "برای استفاده از سامانه میبایست ابتدا ثبتنام کنید. برای ادامه نوع حساب کاربری خود را مشخص نمایید."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"actions": {
|
||||
"save": "ذخیره",
|
||||
"cancel": "لغو",
|
||||
"delete": "حذف",
|
||||
"edit": "ویرایش",
|
||||
"create": "ایجاد",
|
||||
"update": "بروزرسانی",
|
||||
"submit": "ارسال",
|
||||
"reset": "بازنشانی",
|
||||
"back": "بازگشت",
|
||||
"next": "بعدی",
|
||||
"previous": "قبلی",
|
||||
"close": "بستن",
|
||||
"open": "باز کردن",
|
||||
"search": "جستجو",
|
||||
"filter": "فیلتر",
|
||||
"sort": "مرتبسازی",
|
||||
"export": "خروجی",
|
||||
"import": "ورودی",
|
||||
"download": "دانلود",
|
||||
"upload": "آپلود"
|
||||
},
|
||||
"status": {
|
||||
"active": "فعال",
|
||||
"inactive": "غیرفعال",
|
||||
"enabled": "فعال",
|
||||
"disabled": "غیرفعال",
|
||||
"online": "آنلاین",
|
||||
"offline": "آفلاین",
|
||||
"available": "موجود",
|
||||
"unavailable": "ناموجود"
|
||||
},
|
||||
"messages": {
|
||||
"success": "موفقیت",
|
||||
"error": "خطا",
|
||||
"warning": "هشدار",
|
||||
"info": "اطلاعات",
|
||||
"loading": "در حال بارگذاری...",
|
||||
"no_data": "دادهای موجود نیست",
|
||||
"no_results": "نتیجهای یافت نشد"
|
||||
},
|
||||
"time": {
|
||||
"today": "امروز",
|
||||
"yesterday": "دیروز",
|
||||
"tomorrow": "فردا",
|
||||
"this_week": "این هفته",
|
||||
"last_week": "هفته گذشته",
|
||||
"this_month": "این ماه",
|
||||
"last_month": "ماه گذشته",
|
||||
"this_year": "امسال",
|
||||
"last_year": "سال گذشته"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"doctor": {
|
||||
"title": "داشبورد پزشک",
|
||||
"subtitle": "خوش آمدید! اینجا آنچه امروز برای بیماران شما اتفاق میافتد را مشاهده میکنید.",
|
||||
"total_patients": "کل بیماران",
|
||||
"today_appointments": "نوبتهای امروز",
|
||||
"pending_reports": "گزارشات در انتظار",
|
||||
"recent_activity": "فعالیتهای اخیر",
|
||||
"activity": {
|
||||
"appointment_completed": "نوبت با",
|
||||
"report_submitted": "گزارش ارسال شده برای"
|
||||
}
|
||||
},
|
||||
"supervisor": {
|
||||
"title": "داشبورد سرپرست",
|
||||
"subtitle": "نمای کلی از مرکز پزشکی و عملکرد کارکنان.",
|
||||
"total_doctors": "کل پزشکان",
|
||||
"total_patients": "کل بیماران",
|
||||
"today_appointments": "نوبتهای امروز",
|
||||
"pending_reports": "گزارشات در انتظار",
|
||||
"appointments_chart": "نمای کلی نوبتها",
|
||||
"doctor_performance": "عملکرد پزشکان",
|
||||
"satisfaction": "نرخ رضایت",
|
||||
"chart_placeholder": "نمودار اینجا نمایش داده خواهد شد",
|
||||
"recent_activity": "فعالیتهای اخیر",
|
||||
"activity": {
|
||||
"new_doctor_joined": "پزشک جدید پیوست:",
|
||||
"monthly_report_generated": "گزارش ماهانه تولید شد"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"user_roles": {
|
||||
"admin": "مدیر",
|
||||
"doctor": "پزشک",
|
||||
"supervisor": "سرپرست",
|
||||
"patient": "بیمار"
|
||||
},
|
||||
"appointment_status": {
|
||||
"scheduled": "برنامهریزی شده",
|
||||
"confirmed": "تأیید شده",
|
||||
"completed": "تکمیل شده",
|
||||
"cancelled": "لغو شده",
|
||||
"no_show": "حضور نیافته"
|
||||
},
|
||||
"report_status": {
|
||||
"draft": "پیشنویس",
|
||||
"pending": "در انتظار",
|
||||
"approved": "تأیید شده",
|
||||
"rejected": "رد شده"
|
||||
},
|
||||
"gender": {
|
||||
"male": "مرد",
|
||||
"female": "زن",
|
||||
"other": "سایر"
|
||||
},
|
||||
"blood_type": {
|
||||
"a_positive": "A+",
|
||||
"a_negative": "A-",
|
||||
"b_positive": "B+",
|
||||
"b_negative": "B-",
|
||||
"ab_positive": "AB+",
|
||||
"ab_negative": "AB-",
|
||||
"o_positive": "O+",
|
||||
"o_negative": "O-"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"general": {
|
||||
"something_went_wrong": "مشکلی پیش آمد",
|
||||
"try_again": "لطفاً دوباره تلاش کنید",
|
||||
"not_found": "یافت نشد",
|
||||
"unauthorized": "غیرمجاز",
|
||||
"forbidden": "ممنوع",
|
||||
"server_error": "خطای سرور"
|
||||
},
|
||||
"auth": {
|
||||
"invalid_credentials": "ایمیل یا رمز عبور نامعتبر",
|
||||
"account_locked": "حساب کاربری شما قفل شده است",
|
||||
"email_not_verified": "لطفاً آدرس ایمیل خود را تأیید کنید",
|
||||
"password_reset_sent": "لینک بازنشانی رمز عبور به ایمیل شما ارسال شد",
|
||||
"password_reset_success": "رمز عبور با موفقیت بازنشانی شد",
|
||||
"logout_success": "شما با موفقیت خارج شدید"
|
||||
},
|
||||
"form": {
|
||||
"validation_failed": "لطفاً فرم را برای خطاها بررسی کنید",
|
||||
"submission_failed": "ارسال فرم ناموفق بود",
|
||||
"network_error": "خطای شبکه، لطفاً اتصال خود را بررسی کنید"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"title": "به سیستم پزشکی رادیکال خوش آمدید",
|
||||
"subtitle": "پلتفرم جامع مدیریت مراقبتهای بهداشتی برای پزشکان و سرپرستان",
|
||||
"get_started": "شروع کنید",
|
||||
"sign_up": "ثبت نام",
|
||||
"for_doctors": {
|
||||
"title": "برای پزشکان",
|
||||
"description": "بیماران، نوبتها و گزارشات پزشکی خود را به طور کارآمد مدیریت کنید",
|
||||
"cta": "دسترسی به داشبورد پزشک"
|
||||
},
|
||||
"for_supervisors": {
|
||||
"title": "برای سرپرستان",
|
||||
"description": "نظارت بر عملکرد مرکز، مدیریت کارکنان و تولید گزارشات",
|
||||
"cta": "دسترسی به داشبورد سرپرست"
|
||||
},
|
||||
"multi_language": {
|
||||
"title": "پشتیبانی چند زبانه",
|
||||
"description": "در دسترس به زبانهای انگلیسی و فارسی"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"required": "این فیلد الزامی است",
|
||||
"email": "لطفاً یک آدرس ایمیل معتبر وارد کنید",
|
||||
"min": "این فیلد باید حداقل {min} کاراکتر باشد",
|
||||
"max": "این فیلد نباید بیش از {max} کاراکتر باشد",
|
||||
"confirmed": "تکرار مطابقت ندارد",
|
||||
"unique": "این مقدار قبلاً استفاده شده است",
|
||||
"numeric": "این فیلد باید عدد باشد",
|
||||
"string": "این فیلد باید متن باشد",
|
||||
"date": "این فیلد باید تاریخ معتبر باشد",
|
||||
"between": {
|
||||
"numeric": "این فیلد باید بین {min} و {max} باشد",
|
||||
"string": "این فیلد باید بین {min} و {max} کاراکتر باشد"
|
||||
},
|
||||
"password": {
|
||||
"min": "رمز عبور باید حداقل {min} کاراکتر باشد",
|
||||
"mixed": "رمز عبور باید حداقل یک حرف بزرگ و یک حرف کوچک داشته باشد",
|
||||
"numbers": "رمز عبور باید حداقل یک عدد داشته باشد",
|
||||
"symbols": "رمز عبور باید حداقل یک نماد داشته باشد"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<script setup>
|
||||
import { Link } from '@inertiajs/inertia-vue3';
|
||||
import { watch, onMounted, ref } from 'vue';
|
||||
import { usePage } from '@inertiajs/inertia-vue3';
|
||||
import { toast } from 'vue3-toastify';
|
||||
|
||||
const page = usePage();
|
||||
const lastFlash = ref(null);
|
||||
|
||||
const showToast = (type, message) => {
|
||||
if (message) {
|
||||
const toastOptions = {
|
||||
position: 'top-right',
|
||||
rtl: true,
|
||||
theme: 'colored',
|
||||
autoClose: 3000,
|
||||
};
|
||||
|
||||
if (type === 'success') {
|
||||
toast.success(message, toastOptions);
|
||||
} else if (type === 'error') {
|
||||
toast.error(message, toastOptions);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const flash = page.props.value?.flash;
|
||||
if (flash?.success || flash?.error) {
|
||||
lastFlash.value = JSON.stringify(flash);
|
||||
if (flash.success) {
|
||||
showToast('success', flash.success);
|
||||
}
|
||||
if (flash.error) {
|
||||
showToast('error', flash.error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
watch(() => page.props.value?.flash, (newFlash) => {
|
||||
if (newFlash) {
|
||||
const newFlashStr = JSON.stringify(newFlash);
|
||||
if (newFlashStr !== lastFlash.value) {
|
||||
lastFlash.value = newFlashStr;
|
||||
if (newFlash.success) {
|
||||
showToast('success', newFlash.success);
|
||||
}
|
||||
if (newFlash.error) {
|
||||
showToast('error', newFlash.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, { deep: true });
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid grid-cols-a relative grid-rows-[auto] items-center justify-center h-[100svh] w-full bg-dominant-50 content-center">
|
||||
<Link href="/">
|
||||
<figure class="flex justify-center mb-8">
|
||||
<img src="@/images/radical_logo.png" alt="logo" class="w-[125px] h-auto object-cover"></img>
|
||||
</figure>
|
||||
</Link>
|
||||
<slot />
|
||||
<slot name="footer" class=""></slot>
|
||||
<div class="absolute w-full text-center bottom-5 right-0 left-0 m-auto">
|
||||
<p class="text-center text-[13px] max-sm:px-4 max-sm:leading-8 text-dominant-700 font-normal">تمامی حقوق این وبسایت برای مجموعه <span class="font-semibold">تلهرادیولوژی رادیکال</span> محفوظ میباشد.</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,41 @@
|
||||
<script setup>
|
||||
import DialogsProvider from "./DialogsProvider.vue";
|
||||
import SidebarComponent from "../components/sidebar/SidebarComponent.vue";
|
||||
import HeaderComponent from "../components/header/HeaderComponent.vue";
|
||||
import { Transition, onMounted } from 'vue';
|
||||
import { usePage } from '@inertiajs/inertia-vue3';
|
||||
import { useGlobalStore } from "../store/Global";
|
||||
const globalStore = useGlobalStore();
|
||||
const {props} = usePage();
|
||||
|
||||
onMounted(() => {
|
||||
globalStore.current_user = props.value.auth.User;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<sidebar-component />
|
||||
<header-component />
|
||||
<div class="!bg-white">
|
||||
<section class="">
|
||||
<main class="overflow-hidden !ps-[16rem] max-sm:!ps-4 pt-20 min-h-[calc(100svh)] p-4 grid grid-cols-1">
|
||||
<section class="!rounded-2xl border-[1px] border-dominant-50 !bg-dominant-50/50 content-start p-4 grid grid-cols-1">
|
||||
<div v-if="$page.props.flash.success" class="w-full mb-4">
|
||||
<Message size="small" closable class="!text-xs py-1.5" severity="success">{{$page.props.flash.success}}</Message>
|
||||
</div>
|
||||
<Transition
|
||||
name="page-transition"
|
||||
mode="out-in"
|
||||
appear
|
||||
>
|
||||
<section class="grid grid-cols-1">
|
||||
<slot></slot>
|
||||
</section>
|
||||
</Transition>
|
||||
</section>
|
||||
</main>
|
||||
<dialogs-provider />
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,16 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfirmDialog group="deleteTemplate">
|
||||
<template #message="slotProps">
|
||||
<div class="flex flex-col items-center w-full gap-4">
|
||||
<i :class="slotProps.message.icon" class="!text-6xl text-primary-500"></i>
|
||||
<p class="leading-7 text-sm font-normal">{{ slotProps.message.message }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmDialog>
|
||||
<Toast />
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { defineStore } from 'pinia'
|
||||
export const useAuthStore = defineStore('AuthStore', {
|
||||
state: () => ({
|
||||
user: null,
|
||||
}),
|
||||
actions: {},
|
||||
})
|
||||
@@ -0,0 +1,10 @@
|
||||
import { defineStore } from 'pinia'
|
||||
export const useDocumentStore = defineStore('DocumentStore', {
|
||||
state: () => ({
|
||||
endpoints: {
|
||||
index: '/dashboard/documents',
|
||||
show: (id) => `/dashboard/documents/${id}`,
|
||||
},
|
||||
}),
|
||||
actions: {},
|
||||
})
|
||||
@@ -0,0 +1,10 @@
|
||||
import { defineStore } from 'pinia'
|
||||
export const useGlobalStore = defineStore('GlobalStore', {
|
||||
state: () => ({
|
||||
current_user: {},
|
||||
sidebarOpen: false
|
||||
}),
|
||||
actions: {
|
||||
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,52 @@
|
||||
import { definePreset } from '@primeuix/themes';
|
||||
import Aura from '@primeuix/themes/aura';
|
||||
|
||||
const AuraCustomPreset = definePreset(Aura, {
|
||||
semantic: {
|
||||
primary: {
|
||||
50: '#e9edf3',
|
||||
100: '#c8d2e1',
|
||||
200: '#a2afc8',
|
||||
300: '#7286a5',
|
||||
400: '#455a79',
|
||||
500: '#051a3a',
|
||||
600: '#041634',
|
||||
700: '#03132c',
|
||||
800: '#020f25',
|
||||
900: '#020a1b',
|
||||
950: '#010510',
|
||||
},
|
||||
colorScheme: {
|
||||
light: {
|
||||
primary: {
|
||||
color: '{primary.500}',
|
||||
contrastColor: '#ffffff',
|
||||
hoverColor: '{primary.600}',
|
||||
activeColor: '{primary.700}',
|
||||
},
|
||||
highlight: {
|
||||
background: '{primary.50}',
|
||||
focusBackground: '{primary.100}',
|
||||
color: '{primary.700}',
|
||||
focusColor: '{primary.800}',
|
||||
},
|
||||
},
|
||||
dark: {
|
||||
primary: {
|
||||
color: '{primary.400}',
|
||||
contrastColor: '{surface.900}',
|
||||
hoverColor: '{primary.300}',
|
||||
activeColor: '{primary.200}',
|
||||
},
|
||||
highlight: {
|
||||
background: 'color-mix(in srgb, {primary.400}, transparent 84%)',
|
||||
focusBackground: 'color-mix(in srgb, {primary.400}, transparent 76%)',
|
||||
color: 'rgba(255,255,255,.87)',
|
||||
focusColor: 'rgba(255,255,255,.87)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default AuraCustomPreset;
|
||||
@@ -0,0 +1,45 @@
|
||||
export const convertPersianToEnglish = (text) => {
|
||||
if (text === null || text === undefined) {
|
||||
return '0'
|
||||
}
|
||||
|
||||
const persianNumbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']
|
||||
const englishNumbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
||||
|
||||
let result = String(text)
|
||||
persianNumbers.forEach((persian, index) => {
|
||||
result = result.replace(new RegExp(persian, 'g'), englishNumbers[index])
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export const convertEnglishToPersian = (text) => {
|
||||
if (text === null || text === undefined) {
|
||||
return '۰'
|
||||
}
|
||||
|
||||
const englishNumbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
||||
const persianNumbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']
|
||||
|
||||
let result = String(text)
|
||||
englishNumbers.forEach((english, index) => {
|
||||
result = result.replace(new RegExp(english, 'g'), persianNumbers[index])
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export const formatPrice = (price) => {
|
||||
if (price === null || price === undefined) {
|
||||
return '۰'
|
||||
}
|
||||
|
||||
const numPrice = Number(price)
|
||||
if (isNaN(numPrice)) {
|
||||
return '۰'
|
||||
}
|
||||
|
||||
const formattedPrice = numPrice.toLocaleString('fa-IR')
|
||||
return convertEnglishToPersian(formattedPrice)
|
||||
}
|
||||