added dark mode
This commit is contained in:
Vendored
+4
@@ -35,9 +35,11 @@ declare module '@vue/runtime-core' {
|
|||||||
AMenu: typeof import('ant-design-vue/es')['Menu']
|
AMenu: typeof import('ant-design-vue/es')['Menu']
|
||||||
AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
|
AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
|
||||||
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
||||||
|
AMenuItemGroup: typeof import('ant-design-vue/es')['MenuItemGroup']
|
||||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||||
APagination: typeof import('ant-design-vue/es')['Pagination']
|
APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||||
|
APopover: typeof import('ant-design-vue/es')['Popover']
|
||||||
ARadio: typeof import('ant-design-vue/es')['Radio']
|
ARadio: typeof import('ant-design-vue/es')['Radio']
|
||||||
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
|
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
|
||||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||||
@@ -81,6 +83,8 @@ declare module '@vue/runtime-core' {
|
|||||||
CustomTag: typeof import('./src/components/CustomTag.vue')['default']
|
CustomTag: typeof import('./src/components/CustomTag.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
ThemeMenuSection: typeof import('./src/core/components/ThemeMenuSection.vue')['default']
|
||||||
|
ThemeToggle: typeof import('./src/core/components/ThemeToggle.vue')['default']
|
||||||
UploadPic: typeof import('./src/components/UploadPic.vue')['default']
|
UploadPic: typeof import('./src/components/UploadPic.vue')['default']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -6,6 +6,17 @@
|
|||||||
<meta content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<!-- todo -->
|
<!-- todo -->
|
||||||
<title>admin </title>
|
<title>admin </title>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
try {
|
||||||
|
var raw = localStorage.getItem('color-schema')
|
||||||
|
var schema = raw ? JSON.parse(raw) : 'auto'
|
||||||
|
var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
var isDark = schema === 'dark' || (schema !== 'light' && prefersDark)
|
||||||
|
if (isDark) document.documentElement.classList.add('is-dark')
|
||||||
|
} catch (e) {}
|
||||||
|
})()
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
+10
-2
@@ -11,7 +11,10 @@ import {
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
shortcuts: [
|
shortcuts: [
|
||||||
// ...
|
['surface', 'bg-white dark:bg-[#1f1f1f]'],
|
||||||
|
['surface-muted', 'bg-gray-50 dark:bg-[#262626]'],
|
||||||
|
['border-base', 'border-gray-200 dark:border-[color:var(--admin-border)]'],
|
||||||
|
['text-muted', 'text-gray-600 dark:text-gray-400'],
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
colors: {
|
colors: {
|
||||||
@@ -20,7 +23,12 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
presets: [
|
presets: [
|
||||||
presetUno(),
|
presetUno({
|
||||||
|
dark: {
|
||||||
|
dark: 'html.is-dark',
|
||||||
|
light: 'html:not(.is-dark)',
|
||||||
|
},
|
||||||
|
}),
|
||||||
presetAttributify(),
|
presetAttributify(),
|
||||||
presetIcons(),
|
presetIcons(),
|
||||||
presetTypography(),
|
presetTypography(),
|
||||||
|
|||||||
+9
-5
@@ -6,17 +6,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted} from 'vue'
|
import { onMounted } from 'vue'
|
||||||
import {useConfigStore} from "@/store/configStore";
|
import { useConfigStore } from '@/store/configStore'
|
||||||
|
import { initDarkmode } from '@core/stores/darkmode'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const config=useConfigStore()
|
const config = useConfigStore()
|
||||||
|
|
||||||
|
initDarkmode()
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
console.log('roussss', router)
|
console.log('roussss', router)
|
||||||
router.push({ name: 'users' })
|
router.push({ name: 'users' })
|
||||||
}
|
}
|
||||||
onMounted(async ()=>{
|
onMounted(async () => {
|
||||||
await config.getConfigData()
|
await config.getConfigData()
|
||||||
})
|
})
|
||||||
|
|
||||||
/*const router = useRouter()
|
/*const router = useRouter()
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ export const changeProductActivation = async (id: number) =>
|
|||||||
export const changeCustomerOrderActivation = async (id: number) =>
|
export const changeCustomerOrderActivation = async (id: number) =>
|
||||||
await useAxios.get(`/admin/product/trade/${id}`)
|
await useAxios.get(`/admin/product/trade/${id}`)
|
||||||
|
|
||||||
export const changeCustomerArchive = async (id: number) =>
|
export const changeProductArchive = async (id: number) =>
|
||||||
await useAxios.get(`/admin/product/archive/${id}`)
|
await useAxios.get(`/admin/product/archive/${id}`)
|
||||||
|
|
||||||
export const confirmUser = async (id: number) =>
|
export const confirmUser = async (id: number) =>
|
||||||
|
|||||||
@@ -81,13 +81,12 @@
|
|||||||
margin: 0 8px;
|
margin: 0 8px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 1px solid #d1d5db;
|
border: 1px solid var(--admin-border-strong);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: white;
|
background-color: var(--admin-bg-surface);
|
||||||
//@apply bg-gray-50;
|
|
||||||
|
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
background-color: #fff;
|
background-color: var(--admin-bg-surface);
|
||||||
//display: none;
|
//display: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: 1px solid @primary-color !important;
|
border: 1px solid @primary-color !important;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ const props = withDefaults(defineProps<Props>(), {})
|
|||||||
.open {
|
.open {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: #E5E7EB;
|
background-color: var(--admin-border-strong);
|
||||||
}
|
}
|
||||||
|
|
||||||
.rotate {
|
.rotate {
|
||||||
@@ -40,7 +40,7 @@ const props = withDefaults(defineProps<Props>(), {})
|
|||||||
.ant-collapse > .ant-collapse-item > .ant-collapse-header {
|
.ant-collapse > .ant-collapse-item > .ant-collapse-header {
|
||||||
direction: rtl !important;
|
direction: rtl !important;
|
||||||
justify-content: space-between !important;
|
justify-content: space-between !important;
|
||||||
background-color: #fff !important;
|
background-color: var(--admin-bg-surface) !important;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -206,8 +206,8 @@ function handleCancel() {
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
background: #fff;
|
background: var(--admin-bg-elevated);
|
||||||
padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
|
padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
|
||||||
border-top: 1px solid #f0f0f0;
|
border-top: 1px solid var(--admin-border);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
footer
|
footer
|
||||||
>
|
>
|
||||||
<div class="overflow-y-auto max-h-[70vh] mt-10">
|
<div class="overflow-y-auto max-h-[70vh] mt-10">
|
||||||
<div :class="[prefixCls]" class="bg-blue-50 rounded flex justify-between p-3">
|
<div :class="[prefixCls]" class="admin-stat-muted rounded flex justify-between p-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="font-bold">{{ props.name }}</div>
|
<div class="font-bold">{{ props.name }}</div>
|
||||||
<div class="text-primary-type mt-1">{{ props.type }}</div>
|
<div class="text-primary-type mt-1">{{ props.type }}</div>
|
||||||
@@ -40,15 +40,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-[#CACED8] w-full h-[1px] my-8" />
|
<div class="my-8 h-px w-full bg-[var(--admin-border)]" />
|
||||||
<div class="text-[#949DB0]">{{ props.itemsTitle }}</div>
|
<div class="text-[var(--admin-text-secondary)]">{{ props.itemsTitle }}</div>
|
||||||
<div class="grid md:grid-cols-4 mt-5 gap-5 p-5">
|
<div class="grid md:grid-cols-4 mt-5 gap-5 p-5">
|
||||||
<div v-for="val in props.items">
|
<div v-for="val in props.items">
|
||||||
<div class="text-[#949DB0]">{{ val.key }}</div>
|
<div class="text-[var(--admin-text-secondary)]">{{ val.key }}</div>
|
||||||
<div class="font-bold">{{ val.value }}</div>
|
<div class="font-bold">{{ val.value }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="md:col-span-5" v-if="props.description">
|
<div class="md:col-span-5" v-if="props.description">
|
||||||
<div class="text-[#949DB0]">توضیحات</div>
|
<div class="text-[var(--admin-text-secondary)]">توضیحات</div>
|
||||||
<div class="font-bold">{{ props.description ?? '-' }}</div>
|
<div class="font-bold">{{ props.description ?? '-' }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
v-model:selectedKeys="selectedKeys"
|
v-model:selectedKeys="selectedKeys"
|
||||||
:style="{ width: props.width }"
|
:style="{ width: props.width }"
|
||||||
:mode="props.mode"
|
:mode="props.mode"
|
||||||
:theme="props.theme"
|
:theme="resolvedTheme"
|
||||||
>
|
>
|
||||||
<BasicMenuItem :menu="props.menu" />
|
<BasicMenuItem :menu="props.menu" />
|
||||||
</AMenu>
|
</AMenu>
|
||||||
@@ -17,6 +17,9 @@ import { defineProps } from 'vue'
|
|||||||
//import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
//import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||||
import BasicMenuItem from '@/components/BasicMenu/components/BasicMenuItem.vue'
|
import BasicMenuItem from '@/components/BasicMenu/components/BasicMenuItem.vue'
|
||||||
import type { RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
import { useAdminTheme } from '@core/composable/useAdminTheme'
|
||||||
|
|
||||||
|
const { menuTheme } = useAdminTheme()
|
||||||
|
|
||||||
const selectedKeys = ref<string[]>([])
|
const selectedKeys = ref<string[]>([])
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -39,11 +42,13 @@ interface Prop {
|
|||||||
theme?: MenuTheme
|
theme?: MenuTheme
|
||||||
width?: string
|
width?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Prop>(), {
|
const props = withDefaults(defineProps<Prop>(), {
|
||||||
mode: 'inline',
|
mode: 'inline',
|
||||||
theme: 'light',
|
|
||||||
width: '20rem'
|
width: '20rem'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const resolvedTheme = computed(() => props.theme ?? menuTheme.value)
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
selectedKeys.value = [router.currentRoute.value.name as string]
|
selectedKeys.value = [router.currentRoute.value.name as string]
|
||||||
//emits('onChange', '1')
|
//emits('onChange', '1')
|
||||||
|
|||||||
@@ -104,9 +104,9 @@ function navigateTo(item: RouteRecordRaw) {
|
|||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
|
padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
|
||||||
background: #fff;
|
background: var(--admin-bg-surface);
|
||||||
border-top: 1px solid #f0f0f0;
|
border-top: 1px solid var(--admin-border);
|
||||||
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.06);
|
box-shadow: 0 -2px 12px var(--admin-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-bottom-nav__item {
|
.mobile-bottom-nav__item {
|
||||||
@@ -122,14 +122,14 @@ function navigateTo(item: RouteRecordRaw) {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
color: #595959;
|
color: var(--admin-text-secondary);
|
||||||
|
|
||||||
&--active {
|
&--active {
|
||||||
color: #1677ff;
|
color: var(--admin-menu-selected-text);
|
||||||
|
|
||||||
.mobile-bottom-nav__icon-wrap {
|
.mobile-bottom-nav__icon-wrap {
|
||||||
background: #e6f4ff;
|
background: var(--admin-menu-selected);
|
||||||
color: #1677ff;
|
color: var(--admin-menu-selected-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
@@ -141,7 +141,7 @@ function navigateTo(item: RouteRecordRaw) {
|
|||||||
width: 28px;
|
width: 28px;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
border-radius: 3px 3px 0 0;
|
border-radius: 3px 3px 0 0;
|
||||||
background: #1677ff;
|
background: var(--admin-menu-selected-text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ function navigateTo(item: RouteRecordRaw) {
|
|||||||
width: 40px;
|
width: 40px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
color: #292d32;
|
color: var(--admin-text-muted);
|
||||||
|
|
||||||
:deep(svg path) {
|
:deep(svg path) {
|
||||||
stroke: currentColor;
|
stroke: currentColor;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</AMenuItem>
|
</AMenuItem>
|
||||||
<AMenuDivider />
|
<AMenuDivider />
|
||||||
|
<ThemeMenuSection />
|
||||||
<AMenuItem @click="myInfoVisible = true">
|
<AMenuItem @click="myInfoVisible = true">
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<Icon icon="vuesax-linear:profile" size="18" />
|
<Icon icon="vuesax-linear:profile" size="18" />
|
||||||
@@ -80,6 +81,7 @@ import { message } from 'ant-design-vue/es'
|
|||||||
import { onMounted, ref, computed } from 'vue'
|
import { onMounted, ref, computed } from 'vue'
|
||||||
import type { FormInstance } from 'ant-design-vue'
|
import type { FormInstance } from 'ant-design-vue'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
|
import ThemeMenuSection from '@core/components/ThemeMenuSection.vue'
|
||||||
|
|
||||||
const { prefixCls } = usePrefix('basic-header')
|
const { prefixCls } = usePrefix('basic-header')
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
@@ -129,7 +131,11 @@ async function ok() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearLocalStorage() {
|
function clearLocalStorage() {
|
||||||
|
const colorSchema = localStorage.getItem('color-schema')
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
|
if (colorSchema) {
|
||||||
|
localStorage.setItem('color-schema', colorSchema)
|
||||||
|
}
|
||||||
location.reload()
|
location.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,9 +148,9 @@ function handleRefresh() {
|
|||||||
@prefix: ~'@{prefixCls}-basic-header';
|
@prefix: ~'@{prefixCls}-basic-header';
|
||||||
|
|
||||||
.@{prefix} {
|
.@{prefix} {
|
||||||
padding: 12px 16px;
|
padding: 0;
|
||||||
background-color: #f5f5f5;
|
background-color: var(--admin-bg-surface);
|
||||||
border-bottom: none;
|
border-bottom: 1px solid var(--admin-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-header-bar {
|
.mobile-header-bar {
|
||||||
@@ -153,17 +159,18 @@ function handleRefresh() {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
padding: 12px 16px;
|
width: 100%;
|
||||||
background: #fff;
|
padding: 10px 12px;
|
||||||
border: 1px solid #e8e8e8;
|
background: var(--admin-bg-surface);
|
||||||
border-radius: 16px;
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-header-bar__name {
|
.mobile-header-bar__name {
|
||||||
max-width: 34%;
|
max-width: 34%;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #1f1f1f;
|
color: var(--admin-text);
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -195,7 +202,7 @@ function handleRefresh() {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: #292d32;
|
color: var(--admin-text);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
|
|
||||||
@@ -203,4 +210,17 @@ function handleRefresh() {
|
|||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.hr-tamin-base-button.ant-btn-text) {
|
||||||
|
color: var(--admin-text-secondary);
|
||||||
|
background: transparent !important;
|
||||||
|
border-color: transparent !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: var(--admin-text);
|
||||||
|
background: var(--admin-bg-hover) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -92,11 +92,11 @@ function handleSelect(item: RouteRecordRaw) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mobile-overflow-menu__trigger--active {
|
.mobile-overflow-menu__trigger--active {
|
||||||
color: #1677ff;
|
color: var(--admin-menu-selected-text);
|
||||||
|
|
||||||
.mobile-overflow-menu__icon-wrap {
|
.mobile-overflow-menu__icon-wrap {
|
||||||
background: #e6f4ff;
|
background: var(--admin-menu-selected);
|
||||||
color: #1677ff;
|
color: var(--admin-menu-selected-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
@@ -108,7 +108,7 @@ function handleSelect(item: RouteRecordRaw) {
|
|||||||
width: 28px;
|
width: 28px;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
border-radius: 3px 3px 0 0;
|
border-radius: 3px 3px 0 0;
|
||||||
background: #1677ff;
|
background: var(--admin-menu-selected-text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative flex h-full min-h-0 min-w-0 w-full max-w-full flex-col overflow-hidden py-2 pr-3">
|
<div class="relative flex h-full min-h-0 min-w-0 w-full max-w-full flex-col overflow-hidden py-2 pr-3">
|
||||||
<div class="flex shrink-0 min-w-0 items-center justify-between gap-2">
|
<div class="flex shrink-0 min-w-0 items-center justify-between gap-2">
|
||||||
<div class="truncate text-black font-bold">{{ props.title }}</div>
|
<div class="truncate font-bold text-[var(--admin-text)]">{{ props.title }}</div>
|
||||||
<slot name="extra" />
|
<slot name="extra" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 min-h-0 flex-1 overflow-x-hidden overflow-y-auto p-1">
|
<div class="mt-2 min-h-0 flex-1 overflow-x-hidden overflow-y-auto p-1">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<article
|
<article
|
||||||
class="rounded-2xl border border-gray-200 bg-white shadow-sm"
|
class="rounded-2xl border-base surface shadow-sm"
|
||||||
:class="[paddingClass, clickable ? 'cursor-pointer' : '']"
|
:class="[paddingClass, clickable ? 'cursor-pointer' : '']"
|
||||||
@click="clickable ? $emit('click') : undefined"
|
@click="clickable ? $emit('click') : undefined"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
@import (less) './scroll.less';
|
@import (less) './scroll.less';
|
||||||
@import (less) "./fonts.less";
|
@import (less) "./fonts.less";
|
||||||
@import (less) './var.less';
|
@import (less) './var.less';
|
||||||
|
@import (less) './theme.less';
|
||||||
@import (less) './ant-override.less';
|
@import (less) './ant-override.less';
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,431 @@
|
|||||||
|
@import (less) './var.less';
|
||||||
|
|
||||||
|
html {
|
||||||
|
color-scheme: light;
|
||||||
|
--admin-primary: @gold-color-light;
|
||||||
|
--admin-gold: @gold-color;
|
||||||
|
--admin-gold-light: @gold-color-light;
|
||||||
|
--admin-gold-hover: @gold-color-hover;
|
||||||
|
--admin-bg-body: #f0f2f5;
|
||||||
|
--admin-bg-surface: #ffffff;
|
||||||
|
--admin-bg-elevated: #ffffff;
|
||||||
|
--admin-bg-muted: #fafafa;
|
||||||
|
--admin-bg-subtle: #f6f6f4;
|
||||||
|
--admin-bg-hover: #f5f5f5;
|
||||||
|
--admin-border: #f0f0f0;
|
||||||
|
--admin-border-strong: #d9d9d9;
|
||||||
|
--admin-text: rgba(0, 0, 0, 0.88);
|
||||||
|
--admin-text-secondary: rgba(0, 0, 0, 0.45);
|
||||||
|
--admin-text-muted: rgba(0, 0, 0, 0.65);
|
||||||
|
--admin-shadow: rgba(0, 0, 0, 0.06);
|
||||||
|
--admin-menu-selected: @gold-color-muted;
|
||||||
|
--admin-menu-selected-text: @gold-color-dark;
|
||||||
|
--admin-gradient-surface: #ffffff;
|
||||||
|
--admin-gradient-surface-fade: rgba(255, 255, 255, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
html.is-dark {
|
||||||
|
color-scheme: dark;
|
||||||
|
--admin-primary: @gold-color-light;
|
||||||
|
--admin-gold: @gold-color-light;
|
||||||
|
--admin-gold-light: @gold-color-hover;
|
||||||
|
--admin-gold-hover: #edd054;
|
||||||
|
--admin-bg-body: #141414;
|
||||||
|
--admin-bg-surface: #141414;
|
||||||
|
--admin-bg-elevated: #1f1f1f;
|
||||||
|
--admin-bg-muted: #262626;
|
||||||
|
--admin-bg-subtle: #1a1a1a;
|
||||||
|
--admin-bg-hover: rgba(201, 162, 39, 0.1);
|
||||||
|
--admin-border: rgba(201, 162, 39, 0.18);
|
||||||
|
--admin-border-strong: rgba(201, 162, 39, 0.32);
|
||||||
|
--admin-text: rgba(255, 255, 255, 0.85);
|
||||||
|
--admin-text-secondary: rgba(255, 255, 255, 0.45);
|
||||||
|
--admin-text-muted: rgba(255, 255, 255, 0.65);
|
||||||
|
--admin-shadow: rgba(0, 0, 0, 0.45);
|
||||||
|
--admin-menu-selected: @gold-color-light;
|
||||||
|
--admin-menu-selected-text: #141414;
|
||||||
|
--admin-gradient-surface: #141414;
|
||||||
|
--admin-gradient-surface-fade: rgba(20, 20, 20, 0.85);
|
||||||
|
|
||||||
|
--ant-primary-color: @gold-color-light;
|
||||||
|
--ant-primary-color-hover: @gold-color-hover;
|
||||||
|
--ant-primary-color-active: @gold-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--admin-bg-body);
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-layout-header.@{prefixCls}-basic-header {
|
||||||
|
padding: 0 12px !important;
|
||||||
|
line-height: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{prefixCls}-base-button {
|
||||||
|
display: inline-flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
height: auto !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn-primary {
|
||||||
|
background: var(--admin-gold-light) !important;
|
||||||
|
border-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn-primary:not([disabled]):hover,
|
||||||
|
.ant-btn-primary:not([disabled]):focus {
|
||||||
|
background: var(--admin-gold-hover) !important;
|
||||||
|
border-color: var(--admin-gold-hover) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn-primary:not([disabled]):active {
|
||||||
|
background: var(--admin-gold) !important;
|
||||||
|
border-color: var(--admin-gold) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-selected,
|
||||||
|
.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected > .ant-menu-submenu-title {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
background-color: var(--admin-menu-selected) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-selected::after,
|
||||||
|
.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected::after {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn {
|
||||||
|
color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-tabs-ink-bar {
|
||||||
|
background: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-bg-surface {
|
||||||
|
background-color: var(--admin-bg-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-bg-elevated {
|
||||||
|
background-color: var(--admin-bg-elevated);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-stat-muted {
|
||||||
|
background-color: var(--admin-bg-muted);
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-inner {
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||||
|
background: rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
html.is-dark {
|
||||||
|
.stat-inner {
|
||||||
|
border-color: var(--admin-border);
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-green-100 .stat-inner {
|
||||||
|
background: rgba(34, 197, 94, 0.12);
|
||||||
|
border-color: rgba(34, 197, 94, 0.22);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-red-100 .stat-inner {
|
||||||
|
background: rgba(239, 68, 68, 0.12);
|
||||||
|
border-color: rgba(239, 68, 68, 0.22);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-amber-100 .stat-inner {
|
||||||
|
background: rgba(245, 158, 11, 0.12);
|
||||||
|
border-color: rgba(245, 158, 11, 0.22);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-amber-100 {
|
||||||
|
background-color: rgba(245, 158, 11, 0.14) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-white\/70 {
|
||||||
|
background-color: rgba(255, 255, 255, 0.06) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-table-wrapper,
|
||||||
|
.ant-table,
|
||||||
|
.ant-table-container,
|
||||||
|
.ant-table-content,
|
||||||
|
.ant-table-thead > tr > th,
|
||||||
|
.ant-table-tbody > tr > td {
|
||||||
|
border-color: var(--admin-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-toolbar {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
.bg-white {
|
||||||
|
background-color: var(--admin-bg-elevated) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-green-100 {
|
||||||
|
background-color: rgba(34, 197, 94, 0.14) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-red-100 {
|
||||||
|
background-color: rgba(239, 68, 68, 0.14) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blue-100 {
|
||||||
|
background-color: rgba(59, 130, 246, 0.14) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-yellow-100 {
|
||||||
|
background-color: rgba(234, 179, 8, 0.14) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-orange-100,
|
||||||
|
.bg-orange-50 {
|
||||||
|
background-color: rgba(249, 115, 22, 0.14) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blue-50 {
|
||||||
|
background-color: rgba(59, 130, 246, 0.12) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-fuchsia-100 {
|
||||||
|
background-color: rgba(217, 70, 239, 0.14) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-100 {
|
||||||
|
background-color: var(--admin-bg-muted) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-50 {
|
||||||
|
background-color: var(--admin-bg-hover) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-50\/60 {
|
||||||
|
background-color: rgba(48, 48, 48, 0.65) !important;
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-gray-100,
|
||||||
|
.border-gray-200,
|
||||||
|
.border-gray-300 {
|
||||||
|
border-color: var(--admin-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-400,
|
||||||
|
.text-gray-500 {
|
||||||
|
color: var(--admin-text-secondary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-600,
|
||||||
|
.text-gray-700 {
|
||||||
|
color: var(--admin-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-800,
|
||||||
|
.text-gray-900 {
|
||||||
|
color: var(--admin-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-green-700 {
|
||||||
|
color: #4ade80 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-red-600 {
|
||||||
|
color: #f87171 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-light.ant-menu-horizontal {
|
||||||
|
background: transparent !important;
|
||||||
|
border-bottom: 1px solid var(--admin-border) !important;
|
||||||
|
color: var(--admin-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-light.ant-menu-horizontal > .ant-menu-item,
|
||||||
|
.ant-menu-light.ant-menu-horizontal > .ant-menu-submenu > .ant-menu-submenu-title {
|
||||||
|
color: var(--admin-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-light.ant-menu-horizontal > .ant-menu-item-selected,
|
||||||
|
.ant-menu-light.ant-menu-horizontal > .ant-menu-submenu-selected > .ant-menu-submenu-title {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
background: var(--admin-menu-selected) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-light.ant-menu-horizontal > .ant-menu-item-selected::after,
|
||||||
|
.ant-menu-light.ant-menu-horizontal > .ant-menu-submenu-selected::after {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-dark.ant-menu-horizontal {
|
||||||
|
background: transparent !important;
|
||||||
|
border-bottom: 1px solid var(--admin-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-dark.ant-menu-horizontal > .ant-menu-item,
|
||||||
|
.ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu > .ant-menu-submenu-title {
|
||||||
|
color: var(--admin-text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-dark.ant-menu-horizontal > .ant-menu-item-selected,
|
||||||
|
.ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu-selected > .ant-menu-submenu-title {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
background: var(--admin-menu-selected) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-dark.ant-menu-horizontal > .ant-menu-item-selected .ant-menu-item-icon,
|
||||||
|
.ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu-selected .ant-menu-item-icon,
|
||||||
|
.ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu-selected .ant-menu-submenu-arrow {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-dark.ant-menu-horizontal > .ant-menu-item-selected::after,
|
||||||
|
.ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu-selected::after {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-modal-content,
|
||||||
|
.ant-modal-header,
|
||||||
|
.ant-modal-body {
|
||||||
|
background-color: #1f1f1f !important;
|
||||||
|
color: rgba(255, 255, 255, 0.85) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-modal-footer {
|
||||||
|
background-color: #1f1f1f !important;
|
||||||
|
border-top: 1px solid var(--admin-border-strong) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-modal-title,
|
||||||
|
.ant-modal-close-x {
|
||||||
|
color: rgba(255, 255, 255, 0.85) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-tabs-tab {
|
||||||
|
color: rgba(255, 255, 255, 0.65) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn {
|
||||||
|
color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-tabs-ink-bar {
|
||||||
|
background: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-card {
|
||||||
|
background: #1f1f1f !important;
|
||||||
|
border-color: var(--admin-border-strong) !important;
|
||||||
|
color: rgba(255, 255, 255, 0.85) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-card-body {
|
||||||
|
padding: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-card-head {
|
||||||
|
background: #1f1f1f !important;
|
||||||
|
border-color: var(--admin-border-strong) !important;
|
||||||
|
color: rgba(255, 255, 255, 0.85) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-input,
|
||||||
|
.ant-input-affix-wrapper,
|
||||||
|
.ant-select-selector,
|
||||||
|
.ant-picker,
|
||||||
|
.ant-divider {
|
||||||
|
border-color: var(--admin-border-strong) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-descriptions-item-label,
|
||||||
|
.ant-descriptions-item-content {
|
||||||
|
color: rgba(255, 255, 255, 0.85) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu-nav .ant-menu-horizontal > .ant-menu-item,
|
||||||
|
.top-menu-nav .ant-menu-horizontal > .ant-menu-submenu,
|
||||||
|
.top-menu-nav .ant-menu-horizontal > .ant-menu-submenu > .ant-menu-submenu-title {
|
||||||
|
padding: 0 10px !important;
|
||||||
|
height: 36px !important;
|
||||||
|
line-height: 36px !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
top: 0 !important;
|
||||||
|
transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected,
|
||||||
|
.ant-menu.ant-menu-dark .ant-menu-item-selected {
|
||||||
|
background-color: var(--admin-menu-selected) !important;
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected .ant-menu-item-icon,
|
||||||
|
.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected .anticon,
|
||||||
|
.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected .ant-menu-title-content,
|
||||||
|
.ant-menu.ant-menu-dark .ant-menu-item-selected .ant-menu-item-icon,
|
||||||
|
.ant-menu.ant-menu-dark .ant-menu-item-selected .anticon,
|
||||||
|
.ant-menu.ant-menu-dark .ant-menu-item-selected .ant-menu-title-content {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-dark .ant-menu-item:not(.ant-menu-item-selected):hover,
|
||||||
|
.ant-menu-dark .ant-menu-submenu:not(.ant-menu-submenu-selected) > .ant-menu-submenu-title:hover {
|
||||||
|
background-color: var(--admin-bg-hover) !important;
|
||||||
|
color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
background: var(--admin-gold-light) !important;
|
||||||
|
border-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover,
|
||||||
|
.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
background: var(--admin-gold-hover) !important;
|
||||||
|
border-color: var(--admin-gold-hover) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before,
|
||||||
|
.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover::before,
|
||||||
|
.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active::before {
|
||||||
|
background-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-radio-button-wrapper:hover {
|
||||||
|
color: var(--admin-gold-hover) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) {
|
||||||
|
color: var(--admin-gold-light) !important;
|
||||||
|
border-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before {
|
||||||
|
background-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-input:focus,
|
||||||
|
.ant-input-focused,
|
||||||
|
.ant-input-affix-wrapper-focused,
|
||||||
|
.ant-input-affix-wrapper:focus,
|
||||||
|
.ant-select-focused:not(.ant-select-disabled) .ant-select-selector,
|
||||||
|
.ant-picker-focused {
|
||||||
|
border-color: var(--admin-gold-light) !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(212, 175, 55, 0.18) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,9 +26,15 @@ html{
|
|||||||
@header-height:56px;
|
@header-height:56px;
|
||||||
@prefixCls-font-family: 'iran-sans';
|
@prefixCls-font-family: 'iran-sans';
|
||||||
@ant-prefix: @prefixCls;
|
@ant-prefix: @prefixCls;
|
||||||
@primary-color:#2563eb; // #727071; //#abc2f7; //#f4474d;
|
@gold-color: #c9a227;
|
||||||
@second-color: #3b82f6; // #727071; //#abc2f7; //#f4474d;
|
@gold-color-light: #d4af37;
|
||||||
@third-color: #B2B2B2; // #727071; //#abc2f7; //#f4474d;
|
@gold-color-hover: #e0bc3a;
|
||||||
|
@gold-color-dark: #92670a;
|
||||||
|
@gold-color-muted: rgba(201, 162, 39, 0.14);
|
||||||
|
|
||||||
|
@primary-color: @gold-color-light;
|
||||||
|
@second-color: @gold-color-hover;
|
||||||
|
@third-color: @gold-color;
|
||||||
|
|
||||||
@bg-color-1: #F9FAFB;
|
@bg-color-1: #F9FAFB;
|
||||||
@bg-color-2: #F6F6F4;
|
@bg-color-2: #F6F6F4;
|
||||||
@@ -37,10 +43,10 @@ html{
|
|||||||
@border-radius-base: 4px;
|
@border-radius-base: 4px;
|
||||||
|
|
||||||
html{
|
html{
|
||||||
--ant-primary-color:@primary-color;
|
--ant-primary-color: @gold-color-light;
|
||||||
--ant-primary-color-hover:@second-color;
|
--ant-primary-color-hover: @gold-color-hover;
|
||||||
--ant-primary-color-active:@third-color;
|
--ant-primary-color-active: @gold-color;
|
||||||
--ant-primary-1:#f2f3ff;//#f6f6f4;
|
--ant-primary-1: rgba(201, 162, 39, 0.12);
|
||||||
--border-radius-base:@border-radius-base;
|
--border-radius-base:@border-radius-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<AButton :type="props.type" :size="props.size" :class="[prefixCls, _class]">
|
<AButton
|
||||||
<!-- py-1 px-2-->
|
:type="props.type"
|
||||||
<div
|
:size="props.size"
|
||||||
class="flex items-center gap-1 justify-center flex-row-reverse gap-2 py-1 px-2"
|
:class="[prefixCls, _class, { [`${prefixCls}--icon-suffix`]: suffixIcon }]"
|
||||||
:class="[{ 'flex-row-reverse': suffixIcon }]"
|
>
|
||||||
>
|
<span v-if="icon && !suffixIcon" class="base-button__icon">
|
||||||
<slot v-if="$slots.default"></slot>
|
<BaseIcon :size="resolvedIconSize" :icon="icon" :class="iconClass" />
|
||||||
|
</span>
|
||||||
<BaseIcon :size="iconSize" :icon="icon" v-if="icon" :class="iconClass" />
|
<span v-if="$slots.default" class="base-button__label">
|
||||||
</div>
|
<slot />
|
||||||
|
</span>
|
||||||
|
<span v-if="icon && suffixIcon" class="base-button__icon">
|
||||||
|
<BaseIcon :size="resolvedIconSize" :icon="icon" :class="iconClass" />
|
||||||
|
</span>
|
||||||
</AButton>
|
</AButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { usePrefix } from '@core/composable/usePrefix'
|
import { usePrefix } from '@core/composable/usePrefix'
|
||||||
import { computed } from 'vue'
|
import { computed, useSlots } from 'vue'
|
||||||
import { baseButtonIconSize } from '@root/config'
|
import { baseButtonIconSize } from '@root/config'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -24,7 +28,6 @@ interface Props {
|
|||||||
suffixIcon?: boolean
|
suffixIcon?: boolean
|
||||||
type?: string
|
type?: string
|
||||||
size?: string
|
size?: string
|
||||||
// prefixIcon?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const slot = useSlots()
|
const slot = useSlots()
|
||||||
@@ -40,17 +43,74 @@ const { prefixCls } = usePrefix('base-button')
|
|||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
iconSize: baseButtonIconSize,
|
iconSize: baseButtonIconSize,
|
||||||
// iconLeft: false,
|
|
||||||
iconClass: ''
|
iconClass: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const resolvedIconSize = computed(() => {
|
||||||
|
if (props.iconSize !== baseButtonIconSize) {
|
||||||
|
return props.iconSize
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (props.size) {
|
||||||
|
case 'small':
|
||||||
|
return '16'
|
||||||
|
case 'large':
|
||||||
|
return '20'
|
||||||
|
default:
|
||||||
|
return '18'
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@prefix:~'@{prefixCls}-base-button';
|
@prefix:~'@{prefixCls}-base-button';
|
||||||
.@{prefix}{
|
|
||||||
//width: fit-content;
|
.@{prefix} {
|
||||||
padding: 0;
|
display: inline-flex !important;
|
||||||
height: auto;
|
align-items: center !important;
|
||||||
/*padding: 8px;*/
|
justify-content: center !important;
|
||||||
|
gap: 6px;
|
||||||
|
height: auto !important;
|
||||||
|
min-height: 32px;
|
||||||
|
padding: 4px 15px !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: visible;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
&.ant-btn-sm {
|
||||||
|
min-height: 32px;
|
||||||
|
padding: 5px 12px !important;
|
||||||
|
font-size: 14px;
|
||||||
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.ant-btn-lg {
|
||||||
|
min-height: 40px;
|
||||||
|
padding: 6px 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--icon-suffix {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.base-button__icon {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
:deep(.hr-tamin-icons),
|
||||||
|
:deep(svg) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.base-button__label {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 1 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
//todo convert to async load
|
//todo convert to async load
|
||||||
import icons from '@core/assets/icons/icon.json'
|
import icons from '@core/assets/icons/icon.json'
|
||||||
import { usePrefix } from '@core/composable/usePrefix'
|
import { usePrefix } from '@core/composable/usePrefix'
|
||||||
import { computed, onMounted, ref } from 'vue'
|
import { computed, nextTick, onMounted, ref, watch } from 'vue'
|
||||||
import { baseIconSize } from '@root/config'
|
import { baseIconSize } from '@root/config'
|
||||||
interface Props {
|
interface Props {
|
||||||
icon: string
|
icon: string
|
||||||
@@ -27,20 +27,37 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
const { prefixCls } = usePrefix('icons')
|
const { prefixCls } = usePrefix('icons')
|
||||||
const tempIcon = ref<string>()
|
const tempIcon = ref<string>()
|
||||||
const refIcon = ref<HTMLDivElement>()
|
const refIcon = ref<HTMLDivElement>()
|
||||||
//@ts-ignore
|
|
||||||
tempIcon.value = icons[`${props.icon}`] as string
|
function resolveIcon(iconName: string) {
|
||||||
|
return icons[`${iconName}` as keyof typeof icons] as string
|
||||||
|
}
|
||||||
|
|
||||||
|
function applySize() {
|
||||||
|
if (!props.size || !refIcon.value) return
|
||||||
|
|
||||||
|
const svg = refIcon.value.children[0] as SVGElement | undefined
|
||||||
|
if (!svg) return
|
||||||
|
|
||||||
|
svg.setAttribute('width', String(props.size))
|
||||||
|
svg.setAttribute('height', String(props.size))
|
||||||
|
}
|
||||||
|
|
||||||
|
tempIcon.value = resolveIcon(props.icon)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.icon,
|
||||||
|
(iconName) => {
|
||||||
|
tempIcon.value = resolveIcon(iconName)
|
||||||
|
nextTick(() => applySize())
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const color = computed(() => {
|
const color = computed(() => {
|
||||||
return props.color
|
return props.color
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.size) {
|
applySize()
|
||||||
const svg: SVGElement = refIcon.value?.children[0] as SVGElement
|
|
||||||
// console.log(svg)
|
|
||||||
svg.setAttribute('width', props.size as string)
|
|
||||||
svg.setAttribute('height', props.size as string)
|
|
||||||
// console.log(props.icon)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div :class="[prefixCls, 'min-w-0 max-w-full']">
|
<div :class="[prefixCls, 'min-w-0 max-w-full']">
|
||||||
<ASpin tip="در حال دریافت اطلاعات..." :indicator="indicator" :spinning="loading">
|
<ASpin tip="در حال دریافت اطلاعات..." :indicator="indicator" :spinning="loading">
|
||||||
<div class="scrollable-container" id="components-affix-demo-target" ref="containerRef">
|
<div class="scrollable-container" id="components-affix-demo-target" ref="containerRef">
|
||||||
<div class="table-toolbar sticky top-0 z-10 mb-2 shrink-0 bg-white">
|
<div class="table-toolbar sticky top-0 z-10 mb-2 shrink-0">
|
||||||
<div class="flex flex-col gap-2 xl:flex-row xl:items-center xl:justify-between">
|
<div class="flex flex-col gap-2 xl:flex-row xl:items-center xl:justify-between">
|
||||||
<div
|
<div
|
||||||
v-if="showOptionHeader"
|
v-if="showOptionHeader"
|
||||||
@@ -707,12 +707,16 @@ defineExpose({
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-toolbar {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.table-toolbar-extra:empty {
|
.table-toolbar-extra:empty {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-table-wrapper {
|
.ant-table-wrapper {
|
||||||
border: 1px solid #eee;
|
border: 1px solid var(--admin-border);
|
||||||
border-radius: var(--border-radius-base);
|
border-radius: var(--border-radius-base);
|
||||||
}
|
}
|
||||||
.ant-spin-container,
|
.ant-spin-container,
|
||||||
|
|||||||
@@ -673,7 +673,7 @@ defineExpose({
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.ant-table-wrapper {
|
.ant-table-wrapper {
|
||||||
border: 1px solid #eee;
|
border: 1px solid var(--admin-border);
|
||||||
border-radius: var(--border-radius-base);
|
border-radius: var(--border-radius-base);
|
||||||
}
|
}
|
||||||
.ant-spin-container,
|
.ant-spin-container,
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<AMenuItemGroup title="پوسته">
|
||||||
|
<AMenuItem
|
||||||
|
v-for="opt in themeOptions"
|
||||||
|
:key="opt.value"
|
||||||
|
@click="darkmode.setSchema(opt.value)"
|
||||||
|
>
|
||||||
|
<div class="theme-menu-item" :class="{ 'theme-menu-item--active': colorSchema === opt.value }">
|
||||||
|
<div class="theme-menu-item__main">
|
||||||
|
<Icon :icon="opt.icon" size="18" />
|
||||||
|
<span>{{ opt.label }}</span>
|
||||||
|
</div>
|
||||||
|
<Icon
|
||||||
|
v-if="colorSchema === opt.value"
|
||||||
|
icon="vuesax-linear:tick-circle"
|
||||||
|
size="16"
|
||||||
|
class="theme-menu-item__check"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</AMenuItem>
|
||||||
|
<AMenuItem v-if="colorSchema === 'auto'" disabled class="theme-menu-hint-item">
|
||||||
|
<span class="theme-menu-hint">وضعیت فعلی: {{ isDark ? 'تاریک' : 'روشن' }}</span>
|
||||||
|
</AMenuItem>
|
||||||
|
</AMenuItemGroup>
|
||||||
|
<AMenuDivider />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||||
|
import { useAdminTheme } from '@core/composable/useAdminTheme'
|
||||||
|
import type { DarkModeSchema } from '@core/stores/darkmode'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
|
const { isDark, darkmode } = useAdminTheme()
|
||||||
|
const { colorSchema } = storeToRefs(darkmode)
|
||||||
|
|
||||||
|
const themeOptions: Array<{ value: DarkModeSchema; label: string; icon: string }> = [
|
||||||
|
{ value: 'light', label: 'روشن', icon: 'vuesax-linear:sun-1' },
|
||||||
|
{ value: 'dark', label: 'تاریک', icon: 'vuesax-linear:moon' },
|
||||||
|
{ value: 'auto', label: 'سیستم', icon: 'vuesax-linear:monitor' }
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.theme-menu-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-menu-item__main {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-menu-item--active {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-menu-item__check {
|
||||||
|
color: var(--admin-gold-light, #d4af37);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-menu-hint-item {
|
||||||
|
height: auto !important;
|
||||||
|
line-height: 1.3 !important;
|
||||||
|
cursor: default !important;
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-menu-hint {
|
||||||
|
font-size: 11px;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
html.is-dark .theme-menu-hint {
|
||||||
|
color: rgba(255, 255, 255, 0.45);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
<template>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<span v-if="showLabel" class="theme-toggle__label">پوسته</span>
|
||||||
|
<APopover
|
||||||
|
v-model:open="open"
|
||||||
|
trigger="click"
|
||||||
|
placement="bottomLeft"
|
||||||
|
overlay-class-name="theme-toggle-popover"
|
||||||
|
>
|
||||||
|
<template #content>
|
||||||
|
<div class="theme-toggle__menu">
|
||||||
|
<button
|
||||||
|
v-for="opt in themeOptions"
|
||||||
|
:key="opt.value"
|
||||||
|
type="button"
|
||||||
|
class="theme-toggle__option"
|
||||||
|
:class="{ 'theme-toggle__option--active': colorSchema === opt.value }"
|
||||||
|
@click="selectSchema(opt.value)"
|
||||||
|
>
|
||||||
|
<BaseIcon :icon="opt.icon" size="18" />
|
||||||
|
<span>{{ opt.label }}</span>
|
||||||
|
</button>
|
||||||
|
<div v-if="colorSchema === 'auto'" class="theme-toggle__hint">
|
||||||
|
وضعیت فعلی: {{ isDark ? 'تاریک' : 'روشن' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<BaseButton
|
||||||
|
type="text"
|
||||||
|
:icon="triggerIcon"
|
||||||
|
icon-size="20"
|
||||||
|
aria-label="انتخاب پوسته"
|
||||||
|
/>
|
||||||
|
</APopover>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import BaseIcon from '@core/components/BaseIcon/src/Icon.vue'
|
||||||
|
import { useAdminTheme } from '@core/composable/useAdminTheme'
|
||||||
|
import type { DarkModeSchema } from '@core/stores/darkmode'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
|
withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
showLabel?: boolean
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
showLabel: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const open = ref(false)
|
||||||
|
const { isDark, darkmode } = useAdminTheme()
|
||||||
|
const { colorSchema } = storeToRefs(darkmode)
|
||||||
|
|
||||||
|
const themeOptions: Array<{ value: DarkModeSchema; label: string; icon: string }> = [
|
||||||
|
{ value: 'light', label: 'روشن', icon: 'vuesax-linear:sun-1' },
|
||||||
|
{ value: 'dark', label: 'تاریک', icon: 'vuesax-linear:moon' },
|
||||||
|
{ value: 'auto', label: 'سیستم', icon: 'vuesax-linear:monitor' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const triggerIcon = computed(() => {
|
||||||
|
if (colorSchema.value === 'dark') return 'vuesax-linear:moon'
|
||||||
|
if (colorSchema.value === 'light') return 'vuesax-linear:sun-1'
|
||||||
|
return 'vuesax-linear:monitor'
|
||||||
|
})
|
||||||
|
|
||||||
|
function selectSchema(schema: DarkModeSchema) {
|
||||||
|
darkmode.setSchema(schema)
|
||||||
|
open.value = false
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.theme-toggle {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle__label {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--admin-text-secondary);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle__menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
min-width: 9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle__option {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--admin-text);
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.15s ease, color 0.15s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--admin-bg-hover);
|
||||||
|
color: var(--admin-gold-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
background: var(--admin-menu-selected);
|
||||||
|
color: var(--admin-menu-selected-text);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle__hint {
|
||||||
|
margin-top: 4px;
|
||||||
|
padding-top: 8px;
|
||||||
|
border-top: 1px solid var(--admin-border);
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--admin-text-secondary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.theme-toggle-popover {
|
||||||
|
.ant-popover-inner {
|
||||||
|
background: var(--admin-bg-elevated);
|
||||||
|
border: 1px solid var(--admin-border-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-popover-inner-content {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-popover-arrow-content::before {
|
||||||
|
background: var(--admin-bg-elevated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { computed } from 'vue'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { useDarkmode } from '@core/stores/darkmode'
|
||||||
|
|
||||||
|
export function useAdminTheme() {
|
||||||
|
const darkmode = useDarkmode()
|
||||||
|
const { isDark, colorSchema } = storeToRefs(darkmode)
|
||||||
|
|
||||||
|
const menuTheme = computed(() => (isDark.value ? 'dark' : 'light') as 'dark' | 'light')
|
||||||
|
|
||||||
|
return {
|
||||||
|
isDark,
|
||||||
|
colorSchema,
|
||||||
|
menuTheme,
|
||||||
|
darkmode,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex items-center justify-between gap-3">
|
||||||
|
<span class="text-gray-400 text-sm">حالت نمایش</span>
|
||||||
|
<ARadioGroup v-model:value="colorSchema" size="small">
|
||||||
|
<ARadioButton value="light">روشن</ARadioButton>
|
||||||
|
<ARadioButton value="dark">تاریک</ARadioButton>
|
||||||
|
<ARadioButton value="auto">خودکار</ARadioButton>
|
||||||
|
</ARadioGroup>
|
||||||
|
</div>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<span class="text-gray-400 text-sm">نوار کناری (Sidebar)</span>
|
<span class="text-gray-400 text-sm">نوار کناری (Sidebar)</span>
|
||||||
<ASwitch :checked="true" size="small" />
|
<ASwitch :checked="true" size="small" />
|
||||||
@@ -59,10 +67,14 @@
|
|||||||
import { usePrefix } from '@core/composable/usePrefix'
|
import { usePrefix } from '@core/composable/usePrefix'
|
||||||
import { useSettingsStore } from '@core/stores/settings'
|
import { useSettingsStore } from '@core/stores/settings'
|
||||||
import { useLayoutStore } from '@core/stores/layout'
|
import { useLayoutStore } from '@core/stores/layout'
|
||||||
|
import { useDarkmode } from '@core/stores/darkmode'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
//const visible = ref<boolean>(false)
|
//const visible = ref<boolean>(false)
|
||||||
const { prefixCls } = usePrefix('base-settings')
|
const { prefixCls } = usePrefix('base-settings')
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
const layoutStore = useLayoutStore()
|
const layoutStore = useLayoutStore()
|
||||||
|
const darkmode = useDarkmode()
|
||||||
|
const { colorSchema } = storeToRefs(darkmode)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@@ -71,7 +83,7 @@ const layoutStore = useLayoutStore()
|
|||||||
|
|
||||||
.layout-item{
|
.layout-item{
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border:2px solid #eee;
|
border:2px solid var(--admin-border);
|
||||||
padding:5px;
|
padding:5px;
|
||||||
&.active{
|
&.active{
|
||||||
border-color: @primary-color;
|
border-color: @primary-color;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<!-- :class="[, isMobile ? null : 'shadow']"-->
|
<!-- :class="[, isMobile ? null : 'shadow']"-->
|
||||||
<!-- :theme="sideTheme"-->
|
<!-- :theme="sideTheme"-->
|
||||||
<ALayoutSider
|
<ALayoutSider
|
||||||
theme="light"
|
:theme="menuTheme"
|
||||||
:class="[prefixCls]"
|
:class="[prefixCls]"
|
||||||
:width="layoutStore.sideMenu.width"
|
:width="layoutStore.sideMenu.width"
|
||||||
:collapsible="layoutStore.sideMenu.collapsible"
|
:collapsible="layoutStore.sideMenu.collapsible"
|
||||||
@@ -96,10 +96,12 @@
|
|||||||
import { useLayoutStore } from '@core/stores/layout'
|
import { useLayoutStore } from '@core/stores/layout'
|
||||||
import { usePrefix } from '@core/composable/usePrefix'
|
import { usePrefix } from '@core/composable/usePrefix'
|
||||||
import BasicMenu from '@core/layouts/composnts/BasicMenu.vue'
|
import BasicMenu from '@core/layouts/composnts/BasicMenu.vue'
|
||||||
|
import { useAdminTheme } from '@core/composable/useAdminTheme'
|
||||||
//import { coreVersion, version } from '../utils'
|
//import { coreVersion, version } from '../utils'
|
||||||
//import { isDate } from 'lodash'
|
//import { isDate } from 'lodash'
|
||||||
const layoutStore = useLayoutStore()
|
const layoutStore = useLayoutStore()
|
||||||
const { prefixCls } = usePrefix('basic-side-menu')
|
const { prefixCls } = usePrefix('basic-side-menu')
|
||||||
|
const { menuTheme } = useAdminTheme()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@@ -124,13 +126,13 @@ const { prefixCls } = usePrefix('basic-side-menu')
|
|||||||
}
|
}
|
||||||
|
|
||||||
.logo{
|
.logo{
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid var(--admin-border);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-version{
|
.side-version{
|
||||||
border-top: 1px solid #eee;
|
border-top: 1px solid var(--admin-border);
|
||||||
@apply p-2;
|
@apply p-2;
|
||||||
max-height: 50px
|
max-height: 50px
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<ALayoutHeader
|
<ALayoutHeader
|
||||||
theme="light"
|
:theme="menuTheme"
|
||||||
:class="[prefixCls]"
|
:class="[prefixCls]"
|
||||||
:style="`height:${layoutStore.header.height};line-height:${layoutStore.header.height}`"
|
:style="`height:${layoutStore.header.height}`"
|
||||||
>
|
>
|
||||||
<!-- :style="`height:${layoutStore.header.height};line-height:${layoutStore.header.height}`"-->
|
<!-- :style="`height:${layoutStore.header.height};line-height:${layoutStore.header.height}`"-->
|
||||||
<div class="flex w-full min-w-0 items-center overflow-hidden">
|
<div class="flex w-full min-w-0 items-center overflow-hidden">
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
<ADropdown placement="bottomLeft" class="ml-5">
|
<ADropdown placement="bottomLeft" class="ml-5">
|
||||||
<a class="ant-dropdown-link" @click.prevent>
|
<a class="ant-dropdown-link" @click.prevent>
|
||||||
<!-- Hover me-->
|
<!-- Hover me-->
|
||||||
<div class="flex items-center gap-1 text-gray-400">
|
<div class="flex items-center gap-1 text-[var(--admin-text-secondary)]">
|
||||||
<AAvatar :src="placeholderM" />
|
<AAvatar :src="placeholderM" class="header-avatar" />
|
||||||
<Icon icon="vuesax-linear:arrow-down" size="15" />
|
<Icon icon="vuesax-linear:arrow-down" size="15" />
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</AMenuItem>
|
</AMenuItem>
|
||||||
<AMenuDivider />
|
<AMenuDivider />
|
||||||
|
<ThemeMenuSection />
|
||||||
<AMenuItem @click="myInfoVisible = true">
|
<AMenuItem @click="myInfoVisible = true">
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<Icon icon="vuesax-linear:profile" size="18" />
|
<Icon icon="vuesax-linear:profile" size="18" />
|
||||||
@@ -164,11 +165,14 @@ import type { FormInstance } from 'ant-design-vue'
|
|||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import { useWindowSize } from '@vueuse/core'
|
import { useWindowSize } from '@vueuse/core'
|
||||||
import {getConfigApp} from "@/utils/config";
|
import {getConfigApp} from "@/utils/config";
|
||||||
|
import ThemeMenuSection from '@core/components/ThemeMenuSection.vue'
|
||||||
|
import { useAdminTheme } from '@core/composable/useAdminTheme'
|
||||||
const { prefixCls } = usePrefix('basic-header')
|
const { prefixCls } = usePrefix('basic-header')
|
||||||
const layoutStore = useLayoutStore()
|
const layoutStore = useLayoutStore()
|
||||||
const store = useStaticApiListsStore()
|
const store = useStaticApiListsStore()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
|
const { menuTheme } = useAdminTheme()
|
||||||
|
|
||||||
|
|
||||||
const { width } = useWindowSize()
|
const { width } = useWindowSize()
|
||||||
@@ -223,7 +227,11 @@ function handleShowSettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearLocalStorage() {
|
function clearLocalStorage() {
|
||||||
|
const colorSchema = localStorage.getItem('color-schema')
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
|
if (colorSchema) {
|
||||||
|
localStorage.setItem('color-schema', colorSchema)
|
||||||
|
}
|
||||||
location.reload()
|
location.reload()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -232,16 +240,35 @@ function clearLocalStorage() {
|
|||||||
@prefix: ~'@{prefixCls}-basic-header';
|
@prefix: ~'@{prefixCls}-basic-header';
|
||||||
|
|
||||||
.@{prefix} {
|
.@{prefix} {
|
||||||
padding: unset;
|
padding: 0 12px !important;
|
||||||
|
line-height: normal !important;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
//height: unset;
|
display: flex;
|
||||||
//@apply flex flex-col justify-center ;
|
align-items: center;
|
||||||
//height: 64px;
|
border-bottom: 1px solid var(--admin-border);
|
||||||
//line-height: unset;
|
background-color: var(--admin-bg-surface);
|
||||||
border-bottom: 2px solid #eee;
|
|
||||||
// height: @header-height;
|
> .flex {
|
||||||
background-color: #fff;
|
height: 100%;
|
||||||
//@apply backdrop-blur bg-red-200;
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-avatar {
|
||||||
|
border: 2px solid var(--admin-border-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hr-tamin-base-button.ant-btn-text {
|
||||||
|
color: var(--admin-text-secondary);
|
||||||
|
background: transparent !important;
|
||||||
|
border-color: transparent !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: var(--admin-text);
|
||||||
|
background: var(--admin-bg-hover) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
>
|
>
|
||||||
<AMenu
|
<AMenu
|
||||||
:mode="layoutStore.sideMenu.mode"
|
:mode="layoutStore.sideMenu.mode"
|
||||||
|
:theme="menuTheme"
|
||||||
v-model:selectedKeys="selectedKeys"
|
v-model:selectedKeys="selectedKeys"
|
||||||
:disabled-overflow="isTopMenu"
|
:disabled-overflow="isTopMenu"
|
||||||
>
|
>
|
||||||
@@ -64,6 +65,7 @@ import { useLayoutStore } from '@core/stores/layout'
|
|||||||
import BaseMenuItem from '@core/layouts/composnts/BaseMenuItem.vue'
|
import BaseMenuItem from '@core/layouts/composnts/BaseMenuItem.vue'
|
||||||
import type { RouteRecordName, RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordName, RouteRecordRaw } from 'vue-router'
|
||||||
import { useRouterStore } from '@core/stores/router'
|
import { useRouterStore } from '@core/stores/router'
|
||||||
|
import { useAdminTheme } from '@core/composable/useAdminTheme'
|
||||||
|
|
||||||
const SCROLL_STEP = 180
|
const SCROLL_STEP = 180
|
||||||
const EDGE_THRESHOLD = 2
|
const EDGE_THRESHOLD = 2
|
||||||
@@ -73,6 +75,7 @@ const layoutStore = useLayoutStore()
|
|||||||
const currentRoute = useRoute()
|
const currentRoute = useRoute()
|
||||||
const selectedKeys = ref<(RouteRecordName | undefined)[]>([])
|
const selectedKeys = ref<(RouteRecordName | undefined)[]>([])
|
||||||
const routerStore = useRouterStore()
|
const routerStore = useRouterStore()
|
||||||
|
const { menuTheme } = useAdminTheme()
|
||||||
const menuScrollRef = ref<HTMLElement | null>(null)
|
const menuScrollRef = ref<HTMLElement | null>(null)
|
||||||
const showLeftArrow = ref(false)
|
const showLeftArrow = ref(false)
|
||||||
const showRightArrow = ref(false)
|
const showRightArrow = ref(false)
|
||||||
@@ -224,6 +227,77 @@ useResizeObserver(menuScrollRef, () => {
|
|||||||
position: relative;
|
position: relative;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.top-menu-scroll .ant-menu.ant-menu-horizontal {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
width: max-content;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
border-bottom: none !important;
|
||||||
|
padding: 0 4px !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu-scroll .ant-menu-horizontal > .ant-menu-item,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal > .ant-menu-submenu,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal > .ant-menu-submenu > .ant-menu-submenu-title {
|
||||||
|
top: 0 !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
height: 36px !important;
|
||||||
|
line-height: 36px !important;
|
||||||
|
padding: 0 10px !important;
|
||||||
|
margin-inline: 2px !important;
|
||||||
|
border-radius: 6px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
transition: background-color 0.15s ease, color 0.15s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu-scroll .ant-menu-horizontal > .ant-menu-item::after,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal > .ant-menu-submenu::after {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu-scroll .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-selected,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected {
|
||||||
|
background-color: var(--admin-menu-selected);
|
||||||
|
color: var(--admin-menu-selected-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu-scroll .ant-menu-horizontal.ant-menu-dark > .ant-menu-item-selected,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal.ant-menu-dark > .ant-menu-submenu-selected > .ant-menu-submenu-title {
|
||||||
|
background-color: var(--admin-menu-selected) !important;
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu-scroll .ant-menu-horizontal.ant-menu-dark > .ant-menu-item-selected .ant-menu-item-icon,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal.ant-menu-dark > .ant-menu-submenu-selected .ant-menu-item-icon,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal.ant-menu-dark > .ant-menu-submenu-selected .ant-menu-submenu-arrow {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu-scroll .ant-menu-horizontal.ant-menu-dark > .ant-menu-item:not(.ant-menu-item-selected):hover,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal.ant-menu-dark > .ant-menu-submenu:not(.ant-menu-submenu-selected):hover > .ant-menu-submenu-title {
|
||||||
|
background-color: var(--admin-bg-hover) !important;
|
||||||
|
color: var(--admin-gold-light) !important;
|
||||||
|
box-shadow: inset 0 0 0 1px var(--admin-border-strong) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu-scroll .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-selected::after,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected::after {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu-scroll .ant-menu-horizontal .ant-menu-item-icon + .ant-menu-title-content,
|
||||||
|
.top-menu-scroll .ant-menu-horizontal .ant-menu-item-icon + span {
|
||||||
|
margin-inline-start: 6px !important;
|
||||||
|
margin-inline-end: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-menu-nav__btn {
|
.top-menu-nav__btn {
|
||||||
@@ -233,31 +307,31 @@ useResizeObserver(menuScrollRef, () => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 30px;
|
width: 28px;
|
||||||
height: 36px;
|
height: 32px;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: #fff;
|
background: var(--admin-bg-elevated);
|
||||||
color: @primary-color;
|
color: var(--admin-gold-light);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06);
|
box-shadow: 0 0 0 1px var(--admin-border);
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.2s ease;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: lighten(@primary-color, 53%);
|
background: var(--admin-bg-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
&--left {
|
&--left {
|
||||||
left: 0;
|
left: 0;
|
||||||
padding-right: 4px;
|
padding-right: 2px;
|
||||||
background: linear-gradient(to right, #fff 55%, rgba(255, 255, 255, 0.85));
|
background: linear-gradient(to right, var(--admin-gradient-surface) 60%, var(--admin-gradient-surface-fade));
|
||||||
}
|
}
|
||||||
|
|
||||||
&--right {
|
&--right {
|
||||||
right: 0;
|
right: 0;
|
||||||
padding-left: 4px;
|
padding-left: 2px;
|
||||||
background: linear-gradient(to left, #fff 55%, rgba(255, 255, 255, 0.85));
|
background: linear-gradient(to left, var(--admin-gradient-surface) 60%, var(--admin-gradient-surface-fade));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,48 +341,14 @@ useResizeObserver(menuScrollRef, () => {
|
|||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-menu {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
width: max-content;
|
|
||||||
border-bottom: none;
|
|
||||||
padding-top: 4px;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item,
|
|
||||||
.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu {
|
|
||||||
padding: 0 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-menu-horizontal > .ant-menu-item::after,
|
|
||||||
.ant-menu-horizontal > .ant-menu-submenu::after {
|
|
||||||
right: 0 !important;
|
|
||||||
left: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-menu-horizontal > .ant-menu-item-selected::after,
|
|
||||||
.ant-menu-horizontal > .ant-menu-submenu-selected::after {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
border-bottom: 2px solid @primary-color;
|
|
||||||
transition: border-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-menu-item-selected {
|
|
||||||
background-color: lighten(@primary-color, 53%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-menu-item {
|
|
||||||
margin-left: 12px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-menu-item,
|
.ant-menu-item,
|
||||||
@@ -321,40 +361,34 @@ useResizeObserver(menuScrollRef, () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** start style for horizontal menu */
|
|
||||||
|
|
||||||
.ant-menu-horizontal {
|
|
||||||
padding: 0 !important;
|
|
||||||
|
|
||||||
li {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** end style for horizontal menu */
|
|
||||||
|
|
||||||
&-side-menu {
|
&-side-menu {
|
||||||
.ant-menu-item:not(.ant-menu-item-disabled):not(.ant-menu-item-selected):hover,
|
.ant-menu:not(.ant-menu-dark) .ant-menu-item:not(.ant-menu-item-disabled):not(.ant-menu-item-selected):hover,
|
||||||
.ant-menu-submenu .ant-menu-submenu-title:not(.ant-menu-item-disabled):hover {
|
.ant-menu:not(.ant-menu-dark) .ant-menu-submenu .ant-menu-submenu-title:not(.ant-menu-item-disabled):hover {
|
||||||
transition: background-color 0.9ms linear;
|
transition: background-color 0.9ms linear;
|
||||||
border-radius: var(--border-radius-base);
|
border-radius: var(--border-radius-base);
|
||||||
color: unset !important;
|
color: unset !important;
|
||||||
background-color: #f3f3f3 !important;
|
background-color: var(--admin-bg-hover) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-menu {
|
.ant-menu:not(.ant-menu-horizontal) {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
.ant-menu-item,
|
||||||
|
.ant-menu-submenu-title {
|
||||||
|
@apply px-2 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-menu-title-content {
|
.ant-menu-title-content {
|
||||||
font-size: 15px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-menu-item,
|
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item.ant-menu-item-selected {
|
||||||
.ant-menu-submenu-title {
|
&::after {
|
||||||
@apply px-2 !important;
|
content: unset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-menu.ant-menu-inline-collapsed > .ant-menu-item .ant-menu-item-icon + span,
|
.ant-menu.ant-menu-inline-collapsed > .ant-menu-item .ant-menu-item-icon + span,
|
||||||
@@ -380,12 +414,6 @@ useResizeObserver(menuScrollRef, () => {
|
|||||||
height: 36px;
|
height: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-menu-item.ant-menu-item-selected {
|
|
||||||
&::after {
|
|
||||||
content: unset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-menu.ant-menu-sub.ant-menu-inline {
|
.ant-menu.ant-menu-sub.ant-menu-inline {
|
||||||
background-color: unset !important;
|
background-color: unset !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,11 +64,13 @@ const menu = computed(() => {
|
|||||||
@prefix:~ '@{prefixCls}-basic-sub-menu';
|
@prefix:~ '@{prefixCls}-basic-sub-menu';
|
||||||
.@{prefix}{
|
.@{prefix}{
|
||||||
|
|
||||||
&.ant-menu-submenu-selected{
|
&.ant-menu-submenu-selected {
|
||||||
border-radius: var(--border-radius-base);
|
border-radius: var(--border-radius-base);
|
||||||
background-color: var(--ant-primary-1);
|
background-color: var(--admin-menu-selected);
|
||||||
.ant-menu-submenu-arrow{
|
color: var(--admin-menu-selected-text);
|
||||||
color: var(--ant-primary)
|
|
||||||
|
.ant-menu-submenu-arrow {
|
||||||
|
color: var(--admin-menu-selected-text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
import { computed, watchEffect } from 'vue'
|
import { computed, watchEffect } from 'vue'
|
||||||
import { usePreferredDark, useStorage } from '@vueuse/core'
|
import { usePreferredDark, useStorage } from '@vueuse/core'
|
||||||
import { acceptHMRUpdate, defineStore } from 'pinia'
|
import { acceptHMRUpdate, defineStore } from 'pinia'
|
||||||
|
import { syncAntDarkStyle } from '@core/utils/syncAntDarkStyle'
|
||||||
|
|
||||||
export const DARK_MODE_BODY_CLASS = 'is-dark'
|
export const DARK_MODE_BODY_CLASS = 'is-dark'
|
||||||
export type DarkModeSchema = 'auto' | 'dark' | 'light'
|
export type DarkModeSchema = 'auto' | 'dark' | 'light'
|
||||||
@@ -24,13 +25,16 @@ export const initDarkmode = () => {
|
|||||||
*/
|
*/
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (!import.meta.env.SSR) {
|
if (!import.meta.env.SSR) {
|
||||||
const body = document.documentElement
|
const root = document.documentElement
|
||||||
|
const isDark = darkmode.isDark
|
||||||
|
|
||||||
if (darkmode.isDark) {
|
if (isDark) {
|
||||||
body.classList.add(DARK_MODE_BODY_CLASS)
|
root.classList.add(DARK_MODE_BODY_CLASS)
|
||||||
} else {
|
} else {
|
||||||
body.classList.remove(DARK_MODE_BODY_CLASS)
|
root.classList.remove(DARK_MODE_BODY_CLASS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void syncAntDarkStyle(isDark)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -56,9 +60,20 @@ export const useDarkmode = defineStore('darkmode', () => {
|
|||||||
isDark.value = !target.checked
|
isDark.value = !target.checked
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
isDark.value = !isDark.value
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSchema(schema: DarkModeSchema) {
|
||||||
|
colorSchema.value = schema
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isDark,
|
isDark,
|
||||||
|
colorSchema,
|
||||||
onChange,
|
onChange,
|
||||||
|
toggle,
|
||||||
|
setSchema,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const useLayoutStore = defineStore('layout', () => {
|
|||||||
})*/
|
})*/
|
||||||
|
|
||||||
const header = reactive({
|
const header = reactive({
|
||||||
height: '45px',
|
height: '56px',
|
||||||
fixed: true
|
fixed: true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
const STYLE_ATTR = 'data-antd-dark'
|
||||||
|
|
||||||
|
const BRAND_OVERRIDES = `
|
||||||
|
html.is-dark body {
|
||||||
|
background-color: #141414;
|
||||||
|
}
|
||||||
|
html.is-dark {
|
||||||
|
--ant-primary-color: #d4af37;
|
||||||
|
--ant-primary-color-hover: #e0bc3a;
|
||||||
|
--ant-primary-color-active: #c9a227;
|
||||||
|
--admin-menu-selected: #d4af37;
|
||||||
|
--admin-menu-selected-text: #141414;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-layout-header {
|
||||||
|
background: #141414 !important;
|
||||||
|
border-bottom: 1px solid var(--admin-border-strong) !important;
|
||||||
|
padding: 0 12px !important;
|
||||||
|
}
|
||||||
|
html.is-dark .top-menu-nav .ant-menu-dark.ant-menu-horizontal {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected,
|
||||||
|
html.is-dark .ant-menu.ant-menu-dark .ant-menu-item-selected,
|
||||||
|
html.is-dark .top-menu-nav .ant-menu-dark.ant-menu-horizontal > .ant-menu-item-selected,
|
||||||
|
html.is-dark .top-menu-nav .ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu-selected > .ant-menu-submenu-title {
|
||||||
|
background-color: var(--admin-menu-selected) !important;
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected .ant-menu-item-icon,
|
||||||
|
html.is-dark .ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected .anticon,
|
||||||
|
html.is-dark .ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-selected .ant-menu-title-content,
|
||||||
|
html.is-dark .ant-menu.ant-menu-dark .ant-menu-item-selected .ant-menu-item-icon,
|
||||||
|
html.is-dark .ant-menu.ant-menu-dark .ant-menu-item-selected .anticon,
|
||||||
|
html.is-dark .ant-menu.ant-menu-dark .ant-menu-item-selected .ant-menu-title-content,
|
||||||
|
html.is-dark .top-menu-nav .ant-menu-dark.ant-menu-horizontal > .ant-menu-item-selected .ant-menu-item-icon,
|
||||||
|
html.is-dark .top-menu-nav .ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu-selected .ant-menu-item-icon,
|
||||||
|
html.is-dark .top-menu-nav .ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu-selected .ant-menu-submenu-arrow {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-menu-dark .ant-menu-item:not(.ant-menu-item-selected):hover,
|
||||||
|
html.is-dark .ant-menu-dark .ant-menu-submenu:not(.ant-menu-submenu-selected) > .ant-menu-submenu-title:hover,
|
||||||
|
html.is-dark .top-menu-nav .ant-menu-dark.ant-menu-horizontal > .ant-menu-item:hover,
|
||||||
|
html.is-dark .top-menu-nav .ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu:hover > .ant-menu-submenu-title {
|
||||||
|
background-color: var(--admin-bg-hover) !important;
|
||||||
|
color: var(--admin-gold-light) !important;
|
||||||
|
box-shadow: inset 0 0 0 1px var(--admin-border-strong) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .hr-tamin-base-button {
|
||||||
|
display: inline-flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
height: auto !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
}
|
||||||
|
html.is-dark .hr-tamin-base-button.ant-btn-sm {
|
||||||
|
min-height: 32px !important;
|
||||||
|
padding: 5px 12px !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-card-body {
|
||||||
|
padding: 12px !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-card,
|
||||||
|
html.is-dark .ant-card-head {
|
||||||
|
border-color: var(--admin-border-strong) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-input,
|
||||||
|
html.is-dark .ant-input-affix-wrapper,
|
||||||
|
html.is-dark .ant-select-selector,
|
||||||
|
html.is-dark .ant-picker {
|
||||||
|
border-color: var(--admin-border-strong) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-input:focus,
|
||||||
|
html.is-dark .ant-input-focused,
|
||||||
|
html.is-dark .ant-input-affix-wrapper-focused,
|
||||||
|
html.is-dark .ant-input-affix-wrapper:focus,
|
||||||
|
html.is-dark .ant-select-focused:not(.ant-select-disabled) .ant-select-selector,
|
||||||
|
html.is-dark .ant-picker-focused {
|
||||||
|
border-color: var(--admin-gold-light) !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(212, 175, 55, 0.18) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
background: var(--admin-gold-light) !important;
|
||||||
|
border-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover,
|
||||||
|
html.is-dark .ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active {
|
||||||
|
color: var(--admin-menu-selected-text) !important;
|
||||||
|
background: var(--admin-gold-hover) !important;
|
||||||
|
border-color: var(--admin-gold-hover) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before,
|
||||||
|
html.is-dark .ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover::before,
|
||||||
|
html.is-dark .ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active::before {
|
||||||
|
background-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-radio-button-wrapper:hover {
|
||||||
|
color: var(--admin-gold-hover) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) {
|
||||||
|
color: var(--admin-gold-light) !important;
|
||||||
|
border-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before {
|
||||||
|
background-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-btn-primary {
|
||||||
|
background: var(--admin-gold-light) !important;
|
||||||
|
border-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-btn-primary:not([disabled]):hover,
|
||||||
|
html.is-dark .ant-btn-primary:not([disabled]):focus {
|
||||||
|
background: var(--admin-gold-hover) !important;
|
||||||
|
border-color: var(--admin-gold-hover) !important;
|
||||||
|
}
|
||||||
|
html.is-dark .ant-btn-default:not([disabled]):hover,
|
||||||
|
html.is-dark .ant-btn-default:not([disabled]):focus {
|
||||||
|
color: var(--admin-gold-light) !important;
|
||||||
|
border-color: var(--admin-gold-light) !important;
|
||||||
|
}
|
||||||
|
@media (max-width: 376px) {
|
||||||
|
html.is-dark .ant-card-body {
|
||||||
|
padding: 5px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
let darkStyleEl: HTMLStyleElement | null = null
|
||||||
|
let loadingPromise: Promise<void> | null = null
|
||||||
|
|
||||||
|
async function injectDarkStyle() {
|
||||||
|
if (darkStyleEl) return
|
||||||
|
|
||||||
|
if (!loadingPromise) {
|
||||||
|
loadingPromise = import('ant-design-vue/dist/antd.dark.css?inline').then((mod) => {
|
||||||
|
darkStyleEl = document.createElement('style')
|
||||||
|
darkStyleEl.setAttribute(STYLE_ATTR, '')
|
||||||
|
darkStyleEl.textContent = `${mod.default}\n${BRAND_OVERRIDES}`
|
||||||
|
document.head.appendChild(darkStyleEl)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await loadingPromise
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeDarkStyle() {
|
||||||
|
darkStyleEl?.remove()
|
||||||
|
darkStyleEl = null
|
||||||
|
loadingPromise = null
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function syncAntDarkStyle(isDark: boolean) {
|
||||||
|
if (import.meta.env.SSR) return
|
||||||
|
|
||||||
|
if (isDark) {
|
||||||
|
await injectDarkStyle()
|
||||||
|
} else {
|
||||||
|
removeDarkStyle()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,25 +28,25 @@ const props = defineProps<Prop>()
|
|||||||
const bgColor = computed(() => {
|
const bgColor = computed(() => {
|
||||||
switch (props.color) {
|
switch (props.color) {
|
||||||
case 'fuchsia':
|
case 'fuchsia':
|
||||||
return 'bg-fuchsia-100'
|
return 'bg-fuchsia-100 dark:bg-fuchsia-500/20'
|
||||||
case 'orange':
|
case 'orange':
|
||||||
return 'bg-orange-100'
|
return 'bg-orange-100 dark:bg-orange-500/20'
|
||||||
case 'green':
|
case 'green':
|
||||||
return 'bg-green-100'
|
return 'bg-green-100 dark:bg-green-500/20'
|
||||||
case 'blue':
|
case 'blue':
|
||||||
return 'bg-blue-100'
|
return 'bg-blue-100 dark:bg-blue-500/20'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const textColor = computed(() => {
|
const textColor = computed(() => {
|
||||||
switch (props.color) {
|
switch (props.color) {
|
||||||
case 'fuchsia':
|
case 'fuchsia':
|
||||||
return 'text-fuchsia-600'
|
return 'text-fuchsia-600 dark:text-fuchsia-300'
|
||||||
case 'orange':
|
case 'orange':
|
||||||
return 'text-orange-600'
|
return 'text-orange-600 dark:text-orange-300'
|
||||||
case 'green':
|
case 'green':
|
||||||
return 'text-green-600'
|
return 'text-green-600 dark:text-green-300'
|
||||||
case 'blue':
|
case 'blue':
|
||||||
return 'text-blue-600'
|
return 'text-blue-600 dark:text-blue-300'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -859,7 +859,9 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.selected_item {
|
.selected_item {
|
||||||
@apply ! bg- [ #0A1B37 ] ! text-white rounded-lg;
|
background: #2563eb !important;
|
||||||
|
color: #fff !important;
|
||||||
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-chart-toolbar {
|
.dashboard-chart-toolbar {
|
||||||
@@ -869,10 +871,10 @@ onMounted(() => {
|
|||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border: 1px solid #d1d5db;
|
border: 1px solid var(--admin-border-strong);
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background: #fff;
|
background: var(--admin-bg-elevated);
|
||||||
color: #374151;
|
color: var(--admin-text);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
@@ -881,8 +883,8 @@ onMounted(() => {
|
|||||||
|
|
||||||
&.active,
|
&.active,
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #0a1b37;
|
background: #2563eb;
|
||||||
border-color: #0a1b37;
|
border-color: #2563eb;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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">
|
<div class="logo flex justify-center w-full flex-col items-center">
|
||||||
<img :src="getConfigApp('avatar')" class="w-[150px]" />
|
<img :src="getConfigApp('avatar')" class="w-[150px]" />
|
||||||
</div>
|
</div>
|
||||||
@@ -221,6 +221,8 @@ const getcode=()=>{
|
|||||||
@prefix: ~'@{prefixCls}-login-panel';
|
@prefix: ~'@{prefixCls}-login-panel';
|
||||||
|
|
||||||
.@{prefix} {
|
.@{prefix} {
|
||||||
|
background-color: var(--admin-bg-elevated);
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
width: 330px;
|
width: 330px;
|
||||||
height: 148px;
|
height: 148px;
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:style="{ backgroundImage: `url(${bg1})` }"
|
: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" />
|
<LoginPanel @enter="enterTest" class="shadow-2xl" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import LoginPanel from './components/LoginPanel.vue'
|
import LoginPanel from './components/LoginPanel.vue'
|
||||||
|
import ThemeToggle from '@core/components/ThemeToggle.vue'
|
||||||
import bg1 from '../login/assets/img/loginBack.svg'
|
import bg1 from '../login/assets/img/loginBack.svg'
|
||||||
|
|
||||||
const emits = defineEmits(['enter'])
|
const emits = defineEmits(['enter'])
|
||||||
@@ -19,4 +23,24 @@ function enterTest() {
|
|||||||
}
|
}
|
||||||
</script>
|
</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>
|
<style lang="less" scoped>
|
||||||
.setting-card {
|
.setting-card {
|
||||||
border: 1px solid #e8e8e8;
|
border: 1px solid var(--admin-border);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 14px 16px;
|
padding: 14px 16px;
|
||||||
background: #fff;
|
background: var(--admin-bg-elevated);
|
||||||
min-height: 108px;
|
min-height: 108px;
|
||||||
transition: border-color 0.2s, box-shadow 0.2s;
|
transition: border-color 0.2s, box-shadow 0.2s;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -83,7 +83,7 @@ const help = computed(() => helpText(props.row))
|
|||||||
}
|
}
|
||||||
|
|
||||||
&--readonly {
|
&--readonly {
|
||||||
background: #fafafa;
|
background: var(--admin-bg-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
&--saving {
|
&--saving {
|
||||||
@@ -109,14 +109,14 @@ const help = computed(() => helpText(props.row))
|
|||||||
&__title {
|
&__title {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: rgba(0, 0, 0, 0.88);
|
color: var(--admin-text);
|
||||||
line-height: 1.45;
|
line-height: 1.45;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__key {
|
&__key {
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: rgba(0, 0, 0, 0.45);
|
color: var(--admin-text-secondary);
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
@@ -125,7 +125,7 @@ const help = computed(() => helpText(props.row))
|
|||||||
&__help {
|
&__help {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: rgba(0, 0, 0, 0.45);
|
color: var(--admin-text-secondary);
|
||||||
line-height: 1.35;
|
line-height: 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ const help = computed(() => helpText(props.row))
|
|||||||
&__status {
|
&__status {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: rgba(0, 0, 0, 0.45);
|
color: var(--admin-text-secondary);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
|||||||
@@ -589,8 +589,8 @@ async function ok() {
|
|||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 14px 16px;
|
padding: 14px 16px;
|
||||||
background: #fafafa;
|
background: var(--admin-bg-elevated);
|
||||||
border: 1px solid #f0f0f0;
|
border: 1px solid var(--admin-border);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
||||||
&__search {
|
&__search {
|
||||||
@@ -621,7 +621,7 @@ async function ok() {
|
|||||||
&__label {
|
&__label {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: rgba(0, 0, 0, 0.55);
|
color: var(--admin-text-secondary);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,10 +633,10 @@ async function ok() {
|
|||||||
.settings-section-title {
|
.settings-section-title {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: rgba(0, 0, 0, 0.55);
|
color: var(--admin-text-secondary);
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
border-bottom: 1px solid #f0f0f0;
|
border-bottom: 1px solid var(--admin-border);
|
||||||
|
|
||||||
&--spaced {
|
&--spaced {
|
||||||
margin-top: 28px;
|
margin-top: 28px;
|
||||||
@@ -659,11 +659,11 @@ async function ok() {
|
|||||||
|
|
||||||
.settings-collapse :deep(.ant-collapse-item) {
|
.settings-collapse :deep(.ant-collapse-item) {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
background: #fff;
|
background: var(--admin-bg-elevated);
|
||||||
border: 1px solid #f0f0f0;
|
border: 1px solid var(--admin-border);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
overflow: hidden;
|
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;
|
transition: box-shadow 0.2s ease, border-color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,10 +674,10 @@ async function ok() {
|
|||||||
|
|
||||||
.settings-collapse :deep(.ant-collapse-header) {
|
.settings-collapse :deep(.ant-collapse-header) {
|
||||||
padding: 14px 18px !important;
|
padding: 14px 18px !important;
|
||||||
background: linear-gradient(90deg, #fafafa 0%, #fff 100%);
|
background: var(--admin-bg-muted);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #333;
|
color: var(--admin-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-collapse-header {
|
.settings-collapse-header {
|
||||||
@@ -695,15 +695,15 @@ async function ok() {
|
|||||||
.settings-collapse-title {
|
.settings-collapse-title {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #2c2c2c;
|
color: var(--admin-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-empty-group {
|
.settings-empty-group {
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: var(--admin-text-secondary);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: #fafafa;
|
background: var(--admin-bg-muted);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,21 @@
|
|||||||
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
||||||
<BasicShowContext title="لیست مشتریان">
|
<BasicShowContext title="لیست مشتریان">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
|
<BaseButton
|
||||||
<div>افزودن</div>
|
v-if="isMobile"
|
||||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
icon="vuesax-linear:user-add"
|
||||||
|
@click="emits('add')"
|
||||||
|
>
|
||||||
|
افزودن
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
<div class="flex h-full min-h-0 flex-col">
|
<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">
|
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
<template #extraHeader>
|
<template #extraHeader>
|
||||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
<BaseButton type="primary" size="small" icon="vuesax-linear:user-add" @click="emits('add')">
|
||||||
<div>افزودن مشتری</div>
|
افزودن مشتری
|
||||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
<a-tabs v-if="userInfo" v-model:activeKey="activeKey">
|
<a-tabs v-if="userInfo" v-model:activeKey="activeKey">
|
||||||
<a-tab-pane key="اطلاعات جامع" tab="اطلاعات جامع">
|
<a-tab-pane key="اطلاعات جامع" tab="اطلاعات جامع">
|
||||||
<div class="space-y-2">
|
<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>
|
||||||
<div class="font-bold">{{ userInfo.name }}</div>
|
<div class="font-bold">{{ userInfo.name }}</div>
|
||||||
<div class="mt-1">{{ userInfo?.mobile }}</div>
|
<div class="mt-1">{{ userInfo?.mobile }}</div>
|
||||||
@@ -187,7 +187,7 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(item, index) in userInfo.wallet"
|
v-for="(item, index) in userInfo.wallet"
|
||||||
:key="index"
|
: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
|
<BasicInfoItem
|
||||||
title="نام قلک"
|
title="نام قلک"
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
||||||
<BasicShowContext title="لیست کارت های هدیه">
|
<BasicShowContext title="لیست کارت های هدیه">
|
||||||
<template v-if="!customerId" #extra>
|
<template v-if="!customerId && isMobile" #extra>
|
||||||
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add', 'gift')">
|
<BaseButton type="primary" size="small" icon="vuesax-linear:receipt-add" @click="emits('add', 'gift')">
|
||||||
<div>افزودن</div>
|
افزودن
|
||||||
<BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</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">
|
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
<template #extraHeader>
|
<template #extraHeader>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<BaseButton v-if="!customerId" type="primary" size="small" class="flex" @click="emits('add', 'gift')">
|
<BaseButton v-if="!customerId" type="primary" size="small" icon="vuesax-linear:receipt-add" @click="emits('add', 'gift')">
|
||||||
<div>افزودن کارت هدیه</div>
|
افزودن کارت هدیه
|
||||||
<BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
v-if="!customerId && isStoreApp()"
|
v-if="!customerId && isStoreApp()"
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
class="flex"
|
icon="vuesax-linear:discount-circle"
|
||||||
@click="emits('add', 'discount')"
|
@click="emits('add', 'discount')"
|
||||||
>
|
>
|
||||||
<div>افزودن کد تخفیف</div>
|
افزودن کد تخفیف
|
||||||
<BaseIcon icon="vuesax-linear:discount-circle" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
||||||
<BasicShowContext title="لیست سفارشات">
|
<BasicShowContext title="لیست سفارشات">
|
||||||
<template v-if="!customerId" #extra>
|
<template v-if="!customerId && isMobile" #extra>
|
||||||
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
|
<BaseButton type="primary" size="small" icon="vuesax-linear:receipt-add" @click="emits('add')">
|
||||||
<div>افزودن</div>
|
افزودن
|
||||||
<BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
<div class="flex h-full min-h-0 flex-col">
|
<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">
|
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
<template #extraHeader>
|
<template #extraHeader>
|
||||||
<BaseButton v-if="!customerId" type="primary" size="small" class="flex" @click="emits('add')">
|
<BaseButton v-if="!customerId" type="primary" size="small" icon="vuesax-linear:receipt-add" @click="emits('add')">
|
||||||
<div>افزودن سفارش</div>
|
افزودن سفارش
|
||||||
<BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ column, record }">
|
<template #action="{ column, record }">
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
<BasicShowContext title="تاریخچه قیمت">
|
<BasicShowContext title="تاریخچه قیمت">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
|
v-if="isMobile"
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
class="flex shrink-0 md:hidden"
|
icon="vuesax-linear:refresh"
|
||||||
:loading="syncing"
|
:loading="syncing"
|
||||||
@click="emits('sync')"
|
@click="emits('sync')"
|
||||||
>
|
>
|
||||||
<div>بهروزرسانی قیمت</div>
|
بهروزرسانی قیمت
|
||||||
<BaseIcon icon="vuesax-linear:refresh" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -20,12 +20,11 @@
|
|||||||
<BaseButton
|
<BaseButton
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
class="flex"
|
icon="vuesax-linear:refresh"
|
||||||
:loading="syncing"
|
:loading="syncing"
|
||||||
@click="emits('sync')"
|
@click="emits('sync')"
|
||||||
>
|
>
|
||||||
<div>بهروزرسانی قیمت</div>
|
بهروزرسانی قیمت
|
||||||
<BaseIcon icon="vuesax-linear:refresh" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
|
|||||||
@@ -63,13 +63,7 @@
|
|||||||
import type { TableInput } from '@core/type/baseTable'
|
import type { TableInput } from '@core/type/baseTable'
|
||||||
import useBaseTable from '@core/components/BaseTableOld/hooks/useBaseTable'
|
import useBaseTable from '@core/components/BaseTableOld/hooks/useBaseTable'
|
||||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||||
import {
|
import { changeProductArchive } from '@/api/product'
|
||||||
changeCustomerActivation,
|
|
||||||
changeCustomerArchive,
|
|
||||||
changeCustomerOrderActivation,
|
|
||||||
getCustomerArchiveTable,
|
|
||||||
getCustomerTable
|
|
||||||
} from '@/api/customer'
|
|
||||||
import { cols } from '../hooks/archiveColumns'
|
import { cols } from '../hooks/archiveColumns'
|
||||||
import { useUserStore } from '@/store/userStore'
|
import { useUserStore } from '@/store/userStore'
|
||||||
import { usePrefix } from '@core/composable/usePrefix'
|
import { usePrefix } from '@core/composable/usePrefix'
|
||||||
@@ -105,37 +99,12 @@ const tblProps = ref<any>({
|
|||||||
})
|
})
|
||||||
const loading = ref<boolean>(false)
|
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) {
|
async function archiveFunction(id: number) {
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
await changeCustomerArchive(id)
|
await changeProductArchive(id)
|
||||||
await Promise.allSettled([reload(), mobileListRef.value?.fetch?.() as Promise<void>])
|
await Promise.allSettled([reload(), mobileListRef.value?.fetch?.() as Promise<void>])
|
||||||
message.success('مشتری با موفقیت از بایگانی خارج شد.')
|
message.success('محصول با موفقیت از بایگانی خارج شد.')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -36,17 +36,21 @@
|
|||||||
|
|
||||||
<BasicShowContext title="لیست محصولات" class="min-h-0 flex-1">
|
<BasicShowContext title="لیست محصولات" class="min-h-0 flex-1">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
|
<BaseButton
|
||||||
<div>افزودن</div>
|
v-if="isMobile"
|
||||||
<BaseIcon icon="vuesax-linear:box" Size="16px" />
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
icon="vuesax-linear:box"
|
||||||
|
@click="emits('add')"
|
||||||
|
>
|
||||||
|
افزودن محصول
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
<div class="flex h-full min-h-0 flex-col">
|
<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">
|
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
<template #extraHeader>
|
<template #extraHeader>
|
||||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
<BaseButton type="primary" size="small" icon="vuesax-linear:box" @click="emits('add')">
|
||||||
<div>افزودن محصول</div>
|
افزودن محصول
|
||||||
<BaseIcon icon="vuesax-linear:box" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||||
import CustomTag from '@/components/CustomTag.vue'
|
import CustomTag from '@/components/CustomTag.vue'
|
||||||
import { isStoreApp } from '@/utils/config'
|
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 = {
|
const inventoryColumn: BaseTableColumn = {
|
||||||
title: 'موجودی',
|
title: 'موجودی',
|
||||||
@@ -47,7 +52,8 @@ export function getProductColumns(): BaseTableColumn[] {
|
|||||||
title: 'قیمت',
|
title: 'قیمت',
|
||||||
dataIndex: 'price',
|
dataIndex: 'price',
|
||||||
key: 'price',
|
key: 'price',
|
||||||
type: 'Text'
|
type: 'Text',
|
||||||
|
customRender: ({ record }) => formatMoney(record.price)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'تعدیل قیمت (٪)',
|
title: 'تعدیل قیمت (٪)',
|
||||||
@@ -79,13 +85,15 @@ export function getProductColumns(): BaseTableColumn[] {
|
|||||||
title: 'هزینه نقدی موقع خرید',
|
title: 'هزینه نقدی موقع خرید',
|
||||||
dataIndex: 'cash_fee_buy',
|
dataIndex: 'cash_fee_buy',
|
||||||
key: 'cash_fee_buy',
|
key: 'cash_fee_buy',
|
||||||
type: 'Number'
|
type: 'Number',
|
||||||
|
customRender: ({ record }) => formatMoney(record.cash_fee_buy)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'هزینه نقدی موقع فروش',
|
title: 'هزینه نقدی موقع فروش',
|
||||||
dataIndex: 'cash_fee_sell',
|
dataIndex: 'cash_fee_sell',
|
||||||
key: 'cash_fee_sell',
|
key: 'cash_fee_sell',
|
||||||
type: 'Number'
|
type: 'Number',
|
||||||
|
customRender: ({ record }) => formatMoney(record.cash_fee_sell)
|
||||||
},
|
},
|
||||||
...(isStoreApp() ? [inventoryColumn] : []),
|
...(isStoreApp() ? [inventoryColumn] : []),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
||||||
<BasicShowContext title="لیست پیامک ها">
|
<BasicShowContext title="لیست پیامک ها">
|
||||||
<template v-if="!mobile" #extra>
|
<template v-if="!mobile && isMobileScreen" #extra>
|
||||||
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
|
<BaseButton type="primary" size="small" icon="vuesax-linear:sms" @click="emits('add')">
|
||||||
<div>ارسال پیامک</div>
|
ارسال پیامک
|
||||||
<BaseIcon icon="vuesax-linear:sms" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex h-full min-h-0 flex-col">
|
<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">
|
<BaseTable v-if="!isMobileScreen" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
<template #extraHeader>
|
<template #extraHeader>
|
||||||
<BaseButton v-if="!mobile" type="primary" size="small" class="flex" @click="emits('add')">
|
<BaseButton v-if="!mobile" type="primary" size="small" icon="vuesax-linear:sms" @click="emits('add')">
|
||||||
<div>ارسال پیامک</div>
|
ارسال پیامک
|
||||||
<BaseIcon icon="vuesax-linear:sms" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ column, record }">
|
<template #action="{ column, record }">
|
||||||
|
|||||||
@@ -2,18 +2,22 @@
|
|||||||
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
||||||
<BasicShowContext title="لیست مدیران">
|
<BasicShowContext title="لیست مدیران">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<BaseButton type="primary" size="small" class="flex shrink-0 md:hidden" @click="emits('add')">
|
<BaseButton
|
||||||
<div>افزودن مدیر</div>
|
v-if="isMobile"
|
||||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
icon="vuesax-linear:user-add"
|
||||||
|
@click="emits('add')"
|
||||||
|
>
|
||||||
|
افزودن مدیر
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex h-full min-h-0 flex-col">
|
<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">
|
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
<template #extraHeader>
|
<template #extraHeader>
|
||||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
<BaseButton type="primary" size="small" icon="vuesax-linear:user-add" @click="emits('add')">
|
||||||
<div>افزودن مدیر</div>
|
افزودن مدیر
|
||||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ column, record }">
|
<template #action="{ column, record }">
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
>
|
>
|
||||||
<div class="mb-2 font-medium">مجموع موجودی کیف پول</div>
|
<div class="mb-2 font-medium">مجموع موجودی کیف پول</div>
|
||||||
<div class="grid grid-cols-2 gap-2">
|
<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="text-xs text-gray-500">ریال</div>
|
||||||
<div class="mt-1 font-bold break-all">{{ usePrice(sums?.cash ?? 0) }}</div>
|
<div class="mt-1 font-bold break-all">{{ usePrice(sums?.cash ?? 0) }}</div>
|
||||||
</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="text-xs text-gray-500">گرم</div>
|
||||||
<div class="mt-1 font-bold">
|
<div class="mt-1 font-bold">
|
||||||
{{ usePrice(Number(sums?.cashToGold ?? 0).toFixed(2), true, 'گرم') }}
|
{{ usePrice(Number(sums?.cashToGold ?? 0).toFixed(2), true, 'گرم') }}
|
||||||
@@ -28,13 +28,13 @@
|
|||||||
>
|
>
|
||||||
<div class="mb-2 font-medium">مجموع موجودی کیف طلا</div>
|
<div class="mb-2 font-medium">مجموع موجودی کیف طلا</div>
|
||||||
<div class="grid grid-cols-2 gap-2">
|
<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="text-xs text-gray-500">گرم</div>
|
||||||
<div class="mt-1 font-bold">
|
<div class="mt-1 font-bold">
|
||||||
{{ usePrice(sums?.gold ?? 0, true, 'گرم') }}
|
{{ usePrice(sums?.gold ?? 0, true, 'گرم') }}
|
||||||
</div>
|
</div>
|
||||||
</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="text-xs text-gray-500">ریال</div>
|
||||||
<div class="mt-1 font-bold break-all">{{ usePrice(sums?.goldToCash ?? 0) }}</div>
|
<div class="mt-1 font-bold break-all">{{ usePrice(sums?.goldToCash ?? 0) }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
@close="confirmWeightVisible = false"
|
@close="confirmWeightVisible = false"
|
||||||
>
|
>
|
||||||
<div v-for="(item, index) in weightTransactions" :key="index">
|
<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>
|
<div class="mb-4">{{ item?.title }} ({{ weightCount(item) }} عدد)</div>
|
||||||
<ADivider class="!my-0 "/>
|
<ADivider class="!my-0 "/>
|
||||||
<div v-if="weightCount(item) > 0">
|
<div v-if="weightCount(item) > 0">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="mx-3 relative">
|
<div class="mx-3 relative">
|
||||||
<div class="absolute z-10 w-full">
|
<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>
|
<span class="text-base font-bold">اقلام سفارش</span>
|
||||||
<Button type="primary" size="small" v-if="edit" @click="updateOrders"
|
<Button type="primary" size="small" v-if="edit" @click="updateOrders"
|
||||||
>ثبت اطلاعات
|
>ثبت اطلاعات
|
||||||
|
|||||||
Reference in New Issue
Block a user