refactor(catalog): replace InfoPanel tabs with vertical sections
All checks were successful
Build Docker Image / build (push) Successful in 3m57s
All checks were successful
Build Docker Image / build (push) Successful in 3m57s
- Remove all tabs from InfoPanel, use stacked sections instead - Load suppliers (for hub) and hubs (for supplier) immediately - Show entity header as text, not card - Simplify relatedPoints to show all points on map - Add translations for new section titles
This commit is contained in:
@@ -29,7 +29,7 @@ export function useCatalogInfo() {
|
||||
const isLoadingSuppliers = ref(false)
|
||||
const isLoadingOffers = ref(false)
|
||||
|
||||
// Load hub info: hub details + products + suppliers
|
||||
// Load hub info: hub details + products + suppliers (in parallel)
|
||||
const loadHubInfo = async (uuid: string) => {
|
||||
try {
|
||||
// Load hub node details
|
||||
@@ -44,23 +44,27 @@ export function useCatalogInfo() {
|
||||
// Set default active tab to offers (first step shows products)
|
||||
activeTab.value = 'offers'
|
||||
|
||||
// Load products (offers grouped by product)
|
||||
// Load products AND suppliers in parallel
|
||||
isLoadingProducts.value = true
|
||||
try {
|
||||
const offersData = await execute(
|
||||
NearestOffersDocument,
|
||||
{
|
||||
lat: entity.value.latitude,
|
||||
lon: entity.value.longitude,
|
||||
radius: 500
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
)
|
||||
isLoadingSuppliers.value = true
|
||||
|
||||
// Load products (offers grouped by product) and extract suppliers
|
||||
execute(
|
||||
NearestOffersDocument,
|
||||
{
|
||||
lat: entity.value.latitude,
|
||||
lon: entity.value.longitude,
|
||||
radius: 500
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
).then(offersData => {
|
||||
// Group offers by product
|
||||
const productsMap = new Map<string, any>()
|
||||
const suppliersMap = new Map<string, any>()
|
||||
|
||||
offersData?.nearestOffers?.forEach((offer: any) => {
|
||||
// Products
|
||||
if (offer?.productUuid) {
|
||||
if (!productsMap.has(offer.productUuid)) {
|
||||
productsMap.set(offer.productUuid, {
|
||||
@@ -71,19 +75,50 @@ export function useCatalogInfo() {
|
||||
}
|
||||
productsMap.get(offer.productUuid)!.offersCount++
|
||||
}
|
||||
})
|
||||
relatedProducts.value = Array.from(productsMap.values())
|
||||
} finally {
|
||||
isLoadingProducts.value = false
|
||||
}
|
||||
|
||||
// Note: Suppliers and Offers loaded after product selection via loadOffersForHub
|
||||
// Suppliers (extract from offers)
|
||||
if (offer?.supplierUuid) {
|
||||
if (!suppliersMap.has(offer.supplierUuid)) {
|
||||
suppliersMap.set(offer.supplierUuid, {
|
||||
uuid: offer.supplierUuid,
|
||||
name: offer.supplierName || 'Supplier',
|
||||
latitude: offer.latitude,
|
||||
longitude: offer.longitude
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
relatedProducts.value = Array.from(productsMap.values())
|
||||
|
||||
// Load supplier profiles for detailed info
|
||||
const supplierUuids = Array.from(suppliersMap.keys()).slice(0, 12)
|
||||
if (supplierUuids.length > 0) {
|
||||
Promise.all(
|
||||
supplierUuids.map(supplierId =>
|
||||
execute(GetSupplierProfileDocument, { uuid: supplierId }, 'public', 'exchange')
|
||||
.then(data => data?.getSupplierProfile)
|
||||
.catch(() => suppliersMap.get(supplierId)) // Fallback to basic info
|
||||
)
|
||||
).then(profiles => {
|
||||
relatedSuppliers.value = profiles.filter(Boolean)
|
||||
isLoadingSuppliers.value = false
|
||||
})
|
||||
} else {
|
||||
relatedSuppliers.value = []
|
||||
isLoadingSuppliers.value = false
|
||||
}
|
||||
}).finally(() => {
|
||||
isLoadingProducts.value = false
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error loading hub info:', error)
|
||||
isLoadingProducts.value = false
|
||||
isLoadingSuppliers.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// Load supplier info: supplier details + products
|
||||
// Load supplier info: supplier details + products + hubs (in parallel)
|
||||
const loadSupplierInfo = async (uuid: string) => {
|
||||
try {
|
||||
// Load supplier node details (might be geo node)
|
||||
@@ -113,20 +148,21 @@ export function useCatalogInfo() {
|
||||
// Set default active tab to offers (first step shows products)
|
||||
activeTab.value = 'offers'
|
||||
|
||||
// Load products (offers grouped by product)
|
||||
// Load products AND hubs in parallel
|
||||
isLoadingProducts.value = true
|
||||
try {
|
||||
const offersData = await execute(
|
||||
NearestOffersDocument,
|
||||
{
|
||||
lat: entity.value.latitude,
|
||||
lon: entity.value.longitude,
|
||||
radius: 500
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
)
|
||||
isLoadingHubs.value = true
|
||||
|
||||
// Load products (offers grouped by product)
|
||||
execute(
|
||||
NearestOffersDocument,
|
||||
{
|
||||
lat: entity.value.latitude,
|
||||
lon: entity.value.longitude,
|
||||
radius: 500
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
).then(offersData => {
|
||||
// Group offers by product
|
||||
const productsMap = new Map<string, any>()
|
||||
offersData?.nearestOffers?.forEach((offer: any) => {
|
||||
@@ -142,13 +178,30 @@ export function useCatalogInfo() {
|
||||
}
|
||||
})
|
||||
relatedProducts.value = Array.from(productsMap.values())
|
||||
} finally {
|
||||
}).finally(() => {
|
||||
isLoadingProducts.value = false
|
||||
}
|
||||
})
|
||||
|
||||
// Note: Hubs will be loaded after product selection
|
||||
// Load hubs near supplier
|
||||
execute(
|
||||
NearestHubsDocument,
|
||||
{
|
||||
lat: entity.value.latitude,
|
||||
lon: entity.value.longitude,
|
||||
radius: 1000,
|
||||
limit: 12
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
).then(hubsData => {
|
||||
relatedHubs.value = hubsData?.nearestHubs || []
|
||||
}).finally(() => {
|
||||
isLoadingHubs.value = false
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error loading supplier info:', error)
|
||||
isLoadingProducts.value = false
|
||||
isLoadingHubs.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user