Redirect search to catalog offers flow instead of /request
All checks were successful
Build Docker Image / build (push) Successful in 4m2s
All checks were successful
Build Docker Image / build (push) Successful in 4m2s
- GlobalSearchBar now redirects to /catalog/offers/[productId]/[hubId] - GoodsContent redirects to offers flow - select-location pages redirect to offers flow - Added quantity tag to offers page - Added KYC profile loading and offer detail navigation on offers page
This commit is contained in:
@@ -46,16 +46,16 @@ const selectProduct = (product: any) => {
|
|||||||
searchStore.setProduct(product.name)
|
searchStore.setProduct(product.name)
|
||||||
searchStore.setProductUuid(product.uuid)
|
searchStore.setProductUuid(product.uuid)
|
||||||
const locationUuid = searchStore.searchForm.locationUuid
|
const locationUuid = searchStore.searchForm.locationUuid
|
||||||
|
const quantity = searchStore.searchForm.quantity
|
||||||
|
|
||||||
|
const query: Record<string, string> = {}
|
||||||
|
if (quantity) query.quantity = String(quantity)
|
||||||
|
|
||||||
if (locationUuid) {
|
if (locationUuid) {
|
||||||
|
// Both product and hub selected -> show offers
|
||||||
navigateTo({
|
navigateTo({
|
||||||
path: '/request',
|
path: `/catalog/offers/${product.uuid}/${locationUuid}`,
|
||||||
query: {
|
query
|
||||||
productUuid: product.uuid,
|
|
||||||
product: product.name,
|
|
||||||
locationUuid,
|
|
||||||
location: searchStore.searchForm.location,
|
|
||||||
quantity: searchStore.searchForm.quantity || undefined
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,30 +99,33 @@ const canSearch = computed(() => {
|
|||||||
return !!productUuid.value
|
return !!productUuid.value
|
||||||
})
|
})
|
||||||
|
|
||||||
// Search handler - navigate to /request
|
// Search handler - navigate to catalog offers flow
|
||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
if (!canSearch.value) return
|
if (!canSearch.value) return
|
||||||
|
|
||||||
// Sync quantity to store
|
// Sync quantity to store
|
||||||
syncQuantityToStore()
|
syncQuantityToStore()
|
||||||
|
|
||||||
const query: Record<string, string | undefined> = {
|
// Build query params
|
||||||
productUuid: productUuid.value || undefined,
|
const query: Record<string, string> = {}
|
||||||
product: productDisplay.value || undefined,
|
if (quantity.value) {
|
||||||
quantity: quantity.value ? String(quantity.value) : undefined,
|
query.quantity = String(quantity.value)
|
||||||
locationUuid: locationUuid.value || undefined,
|
|
||||||
location: locationDisplay.value || undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove undefined/empty values
|
// Navigate to offers flow
|
||||||
Object.keys(query).forEach(key => {
|
if (productUuid.value && locationUuid.value) {
|
||||||
if (!query[key]) delete query[key]
|
// Both product and hub selected -> show offers
|
||||||
})
|
|
||||||
|
|
||||||
router.push({
|
router.push({
|
||||||
path: localePath('/request'),
|
path: localePath(`/catalog/offers/${productUuid.value}/${locationUuid.value}`),
|
||||||
query: query as Record<string, string>
|
query
|
||||||
})
|
})
|
||||||
|
} else if (productUuid.value) {
|
||||||
|
// Only product selected -> select hub
|
||||||
|
router.push({
|
||||||
|
path: localePath(`/catalog/offers/${productUuid.value}`),
|
||||||
|
query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
emit('search', {
|
emit('search', {
|
||||||
productUuid: productUuid.value,
|
productUuid: productUuid.value,
|
||||||
|
|||||||
@@ -73,6 +73,8 @@
|
|||||||
:stages="item.stages"
|
:stages="item.stages"
|
||||||
:start-name="item.name"
|
:start-name="item.name"
|
||||||
:end-name="hub?.name"
|
:end-name="hub?.name"
|
||||||
|
:kyc-profile-uuid="getOfferData(item.uuid)?.kycProfileUuid"
|
||||||
|
@select="navigateTo(localePath(`/catalog/offers/${item.uuid}`))"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -89,7 +91,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { GetNodeConnectionsDocument, GetOffersByHubDocument } from '~/composables/graphql/public/geo-generated'
|
import { GetNodeConnectionsDocument, GetOffersByHubDocument } from '~/composables/graphql/public/geo-generated'
|
||||||
import { GetAvailableProductsDocument, GetOfferDocument } from '~/composables/graphql/public/exchange-generated'
|
import { GetAvailableProductsDocument, GetOfferDocument, GetSupplierProfileByTeamDocument } from '~/composables/graphql/public/exchange-generated'
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: 'topnav'
|
layout: 'topnav'
|
||||||
@@ -108,9 +110,11 @@ const selectedSourceUuid = ref('')
|
|||||||
const hoveredSourceUuid = ref<string>()
|
const hoveredSourceUuid = ref<string>()
|
||||||
const rawSources = ref<any[]>([])
|
const rawSources = ref<any[]>([])
|
||||||
const offersData = ref<Map<string, any>>(new Map())
|
const offersData = ref<Map<string, any>>(new Map())
|
||||||
|
const suppliersData = ref<Map<string, any>>(new Map())
|
||||||
|
|
||||||
const productId = computed(() => route.params.productId as string)
|
const productId = computed(() => route.params.productId as string)
|
||||||
const hubId = computed(() => route.params.hubId as string)
|
const hubId = computed(() => route.params.hubId as string)
|
||||||
|
const quantity = computed(() => route.query.quantity as string | undefined)
|
||||||
|
|
||||||
// Navigation filters for search bar badges
|
// Navigation filters for search bar badges
|
||||||
const navigationFilters = computed(() => {
|
const navigationFilters = computed(() => {
|
||||||
@@ -132,6 +136,14 @@ const navigationFilters = computed(() => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (quantity.value) {
|
||||||
|
filters.push({
|
||||||
|
id: 'quantity',
|
||||||
|
key: 'Кол-во',
|
||||||
|
label: `${quantity.value} т`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return filters
|
return filters
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -141,6 +153,9 @@ const handleRemoveFilter = (filterId: string) => {
|
|||||||
navigateTo(localePath(`/catalog/offers/${productId.value}`))
|
navigateTo(localePath(`/catalog/offers/${productId.value}`))
|
||||||
} else if (filterId === 'product') {
|
} else if (filterId === 'product') {
|
||||||
navigateTo(localePath('/catalog/offers'))
|
navigateTo(localePath('/catalog/offers'))
|
||||||
|
} else if (filterId === 'quantity') {
|
||||||
|
// Remove quantity from query, stay on same page
|
||||||
|
navigateTo({ path: route.path, query: {} })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,25 +228,57 @@ const getOfferData = (uuid: string) => {
|
|||||||
return offersData.value.get(uuid)
|
return offersData.value.get(uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load offer details for prices
|
// Load offer details for prices and supplier info
|
||||||
const loadOfferDetails = async () => {
|
const loadOfferDetails = async () => {
|
||||||
if (rawSources.value.length === 0) {
|
if (rawSources.value.length === 0) {
|
||||||
offersData.value.clear()
|
offersData.value.clear()
|
||||||
|
suppliersData.value.clear()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const newOffersData = new Map<string, any>()
|
const newOffersData = new Map<string, any>()
|
||||||
|
const newSuppliersData = new Map<string, any>()
|
||||||
|
const teamUuidsToLoad = new Set<string>()
|
||||||
|
|
||||||
|
// First, load all offers
|
||||||
await Promise.all(rawSources.value.map(async (source) => {
|
await Promise.all(rawSources.value.map(async (source) => {
|
||||||
try {
|
try {
|
||||||
const data = await execute(GetOfferDocument, { uuid: source.sourceUuid }, 'public', 'exchange')
|
const data = await execute(GetOfferDocument, { uuid: source.sourceUuid }, 'public', 'exchange')
|
||||||
if (data?.getOffer) {
|
if (data?.getOffer) {
|
||||||
newOffersData.set(source.sourceUuid, data.getOffer)
|
newOffersData.set(source.sourceUuid, data.getOffer)
|
||||||
|
if (data.getOffer.teamUuid) {
|
||||||
|
teamUuidsToLoad.add(data.getOffer.teamUuid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading offer:', source.sourceUuid, error)
|
console.error('Error loading offer:', source.sourceUuid, error)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// Then, load supplier profiles for KYC
|
||||||
|
await Promise.all([...teamUuidsToLoad].map(async (teamUuid) => {
|
||||||
|
try {
|
||||||
|
const data = await execute(GetSupplierProfileByTeamDocument, { teamUuid }, 'public', 'exchange')
|
||||||
|
if (data?.getSupplierProfileByTeam) {
|
||||||
|
newSuppliersData.set(teamUuid, data.getSupplierProfileByTeam)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading supplier:', teamUuid, error)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Merge kycProfileUuid into offer data
|
||||||
|
newOffersData.forEach((offer, offerUuid) => {
|
||||||
|
if (offer.teamUuid) {
|
||||||
|
const supplier = newSuppliersData.get(offer.teamUuid)
|
||||||
|
if (supplier?.kycProfileUuid) {
|
||||||
|
offer.kycProfileUuid = supplier.kycProfileUuid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
offersData.value = newOffersData
|
offersData.value = newOffersData
|
||||||
|
suppliersData.value = newSuppliersData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load offers with routes to this hub
|
// Load offers with routes to this hub
|
||||||
|
|||||||
@@ -132,15 +132,12 @@ const isSelected = (type: 'address' | 'hub', uuid: string) => {
|
|||||||
|
|
||||||
const goToRequestIfReady = () => {
|
const goToRequestIfReady = () => {
|
||||||
if (route.query.after === 'request' && searchStore.searchForm.productUuid && searchStore.searchForm.locationUuid) {
|
if (route.query.after === 'request' && searchStore.searchForm.productUuid && searchStore.searchForm.locationUuid) {
|
||||||
|
const query: Record<string, string> = {}
|
||||||
|
if (searchStore.searchForm.quantity) query.quantity = String(searchStore.searchForm.quantity)
|
||||||
|
|
||||||
router.push({
|
router.push({
|
||||||
path: '/request',
|
path: `/catalog/offers/${searchStore.searchForm.productUuid}/${searchStore.searchForm.locationUuid}`,
|
||||||
query: {
|
query
|
||||||
productUuid: searchStore.searchForm.productUuid,
|
|
||||||
product: searchStore.searchForm.product,
|
|
||||||
locationUuid: searchStore.searchForm.locationUuid,
|
|
||||||
location: searchStore.searchForm.location,
|
|
||||||
quantity: searchStore.searchForm.quantity || undefined
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,15 +76,12 @@ const selectItem = async (item: any) => {
|
|||||||
searchStore.setLocation(item.name)
|
searchStore.setLocation(item.name)
|
||||||
searchStore.setLocationUuid(item.uuid)
|
searchStore.setLocationUuid(item.uuid)
|
||||||
if (route.query.after === 'request' && searchStore.searchForm.productUuid && searchStore.searchForm.locationUuid) {
|
if (route.query.after === 'request' && searchStore.searchForm.productUuid && searchStore.searchForm.locationUuid) {
|
||||||
|
const query: Record<string, string> = {}
|
||||||
|
if (searchStore.searchForm.quantity) query.quantity = String(searchStore.searchForm.quantity)
|
||||||
|
|
||||||
router.push({
|
router.push({
|
||||||
path: '/request',
|
path: `/catalog/offers/${searchStore.searchForm.productUuid}/${searchStore.searchForm.locationUuid}`,
|
||||||
query: {
|
query
|
||||||
productUuid: searchStore.searchForm.productUuid,
|
|
||||||
product: searchStore.searchForm.product,
|
|
||||||
locationUuid: searchStore.searchForm.locationUuid,
|
|
||||||
location: searchStore.searchForm.location,
|
|
||||||
quantity: searchStore.searchForm.quantity || undefined
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user