a.... LOT of Refactoring ~ 30% done???

This commit is contained in:
user
2025-10-21 15:44:16 +03:00
parent 5f4e9fc7fc
commit c0df8cae57
27 changed files with 586 additions and 746 deletions

View File

@@ -4,238 +4,121 @@
import Input from "$lib/components/ui/input/input.svelte";
import * as Select from "$lib/components/ui/select";
import { COUNTRIES_SELECT } from "$lib/core/countries";
import type { SelectOption } from "$lib/core/data.types";
import { capitalize } from "$lib/core/string.utils";
import type { CustomerInfo } from "$lib/domains/ticket/data/entities/create.entities";
import { Gender } from "$lib/domains/ticket/data/entities/index";
import { PHONE_COUNTRY_CODES } from "@pkg/logic/core/data/phonecc";
import type { CustomerInfoModel } from "../data";
import { customerInfoVM } from "./customerinfo.vm.svelte";
let { info = $bindable(), idx }: { info: CustomerInfo; idx: number } =
$props();
const genderOpts = [
{ label: capitalize(Gender.Male), value: Gender.Male },
{ label: capitalize(Gender.Female), value: Gender.Female },
{ label: capitalize(Gender.Other), value: Gender.Other },
] as SelectOption[];
let { info = $bindable() }: { info: CustomerInfoModel } = $props();
function onSubmit(e: SubmitEvent) {
e.preventDefault();
passengerInfoVM.validatePII(info, idx);
customerInfoVM.validateCustomerInfo(info);
}
let validationTimeout = $state(undefined as undefined | NodeJS.Timer);
function debounceValidate() {
if (validationTimeout) {
clearTimeout(validationTimeout);
}
validationTimeout = setTimeout(() => {
passengerInfoVM.validatePII(info, idx);
}, 500);
customerInfoVM.debounceValidate(info);
}
</script>
<form action="#" class="flex w-full flex-col gap-4" onsubmit={onSubmit}>
<!-- Name Fields -->
<div class="flex flex-col gap-4 md:flex-row">
<LabelWrapper
label="First Name"
error={passengerInfoVM.piiErrors[idx].firstName}
>
<LabelWrapper label="First Name" error={customerInfoVM.errors.firstName}>
<Input
placeholder="First Name"
bind:value={info.firstName}
required
oninput={() => debounceValidate()}
minlength={1}
maxlength={64}
/>
</LabelWrapper>
<LabelWrapper
label="Middle Name"
error={passengerInfoVM.piiErrors[idx].middleName}
error={customerInfoVM.errors.middleName}
>
<Input
placeholder="Middle Name"
placeholder="Middle Name (Optional)"
bind:value={info.middleName}
oninput={() => debounceValidate()}
required
maxlength={64}
/>
</LabelWrapper>
<LabelWrapper
label="Last Name"
error={passengerInfoVM.piiErrors[idx].lastName}
>
<LabelWrapper label="Last Name" error={customerInfoVM.errors.lastName}>
<Input
placeholder="Last Name"
bind:value={info.lastName}
required
oninput={() => debounceValidate()}
minlength={1}
maxlength={64}
/>
</LabelWrapper>
</div>
<LabelWrapper label="Email" error={passengerInfoVM.piiErrors[idx].email}>
<!-- Email Field -->
<LabelWrapper label="Email" error={customerInfoVM.errors.email}>
<Input
placeholder="Email"
bind:value={info.email}
type="email"
oninput={() => debounceValidate()}
required
maxlength={128}
/>
</LabelWrapper>
<div class="flex flex-col gap-4 md:flex-row lg:flex-col xl:flex-row">
<LabelWrapper
label="Phone Number"
error={passengerInfoVM.piiErrors[idx].phoneNumber}
>
<div class="flex gap-2">
<Select.Root
type="single"
required
onValueChange={(code) => {
info.phoneCountryCode = code;
}}
name="phoneCode"
>
<Select.Trigger class="w-20">
{#if info.phoneCountryCode}
{info.phoneCountryCode}
{:else}
Select
{/if}
</Select.Trigger>
<Select.Content>
{#each PHONE_COUNTRY_CODES as { country, phoneCode }}
<Select.Item value={phoneCode}>
<span class="flex items-center gap-2">
{phoneCode} ({country})
</span>
</Select.Item>
{/each}
</Select.Content>
</Select.Root>
<Input
placeholder="Phone Number"
type="tel"
bind:value={info.phoneNumber}
required
oninput={() => debounceValidate()}
class="flex-1"
/>
</div>
</LabelWrapper>
<LabelWrapper
label="Passport Expiry"
error={passengerInfoVM.piiErrors[idx].passportExpiry}
>
<Input
placeholder="Passport Expiry"
value={info.passportExpiry}
type="date"
<!-- Phone Number Field -->
<LabelWrapper label="Phone Number" error={customerInfoVM.errors.phoneNumber}>
<div class="flex gap-2">
<Select.Root
type="single"
required
oninput={(v) => {
// @ts-ignore
info.passportExpiry = v.target.value;
onValueChange={(code) => {
info.phoneCountryCode = code;
debounceValidate();
}}
/>
</LabelWrapper>
<LabelWrapper
label="Passport/ID No"
error={passengerInfoVM.piiErrors[idx].passportNo}
>
name="phoneCode"
>
<Select.Trigger class="w-28">
{#if info.phoneCountryCode}
{info.phoneCountryCode}
{:else}
Select
{/if}
</Select.Trigger>
<Select.Content>
{#each PHONE_COUNTRY_CODES as { country, phoneCode }}
<Select.Item value={phoneCode}>
<span class="flex items-center gap-2">
{phoneCode} ({country})
</span>
</Select.Item>
{/each}
</Select.Content>
</Select.Root>
<Input
placeholder="Passport or ID card no."
bind:value={info.passportNo}
placeholder="Phone Number"
type="tel"
bind:value={info.phoneNumber}
required
oninput={() => debounceValidate()}
class="flex-1"
minlength={1}
maxlength={20}
required
oninput={() => debounceValidate()}
/>
</LabelWrapper>
</div>
</div>
</LabelWrapper>
<!-- Address Section -->
<Title size="h5">Address Information</Title>
<div class="flex flex-col gap-4 md:flex-row">
<LabelWrapper
label="Nationality"
error={passengerInfoVM.piiErrors[idx].nationality}
>
<Select.Root
type="single"
required
onValueChange={(e) => {
info.nationality = e;
debounceValidate();
}}
name="role"
>
<Select.Trigger class="w-full">
{capitalize(
info.nationality.length > 0 ? info.nationality : "Select",
)}
</Select.Trigger>
<Select.Content>
{#each COUNTRIES_SELECT as country}
<Select.Item value={country.value}>
{country.label}
</Select.Item>
{/each}
</Select.Content>
</Select.Root>
</LabelWrapper>
<LabelWrapper
label="Gender"
error={passengerInfoVM.piiErrors[idx].gender}
>
<Select.Root
type="single"
required
onValueChange={(e) => {
info.gender = e as Gender;
debounceValidate();
}}
name="role"
>
<Select.Trigger class="w-full">
{capitalize(info.gender.length > 0 ? info.gender : "Select")}
</Select.Trigger>
<Select.Content>
{#each genderOpts as gender}
<Select.Item value={gender.value}>
{gender.label}
</Select.Item>
{/each}
</Select.Content>
</Select.Root>
</LabelWrapper>
<LabelWrapper
label="Date of Birth"
error={passengerInfoVM.piiErrors[idx].dob}
>
<Input
placeholder="Date of Birth"
bind:value={info.dob}
type="date"
required
oninput={() => debounceValidate()}
/>
</LabelWrapper>
</div>
<!-- and now for the address info - country, state, city, zip code, address and address 2 -->
<Title size="h5">Address Info</Title>
<div class="flex flex-col gap-4 md:flex-row">
<LabelWrapper
label="Country"
error={passengerInfoVM.piiErrors[idx].country}
>
<LabelWrapper label="Country" error={customerInfoVM.errors.country}>
<Select.Root
type="single"
required
@@ -243,7 +126,7 @@
info.country = e;
debounceValidate();
}}
name="role"
name="country"
>
<Select.Trigger class="w-full">
{capitalize(
@@ -260,63 +143,60 @@
</Select.Root>
</LabelWrapper>
<LabelWrapper label="State" error={passengerInfoVM.piiErrors[idx].state}>
<LabelWrapper label="State" error={customerInfoVM.errors.state}>
<Input
placeholder="State"
placeholder="State/Province"
bind:value={info.state}
required
oninput={() => debounceValidate()}
minlength={1}
maxlength={128}
/>
</LabelWrapper>
</div>
<div class="flex flex-col gap-4 md:flex-row">
<LabelWrapper label="City" error={passengerInfoVM.piiErrors[idx].city}>
<LabelWrapper label="City" error={customerInfoVM.errors.city}>
<Input
placeholder="City"
bind:value={info.city}
required
minlength={1}
maxlength={80}
maxlength={128}
oninput={() => debounceValidate()}
/>
</LabelWrapper>
<LabelWrapper
label="Zip Code"
error={passengerInfoVM.piiErrors[idx].zipCode}
>
<LabelWrapper label="Zip Code" error={customerInfoVM.errors.zipCode}>
<Input
placeholder="Zip Code"
placeholder="Zip/Postal Code"
bind:value={info.zipCode}
required
minlength={1}
maxlength={21}
oninput={() => debounceValidate()}
maxlength={12}
/>
</LabelWrapper>
</div>
<LabelWrapper label="Address" error={passengerInfoVM.piiErrors[idx].address}>
<LabelWrapper label="Address" error={customerInfoVM.errors.address}>
<Input
placeholder="Address"
placeholder="Street Address"
bind:value={info.address}
required
minlength={1}
maxlength={128}
oninput={() => debounceValidate()}
/>
</LabelWrapper>
<LabelWrapper
label="Address 2"
error={passengerInfoVM.piiErrors[idx].address2}
label="Address 2 (Optional)"
error={customerInfoVM.errors.address2}
>
<Input
placeholder="Address 2"
placeholder="Apartment, suite, etc. (Optional)"
bind:value={info.address2}
required
minlength={1}
maxlength={128}
oninput={() => debounceValidate()}
/>
</LabelWrapper>
</form>