fixes for giftcards and phone input
This commit is contained in:
@@ -0,0 +1,48 @@
|
|||||||
|
export type SavedCard = {
|
||||||
|
id: string;
|
||||||
|
brand: string;
|
||||||
|
last_4: string;
|
||||||
|
exp_month: number;
|
||||||
|
exp_year: number;
|
||||||
|
cardholder_name?: string;
|
||||||
|
is_default: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
function createSavedCardsStore() {
|
||||||
|
let cards = $state<SavedCard[]>([]);
|
||||||
|
let loading = $state(false);
|
||||||
|
let loaded = $state(false);
|
||||||
|
|
||||||
|
async function fetch() {
|
||||||
|
if (loading) return;
|
||||||
|
loading = true;
|
||||||
|
try {
|
||||||
|
const res = await globalThis.fetch('/api/user/payment-methods', { credentials: 'include' });
|
||||||
|
if (res.ok) {
|
||||||
|
cards = await res.json();
|
||||||
|
} else {
|
||||||
|
cards = [];
|
||||||
|
}
|
||||||
|
loaded = true;
|
||||||
|
} catch {
|
||||||
|
cards = [];
|
||||||
|
} finally {
|
||||||
|
loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function invalidate() {
|
||||||
|
loaded = false;
|
||||||
|
return fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
get cards() { return cards; },
|
||||||
|
get loading() { return loading; },
|
||||||
|
get loaded() { return loaded; },
|
||||||
|
fetch,
|
||||||
|
invalidate,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const savedCardsStore = createSavedCardsStore();
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Strips formatting characters from a phone input, preserving digits and leading +.
|
||||||
|
*/
|
||||||
|
export function normalisePhoneInput(value: string): string {
|
||||||
|
return value.replace(/[^\d+]/g, '').replace(/(?!^)\+/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a UK phone number.
|
||||||
|
* Accepts: +44XXXXXXXXXX or 0XXXXXXXXXX (10–11 digits after prefix).
|
||||||
|
* Returns true if valid.
|
||||||
|
*/
|
||||||
|
export function isValidUKPhone(phone: string): boolean {
|
||||||
|
const clean = normalisePhoneInput(phone);
|
||||||
|
return /^(\+44[1-9]\d{9,10}|0[1-9]\d{9,10})$/.test(clean);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a phone string as the user types — inserts spaces for readability.
|
||||||
|
* e.g. 07700900000 → 07700 900000, +447700900000 → +44 7700 900000
|
||||||
|
*/
|
||||||
|
export function formatPhoneDisplay(value: string): string {
|
||||||
|
const clean = normalisePhoneInput(value);
|
||||||
|
if (clean.startsWith('+44')) {
|
||||||
|
const digits = clean.slice(3);
|
||||||
|
if (digits.length <= 4) return '+44 ' + digits;
|
||||||
|
if (digits.length <= 8) return '+44 ' + digits.slice(0, 4) + ' ' + digits.slice(4);
|
||||||
|
return '+44 ' + digits.slice(0, 4) + ' ' + digits.slice(4, 10);
|
||||||
|
}
|
||||||
|
if (clean.startsWith('0')) {
|
||||||
|
const digits = clean.slice(1);
|
||||||
|
if (digits.length <= 4) return '0' + digits;
|
||||||
|
if (digits.length <= 7) return '0' + digits.slice(0, 4) + ' ' + digits.slice(4);
|
||||||
|
return '0' + digits.slice(0, 4) + ' ' + digits.slice(4, 10);
|
||||||
|
}
|
||||||
|
return clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an E.164-normalised phone string ready to send to the backend,
|
||||||
|
* or null if the input is not a valid UK number.
|
||||||
|
*/
|
||||||
|
export function toE164UK(phone: string): string | null {
|
||||||
|
const clean = normalisePhoneInput(phone);
|
||||||
|
if (!isValidUKPhone(clean)) return null;
|
||||||
|
if (clean.startsWith('0')) return '+44' + clean.slice(1);
|
||||||
|
return clean;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user