Files
albion-crafting-calc/src/App.vue
2026-03-04 17:01:08 -05:00

92 lines
3.1 KiB
Vue

<template>
<div class="min-h-screen bg-gray-950 text-gray-100">
<AppHeader :total-recipes="ALL_RECIPES.length" />
<!-- Page tabs -->
<div class="flex gap-0 px-6 border-b border-gray-800 bg-gray-900/80">
<button v-for="page in PAGES" :key="page.id"
class="px-5 py-3 text-sm font-medium transition-colors border-b-2 -mb-px" :class="currentPage === page.id
? 'text-amber-400 border-amber-400'
: 'text-gray-500 border-transparent hover:text-gray-300'" @click="currentPage = page.id">
{{ page.label }}
<span v-if="page.id === 'production' && orderCount > 0"
class="ml-1.5 inline-flex items-center justify-center w-4 h-4 rounded-full bg-amber-600 text-amber-100 text-[10px] font-bold">{{
orderCount }}</span>
</button>
</div>
<!-- Calculator page -->
<div v-if="currentPage === 'calculator'" class="p-6 space-y-4">
<FilterBar :filters="filters" :result-count="profitResults.length" @set-name-filter="setNameFilter"
@set-city="setCity" @toggle-tier="toggleTier" @set-selected-item-types="setSelectedItemTypes"
@toggle-enchantment="toggleEnchantment" @reset-enchantments="resetEnchantments" @set-rrr="setRrr" />
<ProfitTable :results="profitResults" :sort-state="sortState" @sort="handleSort" />
</div>
<!-- Bill of Production page -->
<ProductionPage v-else-if="currentPage === 'production'" />
<!-- Prices page -->
<PricesPage v-else-if="currentPage === 'prices'" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import AppHeader from './components/layout/AppHeader.vue'
import FilterBar from './components/filters/FilterBar.vue'
import ProfitTable from './components/table/ProfitTable.vue'
import PricesPage from './pages/PricesPage.vue'
import ProductionPage from './pages/ProductionPage.vue'
import { useFilters } from './composables/useFilters'
import { useCraftingProfit } from './composables/useCraftingProfit'
import { useProductionOrder } from './composables/useProductionOrder'
import { ALL_RECIPES } from './data/recipes'
import type { SortField, SortState } from './types/crafting'
// Page navigation
const { orderCount } = useProductionOrder()
const PAGES = [
{ id: 'calculator', label: 'Calculator' },
{ id: 'production', label: 'Bill of Production' },
{ id: 'prices', label: 'Prices' },
] as const
type PageId = typeof PAGES[number]['id']
const currentPage = ref<PageId>('calculator')
// Sort state
const sortState = ref<SortState>({ field: 'materialCost', direction: 'asc' })
// Filters
const {
filters,
setCity,
toggleTier,
setSelectedItemTypes,
setRrr,
setNameFilter,
toggleEnchantment,
resetEnchantments,
} = useFilters()
// Profit calculation
const { profitResults } = useCraftingProfit(ALL_RECIPES, filters, sortState)
// Sort handler
function handleSort(field: SortField) {
if (sortState.value.field === field) {
sortState.value = {
field,
direction: sortState.value.direction === 'asc' ? 'desc' : 'asc',
}
} else {
sortState.value = { field, direction: 'asc' }
}
}
</script>