added dark mode

This commit is contained in:
2026-06-14 21:04:26 +03:30
parent 6d0601f464
commit c0633e5d5a
52 changed files with 1386 additions and 314 deletions
@@ -28,25 +28,25 @@ const props = defineProps<Prop>()
const bgColor = computed(() => {
switch (props.color) {
case 'fuchsia':
return 'bg-fuchsia-100'
return 'bg-fuchsia-100 dark:bg-fuchsia-500/20'
case 'orange':
return 'bg-orange-100'
return 'bg-orange-100 dark:bg-orange-500/20'
case 'green':
return 'bg-green-100'
return 'bg-green-100 dark:bg-green-500/20'
case 'blue':
return 'bg-blue-100'
return 'bg-blue-100 dark:bg-blue-500/20'
}
})
const textColor = computed(() => {
switch (props.color) {
case 'fuchsia':
return 'text-fuchsia-600'
return 'text-fuchsia-600 dark:text-fuchsia-300'
case 'orange':
return 'text-orange-600'
return 'text-orange-600 dark:text-orange-300'
case 'green':
return 'text-green-600'
return 'text-green-600 dark:text-green-300'
case 'blue':
return 'text-blue-600'
return 'text-blue-600 dark:text-blue-300'
}
})
</script>
+8 -6
View File
@@ -859,7 +859,9 @@ onMounted(() => {
}
.selected_item {
@apply ! bg- [ #0A1B37 ] ! text-white rounded-lg;
background: #2563eb !important;
color: #fff !important;
border-radius: 0.5rem;
}
.dashboard-chart-toolbar {
@@ -869,10 +871,10 @@ onMounted(() => {
gap: 0.5rem;
button {
border: 1px solid #d1d5db;
border: 1px solid var(--admin-border-strong);
border-radius: 0.5rem;
background: #fff;
color: #374151;
background: var(--admin-bg-elevated);
color: var(--admin-text);
cursor: pointer;
font-family: inherit;
font-size: 0.75rem;
@@ -881,8 +883,8 @@ onMounted(() => {
&.active,
&:hover {
background: #0a1b37;
border-color: #0a1b37;
background: #2563eb;
border-color: #2563eb;
color: #fff;
}
}
+3 -1
View File
@@ -1,5 +1,5 @@
<template>
<div class="bg-white w-fit p-12 rounded-lg m-auto h-[35rem]" :class="[prefixCls]">
<div class="admin-bg-elevated w-fit p-12 rounded-lg m-auto h-[35rem]" :class="[prefixCls]">
<div class="logo flex justify-center w-full flex-col items-center">
<img :src="getConfigApp('avatar')" class="w-[150px]" />
</div>
@@ -221,6 +221,8 @@ const getcode=()=>{
@prefix: ~'@{prefixCls}-login-panel';
.@{prefix} {
background-color: var(--admin-bg-elevated);
.logo {
width: 330px;
height: 148px;
+26 -2
View File
@@ -1,14 +1,18 @@
<template>
<div
:style="{ backgroundImage: `url(${bg1})` }"
class="w-screen h-screen top-0 right-0 fixed bg-cover flex z-[1000]"
class="login-page w-screen h-screen top-0 right-0 fixed bg-cover flex z-[1000]"
>
<div class="login-page__toggle">
<ThemeToggle />
</div>
<LoginPanel @enter="enterTest" class="shadow-2xl" />
</div>
</template>
<script setup lang="ts">
import LoginPanel from './components/LoginPanel.vue'
import ThemeToggle from '@core/components/ThemeToggle.vue'
import bg1 from '../login/assets/img/loginBack.svg'
const emits = defineEmits(['enter'])
@@ -19,4 +23,24 @@ function enterTest() {
}
</script>
<style scoped></style>
<style scoped>
.login-page {
position: relative;
}
.login-page__toggle {
position: absolute;
top: 16px;
left: 16px;
z-index: 1001;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 9999px;
background: var(--admin-bg-elevated);
border: 1px solid var(--admin-border);
box-shadow: 0 2px 8px var(--admin-shadow);
}
</style>
@@ -67,10 +67,10 @@ const help = computed(() => helpText(props.row))
<style lang="less" scoped>
.setting-card {
border: 1px solid #e8e8e8;
border: 1px solid var(--admin-border);
border-radius: 10px;
padding: 14px 16px;
background: #fff;
background: var(--admin-bg-elevated);
min-height: 108px;
transition: border-color 0.2s, box-shadow 0.2s;
height: 100%;
@@ -83,7 +83,7 @@ const help = computed(() => helpText(props.row))
}
&--readonly {
background: #fafafa;
background: var(--admin-bg-muted);
}
&--saving {
@@ -109,14 +109,14 @@ const help = computed(() => helpText(props.row))
&__title {
font-weight: 600;
font-size: 14px;
color: rgba(0, 0, 0, 0.88);
color: var(--admin-text);
line-height: 1.45;
}
&__key {
margin-top: 6px;
font-size: 12px;
color: rgba(0, 0, 0, 0.45);
color: var(--admin-text-secondary);
direction: ltr;
text-align: right;
word-break: break-all;
@@ -125,7 +125,7 @@ const help = computed(() => helpText(props.row))
&__help {
margin-top: 4px;
font-size: 11px;
color: rgba(0, 0, 0, 0.45);
color: var(--admin-text-secondary);
line-height: 1.35;
}
@@ -143,7 +143,7 @@ const help = computed(() => helpText(props.row))
&__status {
margin-top: 8px;
font-size: 11px;
color: rgba(0, 0, 0, 0.45);
color: var(--admin-text-secondary);
display: flex;
align-items: center;
gap: 6px;
+13 -13
View File
@@ -589,8 +589,8 @@ async function ok() {
align-items: flex-end;
margin-bottom: 20px;
padding: 14px 16px;
background: #fafafa;
border: 1px solid #f0f0f0;
background: var(--admin-bg-elevated);
border: 1px solid var(--admin-border);
border-radius: 8px;
&__search {
@@ -621,7 +621,7 @@ async function ok() {
&__label {
font-size: 12px;
font-weight: 500;
color: rgba(0, 0, 0, 0.55);
color: var(--admin-text-secondary);
line-height: 1;
}
@@ -633,10 +633,10 @@ async function ok() {
.settings-section-title {
font-size: 13px;
font-weight: 600;
color: rgba(0, 0, 0, 0.55);
color: var(--admin-text-secondary);
margin-bottom: 12px;
padding-bottom: 6px;
border-bottom: 1px solid #f0f0f0;
border-bottom: 1px solid var(--admin-border);
&--spaced {
margin-top: 28px;
@@ -659,11 +659,11 @@ async function ok() {
.settings-collapse :deep(.ant-collapse-item) {
margin-bottom: 12px;
background: #fff;
border: 1px solid #f0f0f0;
background: var(--admin-bg-elevated);
border: 1px solid var(--admin-border);
border-radius: 10px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
box-shadow: 0 1px 3px var(--admin-shadow);
transition: box-shadow 0.2s ease, border-color 0.2s ease;
}
@@ -674,10 +674,10 @@ async function ok() {
.settings-collapse :deep(.ant-collapse-header) {
padding: 14px 18px !important;
background: linear-gradient(90deg, #fafafa 0%, #fff 100%);
background: var(--admin-bg-muted);
font-weight: 600;
font-size: 14px;
color: #333;
color: var(--admin-text);
}
.settings-collapse-header {
@@ -695,15 +695,15 @@ async function ok() {
.settings-collapse-title {
flex: 1;
font-weight: 600;
color: #2c2c2c;
color: var(--admin-text);
}
.settings-empty-group {
padding: 12px 16px;
font-size: 12px;
color: #999;
color: var(--admin-text-secondary);
text-align: center;
background: #fafafa;
background: var(--admin-bg-muted);
border-radius: 6px;
margin-top: 8px;
}
@@ -2,17 +2,21 @@
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
<BasicShowContext title="لیست مشتریان">
<template #extra>
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
<div>افزودن</div>
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
<BaseButton
v-if="isMobile"
type="primary"
size="small"
icon="vuesax-linear:user-add"
@click="emits('add')"
>
افزودن
</BaseButton>
</template>
<div class="flex h-full min-h-0 flex-col">
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
<template #extraHeader>
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
<div>افزودن مشتری</div>
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
<BaseButton type="primary" size="small" icon="vuesax-linear:user-add" @click="emits('add')">
افزودن مشتری
</BaseButton>
</template>
<template #action="{ record }">
+2 -2
View File
@@ -104,7 +104,7 @@
<a-tabs v-if="userInfo" v-model:activeKey="activeKey">
<a-tab-pane key="اطلاعات جامع" tab="اطلاعات جامع">
<div class="space-y-2">
<div class="rounded-lg bg-gray-100 w-full flex flex-col gap-3 p-3 md:flex-row md:justify-between">
<div class="admin-stat-muted rounded-lg w-full flex flex-col gap-3 p-3 md:flex-row md:justify-between">
<div>
<div class="font-bold">{{ userInfo.name }}</div>
<div class="mt-1">{{ userInfo?.mobile }}</div>
@@ -187,7 +187,7 @@
<div
v-for="(item, index) in userInfo.wallet"
:key="index"
class="grid grid-cols-2 bg-orange-50 gap-2 rounded-lg p-2"
class="grid grid-cols-2 bg-orange-100 dark:bg-orange-500/15 gap-2 rounded-lg p-2"
>
<BasicInfoItem
title="نام قلک"
@@ -1,10 +1,9 @@
<template>
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
<BasicShowContext title="لیست کارت های هدیه">
<template v-if="!customerId" #extra>
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add', 'gift')">
<div>افزودن</div>
<BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />
<template v-if="!customerId && isMobile" #extra>
<BaseButton type="primary" size="small" icon="vuesax-linear:receipt-add" @click="emits('add', 'gift')">
افزودن
</BaseButton>
</template>
@@ -12,19 +11,17 @@
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
<template #extraHeader>
<div class="flex gap-2">
<BaseButton v-if="!customerId" type="primary" size="small" class="flex" @click="emits('add', 'gift')">
<div>افزودن کارت هدیه</div>
<BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />
<BaseButton v-if="!customerId" type="primary" size="small" icon="vuesax-linear:receipt-add" @click="emits('add', 'gift')">
افزودن کارت هدیه
</BaseButton>
<BaseButton
v-if="!customerId && isStoreApp()"
type="primary"
size="small"
class="flex"
icon="vuesax-linear:discount-circle"
@click="emits('add', 'discount')"
>
<div>افزودن کد تخفیف</div>
<BaseIcon icon="vuesax-linear:discount-circle" Size="16px" />
افزودن کد تخفیف
</BaseButton>
</div>
</template>
@@ -1,18 +1,16 @@
<template>
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
<BasicShowContext title="لیست سفارشات">
<template v-if="!customerId" #extra>
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
<div>افزودن</div>
<BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />
<template v-if="!customerId && isMobile" #extra>
<BaseButton type="primary" size="small" icon="vuesax-linear:receipt-add" @click="emits('add')">
افزودن
</BaseButton>
</template>
<div class="flex h-full min-h-0 flex-col">
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
<template #extraHeader>
<BaseButton v-if="!customerId" type="primary" size="small" class="flex" @click="emits('add')">
<div>افزودن سفارش</div>
<BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />
<BaseButton v-if="!customerId" type="primary" size="small" icon="vuesax-linear:receipt-add" @click="emits('add')">
افزودن سفارش
</BaseButton>
</template>
<template #action="{ column, record }">
@@ -3,14 +3,14 @@
<BasicShowContext title="تاریخچه قیمت">
<template #extra>
<BaseButton
v-if="isMobile"
type="primary"
size="small"
class="flex shrink-0 md:hidden"
icon="vuesax-linear:refresh"
:loading="syncing"
@click="emits('sync')"
>
<div>به‌روزرسانی قیمت</div>
<BaseIcon icon="vuesax-linear:refresh" Size="16px" />
به‌روزرسانی قیمت
</BaseButton>
</template>
@@ -20,12 +20,11 @@
<BaseButton
type="primary"
size="small"
class="flex"
icon="vuesax-linear:refresh"
:loading="syncing"
@click="emits('sync')"
>
<div>به‌روزرسانی قیمت</div>
<BaseIcon icon="vuesax-linear:refresh" Size="16px" />
به‌روزرسانی قیمت
</BaseButton>
</template>
<template #action="{ record }">
@@ -63,13 +63,7 @@
import type { TableInput } from '@core/type/baseTable'
import useBaseTable from '@core/components/BaseTableOld/hooks/useBaseTable'
import Icon from '@core/components/BaseIcon/src/Icon.vue'
import {
changeCustomerActivation,
changeCustomerArchive,
changeCustomerOrderActivation,
getCustomerArchiveTable,
getCustomerTable
} from '@/api/customer'
import { changeProductArchive } from '@/api/product'
import { cols } from '../hooks/archiveColumns'
import { useUserStore } from '@/store/userStore'
import { usePrefix } from '@core/composable/usePrefix'
@@ -105,37 +99,12 @@ const tblProps = ref<any>({
})
const loading = ref<boolean>(false)
async function changeCustomerActivationFunction(id: number) {
try {
loading.value = true
await changeCustomerActivation(id)
reload()
message.success('تغییر وضعیت با موفقیت انجام شد')
} catch (e) {
console.error(e)
} finally {
loading.value = false
}
}
async function changeCustomerOrderActivationFunction(id: number) {
try {
loading.value = true
await changeCustomerOrderActivation(id)
reload()
message.success('تغییر وضعیت سفارش دهی با موفقیت انجام شد')
} catch (e) {
console.error(e)
} finally {
loading.value = false
}
}
async function archiveFunction(id: number) {
try {
loading.value = true
await changeCustomerArchive(id)
await changeProductArchive(id)
await Promise.allSettled([reload(), mobileListRef.value?.fetch?.() as Promise<void>])
message.success('مشتری با موفقیت از بایگانی خارج شد.')
message.success('محصول با موفقیت از بایگانی خارج شد.')
} catch (e) {
console.error(e)
} finally {
@@ -36,17 +36,21 @@
<BasicShowContext title="لیست محصولات" class="min-h-0 flex-1">
<template #extra>
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
<div>افزودن</div>
<BaseIcon icon="vuesax-linear:box" Size="16px" />
<BaseButton
v-if="isMobile"
type="primary"
size="small"
icon="vuesax-linear:box"
@click="emits('add')"
>
افزودن محصول
</BaseButton>
</template>
<div class="flex h-full min-h-0 flex-col">
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
<template #extraHeader>
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
<div>افزودن محصول</div>
<BaseIcon icon="vuesax-linear:box" Size="16px" />
<BaseButton type="primary" size="small" icon="vuesax-linear:box" @click="emits('add')">
افزودن محصول
</BaseButton>
</template>
<template #action="{ record }">
@@ -1,6 +1,11 @@
import type { BaseTableColumn } from '@core/type/baseTable'
import CustomTag from '@/components/CustomTag.vue'
import { isStoreApp } from '@/utils/config'
import { usePrice } from '@core/utils/usePrice'
function formatMoney(value: number | null | undefined) {
return usePrice(value ?? 0, true, '').trim()
}
const inventoryColumn: BaseTableColumn = {
title: 'موجودی',
@@ -47,7 +52,8 @@ export function getProductColumns(): BaseTableColumn[] {
title: 'قیمت',
dataIndex: 'price',
key: 'price',
type: 'Text'
type: 'Text',
customRender: ({ record }) => formatMoney(record.price)
},
{
title: 'تعدیل قیمت (٪)',
@@ -79,13 +85,15 @@ export function getProductColumns(): BaseTableColumn[] {
title: 'هزینه نقدی موقع خرید',
dataIndex: 'cash_fee_buy',
key: 'cash_fee_buy',
type: 'Number'
type: 'Number',
customRender: ({ record }) => formatMoney(record.cash_fee_buy)
},
{
title: 'هزینه نقدی موقع فروش',
dataIndex: 'cash_fee_sell',
key: 'cash_fee_sell',
type: 'Number'
type: 'Number',
customRender: ({ record }) => formatMoney(record.cash_fee_sell)
},
...(isStoreApp() ? [inventoryColumn] : []),
{
+5 -7
View File
@@ -1,19 +1,17 @@
<template>
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
<BasicShowContext title="لیست پیامک ها">
<template v-if="!mobile" #extra>
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
<div>ارسال پیامک</div>
<BaseIcon icon="vuesax-linear:sms" Size="16px" />
<template v-if="!mobile && isMobileScreen" #extra>
<BaseButton type="primary" size="small" icon="vuesax-linear:sms" @click="emits('add')">
ارسال پیامک
</BaseButton>
</template>
<div class="flex h-full min-h-0 flex-col">
<BaseTable v-if="!isMobileScreen" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
<template #extraHeader>
<BaseButton v-if="!mobile" type="primary" size="small" class="flex" @click="emits('add')">
<div>ارسال پیامک</div>
<BaseIcon icon="vuesax-linear:sms" Size="16px" />
<BaseButton v-if="!mobile" type="primary" size="small" icon="vuesax-linear:sms" @click="emits('add')">
ارسال پیامک
</BaseButton>
</template>
<template #action="{ column, record }">
+10 -6
View File
@@ -2,18 +2,22 @@
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
<BasicShowContext title="لیست مدیران">
<template #extra>
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
<div>افزودن مدیر</div>
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
<BaseButton
v-if="isMobile"
type="primary"
size="small"
icon="vuesax-linear:user-add"
@click="emits('add')"
>
افزودن مدیر
</BaseButton>
</template>
<div class="flex h-full min-h-0 flex-col">
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
<template #extraHeader>
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
<div>افزودن مدیر</div>
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
<BaseButton type="primary" size="small" icon="vuesax-linear:user-add" @click="emits('add')">
افزودن مدیر
</BaseButton>
</template>
<template #action="{ column, record }">
@@ -9,11 +9,11 @@
>
<div class="mb-2 font-medium">مجموع موجودی کیف پول</div>
<div class="grid grid-cols-2 gap-2">
<div class="rounded-lg border border-gray-200 bg-white/70 px-2 py-1.5 text-center">
<div class="stat-inner rounded-lg px-2 py-1.5 text-center">
<div class="text-xs text-gray-500">ریال</div>
<div class="mt-1 font-bold break-all">{{ usePrice(sums?.cash ?? 0) }}</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white/70 px-2 py-1.5 text-center">
<div class="stat-inner rounded-lg px-2 py-1.5 text-center">
<div class="text-xs text-gray-500">گرم</div>
<div class="mt-1 font-bold">
{{ usePrice(Number(sums?.cashToGold ?? 0).toFixed(2), true, 'گرم') }}
@@ -28,13 +28,13 @@
>
<div class="mb-2 font-medium">مجموع موجودی کیف طلا</div>
<div class="grid grid-cols-2 gap-2">
<div class="rounded-lg border border-gray-200 bg-white/70 px-2 py-1.5 text-center">
<div class="stat-inner rounded-lg px-2 py-1.5 text-center">
<div class="text-xs text-gray-500">گرم</div>
<div class="mt-1 font-bold">
{{ usePrice(sums?.gold ?? 0, true, 'گرم') }}
</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white/70 px-2 py-1.5 text-center">
<div class="stat-inner rounded-lg px-2 py-1.5 text-center">
<div class="text-xs text-gray-500">ریال</div>
<div class="mt-1 font-bold break-all">{{ usePrice(sums?.goldToCash ?? 0) }}</div>
</div>
+1 -1
View File
@@ -72,7 +72,7 @@
@close="confirmWeightVisible = false"
>
<div v-for="(item, index) in weightTransactions" :key="index">
<div class="bg-gray-100 rounded-lg p-4 mt-2">
<div class="admin-stat-muted rounded-lg p-4 mt-2">
<div class="mb-4">{{ item?.title }} ({{ weightCount(item) }} عدد)</div>
<ADivider class="!my-0 "/>
<div v-if="weightCount(item) > 0">
@@ -2,7 +2,7 @@
<div>
<div class="mx-3 relative">
<div class="absolute z-10 w-full">
<div class="flex justify-between items-center bg-gray-50 rounded p-3 w-full">
<div class="flex justify-between items-center admin-stat-muted rounded p-3 w-full">
<span class="text-base font-bold">اقلام سفارش</span>
<Button type="primary" size="small" v-if="edit" @click="updateOrders"
>ثبت اطلاعات