This commit is contained in:
@@ -1,3 +1,91 @@
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { RouterLink } from 'vue-router';
|
||||
|
||||
import { useAuth } from '@/composables/useAuth.js';
|
||||
import { createAdminInventory, createAdminProduct, listAdminInventory, listAdminProducts } from '@/services/admin-catalog-service.js';
|
||||
|
||||
const { principal } = useAuth();
|
||||
const products = ref([]);
|
||||
const inventory = ref([]);
|
||||
const isLoading = ref(true);
|
||||
const isSaving = ref(false);
|
||||
const error = ref(null);
|
||||
const productName = ref('');
|
||||
const categoryId = ref('');
|
||||
const inventoryProductId = ref('');
|
||||
const conditionId = ref('');
|
||||
|
||||
function csrfToken() {
|
||||
return document.cookie.split('; ').find((value) => value.startsWith('pokemon_inventory_csrf='))?.split('=')[1] ?? '';
|
||||
}
|
||||
|
||||
async function load() {
|
||||
isLoading.value = true;
|
||||
try {
|
||||
[products.value, inventory.value] = await Promise.all([listAdminProducts(), listAdminInventory()]);
|
||||
} catch (requestError) { error.value = requestError; }
|
||||
finally { isLoading.value = false; }
|
||||
}
|
||||
|
||||
async function createProduct() {
|
||||
isSaving.value = true;
|
||||
try {
|
||||
const product = await createAdminProduct({ name: productName.value, categoryId: categoryId.value }, csrfToken());
|
||||
products.value.push(product);
|
||||
productName.value = '';
|
||||
} catch (requestError) { error.value = requestError; }
|
||||
finally { isSaving.value = false; }
|
||||
}
|
||||
|
||||
async function createInventory() {
|
||||
isSaving.value = true;
|
||||
try {
|
||||
const item = await createAdminInventory({ productId: inventoryProductId.value, conditionId: conditionId.value }, csrfToken());
|
||||
inventory.value.push(item);
|
||||
} catch (requestError) { error.value = requestError; }
|
||||
finally { isSaving.value = false; }
|
||||
}
|
||||
|
||||
onMounted(load);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="admin-page"><p class="catalog-kicker">Overview</p><h1>Collector workspace</h1><p class="detail-notes">Select an inventory item to manage its images and listing details.</p></section>
|
||||
<section class="admin-page">
|
||||
<p class="catalog-kicker">Overview</p>
|
||||
<h1>Collector workspace</h1>
|
||||
<p class="detail-notes">{{ principal?.email }} · Build the catalog one physical copy at a time.</p>
|
||||
<p v-if="isLoading" class="state state--loading" role="status">Loading inventory...</p>
|
||||
<p v-if="error" class="state state--error" role="alert">{{ error.message }}</p>
|
||||
|
||||
<div class="admin-workspace-grid">
|
||||
<form class="showcase-panel" @submit.prevent="createProduct">
|
||||
<h2>Add product</h2>
|
||||
<label class="fixture-label" for="product-name">Name</label>
|
||||
<input id="product-name" v-model="productName" class="fixture-input" required />
|
||||
<label class="fixture-label" for="product-category">Category ID</label>
|
||||
<input id="product-category" v-model="categoryId" class="fixture-input" required />
|
||||
<button class="button button--primary" type="submit" :disabled="isSaving">Create product</button>
|
||||
</form>
|
||||
<form class="showcase-panel" @submit.prevent="createInventory">
|
||||
<h2>Add inventory copy</h2>
|
||||
<label class="fixture-label" for="inventory-product">Product ID</label>
|
||||
<input id="inventory-product" v-model="inventoryProductId" class="fixture-input" required />
|
||||
<label class="fixture-label" for="inventory-condition">Condition ID</label>
|
||||
<input id="inventory-condition" v-model="conditionId" class="fixture-input" required />
|
||||
<button class="button button--primary" type="submit" :disabled="isSaving">Create copy</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<section class="admin-list" aria-labelledby="products-title">
|
||||
<h2 id="products-title">Products</h2>
|
||||
<p v-if="!products.length && !isLoading" class="state state--empty">No products yet.</p>
|
||||
<ul v-else><li v-for="product in products" :key="product.id">{{ product.name }} <span>{{ product.id }}</span></li></ul>
|
||||
</section>
|
||||
<section class="admin-list" aria-labelledby="inventory-title">
|
||||
<h2 id="inventory-title">Physical inventory</h2>
|
||||
<p v-if="!inventory.length && !isLoading" class="state state--empty">No physical copies yet.</p>
|
||||
<ul v-else><li v-for="item in inventory" :key="item.id"><span>{{ item.id }}</span> · {{ item.status }} <RouterLink :to="{ name: 'admin-image-manager', params: { id: item.id } }">Manage images</RouterLink></li></ul>
|
||||
</section>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user