From 8c753edb28ef4e3579309a15aa78f6bdabbbd00d Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Sat, 24 Jan 2026 11:58:56 +0700 Subject: [PATCH] Add cascading filters for Explore mode When a product is selected, hubs and suppliers are filtered to show only those that are relevant to that product. --- .../graphql/public/geo-generated.ts | 36 +++++++++++++++- app/composables/useCatalogHubs.ts | 29 ++++++++++++- app/composables/useCatalogSuppliers.ts | 41 ++++++++++++++++++- app/pages/catalog/index.vue | 10 ++++- 4 files changed, 110 insertions(+), 6 deletions(-) diff --git a/app/composables/graphql/public/geo-generated.ts b/app/composables/graphql/public/geo-generated.ts index db0ee94..ac707ec 100644 --- a/app/composables/graphql/public/geo-generated.ts +++ b/app/composables/graphql/public/geo-generated.ts @@ -112,6 +112,8 @@ export type Query = { clusteredNodes?: Maybe>>; /** List of countries that have logistics hubs */ hubCountries?: Maybe>>; + /** Get hubs where a product is available nearby */ + hubsForProduct?: Maybe>>; /** Get nearest hubs to an offer location */ hubsNearOffer?: Maybe>>; /** Find nearest logistics nodes to given coordinates */ @@ -142,6 +144,8 @@ export type Query = { railRoute?: Maybe; /** Get unique suppliers from all offers */ suppliers?: Maybe>>; + /** Get suppliers that offer a specific product */ + suppliersForProduct?: Maybe>>; }; @@ -166,6 +170,13 @@ export type QueryClusteredNodesArgs = { }; +/** Root query. */ +export type QueryHubsForProductArgs = { + productUuid: Scalars['String']['input']; + radiusKm?: InputMaybe; +}; + + /** Root query. */ export type QueryHubsNearOfferArgs = { limit?: InputMaybe; @@ -261,6 +272,12 @@ export type QueryRailRouteArgs = { toLon: Scalars['Float']['input']; }; + +/** Root query. */ +export type QuerySuppliersForProductArgs = { + productUuid: Scalars['String']['input']; +}; + /** Complete route through graph with multiple stages. */ export type RoutePathType = { __typename?: 'RoutePathType'; @@ -327,6 +344,14 @@ export type GetHubCountriesQueryVariables = Exact<{ [key: string]: never; }>; export type GetHubCountriesQuery = { __typename?: 'Query', hubCountries?: Array | null }; +export type GetHubsForProductQueryVariables = Exact<{ + productUuid: Scalars['String']['input']; + radiusKm?: InputMaybe; +}>; + + +export type GetHubsForProductQuery = { __typename?: 'Query', hubsForProduct?: Array<{ __typename?: 'NodeType', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, transportTypes?: Array | null } | null> | null }; + export type GetHubsNearOfferQueryVariables = Exact<{ offerUuid: Scalars['String']['input']; limit?: InputMaybe; @@ -428,10 +453,18 @@ export type GetSuppliersQueryVariables = Exact<{ [key: string]: never; }>; export type GetSuppliersQuery = { __typename?: 'Query', suppliers?: Array<{ __typename?: 'SupplierType', uuid?: string | null } | null> | null }; +export type GetSuppliersForProductQueryVariables = Exact<{ + productUuid: Scalars['String']['input']; +}>; + + +export type GetSuppliersForProductQuery = { __typename?: 'Query', suppliersForProduct?: Array<{ __typename?: 'SupplierType', uuid?: string | null } | null> | null }; + export const GetAutoRouteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAutoRoute"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"fromLat"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"fromLon"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"toLat"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"toLon"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"autoRoute"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"fromLat"},"value":{"kind":"Variable","name":{"kind":"Name","value":"fromLat"}}},{"kind":"Argument","name":{"kind":"Name","value":"fromLon"},"value":{"kind":"Variable","name":{"kind":"Name","value":"fromLon"}}},{"kind":"Argument","name":{"kind":"Name","value":"toLat"},"value":{"kind":"Variable","name":{"kind":"Name","value":"toLat"}}},{"kind":"Argument","name":{"kind":"Name","value":"toLon"},"value":{"kind":"Variable","name":{"kind":"Name","value":"toLon"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"distanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"geometry"}}]}}]}}]} as unknown as DocumentNode; export const GetClusteredNodesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetClusteredNodes"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"west"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"south"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"east"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"north"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"zoom"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"transportType"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"nodeType"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"clusteredNodes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"west"},"value":{"kind":"Variable","name":{"kind":"Name","value":"west"}}},{"kind":"Argument","name":{"kind":"Name","value":"south"},"value":{"kind":"Variable","name":{"kind":"Name","value":"south"}}},{"kind":"Argument","name":{"kind":"Name","value":"east"},"value":{"kind":"Variable","name":{"kind":"Name","value":"east"}}},{"kind":"Argument","name":{"kind":"Name","value":"north"},"value":{"kind":"Variable","name":{"kind":"Name","value":"north"}}},{"kind":"Argument","name":{"kind":"Name","value":"zoom"},"value":{"kind":"Variable","name":{"kind":"Name","value":"zoom"}}},{"kind":"Argument","name":{"kind":"Name","value":"transportType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transportType"}}},{"kind":"Argument","name":{"kind":"Name","value":"nodeType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"nodeType"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"expansionZoom"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; export const GetHubCountriesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetHubCountries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hubCountries"}}]}}]} as unknown as DocumentNode; +export const GetHubsForProductDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetHubsForProduct"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"radiusKm"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hubsForProduct"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"radiusKm"},"value":{"kind":"Variable","name":{"kind":"Name","value":"radiusKm"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"transportTypes"}}]}}]}}]} as unknown as DocumentNode; export const GetHubsNearOfferDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetHubsNearOffer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offerUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hubsNearOffer"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"offerUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offerUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"transportTypes"}}]}}]}}]} as unknown as DocumentNode; export const GetNodeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetNode"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"uuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"uuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"uuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"syncedAt"}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"toUuid"}},{"kind":"Field","name":{"kind":"Name","value":"toName"}},{"kind":"Field","name":{"kind":"Name","value":"toLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"toLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"distanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"travelTimeSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"transportType"}}]}}]}}]}}]} as unknown as DocumentNode; export const GetNodeConnectionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetNodeConnections"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"uuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limitAuto"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limitRail"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"nodeConnections"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"uuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"uuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"limitAuto"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limitAuto"}}},{"kind":"Argument","name":{"kind":"Name","value":"limitRail"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limitRail"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hub"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"syncedAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"railNode"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"syncedAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"autoEdges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"toUuid"}},{"kind":"Field","name":{"kind":"Name","value":"toName"}},{"kind":"Field","name":{"kind":"Name","value":"toLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"toLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"distanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"travelTimeSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"transportType"}}]}},{"kind":"Field","name":{"kind":"Name","value":"railEdges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"toUuid"}},{"kind":"Field","name":{"kind":"Name","value":"toName"}},{"kind":"Field","name":{"kind":"Name","value":"toLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"toLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"distanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"travelTimeSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"transportType"}}]}}]}}]}}]} as unknown as DocumentNode; @@ -444,4 +477,5 @@ export const GetProductsDocument = {"kind":"Document","definitions":[{"kind":"Op export const GetProductsBySupplierDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProductsBySupplier"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"supplierUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"productsBySupplier"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"supplierUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"supplierUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"offersCount"}}]}}]}}]} as unknown as DocumentNode; export const GetProductsNearHubDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProductsNearHub"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"hubUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"radiusKm"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"productsNearHub"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"hubUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"hubUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"radiusKm"},"value":{"kind":"Variable","name":{"kind":"Name","value":"radiusKm"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"offersCount"}}]}}]}}]} as unknown as DocumentNode; export const GetRailRouteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetRailRoute"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"fromLat"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"fromLon"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"toLat"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"toLon"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"railRoute"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"fromLat"},"value":{"kind":"Variable","name":{"kind":"Name","value":"fromLat"}}},{"kind":"Argument","name":{"kind":"Name","value":"fromLon"},"value":{"kind":"Variable","name":{"kind":"Name","value":"fromLon"}}},{"kind":"Argument","name":{"kind":"Name","value":"toLat"},"value":{"kind":"Variable","name":{"kind":"Name","value":"toLat"}}},{"kind":"Argument","name":{"kind":"Name","value":"toLon"},"value":{"kind":"Variable","name":{"kind":"Name","value":"toLon"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"distanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"geometry"}}]}}]}}]} as unknown as DocumentNode; -export const GetSuppliersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSuppliers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"suppliers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file +export const GetSuppliersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSuppliers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"suppliers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}}]}}]}}]} as unknown as DocumentNode; +export const GetSuppliersForProductDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSuppliersForProduct"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"suppliersForProduct"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/app/composables/useCatalogHubs.ts b/app/composables/useCatalogHubs.ts index 97859dc..b648919 100644 --- a/app/composables/useCatalogHubs.ts +++ b/app/composables/useCatalogHubs.ts @@ -1,4 +1,4 @@ -import { GetNodesDocument, GetHubCountriesDocument } from '~/composables/graphql/public/geo-generated' +import { GetNodesDocument, GetHubCountriesDocument, GetHubsForProductDocument } from '~/composables/graphql/public/geo-generated' const PAGE_SIZE = 24 @@ -11,6 +11,7 @@ const countries = ref([]) const isLoading = ref(false) const isLoadingMore = ref(false) const isInitialized = ref(false) +const filterProductUuid = ref(null) export function useCatalogHubs() { const { t } = useI18n() @@ -50,6 +51,22 @@ export function useCatalogHubs() { const fetchPage = async (offset: number, replace = false) => { if (replace) isLoading.value = true try { + // If filtering by product, use specialized query + if (filterProductUuid.value) { + const data = await execute( + GetHubsForProductDocument, + { productUuid: filterProductUuid.value }, + 'public', + 'geo' + ) + const next = data?.hubsForProduct || [] + items.value = next + total.value = next.length + isInitialized.value = true + return + } + + // Default: fetch all hubs with filters const transportType = selectedFilter.value === 'all' ? null : selectedFilter.value const country = selectedCountry.value === 'all' ? null : selectedCountry.value const data = await execute( @@ -93,6 +110,13 @@ export function useCatalogHubs() { } }) + const setProductFilter = (uuid: string | null) => { + filterProductUuid.value = uuid + if (isInitialized.value) { + fetchPage(0, true) + } + } + // Initialize data if not already loaded const init = async () => { if (!isInitialized.value && items.value.length === 0) { @@ -117,6 +141,7 @@ export function useCatalogHubs() { canLoadMore, fetchPage, loadMore, - init + init, + setProductFilter } } diff --git a/app/composables/useCatalogSuppliers.ts b/app/composables/useCatalogSuppliers.ts index a7d08a9..438c3fe 100644 --- a/app/composables/useCatalogSuppliers.ts +++ b/app/composables/useCatalogSuppliers.ts @@ -1,4 +1,5 @@ import { GetSupplierProfilesDocument } from '~/composables/graphql/public/exchange-generated' +import { GetSuppliersForProductDocument } from '~/composables/graphql/public/geo-generated' const PAGE_SIZE = 24 @@ -8,6 +9,7 @@ const total = ref(0) const isLoading = ref(false) const isLoadingMore = ref(false) const isInitialized = ref(false) +const filterProductUuid = ref(null) export function useCatalogSuppliers() { const { execute } = useGraphQL() @@ -21,6 +23,35 @@ export function useCatalogSuppliers() { const fetchPage = async (offset: number, replace = false) => { if (replace) isLoading.value = true try { + // If filtering by product, use specialized query + if (filterProductUuid.value) { + const data = await execute( + GetSuppliersForProductDocument, + { productUuid: filterProductUuid.value }, + 'public', + 'geo' + ) + const supplierUuids = (data?.suppliersForProduct || []).map(s => s?.uuid).filter(Boolean) + // Fetch full profiles for these suppliers + if (supplierUuids.length > 0) { + const profilesData = await execute( + GetSupplierProfilesDocument, + { limit: supplierUuids.length, offset: 0 }, + 'public', + 'exchange' + ) + // Filter to only include suppliers that match the product filter + const allProfiles = profilesData?.getSupplierProfiles || [] + items.value = allProfiles.filter(p => supplierUuids.includes(p.uuid)) + } else { + items.value = [] + } + total.value = items.value.length + isInitialized.value = true + return + } + + // Default: fetch all suppliers const data = await execute( GetSupplierProfilesDocument, { limit: PAGE_SIZE, offset }, @@ -53,6 +84,13 @@ export function useCatalogSuppliers() { } } + const setProductFilter = (uuid: string | null) => { + filterProductUuid.value = uuid + if (isInitialized.value) { + fetchPage(0, true) + } + } + return { items, total, @@ -62,6 +100,7 @@ export function useCatalogSuppliers() { canLoadMore, fetchPage, loadMore, - init + init, + setProductFilter } } diff --git a/app/pages/catalog/index.vue b/app/pages/catalog/index.vue index d3f8e25..d8db380 100644 --- a/app/pages/catalog/index.vue +++ b/app/pages/catalog/index.vue @@ -119,8 +119,8 @@ const { setHubFilter, clearFilters: clearProductFilters } = useCatalogProducts() -const { items: hubs, isLoading: hubsLoading, isLoadingMore: hubsLoadingMore, canLoadMore: hubsCanLoadMore, loadMore: loadMoreHubs, init: initHubs } = useCatalogHubs() -const { items: suppliers, isLoading: suppliersLoading, isLoadingMore: suppliersLoadingMore, canLoadMore: suppliersCanLoadMore, loadMore: loadMoreSuppliers, init: initSuppliers } = useCatalogSuppliers() +const { items: hubs, isLoading: hubsLoading, isLoadingMore: hubsLoadingMore, canLoadMore: hubsCanLoadMore, loadMore: loadMoreHubs, init: initHubs, setProductFilter: setHubProductFilter } = useCatalogHubs() +const { items: suppliers, isLoading: suppliersLoading, isLoadingMore: suppliersLoadingMore, canLoadMore: suppliersCanLoadMore, loadMore: loadMoreSuppliers, init: initSuppliers, setProductFilter: setSupplierProductFilter } = useCatalogSuppliers() // Filtered items by map bounds const filteredProducts = computed(() => { @@ -196,6 +196,12 @@ watch([supplierId, hubId], ([newSupplierId, newHubId]) => { } }, { immediate: true }) +// Apply product filter to hubs and suppliers (cascading filter) +watch(productId, (newProductId) => { + setHubProductFilter(newProductId || null) + setSupplierProductFilter(newProductId || null) +}, { immediate: true }) + // Offers data for quote results const offers = ref([]) const offersLoading = ref(false)