updated calendar to be tabular, moved bid schedule there, started client view refactoring

This commit is contained in:
Casey 2025-12-12 08:03:48 -06:00
parent c5c5ffb0fb
commit 440381265c
18 changed files with 2283 additions and 2159 deletions

View file

@ -0,0 +1,29 @@
<template>
<div class="additional-info-bar">
<span>additional address information. coming soon</span>
</div>
</template>
<script setup>
const props = defineProps({
address: {
type: Object,
default: null
}
})
</script>
<style lang="scss" scoped>
.additional-info-bar {
display: flex;
align-items: center;
justify-content: center;
padding: 0.25rem 1rem;
background: linear-gradient(135deg, #f0f9f0 0%, #e8f5e8 100%);
color: #2d5a47;
border-bottom: 1px solid #c8e6c9;
font-size: 0.75rem;
font-weight: 500;
min-height: 30px;
}
</style>

View file

@ -0,0 +1,180 @@
<template>
<div class="top-bar">
<div class="address-section">
<label class="section-label">Address:</label>
<Dropdown
v-model="selectedAddressIdx"
:options="addressOptions"
option-label="label"
option-value="value"
placeholder="Select Address"
class="address-dropdown"
/>
</div>
<div class="contact-section">
<div class="contact-info">
<div class="contact-item">
<strong>{{ primaryContact.name }}</strong>
</div>
<div class="contact-item">
<i class="pi pi-phone"></i> {{ primaryContact.phone }}
</div>
<div class="contact-item">
<i class="pi pi-envelope"></i> {{ primaryContact.email }}
</div>
</div>
<div v-if="client.customerName !== primaryContact.fullName" class="customer-name">
<span class="customer-label">Customer:</span> {{ client.customerName }}
</div>
</div>
<div class="visit-section">
<i class="pi pi-calendar"></i>
<span>Next Visit: {{ nextVisitDate ? formatDate(nextVisitDate) : 'None' }}</span>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import Dropdown from 'primevue/dropdown'
const props = defineProps({
client: {
type: Object,
required: true
},
nextVisitDate: {
type: [String, Date],
default: null
}
})
const selectedAddressIdx = defineModel('selectedAddressIdx')
const addressOptions = computed(() => {
return props.client.addresses.map((addr, index) => ({
label: addr.fullAddress,
value: index
}))
})
const primaryContact = computed(() => {
const contactName = props.client.addresses[selectedAddressIdx.value]?.customContactName
return props.client.contacts.find(contact => contact.name === contactName) || {}
})
const formatDate = (date) => {
// Assuming date is a string or Date object, format as needed
return new Date(date).toLocaleDateString()
}
</script>
<style lang="scss" scoped>
.top-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.5rem 1rem;
background: linear-gradient(135deg, #0d4f3c 0%, #1a5f4a 100%);
color: #fff;
border-bottom: 1px solid #2d5a47;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
flex-wrap: wrap;
gap: 0.5rem;
min-height: 50px;
}
.address-section {
display: flex;
align-items: center;
gap: 0.25rem;
min-width: 200px;
}
.section-label {
font-weight: 500;
color: #adb5bd;
white-space: nowrap;
font-size: 0.85rem;
}
.address-dropdown {
flex: 1;
min-width: 150px;
}
.contact-section {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25rem;
flex: 1;
text-align: center;
}
.contact-info {
display: flex;
gap: 0.75rem;
align-items: center;
flex-wrap: wrap;
justify-content: center;
}
.contact-item {
display: flex;
align-items: center;
gap: 0.2rem;
font-size: 0.8rem;
color: #fff;
}
.customer-name {
font-size: 0.75rem;
color: #adb5bd;
font-weight: 500;
}
.customer-label {
font-weight: 600;
color: #fff;
}
.visit-section {
display: flex;
align-items: center;
gap: 0.25rem;
font-weight: 500;
font-size: 0.8rem;
background: #495057;
padding: 0.25rem 0.5rem;
border-radius: 10px;
white-space: nowrap;
color: #fff;
}
@media (max-width: 768px) {
.top-bar {
flex-direction: column;
align-items: stretch;
padding: 0.5rem;
min-height: auto;
}
.address-section {
justify-content: center;
}
.contact-section {
align-items: center;
}
.contact-info {
flex-direction: column;
gap: 0.25rem;
}
.visit-section {
justify-content: center;
}
}
</style>