olli b84dc6c6e9 feat: add typography and utility styles for layout
- Introduced typography styles in _typography.scss for headings, paragraphs, blockquotes, and horizontal rules.
- Added utility classes in _utils.scss for card styling and clearfix.
- Updated layout.scss to include new typography and utility styles.
- Defined common CSS variables in _common.scss for consistent theming.
- Created dark and light theme variables in _dark.scss and _light.scss respectively.
- Integrated Tailwind CSS with custom configurations in tailwind.config.js and postcss.config.js.
- Implemented database migrations for contact and contact_persons tables.
- Added data fixtures for generating sample contact data.
- Developed Contact and ContactPerson entities with appropriate validation and serialization.
- Enhanced ContactRepository with search and type filtering methods.
2025-11-09 11:02:15 +01:00

88 lines
2.5 KiB
JavaScript

import { computed, reactive } from 'vue';
// Load preferences from localStorage
const savedDarkMode = localStorage.getItem('darkMode') === 'true';
const savedPrimary = localStorage.getItem('primaryColor') || 'emerald';
const savedSurface = localStorage.getItem('surfaceColor') || null;
const savedPreset = localStorage.getItem('preset') || 'Aura';
const savedMenuMode = localStorage.getItem('menuMode') || 'static';
const layoutConfig = reactive({
preset: savedPreset,
primary: savedPrimary,
surface: savedSurface,
darkTheme: savedDarkMode,
menuMode: savedMenuMode
});
// Apply dark mode on initial load
if (savedDarkMode) {
document.documentElement.classList.add('app-dark');
}
const layoutState = reactive({
staticMenuDesktopInactive: false,
overlayMenuActive: false,
profileSidebarVisible: false,
configSidebarVisible: false,
staticMenuMobileActive: false,
menuHoverActive: false,
activeMenuItem: null
});
export function useLayout() {
const setActiveMenuItem = (item) => {
layoutState.activeMenuItem = item.value || item;
};
const toggleDarkMode = () => {
if (!document.startViewTransition) {
executeDarkModeToggle();
return;
}
document.startViewTransition(() => executeDarkModeToggle(event));
};
const executeDarkModeToggle = () => {
layoutConfig.darkTheme = !layoutConfig.darkTheme;
document.documentElement.classList.toggle('app-dark');
// Save preference to localStorage
localStorage.setItem('darkMode', layoutConfig.darkTheme.toString());
};
const toggleMenu = () => {
if (layoutConfig.menuMode === 'overlay') {
layoutState.overlayMenuActive = !layoutState.overlayMenuActive;
}
if (window.innerWidth > 991) {
layoutState.staticMenuDesktopInactive = !layoutState.staticMenuDesktopInactive;
} else {
layoutState.staticMenuMobileActive = !layoutState.staticMenuMobileActive;
}
};
const isSidebarActive = computed(() => layoutState.overlayMenuActive || layoutState.staticMenuMobileActive);
const isDarkTheme = computed(() => layoutConfig.darkTheme);
const getPrimary = computed(() => layoutConfig.primary);
const getSurface = computed(() => layoutConfig.surface);
return {
layoutConfig,
layoutState,
toggleMenu,
isSidebarActive,
isDarkTheme,
getPrimary,
getSurface,
setActiveMenuItem,
toggleDarkMode
};
}