diff --git a/src/lib/api/queries/raid.queries.ts b/src/lib/api/queries/raid.queries.ts new file mode 100644 index 00000000..18ef497c --- /dev/null +++ b/src/lib/api/queries/raid.queries.ts @@ -0,0 +1,68 @@ +/** + * Raid Query Options Factory + * + * Provides type-safe, reusable query configurations for raid operations + * using TanStack Query v6 patterns. + * + * @module api/queries/raid + */ + +import { queryOptions } from '@tanstack/svelte-query' +import { raidAdapter } from '$lib/api/adapters/raid.adapter' +import type { RaidFull, RaidGroupFull } from '$lib/types/api/raid' + +/** + * Raid query options factory + * + * Provides query configurations for all raid-related operations. + * + * @example + * ```typescript + * import { createQuery } from '@tanstack/svelte-query' + * import { raidQueries } from '$lib/api/queries/raid.queries' + * + * // All raid groups with their raids + * const groups = createQuery(() => raidQueries.groups()) + * + * // Single raid by slug + * const raid = createQuery(() => raidQueries.bySlug('proto-bahamut')) + * ``` + */ +export const raidQueries = { + /** + * All raid groups with their raids + * + * @returns Query options for fetching all raid groups + */ + groups: () => + queryOptions({ + queryKey: ['raids', 'groups'] as const, + queryFn: () => raidAdapter.getGroups(), + staleTime: 1000 * 60 * 60, // 1 hour - raid data rarely changes + gcTime: 1000 * 60 * 60 * 24 // 24 hours + }), + + /** + * Single raid by slug + * + * @param slug - Raid slug + * @returns Query options for fetching a single raid + */ + bySlug: (slug: string) => + queryOptions({ + queryKey: ['raids', slug] as const, + queryFn: () => raidAdapter.getBySlug(slug), + enabled: !!slug, + staleTime: 1000 * 60 * 60, // 1 hour + gcTime: 1000 * 60 * 60 * 24 // 24 hours + }) +} + +/** + * Query key helpers for cache invalidation + */ +export const raidKeys = { + all: ['raids'] as const, + groups: () => [...raidKeys.all, 'groups'] as const, + detail: (slug: string) => [...raidKeys.all, slug] as const +} diff --git a/src/lib/components/party/edit/BattleSettingsSection.svelte b/src/lib/components/party/edit/BattleSettingsSection.svelte new file mode 100644 index 00000000..364dfaa0 --- /dev/null +++ b/src/lib/components/party/edit/BattleSettingsSection.svelte @@ -0,0 +1,98 @@ + + + + + {#snippet children()} + handleChange('chargeAttack', v)} + /> + {/snippet} + + + + {#snippet children()} + handleChange('fullAuto', v)} + /> + {/snippet} + + + + {#snippet children()} + handleChange('autoSummon', v)} + /> + {/snippet} + + + + {#snippet children()} + handleChange('autoGuard', v)} + /> + {/snippet} + + diff --git a/src/lib/components/party/edit/ClearTimeInput.svelte b/src/lib/components/party/edit/ClearTimeInput.svelte new file mode 100644 index 00000000..d939c3ab --- /dev/null +++ b/src/lib/components/party/edit/ClearTimeInput.svelte @@ -0,0 +1,204 @@ + + +
+
+ + min +
+ : +
+ + sec +
+
+ + diff --git a/src/lib/components/party/edit/MetricField.svelte b/src/lib/components/party/edit/MetricField.svelte new file mode 100644 index 00000000..5a2675a7 --- /dev/null +++ b/src/lib/components/party/edit/MetricField.svelte @@ -0,0 +1,129 @@ + + +
+ + {label} +
+ + diff --git a/src/lib/components/party/edit/YouTubeUrlInput.svelte b/src/lib/components/party/edit/YouTubeUrlInput.svelte new file mode 100644 index 00000000..e62b561e --- /dev/null +++ b/src/lib/components/party/edit/YouTubeUrlInput.svelte @@ -0,0 +1,347 @@ + + +
+ {#if label} + + {/if} +
+ + {#if inputValue && !disabled} + + {/if} +
+ + {#if showError} +

Please enter a valid YouTube URL

+ {/if} + + {#if showPreview && thumbnailUrl} +
+ + Video thumbnail +
+ + + +
+
+
+ {#if isLoadingMetadata} + Loading... + {:else if videoTitle} + {videoTitle} + {/if} +
+
+ {/if} +
+ + diff --git a/src/lib/components/raid/RaidGroupItem.svelte b/src/lib/components/raid/RaidGroupItem.svelte new file mode 100644 index 00000000..5a935c31 --- /dev/null +++ b/src/lib/components/raid/RaidGroupItem.svelte @@ -0,0 +1,161 @@ + + +
+
+ {getGroupName(group)} + {#if group.extra} + EX + {/if} +
+ +
+ {#each group.raids as raid (raid.id)} + {@const isSelected = raid.id === selectedRaidId} + + {/each} +
+
+ + diff --git a/src/lib/components/raid/RaidGroupList.svelte b/src/lib/components/raid/RaidGroupList.svelte new file mode 100644 index 00000000..b8a95ea4 --- /dev/null +++ b/src/lib/components/raid/RaidGroupList.svelte @@ -0,0 +1,95 @@ + + +
+ {#if hasResults} + {#each filteredGroups() as group (group.id)} + + {/each} + {:else} +
+ No raids found +
+ {/if} +
+ + diff --git a/src/lib/components/raid/RaidSectionTabs.svelte b/src/lib/components/raid/RaidSectionTabs.svelte new file mode 100644 index 00000000..2b107568 --- /dev/null +++ b/src/lib/components/raid/RaidSectionTabs.svelte @@ -0,0 +1,43 @@ + + + + {#each sections as section (section.value)} + {section.label} + {/each} +