initial commit
This commit is contained in:
91
src/App.vue
Normal file
91
src/App.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user