Hello from MCP server
<template>
<BaseLayout title="Start">
<!-- Toolbar at top of screen -->
<Toolbar @help-clicked="openInfoModal" />
<div class="start-container">
<h2 class="start-title">Start</h2>
<!-- Actions Panel -->
<div class="content-panel">
<!-- No Active Call -->
<div v-if="!hasActiveCall">
<p class="status-message">No active service call</p>
<div class="button-group">
<ion-button
expand="block"
size="large"
color="primary"
@click="handleStartServiceCall"
class="start-button"
>
Start Service Call
</ion-button>
<ion-button
expand="block"
size="large"
color="secondary"
@click="handleServiceCallReview"
class="start-button"
>
Service Call Review
</ion-button>
</div>
</div>
<!-- Active Call -->
<div v-else>
<p class="status-message success">Service call in progress</p>
<div class="button-group">
<ion-button
expand="block"
size="large"
color="success"
@click="handleGoToServiceCall"
class="action-button"
>
Go To Service Call
</ion-button>
<ion-button
expand="block"
size="large"
color="danger"
@click="handleEndServiceCall"
class="action-button"
>
End Service Call
</ion-button>
</div>
</div>
</div>
<!-- Current Jobs Panel -->
<div v-if="sessionStore.jobs.length > 0" class="content-panel">
<h3 class="section-heading">Current Jobs</h3>
<div class="job-list">
<div v-for="job in sessionStore.jobs" :key="job.id" class="job-item">
<span class="job-title">{{ job.problem?.name || job.title || 'Untitled Job' }}</span>
<span v-if="job.baseHours" class="job-hours">{{ job.baseHours.toFixed(1) }}h</span>
</div>
</div>
</div>
</div>
<!-- Info Modal -->
<ion-modal :is-open="isInfoModalOpen" @didDismiss="closeInfoModal">
<ion-header>
<ion-toolbar>
<ion-title>Session Store</ion-title>
<ion-buttons slot="end">
<ion-button @click="closeInfoModal">Close</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<div class="info-content">
<pre>{{ JSON.stringify(sessionStore.$state, null, 2) }}</pre>
</div>
</ion-content>
</ion-modal>
</BaseLayout>
</template>
<script setup lang="ts">
import { ref, computed } from "vue";
import { useRouter } from "vue-router";
import {
IonButton,
IonModal,
IonHeader,
IonToolbar,
IonTitle,
IonButtons,
IonContent,
} from "@ionic/vue";
import BaseLayout from "@/components/BaseLayout.vue";
import Toolbar from "@/components/Toolbar.vue";
import { useSessionStore } from "@/stores/session";
const router = useRouter();
const sessionStore = useSessionStore();
const isInfoModalOpen = ref(false);
const hasActiveCall = computed(() => {
// A call is active if there are jobs in the session or if step1 is true
return sessionStore.jobs.length > 0 || sessionStore.appProgress.step1;
});
const openInfoModal = () => {
isInfoModalOpen.value = true;
};
const closeInfoModal = () => {
isInfoModalOpen.value = false;
};
const handleStartServiceCall = async () => {
// Initialize new session state
await sessionStore.clear();
await sessionStore.save();
// Navigate to service-call
router.push('/service-call');
};
const handleGoToServiceCall = () => {
router.push('/service-call');
};
const handleEndServiceCall = async () => {
// Clear the session
await sessionStore.clear();
await sessionStore.save();
};
const handleServiceCallReview = () => {
router.push('/service-call-review');
};
</script>
<style scoped>
:deep(.ion-page) {
animation: none !important;
transform: none !important;
transition: none !important;
}
.start-container {
padding: 20px;
max-width: 1200px;
margin: 0 auto;
animation: none !important;
transform: none !important;
transition: none !important;
}
.start-title {
margin: 0 0 32px 0;
color: var(--ion-text-color);
font-size: 32px;
font-weight: 600;
text-align: center;
font-variant: small-caps;
}
.content-panel {
background-color: var(--ion-background-color-step-50);
border-radius: 12px;
padding: 24px;
margin-bottom: 24px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.status-message {
margin: 0 0 24px 0;
text-align: center;
color: var(--ion-color-medium);
font-size: 20px;
font-style: italic;
}
.status-message.success {
color: var(--ion-color-success);
font-weight: 600;
}
.start-button {
margin: 0 auto;
max-width: 400px;
height: 60px;
font-size: 20px;
font-weight: 700;
}
.button-group {
display: flex;
flex-direction: column;
gap: 16px;
}
.action-button {
max-width: 400px;
margin: 0 auto;
height: 56px;
font-size: 18px;
font-weight: 600;
}
.section-heading {
margin: 0 0 20px 0;
color: var(--ion-text-color);
font-size: 24px;
font-weight: 700;
text-align: center;
}
.job-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.job-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
background: var(--ion-background-color);
border-radius: 8px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.job-title {
color: var(--ion-text-color);
font-size: 16px;
font-weight: 500;
}
.job-hours {
color: var(--ion-color-primary);
font-size: 14px;
font-weight: 600;
}
/* Info Modal Styles */
.info-content {
color: var(--ion-color-dark);
}
.info-content pre {
background: var(--ion-color-light);
padding: 16px;
border-radius: 8px;
overflow-x: auto;
font-size: 12px;
line-height: 1.5;
white-space: pre-wrap;
word-wrap: break-word;
}
/* Mobile adjustments */
@media (max-width: 767px) {
.start-container {
padding: 16px;
}
.start-title {
font-size: 28px;
}
.status-message {
font-size: 18px;
}
.start-button {
height: 56px;
font-size: 18px;
}
.action-button {
height: 52px;
font-size: 16px;
}
}
</style>