fix: revert agent damage — fix svelte-ignore comments, catch var refs, prop mismatches
- Convert HTML comments in script sections to eslint-disable-next-line - Fix err->_err references in catch blocks across 8 files - Fix required→_required and onclose→_onclose prop mismatches - Revert BookingCreateModal.svelte from no-unused-vars agent damage - Fix broken regex in account page - Fix .writable (not in Svelte 5 stable) back to + - Fix NavBar dynamic href links with proper eslint-disable
This commit is contained in:
@@ -146,6 +146,8 @@
|
||||
!customServiceErrors.minimum_age_required
|
||||
);
|
||||
|
||||
function toggleCustomForm(show: boolean) {
|
||||
showCustomCreateForm = show;
|
||||
if (show) {
|
||||
newCustomService = {
|
||||
name: '',
|
||||
@@ -324,6 +326,7 @@
|
||||
: !!(guestName.trim() && guestPhone.trim() && isValidUKPhone(guestPhone))
|
||||
);
|
||||
const canProceedStep2 = $derived(selectedServices.length > 0);
|
||||
const canProceedStep3 = $derived(true); // Overrides are optional
|
||||
const canProceedStep4 = $derived(!!(selectedDate && selectedTime));
|
||||
|
||||
/** Whether the currently selected time slot is out-of-hours */
|
||||
@@ -484,7 +487,7 @@
|
||||
(user: { account_role: string }) => !excludedRoles.includes(user.account_role)
|
||||
);
|
||||
}
|
||||
} catch (_err) {
|
||||
} catch (err) {
|
||||
toast.error('Failed to load users');
|
||||
} finally {
|
||||
loadingUsers = false;
|
||||
@@ -505,7 +508,7 @@
|
||||
if (response.ok) {
|
||||
services = await response.json();
|
||||
}
|
||||
} catch (_err) {
|
||||
} catch (err) {
|
||||
toast.error('Failed to load services');
|
||||
} finally {
|
||||
loadingServices = false;
|
||||
@@ -579,7 +582,7 @@
|
||||
workingHours = { ...workingHours, ...whMap };
|
||||
availableHours = { ...availableHours, ...ahMap };
|
||||
}
|
||||
} catch (_err) {
|
||||
} catch (err) {
|
||||
toast.error('Failed to load availability');
|
||||
} finally {
|
||||
_loadingWorkingHours = false;
|
||||
@@ -649,7 +652,7 @@
|
||||
workingHours = { ...workingHours, ...whMap };
|
||||
availableHours = { ...availableHours, ...ahMap };
|
||||
}
|
||||
} catch (_err) {
|
||||
} catch (err) {
|
||||
toast.error('Failed to load availability');
|
||||
} finally {
|
||||
_loadingWorkingHours = false;
|
||||
@@ -739,7 +742,7 @@
|
||||
toast.error(`Failed to reserve slot: ${errorText}`);
|
||||
return false;
|
||||
}
|
||||
} catch (_err) {
|
||||
} catch (err) {
|
||||
toast.error('Failed to reserve slot');
|
||||
return false;
|
||||
} finally {
|
||||
@@ -1039,7 +1042,7 @@
|
||||
const errorText = await res.text();
|
||||
toast.error(`Failed to create booking: ${errorText}`);
|
||||
}
|
||||
} catch (_err) {
|
||||
} catch (err) {
|
||||
toast.error('An error occurred while creating booking');
|
||||
} finally {
|
||||
submitting = false;
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
toast.error('Failed to load booking details: ' + text);
|
||||
}
|
||||
} catch (_err) {
|
||||
console.error('Error fetching booking details:', err);
|
||||
console.error(..._err);
|
||||
toast.error('Network error loading booking details');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@
|
||||
|
||||
noSlotsToday = true;
|
||||
} catch (_err) {
|
||||
console.error('Failed to calculate slot availability', err);
|
||||
console.error('Failed to calculate slot availability', _err);
|
||||
noSlotsToday = true;
|
||||
} finally {
|
||||
loading = false;
|
||||
@@ -279,7 +279,7 @@
|
||||
return false;
|
||||
}
|
||||
} catch (_err) {
|
||||
console.error('Reservation error:', err);
|
||||
console.error('Reservation error:', _err);
|
||||
toast.error('Failed to reserve slot');
|
||||
return false;
|
||||
} finally {
|
||||
|
||||
@@ -297,7 +297,7 @@
|
||||
);
|
||||
}
|
||||
} catch (_err) {
|
||||
console.error('Failed to fetch users', err);
|
||||
console.error('Failed to fetch users', _err);
|
||||
toast.error('Failed to load users');
|
||||
} finally {
|
||||
loadingUsers = false;
|
||||
@@ -815,7 +815,7 @@
|
||||
bind:value={guestPhone}
|
||||
bind:error={guestPhoneError}
|
||||
placeholder="07700 900000"
|
||||
required={false}
|
||||
_required={false}
|
||||
/>
|
||||
</div>
|
||||
<p class="rounded-lg bg-yellow-50 p-3 text-sm text-yellow-800">
|
||||
|
||||
@@ -280,7 +280,7 @@
|
||||
}
|
||||
}
|
||||
} catch (_err) {
|
||||
console.error('Failed to fetch discount preview:', err);
|
||||
console.error('Failed to fetch discount preview:', _err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,8 @@
|
||||
{#if isLoading}
|
||||
<Skeleton class={`h-4 ${link.width} rounded`} />
|
||||
{:else}
|
||||
<a href={resolve(link.href)} class="font-medium text-gray-800 hover:text-primary"
|
||||
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
|
||||
<a href={link.href} class="font-medium text-gray-800 hover:text-primary"
|
||||
>{link.label}</a
|
||||
>
|
||||
{/if}
|
||||
@@ -230,7 +231,7 @@
|
||||
<Skeleton class="h-4 w-full rounded" />
|
||||
{:else}
|
||||
<a
|
||||
href={resolve(link.href)}
|
||||
href={link.href}
|
||||
class="block rounded px-3 py-2 text-center text-primary hover:text-gray-800"
|
||||
>
|
||||
{link.label}
|
||||
|
||||
@@ -299,7 +299,7 @@
|
||||
startPolling();
|
||||
} catch (_err) {
|
||||
status = 'error';
|
||||
error = err instanceof Error ? err.message : 'Failed to initiate payment';
|
||||
error = _err instanceof Error ? _err.message : 'Failed to initiate payment';
|
||||
toast.error(error ?? 'Unknown error');
|
||||
}
|
||||
}
|
||||
@@ -452,7 +452,7 @@
|
||||
onComplete(paymentResult);
|
||||
} catch (_err) {
|
||||
status = 'error';
|
||||
error = err instanceof Error ? err.message : 'Failed to process payment';
|
||||
error = _err instanceof Error ? _err.message : 'Failed to process payment';
|
||||
toast.error(error ?? 'Unknown error');
|
||||
}
|
||||
}
|
||||
@@ -577,7 +577,7 @@
|
||||
onComplete(paymentResult);
|
||||
} catch (_err) {
|
||||
status = 'error';
|
||||
error = err instanceof Error ? err.message : 'Failed to process gift card';
|
||||
error = _err instanceof Error ? _err.message : 'Failed to process gift card';
|
||||
toast.error(error ?? 'Unknown error');
|
||||
}
|
||||
}
|
||||
@@ -659,7 +659,7 @@
|
||||
onComplete(paymentResult);
|
||||
} catch (_err) {
|
||||
status = 'error';
|
||||
error = err instanceof Error ? err.message : 'Failed to process saved card payment';
|
||||
error = _err instanceof Error ? _err.message : 'Failed to process saved card payment';
|
||||
toast.error(error ?? 'Unknown error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,11 @@
|
||||
// state. The backend will split the charge into deposit + non-deposit records
|
||||
// when appropriate, so this choice mainly controls the button label and amount.
|
||||
const defaultType = $derived(defaultPaymentType ?? (depositOutstanding ? 'deposit' : 'full'));
|
||||
let paymentType = $derived.writable(defaultType as 'full' | 'partial' | 'deposit');
|
||||
// eslint-disable-next-line svelte/prefer-writable-derived — $derived.writable not in Svelte 5 stable
|
||||
let paymentType = $state<'full' | 'partial' | 'deposit'>('full');
|
||||
$effect(() => {
|
||||
paymentType = defaultType as 'full' | 'partial' | 'deposit';
|
||||
});
|
||||
|
||||
let pollingInterval: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
@@ -358,7 +362,7 @@
|
||||
lockTimer = 300;
|
||||
}
|
||||
} catch (_err) {
|
||||
console.error('Failed to acquire payment lock:', err);
|
||||
console.error('Failed to acquire payment lock:', _err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +377,7 @@
|
||||
}
|
||||
});
|
||||
} catch (_err) {
|
||||
console.error('Failed to release payment lock:', err);
|
||||
console.error('Failed to release payment lock:', _err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +401,7 @@
|
||||
lockAcquired = true;
|
||||
}
|
||||
} catch (_err) {
|
||||
console.error('Failed to renew payment lock:', err);
|
||||
console.error('Failed to renew payment lock:', _err);
|
||||
}
|
||||
}, 60000);
|
||||
}
|
||||
@@ -433,7 +437,7 @@
|
||||
paymentMethods = await response.json();
|
||||
}
|
||||
} catch (_err) {
|
||||
console.error('Failed to fetch payment methods:', err);
|
||||
console.error('Failed to fetch payment methods:', _err);
|
||||
} finally {
|
||||
paymentMethodsLoading = false;
|
||||
}
|
||||
@@ -452,7 +456,7 @@
|
||||
stamps = data.stamps ?? 0;
|
||||
}
|
||||
} catch (_err) {
|
||||
console.error('Failed to fetch loyalty data:', err);
|
||||
console.error('Failed to fetch loyalty data:', _err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,7 +511,7 @@
|
||||
}
|
||||
} catch (_err) {
|
||||
status = 'error';
|
||||
const msg = err instanceof Error ? err.message : 'Failed to apply loyalty discount';
|
||||
const msg = _err instanceof Error ? _err.message : 'Failed to apply loyalty discount';
|
||||
error = msg;
|
||||
toast.error(msg);
|
||||
return;
|
||||
@@ -570,7 +574,7 @@
|
||||
releaseLock();
|
||||
} catch (_err) {
|
||||
status = 'error';
|
||||
const msg = err instanceof Error ? err.message : 'Payment declined';
|
||||
const msg = _err instanceof Error ? _err.message : 'Payment declined';
|
||||
error = msg;
|
||||
toast.error(`${msg}. Please try again or use another card.`);
|
||||
releaseLock();
|
||||
@@ -643,7 +647,7 @@
|
||||
discountPreview = await resp.json();
|
||||
}
|
||||
} catch (_err) {
|
||||
console.error('Failed to fetch discount preview:', err);
|
||||
console.error('Failed to fetch discount preview:', _err);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
let wrapperElement: HTMLDivElement | null = $state(null);
|
||||
|
||||
// Create popup when map is ready
|
||||
<!-- svelte-ignore no-dom-manipulating -->
|
||||
// eslint-disable-next-line svelte/no-dom-manipulating
|
||||
$effect(() => {
|
||||
const map = mapCtx.getMap();
|
||||
const loaded = mapCtx.isLoaded();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
let movedContent: Node[] = [];
|
||||
|
||||
// Move content to marker element when ready
|
||||
<!-- svelte-ignore no-dom-manipulating -->
|
||||
// eslint-disable-next-line svelte/no-dom-manipulating
|
||||
$effect(() => {
|
||||
const element = markerCtx.getElement();
|
||||
const ready = markerCtx.isReady();
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
let shouldStayOpen = $state(false);
|
||||
|
||||
// Create popup when marker is ready
|
||||
<!-- svelte-ignore no-dom-manipulating -->
|
||||
// eslint-disable-next-line svelte/no-dom-manipulating
|
||||
$effect(() => {
|
||||
const marker = markerCtx.getMarker();
|
||||
const ready = markerCtx.isReady();
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
let wrapperElement: HTMLDivElement | null = $state(null);
|
||||
|
||||
// Create tooltip popup when marker is ready
|
||||
<!-- svelte-ignore no-dom-manipulating -->
|
||||
// eslint-disable-next-line svelte/no-dom-manipulating
|
||||
$effect(() => {
|
||||
const marker = markerCtx.getMarker();
|
||||
const markerElement = markerCtx.getElement();
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
function handleInput(e: Event) {
|
||||
const _target = e.target as HTMLInputElement;
|
||||
const formatted = formatPhoneDisplay(target.value);
|
||||
const formatted = formatPhoneDisplay(_target.value);
|
||||
value = formatted;
|
||||
onvaluechange?.(formatted);
|
||||
// Only show live validation after the field has been blurred at least once
|
||||
|
||||
Reference in New Issue
Block a user