first commit
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { $themeConfig } from '@/theme.config'
|
import { $themeConfig } from '@/theme.config'
|
||||||
import { useAppStore } from '@/stores/app'
|
import { useAppStore, type LocaleCode } from '@/stores/app'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
init() {
|
init() {
|
||||||
@@ -32,7 +32,7 @@ export default {
|
|||||||
store.toggleSemidark(value === 'true' ? true : $themeConfig.semidark)
|
store.toggleSemidark(value === 'true' ? true : $themeConfig.semidark)
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleLanguage(item?: { code: string; name: string }) {
|
toggleLanguage(item?: { code: LocaleCode; name: string }) {
|
||||||
const store = useAppStore()
|
const store = useAppStore()
|
||||||
const lang = item || store.languageList.find((entry) => entry.code === store.locale) || store.languageList[0]
|
const lang = item || store.languageList.find((entry) => entry.code === store.locale) || store.languageList[0]
|
||||||
store.toggleLocale(lang.code)
|
store.toggleLocale(lang.code)
|
||||||
|
|||||||
@@ -490,6 +490,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
|
import type { ApexOptions } from 'apexcharts';
|
||||||
import apexchart from 'vue3-apexcharts';
|
import apexchart from 'vue3-apexcharts';
|
||||||
import { useAppStore } from '@/stores/app';
|
import { useAppStore } from '@/stores/app';
|
||||||
import { useMeta } from '@/composables/use-meta';
|
import { useMeta } from '@/composables/use-meta';
|
||||||
@@ -546,7 +547,7 @@
|
|||||||
},
|
},
|
||||||
responsive: [
|
responsive: [
|
||||||
{
|
{
|
||||||
breakPoint: 576,
|
breakpoint: 576,
|
||||||
options: {
|
options: {
|
||||||
chart: {
|
chart: {
|
||||||
height: 95,
|
height: 95,
|
||||||
@@ -561,7 +562,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const bitcoinSeries = ref([
|
const bitcoinSeries = ref([
|
||||||
@@ -608,7 +609,7 @@
|
|||||||
},
|
},
|
||||||
responsive: [
|
responsive: [
|
||||||
{
|
{
|
||||||
breakPoint: 576,
|
breakpoint: 576,
|
||||||
options: {
|
options: {
|
||||||
chart: {
|
chart: {
|
||||||
height: 95,
|
height: 95,
|
||||||
@@ -623,7 +624,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const ethereumSeries = ref([
|
const ethereumSeries = ref([
|
||||||
@@ -670,7 +671,7 @@
|
|||||||
},
|
},
|
||||||
responsive: [
|
responsive: [
|
||||||
{
|
{
|
||||||
breakPoint: 576,
|
breakpoint: 576,
|
||||||
options: {
|
options: {
|
||||||
chart: {
|
chart: {
|
||||||
height: 95,
|
height: 95,
|
||||||
@@ -685,7 +686,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const litecoinSeries = ref([
|
const litecoinSeries = ref([
|
||||||
@@ -732,7 +733,7 @@
|
|||||||
},
|
},
|
||||||
responsive: [
|
responsive: [
|
||||||
{
|
{
|
||||||
breakPoint: 576,
|
breakpoint: 576,
|
||||||
options: {
|
options: {
|
||||||
chart: {
|
chart: {
|
||||||
height: 95,
|
height: 95,
|
||||||
@@ -747,7 +748,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const binanceSeries = ref([
|
const binanceSeries = ref([
|
||||||
@@ -794,7 +795,7 @@
|
|||||||
},
|
},
|
||||||
responsive: [
|
responsive: [
|
||||||
{
|
{
|
||||||
breakPoint: 576,
|
breakpoint: 576,
|
||||||
options: {
|
options: {
|
||||||
chart: {
|
chart: {
|
||||||
height: 95,
|
height: 95,
|
||||||
@@ -809,7 +810,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const tetherSeries = ref([
|
const tetherSeries = ref([
|
||||||
@@ -856,7 +857,7 @@
|
|||||||
},
|
},
|
||||||
responsive: [
|
responsive: [
|
||||||
{
|
{
|
||||||
breakPoint: 576,
|
breakpoint: 576,
|
||||||
options: {
|
options: {
|
||||||
chart: {
|
chart: {
|
||||||
height: 95,
|
height: 95,
|
||||||
@@ -871,7 +872,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const solanaSeries = ref([
|
const solanaSeries = ref([
|
||||||
|
|||||||
@@ -747,6 +747,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
|
import type { ApexOptions } from 'apexcharts';
|
||||||
import apexchart from 'vue3-apexcharts';
|
import apexchart from 'vue3-apexcharts';
|
||||||
|
|
||||||
import { useAppStore } from '@/stores/app';
|
import { useAppStore } from '@/stores/app';
|
||||||
@@ -907,7 +908,7 @@
|
|||||||
stops: isDark ? [100, 100] : [45, 100],
|
stops: isDark ? [100, 100] : [45, 100],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const revenueSeries = ref([
|
const revenueSeries = ref([
|
||||||
@@ -936,7 +937,7 @@
|
|||||||
stroke: {
|
stroke: {
|
||||||
show: true,
|
show: true,
|
||||||
width: 25,
|
width: 25,
|
||||||
colors: isDark ? '#0e1726' : '#fff',
|
colors: isDark ? ['#0e1726'] : ['#fff'],
|
||||||
},
|
},
|
||||||
colors: isDark ? ['#5c1ac3', '#e2a03f', '#e7515a', '#e2a03f'] : ['#e2a03f', '#5c1ac3', '#e7515a'],
|
colors: isDark ? ['#5c1ac3', '#e2a03f', '#e7515a', '#e2a03f'] : ['#e2a03f', '#5c1ac3', '#e7515a'],
|
||||||
legend: {
|
legend: {
|
||||||
@@ -1002,7 +1003,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const salesByCategorySeries = ref([985, 737, 270]);
|
const salesByCategorySeries = ref([985, 737, 270]);
|
||||||
@@ -1076,7 +1077,7 @@
|
|||||||
left: -20,
|
left: -20,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const dailySalesSeries = ref([
|
const dailySalesSeries = ref([
|
||||||
@@ -1137,7 +1138,7 @@
|
|||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
} as ApexOptions;
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalOrdersSeries = ref([
|
const totalOrdersSeries = ref([
|
||||||
|
|||||||
12
src/env.d.ts
vendored
12
src/env.d.ts
vendored
@@ -5,3 +5,15 @@ declare module '*.vue' {
|
|||||||
const component: DefineComponent<{}, {}, any>
|
const component: DefineComponent<{}, {}, any>
|
||||||
export default component
|
export default component
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module 'vue-height-collapsible/vue3' {
|
||||||
|
import type { DefineComponent } from 'vue'
|
||||||
|
const component: DefineComponent<{}, {}, any>
|
||||||
|
export default component
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'vue-height-collapsible/vue3/vue-height-collapsible.esm.js' {
|
||||||
|
import type { DefineComponent } from 'vue'
|
||||||
|
const component: DefineComponent<{}, {}, any>
|
||||||
|
export default component
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import type {
|
|||||||
} from '@/types/product'
|
} from '@/types/product'
|
||||||
|
|
||||||
type QueryPrimitive = string | number | boolean | null | undefined
|
type QueryPrimitive = string | number | boolean | null | undefined
|
||||||
type QueryValue = QueryPrimitive | string[] | ProductAttributes | ProductAttributeAssignment[] | ProductMeta | Record<string, unknown>
|
export type QueryValue = QueryPrimitive | string[] | ProductAttributes | ProductAttributeAssignment[] | ProductMeta | Record<string, unknown>
|
||||||
|
|
||||||
export const buildQueryParams = (params: Record<string, QueryValue>) => {
|
export const buildQueryParams = (params: Record<string, unknown>) => {
|
||||||
const query: Record<string, string | number | boolean> = {}
|
const query: Record<string, string | number | boolean> = {}
|
||||||
|
|
||||||
Object.entries(params).forEach(([key, value]) => {
|
Object.entries(params).forEach(([key, value]) => {
|
||||||
@@ -24,19 +24,19 @@ export const buildQueryParams = (params: Record<string, QueryValue>) => {
|
|||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
if (value.length > 0) {
|
if (value.length > 0) {
|
||||||
query[key] = JSON.stringify(value)
|
query[key] = JSON.stringify(value as QueryValue)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'object') {
|
if (typeof value === 'object') {
|
||||||
if (Object.keys(value).length > 0) {
|
if (Object.keys(value).length > 0) {
|
||||||
query[key] = JSON.stringify(value)
|
query[key] = JSON.stringify(value as QueryValue)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
query[key] = value
|
query[key] = value as string | number | boolean
|
||||||
})
|
})
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class ApiService {
|
|||||||
if (refreshToken) {
|
if (refreshToken) {
|
||||||
try {
|
try {
|
||||||
const response = await this.refreshToken({ refreshToken })
|
const response = await this.refreshToken({ refreshToken })
|
||||||
const { accessToken, refreshToken: newRefreshToken } = response.data
|
const { accessToken, refreshToken: newRefreshToken } = response
|
||||||
|
|
||||||
localStorage.setItem('accessToken', accessToken)
|
localStorage.setItem('accessToken', accessToken)
|
||||||
localStorage.setItem('refreshToken', newRefreshToken)
|
localStorage.setItem('refreshToken', newRefreshToken)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import i18n from '@/i18n'
|
|||||||
import appSetting from '@/app-setting'
|
import appSetting from '@/app-setting'
|
||||||
|
|
||||||
const rtlLanguages = new Set(['ae', 'fa', 'ar'])
|
const rtlLanguages = new Set(['ae', 'fa', 'ar'])
|
||||||
|
export type LocaleCode = 'fa' | 'ae' | 'en'
|
||||||
|
|
||||||
export const useAppStore = defineStore('app', {
|
export const useAppStore = defineStore('app', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@@ -13,13 +14,13 @@ export const useAppStore = defineStore('app', {
|
|||||||
rtlClass: 'rtl',
|
rtlClass: 'rtl',
|
||||||
animation: '',
|
animation: '',
|
||||||
navbar: 'navbar-sticky',
|
navbar: 'navbar-sticky',
|
||||||
locale: 'fa',
|
locale: 'fa' as LocaleCode,
|
||||||
sidebar: false,
|
sidebar: false,
|
||||||
languageList: [
|
languageList: [
|
||||||
{ code: 'fa', name: 'فارسی' },
|
{ code: 'fa', name: 'فارسی' },
|
||||||
{ code: 'ae', name: 'Arabic' },
|
{ code: 'ae', name: 'Arabic' },
|
||||||
{ code: 'en', name: 'English' },
|
{ code: 'en', name: 'English' },
|
||||||
],
|
] as Array<{ code: LocaleCode; name: string }>,
|
||||||
isShowMainLoader: true,
|
isShowMainLoader: true,
|
||||||
semidark: false,
|
semidark: false,
|
||||||
}),
|
}),
|
||||||
@@ -81,7 +82,7 @@ export const useAppStore = defineStore('app', {
|
|||||||
this.semidark = value
|
this.semidark = value
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleLocale(payload: string | null = null) {
|
toggleLocale(payload: LocaleCode | null = null) {
|
||||||
const value = payload || this.locale
|
const value = payload || this.locale
|
||||||
i18n.global.locale.value = value
|
i18n.global.locale.value = value
|
||||||
localStorage.setItem('i18n_locale', value)
|
localStorage.setItem('i18n_locale', value)
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ export interface ProductFormPayload {
|
|||||||
brandId?: string
|
brandId?: string
|
||||||
brand: string
|
brand: string
|
||||||
basePriceUSD: number
|
basePriceUSD: number
|
||||||
salePriceUSD?: number | null
|
salePriceUSD?: number | null | ''
|
||||||
stock: number
|
stock: number
|
||||||
featured: boolean
|
featured: boolean
|
||||||
type: ProductType
|
type: ProductType
|
||||||
|
|||||||
@@ -139,8 +139,9 @@ export const normalizeAttributes = (attributes?: Record<string, unknown> | Produ
|
|||||||
}, {})
|
}, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const attributesToEntries = (attributes?: ProductAttributes): AttributeEntry[] => {
|
export const attributesToEntries = (attributes?: ProductAttributes | ProductAttributeAssignment[]): AttributeEntry[] => {
|
||||||
const entries = Object.entries(attributes || {}).map(([key, value]) => ({
|
const normalizedAttributes = normalizeAttributes(attributes)
|
||||||
|
const entries = Object.entries(normalizedAttributes).map(([key, value]) => ({
|
||||||
key,
|
key,
|
||||||
value: value === null || value === undefined ? '' : String(value),
|
value: value === null || value === undefined ? '' : String(value),
|
||||||
}))
|
}))
|
||||||
@@ -263,7 +264,7 @@ export const normalizeEnglishSlug = (value: string) =>
|
|||||||
|
|
||||||
export const generateEnglishSlug = (value: string) => normalizeEnglishSlug(transliteratePersianToLatin(value))
|
export const generateEnglishSlug = (value: string) => normalizeEnglishSlug(transliteratePersianToLatin(value))
|
||||||
|
|
||||||
export const formatCurrency = (value?: number | null) => {
|
export const formatCurrency = (value?: number | null | '') => {
|
||||||
const safeValue = Number(value || 0)
|
const safeValue = Number(value || 0)
|
||||||
return new Intl.NumberFormat('en-US', {
|
return new Intl.NumberFormat('en-US', {
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
|
|||||||
@@ -202,6 +202,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
|
import type { ApexOptions } from 'apexcharts'
|
||||||
import apexchart from 'vue3-apexcharts'
|
import apexchart from 'vue3-apexcharts'
|
||||||
import { useAppStore } from '@/stores/app'
|
import { useAppStore } from '@/stores/app'
|
||||||
import IconHorizontalDots from '@/components/icon/icon-horizontal-dots.vue'
|
import IconHorizontalDots from '@/components/icon/icon-horizontal-dots.vue'
|
||||||
@@ -399,7 +400,7 @@ const revenueChart = computed(() => {
|
|||||||
stops: [40, 100],
|
stops: [40, 100],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
} as ApexOptions
|
||||||
})
|
})
|
||||||
|
|
||||||
const salesByCategory = computed(() => {
|
const salesByCategory = computed(() => {
|
||||||
@@ -446,7 +447,7 @@ const salesByCategory = computed(() => {
|
|||||||
hover: { filter: { type: 'none', value: 0.15 } },
|
hover: { filter: { type: 'none', value: 0.15 } },
|
||||||
active: { filter: { type: 'none', value: 0.15 } },
|
active: { filter: { type: 'none', value: 0.15 } },
|
||||||
},
|
},
|
||||||
}
|
} as ApexOptions
|
||||||
})
|
})
|
||||||
|
|
||||||
const dailySales = computed(() => ({
|
const dailySales = computed(() => ({
|
||||||
@@ -478,7 +479,7 @@ const dailySales = computed(() => ({
|
|||||||
formatter: (value: number) => `${value} سفارش`,
|
formatter: (value: number) => `${value} سفارش`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}))
|
} as ApexOptions))
|
||||||
|
|
||||||
const inventoryChart = computed(() => ({
|
const inventoryChart = computed(() => ({
|
||||||
chart: {
|
chart: {
|
||||||
@@ -510,5 +511,5 @@ const inventoryChart = computed(() => ({
|
|||||||
formatter: (value: number) => `${value} SKU`,
|
formatter: (value: number) => `${value} SKU`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}))
|
} as ApexOptions))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -169,7 +169,7 @@
|
|||||||
v-model="form.slug"
|
v-model="form.slug"
|
||||||
type="text"
|
type="text"
|
||||||
dir="ltr"
|
dir="ltr"
|
||||||
inputmode="latin"
|
inputmode="text"
|
||||||
class="form-input"
|
class="form-input"
|
||||||
placeholder="skf"
|
placeholder="skf"
|
||||||
@input="sanitizeSlugInput"
|
@input="sanitizeSlugInput"
|
||||||
|
|||||||
@@ -224,7 +224,7 @@
|
|||||||
v-model="form.slug"
|
v-model="form.slug"
|
||||||
type="text"
|
type="text"
|
||||||
dir="ltr"
|
dir="ltr"
|
||||||
inputmode="latin"
|
inputmode="text"
|
||||||
class="form-input"
|
class="form-input"
|
||||||
placeholder="bolbering-sanati"
|
placeholder="bolbering-sanati"
|
||||||
@input="sanitizeSlugInput"
|
@input="sanitizeSlugInput"
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ const errors = reactive({
|
|||||||
const errorMessage = ref('')
|
const errorMessage = ref('')
|
||||||
const countdown = ref(120) // 2 minutes
|
const countdown = ref(120) // 2 minutes
|
||||||
const isResending = ref(false)
|
const isResending = ref(false)
|
||||||
let countdownInterval: NodeJS.Timeout | null = null
|
let countdownInterval: ReturnType<typeof setInterval> | null = null
|
||||||
|
|
||||||
const phone = ref(sessionStorage.getItem('otpPhone') || '')
|
const phone = ref(sessionStorage.getItem('otpPhone') || '')
|
||||||
const fullName = ref(sessionStorage.getItem('otpFullName') || '')
|
const fullName = ref(sessionStorage.getItem('otpFullName') || '')
|
||||||
|
|||||||
Reference in New Issue
Block a user