Refactor frontend to Composition API and improve UI/UX

Major Changes:
- Migrate components from Options API to Composition API with <script setup>
- Add centralized service layer (serviceService, deliveryService, adminService)
- Implement new reusable components (EnhancedButton, EnhancedModal, StatCard, etc.)
- Add theme store for consistent theming across application
- Improve ServiceCalendar with federal holidays and better styling
- Refactor customer profile and tank estimation components
- Update all delivery and payment pages to use centralized services
- Add utility functions for formatting and validation
- Update Dockerfiles for better environment configuration
- Enhance Tailwind config with custom design tokens

UI Improvements:
- Modern, premium design with glassmorphism effects
- Improved form layouts with FloatingInput components
- Better loading states and empty states
- Enhanced modals and tables with consistent styling
- Responsive design improvements across all pages

Technical Improvements:
- Strict TypeScript types throughout
- Better error handling and validation
- Removed deprecated api.js in favor of TypeScript services
- Improved code organization and maintainability
This commit is contained in:
2026-02-01 19:04:07 -05:00
parent 72d8e35e06
commit 61f93ec4e8
86 changed files with 3931 additions and 2086 deletions

52
src/stores/theme.ts Normal file
View File

@@ -0,0 +1,52 @@
// src/stores/theme.ts
import { ref } from 'vue'
import { defineStore } from 'pinia'
import type { ThemeOption } from '../types/models'
const STORAGE_KEY = 'user_theme'
const DEFAULT_THEME = 'ocean'
export const AVAILABLE_THEMES: ThemeOption[] = [
{ name: 'ocean', label: 'Ocean', preview: '#ff6600' },
{ name: 'forest', label: 'Forest', preview: '#4ade80' },
{ name: 'sunset', label: 'Sunset', preview: '#fb923c' },
{ name: 'arctic', label: 'Arctic', preview: '#06b6d4' },
{ name: 'midnight', label: 'Midnight', preview: '#a78bfa' },
]
export const useThemeStore = defineStore('theme', () => {
// --- STATE ---
const currentTheme = ref(localStorage.getItem(STORAGE_KEY) || DEFAULT_THEME)
// --- ACTIONS ---
function setTheme(theme: string) {
const validTheme = AVAILABLE_THEMES.find(t => t.name === theme)
if (validTheme) {
currentTheme.value = theme
localStorage.setItem(STORAGE_KEY, theme)
document.documentElement.setAttribute('data-theme', theme)
}
}
function initTheme() {
// Validate stored theme is still valid
const storedTheme = localStorage.getItem(STORAGE_KEY)
const validTheme = AVAILABLE_THEMES.find(t => t.name === storedTheme)
if (validTheme) {
currentTheme.value = storedTheme!
} else {
currentTheme.value = DEFAULT_THEME
localStorage.setItem(STORAGE_KEY, DEFAULT_THEME)
}
document.documentElement.setAttribute('data-theme', currentTheme.value)
}
// --- RETURN ---
return {
currentTheme,
setTheme,
initTheme,
AVAILABLE_THEMES,
}
})