fix(auth): org-scoped team tokens and header search order
This commit is contained in:
@@ -43,16 +43,36 @@ const LANDING_SEARCH_TOP_STOP = 16
|
||||
const LANDING_SEARCH_BOTTOM_GAP = 30
|
||||
|
||||
const logisticsSearch = reactive({
|
||||
from: '',
|
||||
to: '',
|
||||
cargo: '',
|
||||
destination: '',
|
||||
product: '',
|
||||
quantity: '',
|
||||
})
|
||||
|
||||
function syncSearchFromRoute() {
|
||||
hydrateFromQuery(route.query)
|
||||
logisticsSearch.from = typeof route.query.from === 'string' ? route.query.from : isCalcPage.value ? calcDraft.value.from : ''
|
||||
logisticsSearch.to = typeof route.query.to === 'string' ? route.query.to : isCalcPage.value ? calcDraft.value.to : ''
|
||||
logisticsSearch.cargo = typeof route.query.cargo === 'string' ? route.query.cargo : isCalcPage.value ? calcDraft.value.cargo : ''
|
||||
logisticsSearch.destination = typeof route.query.hubName === 'string'
|
||||
? route.query.hubName
|
||||
: typeof route.query.to === 'string'
|
||||
? route.query.to
|
||||
: isCalcPage.value
|
||||
? calcDraft.value.to
|
||||
: ''
|
||||
logisticsSearch.product = typeof route.query.productName === 'string'
|
||||
? route.query.productName
|
||||
: typeof route.query.from === 'string'
|
||||
? route.query.from
|
||||
: isCalcPage.value
|
||||
? calcDraft.value.from
|
||||
: ''
|
||||
logisticsSearch.quantity = typeof route.query.qty === 'string'
|
||||
? route.query.qty
|
||||
: typeof route.query.quantity === 'string'
|
||||
? route.query.quantity
|
||||
: typeof route.query.cargo === 'string'
|
||||
? route.query.cargo
|
||||
: isCalcPage.value
|
||||
? calcDraft.value.cargo
|
||||
: ''
|
||||
}
|
||||
|
||||
function inferCountryIso(value: string, fallback: string) {
|
||||
@@ -69,10 +89,8 @@ function isoToFlag(iso: string) {
|
||||
return String.fromCodePoint(...[...normalized].map(char => 127397 + char.charCodeAt(0)))
|
||||
}
|
||||
|
||||
const fromIso = computed(() => inferCountryIso(logisticsSearch.from, 'CN'))
|
||||
const toIso = computed(() => inferCountryIso(logisticsSearch.to, 'RU'))
|
||||
const fromFlag = computed(() => isoToFlag(fromIso.value))
|
||||
const toFlag = computed(() => isoToFlag(toIso.value))
|
||||
const destinationIso = computed(() => inferCountryIso(logisticsSearch.destination, 'RU'))
|
||||
const destinationFlag = computed(() => isoToFlag(destinationIso.value))
|
||||
const showAdminDock = computed(() => Boolean(showLogistics.value) && !isAuthPage.value)
|
||||
// Fullscreen menu
|
||||
const isMenuOpen = ref(false)
|
||||
@@ -212,53 +230,60 @@ const headerBackdropClass = computed(() => {
|
||||
return 'header-glass-backdrop--default'
|
||||
})
|
||||
|
||||
function buildHeaderSearchQuery(from: string, to: string, cargo: string) {
|
||||
function buildHeaderSearchQuery(destination: string, product: string, quantity: string) {
|
||||
const currentQuery = route.query || {}
|
||||
const patch = {
|
||||
from,
|
||||
to,
|
||||
cargo,
|
||||
from: product,
|
||||
to: destination,
|
||||
cargo: quantity,
|
||||
}
|
||||
const semanticQuery = {
|
||||
...(product ? { productName: product } : {}),
|
||||
...(destination ? { hubName: destination } : {}),
|
||||
...(quantity ? { qty: quantity, quantity } : {}),
|
||||
}
|
||||
|
||||
if (isCalcPage.value) {
|
||||
return {
|
||||
...currentQuery,
|
||||
...buildCalcQuery(patch),
|
||||
...semanticQuery,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...currentQuery,
|
||||
...(from ? { from } : {}),
|
||||
...(to ? { to } : {}),
|
||||
...(cargo ? { cargo } : {}),
|
||||
...(product ? { from: product } : {}),
|
||||
...(destination ? { to: destination } : {}),
|
||||
...(quantity ? { cargo: quantity } : {}),
|
||||
...semanticQuery,
|
||||
}
|
||||
}
|
||||
|
||||
async function submitHeaderSearch() {
|
||||
const from = logisticsSearch.from.trim()
|
||||
const to = logisticsSearch.to.trim()
|
||||
const cargo = logisticsSearch.cargo.trim()
|
||||
const destination = logisticsSearch.destination.trim()
|
||||
const product = logisticsSearch.product.trim()
|
||||
const quantity = logisticsSearch.quantity.trim()
|
||||
await navigateToLocalized({
|
||||
path: '/catalog',
|
||||
query: buildHeaderSearchQuery(from, to, cargo),
|
||||
query: buildHeaderSearchQuery(destination, product, quantity),
|
||||
})
|
||||
}
|
||||
|
||||
type StepRoute = 'from' | 'to' | 'cargo'
|
||||
type StepRoute = 'destination' | 'product' | 'quantity'
|
||||
|
||||
async function openStep(step: StepRoute) {
|
||||
const from = logisticsSearch.from.trim()
|
||||
const to = logisticsSearch.to.trim()
|
||||
const cargo = logisticsSearch.cargo.trim()
|
||||
const stepPath = step === 'from'
|
||||
? '/catalog/product'
|
||||
: step === 'to'
|
||||
? '/catalog/destination'
|
||||
const destination = logisticsSearch.destination.trim()
|
||||
const product = logisticsSearch.product.trim()
|
||||
const quantity = logisticsSearch.quantity.trim()
|
||||
const stepPath = step === 'destination'
|
||||
? '/catalog/destination'
|
||||
: step === 'product'
|
||||
? '/catalog/product'
|
||||
: '/catalog/quantity'
|
||||
await navigateToLocalized({
|
||||
path: stepPath,
|
||||
query: buildHeaderSearchQuery(from, to, cargo),
|
||||
query: buildHeaderSearchQuery(destination, product, quantity),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -297,7 +322,7 @@ async function goToSignIn() {
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary h-10 min-h-0 w-full rounded-full text-sm font-semibold"
|
||||
@click="openStep('from')"
|
||||
@click="openStep('destination')"
|
||||
>
|
||||
{{ $t('ui.calculate') }}
|
||||
</button>
|
||||
@@ -321,43 +346,46 @@ async function goToSignIn() {
|
||||
<div :class="searchCapsuleClass">
|
||||
<form class="flex min-w-0 flex-wrap items-center gap-2 rounded-full" @submit.prevent="submitHeaderSearch">
|
||||
<label class="search-arch input flex h-11 min-h-0 min-w-[170px] flex-1 items-center gap-3 rounded-full shadow-none">
|
||||
<span class="shrink-0 text-base leading-none">{{ fromFlag }}</span>
|
||||
<span class="shrink-0 text-base leading-none">{{ destinationFlag }}</span>
|
||||
<input
|
||||
:value="logisticsSearch.from"
|
||||
type="text"
|
||||
class="w-full cursor-pointer"
|
||||
:placeholder="$t('ui.from')"
|
||||
readonly
|
||||
@focus.prevent="openStep('from')"
|
||||
@click.prevent="openStep('from')"
|
||||
/>
|
||||
</label>
|
||||
<label class="search-arch input flex h-11 min-h-0 min-w-[170px] flex-1 items-center gap-3 rounded-full shadow-none">
|
||||
<span class="shrink-0 text-base leading-none">{{ toFlag }}</span>
|
||||
<input
|
||||
:value="logisticsSearch.to"
|
||||
:value="logisticsSearch.destination"
|
||||
type="text"
|
||||
class="w-full cursor-pointer"
|
||||
:placeholder="$t('ui.to')"
|
||||
readonly
|
||||
@focus.prevent="openStep('to')"
|
||||
@click.prevent="openStep('to')"
|
||||
@focus.prevent="openStep('destination')"
|
||||
@click.prevent="openStep('destination')"
|
||||
/>
|
||||
</label>
|
||||
<label class="search-arch input flex h-11 min-h-0 min-w-[190px] flex-[1.4] items-center gap-3 rounded-full shadow-none">
|
||||
<label class="search-arch input flex h-11 min-h-0 min-w-[170px] flex-1 items-center gap-3 rounded-full shadow-none">
|
||||
<svg viewBox="0 0 24 24" fill="none" class="h-4 w-4 shrink-0 text-base-content/60" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
|
||||
<path d="m3.3 7 8.7 5 8.7-5" />
|
||||
<path d="M12 22V12" />
|
||||
</svg>
|
||||
<input
|
||||
:value="logisticsSearch.cargo"
|
||||
:value="logisticsSearch.product"
|
||||
type="text"
|
||||
class="w-full cursor-pointer"
|
||||
:placeholder="$t('ui.cargo')"
|
||||
:placeholder="$t('ui.product')"
|
||||
readonly
|
||||
@focus.prevent="openStep('cargo')"
|
||||
@click.prevent="openStep('cargo')"
|
||||
@focus.prevent="openStep('product')"
|
||||
@click.prevent="openStep('product')"
|
||||
/>
|
||||
</label>
|
||||
<label class="search-arch input flex h-11 min-h-0 min-w-[170px] flex-1 items-center gap-3 rounded-full shadow-none">
|
||||
<svg viewBox="0 0 24 24" fill="none" class="h-4 w-4 shrink-0 text-base-content/60" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10 13a2 2 0 1 1 0-4h4a2 2 0 1 1 0 4h-4Zm0 0v2m4-2v2" />
|
||||
<path d="M6 5h12M6 19h12" />
|
||||
</svg>
|
||||
<input
|
||||
:value="logisticsSearch.quantity"
|
||||
type="text"
|
||||
class="w-full cursor-pointer"
|
||||
:placeholder="$t('ui.quantity')"
|
||||
readonly
|
||||
@focus.prevent="openStep('quantity')"
|
||||
@click.prevent="openStep('quantity')"
|
||||
/>
|
||||
</label>
|
||||
<button type="submit" class="btn btn-secondary h-11 min-h-0 rounded-full px-5">{{ $t('ui.find') }}</button>
|
||||
|
||||
Reference in New Issue
Block a user