style: fix prefer-svelte-reactivity — replace with Svelte reactive equivalents

This commit is contained in:
2026-06-25 14:40:22 +01:00
parent d5e93b3be2
commit 334b911e16
11 changed files with 35 additions and 29 deletions
@@ -1,7 +1,7 @@
<script lang="ts">
import { authStore } from '$lib/stores/auth.svelte';
import { toast } from 'svelte-sonner';
import { SvelteDate } from 'svelte/reactivity';
import { SvelteDate, SvelteSet, SvelteURLSearchParams } from 'svelte/reactivity';
import { CalendarDate, getLocalTimeZone, type DateValue } from '@internationalized/date';
import { isValidUKPhone, toE164UK } from '$lib/utils/phone';
import { formatUserName } from '$lib/utils/nameDisplay';
@@ -235,7 +235,7 @@
// =============== Cache ===============
let workingHoursCache: Record<string, Record<string, DayHours>> = {};
let availableHoursCache: Record<string, Record<string, DayAvailability>> = {};
let loadingMonthKeys: Set<string> = new Set();
let loadingMonthKeys: Set<string> = new SvelteSet();
// =============== Derived Helpers ===============
function getTotalDuration() {
@@ -456,7 +456,7 @@
bookingCreateInitialLoadDone = false;
userNavigatedCalendar = false;
bookingCreateAutoSelectDone = false;
loadingMonthKeys = new Set();
loadingMonthKeys = new SvelteSet();
outOfHours = false;
normalWorkingHours = null;
// Clear reservation state
@@ -602,7 +602,7 @@
// Prevent re-entrant calls for the same month
if (loadingMonthKeys.has(monthKey)) return;
loadingMonthKeys = new Set(loadingMonthKeys).add(monthKey);
loadingMonthKeys = new SvelteSet(loadingMonthKeys).add(monthKey);
hoursMonthGeneration++;
const gen = hoursMonthGeneration;
@@ -657,7 +657,7 @@
} finally {
_loadingWorkingHours = false;
loadingAvailableHours = false;
loadingMonthKeys = new Set([...loadingMonthKeys].filter((k) => k !== monthKey));
loadingMonthKeys = new SvelteSet([...loadingMonthKeys].filter((k) => k !== monthKey));
}
}
@@ -811,7 +811,7 @@
async function fetchCustomServices() {
loadingCustomServices = true;
try {
const params = new URLSearchParams();
const params = new SvelteURLSearchParams();
if (customSearchQuery.trim()) {
params.set('q', customSearchQuery.trim());
} else {
@@ -1,6 +1,6 @@
<script lang="ts">
import { authStore } from '$lib/stores/auth.svelte';
import { SvelteDate } from 'svelte/reactivity';
import { SvelteDate, SvelteURLSearchParams } from 'svelte/reactivity';
import { toast } from 'svelte-sonner';
// shadcn-svelte components
@@ -31,7 +31,7 @@
async function fetchBookings(pageIdx: number = 0, search: string = '') {
loadingSearch = true;
try {
const params = new URLSearchParams({
const params = new SvelteURLSearchParams({
per_page: '3'
});
const cursor = cursors[pageIdx];
@@ -8,6 +8,7 @@
import * as Modal from '$lib/components/ui/dialog';
import { Skeleton } from '$lib/components/ui/skeleton';
import { Separator } from '$lib/components/ui/separator';
import { SvelteURLSearchParams } from 'svelte/reactivity';
type CustomService = {
id: string;
@@ -106,7 +107,7 @@
async function fetchServices() {
loading = true;
try {
const params = new URLSearchParams({
const params = new SvelteURLSearchParams({
page: page.toString(),
per_page: perPage.toString()
});
@@ -8,6 +8,7 @@
import * as Modal from '$lib/components/ui/dialog';
import { Skeleton } from '$lib/components/ui/skeleton';
import { formatUserName } from '$lib/utils/nameDisplay';
import { SvelteDate, SvelteURLSearchParams } from 'svelte/reactivity';
interface GiftCard {
id: string;
@@ -252,7 +253,7 @@
loading = true;
loadingSearch = true;
try {
const params = new URLSearchParams({
const params = new SvelteURLSearchParams({
page: page.toString(),
per_page: '10'
});
@@ -779,7 +780,7 @@
}
function formatDate(dateStr: string): string {
return new Date(dateStr).toLocaleDateString('en-GB', {
return new SvelteDate(dateStr).toLocaleDateString('en-GB', {
day: 'numeric',
month: 'short',
year: 'numeric',
@@ -789,14 +790,14 @@
function getExpiryDate(lastUsedAt?: string): Date | null {
if (!lastUsedAt) return null;
const date = new Date(lastUsedAt);
const date = new SvelteDate(lastUsedAt);
date.setMonth(date.getMonth() + 24);
return date;
}
function isExpired(lastUsedAt?: string): boolean {
const expiry = getExpiryDate(lastUsedAt);
return expiry !== null && expiry < new Date();
return expiry !== null && expiry < new SvelteDate();
}
// =============== Sorting ===============
@@ -854,7 +855,7 @@
case 'remaining':
return (a.amount_remaining - b.amount_remaining) * mul;
case 'created':
return (new Date(a.created_at).getTime() - new Date(b.created_at).getTime()) * mul;
return (new SvelteDate(a.created_at).getTime() - new SvelteDate(b.created_at).getTime()) * mul;
case 'status': {
const aVal = a.redeemed_by ? 2 : a.amount_remaining === 0 ? 1 : 0;
const bVal = b.redeemed_by ? 2 : b.amount_remaining === 0 ? 1 : 0;
@@ -883,7 +884,7 @@
case 'balance':
return (a.balance - b.balance) * mul;
case 'updated':
return (new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime()) * mul;
return (new SvelteDate(a.updated_at).getTime() - new SvelteDate(b.updated_at).getTime()) * mul;
default:
return 0;
}
@@ -7,6 +7,7 @@
import { Checkbox } from '$lib/components/ui/checkbox';
import { Skeleton } from '$lib/components/ui/skeleton';
import * as Modal from '$lib/components/ui/dialog';
import { SvelteMap } from 'svelte/reactivity';
type Service = {
id: string;
@@ -110,7 +111,7 @@
if (ptRes.ok && svcRes.ok) {
patchTests = await ptRes.json();
const svcData = await svcRes.json();
const uniqueSvc = new Map();
const uniqueSvc = new SvelteMap();
svcData.forEach((s: Service) => {
if (s.id) uniqueSvc.set(s.id, s);
});
@@ -8,6 +8,7 @@
import { Input } from '$lib/components/ui/input';
import * as Modal from '$lib/components/ui/dialog';
import { Skeleton } from '$lib/components/ui/skeleton';
import { SvelteMap } from 'svelte/reactivity';
// =============== Types ===============
type Service = {
@@ -151,7 +152,7 @@
if (response.ok) {
const data = await response.json();
const uniqueServices = new Map();
const uniqueServices = new SvelteMap();
data.forEach((s: Service) => {
if (s.id) uniqueServices.set(s.id, s);
});
@@ -1,6 +1,6 @@
<script lang="ts">
import { authStore } from '$lib/stores/auth.svelte';
import { SvelteDate } from 'svelte/reactivity';
import { SvelteDate, SvelteURLSearchParams } from 'svelte/reactivity';
import { toast } from 'svelte-sonner';
import * as Modal from '$lib/components/ui/dialog';
import { Button } from '$lib/components/ui/button';
@@ -155,7 +155,7 @@
loadingBookings = true;
try {
const params = new URLSearchParams({
const params = new SvelteURLSearchParams({
per_page: '4'
});
const cursor = cursors[pageIdx];
@@ -6,6 +6,7 @@
import { Button } from '$lib/components/ui/button';
import { Skeleton } from '$lib/components/ui/skeleton';
import { formatUserName } from '$lib/utils/nameDisplay';
import { SvelteURLSearchParams } from 'svelte/reactivity';
interface Props {
openUserModal: (userId: string) => void;
@@ -47,7 +48,7 @@
loadingSearch = true;
try {
const params = new URLSearchParams({
const params = new SvelteURLSearchParams({
per_page: '4'
});
const cursor = cursors[pageIdx];
@@ -2,7 +2,7 @@
import { authStore } from '$lib/stores/auth.svelte';
import { generateUUID } from '$lib/utils/uuid';
import { toast } from 'svelte-sonner';
import { SvelteDate } from 'svelte/reactivity';
import { SvelteDate, SvelteURLSearchParams } from 'svelte/reactivity';
import { getLocalTimeZone } from '@internationalized/date';
import { isValidUKPhone, toE164UK } from '$lib/utils/phone';
import { formatUserName } from '$lib/utils/nameDisplay';
@@ -351,7 +351,7 @@
async function fetchCustomServices() {
loadingCustomServices = true;
try {
const params = new URLSearchParams();
const params = new SvelteURLSearchParams();
if (customSearchQuery.trim()) {
params.set('q', customSearchQuery.trim());
} else {
@@ -104,15 +104,15 @@
/** Return the current London date as a Date set to midnight in the local timezone.
* Uses Intl.DateTimeFormat with Europe/London to handle BST/GMT correctly. */
function getLondonToday(): Date {
const dateStr = new Date().toLocaleDateString('en-CA', { timeZone: 'Europe/London' });
return new Date(dateStr + 'T00:00:00');
const dateStr = new SvelteDate().toLocaleDateString('en-CA', { timeZone: 'Europe/London' });
return new SvelteDate(dateStr + 'T00:00:00');
}
/** Return the current time-of-day in London as minutes since midnight, using
* Intl.DateTimeFormat with Europe/London so the current-time blue line is
* positioned correctly regardless of the browser's system timezone. */
function getLondonNowMinutes(): number {
const timeStr = new Date().toLocaleTimeString('en-GB', {
const timeStr = new SvelteDate().toLocaleTimeString('en-GB', {
timeZone: 'Europe/London',
hour: '2-digit',
minute: '2-digit',
@@ -127,7 +127,7 @@
* at 23:30 UTC (00:30 BST next day) are grouped under the correct
* London date column rather than the UTC date. */
function getLondonDateKey(iso: string): string {
return new Date(iso).toLocaleDateString('en-CA', { timeZone: 'Europe/London' });
return new SvelteDate(iso).toLocaleDateString('en-CA', { timeZone: 'Europe/London' });
}
function formatWeekLabel(start: Date): string {
@@ -316,7 +316,7 @@
function navigateWeek(delta: number) {
if (!weekStart) return;
const d = new Date(weekStart);
const d = new SvelteDate(weekStart);
d.setDate(d.getDate() + delta * 7);
weekStart = d;
}
+3 -2
View File
@@ -6,6 +6,7 @@
import * as Card from '$lib/components/ui/card';
import { Skeleton } from '$lib/components/ui/skeleton';
import { Separator } from '$lib/components/ui/separator';
import { SvelteMap } from 'svelte/reactivity';
type GdprData = {
user_profile: {
@@ -401,7 +402,7 @@
.filter((r) => r.status === 'completed')
.reduce((sum, r) => sum + Number(r.amount), 0);
const serviceMap = new Map<string, { count: number; total: number }>();
const serviceMap = new SvelteMap<string, { count: number; total: number }>();
for (const b of bookings) {
for (const s of b.services ?? []) {
const existing = serviceMap.get(s.name) ?? { count: 0, total: 0 };
@@ -415,7 +416,7 @@
.sort((a, b) => b.count - a.count)
.slice(0, 5);
const methodMap = new Map<string, { count: number; total: number }>();
const methodMap = new SvelteMap<string, { count: number; total: number }>();
for (const p of payments.filter((p) => p.status === 'completed')) {
if (p.payment_method === 'discount') continue;
const method = p.payment_method.replace(/_/g, ' ');