This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
|
||||
import { useAuth } from "@/composables/useAuth.js";
|
||||
import AdminListingStatus from "@/components/molecules/AdminListingStatus.vue";
|
||||
import InventoryWorkflowStepper from "@/components/molecules/InventoryWorkflowStepper.vue";
|
||||
import ProductIdentityStep from "@/components/molecules/ProductIdentityStep.vue";
|
||||
import ProviderMappingStep from "@/components/molecules/ProviderMappingStep.vue";
|
||||
@@ -26,8 +25,6 @@ import {
|
||||
import {
|
||||
createAdminListing,
|
||||
listAdminListings,
|
||||
markListingPending,
|
||||
publishAdminListing,
|
||||
} from "@/services/admin-listing-service.js";
|
||||
import {
|
||||
createAdminSale,
|
||||
@@ -348,20 +345,6 @@ async function createListing() {
|
||||
}
|
||||
}
|
||||
|
||||
async function transitionListing(action, id) {
|
||||
isSaving.value = true;
|
||||
try {
|
||||
const listing = await action(id, csrfToken());
|
||||
listings.value = listings.value.map((candidate) =>
|
||||
candidate.id === listing.id ? listing : candidate,
|
||||
);
|
||||
} catch (requestError) {
|
||||
error.value = requestError;
|
||||
} finally {
|
||||
isSaving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function recordSale() {
|
||||
isSaving.value = true;
|
||||
try {
|
||||
@@ -1043,19 +1026,8 @@ onMounted(() => {
|
||||
</section>
|
||||
<section class="admin-list" aria-labelledby="listings-title">
|
||||
<h2 id="listings-title">Listings</h2>
|
||||
<p v-if="!listings.length && !isLoading" class="state state--empty">
|
||||
No listings yet.
|
||||
</p>
|
||||
<div v-else class="admin-listing-stack">
|
||||
<AdminListingStatus
|
||||
v-for="listing in listings"
|
||||
:key="listing.id"
|
||||
:listing="listing"
|
||||
:is-saving="isSaving"
|
||||
@publish="transitionListing(publishAdminListing, listing.id)"
|
||||
@pending="transitionListing(markListingPending, listing.id)"
|
||||
/>
|
||||
</div>
|
||||
<p>{{ listings.length }} listing{{ listings.length === 1 ? "" : "s" }} recorded.</p>
|
||||
<a class="button button--secondary" href="/admin/listings">Manage listings</a>
|
||||
</section>
|
||||
<section class="admin-list" aria-labelledby="sales-title">
|
||||
<h2 id="sales-title">Sale history</h2>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import AdminListingsPage from './AdminListingsPage.vue';
|
||||
|
||||
export default { title: 'Pages/AdminListingsPage', component: AdminListingsPage };
|
||||
|
||||
export const Listings = {};
|
||||
@@ -0,0 +1,63 @@
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import AdminListingStatus from '@/components/molecules/AdminListingStatus.vue';
|
||||
import { listAdminListings, markListingPending, publishAdminListing } from '@/services/admin-listing-service.js';
|
||||
|
||||
const listings = ref([]);
|
||||
const isLoading = ref(true);
|
||||
const isSaving = ref(false);
|
||||
const error = ref('');
|
||||
|
||||
function csrfToken() {
|
||||
return document.cookie.split('; ').find((value) => value.startsWith('pokemon_inventory_csrf='))?.split('=')[1] ?? '';
|
||||
}
|
||||
|
||||
async function load() {
|
||||
try {
|
||||
listings.value = await listAdminListings();
|
||||
} catch (requestError) {
|
||||
error.value = requestError.message;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function transitionListing(action, id) {
|
||||
isSaving.value = true;
|
||||
error.value = '';
|
||||
try {
|
||||
const listing = await action(id, csrfToken());
|
||||
listings.value = listings.value.map((candidate) => (candidate.id === listing.id ? listing : candidate));
|
||||
} catch (requestError) {
|
||||
error.value = requestError.message;
|
||||
} finally {
|
||||
isSaving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="admin-page">
|
||||
<p class="catalog-kicker">Inventory management</p>
|
||||
<h1>Listings</h1>
|
||||
<p v-if="isLoading" class="state state--loading" role="status">Loading listings...</p>
|
||||
<p v-if="error" class="state state--error" role="alert">{{ error }}</p>
|
||||
<section v-if="!isLoading" class="admin-list" aria-labelledby="listings-title">
|
||||
<h2 id="listings-title">All listings</h2>
|
||||
<p v-if="!listings.length" class="state state--empty">No listings yet.</p>
|
||||
<div v-else class="admin-listing-stack">
|
||||
<AdminListingStatus
|
||||
v-for="listing in listings"
|
||||
:key="listing.id"
|
||||
:listing="listing"
|
||||
:is-saving="isSaving"
|
||||
@publish="transitionListing(publishAdminListing, listing.id)"
|
||||
@pending="transitionListing(markListingPending, listing.id)"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</template>
|
||||
@@ -19,6 +19,7 @@ async function logout() {
|
||||
<h1>Inventory</h1>
|
||||
<nav aria-label="Admin navigation">
|
||||
<a href="/admin">Overview</a>
|
||||
<RouterLink :to="{ name: 'admin-listings' }">Listings</RouterLink>
|
||||
<RouterLink :to="{ name: 'admin-settings' }">Settings</RouterLink>
|
||||
<RouterLink :to="{ name: 'admin-saved-views' }">Saved views</RouterLink>
|
||||
</nav>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useAuth } from '@/composables/useAuth.js';
|
||||
import AdminImagePage from '@/pages/AdminImagePage.vue';
|
||||
import AdminSettingsPage from '@/pages/AdminSettingsPage.vue';
|
||||
import AdminSavedViewsPage from '@/pages/AdminSavedViewsPage.vue';
|
||||
import AdminListingsPage from '@/pages/AdminListingsPage.vue';
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
@@ -24,6 +25,7 @@ const router = createRouter({
|
||||
children: [
|
||||
{ path: '', name: 'admin-home', component: AdminHomePage },
|
||||
{ path: 'inventory/:id/images', name: 'admin-image-manager', component: AdminImagePage },
|
||||
{ path: 'listings', name: 'admin-listings', component: AdminListingsPage },
|
||||
{ path: 'settings', name: 'admin-settings', component: AdminSettingsPage },
|
||||
{ path: 'saved-views', name: 'admin-saved-views', component: AdminSavedViewsPage },
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user