Hello from MCP server
<template>
<ion-app>
<ion-menu side="start" menu-id="main-menu" content-id="main-content">
<ion-header>
<ion-toolbar>
<div class="menu-header">
<img
:src="customLogo || '/images/branding-dark.png'"
alt="The New Flat Rate"
class="branding-logo"
/>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="menu-content">
<ion-list class="menu-list">
<ion-menu-toggle>
<ion-item button @click="navigateTo('/review')">
<ion-icon :icon="briefcaseOutline" slot="start" color="primary" />
<ion-label>Work Orders</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle>
<ion-item button @click="navigateTo('/training-lab')">
<ion-icon :icon="schoolOutline" slot="start" color="primary" />
<ion-label>Training Lab</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle>
<ion-item button @click="navigateTo('/presentation-scripts')">
<ion-icon :icon="documentTextOutline" slot="start" color="primary" />
<ion-label>Presentation Scripts</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle>
<ion-item button @click="navigateTo('/terminology-guides')">
<ion-icon :icon="bookOutline" slot="start" color="primary" />
<ion-label>Terminology Guides</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle>
<ion-item button @click="resetCart">
<ion-icon :icon="refreshOutline" slot="start" color="primary" />
<ion-label>Reset Cart</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle>
<ion-item button @click="navigateTo('/profile')">
<ion-icon :icon="personOutline" slot="start" color="primary" />
<ion-label>Profile</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle>
<ion-item button @click="navigateTo('/settings')">
<ion-icon :icon="settingsOutline" slot="start" color="primary" />
<ion-label>Settings</ion-label>
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle>
<ion-item button @click="navigateTo('/auth/logout')">
<ion-icon :icon="logOutOutline" slot="start" color="primary" />
<ion-label>Logout</ion-label>
</ion-item>
</ion-menu-toggle>
</ion-list>
<div class="menu-version">
{{ appVersion }}
</div>
</div>
</ion-content>
</ion-menu>
<ion-router-outlet id="main-content" />
<!-- Global Bulk Upload Modal (Secret Mode) -->
<BulkUploadModal />
</ion-app>
</template>
<script setup lang="ts">
import { onMounted, ref, computed } from "vue";
import {
IonApp,
IonContent,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonMenu,
IonMenuToggle,
IonRouterOutlet,
IonTitle,
IonToolbar,
} from "@ionic/vue";
import {
briefcaseOutline,
logOutOutline,
personOutline,
settingsOutline,
schoolOutline,
documentTextOutline,
bookOutline,
refreshOutline,
} from "ionicons/icons";
import { useRouter } from "vue-router";
import { useTheme } from "@/composables/useTheme";
import { useLogo } from "@/composables/useLogo";
import { useSessionStore } from "@/stores/session";
import { usePreferencesStore } from "@/stores/preferences";
import { useTnfrStore } from "@/stores/tnfr";
import BulkUploadModal from "@/components/BulkUploadModal.vue";
const router = useRouter();
const { loadTheme } = useTheme();
const { logo, loadLogos } = useLogo();
const sessionStore = useSessionStore();
const preferences = usePreferencesStore();
const tnfrStore = useTnfrStore();
// Use computed to reactively get the logo
const customLogo = computed(() => logo.value);
// App version from environment
const appVersion = import.meta.env.VITE_APP_VERSION || 'Development';
const navigateTo = (path: string) => {
router.push(path);
};
const resetCart = () => {
// Clear the cart/tnfr store and navigate to directory
tnfrStore.clear();
router.push('/directory');
};
onMounted(async () => {
console.log('[App] Loading preferences...');
// Load preferences first so theme can be loaded from them
await preferences.getPreferences();
console.log('[App] Loading session data...');
// Load session data which includes theme colors
await sessionStore.load();
console.log('[App] Loading theme...');
// Apply saved theme or default theme
await loadTheme();
console.log('[App] Loading logos...');
// Load custom logos from IndexedDB
await loadLogos();
console.log('[App] App initialization complete');
});
</script>
<style scoped>
.menu-content {
display: flex;
flex-direction: column;
height: 100%;
/* Remove min-height: 100vh; */
}
.menu-list {
flex: 1;
/* Ensure the list doesn't create its own scroll */
overflow: visible;
}
/* Ensure ion-content doesn't scroll */
ion-content {
--overflow: hidden;
}
.menu-header {
display: flex;
justify-content: center;
align-items: center;
padding: 16px 12px;
}
.branding-logo {
max-width: 100%;
height: auto;
max-height: 50px;
}
.menu-version {
padding: 16px;
text-align: center;
font-size: 12px;
color: var(--ion-color-medium);
margin-top: auto;
}
</style>