fix client creation

This commit is contained in:
Casey 2025-12-13 08:23:03 -06:00
parent 0d7976b140
commit 0c1bb52f1b
9 changed files with 305 additions and 161 deletions

View file

@ -1,78 +1,87 @@
<template>
<div class="form-section">
<div class="section-header">
<h3>Client Information</h3>
<label class="toggle-container" v-if="!isEditMode">
<v-switch v-model="isNewClient" color="success" />
<span class="toggle-label">New Client</span>
</label>
</div>
<div class="form-grid">
<div class="form-field">
<label for="customer-name"> Customer Name <span class="required">*</span> </label>
<div class="input-with-button">
<InputText
id="customer-name"
v-model="localFormData.customerName"
:disabled="isSubmitting || isEditMode"
placeholder="Enter customer name"
<div>
<div class="form-section">
<div class="section-header">
<h3>Client Information</h3>
<label class="toggle-container" v-if="!isEditMode">
<v-switch v-model="isNewClient" color="success" />
<span class="toggle-label">New Client</span>
</label>
</div>
<div class="form-grid">
<div class="form-field">
<label for="customer-name"> Customer Name <span class="required">*</span> </label>
<div class="input-with-button">
<InputText
id="customer-name"
v-model="localFormData.customerName"
:disabled="isSubmitting || isEditMode"
placeholder="Enter customer name"
class="w-full"
/>
<Button
label="Check Client"
size="small"
icon="pi pi-user-check"
class="check-btn"
@click="checkCustomerExists"
:disabled="isSubmitting || !localFormData.customerName.trim()"
>Check</Button>
<Button
v-if="!isNewClient && !isEditMode"
@click="searchCustomers"
:disabled="isSubmitting || !localFormData.customerName.trim()"
size="small"
icon="pi pi-search"
class="search-btn"
></Button>
</div>
</div>
<div class="form-field">
<label for="customer-type"> Customer Type <span class="required">*</span> </label>
<Select
id="customer-type"
v-model="localFormData.customerType"
:options="customerTypeOptions"
:disabled="isSubmitting || (!isNewClient && !isEditMode)"
placeholder="Select customer type"
class="w-full"
/>
<Button
v-if="!isNewClient && !isEditMode"
@click="searchCustomers"
:disabled="isSubmitting || !localFormData.customerName.trim()"
size="small"
icon="pi pi-search"
class="search-btn"
></Button>
</div>
</div>
<div class="form-field">
<label for="customer-type"> Customer Type <span class="required">*</span> </label>
<Select
id="customer-type"
v-model="localFormData.customerType"
:options="customerTypeOptions"
:disabled="isSubmitting || (!isNewClient && !isEditMode)"
placeholder="Select customer type"
class="w-full"
/>
</div>
</div>
<!-- Customer Search Results Modal -->
<Dialog
:visible="showCustomerSearchModal"
@update:visible="showCustomerSearchModal = $event"
header="Select Customer"
:modal="true"
class="search-dialog"
>
<div class="search-results">
<div v-if="customerSearchResults.length === 0" class="no-results">
<i class="pi pi-info-circle"></i>
<p>No customers found matching your search.</p>
</div>
<div v-else class="results-list">
<div
v-for="(customerName, index) in customerSearchResults"
:key="index"
class="result-item"
@click="selectCustomer(customerName)"
>
<strong>{{ customerName }}</strong>
<i class="pi pi-chevron-right"></i>
</div>
</div>
</div>
<template #footer>
<Button label="Cancel" severity="secondary" @click="showCustomerSearchModal = false" />
</template>
</Dialog>
</div>
<!-- Customer Search Results Modal -->
<Dialog
v-model:visible="showCustomerSearchModal"
header="Select Customer"
:modal="true"
class="search-dialog"
>
<div class="search-results">
<div v-if="customerSearchResults.length === 0" class="no-results">
<i class="pi pi-info-circle"></i>
<p>No customers found matching your search.</p>
</div>
<div v-else class="results-list">
<div
v-for="(customerName, index) in customerSearchResults"
:key="index"
class="result-item"
@click="selectCustomer(customerName)"
>
<strong>{{ customerName }}</strong>
<i class="pi pi-chevron-right"></i>
</div>
</div>
</div>
<template #footer>
<Button label="Cancel" severity="secondary" @click="showCustomerSearchModal = false" />
</template>
</Dialog>
</template>
<script setup>
</template><script setup>
import { ref, watch, computed } from "vue";
import InputText from "primevue/inputtext";
import Select from "primevue/select";
@ -109,6 +118,30 @@ const showCustomerSearchModal = ref(false);
const customerSearchResults = ref([]);
const customerTypeOptions = ["Individual", "Partnership", "Company"];
const mapContactsFromClient = (contacts = []) => {
if (!Array.isArray(contacts) || contacts.length === 0) {
return [
{
firstName: "",
lastName: "",
phoneNumber: "",
email: "",
contactRole: "",
isPrimary: true,
},
];
}
return contacts.map((contact, index) => ({
firstName: contact.firstName || "",
lastName: contact.lastName || "",
phoneNumber: contact.phoneNumber || contact.phone || contact.mobileNo || "",
email: contact.email || contact.emailId || contact.customEmail || "",
contactRole: contact.contactRole || contact.role || "",
isPrimary: contact.isPrimary ?? contact.isPrimaryContact ?? index === 0,
}));
};
// Watch for toggle changes
watch(isNewClient, (newValue) => {
emit("newClientToggle", newValue);
@ -138,6 +171,45 @@ const searchCustomers = async () => {
}
};
const checkCustomerExists = async () => {
const searchTerm = localFormData.value.customerName.trim();
if (!searchTerm) return;
try {
const client = await Api.getClient(searchTerm);
if (!client) {
notificationStore.addInfo("Customer is not in our system yet.");
return;
}
localFormData.value.customerName = client.customerName || searchTerm;
localFormData.value.customerType = client.customerType || localFormData.value.customerType;
localFormData.value.contacts = mapContactsFromClient(client.contacts);
isNewClient.value = false;
showCustomerSearchModal.value = false;
emit("customerSelected", client);
notificationStore.addSuccess(
`Customer ${localFormData.value.customerName} found and loaded from system.`,
);
} catch (error) {
console.error("Error checking customer:", error);
const message =
typeof error?.message === "string" &&
error.message.toLowerCase().includes("not found")
? "Customer is not in our system yet."
: "Failed to check customer. Please try again.";
if (message.includes("not in our system")) {
notificationStore.addInfo(message);
} else {
notificationStore.addError(message);
}
}
};
const selectCustomer = async (customerName) => {
try {
// Fetch full customer data
@ -145,6 +217,7 @@ const selectCustomer = async (customerName) => {
localFormData.value.customerName = clientData.customerName;
localFormData.value.customerType = clientData.customerType;
localFormData.value.contacts = mapContactsFromClient(clientData.contacts);
showCustomerSearchModal.value = false;
// Pass the full client data including contacts
@ -306,6 +379,24 @@ defineExpose({
background: var(--surface-hover);
}
.check-btn {
border: 1px solid var(--primary-color);
color: var(--primary-color);
background: var(--surface-card);
padding: 0.25rem 0.75rem;
min-width: 8rem;
justify-content: center;
}
.check-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.check-btn:hover:not(:disabled) {
background: var(--surface-hover);
}
.search-btn {
background: var(--primary-color);
border: 1px solid var(--primary-color);
@ -317,6 +408,7 @@ defineExpose({
border-radius: 4px;
transition: background 0.2s;
color: white;
min-width: 8rem;
}
.search-btn:disabled {