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

View File

@@ -13,76 +13,120 @@
</h1>
<!-- Main Dashboard Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6 my-6">
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6 my-6 animate-fade-in">
<!-- Card 1: Today's Stats -->
<div class="bg-neutral rounded-lg p-5 xl:col-span-2">
<h3 class="text-xl font-bold mb-4">Today's Stats</h3>
<!-- Card 1: Today's Deliveries -->
<div class="bg-gradient-to-br from-neutral to-neutral/80 rounded-xl p-6 shadow-medium hover-lift xl:col-span-2">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-semibold">Today's Deliveries</h3>
<div class="w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 text-primary">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h1.125c.621 0 1.129-.504 1.09-1.124a17.902 17.902 0 00-3.213-9.193 2.056 2.056 0 00-1.58-.86H14.25M16.5 18.75h-2.25m0-11.177v-.958c0-.568-.422-1.048-.987-1.106a48.554 48.554 0 00-10.026 0 1.106 1.106 0 00-.987 1.106v7.635m12-6.677v6.677m0 4.5v-4.5m0 0h-12" />
</svg>
</div>
</div>
<div class="space-y-4">
<div>
<span class="font-semibold">Total Deliveries Today:</span>
<span class="text-lg ml-2">{{ delivery_count }}</span>
<div class="flex items-baseline gap-2">
<span class="text-4xl font-bold">{{ delivery_count }}</span>
<span class="text-base-content/60">total deliveries</span>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span>Completed</span>
<span>{{ delivery_count_delivered }} / {{ delivery_count }}</span>
<div class="flex justify-between text-sm mb-2">
<span class="font-medium">Completed</span>
<span class="font-mono">{{ delivery_count_delivered }} / {{ delivery_count }}</span>
</div>
<progress class="progress progress-primary w-full" :value="delivery_count_delivered" :max="delivery_count"></progress>
<progress class="progress progress-primary w-full h-3" :value="delivery_count_delivered" :max="delivery_count"></progress>
</div>
</div>
</div>
<!-- Card 2: Today's Oil Price -->
<div class="bg-neutral rounded-lg p-5">
<h3 class="text-xl font-bold mb-4">Today's Oil Price</h3>
<div class="space-y-2">
<div class="flex justify-between">
<span>Price / Gallon:</span>
<span class="font-mono">${{ today_oil_price }}</span>
<div class="bg-gradient-to-br from-neutral to-neutral/80 rounded-xl p-6 shadow-medium hover-lift">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-semibold">Oil Pricing</h3>
<div class="w-12 h-12 rounded-full bg-warning/10 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 text-warning">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v12m-3-2.818l.879.659c1.171.879 3.07.879 4.242 0 1.172-.879 1.172-2.303 0-3.182C13.536 12.219 12.768 12 12 12c-.725 0-1.45-.22-2.003-.659-1.106-.879-1.106-2.303 0-3.182s2.9-.879 4.006 0l.415.33M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div class="flex justify-between">
<span>Same Day Fee:</span>
<span class="font-mono">${{ price_same_day }}</span>
</div>
<div class="space-y-3">
<div class="flex justify-between items-center">
<span class="text-sm text-base-content/70">Per Gallon</span>
<span class="text-2xl font-bold font-mono">${{ today_oil_price }}</span>
</div>
<div class="flex justify-between">
<span>Prime Fee:</span>
<span class="font-mono">${{ price_prime }}</span>
</div>
<div class="flex justify-between">
<span>Emergency Fee:</span>
<span class="font-mono">${{ price_emergency }}</span>
<div class="divider my-2"></div>
<div class="space-y-2 text-sm">
<div class="flex justify-between">
<span class="text-base-content/70">Same Day</span>
<span class="font-mono font-semibold">${{ price_same_day }}</span>
</div>
<div class="flex justify-between">
<span class="text-base-content/70">Prime</span>
<span class="font-mono font-semibold">${{ price_prime }}</span>
</div>
<div class="flex justify-between">
<span class="text-base-content/70">Emergency</span>
<span class="font-mono font-semibold">${{ price_emergency }}</span>
</div>
</div>
</div>
</div>
<!-- Card 3: Today's Oil Price -->
<div class="bg-neutral rounded-lg p-5">
<h3 class="text-xl font-bold mb-4">Service Price</h3>
<div class="space-y-2">
<div class="flex justify-between">
<span>Price / Hour:</span>
<span class="font-mono">$125</span>
<!-- Card 3: Service Pricing -->
<div class="bg-gradient-to-br from-neutral to-neutral/80 rounded-xl p-6 shadow-medium hover-lift">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-semibold">Service Pricing</h3>
<div class="w-12 h-12 rounded-full bg-info/10 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 text-info">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.42 15.17L17.25 21A2.652 2.652 0 0021 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 11-3.586-3.586l6.837-5.63m5.108-.233c.55-.164 1.163-.188 1.743-.14a4.5 4.5 0 004.486-6.336l-3.276 3.277a3.004 3.004 0 01-2.25-2.25l3.276-3.276a4.5 4.5 0 00-6.336 4.486c.091 1.076-.071 2.264-.904 2.95l-.102.085m-1.745 1.437L5.909 7.5H4.5L2.25 3.75l1.5-1.5L7.5 4.5v1.409l4.26 4.26m-1.745 1.437l1.745-1.437m6.615 8.206L15.75 15.75M4.867 19.125h.008v.008h-.008v-.008z" />
</svg>
</div>
<div class="flex justify-between">
<span>Price / Emergency:</span>
<span class="font-mono">$200</span>
</div>
<div class="space-y-4">
<div class="flex justify-between items-center">
<span class="text-sm text-base-content/70">Per Hour</span>
<span class="text-2xl font-bold font-mono">$125</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-base-content/70">Emergency</span>
<span class="text-2xl font-bold font-mono">$200</span>
</div>
</div>
</div>
<!-- Card 4: Customer Search Keys -->
<div class="bg-neutral rounded-lg p-5">
<h3 class="text-xl font-bold mb-4">Customer Search Keys</h3>
<div class="space-y-2 text-sm">
<div><span class="font-mono font-bold">@</span> - Searches customer last name only</div>
<div><span class="font-mono font-bold">!</span> - Searches customer address only</div>
<div><span class="font-mono font-bold">#</span> - Searches phone number only</div>
<div><span class="font-mono font-bold">$</span> - Searches account number only</div>
<!-- Card 4: Search Shortcuts -->
<div class="bg-gradient-to-br from-neutral to-neutral/80 rounded-xl p-6 shadow-medium hover-lift">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-semibold">Search Shortcuts</h3>
<div class="w-12 h-12 rounded-full bg-accent/10 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 text-accent">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
</svg>
</div>
</div>
<div class="space-y-3 text-sm">
<div class="flex items-center gap-3">
<kbd class="kbd kbd-sm">@</kbd>
<span class="text-base-content/70">Last name</span>
</div>
<div class="flex items-center gap-3">
<kbd class="kbd kbd-sm">!</kbd>
<span class="text-base-content/70">Address</span>
</div>
<div class="flex items-center gap-3">
<kbd class="kbd kbd-sm">#</kbd>
<span class="text-base-content/70">Phone number</span>
</div>
<div class="flex items-center gap-3">
<kbd class="kbd kbd-sm">$</kbd>
<span class="text-base-content/70">Account number</span>
</div>
</div>
</div>
<!-- Card 5: This Week's Stats -->
<!-- <div class="bg-neutral rounded-lg p-5 xl:col-span-4">
<h3 class="text-xl font-bold mb-4">This Week's Stats</h3>
@@ -108,7 +152,7 @@
</div>
</div>
</div>
<Footer />
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
@@ -117,7 +161,6 @@ import axios from 'axios'
import authHeader from '../services/auth.header'
import Header from '../layouts/headers/headerauth.vue'
import SideBar from '../layouts/sidebar/sidebar.vue'
import Footer from '../layouts/footers/footer.vue'
// Props
const props = defineProps<{