dark & light theme

This commit is contained in:
2025-06-16 15:01:07 +07:00
parent 08542471d0
commit 0b7f20b800
8 changed files with 190 additions and 72 deletions
+5 -3
View File
@@ -64,7 +64,7 @@ watch([mdAndDown, () => props.items], ([mdVal, items]) => {
<LayoutFullVerticalHeaderNotificationDD />
</div>
<div>
<v-menu :close-on-content-click="true" class="mobile_popup">
<!-- <v-menu :close-on-content-click="true" class="mobile_popup">
<template v-slot:activator="{ props }">
<v-btn icon class="hidden-md-and-up custom-hover-primary" color="primary" variant="text" v-bind="props" size="small">
<Icon icon="solar:menu-dots-bold-duotone" height="22" />
@@ -72,6 +72,7 @@ watch([mdAndDown, () => props.items], ([mdVal, items]) => {
</template>
<v-sheet rounded="lg" elevation="10" class="mt-4 dropdown-box px-4 py-3">
<div class="d-flex justify-space-between align-center">
<LayoutFullVerticalHeaderRightMobileSidebar />
<LayoutFullVerticalHeaderNotificationDD />
<v-btn icon variant="text" class="mr-sm-3 mr-2 custom-hover-primary" to="/ecommerce/checkout" size="small">
@@ -82,10 +83,11 @@ watch([mdAndDown, () => props.items], ([mdVal, items]) => {
</div>
</v-sheet>
</v-menu>
</v-menu> -->
</div>
<div>
<!-- <LayoutFullVerticalHeaderRightMobileSidebar /> -->
<LayoutFullVerticalHeaderRightMobileSidebar />
<LayoutFullVerticalHeaderThemeToggler />
<LayoutFullVerticalHeaderNavigations />
<LayoutFullVerticalHeaderProfileDD />
</div>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import {appsLink} from '~/_mockApis/headerData';
import {appsLink} from '@/_mockApis/headerData';
import { Icon } from '@iconify/vue';
</script>
<template>
@@ -21,4 +21,4 @@ import { Icon } from '@iconify/vue';
</router-link>
</v-col>
</v-row>
</template>
</template>
@@ -1,59 +1,24 @@
<script setup lang="ts">
import { ref } from 'vue';
import { AppsIcon, CalendarIcon, MailIcon, MessagesIcon } from 'vue-tabler-icons';
import AppsLink from './AppsLink.vue';
//import QuickLinks from './QuickLinks.vue';
const open = ref(['Apps']);
import { Icon } from '@iconify/vue';
</script>
<template>
<div class="pt-6">
<h5 class="text-h5 mb-4 px-5">Navigation</h5>
<v-list v-model:opened="open" class="right-sidebar">
<v-list-group value="Apps">
<template v-slot:activator="{ props }">
<v-list-item v-bind="props">
<template v-slot:prepend>
<AppsIcon width="21" stroke-width="1.5" />
</template>
<h5 class="text-subtitle-1 ml-2">Apps</h5>
</v-list-item>
</template>
<v-list-item class="pl-6 pb-6">
<div>
<AppsLink />
</div>
</v-list-item>
</v-list-group>
<v-list-item>
<template v-slot:prepend>
<MessagesIcon width="21" stroke-width="1.5" />
</template>
<h5 class="text-subtitle-1 ml-2">Chats</h5>
</v-list-item>
<v-list-item>
<template v-slot:prepend>
<CalendarIcon width="21" stroke-width="1.5" />
</template>
<h5 class="text-subtitle-1 ml-2">Calendar</h5>
</v-list-item>
<v-list-item>
<template v-slot:prepend>
<MailIcon width="21" stroke-width="1.5" />
</template>
<h5 class="text-subtitle-1 ml-2">Mail</h5>
</v-list-item>
</v-list>
<div class="px-5">
<h5 class="text-h5 my-4">Quick Links</h5>
<!-- <QuickLinks /> -->
</div>
</div>
<v-menu open-on-hover open-on-click >
<template v-slot:activator="{ props }">
<v-btn icon class="custom-hover-primary" size="small" variant="text" color="primary" v-bind="props">
<Icon icon="solar:widget-line-duotone" height="22" />
</v-btn>
</template>
<v-sheet rounded="md" width="360" elevation="10">
<perfect-scrollbar style="height: 370px">
<div class="pa-6">
<AppsLink />
</div>
</perfect-scrollbar>
</v-sheet>
</v-menu>
</template>
<style scoped>
.right-sidebar .v-list-group__items .v-list-item {
padding-inline-start: 26px !important;
}
</style>
@@ -0,0 +1,77 @@
<script setup lang="ts">
import { ref } from "vue";
import { useTheme } from "vuetify";
import { useCustomizerStore } from "@/stores/customizer";
import { Icon } from "@iconify/vue";
import { useNuxtApp } from "#app";
// import vuetify from '~/plugins/vuetify';
const theme = useTheme();
const customizer = useCustomizerStore();
// themes color options
const themeColors = ref([
{
name: "BLUE_THEME",
bg: "togglethemeBlue",
},
{
name: "DARK_BLUE_THEME",
bg: "togglethemeDarkBlue",
},
]);
console.log("Masuk theme")
const vuetify = useNuxtApp().$vuetify;
// const selectTheme = ref();
const selectTheme = () => {
if (customizer.actTheme == "BLUE_THEME")
customizer.SET_THEME(themeColors.value[1].name);
else customizer.SET_THEME(themeColors.value[0].name);
// vuetify.theme.dark = customizer.actTheme == 'DARK_BLUE_THEME'
vuetify.theme.global.name.value = customizer.actTheme;
console.log("customizer.actTheme", vuetify.theme.global.name);
};
</script>
<template>
<!-- <div class="position-relative">
<v-item-group mandatory v-model="customizer.actTheme" class="d-flex">
<div v-for="theme in themeColors" :key="theme.name">
<v-item v-slot="{toggle }" :value="theme.name">
<v-sheet rounded="circle" class="cursor-pointer text-center hover-btns" elevation="0" @click="toggle">
<v-btn icon :class="theme.bg" class="custom-hover-primary" size="small" variant="text" color="primary" >
<Icon v-if="theme.bg == 'togglethemeBlue'" icon="solar:sun-2-line-duotone" :class="theme.bg" height="22" />
<Icon v-if="theme.bg == 'togglethemeDarkBlue'" icon="solar:moon-line-duotone" :class="theme.bg" height="22" />
</v-btn>
</v-sheet>
</v-item>
</div>
</v-item-group>
</div> -->
<!-- <div class="position-relative"> -->
<v-btn
icon
:class="theme.bg"
class="custom-hover-primary"
size="small"
variant="text"
color="primary"
v-model="customizer.actTheme"
@click="selectTheme"
>
<Icon
v-if="customizer.actTheme == 'BLUE_THEME'"
icon="solar:sun-2-line-duotone"
:class="themeColors[0].bg"
height="22"
/>
<Icon
v-if="customizer.actTheme == 'DARK_BLUE_THEME'"
icon="solar:moon-line-duotone"
:class="themeColors[1].bg"
height="22"
/>
</v-btn>
<!-- </div> -->
</template>
+23
View File
@@ -0,0 +1,23 @@
export type ConfigProps = {
Sidebar_drawer: any;
Customizer_drawer: boolean;
mini_sidebar: boolean;
setHorizontalLayout: boolean;
setRTLLayout: boolean;
actTheme: string;
boxed: boolean;
setBorderCard: boolean;
};
const config: ConfigProps = {
Sidebar_drawer: null,
Customizer_drawer: false,
mini_sidebar: false,
setHorizontalLayout: false, // Horizontal layout
setRTLLayout: false, // RTL layout
actTheme: 'BLUE_THEME',
boxed: true,
setBorderCard: false
};
export default config;
+2 -2
View File
@@ -14,7 +14,7 @@
"@iconify/vue": "^4.3.0",
"@mdi/font": "7.4.47",
"@nuxt/vite-builder": "3.16.2",
"@pinia/nuxt": "^0.11.0",
"@pinia/nuxt": "^0.5.1",
"@vueform/nuxt": "^1.13.0",
"apexcharts": "4.5.0",
"axios": "^1.9.0",
@@ -24,7 +24,7 @@
"nuxt-auth-utils": "^0.5.20",
"nuxt-mongoose": "^1.0.6",
"openid-client": "^5.7.1",
"pinia": "^3.0.2",
"pinia": "2.1.7",
"sass": "1.70.0",
"sweetalert2": "^11.22.0",
"vue": "3.5.13",
+25 -14
View File
@@ -1,15 +1,20 @@
import { createVuetify } from "vuetify";
import * as components from "vuetify/components";
import * as directives from "vuetify/directives";
import PerfectScrollbar from 'vue3-perfect-scrollbar';
import VueApexCharts from 'vue3-apexcharts';
import VueTablerIcons from 'vue-tabler-icons';
import '@mdi/font/css/materialdesignicons.css';
import '@/scss/style.scss';
import PerfectScrollbar from "vue3-perfect-scrollbar";
import VueApexCharts from "vue3-apexcharts";
import VueTablerIcons from "vue-tabler-icons";
import "@mdi/font/css/materialdesignicons.css";
import "@/scss/style.scss";
import { BLUE_THEME } from "@/theme/LightTheme";
import {
BLUE_THEME,
} from "@/theme/LightTheme";
DARK_BLUE_THEME,
DARK_AQUA_THEME,
DARK_ORANGE_THEME,
DARK_PURPLE_THEME,
DARK_GREEN_THEME,
DARK_CYAN_THEME,
} from "@/theme/DarkTheme";
export default defineNuxtPlugin((nuxtApp) => {
const vuetify = createVuetify({
components,
@@ -18,24 +23,30 @@ export default defineNuxtPlugin((nuxtApp) => {
defaultTheme: "BLUE_THEME",
themes: {
BLUE_THEME,
DARK_BLUE_THEME,
DARK_AQUA_THEME,
DARK_ORANGE_THEME,
DARK_PURPLE_THEME,
DARK_GREEN_THEME,
DARK_CYAN_THEME,
},
},
defaults: {
VBtn: {},
VCard: {
rounded: 'md'
rounded: "md",
},
VTextField: {
rounded: 'lg'
rounded: "lg",
},
VTooltip: {
location: 'top'
}
}
location: "top",
},
},
});
nuxtApp.vueApp.use(vuetify);
nuxtApp.provide('vuetify', vuetify)
nuxtApp.vueApp.use(PerfectScrollbar);
nuxtApp.vueApp.use(VueApexCharts);
nuxtApp.vueApp.use(VueTablerIcons);
});
+40
View File
@@ -0,0 +1,40 @@
import { defineStore } from "pinia";
import config from '@/config'
export const useCustomizerStore = defineStore('theme',{
id: "customizer",
state: () => ({
Sidebar_drawer: config.Sidebar_drawer,
Customizer_drawer: config.Customizer_drawer,
mini_sidebar: config.mini_sidebar,
setHorizontalLayout: config.setHorizontalLayout, // Horizontal layout
setRTLLayout:config.setRTLLayout, // RTL layout
actTheme: config.actTheme,
boxed: config.boxed,
setBorderCard: config.setBorderCard
}),
getters: {},
actions: {
SET_SIDEBAR_DRAWER() {
this.Sidebar_drawer = !this.Sidebar_drawer;
},
SET_MINI_SIDEBAR(payload: any) {
this.mini_sidebar = payload;
},
SET_CUSTOMIZER_DRAWER(payload: any) {
this.Customizer_drawer = payload;
},
SET_LAYOUT(payload: any) {
this.setHorizontalLayout = payload;
},
SET_THEME(payload: any) {
this.actTheme = payload;
},
SET_CARD_BORDER(payload: any){
this.setBorderCard = payload
}
},
});