85 lines
3.6 KiB
Vue
85 lines
3.6 KiB
Vue
<template>
|
|
<thead class="sticky top-0 z-10">
|
|
<!-- Group row -->
|
|
<tr class="bg-gray-800 border-b border-gray-700/50">
|
|
<th colspan="5" class="bg-gray-800" />
|
|
<th colspan="4" class="px-4 py-1.5 text-center text-[10px] font-semibold text-gray-500 uppercase tracking-wider border-l border-gray-700/60">
|
|
No Focus
|
|
</th>
|
|
<th colspan="4" class="px-4 py-1.5 text-center text-[10px] font-semibold text-violet-400/70 uppercase tracking-wider border-l border-gray-700/60">
|
|
With Focus
|
|
</th>
|
|
<th colspan="1" class="bg-gray-800" />
|
|
</tr>
|
|
|
|
<!-- Column row -->
|
|
<tr class="bg-gray-800 border-b border-gray-700">
|
|
<!-- Fixed left cols -->
|
|
<th class="px-3 py-2 w-4" />
|
|
<th
|
|
v-for="col in leftCols" :key="col.field"
|
|
class="px-4 py-2 text-left text-xs font-semibold text-gray-400 uppercase tracking-wider whitespace-nowrap select-none"
|
|
:class="col.sortable ? 'cursor-pointer hover:text-gray-200 transition-colors' : ''"
|
|
@click="col.sortable ? $emit('sort', col.field as SortField) : undefined"
|
|
>
|
|
<span class="flex items-center gap-1">
|
|
{{ col.label }}
|
|
<span v-if="sortState.field === col.field" class="text-amber-400">{{ sortState.direction === 'asc' ? '↑' : '↓' }}</span>
|
|
<span v-else class="text-gray-600">↕</span>
|
|
</span>
|
|
</th>
|
|
|
|
<!-- No-focus group -->
|
|
<th
|
|
v-for="col in priceCols" :key="'nf-' + col.field"
|
|
class="px-4 py-2 text-right text-xs font-semibold text-gray-400 uppercase tracking-wider whitespace-nowrap select-none border-l border-gray-700/60"
|
|
:class="[col.sortable ? 'cursor-pointer hover:text-gray-200 transition-colors' : '', col.first ? 'border-l border-gray-700/60' : '']"
|
|
@click="col.sortable ? $emit('sort', col.field as SortField) : undefined"
|
|
>
|
|
<span class="flex items-center gap-1">
|
|
{{ col.label }}
|
|
<span v-if="col.sortable && sortState.field === col.field" class="text-amber-400">{{ sortState.direction === 'asc' ? '↑' : '↓' }}</span>
|
|
<span v-else-if="col.sortable" class="text-gray-600">↕</span>
|
|
</span>
|
|
</th>
|
|
<th class="px-3 py-2 w-8" />
|
|
|
|
<!-- With-focus group -->
|
|
<th
|
|
v-for="col in priceCols" :key="'f-' + col.field"
|
|
class="px-4 py-2 text-right text-xs font-semibold text-violet-400/70 uppercase tracking-wider whitespace-nowrap select-none border-l border-gray-700/60"
|
|
:class="col.first ? 'border-l border-gray-700/60' : ''"
|
|
>
|
|
{{ col.label }}
|
|
</th>
|
|
<th class="px-3 py-2 w-8" />
|
|
|
|
<!-- Status -->
|
|
<th class="px-4 py-2 text-center text-xs font-semibold text-gray-400 uppercase tracking-wider whitespace-nowrap select-none">
|
|
Status
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { SortField, SortState } from '../../types/crafting'
|
|
|
|
const leftCols = [
|
|
{ field: 'variantType' as SortField, label: 'Variant', sortable: true },
|
|
{ field: 'displayName' as SortField, label: 'Item', sortable: true },
|
|
{ field: 'station' as SortField, label: 'Station', sortable: true },
|
|
{ field: 'tier' as SortField, label: 'Tier', sortable: true },
|
|
]
|
|
|
|
const priceCols = [
|
|
{ field: 'materialCost' as SortField, label: 'Cost', sortable: true, first: true },
|
|
{ field: 'markup15' as const, label: '+15%', sortable: false, first: false },
|
|
{ field: 'markup30' as const, label: '+30%', sortable: false, first: false },
|
|
]
|
|
|
|
|
|
defineProps<{ sortState: SortState }>()
|
|
defineEmits<{ sort: [field: SortField] }>()
|
|
</script>
|