diff --git a/src/lib/features/database/characters/sections/CharacterMetadataSection.svelte b/src/lib/features/database/characters/sections/CharacterMetadataSection.svelte index bda2ff6c..3d7cecc6 100644 --- a/src/lib/features/database/characters/sections/CharacterMetadataSection.svelte +++ b/src/lib/features/database/characters/sections/CharacterMetadataSection.svelte @@ -5,11 +5,13 @@ import DetailItem from '$lib/components/ui/DetailItem.svelte' import { getRarityLabel, getRarityOptions } from '$lib/utils/rarity' - let { - character, - editMode = false, - editData = $bindable() - }: { character: any; editMode?: boolean; editData?: any } = $props() + interface Props { + character: any + editMode?: boolean + editData?: any + } + + let { character, editMode = false, editData = $bindable() }: Props = $props() const rarityOptions = getRarityOptions() @@ -17,10 +19,11 @@ {#if editMode} - + + {:else} - + {/if} diff --git a/src/lib/features/database/characters/sections/CharacterStatsSection.svelte b/src/lib/features/database/characters/sections/CharacterStatsSection.svelte index 8eec075b..b32fba01 100644 --- a/src/lib/features/database/characters/sections/CharacterStatsSection.svelte +++ b/src/lib/features/database/characters/sections/CharacterStatsSection.svelte @@ -4,39 +4,41 @@ import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte' import DetailItem from '$lib/components/ui/DetailItem.svelte' - let { - character, - editMode = false, - editData = $bindable() - }: { character: any; editMode?: boolean; editData?: any } = $props() + interface Props { + character: any + editMode?: boolean + editData?: any + } + + let { character, editMode = false, editData = $bindable() }: Props = $props() const flb = $derived(editMode ? Boolean(editData.flb) : Boolean(character?.uncap?.flb)) {#if editMode} - - - + + + {:else} - - + + {#if flb} - - {/if} - {/if} - - - - {#if editMode} - - - - {:else} - - - {#if flb} - + + {/if} + {/if} + + + + {#if editMode} + + + + {:else} + + + {#if flb} + {/if} {/if} diff --git a/src/lib/features/database/characters/sections/CharacterTaxonomySection.svelte b/src/lib/features/database/characters/sections/CharacterTaxonomySection.svelte index 54a5316e..1785f619 100644 --- a/src/lib/features/database/characters/sections/CharacterTaxonomySection.svelte +++ b/src/lib/features/database/characters/sections/CharacterTaxonomySection.svelte @@ -8,11 +8,13 @@ import { getGenderLabel, getGenderOptions } from '$lib/utils/gender' import { getProficiencyLabel, getProficiencyOptions } from '$lib/utils/proficiency' - let { - character, - editMode = false, - editData = $bindable() - }: { character: any; editMode?: boolean; editData?: any } = $props() + interface Props { + character: any + editMode?: boolean + editData?: any + } + + let { character, editMode = false, editData = $bindable() }: Props = $props() const elementOptions = getElementOptions() const raceOptions = getRaceOptions() @@ -35,8 +37,8 @@ {/if} - - + + {/if} diff --git a/src/lib/features/database/characters/sections/CharacterUncapSection.svelte b/src/lib/features/database/characters/sections/CharacterUncapSection.svelte index ec9c9cfc..b0453040 100644 --- a/src/lib/features/database/characters/sections/CharacterUncapSection.svelte +++ b/src/lib/features/database/characters/sections/CharacterUncapSection.svelte @@ -5,12 +5,17 @@ import DetailItem from '$lib/components/ui/DetailItem.svelte' import UncapIndicator from '$lib/components/uncap/UncapIndicator.svelte' import { getCharacterMaxUncapLevel } from '$lib/utils/uncap' + import { getElementLabel } from '$lib/utils/element' - let { - character, - editMode = false, - editData = $bindable() - }: { character: any; editMode?: boolean; editData?: any } = $props() + type ElementName = 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light' + + interface Props { + character: any + editMode?: boolean + editData?: any + } + + let { character, editMode = false, editData = $bindable() }: Props = $props() const uncap = $derived( editMode @@ -23,10 +28,19 @@ const special = $derived(editMode ? editData.special : (character?.special ?? false)) const uncapLevel = $derived(getCharacterMaxUncapLevel({ special, uncap })) const transcendenceStage = $derived(transcendence ? 5 : 0) + + // Get element name for checkbox theming + const elementName = $derived.by((): ElementName | undefined => { + const el = editMode ? editData.element : character?.element + const label = getElementLabel(el) + return label !== '—' && label !== 'Null' + ? (label.toLowerCase() as ElementName) + : undefined + }) - - {#if character.uncap} + + {#if character?.uncap || editMode} - - - + + + + {/if} diff --git a/src/routes/(app)/database/characters/[id]/+page.svelte b/src/routes/(app)/database/characters/[id]/+page.svelte index 6e8f8b55..1c31176b 100644 --- a/src/routes/(app)/database/characters/[id]/+page.svelte +++ b/src/routes/(app)/database/characters/[id]/+page.svelte @@ -10,20 +10,13 @@ import { entityAdapter } from '$lib/api/adapters/entity.adapter' import { withInitialData } from '$lib/query/ssr' - // Utility functions - import { getRarityLabel, getRarityOptions } from '$lib/utils/rarity' - import { getElementLabel, getElementOptions } from '$lib/utils/element' - import { getProficiencyLabel, getProficiencyOptions } from '$lib/utils/proficiency' - import { getRaceLabel, getRaceOptions } from '$lib/utils/race' - import { getGenderLabel, getGenderOptions } from '$lib/utils/gender' - import { getCharacterMaxUncapLevel } from '$lib/utils/uncap' - // Components - import UncapIndicator from '$lib/components/uncap/UncapIndicator.svelte' + import DetailScaffold from '$lib/features/database/detail/DetailScaffold.svelte' + import CharacterMetadataSection from '$lib/features/database/characters/sections/CharacterMetadataSection.svelte' + import CharacterUncapSection from '$lib/features/database/characters/sections/CharacterUncapSection.svelte' + import CharacterTaxonomySection from '$lib/features/database/characters/sections/CharacterTaxonomySection.svelte' + import CharacterStatsSection from '$lib/features/database/characters/sections/CharacterStatsSection.svelte' import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte' - import DetailItem from '$lib/components/ui/DetailItem.svelte' - import DetailsHeader from '$lib/components/ui/DetailsHeader.svelte' - import Button from '$lib/components/ui/Button.svelte' import { getCharacterImage } from '$lib/utils/images' // Types @@ -54,6 +47,7 @@ }, enabled: !!character?.characterId && !editMode })) + let isSaving = $state(false) let saveError = $state(null) let saveSuccess = $state(false) @@ -110,13 +104,6 @@ } }) - // Options for select dropdowns - using centralized utilities - const rarityOptions = getRarityOptions() - const elementOptions = getElementOptions() - const raceOptions = getRaceOptions() - const genderOptions = getGenderOptions() - const proficiencyOptions = getProficiencyOptions() - function toggleEditMode() { editMode = !editMode saveError = null @@ -155,7 +142,7 @@ saveSuccess = false try { - // Prepare the data for API + // Prepare the data for API (convert to snake_case) const payload = { name: editData.name, granblue_id: editData.granblueId, @@ -208,264 +195,32 @@ } } - // Helper function to get character image // Helper function for character grid image function getCharacterGridImage(character: any): string { return getCharacterImage(character?.granblueId, 'grid', '01') } - - // Calculate uncap properties for the indicator - const uncap = $derived( - editMode - ? { flb: editData.flb, ulb: editData.ulb, transcendence: editData.transcendence } - : (character?.uncap ?? { flb: false, ulb: false, transcendence: false }) - ) - const flb = $derived(uncap.flb ?? false) - const ulb = $derived(uncap.ulb ?? false) - const transcendence = $derived(uncap.transcendence ?? false) - const special = $derived(editMode ? editData.special : (character?.special ?? false)) - - const uncapLevel = $derived( - getCharacterMaxUncapLevel({ special, uncap: { flb, ulb, transcendence } }) - ) - const transcendenceStage = $derived(transcendence ? 5 : 0) - - // Get element name for checkbox theming - const elementName = $derived.by(() => { - const el = editMode ? editData.element : character?.element - const label = getElementLabel(el) - return label !== '—' && label !== 'Null' - ? (label.toLowerCase() as 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light') - : undefined - })
{#if character} -
- - - {#if saveSuccess || saveError} -
- {#if saveSuccess} - Changes saved successfully! - {/if} - - {#if saveError} - {saveError} - {/if} -
- {/if} - +
- - {#if editMode} - - - - {:else} - - - {/if} - - - - {#if character.uncap} - - - - {/if} - - {#if editMode} - - - - - {/if} - - {#if editMode} - - - - - - - {:else} - - - {#if character.race?.[1]} - - {/if} - - - - {/if} - - - - {#if editMode} - - - - {:else} - - - {#if flb} - - {/if} - {/if} - - - - {#if editMode} - - - - {:else} - - - {#if flb} - - {/if} - {/if} - + + + + {#if !editMode && relatedQuery.data?.length} @@ -484,7 +239,7 @@ {/if}
-
+ {:else}

Character Not Found

@@ -499,7 +254,6 @@ @use '$src/themes/layout' as layout; @use '$src/themes/spacing' as spacing; @use '$src/themes/typography' as typography; - @use '$src/themes/effects' as effects; .not-found { text-align: center; @@ -520,46 +274,9 @@ } } - .content { - background: white; - border-radius: layout.$card-corner; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - overflow: visible; - position: relative; - - .details { - display: flex; - flex-direction: column; - } - } - - .edit-controls { - padding: spacing.$unit-2x; - border-bottom: 1px solid colors.$grey-80; + .details { display: flex; - gap: spacing.$unit; - align-items: center; - - .success-message { - color: colors.$grey-30; - font-size: typography.$font-small; - animation: fadeIn effects.$duration-opacity-fade ease-in; - } - - .error-message { - color: colors.$error; - font-size: typography.$font-small; - animation: fadeIn effects.$duration-opacity-fade ease-in; - } - } - - @keyframes fadeIn { - from { - opacity: 0; - } - to { - opacity: 1; - } + flex-direction: column; } .related-units {