add ElementBadge component, use in gw event pages

This commit is contained in:
Justin Edmund 2025-12-18 11:03:36 -08:00
parent 6f0870e37f
commit 00813ddd58
4 changed files with 81 additions and 199 deletions

View file

@ -0,0 +1,72 @@
<svelte:options runes={true} />
<script lang="ts">
import { ELEMENT_LABELS, ELEMENT_CSS_CLASSES } from '$lib/utils/gw'
interface Props {
element: number
size?: 'small' | 'medium'
}
let { element, size = 'small' }: Props = $props()
const label = $derived(ELEMENT_LABELS[element] ?? 'Unknown')
const cssClass = $derived(ELEMENT_CSS_CLASSES[element] ?? 'null')
</script>
<span class="element-badge element-{cssClass}" class:medium={size === 'medium'}>
{label}
</span>
<style lang="scss">
@use '$src/themes/layout' as layout;
@use '$src/themes/typography' as typography;
.element-badge {
display: inline-block;
padding: 2px 8px;
border-radius: layout.$item-corner-small;
font-size: typography.$font-small;
font-weight: typography.$medium;
&.medium {
padding: 4px 12px;
font-size: typography.$font-regular;
}
&.element-null {
background: rgba(0, 0, 0, 0.04);
color: var(--text-secondary);
}
&.element-fire {
background: #fee2e2;
color: #dc2626;
}
&.element-water {
background: #dbeafe;
color: #2563eb;
}
&.element-earth {
background: #fef3c7;
color: #d97706;
}
&.element-wind {
background: #d1fae5;
color: #059669;
}
&.element-light {
background: #fef9c3;
color: #ca8a04;
}
&.element-dark {
background: #ede9fe;
color: #7c3aed;
}
}
</style>

View file

@ -15,6 +15,8 @@
import Input from '$lib/components/ui/Input.svelte'
import CrewHeader from '$lib/components/crew/CrewHeader.svelte'
import { formatDateJST } from '$lib/utils/date'
import { formatScore } from '$lib/utils/gw'
import ElementBadge from '$lib/components/ui/ElementBadge.svelte'
import type { PageData } from './$types'
interface Props {
@ -39,28 +41,6 @@
staleTime: 1000 * 60 * 5
}))
// Element labels (matches GranblueEnums::ELEMENTS)
const elementLabels: Record<number, string> = {
0: 'Null',
1: 'Wind',
2: 'Fire',
3: 'Water',
4: 'Earth',
5: 'Dark',
6: 'Light'
}
// Element colors for badges
const elementColors: Record<number, string> = {
0: 'null',
1: 'wind',
2: 'fire',
3: 'water',
4: 'earth',
5: 'dark',
6: 'light'
}
// Mutations
const createCrewMutation = useCreateCrew()
const updateCrewMutation = useUpdateCrew()
@ -160,11 +140,6 @@
settingsError = null
}
// Helper for formatting scores with commas
function formatScore(score: number): string {
return score.toLocaleString()
}
function formatEventStatus(status: string, startDate: string): string {
if (status === 'upcoming') {
const now = new Date()
@ -283,9 +258,7 @@
<li class="event-item" onclick={() => goto(`/crew/events/${event.eventNumber}`)}>
<div class="event-info">
<span class="event-number">{event.eventNumber}</span>
<span class="element-badge element-{elementColors[event.element]}">
{elementLabels[event.element] ?? 'Unknown'}
</span>
<ElementBadge element={event.element} />
</div>
<span class="event-dates">
{formatDateJST(event.startDate)} {formatDateJST(event.endDate)}
@ -660,49 +633,6 @@
}
}
.element-badge {
display: inline-block;
padding: 2px 8px;
border-radius: layout.$item-corner-small;
font-size: typography.$font-small;
font-weight: typography.$medium;
&.element-null {
background: rgba(0, 0, 0, 0.04);
color: var(--text-secondary);
}
&.element-fire {
background: #fee2e2;
color: #dc2626;
}
&.element-water {
background: #dbeafe;
color: #2563eb;
}
&.element-earth {
background: #fef3c7;
color: #d97706;
}
&.element-wind {
background: #d1fae5;
color: #059669;
}
&.element-light {
background: #fef9c3;
color: #ca8a04;
}
&.element-dark {
background: #ede9fe;
color: #7c3aed;
}
}
.empty-state {
text-align: center;
color: var(--text-secondary);

View file

@ -8,6 +8,8 @@
import { gwAdapter } from '$lib/api/adapters/gw.adapter'
import Button from '$lib/components/ui/Button.svelte'
import { formatDateJST } from '$lib/utils/date'
import { ELEMENT_LABELS } from '$lib/utils/gw'
import ElementBadge from '$lib/components/ui/ElementBadge.svelte'
import type { GwEvent } from '$lib/types/api/gw'
import type { PageData } from './$types'
@ -27,28 +29,6 @@
staleTime: 1000 * 60 * 5
}))
// Element labels (matches GranblueEnums::ELEMENTS)
const elementLabels: Record<number, string> = {
0: 'Null',
1: 'Wind',
2: 'Fire',
3: 'Water',
4: 'Earth',
5: 'Dark',
6: 'Light'
}
// Element colors for badges
const elementColors: Record<number, string> = {
0: 'null',
1: 'wind',
2: 'fire',
3: 'water',
4: 'earth',
5: 'dark',
6: 'light'
}
// Filter events by search
const filteredEvents = $derived.by(() => {
const events = eventsQuery.data ?? []
@ -58,7 +38,7 @@
return events.filter(
(e) =>
String(e.eventNumber).includes(term) ||
elementLabels[e.element]?.toLowerCase().includes(term)
ELEMENT_LABELS[e.element]?.toLowerCase().includes(term)
)
})
@ -110,9 +90,7 @@
<span class="event-number">{event.eventNumber}</span>
</td>
<td class="col-element">
<span class="element-badge element-{elementColors[event.element]}">
{elementLabels[event.element] ?? 'Unknown'}
</span>
<ElementBadge element={event.element} />
</td>
<td class="col-dates">
<span class="dates">
@ -260,44 +238,6 @@
color: #666;
}
.element-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: typography.$font-small;
font-weight: 500;
&.element-fire {
background: #fee2e2;
color: #dc2626;
}
&.element-water {
background: #dbeafe;
color: #2563eb;
}
&.element-earth {
background: #fef3c7;
color: #d97706;
}
&.element-wind {
background: #d1fae5;
color: #059669;
}
&.element-light {
background: #fef9c3;
color: #ca8a04;
}
&.element-dark {
background: #ede9fe;
color: #7c3aed;
}
}
.dates {
font-size: typography.$font-small;
color: #666;

View file

@ -10,6 +10,7 @@
import DetailItem from '$lib/components/ui/DetailItem.svelte'
import SidebarHeader from '$lib/components/ui/SidebarHeader.svelte'
import { formatDateJST, formatDateLongJST } from '$lib/utils/date'
import ElementBadge from '$lib/components/ui/ElementBadge.svelte'
import type { PageData } from './$types'
interface Props {
@ -32,27 +33,6 @@
const userRole = $derived(data.role || 0)
const canEdit = $derived(userRole >= 7)
// Element labels and colors (matches GranblueEnums::ELEMENTS)
const elementLabels: Record<number, string> = {
0: 'Null',
1: 'Wind',
2: 'Fire',
3: 'Water',
4: 'Earth',
5: 'Dark',
6: 'Light'
}
const elementColors: Record<number, string> = {
0: 'null',
1: 'wind',
2: 'fire',
3: 'water',
4: 'earth',
5: 'dark',
6: 'light'
}
// Navigate to edit
function handleEdit() {
goto(`/database/gw-events/${eventId}/edit`)
@ -90,9 +70,7 @@
<DetailsContainer title="Event Details">
<DetailItem label="Event Number" value={`#${event.eventNumber}`} />
<DetailItem label="Element">
<span class="element-badge element-{elementColors[event.element]}">
{elementLabels[event.element] ?? 'Unknown'}
</span>
<ElementBadge element={event.element} />
</DetailItem>
<DetailItem label="Start Date" value={formatDateLongJST(event.startDate)} />
<DetailItem label="End Date" value={formatDateLongJST(event.endDate)} />
@ -159,42 +137,4 @@
display: flex;
flex-direction: column;
}
.element-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: typography.$font-small;
font-weight: 500;
&.element-fire {
background: #fee2e2;
color: #dc2626;
}
&.element-water {
background: #dbeafe;
color: #2563eb;
}
&.element-earth {
background: #fef3c7;
color: #d97706;
}
&.element-wind {
background: #d1fae5;
color: #059669;
}
&.element-light {
background: #fef9c3;
color: #ca8a04;
}
&.element-dark {
background: #ede9fe;
color: #7c3aed;
}
}
</style>