add element styling to link buttons on db detail pages
This commit is contained in:
parent
2ace9590ab
commit
cde15428da
3 changed files with 176 additions and 92 deletions
|
|
@ -17,7 +17,9 @@
|
||||||
import { fetchWikiPage } from '$lib/api/wiki'
|
import { fetchWikiPage } from '$lib/api/wiki'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import DetailScaffold, { type DetailTab } from '$lib/features/database/detail/DetailScaffold.svelte'
|
import DetailScaffold, {
|
||||||
|
type DetailTab
|
||||||
|
} from '$lib/features/database/detail/DetailScaffold.svelte'
|
||||||
import CharacterMetadataSection from '$lib/features/database/characters/sections/CharacterMetadataSection.svelte'
|
import CharacterMetadataSection from '$lib/features/database/characters/sections/CharacterMetadataSection.svelte'
|
||||||
import CharacterUncapSection from '$lib/features/database/characters/sections/CharacterUncapSection.svelte'
|
import CharacterUncapSection from '$lib/features/database/characters/sections/CharacterUncapSection.svelte'
|
||||||
import CharacterTaxonomySection from '$lib/features/database/characters/sections/CharacterTaxonomySection.svelte'
|
import CharacterTaxonomySection from '$lib/features/database/characters/sections/CharacterTaxonomySection.svelte'
|
||||||
|
|
@ -27,12 +29,14 @@
|
||||||
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
||||||
import DetailItem from '$lib/components/ui/DetailItem.svelte'
|
import DetailItem from '$lib/components/ui/DetailItem.svelte'
|
||||||
import { getCharacterImage } from '$lib/utils/images'
|
import { getCharacterImage } from '$lib/utils/images'
|
||||||
|
import { getElementLabel } from '$lib/utils/element'
|
||||||
import {
|
import {
|
||||||
buildWikiEnUrl,
|
buildWikiEnUrl,
|
||||||
buildWikiJaUrl,
|
buildWikiJaUrl,
|
||||||
buildGamewithUrl,
|
buildGamewithUrl,
|
||||||
buildKamigameUrl
|
buildKamigameUrl
|
||||||
} from '$lib/utils/external-links'
|
} from '$lib/utils/external-links'
|
||||||
|
import Button from '$lib/components/ui/Button.svelte'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
|
|
@ -64,8 +68,22 @@
|
||||||
const userRole = $derived(data.role || 0)
|
const userRole = $derived(data.role || 0)
|
||||||
const canEdit = $derived(userRole >= 7)
|
const canEdit = $derived(userRole >= 7)
|
||||||
|
|
||||||
|
// Element for button styling
|
||||||
|
const elementName = $derived(
|
||||||
|
getElementLabel(character?.element)?.toLowerCase() as
|
||||||
|
| 'wind'
|
||||||
|
| 'fire'
|
||||||
|
| 'water'
|
||||||
|
| 'earth'
|
||||||
|
| 'dark'
|
||||||
|
| 'light'
|
||||||
|
| undefined
|
||||||
|
)
|
||||||
|
|
||||||
// Edit URL for navigation
|
// Edit URL for navigation
|
||||||
const editUrl = $derived(character?.granblueId ? `/database/characters/${character.granblueId}/edit` : undefined)
|
const editUrl = $derived(
|
||||||
|
character?.granblueId ? `/database/characters/${character.granblueId}/edit` : undefined
|
||||||
|
)
|
||||||
|
|
||||||
// Query for related characters (same character_id)
|
// Query for related characters (same character_id)
|
||||||
const relatedQuery = createQuery(() => ({
|
const relatedQuery = createQuery(() => ({
|
||||||
|
|
@ -132,7 +150,11 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
// Image download handlers
|
// Image download handlers
|
||||||
async function handleDownloadImage(size: string, transformation: string | undefined, force: boolean) {
|
async function handleDownloadImage(
|
||||||
|
size: string,
|
||||||
|
transformation: string | undefined,
|
||||||
|
force: boolean
|
||||||
|
) {
|
||||||
if (!character?.id) return
|
if (!character?.id) return
|
||||||
await entityAdapter.downloadCharacterImage(character.id, size, transformation, force)
|
await entityAdapter.downloadCharacterImage(character.id, size, transformation, force)
|
||||||
}
|
}
|
||||||
|
|
@ -226,41 +248,65 @@
|
||||||
|
|
||||||
<DetailsContainer title="Links">
|
<DetailsContainer title="Links">
|
||||||
<DetailItem label="Wiki (EN)">
|
<DetailItem label="Wiki (EN)">
|
||||||
{@const url = buildWikiEnUrl(character.wiki?.en)}
|
{#if character.wiki?.en}
|
||||||
{#if url}
|
<Button
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
href={buildWikiEnUrl(character.wiki.en) ?? undefined}
|
||||||
{url}
|
target="_blank"
|
||||||
</a>
|
variant="element-ghost"
|
||||||
|
element={elementName}
|
||||||
|
size="small"
|
||||||
|
rightIcon="link"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
</DetailItem>
|
</DetailItem>
|
||||||
<DetailItem label="Wiki (JP)">
|
<DetailItem label="Wiki (JP)">
|
||||||
{@const url = buildWikiJaUrl(character.wiki?.ja)}
|
{#if character.wiki?.ja}
|
||||||
{#if url}
|
<Button
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
href={buildWikiJaUrl(character.wiki.ja) ?? undefined}
|
||||||
{url}
|
target="_blank"
|
||||||
</a>
|
variant="element-ghost"
|
||||||
|
element={elementName}
|
||||||
|
size="small"
|
||||||
|
rightIcon="link"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
</DetailItem>
|
</DetailItem>
|
||||||
<DetailItem label="Gamewith">
|
<DetailItem label="Gamewith">
|
||||||
{@const url = buildGamewithUrl(character.gamewith)}
|
{#if character.gamewith}
|
||||||
{#if url}
|
<Button
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
href={buildGamewithUrl(character.gamewith) ?? undefined}
|
||||||
{url}
|
target="_blank"
|
||||||
</a>
|
variant="element-ghost"
|
||||||
|
element={elementName}
|
||||||
|
size="small"
|
||||||
|
rightIcon="link"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
</DetailItem>
|
</DetailItem>
|
||||||
<DetailItem label="Kamigame">
|
<DetailItem label="Kamigame">
|
||||||
{@const url = buildKamigameUrl(character.kamigame, 'character')}
|
{#if character.kamigame}
|
||||||
{#if url}
|
<Button
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
href={buildKamigameUrl(character.kamigame, 'character') ?? undefined}
|
||||||
{url}
|
target="_blank"
|
||||||
</a>
|
variant="element-ghost"
|
||||||
|
element={elementName}
|
||||||
|
size="small"
|
||||||
|
rightIcon="link"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
@ -404,16 +450,6 @@
|
||||||
font-size: typography.$font-small;
|
font-size: typography.$font-small;
|
||||||
}
|
}
|
||||||
|
|
||||||
.external-link {
|
|
||||||
color: colors.$blue;
|
|
||||||
text-decoration: none;
|
|
||||||
word-break: break-all;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty-value {
|
.empty-value {
|
||||||
color: colors.$grey-50;
|
color: colors.$grey-50;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,14 @@
|
||||||
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
||||||
import DetailItem from '$lib/components/ui/DetailItem.svelte'
|
import DetailItem from '$lib/components/ui/DetailItem.svelte'
|
||||||
import { getSummonImage } from '$lib/utils/images'
|
import { getSummonImage } from '$lib/utils/images'
|
||||||
|
import { getElementLabel } from '$lib/utils/element'
|
||||||
import {
|
import {
|
||||||
buildWikiEnUrl,
|
buildWikiEnUrl,
|
||||||
buildWikiJaUrl,
|
buildWikiJaUrl,
|
||||||
buildGamewithUrl,
|
buildGamewithUrl,
|
||||||
buildKamigameUrl
|
buildKamigameUrl
|
||||||
} from '$lib/utils/external-links'
|
} from '$lib/utils/external-links'
|
||||||
|
import Button from '$lib/components/ui/Button.svelte'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
|
|
@ -65,6 +67,18 @@
|
||||||
const userRole = $derived(data.role || 0)
|
const userRole = $derived(data.role || 0)
|
||||||
const canEdit = $derived(userRole >= 7)
|
const canEdit = $derived(userRole >= 7)
|
||||||
|
|
||||||
|
// Element for button styling
|
||||||
|
const elementName = $derived(
|
||||||
|
getElementLabel(summon?.element)?.toLowerCase() as
|
||||||
|
| 'wind'
|
||||||
|
| 'fire'
|
||||||
|
| 'water'
|
||||||
|
| 'earth'
|
||||||
|
| 'dark'
|
||||||
|
| 'light'
|
||||||
|
| undefined
|
||||||
|
)
|
||||||
|
|
||||||
// Edit URL for navigation
|
// Edit URL for navigation
|
||||||
const editUrl = $derived(summon?.granblueId ? `/database/summons/${summon.granblueId}/edit` : undefined)
|
const editUrl = $derived(summon?.granblueId ? `/database/summons/${summon.granblueId}/edit` : undefined)
|
||||||
|
|
||||||
|
|
@ -225,41 +239,41 @@
|
||||||
|
|
||||||
<DetailsContainer title="Links">
|
<DetailsContainer title="Links">
|
||||||
<DetailItem label="Wiki (EN)">
|
<DetailItem label="Wiki (EN)">
|
||||||
{@const url = buildWikiEnUrl(summon.wiki?.en)}
|
{#if summon.wiki?.en}
|
||||||
{#if url}
|
<Button href={buildWikiEnUrl(summon.wiki.en) ?? undefined} target="_blank" variant="element-ghost"
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
element={elementName} size="small" rightIcon="link">
|
||||||
{url}
|
Open
|
||||||
</a>
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
</DetailItem>
|
</DetailItem>
|
||||||
<DetailItem label="Wiki (JP)">
|
<DetailItem label="Wiki (JP)">
|
||||||
{@const url = buildWikiJaUrl(summon.wiki?.ja)}
|
{#if summon.wiki?.ja}
|
||||||
{#if url}
|
<Button href={buildWikiJaUrl(summon.wiki.ja) ?? undefined} target="_blank" variant="element-ghost"
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
element={elementName} size="small" rightIcon="link">
|
||||||
{url}
|
Open
|
||||||
</a>
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
</DetailItem>
|
</DetailItem>
|
||||||
<DetailItem label="Gamewith">
|
<DetailItem label="Gamewith">
|
||||||
{@const url = buildGamewithUrl(summon.gamewith)}
|
{#if summon.gamewith}
|
||||||
{#if url}
|
<Button href={buildGamewithUrl(summon.gamewith) ?? undefined} target="_blank" variant="element-ghost"
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
element={elementName} size="small" rightIcon="link">
|
||||||
{url}
|
Open
|
||||||
</a>
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
</DetailItem>
|
</DetailItem>
|
||||||
<DetailItem label="Kamigame">
|
<DetailItem label="Kamigame">
|
||||||
{@const url = buildKamigameUrl(summon.kamigame, 'summon')}
|
{#if summon.kamigame}
|
||||||
{#if url}
|
<Button href={buildKamigameUrl(summon.kamigame, 'summon') ?? undefined} target="_blank" variant="element-ghost"
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
element={elementName} size="small" rightIcon="link">
|
||||||
{url}
|
Open
|
||||||
</a>
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
@ -446,13 +460,7 @@
|
||||||
font-size: typography.$font-small;
|
font-size: typography.$font-small;
|
||||||
}
|
}
|
||||||
|
|
||||||
.external-link {
|
.empty-value {
|
||||||
color: colors.$blue;
|
color: colors.$grey-50;
|
||||||
text-decoration: none;
|
|
||||||
word-break: break-all;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,9 @@
|
||||||
import { fetchWikiPage } from '$lib/api/wiki'
|
import { fetchWikiPage } from '$lib/api/wiki'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import DetailScaffold, { type DetailTab } from '$lib/features/database/detail/DetailScaffold.svelte'
|
import DetailScaffold, {
|
||||||
|
type DetailTab
|
||||||
|
} from '$lib/features/database/detail/DetailScaffold.svelte'
|
||||||
import WeaponMetadataSection from '$lib/features/database/weapons/sections/WeaponMetadataSection.svelte'
|
import WeaponMetadataSection from '$lib/features/database/weapons/sections/WeaponMetadataSection.svelte'
|
||||||
import WeaponUncapSection from '$lib/features/database/weapons/sections/WeaponUncapSection.svelte'
|
import WeaponUncapSection from '$lib/features/database/weapons/sections/WeaponUncapSection.svelte'
|
||||||
import WeaponTaxonomySection from '$lib/features/database/weapons/sections/WeaponTaxonomySection.svelte'
|
import WeaponTaxonomySection from '$lib/features/database/weapons/sections/WeaponTaxonomySection.svelte'
|
||||||
|
|
@ -28,12 +30,14 @@
|
||||||
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
||||||
import DetailItem from '$lib/components/ui/DetailItem.svelte'
|
import DetailItem from '$lib/components/ui/DetailItem.svelte'
|
||||||
import { getWeaponGridImage, getWeaponImage as getWeaponImageUrl } from '$lib/utils/images'
|
import { getWeaponGridImage, getWeaponImage as getWeaponImageUrl } from '$lib/utils/images'
|
||||||
|
import { getElementLabel } from '$lib/utils/element'
|
||||||
import {
|
import {
|
||||||
buildWikiEnUrl,
|
buildWikiEnUrl,
|
||||||
buildWikiJaUrl,
|
buildWikiJaUrl,
|
||||||
buildGamewithUrl,
|
buildGamewithUrl,
|
||||||
buildKamigameUrl
|
buildKamigameUrl
|
||||||
} from '$lib/utils/external-links'
|
} from '$lib/utils/external-links'
|
||||||
|
import Button from '$lib/components/ui/Button.svelte'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
|
|
@ -65,8 +69,22 @@
|
||||||
const userRole = $derived(data.role || 0)
|
const userRole = $derived(data.role || 0)
|
||||||
const canEdit = $derived(userRole >= 7)
|
const canEdit = $derived(userRole >= 7)
|
||||||
|
|
||||||
|
// Element for button styling
|
||||||
|
const elementName = $derived(
|
||||||
|
getElementLabel(weapon?.element)?.toLowerCase() as
|
||||||
|
| 'wind'
|
||||||
|
| 'fire'
|
||||||
|
| 'water'
|
||||||
|
| 'earth'
|
||||||
|
| 'dark'
|
||||||
|
| 'light'
|
||||||
|
| undefined
|
||||||
|
)
|
||||||
|
|
||||||
// Edit URL for navigation
|
// Edit URL for navigation
|
||||||
const editUrl = $derived(weapon?.granblueId ? `/database/weapons/${weapon.granblueId}/edit` : undefined)
|
const editUrl = $derived(
|
||||||
|
weapon?.granblueId ? `/database/weapons/${weapon.granblueId}/edit` : undefined
|
||||||
|
)
|
||||||
|
|
||||||
// Query for raw data (only when on raw tab)
|
// Query for raw data (only when on raw tab)
|
||||||
const rawDataQuery = createQuery(() => ({
|
const rawDataQuery = createQuery(() => ({
|
||||||
|
|
@ -122,7 +140,11 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
// Image download handlers
|
// Image download handlers
|
||||||
async function handleDownloadImage(size: string, transformation: string | undefined, force: boolean) {
|
async function handleDownloadImage(
|
||||||
|
size: string,
|
||||||
|
transformation: string | undefined,
|
||||||
|
force: boolean
|
||||||
|
) {
|
||||||
if (!weapon?.id) return
|
if (!weapon?.id) return
|
||||||
// For weapons, '01' means base (no transformation suffix)
|
// For weapons, '01' means base (no transformation suffix)
|
||||||
const trans = transformation === '01' ? undefined : transformation
|
const trans = transformation === '01' ? undefined : transformation
|
||||||
|
|
@ -218,41 +240,65 @@
|
||||||
|
|
||||||
<DetailsContainer title="Links">
|
<DetailsContainer title="Links">
|
||||||
<DetailItem label="Wiki (EN)">
|
<DetailItem label="Wiki (EN)">
|
||||||
{@const url = buildWikiEnUrl(weapon.wiki?.en)}
|
{#if weapon.wiki?.en}
|
||||||
{#if url}
|
<Button
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
href={buildWikiEnUrl(weapon.wiki.en) ?? undefined}
|
||||||
{url}
|
target="_blank"
|
||||||
</a>
|
variant="element-ghost"
|
||||||
|
element={elementName}
|
||||||
|
size="small"
|
||||||
|
rightIcon="link"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
</DetailItem>
|
</DetailItem>
|
||||||
<DetailItem label="Wiki (JP)">
|
<DetailItem label="Wiki (JP)">
|
||||||
{@const url = buildWikiJaUrl(weapon.wiki?.ja)}
|
{#if weapon.wiki?.ja}
|
||||||
{#if url}
|
<Button
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
href={buildWikiJaUrl(weapon.wiki.ja) ?? undefined}
|
||||||
{url}
|
target="_blank"
|
||||||
</a>
|
variant="element-ghost"
|
||||||
|
element={elementName}
|
||||||
|
size="small"
|
||||||
|
rightIcon="link"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
</DetailItem>
|
</DetailItem>
|
||||||
<DetailItem label="Gamewith">
|
<DetailItem label="Gamewith">
|
||||||
{@const url = buildGamewithUrl(weapon.gamewith)}
|
{#if weapon.gamewith}
|
||||||
{#if url}
|
<Button
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
href={buildGamewithUrl(weapon.gamewith) ?? undefined}
|
||||||
{url}
|
target="_blank"
|
||||||
</a>
|
variant="element-ghost"
|
||||||
|
element={elementName}
|
||||||
|
size="small"
|
||||||
|
rightIcon="link"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
</DetailItem>
|
</DetailItem>
|
||||||
<DetailItem label="Kamigame">
|
<DetailItem label="Kamigame">
|
||||||
{@const url = buildKamigameUrl(weapon.kamigame, 'weapon', weapon.rarity)}
|
{#if weapon.kamigame}
|
||||||
{#if url}
|
<Button
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer" class="external-link">
|
href={buildKamigameUrl(weapon.kamigame, 'weapon', weapon.rarity) ?? undefined}
|
||||||
{url}
|
target="_blank"
|
||||||
</a>
|
variant="element-ghost"
|
||||||
|
element={elementName}
|
||||||
|
size="small"
|
||||||
|
rightIcon="link"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="empty-value">—</span>
|
<span class="empty-value">—</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
@ -419,13 +465,7 @@
|
||||||
font-size: typography.$font-small;
|
font-size: typography.$font-small;
|
||||||
}
|
}
|
||||||
|
|
||||||
.external-link {
|
.empty-value {
|
||||||
color: colors.$blue;
|
color: colors.$grey-50;
|
||||||
text-decoration: none;
|
|
||||||
word-break: break-all;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue