2026-09-09 17:08:45 +03:30
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
import { nextTick, onMounted, ref } from 'vue'
|
|
|
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
|
|
|
import PageHeader from '@/components/layout/PageHeader.vue'
|
|
|
|
|
|
import PageSkeleton from '@/components/ui/PageSkeleton.vue'
|
|
|
|
|
|
import { useCatalogStore } from '@/stores/catalog'
|
|
|
|
|
|
import type { Catalog } from '@/types'
|
|
|
|
|
|
import IconChevronLeft from '@/components/icons/IconChevronLeft.vue'
|
|
|
|
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
const catalogStore = useCatalogStore()
|
|
|
|
|
|
const catalogs = ref<Catalog[]>([])
|
|
|
|
|
|
const loading = ref(true)
|
|
|
|
|
|
const error = ref<string | null>(null)
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const companies = await catalogStore.loadCompanies()
|
|
|
|
|
|
const lists = await Promise.all(companies.map((c) => catalogStore.loadCatalogs(c.id)))
|
|
|
|
|
|
catalogs.value = lists.flat()
|
|
|
|
|
|
const focusId = String(route.query.id ?? '')
|
|
|
|
|
|
if (focusId) {
|
|
|
|
|
|
const hit = catalogs.value.find((c) => c.id === focusId)
|
|
|
|
|
|
if (hit) {
|
|
|
|
|
|
await nextTick()
|
|
|
|
|
|
openCatalog(hit)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
error.value = e instanceof Error ? e.message : 'بارگذاری کالیتهها ناموفق بود.'
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
function openCatalog(item: Catalog) {
|
|
|
|
|
|
router.push({
|
2026-09-10 21:05:05 +03:30
|
|
|
|
path: '/products',
|
|
|
|
|
|
query: { catalogId: item.id, companyId: item.companyId },
|
2026-09-09 17:08:45 +03:30
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function companyName(companyId: string) {
|
|
|
|
|
|
return catalogStore.getCompany(companyId)?.name ?? 'برند'
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<div class="page">
|
|
|
|
|
|
<PageHeader title="کالیتهها" show-back centered @back="router.push('/')" />
|
|
|
|
|
|
<div class="page__scroll page__scroll--with-nav catalog-hub">
|
|
|
|
|
|
<button type="button" class="hub-card" @click="router.push('/catalog-request')">
|
|
|
|
|
|
<strong>درخواست کالیته فیزیکی</strong>
|
|
|
|
|
|
<span>ثبت اقلام و پیگیری وضعیت</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button type="button" class="hub-card" @click="router.push('/catalog-requests')">
|
|
|
|
|
|
<strong>وضعیت درخواستها</strong>
|
|
|
|
|
|
<span>پیگیری کالیتههای ثبتشده</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button type="button" class="hub-card" @click="router.push('/categories')">
|
|
|
|
|
|
<strong>مشاهده دستهبندیها</strong>
|
|
|
|
|
|
<span>انتخاب بر اساس کاربرد و فصل</span>
|
|
|
|
|
|
</button>
|
2026-09-10 21:05:05 +03:30
|
|
|
|
<button type="button" class="hub-card" @click="router.push('/products')">
|
|
|
|
|
|
<strong>همه محصولات</strong>
|
|
|
|
|
|
<span>مشاهده کاتالوگ و ثبت سفارش</span>
|
2026-09-09 17:08:45 +03:30
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
|
|
<PageSkeleton v-if="loading" variant="grid" />
|
|
|
|
|
|
<p v-else-if="error">{{ error }}</p>
|
|
|
|
|
|
<template v-else>
|
|
|
|
|
|
<h2 class="section-title">کالیتههای موجود</h2>
|
|
|
|
|
|
<button
|
|
|
|
|
|
v-for="item in catalogs"
|
|
|
|
|
|
:key="item.id"
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
class="calite-item"
|
|
|
|
|
|
:class="{ 'calite-item--focus': String(route.query.id ?? '') === item.id }"
|
|
|
|
|
|
@click="openCatalog(item)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="calite-item__text">
|
|
|
|
|
|
<strong>{{ item.name }}</strong>
|
|
|
|
|
|
<span>کد {{ item.code }}</span>
|
|
|
|
|
|
<em>{{ companyName(item.companyId) }}</em>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<IconChevronLeft :size="18" color="#9aa3a0" />
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<p v-if="!catalogs.length" class="empty-hint">کالیتهای یافت نشد.</p>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.catalog-hub {
|
|
|
|
|
|
padding: 12px var(--page-padding) 24px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-title {
|
|
|
|
|
|
margin: 8px 0 0;
|
|
|
|
|
|
font-size: 0.95rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.hub-card,
|
|
|
|
|
|
.calite-item {
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
text-align: start;
|
|
|
|
|
|
background: var(--color-surface);
|
|
|
|
|
|
border-radius: var(--radius-md);
|
|
|
|
|
|
padding: 14px;
|
|
|
|
|
|
box-shadow: var(--shadow-sm);
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: stretch;
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.calite-item {
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.calite-item--focus {
|
|
|
|
|
|
outline: 2px solid var(--color-primary);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.calite-item__text {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.calite-item strong {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
font-size: 0.95rem;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
line-height: 1.5;
|
|
|
|
|
|
color: var(--color-text);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.hub-card span,
|
|
|
|
|
|
.calite-item span,
|
|
|
|
|
|
.calite-item em {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
color: var(--color-text-muted);
|
|
|
|
|
|
font-size: 0.8rem;
|
|
|
|
|
|
line-height: 1.5;
|
|
|
|
|
|
font-style: normal;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.empty-hint {
|
|
|
|
|
|
color: var(--color-text-muted);
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
margin: 12px 0 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|