Compare commits
195 Commits
4c6f5abd78
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29c34a048a | ||
|
|
4467d20160 | ||
|
|
2e9ce856f2 | ||
|
|
1c8c81a54e | ||
|
|
61a37040d6 | ||
|
|
055d682167 | ||
|
|
24398ad918 | ||
|
|
37c9419155 | ||
|
|
fea81b43b8 | ||
|
|
25f946b293 | ||
|
|
15563991df | ||
|
|
5982838ebd | ||
|
|
84e857ffc1 | ||
|
|
e4d6c9ce81 | ||
|
|
4001756c3c | ||
|
|
85913a760d | ||
|
|
bef34eeaa5 | ||
|
|
8ff44c42bc | ||
|
|
3f92b3876d | ||
|
|
a73a801a1d | ||
|
|
2d54dc3283 | ||
|
|
d36409df57 | ||
|
|
87d3d5b1a7 | ||
|
|
1c033a55b4 | ||
|
|
49f2c237b7 | ||
|
|
6b9935e8e8 | ||
|
|
38081a5cb0 | ||
|
|
481a38b3a1 | ||
|
|
1f60062d15 | ||
|
|
74dd220104 | ||
|
|
c0466c7234 | ||
|
|
2fb34f664f | ||
|
|
28eff7c323 | ||
|
|
589a74d75e | ||
|
|
1fa4a707ad | ||
|
|
f85b1504e2 | ||
|
|
34fc1bfab6 | ||
|
|
755a92d194 | ||
|
|
aa7790f45e | ||
|
|
2d85e7187e | ||
|
|
795aa0381e | ||
|
|
c5d1dc87ae | ||
|
|
2939482fc3 | ||
|
|
1287ae9db7 | ||
|
|
87133ed37a | ||
|
|
0453aeae07 | ||
|
|
d877eff212 | ||
|
|
269d801493 | ||
|
|
85457a34d5 | ||
|
|
675f46a75e | ||
|
|
e4f81dba7c | ||
|
|
b971391fd7 | ||
|
|
8c1827fab6 | ||
|
|
eb31b8299b | ||
|
|
981500ec5d | ||
|
|
ca7c6fa8a5 | ||
|
|
4585d30d53 | ||
|
|
f80164c912 | ||
|
|
f0c687c3ff | ||
|
|
fa0465fabb | ||
|
|
161a1426e4 | ||
|
|
a3e7c92915 | ||
|
|
1e761ca2a8 | ||
|
|
4bdefc9ce9 | ||
|
|
fb29c2a4f6 | ||
|
|
d262928a09 | ||
|
|
b76c7fce94 | ||
|
|
666423bcf4 | ||
|
|
cf081e7e67 | ||
|
|
05c91ca352 | ||
|
|
adf2a7765c | ||
|
|
4669911162 | ||
|
|
71a27a4ab9 | ||
|
|
0f0b1db394 | ||
|
|
beb02bd3fc | ||
|
|
f1eb7bc746 | ||
|
|
2fc4faaa83 | ||
|
|
9c19d08cf5 | ||
|
|
bd2a063e39 | ||
|
|
2a8ef4b7dc | ||
|
|
8a2a804c58 | ||
|
|
0a63d4b0b2 | ||
|
|
532b9ce78d | ||
|
|
a244589fe5 | ||
|
|
1850d255a7 | ||
|
|
de3ec4c39d | ||
|
|
71e69a7abc | ||
|
|
d5aa47c323 | ||
|
|
d227325d1a | ||
|
|
bd7a1d1b4b | ||
|
|
3a46cfc5dc | ||
|
|
f4afd362eb | ||
|
|
5a780707dc | ||
|
|
886415344d | ||
|
|
6ee8c12e6f | ||
|
|
bc037e85a4 | ||
|
|
72f2e1c39d | ||
|
|
3d5215d967 | ||
|
|
33c406995f | ||
|
|
209d81ec61 | ||
|
|
984daa7a84 | ||
|
|
63e8d47b79 | ||
|
|
f5b95c27ef | ||
|
|
8b0e1900d1 | ||
|
|
45acef9b20 | ||
|
|
1f996d27e5 | ||
|
|
02419abdd1 | ||
|
|
7066c51505 | ||
|
|
88d78e9662 | ||
|
|
3f7b83bb6d | ||
|
|
b5534d1fd5 | ||
|
|
7f8a148aa7 | ||
|
|
f269c0daf0 | ||
|
|
497a80f0c6 | ||
|
|
5aa460fd8a | ||
|
|
805b6795f0 | ||
|
|
c39bc55ebc | ||
|
|
c152a5b14c | ||
|
|
2dbe600d8a | ||
|
|
ff34c564e1 | ||
|
|
80474acc0f | ||
|
|
859eef3761 | ||
|
|
7bd4aa37bd | ||
|
|
20e0e73c58 | ||
|
|
9210f79a3d | ||
|
|
65250f1342 | ||
|
|
3f823b2abc | ||
|
|
75ce64b46e | ||
|
|
70c53da8eb | ||
|
|
839ab4e830 | ||
|
|
19aca61845 | ||
|
|
6545eeabea | ||
|
|
f9eb027ebd | ||
|
|
b02e3882cc | ||
|
|
c56bb57fbf | ||
|
|
c6abf8ad4a | ||
|
|
33c1559ab7 | ||
|
|
e905098cb5 | ||
|
|
69bb978526 | ||
|
|
263e60e003 | ||
|
|
eb2266d66f | ||
|
|
3f56a2f117 | ||
|
|
f680740f52 | ||
|
|
53a51ed80c | ||
|
|
d4b4f7011f | ||
|
|
11a52003e7 | ||
|
|
80a587c74f | ||
|
|
cecbed99b5 | ||
|
|
f973784257 | ||
|
|
8354102895 | ||
|
|
a569942e24 | ||
|
|
2275f956ae | ||
|
|
6b359b177c | ||
|
|
1c298951b1 | ||
|
|
c76750a738 | ||
|
|
2d83110ef1 | ||
|
|
5ca995ebcc | ||
|
|
3211c5a881 | ||
|
|
911de423f6 | ||
|
|
a48dcf24ee | ||
|
|
0efc4eddfd | ||
|
|
65b07271d9 | ||
|
|
6d916d65a0 | ||
|
|
2b6cccdead | ||
|
|
b326d8cd76 | ||
|
|
ed7dec304f | ||
|
|
cc52aa6179 | ||
|
|
50375f2a74 | ||
|
|
7403d4f063 | ||
|
|
39c3d24b3a | ||
|
|
908d63062c | ||
|
|
2ce3bd0bd2 | ||
|
|
9b99d8981c | ||
|
|
8c753edb28 | ||
|
|
726c63efb7 | ||
|
|
4d018323e7 | ||
|
|
690c76ac79 | ||
|
|
467f099130 | ||
|
|
7c566aeafc | ||
|
|
2fc4dfb834 | ||
|
|
d03564a2d9 | ||
|
|
74324ff337 | ||
|
|
404375248b | ||
|
|
2a607d0d2d | ||
|
|
3140226bc3 | ||
|
|
5e55443975 | ||
|
|
63d81ab42f | ||
|
|
593aa0df12 | ||
|
|
aa5a0a66fa | ||
|
|
9d46bab93f | ||
|
|
655c02d6fc | ||
|
|
999658aee1 | ||
|
|
f31ceacdee | ||
|
|
5258347ccb | ||
|
|
fc6ce31659 |
@@ -26,12 +26,6 @@ jobs:
|
||||
context: .
|
||||
push: true
|
||||
tags: gitea.dsrptlab.com/optovia/webapp/webapp:latest
|
||||
build-args: |
|
||||
INFISICAL_API_URL=${{ secrets.INFISICAL_API_URL }}
|
||||
INFISICAL_CLIENT_ID=${{ secrets.INFISICAL_CLIENT_ID }}
|
||||
INFISICAL_CLIENT_SECRET=${{ secrets.INFISICAL_CLIENT_SECRET }}
|
||||
INFISICAL_PROJECT_ID=${{ secrets.INFISICAL_PROJECT_ID }}
|
||||
INFISICAL_ENV=prod
|
||||
|
||||
- name: Deploy to Dokploy
|
||||
run: curl -X POST "https://dokploy.optovia.ru/api/deploy/0_iNAXPDx28BLZIddGTzB"
|
||||
run: curl -k -X POST "https://dokploy.dsrptlab.com/api/deploy/3zjbiuDvfDQ435HvMUAG8"
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
import path from 'node:path'
|
||||
import type { StorybookConfig } from '@storybook/vue3-vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ['../app/components/**/*.stories.@(js|ts)'],
|
||||
addons: ['@storybook/addon-essentials', '@storybook/addon-interactions'],
|
||||
framework: {
|
||||
name: '@storybook/vue3-vite',
|
||||
options: {}
|
||||
},
|
||||
core: {
|
||||
disableTelemetry: true
|
||||
},
|
||||
docs: {
|
||||
autodocs: false
|
||||
},
|
||||
viteFinal: async (baseConfig) => {
|
||||
const projectRoot = path.resolve(__dirname, '..')
|
||||
baseConfig.resolve = baseConfig.resolve || {}
|
||||
baseConfig.resolve.alias = {
|
||||
...baseConfig.resolve.alias,
|
||||
'~': path.resolve(__dirname, '../app'),
|
||||
'@': path.resolve(__dirname, '../app'),
|
||||
'@graphql-typed-document-node/core': path.resolve(__dirname, './shims/graphql-typed-document-node-core.ts')
|
||||
}
|
||||
baseConfig.plugins = baseConfig.plugins || []
|
||||
baseConfig.plugins.push(vue())
|
||||
baseConfig.root = projectRoot
|
||||
baseConfig.server = {
|
||||
...(baseConfig.server || {}),
|
||||
fs: {
|
||||
...(baseConfig.server?.fs || {}),
|
||||
allow: Array.from(
|
||||
new Set([
|
||||
...(baseConfig.server?.fs?.allow || []),
|
||||
projectRoot
|
||||
])
|
||||
)
|
||||
}
|
||||
}
|
||||
return baseConfig
|
||||
}
|
||||
}
|
||||
|
||||
export default config
|
||||
@@ -1,23 +0,0 @@
|
||||
import type { Preview } from '@storybook/vue3'
|
||||
import { setup } from '@storybook/vue3'
|
||||
|
||||
import '../app/assets/css/tailwind.css'
|
||||
|
||||
setup((app) => {
|
||||
app.config.globalProperties.$t = (key: string) => key
|
||||
app.config.globalProperties.$d = (value: any) => value
|
||||
})
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default preview
|
||||
@@ -1,10 +0,0 @@
|
||||
// Minimal runtime shim so Vite/Storybook can resolve generated GraphQL imports.
|
||||
import type { DocumentNode } from 'graphql'
|
||||
|
||||
export type TypedDocumentNode<TResult = any, TVariables = Record<string, any>> = DocumentNode & {
|
||||
__resultType?: TResult
|
||||
__variablesType?: TVariables
|
||||
}
|
||||
|
||||
// Runtime placeholder; generated files import the symbol but do not use the value.
|
||||
export const TypedDocumentNode = {} as unknown as TypedDocumentNode
|
||||
21
Dockerfile
21
Dockerfile
@@ -2,28 +2,21 @@ FROM node:22-slim AS build
|
||||
|
||||
ENV PNPM_HOME=/pnpm
|
||||
ENV PATH=$PNPM_HOME:$PATH
|
||||
ENV NODE_OPTIONS=--max-old-space-size=2048
|
||||
ENV NUXT_SOURCEMAP=false
|
||||
ENV NUXT_MINIFY=false
|
||||
ENV SENTRY_ENABLED=false
|
||||
ENV NUXT_TELEMETRY_DISABLED=1
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
ARG INFISICAL_API_URL
|
||||
ARG INFISICAL_CLIENT_ID
|
||||
ARG INFISICAL_CLIENT_SECRET
|
||||
ARG INFISICAL_PROJECT_ID
|
||||
ARG INFISICAL_ENV
|
||||
|
||||
ENV INFISICAL_API_URL=$INFISICAL_API_URL \
|
||||
INFISICAL_CLIENT_ID=$INFISICAL_CLIENT_ID \
|
||||
INFISICAL_CLIENT_SECRET=$INFISICAL_CLIENT_SECRET \
|
||||
INFISICAL_PROJECT_ID=$INFISICAL_PROJECT_ID \
|
||||
INFISICAL_ENV=$INFISICAL_ENV
|
||||
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
COPY . .
|
||||
RUN node scripts/load-secrets.mjs && . ./.env.infisical && pnpm run build
|
||||
RUN pnpm run build
|
||||
|
||||
FROM node:22-slim
|
||||
|
||||
@@ -41,4 +34,4 @@ COPY --from=build /app/package.json ./package.json
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["sh", "-c", "node scripts/load-secrets.mjs && . ./.env.infisical && node --import ./.output/server/sentry.server.config.mjs .output/server/index.mjs"]
|
||||
CMD ["sh", "-c", "node scripts/load-secrets.mjs && . ./.env.infisical && if [ \"$SENTRY_ENABLED\" = \"false\" ] || [ ! -f ./.output/server/sentry.server.config.mjs ]; then node .output/server/index.mjs; else node --import ./.output/server/sentry.server.config.mjs .output/server/index.mjs; fi"]
|
||||
|
||||
@@ -36,6 +36,104 @@
|
||||
--noise: 0;
|
||||
}
|
||||
|
||||
@layer components {
|
||||
/* ── Three-tier glass system (Apple-style glassmorphism) ── */
|
||||
|
||||
/* Tier 1 — lightest underlay, large panels / sidebars */
|
||||
.glass-underlay {
|
||||
background: rgba(255, 255, 255, 0.34);
|
||||
box-shadow:
|
||||
0 16px 44px rgba(24, 20, 12, 0.11),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.4);
|
||||
backdrop-filter: blur(18px);
|
||||
-webkit-backdrop-filter: blur(18px);
|
||||
}
|
||||
|
||||
/* Tier 2 — medium capsule, nav pills / search bar */
|
||||
.glass-capsule {
|
||||
background: rgba(255, 255, 255, 0.56);
|
||||
box-shadow:
|
||||
0 8px 24px rgba(24, 20, 12, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.56);
|
||||
backdrop-filter: blur(22px);
|
||||
-webkit-backdrop-filter: blur(22px);
|
||||
}
|
||||
|
||||
/* Tier 3 — densest chip, small tags / badges */
|
||||
.glass-chip {
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.62);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
}
|
||||
|
||||
/* Legacy aliases — keep backward compat during transition */
|
||||
.glass-soft {
|
||||
background: rgba(255, 255, 255, 0.34);
|
||||
box-shadow:
|
||||
0 16px 44px rgba(24, 20, 12, 0.11),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.4);
|
||||
backdrop-filter: blur(18px);
|
||||
-webkit-backdrop-filter: blur(18px);
|
||||
}
|
||||
|
||||
.glass-bright {
|
||||
background: rgba(255, 255, 255, 0.56);
|
||||
box-shadow:
|
||||
0 8px 24px rgba(24, 20, 12, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.56);
|
||||
backdrop-filter: blur(22px);
|
||||
-webkit-backdrop-filter: blur(22px);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Header glass: two-layer Apple-style glassmorphism ── */
|
||||
|
||||
.header-glass {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Layer 1: frosted bar backdrop — fades to transparent at bottom */
|
||||
.header-glass-backdrop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
height: 350%;
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(180%);
|
||||
backdrop-filter: blur(16px) saturate(180%);
|
||||
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 20%, rgba(0,0,0,0.4) 40%, rgba(0,0,0,0.1) 65%, transparent 100%);
|
||||
mask-image: linear-gradient(to bottom, black 0%, black 20%, rgba(0,0,0,0.4) 40%, rgba(0,0,0,0.1) 65%, transparent 100%);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* Layer 2: capsule pills — denser frosted glass with inner shine */
|
||||
.pill-glass {
|
||||
position: relative;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
box-shadow:
|
||||
0 8px 32px rgba(31, 38, 135, 0.2),
|
||||
inset 0 4px 20px rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
/* Inner shine highlight — liquid glass refraction */
|
||||
.pill-glass::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: inherit;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
box-shadow:
|
||||
inset -10px -8px 0 -11px rgba(255, 255, 255, 1),
|
||||
inset 0 -9px 0 -8px rgba(255, 255, 255, 1);
|
||||
opacity: 0.6;
|
||||
filter: blur(1px) brightness(115%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@plugin "daisyui/theme" {
|
||||
name: "silk";
|
||||
default: false;
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './BankSearchRussia.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'BankSearchRussia',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -47,13 +47,22 @@ interface BankData {
|
||||
correspondentAccount: string
|
||||
}
|
||||
|
||||
interface BankSuggestion {
|
||||
value: string
|
||||
data: {
|
||||
bic: string
|
||||
correspondent_account?: string
|
||||
address?: { value: string }
|
||||
}
|
||||
}
|
||||
|
||||
interface Props {
|
||||
modelValue?: BankData
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: BankData): void
|
||||
(e: 'select', bank: any): void
|
||||
(e: 'select', bank: BankSuggestion): void
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -67,14 +76,14 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const query = ref('')
|
||||
const suggestions = ref([])
|
||||
const suggestions = ref<BankSuggestion[]>([])
|
||||
const loading = ref(false)
|
||||
const showDropdown = ref(false)
|
||||
|
||||
// Hide dropdown when clicking outside
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!e.target?.closest('.relative')) {
|
||||
document.addEventListener('click', (e: MouseEvent) => {
|
||||
if (!(e.target as HTMLElement)?.closest('.relative')) {
|
||||
showDropdown.value = false
|
||||
}
|
||||
})
|
||||
@@ -114,7 +123,7 @@ const onInput = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const selectBank = (bank: any) => {
|
||||
const selectBank = (bank: BankSuggestion) => {
|
||||
query.value = bank.value
|
||||
showDropdown.value = false
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ const breadcrumbs = computed(() => {
|
||||
let currentPath = '/clientarea'
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
const segment = segments[i]
|
||||
if (!segment) continue
|
||||
currentPath += `/${segment}`
|
||||
const isLast = i === segments.length - 1
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './CalcResultContent.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'CalcResultContent',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -18,14 +18,17 @@
|
||||
<!-- Results -->
|
||||
<div v-else-if="productRouteOptions.length > 0" class="space-y-4">
|
||||
<OfferResultCard
|
||||
v-for="option in productRouteOptions"
|
||||
:key="option.sourceUuid"
|
||||
v-for="(option, index) in productRouteOptions"
|
||||
:key="option.sourceUuid ?? index"
|
||||
:supplier-name="getSupplierName(option.sourceUuid)"
|
||||
:location-name="getOfferData(option.sourceUuid)?.locationName"
|
||||
:product-name="productName"
|
||||
:price-per-unit="getOfferData(option.sourceUuid)?.pricePerUnit"
|
||||
:price-per-unit="parseFloat(getOfferData(option.sourceUuid)?.pricePerUnit || '0') || null"
|
||||
:quantity="getOfferData(option.sourceUuid)?.quantity"
|
||||
:currency="getOfferData(option.sourceUuid)?.currency"
|
||||
:unit="getOfferData(option.sourceUuid)?.unit"
|
||||
:stages="getRouteStages(option)"
|
||||
:total-time-seconds="option.routes?.[0]?.totalTimeSeconds ?? null"
|
||||
:kyc-profile-uuid="getKycProfileUuid(option.sourceUuid)"
|
||||
@select="navigateToOffer(option.sourceUuid)"
|
||||
/>
|
||||
@@ -64,9 +67,25 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { GetOffersByHubDocument } from '~/composables/graphql/public/geo-generated'
|
||||
import { GetNodeDocument, NearestOffersDocument } from '~/composables/graphql/public/geo-generated'
|
||||
import type { RouteStageItem } from '~/components/RouteStagesList.vue'
|
||||
import { GetOfferDocument, GetSupplierProfileByTeamDocument } from '~/composables/graphql/public/exchange-generated'
|
||||
|
||||
interface RouteStage {
|
||||
fromUuid?: string | null
|
||||
fromName?: string | null
|
||||
toName?: string | null
|
||||
distanceKm?: number | null
|
||||
travelTimeSeconds?: number | null
|
||||
transportType?: string | null
|
||||
}
|
||||
|
||||
interface RoutePathType {
|
||||
totalDistanceKm?: number | null
|
||||
totalTimeSeconds?: number | null
|
||||
stages?: (RouteStage | null)[]
|
||||
}
|
||||
import { GetOfferDocument, GetSupplierProfileByTeamDocument, type GetOfferQueryResult, type GetSupplierProfileByTeamQueryResult } from '~/composables/graphql/public/exchange-generated'
|
||||
import type { OfferWithRoute, RouteStage } from '~/composables/graphql/public/geo-generated'
|
||||
|
||||
const route = useRoute()
|
||||
const localePath = useLocalePath()
|
||||
@@ -75,12 +94,14 @@ const { execute } = useGraphQL()
|
||||
|
||||
const productName = computed(() => searchStore.searchForm.product || (route.query.product as string) || 'Товар')
|
||||
const locationName = computed(() => searchStore.searchForm.location || (route.query.location as string) || 'Назначение')
|
||||
const quantity = computed(() => (route.query.quantity as string) || (searchStore.searchForm as any)?.quantity)
|
||||
const quantity = computed(() => (route.query.quantity as string) || searchStore.searchForm.quantity)
|
||||
|
||||
// Offer data for prices
|
||||
const offersData = ref<Map<string, any>>(new Map())
|
||||
type OfferData = NonNullable<GetOfferQueryResult['getOffer']>
|
||||
const offersData = ref<Map<string, OfferData>>(new Map())
|
||||
// Supplier data for KYC profile UUID (by team_uuid)
|
||||
const suppliersData = ref<Map<string, any>>(new Map())
|
||||
type SupplierData = NonNullable<GetSupplierProfileByTeamQueryResult['getSupplierProfileByTeam']>
|
||||
const suppliersData = ref<Map<string, SupplierData>>(new Map())
|
||||
|
||||
const summaryTitle = computed(() => `${productName.value} → ${locationName.value}`)
|
||||
const summaryMeta = computed(() => {
|
||||
@@ -106,17 +127,46 @@ type ProductRouteOption = {
|
||||
|
||||
const fetchOffersByHub = async () => {
|
||||
if (!productUuid.value || !destinationUuid.value) return null
|
||||
const { client } = useApolloClient('publicGeo')
|
||||
|
||||
const { data } = await client.query({
|
||||
query: GetOffersByHubDocument,
|
||||
variables: {
|
||||
hubUuid: destinationUuid.value,
|
||||
// 1. Get hub node to get coordinates
|
||||
const hubData = await execute(GetNodeDocument, { uuid: destinationUuid.value }, 'public', 'geo')
|
||||
const hub = hubData?.node
|
||||
|
||||
if (!hub?.latitude || !hub?.longitude) {
|
||||
console.warn('Hub has no coordinates')
|
||||
return null
|
||||
}
|
||||
|
||||
// 2. Find offers near hub for this product WITH routes calculated on backend
|
||||
const offersResponse = await execute(
|
||||
NearestOffersDocument,
|
||||
{
|
||||
lat: hub.latitude,
|
||||
lon: hub.longitude,
|
||||
productUuid: productUuid.value,
|
||||
hubUuid: destinationUuid.value, // Pass hubUuid to get routes calculated on backend
|
||||
radius: 500,
|
||||
limit: 5
|
||||
}
|
||||
})
|
||||
return data
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
)
|
||||
|
||||
const offers = offersResponse?.nearestOffers || []
|
||||
|
||||
// Offers already include routes from backend
|
||||
const offersWithRoutes = offers
|
||||
.filter((offer): offer is NonNullable<OfferWithRoute> => offer !== null)
|
||||
.map((offer) => ({
|
||||
sourceUuid: offer.uuid,
|
||||
sourceName: offer.productName,
|
||||
sourceLat: offer.latitude,
|
||||
sourceLon: offer.longitude,
|
||||
distanceKm: offer.distanceKm,
|
||||
routes: offer.routes || []
|
||||
}))
|
||||
|
||||
return { offersByHub: offersWithRoutes }
|
||||
}
|
||||
|
||||
const { data: productRoutesData, pending, error } = await useAsyncData(
|
||||
@@ -135,7 +185,7 @@ const productRouteOptions = computed(() => {
|
||||
return options?.filter(Boolean) || []
|
||||
})
|
||||
|
||||
const legacyRoutes = computed(() => {
|
||||
const legacyRoutes = computed<RoutePathType[]>(() => {
|
||||
return [] // Legacy routes removed
|
||||
})
|
||||
|
||||
@@ -156,10 +206,14 @@ const mapRouteStages = (route: RoutePathType): RouteStageItem[] => {
|
||||
const getRouteStages = (option: ProductRouteOption) => {
|
||||
const route = option.routes?.[0]
|
||||
if (!route?.stages) return []
|
||||
return route.stages.filter(Boolean).map((stage: any) => ({
|
||||
transportType: stage?.transportType,
|
||||
distanceKm: stage?.distanceKm
|
||||
}))
|
||||
return route.stages
|
||||
.filter((stage): stage is NonNullable<RouteStage> => stage !== null)
|
||||
.map((stage) => ({
|
||||
transportType: stage.transportType,
|
||||
distanceKm: stage.distanceKm,
|
||||
travelTimeSeconds: stage.travelTimeSeconds,
|
||||
fromName: stage.fromName
|
||||
}))
|
||||
}
|
||||
|
||||
// Get offer data for card
|
||||
@@ -177,6 +231,14 @@ const getKycProfileUuid = (offerUuid?: string | null) => {
|
||||
return supplier?.kycProfileUuid || null
|
||||
}
|
||||
|
||||
const getSupplierName = (offerUuid?: string | null) => {
|
||||
if (!offerUuid) return null
|
||||
const offer = offersData.value.get(offerUuid)
|
||||
if (!offer?.teamUuid) return null
|
||||
const supplier = suppliersData.value.get(offer.teamUuid)
|
||||
return supplier?.name || null
|
||||
}
|
||||
|
||||
// Navigate to offer detail page
|
||||
const navigateToOffer = (offerUuid?: string | null) => {
|
||||
if (!offerUuid) return
|
||||
@@ -191,8 +253,8 @@ const loadOfferDetails = async (options: ProductRouteOption[]) => {
|
||||
return
|
||||
}
|
||||
|
||||
const newOffersData = new Map<string, any>()
|
||||
const newSuppliersData = new Map<string, any>()
|
||||
const newOffersData = new Map<string, OfferData>()
|
||||
const newSuppliersData = new Map<string, SupplierData>()
|
||||
const teamUuidsToLoad = new Set<string>()
|
||||
|
||||
// First, load all offers
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './CompanyCard.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'CompanyCard',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './CompanySearchRussia.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'CompanySearchRussia',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -48,13 +48,24 @@ interface CompanyData {
|
||||
address: string
|
||||
}
|
||||
|
||||
interface CompanySuggestion {
|
||||
value: string
|
||||
unrestricted_value: string
|
||||
data: {
|
||||
inn: string
|
||||
kpp?: string
|
||||
ogrn?: string
|
||||
address?: { value: string }
|
||||
}
|
||||
}
|
||||
|
||||
interface Props {
|
||||
modelValue?: CompanyData
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: CompanyData): void
|
||||
(e: 'select', company: any): void
|
||||
(e: 'select', company: CompanySuggestion): void
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -71,14 +82,14 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const query = ref('')
|
||||
const suggestions = ref([])
|
||||
const suggestions = ref<CompanySuggestion[]>([])
|
||||
const loading = ref(false)
|
||||
const showDropdown = ref(false)
|
||||
|
||||
// Hide dropdown when clicking outside
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!e.target?.closest('.relative')) {
|
||||
document.addEventListener('click', (e: MouseEvent) => {
|
||||
if (!(e.target as HTMLElement)?.closest('.relative')) {
|
||||
showDropdown.value = false
|
||||
}
|
||||
})
|
||||
@@ -118,10 +129,10 @@ const onInput = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const selectCompany = (company: any) => {
|
||||
const selectCompany = (company: CompanySuggestion) => {
|
||||
query.value = company.value
|
||||
showDropdown.value = false
|
||||
|
||||
|
||||
const companyData: CompanyData = {
|
||||
companyName: company.value,
|
||||
companyFullName: company.unrestricted_value,
|
||||
@@ -130,7 +141,7 @@ const selectCompany = (company: any) => {
|
||||
ogrn: company.data.ogrn || '',
|
||||
address: company.data.address?.value || ''
|
||||
}
|
||||
|
||||
|
||||
emit('update:modelValue', companyData)
|
||||
emit('select', company)
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './FooterPublic.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'FooterPublic',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './GanttTimeline.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'GanttTimeline',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './GoodsContent.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'GoodsContent',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -24,25 +24,27 @@
|
||||
|
||||
<Grid v-else :cols="1" :md="2" :lg="3" :gap="4">
|
||||
<ProductCard
|
||||
v-for="product in productsData"
|
||||
:key="product.uuid"
|
||||
:product="product"
|
||||
v-for="(product, index) in productsData"
|
||||
:key="product?.uuid ?? index"
|
||||
:product="product!"
|
||||
selectable
|
||||
@select="selectProduct(product)"
|
||||
@select="selectProduct(product!)"
|
||||
/>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { GetProductsDocument } from '~/composables/graphql/public/exchange-generated'
|
||||
import { GetProductsDocument, type GetProductsQueryResult } from '~/composables/graphql/public/exchange-generated'
|
||||
|
||||
type Product = NonNullable<NonNullable<GetProductsQueryResult['getProducts']>[number]>
|
||||
|
||||
const searchStore = useSearchStore()
|
||||
|
||||
const { data, pending, error, refresh } = await useServerQuery('products', GetProductsDocument, {}, 'public', 'exchange')
|
||||
const productsData = computed(() => data.value?.getProducts || [])
|
||||
|
||||
const selectProduct = (product: any) => {
|
||||
const selectProduct = (product: Product) => {
|
||||
searchStore.setProduct(product.name)
|
||||
searchStore.setProductUuid(product.uuid)
|
||||
const locationUuid = searchStore.searchForm.locationUuid
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './KYCFormRussia.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'KYCFormRussia',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -154,10 +154,44 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface KycSubmitData {
|
||||
company_name: string
|
||||
company_full_name: string
|
||||
inn: string
|
||||
kpp: string
|
||||
ogrn: string
|
||||
address: string
|
||||
bank_name: string
|
||||
bik: string
|
||||
correspondent_account: string
|
||||
contact_person: string
|
||||
contact_email: string
|
||||
contact_phone: string
|
||||
}
|
||||
|
||||
interface CompanySuggestion {
|
||||
value: string
|
||||
unrestricted_value: string
|
||||
data: {
|
||||
inn: string
|
||||
kpp?: string
|
||||
ogrn?: string
|
||||
address?: { value: string }
|
||||
}
|
||||
}
|
||||
|
||||
interface BankSuggestion {
|
||||
value: string
|
||||
data: {
|
||||
bic: string
|
||||
correspondent_account?: string
|
||||
}
|
||||
}
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const emit = defineEmits<{
|
||||
submit: [data: any]
|
||||
submit: [data: KycSubmitData]
|
||||
}>()
|
||||
|
||||
const loading = ref(false)
|
||||
@@ -195,7 +229,7 @@ const isFormValid = computed(() => {
|
||||
})
|
||||
|
||||
// Handlers
|
||||
const onCompanySelect = (company: any) => {
|
||||
const onCompanySelect = (company: CompanySuggestion) => {
|
||||
formData.value.company = {
|
||||
companyName: company.value,
|
||||
companyFullName: company.unrestricted_value,
|
||||
@@ -206,7 +240,7 @@ const onCompanySelect = (company: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
const onBankSelect = (bank: any) => {
|
||||
const onBankSelect = (bank: BankSuggestion) => {
|
||||
formData.value.bank = {
|
||||
bankName: bank.value,
|
||||
bik: bank.data.bic,
|
||||
|
||||
@@ -112,8 +112,8 @@ const profileData = ref<{
|
||||
address?: string | null
|
||||
director?: string | null
|
||||
capital?: string | null
|
||||
activities?: string[] | null
|
||||
sources?: string[] | null
|
||||
activities?: (string | null)[] | null
|
||||
sources?: (string | null)[] | null
|
||||
lastUpdated?: string | null
|
||||
} | null>(null)
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './LangSwitcher.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'LangSwitcher',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './LocationsContent.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'LocationsContent',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
<Grid :cols="1" :md="2" :lg="3" :gap="4">
|
||||
<Card
|
||||
v-for="addr in teamAddresses"
|
||||
:key="addr.uuid"
|
||||
v-for="(addr, index) in teamAddresses"
|
||||
:key="addr.uuid ?? index"
|
||||
padding="small"
|
||||
interactive
|
||||
@click="selectTeamAddress(addr)"
|
||||
@@ -57,8 +57,8 @@
|
||||
|
||||
<Grid v-else :cols="1" :md="2" :lg="3" :gap="4">
|
||||
<HubCard
|
||||
v-for="location in locationsData"
|
||||
:key="location.uuid"
|
||||
v-for="(location, index) in locationsData"
|
||||
:key="location.uuid ?? index"
|
||||
:hub="location"
|
||||
selectable
|
||||
@select="selectLocation(location)"
|
||||
@@ -69,7 +69,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { GetNodesDocument } from '~/composables/graphql/public/geo-generated'
|
||||
import { HubsListDocument, type HubsListQueryResult } from '~/composables/graphql/public/geo-generated'
|
||||
|
||||
type HubItem = NonNullable<NonNullable<HubsListQueryResult['hubsList']>[number]>
|
||||
type HubWithDistance = HubItem & { distance?: string }
|
||||
|
||||
interface TeamAddress {
|
||||
uuid?: string | null
|
||||
name?: string | null
|
||||
address?: string | null
|
||||
isDefault?: boolean | null
|
||||
}
|
||||
|
||||
const { t } = useI18n()
|
||||
const searchStore = useSearchStore()
|
||||
@@ -84,36 +94,38 @@ const calculateDistance = (lat: number, lng: number) => {
|
||||
}
|
||||
|
||||
// Load logistics hubs
|
||||
const { data: locationsDataRaw, pending, error, refresh } = await useServerQuery('locations', GetNodesDocument, {}, 'public', 'geo')
|
||||
const locationsData = computed(() => {
|
||||
return (locationsDataRaw.value || []).map((location: any) => ({
|
||||
...location,
|
||||
distance: location?.latitude && location?.longitude
|
||||
? calculateDistance(location.latitude, location.longitude)
|
||||
: undefined,
|
||||
}))
|
||||
const { data: locationsDataRaw, pending, error, refresh } = await useServerQuery('locations', HubsListDocument, { limit: 100 }, 'public', 'geo')
|
||||
const locationsData = computed<HubWithDistance[]>(() => {
|
||||
return (locationsDataRaw.value?.hubsList || [])
|
||||
.filter((location): location is HubItem => location !== null)
|
||||
.map((location) => ({
|
||||
...location,
|
||||
distance: location.latitude && location.longitude
|
||||
? calculateDistance(location.latitude, location.longitude)
|
||||
: undefined,
|
||||
}))
|
||||
})
|
||||
|
||||
// Load team addresses (if authenticated)
|
||||
const teamAddresses = ref<any[]>([])
|
||||
const teamAddresses = ref<TeamAddress[]>([])
|
||||
|
||||
if (isAuthenticated.value) {
|
||||
try {
|
||||
const { GetTeamAddressesDocument } = await import('~/composables/graphql/team/teams-generated')
|
||||
const { data: addressData } = await useServerQuery('locations-team-addresses', GetTeamAddressesDocument, {}, 'team', 'teams')
|
||||
teamAddresses.value = addressData.value?.teamAddresses || []
|
||||
teamAddresses.value = (addressData.value?.teamAddresses || []).filter((a): a is NonNullable<typeof a> => a !== null)
|
||||
} catch (e) {
|
||||
console.log('Team addresses not available')
|
||||
}
|
||||
}
|
||||
|
||||
const selectLocation = (location: any) => {
|
||||
const selectLocation = (location: HubWithDistance) => {
|
||||
searchStore.setLocation(location.name)
|
||||
searchStore.setLocationUuid(location.uuid)
|
||||
history.back()
|
||||
}
|
||||
|
||||
const selectTeamAddress = (addr: any) => {
|
||||
const selectTeamAddress = (addr: TeamAddress) => {
|
||||
searchStore.setLocation(addr.address)
|
||||
searchStore.setLocationUuid(addr.uuid)
|
||||
history.back()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<!-- Header with back button -->
|
||||
<div class="p-4 border-b border-base-300">
|
||||
<NuxtLink
|
||||
:to="localePath('/catalog')"
|
||||
:to="localePath('/catalog?select=product')"
|
||||
class="btn btn-sm btn-ghost gap-2"
|
||||
>
|
||||
<Icon name="lucide:arrow-left" size="18" />
|
||||
@@ -52,8 +52,8 @@
|
||||
<!-- Hubs Tab -->
|
||||
<div v-else-if="activeTab === 'hubs'" class="space-y-2">
|
||||
<HubCard
|
||||
v-for="hub in hubs"
|
||||
:key="hub.uuid"
|
||||
v-for="(hub, index) in hubs"
|
||||
:key="hub.uuid ?? index"
|
||||
:hub="hub"
|
||||
selectable
|
||||
:is-selected="selectedItemId === hub.uuid"
|
||||
@@ -67,8 +67,8 @@
|
||||
<!-- Suppliers Tab -->
|
||||
<div v-else-if="activeTab === 'suppliers'" class="space-y-2">
|
||||
<SupplierCard
|
||||
v-for="supplier in suppliers"
|
||||
:key="supplier.uuid"
|
||||
v-for="(supplier, index) in suppliers"
|
||||
:key="supplier.uuid ?? index"
|
||||
:supplier="supplier"
|
||||
selectable
|
||||
:is-selected="selectedItemId === supplier.uuid"
|
||||
@@ -81,15 +81,20 @@
|
||||
|
||||
<!-- Offers Tab -->
|
||||
<div v-else-if="activeTab === 'offers'" class="space-y-2">
|
||||
<OfferCard
|
||||
v-for="offer in offers"
|
||||
:key="offer.uuid"
|
||||
:offer="offer"
|
||||
selectable
|
||||
:is-selected="selectedItemId === offer.uuid"
|
||||
<OfferResultCard
|
||||
v-for="(offer, index) in offersWithPrice"
|
||||
:key="offer.uuid ?? index"
|
||||
:supplier-name="offer.supplierName"
|
||||
:location-name="offer.locationName || offer.locationCountry"
|
||||
:product-name="offer.productName"
|
||||
:price-per-unit="offer.pricePerUnit ? Number(offer.pricePerUnit) : null"
|
||||
:quantity="offer.quantity"
|
||||
:currency="offer.currency"
|
||||
:unit="offer.unit"
|
||||
:stages="[]"
|
||||
@select="$emit('select', offer, 'offer')"
|
||||
/>
|
||||
<div v-if="offers.length === 0" class="text-center text-base-content/50 py-8">
|
||||
<div v-if="offersWithPrice.length === 0" class="text-center text-base-content/50 py-8">
|
||||
{{ t('catalogMap.empty.offers') }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -98,20 +103,63 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
interface Hub {
|
||||
uuid?: string | null
|
||||
name?: string | null
|
||||
country?: string | null
|
||||
countryCode?: string | null
|
||||
distance?: string
|
||||
transportTypes?: (string | null)[] | null
|
||||
}
|
||||
|
||||
interface Supplier {
|
||||
uuid?: string | null
|
||||
teamUuid?: string | null
|
||||
name?: string | null
|
||||
country?: string | null
|
||||
countryCode?: string | null
|
||||
logo?: string | null
|
||||
onTimeRate?: number | null
|
||||
offersCount?: number | null
|
||||
isVerified?: boolean | null
|
||||
}
|
||||
|
||||
interface Offer {
|
||||
uuid?: string | null
|
||||
productUuid?: string | null
|
||||
productName?: string | null
|
||||
categoryName?: string | null
|
||||
supplierName?: string | null
|
||||
locationUuid?: string | null
|
||||
locationName?: string | null
|
||||
locationCountry?: string | null
|
||||
locationCountryCode?: string | null
|
||||
quantity?: number | string | null
|
||||
unit?: string | null
|
||||
pricePerUnit?: number | string | null
|
||||
currency?: string | null
|
||||
status?: string | null
|
||||
validUntil?: string | null
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
activeTab: 'hubs' | 'suppliers' | 'offers'
|
||||
hubs: any[]
|
||||
suppliers: any[]
|
||||
offers: any[]
|
||||
hubs: Hub[]
|
||||
suppliers: Supplier[]
|
||||
offers: Offer[]
|
||||
selectedItemId: string | null
|
||||
isLoading: boolean
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
'update:activeTab': [tab: 'hubs' | 'suppliers' | 'offers']
|
||||
'select': [item: any, type: string]
|
||||
'select': [item: Hub | Supplier | Offer, type: 'hub' | 'supplier' | 'offer']
|
||||
}>()
|
||||
|
||||
const localePath = useLocalePath()
|
||||
const { t } = useI18n()
|
||||
|
||||
const offersWithPrice = computed(() =>
|
||||
(props.offers || []).filter(o => o?.pricePerUnit != null)
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './MapboxGlobe.client.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'MapboxGlobe.client',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -228,15 +228,16 @@ const onMapCreated = (map: MapboxMap) => {
|
||||
// Click on cluster to zoom in
|
||||
map.on('click', 'clusters', (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: ['clusters'] })
|
||||
if (!features.length) return
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
|
||||
const clusterId = features[0].properties?.cluster_id
|
||||
const clusterId = feature.properties?.cluster_id
|
||||
const source = map.getSource('locations') as mapboxgl.GeoJSONSource
|
||||
|
||||
source.getClusterExpansionZoom(clusterId, (err, zoom) => {
|
||||
if (err) return
|
||||
|
||||
const geometry = features[0].geometry as GeoJSON.Point
|
||||
const geometry = feature.geometry as GeoJSON.Point
|
||||
map.easeTo({
|
||||
center: geometry.coordinates as [number, number],
|
||||
zoom: zoom || 4
|
||||
@@ -247,10 +248,11 @@ const onMapCreated = (map: MapboxMap) => {
|
||||
// Click on individual point
|
||||
map.on('click', 'unclustered-point', (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: ['unclustered-point'] })
|
||||
if (!features.length) return
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
|
||||
const featureProps = features[0].properties
|
||||
const geometry = features[0].geometry as GeoJSON.Point
|
||||
const featureProps = feature.properties
|
||||
const geometry = feature.geometry as GeoJSON.Point
|
||||
|
||||
const location: Location = {
|
||||
uuid: featureProps?.uuid,
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
</div>
|
||||
<Stack v-if="autoEdges.length > 0" gap="2">
|
||||
<NuxtLink
|
||||
v-for="edge in autoEdges"
|
||||
:key="edge.toUuid"
|
||||
v-for="(edge, index) in autoEdges"
|
||||
:key="edge.toUuid ?? index"
|
||||
:to="localePath(`/catalog/hubs/${edge.toUuid}`)"
|
||||
class="flex flex-col gap-2 p-3 rounded-lg border border-base-300 hover:bg-base-200 transition-colors"
|
||||
>
|
||||
@@ -70,8 +70,8 @@
|
||||
</div>
|
||||
<Stack v-if="railEdges.length > 0" gap="2">
|
||||
<NuxtLink
|
||||
v-for="edge in railEdges"
|
||||
:key="edge.toUuid"
|
||||
v-for="(edge, index) in railEdges"
|
||||
:key="edge.toUuid ?? index"
|
||||
:to="localePath(`/catalog/hubs/${edge.toUuid}`)"
|
||||
class="flex flex-col gap-2 p-3 rounded-lg border border-base-300 hover:bg-base-200 transition-colors"
|
||||
>
|
||||
@@ -104,7 +104,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { Map as MapboxMapType } from 'mapbox-gl'
|
||||
import { LngLatBounds, Popup } from 'mapbox-gl'
|
||||
import type { EdgeType } from '~/composables/graphql/public/geo-generated'
|
||||
import type { Edge } from '~/composables/graphql/public/geo-generated'
|
||||
|
||||
interface CurrentHub {
|
||||
uuid: string
|
||||
@@ -119,8 +119,8 @@ interface RouteGeometry {
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
autoEdges: EdgeType[]
|
||||
railEdges: EdgeType[]
|
||||
autoEdges: Edge[]
|
||||
railEdges: Edge[]
|
||||
hub: CurrentHub
|
||||
railHub: CurrentHub
|
||||
autoRouteGeometries: RouteGeometry[]
|
||||
@@ -190,7 +190,7 @@ const buildRouteFeatureCollection = (routes: RouteGeometry[], transportType: 'au
|
||||
}))
|
||||
})
|
||||
|
||||
const buildNeighborsFeatureCollection = (edges: EdgeType[], transportType: 'auto' | 'rail') => ({
|
||||
const buildNeighborsFeatureCollection = (edges: Edge[], transportType: 'auto' | 'rail') => ({
|
||||
type: 'FeatureCollection' as const,
|
||||
features: edges
|
||||
.filter(e => e.toLatitude && e.toLongitude)
|
||||
@@ -292,8 +292,10 @@ const addHubSource = (map: MapboxMapType, id: string, hub: CurrentHub, color: st
|
||||
})
|
||||
|
||||
map.on('click', `${id}-circle`, (e) => {
|
||||
const coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const name = e.features![0].properties?.name
|
||||
const feature = e.features?.[0]
|
||||
if (!feature) return
|
||||
const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const name = feature.properties?.name
|
||||
|
||||
new Popup()
|
||||
.setLngLat(coordinates)
|
||||
@@ -390,8 +392,10 @@ const onMapCreated = (map: MapboxMapType) => {
|
||||
})
|
||||
|
||||
const onNeighborsClick = (e: mapboxgl.MapLayerMouseEvent) => {
|
||||
const coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const featureProps = e.features![0].properties
|
||||
const feature = e.features?.[0]
|
||||
if (!feature) return
|
||||
const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const featureProps = feature.properties
|
||||
const name = featureProps?.name
|
||||
const distanceKm = featureProps?.distanceKm
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
<div class="order-1 lg:order-2">
|
||||
<Stack gap="2">
|
||||
<NuxtLink
|
||||
v-for="edge in edges"
|
||||
:key="edge.toUuid"
|
||||
v-for="(edge, index) in edges"
|
||||
:key="edge.toUuid ?? index"
|
||||
:to="localePath(`/catalog/hubs/${edge.toUuid}`)"
|
||||
class="flex flex-col gap-2 p-3 rounded-lg border border-base-300 hover:bg-base-200 transition-colors"
|
||||
>
|
||||
@@ -66,7 +66,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { Map as MapboxMapType } from 'mapbox-gl'
|
||||
import { LngLatBounds, Popup } from 'mapbox-gl'
|
||||
import type { EdgeType } from '~/composables/graphql/public/geo-generated'
|
||||
import type { Edge } from '~/composables/graphql/public/geo-generated'
|
||||
|
||||
interface CurrentHub {
|
||||
uuid: string
|
||||
@@ -81,7 +81,7 @@ interface RouteGeometry {
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
edges: EdgeType[]
|
||||
edges: Edge[]
|
||||
currentHub: CurrentHub
|
||||
routeGeometries: RouteGeometry[]
|
||||
transportType: 'auto' | 'rail'
|
||||
@@ -304,8 +304,10 @@ const onMapCreated = (map: MapboxMapType) => {
|
||||
|
||||
// Popups on click
|
||||
map.on('click', 'current-hub-circle', (e) => {
|
||||
const coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const name = e.features![0].properties?.name
|
||||
const feature = e.features?.[0]
|
||||
if (!feature) return
|
||||
const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const name = feature.properties?.name
|
||||
|
||||
new Popup()
|
||||
.setLngLat(coordinates)
|
||||
@@ -314,8 +316,10 @@ const onMapCreated = (map: MapboxMapType) => {
|
||||
})
|
||||
|
||||
map.on('click', 'neighbors-circles', (e) => {
|
||||
const coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const featureProps = e.features![0].properties
|
||||
const feature = e.features?.[0]
|
||||
if (!feature) return
|
||||
const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const featureProps = feature.properties
|
||||
const name = featureProps?.name
|
||||
const distanceKm = featureProps?.distanceKm
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './NovuNotificationBell.client.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'NovuNotificationBell.client',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './OrderCalendar.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'OrderCalendar',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './OrderMap.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'OrderMap',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './OrderTimeline.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'OrderTimeline',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -120,7 +120,7 @@ const fetchRouteGeometry = async (stage: RouteStage): Promise<[number, number][]
|
||||
fromLon: stage.fromLon,
|
||||
toLat: stage.toLat,
|
||||
toLon: stage.toLon
|
||||
}, 'public', 'geo')
|
||||
}, 'public', 'geo') as Record<string, any>
|
||||
|
||||
const geometry = routeData?.[routeField]?.geometry
|
||||
if (typeof geometry === 'string') {
|
||||
@@ -363,13 +363,15 @@ const onMapCreated = (map: MapboxMapType) => {
|
||||
|
||||
// Click on marker
|
||||
map.on('click', 'orders-markers-circles', (e) => {
|
||||
const props = e.features?.[0]?.properties
|
||||
const feature = e.features?.[0]
|
||||
if (!feature) return
|
||||
const props = feature.properties
|
||||
const orderId = props?.orderId
|
||||
if (orderId) {
|
||||
emit('select-order', orderId)
|
||||
}
|
||||
|
||||
const coordinates = (e.features?.[0].geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
new Popup()
|
||||
.setLngLat(coordinates)
|
||||
.setHTML(`<strong>${props?.name || 'Point'}</strong><br/>${props?.orderName || ''}`)
|
||||
|
||||
@@ -90,6 +90,7 @@ const routeMarkers = computed(() => {
|
||||
if (!stages.length) return
|
||||
const first = stages[0]
|
||||
const last = stages[stages.length - 1]
|
||||
if (!first || !last) return
|
||||
|
||||
if (typeof first.fromLat === 'number' && typeof first.fromLon === 'number') {
|
||||
markers.push({
|
||||
@@ -183,7 +184,7 @@ const fetchStageGeometry = async (stage: RouteStage, routeIndex: number, stageIn
|
||||
const RouteDocument = stage.transportType === 'auto' ? GetAutoRouteDocument : GetRailRouteDocument
|
||||
const routeField = stage.transportType === 'auto' ? 'autoRoute' : 'railRoute'
|
||||
|
||||
const routeData = await execute(RouteDocument, { fromLat, fromLon, toLat, toLon }, 'public', 'geo')
|
||||
const routeData = await execute(RouteDocument, { fromLat, fromLon, toLat, toLon }, 'public', 'geo') as Record<string, any>
|
||||
const geometry = routeData?.[routeField]?.geometry
|
||||
|
||||
if (typeof geometry === 'string') {
|
||||
@@ -341,8 +342,10 @@ const onMapCreated = (map: MapboxMapType) => {
|
||||
})
|
||||
|
||||
map.on('click', 'request-markers-circles', (e) => {
|
||||
const coordinates = (e.features?.[0].geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const featureProps = e.features?.[0].properties
|
||||
const feature = e.features?.[0]
|
||||
if (!feature) return
|
||||
const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const featureProps = feature.properties
|
||||
const title = featureProps?.name || 'Точка'
|
||||
const label = featureProps?.label || ''
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './RouteMap.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'RouteMap',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<MapboxMap
|
||||
:key="mapId"
|
||||
:map-id="mapId"
|
||||
:style="`height: ${height}px; width: 100%;`"
|
||||
:style="`height: ${heightValue}px; width: 100%;`"
|
||||
class="rounded-lg border border-base-300"
|
||||
:options="mapOptions"
|
||||
@load="onMapCreated"
|
||||
@@ -26,16 +26,46 @@ import type { Map as MapboxMapType } from 'mapbox-gl'
|
||||
import { LngLatBounds, Popup } from 'mapbox-gl'
|
||||
import { getCurrentInstance } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
stages: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 400
|
||||
}
|
||||
})
|
||||
interface StageCompany {
|
||||
uuid?: string | null
|
||||
name?: string | null
|
||||
}
|
||||
|
||||
interface StageTrip {
|
||||
uuid?: string | null
|
||||
company?: StageCompany | null
|
||||
}
|
||||
|
||||
interface RouteStage {
|
||||
uuid?: string | null
|
||||
stageType?: string | null
|
||||
sourceLatitude?: number | null
|
||||
sourceLongitude?: number | null
|
||||
sourceLocationName?: string | null
|
||||
destinationLatitude?: number | null
|
||||
destinationLongitude?: number | null
|
||||
destinationLocationName?: string | null
|
||||
locationLatitude?: number | null
|
||||
locationLongitude?: number | null
|
||||
locationName?: string | null
|
||||
selectedCompany?: StageCompany | null
|
||||
trips?: StageTrip[] | null
|
||||
}
|
||||
|
||||
interface RoutePoint {
|
||||
id: string
|
||||
name: string
|
||||
lat: number
|
||||
lng: number
|
||||
companies: StageCompany[]
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
stages?: RouteStage[]
|
||||
height?: number
|
||||
}>()
|
||||
|
||||
const defaultHeight = 400
|
||||
|
||||
const { t } = useI18n()
|
||||
const mapRef = ref<MapboxMapType | null>(null)
|
||||
@@ -44,10 +74,12 @@ const didFitBounds = ref(false)
|
||||
const instanceId = getCurrentInstance()?.uid || Math.floor(Math.random() * 100000)
|
||||
const mapId = computed(() => `route-map-${instanceId}`)
|
||||
|
||||
const routePoints = computed(() => {
|
||||
const points: Array<{ id: string; name: string; lat: number; lng: number; companies: any[] }> = []
|
||||
const heightValue = computed(() => props.height ?? defaultHeight)
|
||||
|
||||
props.stages.forEach((stage: any) => {
|
||||
const routePoints = computed(() => {
|
||||
const points: RoutePoint[] = []
|
||||
|
||||
props.stages?.forEach((stage: RouteStage) => {
|
||||
if (stage.stageType === 'transport') {
|
||||
if (stage.sourceLatitude && stage.sourceLongitude) {
|
||||
const existingPoint = points.find(p => p.lat === stage.sourceLatitude && p.lng === stage.sourceLongitude)
|
||||
@@ -227,8 +259,10 @@ const onMapCreated = (map: MapboxMapType) => {
|
||||
})
|
||||
|
||||
map.on('click', 'route-points-layer', (e) => {
|
||||
const coordinates = (e.features?.[0].geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const props = e.features?.[0].properties
|
||||
const feature = e.features?.[0]
|
||||
if (!feature) return
|
||||
const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number]
|
||||
const props = feature.properties
|
||||
const name = props?.name || t('routeMap.points.service')
|
||||
|
||||
new Popup()
|
||||
@@ -261,16 +295,16 @@ watch(
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
const getStageCompanies = (stage: any) => {
|
||||
const companies: any[] = []
|
||||
const getStageCompanies = (stage: RouteStage): StageCompany[] => {
|
||||
const companies: StageCompany[] = []
|
||||
|
||||
if (stage.selectedCompany) {
|
||||
companies.push(stage.selectedCompany)
|
||||
}
|
||||
|
||||
const uniqueCompanies = new Set()
|
||||
stage.trips?.forEach((trip: any) => {
|
||||
if (trip.company && !uniqueCompanies.has(trip.company.uuid)) {
|
||||
const uniqueCompanies = new Set<string>()
|
||||
stage.trips?.forEach((trip: StageTrip) => {
|
||||
if (trip.company && trip.company.uuid && !uniqueCompanies.has(trip.company.uuid)) {
|
||||
uniqueCompanies.add(trip.company.uuid)
|
||||
companies.push(trip.company)
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './TeamCard.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'TeamCard',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -40,6 +40,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface TeamMember {
|
||||
id: string
|
||||
userId: string
|
||||
role?: string | null
|
||||
}
|
||||
|
||||
interface Team {
|
||||
id?: string | null
|
||||
name: string
|
||||
createdAt?: string | null
|
||||
members?: TeamMember[] | null
|
||||
}
|
||||
|
||||
interface Props {
|
||||
team: Team
|
||||
}
|
||||
@@ -49,7 +62,7 @@ const membersCount = computed(() => props.team?.members?.length || 1)
|
||||
const displayMembers = computed(() => (props.team?.members || []).slice(0, 3))
|
||||
const remainingMembers = computed(() => Math.max(0, membersCount.value - 3))
|
||||
|
||||
const formatDate = (dateString: string) => {
|
||||
const formatDate = (dateString: string | null | undefined) => {
|
||||
if (!dateString) return ''
|
||||
try {
|
||||
return new Date(dateString).toLocaleDateString('ru-RU')
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './TeamCreateForm.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'TeamCreateForm',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -70,6 +70,7 @@
|
||||
<script setup lang="ts">
|
||||
import { CreateTeamDocument } from '~/composables/graphql/user/teams-generated'
|
||||
|
||||
const { t } = useI18n()
|
||||
const emit = defineEmits(['teamCreated', 'cancel'])
|
||||
|
||||
const teamName = ref('')
|
||||
@@ -93,9 +94,9 @@ const handleSubmit = async () => {
|
||||
emit('teamCreated', result.createTeam?.team)
|
||||
teamName.value = ''
|
||||
teamType.value = 'BUYER'
|
||||
} catch (err: any) {
|
||||
} catch (err: unknown) {
|
||||
hasError.value = true
|
||||
error.value = err?.message || $t('teams.errors.create_failed')
|
||||
error.value = err instanceof Error ? err.message : t('teams.errors.create_failed')
|
||||
console.error('Error creating team:', err)
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './TimelineStages.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'TimelineStages',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './TripBadge.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'TripBadge',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './UserAvatar.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'UserAvatar',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
159
app/components/ai/AiChatSidebar.vue
Normal file
159
app/components/ai/AiChatSidebar.vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<aside
|
||||
class="fixed top-0 left-0 bottom-0 z-50 overflow-hidden transition-[width] duration-300"
|
||||
:style="{ width: open ? width : '0px' }"
|
||||
aria-label="AI assistant"
|
||||
>
|
||||
<div
|
||||
class="h-full flex flex-col bg-base-100/80 backdrop-blur-xl border-r border-white/10 shadow-xl transition-opacity duration-200"
|
||||
:class="open ? 'opacity-100' : 'opacity-0 pointer-events-none'"
|
||||
>
|
||||
<div class="flex items-center justify-between px-4 py-3 border-b border-white/10">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-8 h-8 rounded-full bg-primary/20 flex items-center justify-center">
|
||||
<Icon name="lucide:bot" size="16" class="text-primary" />
|
||||
</div>
|
||||
<div class="font-semibold text-base-content">{{ $t('aiAssistants.view.agentName') }}</div>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-ghost btn-xs btn-circle text-base-content/60 hover:text-base-content"
|
||||
aria-label="Close"
|
||||
@click="emit('close')"
|
||||
>
|
||||
<Icon name="lucide:x" size="14" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div ref="chatContainer" class="flex-1 overflow-y-auto p-4 space-y-3">
|
||||
<div
|
||||
v-for="(message, idx) in chat"
|
||||
:key="idx"
|
||||
class="flex"
|
||||
:class="message.role === 'user' ? 'justify-end' : 'justify-start'"
|
||||
>
|
||||
<div
|
||||
class="max-w-[90%] rounded-2xl px-3 py-2 shadow-sm"
|
||||
:class="message.role === 'user' ? 'bg-primary text-primary-content' : 'bg-base-100 text-base-content border border-base-300'"
|
||||
>
|
||||
<Text weight="semibold" class="mb-1">
|
||||
{{ message.role === 'user' ? $t('aiAssistants.view.you') : $t('aiAssistants.view.agentName') }}
|
||||
</Text>
|
||||
<Text :tone="message.role === 'user' ? undefined : 'muted'">
|
||||
{{ message.content }}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isStreaming" class="text-sm text-base-content/60">
|
||||
{{ $t('aiAssistants.view.typing') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-base-300 bg-base-100/70 p-3">
|
||||
<form class="flex items-end gap-2" @submit.prevent="handleSend">
|
||||
<div class="flex-1">
|
||||
<Textarea
|
||||
v-model="input"
|
||||
:placeholder="$t('aiAssistants.view.placeholder')"
|
||||
rows="2"
|
||||
class="w-full"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<Button type="submit" size="sm" :loading="isSending" :disabled="!input.trim()">
|
||||
{{ $t('aiAssistants.view.send') }}
|
||||
</Button>
|
||||
<Button type="button" size="sm" variant="ghost" @click="resetChat" :disabled="isSending">
|
||||
{{ $t('aiAssistants.view.reset') }}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="text-xs text-error text-center mt-2" v-if="error">
|
||||
{{ error }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
open: boolean
|
||||
width: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'close'): void
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
|
||||
const agentUrl = computed(() => runtimeConfig.public.langAgentUrl || '')
|
||||
const chatContainer = ref<HTMLElement | null>(null)
|
||||
const chat = ref<{ role: 'user' | 'assistant', content: string }[]>([
|
||||
{ role: 'assistant', content: t('aiAssistants.view.welcome') }
|
||||
])
|
||||
const input = ref('')
|
||||
const isSending = ref(false)
|
||||
const isStreaming = ref(false)
|
||||
const error = ref('')
|
||||
|
||||
const scrollToBottom = () => {
|
||||
nextTick(() => {
|
||||
if (chatContainer.value) {
|
||||
chatContainer.value.scrollTop = chatContainer.value.scrollHeight
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleSend = async () => {
|
||||
if (!input.value.trim()) return
|
||||
error.value = ''
|
||||
const userMessage = input.value.trim()
|
||||
chat.value.push({ role: 'user', content: userMessage })
|
||||
input.value = ''
|
||||
isSending.value = true
|
||||
isStreaming.value = true
|
||||
scrollToBottom()
|
||||
|
||||
try {
|
||||
const body = {
|
||||
input: {
|
||||
messages: chat.value.map((m) => ({
|
||||
type: m.role === 'assistant' ? 'ai' : 'human',
|
||||
content: m.content
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
const response = await $fetch(`${agentUrl.value}/invoke`, {
|
||||
method: 'POST',
|
||||
body
|
||||
})
|
||||
|
||||
const outputMessages = (response as any)?.output?.messages || []
|
||||
const last = outputMessages[outputMessages.length - 1]
|
||||
const content = last?.content?.[0]?.text || last?.content || t('aiAssistants.view.emptyResponse')
|
||||
chat.value.push({ role: 'assistant', content })
|
||||
scrollToBottom()
|
||||
} catch (e: unknown) {
|
||||
console.error('Agent error', e)
|
||||
error.value = e instanceof Error ? e.message : t('aiAssistants.view.error')
|
||||
chat.value.push({ role: 'assistant', content: t('aiAssistants.view.error') })
|
||||
scrollToBottom()
|
||||
} finally {
|
||||
isSending.value = false
|
||||
isStreaming.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const resetChat = () => {
|
||||
chat.value = [{ role: 'assistant', content: t('aiAssistants.view.welcome') }]
|
||||
input.value = ''
|
||||
error.value = ''
|
||||
}
|
||||
|
||||
watch(() => props.open, (isOpen) => {
|
||||
if (isOpen) scrollToBottom()
|
||||
})
|
||||
</script>
|
||||
@@ -48,5 +48,5 @@ defineEmits<{
|
||||
const localePath = useLocalePath()
|
||||
const { t } = useI18n()
|
||||
|
||||
const linkable = computed(() => !props.selectable && props.address.uuid)
|
||||
const linkable = computed(() => !props.selectable && !!props.address.uuid)
|
||||
</script>
|
||||
|
||||
178
app/components/catalog/AddressDetailBottomSheet.vue
Normal file
178
app/components/catalog/AddressDetailBottomSheet.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<Transition name="address-slide">
|
||||
<div
|
||||
v-if="isOpen && addressUuid"
|
||||
class="fixed inset-x-0 bottom-0 z-50 flex justify-center px-3 md:px-4"
|
||||
style="height: 72vh"
|
||||
>
|
||||
<!-- Backdrop (clickable to close) -->
|
||||
<div
|
||||
class="absolute inset-0 -top-[32vh] bg-gradient-to-t from-black/45 via-black/20 to-transparent"
|
||||
@click="emit('close')"
|
||||
/>
|
||||
|
||||
<!-- Sheet content -->
|
||||
<div class="relative flex w-full max-w-[980px] flex-col overflow-hidden rounded-t-[2rem] border border-white/60 bg-base-100/95 shadow-[0_-24px_70px_rgba(15,23,42,0.3)] backdrop-blur-xl">
|
||||
<!-- Header with drag handle and close -->
|
||||
<div class="sticky top-0 z-10 border-b border-base-300 bg-base-100/90">
|
||||
<div class="flex justify-center py-2">
|
||||
<div class="h-1.5 w-12 rounded-full bg-base-content/20" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between px-6 pb-4">
|
||||
<template v-if="address">
|
||||
<div class="flex items-center gap-3 flex-1 min-w-0">
|
||||
<div class="flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-xl bg-success/20 text-2xl">
|
||||
{{ isoToEmoji(address.countryCode) }}
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="truncate text-xl font-black text-base-content">{{ address.name }}</div>
|
||||
<div class="truncate text-sm text-base-content/60">{{ address.address }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<div class="flex items-center gap-3 flex-1">
|
||||
<div class="h-10 w-10 animate-pulse rounded-xl bg-base-300/70" />
|
||||
<div class="flex-1">
|
||||
<div class="h-5 w-48 animate-pulse rounded bg-base-300/70" />
|
||||
<div class="mt-1 h-4 w-32 animate-pulse rounded bg-base-300/70" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<button class="btn btn-ghost btn-sm btn-circle flex-shrink-0 text-base-content/60 hover:text-base-content" @click="emit('close')">
|
||||
<Icon name="lucide:x" size="20" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div v-if="address" class="h-[calc(72vh-110px)] overflow-y-auto px-6 py-4 space-y-4">
|
||||
<!-- Location info -->
|
||||
<div class="rounded-2xl border border-base-300 bg-base-100 p-4">
|
||||
<div class="mb-3 flex items-center gap-2 text-base-content">
|
||||
<Icon name="lucide:map-pin" size="18" />
|
||||
<span class="text-lg font-black">{{ t('profileAddresses.detail.location') }}</span>
|
||||
</div>
|
||||
<div class="space-y-2 text-sm">
|
||||
<div class="flex items-start gap-2 text-base-content/80">
|
||||
<Icon name="lucide:navigation" size="14" class="mt-0.5 flex-shrink-0 text-base-content/50" />
|
||||
<span>{{ address.address }}</span>
|
||||
</div>
|
||||
<div v-if="address.latitude && address.longitude" class="flex items-center gap-2 text-base-content/60">
|
||||
<Icon name="lucide:crosshair" size="14" class="text-base-content/50" />
|
||||
<span class="font-mono text-xs">{{ address.latitude.toFixed(6) }}, {{ address.longitude.toFixed(6) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Map preview -->
|
||||
<div v-if="address.latitude && address.longitude" class="rounded-2xl border border-base-300 bg-base-100 p-4">
|
||||
<div class="mb-3 flex items-center gap-2 text-base-content">
|
||||
<Icon name="lucide:map" size="18" />
|
||||
<span class="text-lg font-black">{{ t('profileAddresses.detail.map') }}</span>
|
||||
</div>
|
||||
<div class="h-48 overflow-hidden rounded-xl">
|
||||
<ClientOnly>
|
||||
<MapboxMap
|
||||
:map-id="'address-preview-' + addressUuid"
|
||||
style="width: 100%; height: 100%"
|
||||
:options="{
|
||||
style: 'mapbox://styles/mapbox/light-v11',
|
||||
center: [address.longitude, address.latitude],
|
||||
zoom: 14,
|
||||
interactive: false
|
||||
}"
|
||||
>
|
||||
<MapboxDefaultMarker
|
||||
:marker-id="'address-marker'"
|
||||
:lnglat="[address.longitude, address.latitude]"
|
||||
color="#10b981"
|
||||
/>
|
||||
</MapboxMap>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="flex gap-3">
|
||||
<NuxtLink :to="localePath(`/clientarea/addresses/${addressUuid}`)" class="flex-1">
|
||||
<button class="btn btn-sm w-full btn-outline">
|
||||
<Icon name="lucide:pencil" size="14" class="mr-2" />
|
||||
{{ t('profileAddresses.actions.edit') }}
|
||||
</button>
|
||||
</NuxtLink>
|
||||
<button
|
||||
class="btn btn-sm bg-error/20 border-error/30 text-error hover:bg-error/30"
|
||||
@click="handleDelete"
|
||||
:disabled="isDeleting"
|
||||
>
|
||||
<Icon name="lucide:trash-2" size="14" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading state -->
|
||||
<div v-else class="px-6 py-4 space-y-4">
|
||||
<div class="h-24 animate-pulse rounded-xl bg-base-300/70" />
|
||||
<div class="h-48 animate-pulse rounded-xl bg-base-300/70" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
isOpen: boolean
|
||||
addressUuid: string | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'close': []
|
||||
'deleted': []
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const localePath = useLocalePath()
|
||||
|
||||
const { items, isoToEmoji, deleteAddress } = useTeamAddresses()
|
||||
|
||||
const isDeleting = ref(false)
|
||||
|
||||
const address = computed(() => {
|
||||
if (!props.addressUuid) return null
|
||||
return items.value.find(a => a.uuid === props.addressUuid) || null
|
||||
})
|
||||
|
||||
const handleDelete = async () => {
|
||||
if (!props.addressUuid) return
|
||||
isDeleting.value = true
|
||||
const success = await deleteAddress(props.addressUuid)
|
||||
isDeleting.value = false
|
||||
if (success) {
|
||||
emit('deleted')
|
||||
emit('close')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.address-slide-enter-active,
|
||||
.address-slide-leave-active {
|
||||
transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.address-slide-enter-from,
|
||||
.address-slide-leave-to {
|
||||
transform: translateY(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.address-slide-enter-to,
|
||||
.address-slide-leave-from {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
@@ -17,8 +17,8 @@
|
||||
<Text weight="semibold" class="mb-3">{{ country.name }}</Text>
|
||||
<Grid :cols="1" :md="2" :lg="3" :gap="4">
|
||||
<HubCard
|
||||
v-for="hub in country.hubs"
|
||||
:key="hub.uuid"
|
||||
v-for="(hub, index) in country.hubs"
|
||||
:key="hub.uuid ?? index"
|
||||
:hub="hub"
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
<script setup lang="ts">
|
||||
import type { Map as MapboxMapType } from 'mapbox-gl'
|
||||
import { LngLatBounds } from 'mapbox-gl'
|
||||
import type { ClusterPointType } from '~/composables/graphql/public/geo-generated'
|
||||
import type { ClusterPoint } from '~/composables/graphql/public/geo-generated'
|
||||
|
||||
interface MapItem {
|
||||
uuid: string
|
||||
name: string
|
||||
latitude: number
|
||||
longitude: number
|
||||
country?: string
|
||||
uuid?: string | null
|
||||
name?: string | null
|
||||
latitude?: number | null
|
||||
longitude?: number | null
|
||||
country?: string | null
|
||||
}
|
||||
|
||||
export interface MapBounds {
|
||||
@@ -43,24 +43,40 @@ interface HoveredItem {
|
||||
const props = withDefaults(defineProps<{
|
||||
mapId: string
|
||||
items?: MapItem[]
|
||||
clusteredPoints?: ClusterPointType[]
|
||||
clusteredPoints?: ClusterPoint[]
|
||||
clusteredPointsByType?: Partial<Record<'offer' | 'hub' | 'supplier', ClusterPoint[]>>
|
||||
useServerClustering?: boolean
|
||||
hoveredItemId?: string | null
|
||||
hoveredItem?: HoveredItem | null
|
||||
pointColor?: string
|
||||
entityType?: 'offer' | 'hub' | 'supplier'
|
||||
initialCenter?: [number, number]
|
||||
initialZoom?: number
|
||||
infoLoading?: boolean
|
||||
fitPaddingLeft?: number
|
||||
relatedPoints?: Array<{
|
||||
uuid: string
|
||||
name: string
|
||||
latitude: number
|
||||
longitude: number
|
||||
type: 'hub' | 'supplier' | 'offer'
|
||||
}>
|
||||
}>(), {
|
||||
pointColor: '#10b981',
|
||||
pointColor: '#f97316',
|
||||
entityType: 'offer',
|
||||
initialCenter: () => [37.64, 55.76],
|
||||
initialZoom: 2,
|
||||
useServerClustering: false,
|
||||
infoLoading: false,
|
||||
fitPaddingLeft: 0,
|
||||
items: () => [],
|
||||
clusteredPoints: () => []
|
||||
clusteredPoints: () => [],
|
||||
clusteredPointsByType: undefined,
|
||||
relatedPoints: () => []
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
'select-item': [uuid: string]
|
||||
'select-item': [uuid: string, properties?: Record<string, any>]
|
||||
'bounds-change': [bounds: MapBounds]
|
||||
}>()
|
||||
|
||||
@@ -69,6 +85,119 @@ const { flyThroughSpace } = useMapboxFlyAnimation()
|
||||
const didFitBounds = ref(false)
|
||||
const mapInitialized = ref(false)
|
||||
|
||||
const usesTypedClusters = computed(() => {
|
||||
const typed = props.clusteredPointsByType
|
||||
return !!typed && Object.keys(typed).length > 0
|
||||
})
|
||||
|
||||
const buildFitPadding = (base: number) => {
|
||||
const extraLeft = Math.max(0, props.fitPaddingLeft || 0)
|
||||
return {
|
||||
top: base,
|
||||
bottom: base,
|
||||
left: base + extraLeft,
|
||||
right: base
|
||||
}
|
||||
}
|
||||
|
||||
// Entity type icons - SVG data URLs with specific colors
|
||||
const createEntityIcon = (type: 'offer' | 'hub' | 'supplier', color: string) => {
|
||||
const icons = {
|
||||
offer: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>`,
|
||||
hub: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 8.35V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8.35A2 2 0 0 1 3.26 6.5l8-3.2a2 2 0 0 1 1.48 0l8 3.2A2 2 0 0 1 22 8.35Z"/><path d="M6 18h12"/><path d="M6 14h12"/><rect width="12" height="12" x="6" y="10"/></svg>`,
|
||||
supplier: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-7 5V8l-7 5V4a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"/><path d="M17 18h1"/><path d="M12 18h1"/><path d="M7 18h1"/></svg>`
|
||||
}
|
||||
return icons[type]
|
||||
}
|
||||
|
||||
// Load icon into map as image
|
||||
const loadEntityIcon = async (map: MapboxMapType, type: 'offer' | 'hub' | 'supplier', color: string) => {
|
||||
const iconName = `entity-icon-${type}`
|
||||
if (map.hasImage(iconName)) {
|
||||
map.removeImage(iconName)
|
||||
}
|
||||
|
||||
const svg = createEntityIcon(type, color)
|
||||
const img = new Image(32, 32)
|
||||
|
||||
return new Promise<void>((resolve) => {
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = 32
|
||||
canvas.height = 32
|
||||
const ctx = canvas.getContext('2d')
|
||||
if (ctx) {
|
||||
// Draw colored circle background
|
||||
ctx.beginPath()
|
||||
ctx.arc(16, 16, 15, 0, 2 * Math.PI)
|
||||
ctx.fillStyle = color
|
||||
ctx.fill()
|
||||
ctx.strokeStyle = 'white'
|
||||
ctx.lineWidth = 2
|
||||
ctx.stroke()
|
||||
// Draw icon on top
|
||||
ctx.drawImage(img, 4, 4, 24, 24)
|
||||
}
|
||||
|
||||
const imageData = ctx?.getImageData(0, 0, 32, 32)
|
||||
if (imageData) {
|
||||
map.addImage(iconName, { width: 32, height: 32, data: imageData.data })
|
||||
}
|
||||
resolve()
|
||||
}
|
||||
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg)
|
||||
})
|
||||
}
|
||||
|
||||
// Standard colors for entity types
|
||||
const ENTITY_COLORS = {
|
||||
hub: '#22c55e', // green
|
||||
supplier: '#3b82f6', // blue
|
||||
offer: '#f97316' // orange
|
||||
} as const
|
||||
|
||||
const CLUSTER_TYPES: Array<'offer' | 'hub' | 'supplier'> = ['offer', 'hub', 'supplier']
|
||||
|
||||
// Load all icons for related points (each type with its standard color)
|
||||
const loadRelatedPointIcons = async (map: MapboxMapType) => {
|
||||
const types: Array<'hub' | 'supplier' | 'offer'> = ['hub', 'supplier', 'offer']
|
||||
for (const type of types) {
|
||||
const iconName = `related-icon-${type}`
|
||||
if (map.hasImage(iconName)) {
|
||||
map.removeImage(iconName)
|
||||
}
|
||||
|
||||
const svg = createEntityIcon(type, ENTITY_COLORS[type])
|
||||
const img = new Image(32, 32)
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = 32
|
||||
canvas.height = 32
|
||||
const ctx = canvas.getContext('2d')
|
||||
if (ctx) {
|
||||
ctx.beginPath()
|
||||
ctx.arc(16, 16, 15, 0, 2 * Math.PI)
|
||||
ctx.fillStyle = ENTITY_COLORS[type]
|
||||
ctx.fill()
|
||||
ctx.strokeStyle = 'white'
|
||||
ctx.lineWidth = 2
|
||||
ctx.stroke()
|
||||
ctx.drawImage(img, 4, 4, 24, 24)
|
||||
}
|
||||
|
||||
const imageData = ctx?.getImageData(0, 0, 32, 32)
|
||||
if (imageData) {
|
||||
map.addImage(iconName, { width: 32, height: 32, data: imageData.data })
|
||||
}
|
||||
resolve()
|
||||
}
|
||||
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const mapOptions = computed(() => ({
|
||||
style: 'mapbox://styles/mapbox/satellite-streets-v12',
|
||||
center: props.initialCenter,
|
||||
@@ -80,11 +209,13 @@ const mapOptions = computed(() => ({
|
||||
// Client-side clustering GeoJSON (when not using server clustering)
|
||||
const geoJsonData = computed(() => ({
|
||||
type: 'FeatureCollection' as const,
|
||||
features: props.items.map(item => ({
|
||||
type: 'Feature' as const,
|
||||
properties: { uuid: item.uuid, name: item.name, country: item.country },
|
||||
geometry: { type: 'Point' as const, coordinates: [item.longitude, item.latitude] }
|
||||
}))
|
||||
features: props.items
|
||||
.filter(item => item.latitude != null && item.longitude != null)
|
||||
.map(item => ({
|
||||
type: 'Feature' as const,
|
||||
properties: { uuid: item.uuid, name: item.name, country: item.country },
|
||||
geometry: { type: 'Point' as const, coordinates: [item.longitude!, item.latitude!] }
|
||||
}))
|
||||
}))
|
||||
|
||||
// Server-side clustering GeoJSON
|
||||
@@ -106,6 +237,33 @@ const serverClusteredGeoJson = computed(() => ({
|
||||
}))
|
||||
}))
|
||||
|
||||
const serverClusteredGeoJsonByType = computed(() => {
|
||||
const build = (points: ClusterPoint[] | undefined, type: 'offer' | 'hub' | 'supplier') => ({
|
||||
type: 'FeatureCollection' as const,
|
||||
features: (points || []).filter(Boolean).map(point => ({
|
||||
type: 'Feature' as const,
|
||||
properties: {
|
||||
id: point!.id,
|
||||
name: point!.name,
|
||||
count: point!.count ?? 1,
|
||||
expansionZoom: point!.expansionZoom,
|
||||
isCluster: (point!.count ?? 1) > 1,
|
||||
type
|
||||
},
|
||||
geometry: {
|
||||
type: 'Point' as const,
|
||||
coordinates: [point!.longitude ?? 0, point!.latitude ?? 0]
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
return {
|
||||
offer: build(props.clusteredPointsByType?.offer, 'offer'),
|
||||
hub: build(props.clusteredPointsByType?.hub, 'hub'),
|
||||
supplier: build(props.clusteredPointsByType?.supplier, 'supplier')
|
||||
}
|
||||
})
|
||||
|
||||
// Hovered point GeoJSON (separate layer on top)
|
||||
const hoveredPointGeoJson = computed(() => ({
|
||||
type: 'FeatureCollection' as const,
|
||||
@@ -119,8 +277,39 @@ const hoveredPointGeoJson = computed(() => ({
|
||||
}] : []
|
||||
}))
|
||||
|
||||
// Related points GeoJSON (for Info mode)
|
||||
const relatedPointsGeoJson = computed(() => {
|
||||
if (!props.relatedPoints || props.relatedPoints.length === 0) {
|
||||
return { type: 'FeatureCollection' as const, features: [] }
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'FeatureCollection' as const,
|
||||
features: props.relatedPoints.map(point => ({
|
||||
type: 'Feature' as const,
|
||||
properties: {
|
||||
uuid: point.uuid,
|
||||
name: point.name,
|
||||
type: point.type
|
||||
},
|
||||
geometry: {
|
||||
type: 'Point' as const,
|
||||
coordinates: [point.longitude, point.latitude]
|
||||
}
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
const sourceId = computed(() => `${props.mapId}-points`)
|
||||
const hoveredSourceId = computed(() => `${props.mapId}-hovered`)
|
||||
const relatedSourceId = computed(() => `${props.mapId}-related`)
|
||||
|
||||
const getServerSourceId = (type: 'offer' | 'hub' | 'supplier') => `${props.mapId}-server-${type}`
|
||||
const getServerClusterLayerId = (type: 'offer' | 'hub' | 'supplier') => `${props.mapId}-server-${type}-clusters`
|
||||
const getServerClusterCountLayerId = (type: 'offer' | 'hub' | 'supplier') => `${props.mapId}-server-${type}-cluster-count`
|
||||
const getServerPointLayerId = (type: 'offer' | 'hub' | 'supplier') => `${props.mapId}-server-${type}-points`
|
||||
const getServerPointLabelLayerId = (type: 'offer' | 'hub' | 'supplier') => `${props.mapId}-server-${type}-point-labels`
|
||||
|
||||
|
||||
const emitBoundsChange = (map: MapboxMapType) => {
|
||||
const bounds = map.getBounds()
|
||||
@@ -135,7 +324,7 @@ const emitBoundsChange = (map: MapboxMapType) => {
|
||||
}
|
||||
|
||||
const onMapCreated = (map: MapboxMapType) => {
|
||||
const initMap = () => {
|
||||
const initMap = async () => {
|
||||
map.setFog({
|
||||
color: 'rgb(186, 210, 235)',
|
||||
'high-color': 'rgb(36, 92, 223)',
|
||||
@@ -145,9 +334,13 @@ const onMapCreated = (map: MapboxMapType) => {
|
||||
})
|
||||
|
||||
if (props.useServerClustering) {
|
||||
initServerClusteringLayers(map)
|
||||
if (usesTypedClusters.value) {
|
||||
await initServerClusteringLayersByType(map)
|
||||
} else {
|
||||
await initServerClusteringLayers(map)
|
||||
}
|
||||
} else {
|
||||
initClientClusteringLayers(map)
|
||||
await initClientClusteringLayers(map)
|
||||
}
|
||||
|
||||
// Emit initial bounds
|
||||
@@ -166,7 +359,10 @@ const onMapCreated = (map: MapboxMapType) => {
|
||||
}
|
||||
}
|
||||
|
||||
const initClientClusteringLayers = (map: MapboxMapType) => {
|
||||
const initClientClusteringLayers = async (map: MapboxMapType) => {
|
||||
// Load entity icon first
|
||||
await loadEntityIcon(map, props.entityType, props.pointColor)
|
||||
|
||||
map.addSource(sourceId.value, {
|
||||
type: 'geojson',
|
||||
data: geoJsonData.value,
|
||||
@@ -203,14 +399,13 @@ const initClientClusteringLayers = (map: MapboxMapType) => {
|
||||
|
||||
map.addLayer({
|
||||
id: 'unclustered-point',
|
||||
type: 'circle',
|
||||
type: 'symbol',
|
||||
source: sourceId.value,
|
||||
filter: ['!', ['has', 'point_count']],
|
||||
paint: {
|
||||
'circle-radius': 12,
|
||||
'circle-color': props.pointColor,
|
||||
'circle-stroke-width': 3,
|
||||
'circle-stroke-color': '#ffffff'
|
||||
layout: {
|
||||
'icon-image': `entity-icon-${props.entityType}`,
|
||||
'icon-size': 1,
|
||||
'icon-allow-overlap': true
|
||||
}
|
||||
})
|
||||
|
||||
@@ -221,7 +416,7 @@ const initClientClusteringLayers = (map: MapboxMapType) => {
|
||||
filter: ['!', ['has', 'point_count']],
|
||||
layout: {
|
||||
'text-field': ['get', 'name'],
|
||||
'text-offset': [0, 1.5],
|
||||
'text-offset': [0, 1.8],
|
||||
'text-size': 12,
|
||||
'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold']
|
||||
},
|
||||
@@ -234,20 +429,22 @@ const initClientClusteringLayers = (map: MapboxMapType) => {
|
||||
|
||||
map.on('click', 'clusters', (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: ['clusters'] })
|
||||
if (!features.length) return
|
||||
const clusterId = features[0].properties?.cluster_id
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
const clusterId = feature.properties?.cluster_id
|
||||
const source = map.getSource(sourceId.value) as mapboxgl.GeoJSONSource
|
||||
source.getClusterExpansionZoom(clusterId, (err, zoom) => {
|
||||
if (err) return
|
||||
const geometry = features[0].geometry as GeoJSON.Point
|
||||
const geometry = feature.geometry as GeoJSON.Point
|
||||
map.easeTo({ center: geometry.coordinates as [number, number], zoom: zoom || 4 })
|
||||
})
|
||||
})
|
||||
|
||||
map.on('click', 'unclustered-point', (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: ['unclustered-point'] })
|
||||
if (!features.length) return
|
||||
emit('select-item', features[0].properties?.uuid)
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
emit('select-item', feature.properties?.uuid)
|
||||
})
|
||||
|
||||
map.on('mouseenter', 'clusters', () => { map.getCanvas().style.cursor = 'pointer' })
|
||||
@@ -285,24 +482,87 @@ const initClientClusteringLayers = (map: MapboxMapType) => {
|
||||
}
|
||||
})
|
||||
|
||||
// Related points layer (for Info mode - icons by type)
|
||||
await loadRelatedPointIcons(map)
|
||||
|
||||
map.addSource(relatedSourceId.value, {
|
||||
type: 'geojson',
|
||||
data: relatedPointsGeoJson.value
|
||||
})
|
||||
map.addLayer({
|
||||
id: `${props.mapId}-related-points`,
|
||||
type: 'symbol',
|
||||
source: relatedSourceId.value,
|
||||
layout: {
|
||||
'icon-image': [
|
||||
'match',
|
||||
['get', 'type'],
|
||||
'hub', 'related-icon-hub',
|
||||
'supplier', 'related-icon-supplier',
|
||||
'offer', 'related-icon-offer',
|
||||
'related-icon-offer' // default
|
||||
],
|
||||
'icon-size': 1,
|
||||
'icon-allow-overlap': true
|
||||
}
|
||||
})
|
||||
map.addLayer({
|
||||
id: `${props.mapId}-related-labels`,
|
||||
type: 'symbol',
|
||||
source: relatedSourceId.value,
|
||||
layout: {
|
||||
'text-field': ['get', 'name'],
|
||||
'text-size': 11,
|
||||
'text-anchor': 'top',
|
||||
'text-offset': [0, 1.5]
|
||||
},
|
||||
paint: {
|
||||
'text-color': '#ffffff',
|
||||
'text-halo-color': '#000000',
|
||||
'text-halo-width': 1
|
||||
}
|
||||
})
|
||||
|
||||
// Click handlers for related points
|
||||
map.on('click', `${props.mapId}-related-points`, (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: [`${props.mapId}-related-points`] })
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
const props_data = feature.properties as Record<string, any> | undefined
|
||||
emit('select-item', props_data?.uuid, props_data)
|
||||
})
|
||||
|
||||
map.on('mouseenter', `${props.mapId}-related-points`, () => {
|
||||
map.getCanvas().style.cursor = 'pointer'
|
||||
})
|
||||
|
||||
map.on('mouseleave', `${props.mapId}-related-points`, () => {
|
||||
map.getCanvas().style.cursor = ''
|
||||
})
|
||||
|
||||
// Auto-fit bounds to all items
|
||||
if (!didFitBounds.value && props.items.length > 0) {
|
||||
const bounds = new LngLatBounds()
|
||||
props.items.forEach(item => {
|
||||
bounds.extend([item.longitude, item.latitude])
|
||||
if (item.longitude != null && item.latitude != null) {
|
||||
bounds.extend([item.longitude, item.latitude])
|
||||
}
|
||||
})
|
||||
map.fitBounds(bounds, { padding: 50, maxZoom: 10 })
|
||||
map.fitBounds(bounds, { padding: buildFitPadding(50), maxZoom: 10 })
|
||||
didFitBounds.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const initServerClusteringLayers = (map: MapboxMapType) => {
|
||||
const initServerClusteringLayers = async (map: MapboxMapType) => {
|
||||
// Load entity icon first
|
||||
await loadEntityIcon(map, props.entityType, props.pointColor)
|
||||
|
||||
map.addSource(sourceId.value, {
|
||||
type: 'geojson',
|
||||
data: serverClusteredGeoJson.value
|
||||
})
|
||||
|
||||
// Clusters (count > 1)
|
||||
// Clusters (count > 1) - circle with count
|
||||
map.addLayer({
|
||||
id: 'server-clusters',
|
||||
type: 'circle',
|
||||
@@ -329,17 +589,16 @@ const initServerClusteringLayers = (map: MapboxMapType) => {
|
||||
paint: { 'text-color': '#ffffff' }
|
||||
})
|
||||
|
||||
// Individual points (count == 1)
|
||||
// Individual points (count == 1) - icon with entity type
|
||||
map.addLayer({
|
||||
id: 'server-points',
|
||||
type: 'circle',
|
||||
type: 'symbol',
|
||||
source: sourceId.value,
|
||||
filter: ['==', ['get', 'count'], 1],
|
||||
paint: {
|
||||
'circle-radius': 12,
|
||||
'circle-color': props.pointColor,
|
||||
'circle-stroke-width': 3,
|
||||
'circle-stroke-color': '#ffffff'
|
||||
layout: {
|
||||
'icon-image': `entity-icon-${props.entityType}`,
|
||||
'icon-size': 1,
|
||||
'icon-allow-overlap': true
|
||||
}
|
||||
})
|
||||
|
||||
@@ -350,7 +609,7 @@ const initServerClusteringLayers = (map: MapboxMapType) => {
|
||||
filter: ['==', ['get', 'count'], 1],
|
||||
layout: {
|
||||
'text-field': ['get', 'name'],
|
||||
'text-offset': [0, 1.5],
|
||||
'text-offset': [0, 1.8],
|
||||
'text-size': 12,
|
||||
'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold']
|
||||
},
|
||||
@@ -364,20 +623,23 @@ const initServerClusteringLayers = (map: MapboxMapType) => {
|
||||
// Click on cluster to zoom in
|
||||
map.on('click', 'server-clusters', (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: ['server-clusters'] })
|
||||
if (!features.length) return
|
||||
const expansionZoom = features[0].properties?.expansionZoom
|
||||
const geometry = features[0].geometry as GeoJSON.Point
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
const expansionZoom = feature.properties?.expansionZoom
|
||||
const geometry = feature.geometry as GeoJSON.Point
|
||||
map.easeTo({
|
||||
center: geometry.coordinates as [number, number],
|
||||
zoom: expansionZoom || map.getZoom() + 2
|
||||
})
|
||||
})
|
||||
|
||||
// Click on individual point
|
||||
// Click on individual point - emit full properties
|
||||
map.on('click', 'server-points', (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: ['server-points'] })
|
||||
if (!features.length) return
|
||||
emit('select-item', features[0].properties?.id)
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
const props = feature.properties || {}
|
||||
emit('select-item', props.id, props)
|
||||
})
|
||||
|
||||
map.on('mouseenter', 'server-clusters', () => { map.getCanvas().style.cursor = 'pointer' })
|
||||
@@ -414,17 +676,272 @@ const initServerClusteringLayers = (map: MapboxMapType) => {
|
||||
'circle-stroke-color': '#ffffff'
|
||||
}
|
||||
})
|
||||
|
||||
// Related points layer (for Info mode - icons by type)
|
||||
await loadRelatedPointIcons(map)
|
||||
|
||||
map.addSource(relatedSourceId.value, {
|
||||
type: 'geojson',
|
||||
data: relatedPointsGeoJson.value
|
||||
})
|
||||
map.addLayer({
|
||||
id: `${props.mapId}-related-points`,
|
||||
type: 'symbol',
|
||||
source: relatedSourceId.value,
|
||||
layout: {
|
||||
'icon-image': [
|
||||
'match',
|
||||
['get', 'type'],
|
||||
'hub', 'related-icon-hub',
|
||||
'supplier', 'related-icon-supplier',
|
||||
'offer', 'related-icon-offer',
|
||||
'related-icon-offer' // default
|
||||
],
|
||||
'icon-size': 1,
|
||||
'icon-allow-overlap': true
|
||||
}
|
||||
})
|
||||
map.addLayer({
|
||||
id: `${props.mapId}-related-labels`,
|
||||
type: 'symbol',
|
||||
source: relatedSourceId.value,
|
||||
layout: {
|
||||
'text-field': ['get', 'name'],
|
||||
'text-size': 11,
|
||||
'text-anchor': 'top',
|
||||
'text-offset': [0, 1.5]
|
||||
},
|
||||
paint: {
|
||||
'text-color': '#ffffff',
|
||||
'text-halo-color': '#000000',
|
||||
'text-halo-width': 1
|
||||
}
|
||||
})
|
||||
|
||||
// Click handlers for related points
|
||||
map.on('click', `${props.mapId}-related-points`, (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: [`${props.mapId}-related-points`] })
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
const props_data = feature.properties as Record<string, any> | undefined
|
||||
emit('select-item', props_data?.uuid, props_data)
|
||||
})
|
||||
|
||||
map.on('mouseenter', `${props.mapId}-related-points`, () => {
|
||||
map.getCanvas().style.cursor = 'pointer'
|
||||
})
|
||||
|
||||
map.on('mouseleave', `${props.mapId}-related-points`, () => {
|
||||
map.getCanvas().style.cursor = ''
|
||||
})
|
||||
}
|
||||
|
||||
const initServerClusteringLayersByType = async (map: MapboxMapType) => {
|
||||
for (const type of CLUSTER_TYPES) {
|
||||
await loadEntityIcon(map, type, ENTITY_COLORS[type])
|
||||
|
||||
const sourceIdByType = getServerSourceId(type)
|
||||
map.addSource(sourceIdByType, {
|
||||
type: 'geojson',
|
||||
data: serverClusteredGeoJsonByType.value[type]
|
||||
})
|
||||
|
||||
const clusterLayerId = getServerClusterLayerId(type)
|
||||
const clusterCountLayerId = getServerClusterCountLayerId(type)
|
||||
const pointLayerId = getServerPointLayerId(type)
|
||||
const pointLabelLayerId = getServerPointLabelLayerId(type)
|
||||
|
||||
map.addLayer({
|
||||
id: clusterLayerId,
|
||||
type: 'circle',
|
||||
source: sourceIdByType,
|
||||
filter: ['>', ['get', 'count'], 1],
|
||||
paint: {
|
||||
'circle-color': ENTITY_COLORS[type],
|
||||
'circle-radius': ['step', ['get', 'count'], 20, 10, 30, 50, 40],
|
||||
'circle-opacity': 0.8,
|
||||
'circle-stroke-width': 2,
|
||||
'circle-stroke-color': '#ffffff'
|
||||
},
|
||||
layout: {}
|
||||
})
|
||||
|
||||
map.addLayer({
|
||||
id: clusterCountLayerId,
|
||||
type: 'symbol',
|
||||
source: sourceIdByType,
|
||||
filter: ['>', ['get', 'count'], 1],
|
||||
layout: {
|
||||
'text-field': ['get', 'count'],
|
||||
'text-size': 14
|
||||
},
|
||||
paint: { 'text-color': '#ffffff' }
|
||||
})
|
||||
|
||||
map.addLayer({
|
||||
id: pointLayerId,
|
||||
type: 'symbol',
|
||||
source: sourceIdByType,
|
||||
filter: ['==', ['get', 'count'], 1],
|
||||
layout: {
|
||||
'icon-image': `entity-icon-${type}`,
|
||||
'icon-size': 1,
|
||||
'icon-allow-overlap': true
|
||||
}
|
||||
})
|
||||
|
||||
map.addLayer({
|
||||
id: pointLabelLayerId,
|
||||
type: 'symbol',
|
||||
source: sourceIdByType,
|
||||
filter: ['==', ['get', 'count'], 1],
|
||||
layout: {
|
||||
'text-field': ['get', 'name'],
|
||||
'text-offset': [0, 1.8],
|
||||
'text-size': 12,
|
||||
'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold']
|
||||
},
|
||||
paint: {
|
||||
'text-color': '#ffffff',
|
||||
'text-halo-color': '#000000',
|
||||
'text-halo-width': 1.5
|
||||
}
|
||||
})
|
||||
|
||||
map.on('click', clusterLayerId, (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: [clusterLayerId] })
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
const expansionZoom = feature.properties?.expansionZoom
|
||||
const geometry = feature.geometry as GeoJSON.Point
|
||||
map.easeTo({
|
||||
center: geometry.coordinates as [number, number],
|
||||
zoom: expansionZoom || map.getZoom() + 2
|
||||
})
|
||||
})
|
||||
|
||||
map.on('click', pointLayerId, (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: [pointLayerId] })
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
const props_data = feature.properties as Record<string, any> | undefined
|
||||
emit('select-item', props_data?.id, props_data)
|
||||
})
|
||||
|
||||
map.on('mouseenter', clusterLayerId, () => { map.getCanvas().style.cursor = 'pointer' })
|
||||
map.on('mouseleave', clusterLayerId, () => { map.getCanvas().style.cursor = '' })
|
||||
map.on('mouseenter', pointLayerId, () => { map.getCanvas().style.cursor = 'pointer' })
|
||||
map.on('mouseleave', pointLayerId, () => { map.getCanvas().style.cursor = '' })
|
||||
}
|
||||
|
||||
// Hovered point layer (on top of everything)
|
||||
map.addSource(hoveredSourceId.value, {
|
||||
type: 'geojson',
|
||||
data: hoveredPointGeoJson.value
|
||||
})
|
||||
map.addLayer({
|
||||
id: 'hovered-point-ring',
|
||||
type: 'circle',
|
||||
source: hoveredSourceId.value,
|
||||
paint: {
|
||||
'circle-radius': 20,
|
||||
'circle-color': 'transparent',
|
||||
'circle-stroke-width': 3,
|
||||
'circle-stroke-color': '#ffffff'
|
||||
}
|
||||
})
|
||||
map.addLayer({
|
||||
id: 'hovered-point-layer',
|
||||
type: 'circle',
|
||||
source: hoveredSourceId.value,
|
||||
paint: {
|
||||
'circle-radius': 14,
|
||||
'circle-color': props.pointColor,
|
||||
'circle-stroke-width': 3,
|
||||
'circle-stroke-color': '#ffffff'
|
||||
}
|
||||
})
|
||||
|
||||
// Related points layer
|
||||
await loadRelatedPointIcons(map)
|
||||
|
||||
map.addSource(relatedSourceId.value, {
|
||||
type: 'geojson',
|
||||
data: relatedPointsGeoJson.value
|
||||
})
|
||||
map.addLayer({
|
||||
id: `${props.mapId}-related-points`,
|
||||
type: 'symbol',
|
||||
source: relatedSourceId.value,
|
||||
layout: {
|
||||
'icon-image': [
|
||||
'match',
|
||||
['get', 'type'],
|
||||
'hub', 'related-icon-hub',
|
||||
'supplier', 'related-icon-supplier',
|
||||
'offer', 'related-icon-offer',
|
||||
'related-icon-offer'
|
||||
],
|
||||
'icon-size': 1,
|
||||
'icon-allow-overlap': true
|
||||
}
|
||||
})
|
||||
map.addLayer({
|
||||
id: `${props.mapId}-related-labels`,
|
||||
type: 'symbol',
|
||||
source: relatedSourceId.value,
|
||||
layout: {
|
||||
'text-field': ['get', 'name'],
|
||||
'text-size': 11,
|
||||
'text-anchor': 'top',
|
||||
'text-offset': [0, 1.5]
|
||||
},
|
||||
paint: {
|
||||
'text-color': '#ffffff',
|
||||
'text-halo-color': '#000000',
|
||||
'text-halo-width': 1
|
||||
}
|
||||
})
|
||||
|
||||
map.on('click', `${props.mapId}-related-points`, (e) => {
|
||||
const features = map.queryRenderedFeatures(e.point, { layers: [`${props.mapId}-related-points`] })
|
||||
const feature = features[0]
|
||||
if (!feature) return
|
||||
const props_data = feature.properties as Record<string, any> | undefined
|
||||
emit('select-item', props_data?.uuid, props_data)
|
||||
})
|
||||
|
||||
map.on('mouseenter', `${props.mapId}-related-points`, () => {
|
||||
map.getCanvas().style.cursor = 'pointer'
|
||||
})
|
||||
|
||||
map.on('mouseleave', `${props.mapId}-related-points`, () => {
|
||||
map.getCanvas().style.cursor = ''
|
||||
})
|
||||
}
|
||||
|
||||
// Update map data when items or clusteredPoints change
|
||||
watch(() => props.useServerClustering ? serverClusteredGeoJson.value : geoJsonData.value, (newData) => {
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
if (usesTypedClusters.value) return
|
||||
const source = mapRef.value.getSource(sourceId.value) as mapboxgl.GeoJSONSource | undefined
|
||||
if (source) {
|
||||
source.setData(newData)
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
watch(() => serverClusteredGeoJsonByType.value, (newData) => {
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
if (!usesTypedClusters.value) return
|
||||
for (const type of CLUSTER_TYPES) {
|
||||
const sourceIdByType = getServerSourceId(type)
|
||||
const source = mapRef.value.getSource(sourceIdByType) as mapboxgl.GeoJSONSource | undefined
|
||||
if (source) {
|
||||
source.setData(newData[type])
|
||||
}
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
// Update hovered point layer when hoveredItem changes
|
||||
watch(() => props.hoveredItem, () => {
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
@@ -434,8 +951,71 @@ watch(() => props.hoveredItem, () => {
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
// Update related points layer when relatedPoints changes
|
||||
watch(() => props.relatedPoints, () => {
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
|
||||
// Update the source data immediately
|
||||
const source = mapRef.value.getSource(relatedSourceId.value) as mapboxgl.GeoJSONSource | undefined
|
||||
if (source) {
|
||||
source.setData(relatedPointsGeoJson.value)
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
// no visibility toggling; layers are data-driven by query
|
||||
|
||||
// Fit bounds when info loading finishes (all related data loaded)
|
||||
watch(() => props.infoLoading, (loading, wasLoading) => {
|
||||
// Only fit bounds when loading changes from true to false (data finished loading)
|
||||
if (wasLoading && !loading && props.relatedPoints && props.relatedPoints.length > 0) {
|
||||
if (!mapRef.value) return
|
||||
const bounds = new LngLatBounds()
|
||||
props.relatedPoints.forEach(p => {
|
||||
bounds.extend([p.longitude, p.latitude])
|
||||
})
|
||||
if (!bounds.isEmpty()) {
|
||||
mapRef.value.fitBounds(bounds, { padding: buildFitPadding(80), maxZoom: 12 })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Watch for pointColor or entityType changes - update colors and icons
|
||||
watch([() => props.pointColor, () => props.entityType], async ([newColor, newType]) => {
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
const map = mapRef.value
|
||||
|
||||
// Reload icon with new color and type
|
||||
await loadEntityIcon(map, newType, newColor)
|
||||
|
||||
// Update cluster circle colors
|
||||
if (props.useServerClustering) {
|
||||
if (usesTypedClusters.value) {
|
||||
return
|
||||
}
|
||||
if (map.getLayer('server-clusters')) {
|
||||
map.setPaintProperty('server-clusters', 'circle-color', newColor)
|
||||
}
|
||||
if (map.getLayer('server-points')) {
|
||||
map.setLayoutProperty('server-points', 'icon-image', `entity-icon-${newType}`)
|
||||
}
|
||||
} else {
|
||||
if (map.getLayer('clusters')) {
|
||||
map.setPaintProperty('clusters', 'circle-color', newColor)
|
||||
}
|
||||
if (map.getLayer('unclustered-point')) {
|
||||
map.setLayoutProperty('unclustered-point', 'icon-image', `entity-icon-${newType}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Update hovered point color
|
||||
if (map.getLayer('hovered-point-layer')) {
|
||||
map.setPaintProperty('hovered-point-layer', 'circle-color', newColor)
|
||||
}
|
||||
})
|
||||
|
||||
// fitBounds for server clustering when first data arrives
|
||||
watch(() => props.clusteredPoints, (points) => {
|
||||
if (usesTypedClusters.value) return
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
if (!didFitBounds.value && points && points.length > 0) {
|
||||
const bounds = new LngLatBounds()
|
||||
@@ -445,12 +1025,31 @@ watch(() => props.clusteredPoints, (points) => {
|
||||
}
|
||||
})
|
||||
if (!bounds.isEmpty()) {
|
||||
mapRef.value.fitBounds(bounds, { padding: 50, maxZoom: 6 })
|
||||
mapRef.value.fitBounds(bounds, { padding: buildFitPadding(50), maxZoom: 6 })
|
||||
didFitBounds.value = true
|
||||
}
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
watch(() => props.clusteredPointsByType, () => {
|
||||
if (!usesTypedClusters.value) return
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
if (didFitBounds.value) return
|
||||
|
||||
const bounds = new LngLatBounds()
|
||||
CLUSTER_TYPES.forEach(type => {
|
||||
const points = serverClusteredGeoJsonByType.value[type]?.features ?? []
|
||||
points.forEach((p) => {
|
||||
const coords = (p.geometry as GeoJSON.Point).coordinates as [number, number]
|
||||
bounds.extend(coords)
|
||||
})
|
||||
})
|
||||
if (!bounds.isEmpty()) {
|
||||
mapRef.value.fitBounds(bounds, { padding: buildFitPadding(50), maxZoom: 6 })
|
||||
didFitBounds.value = true
|
||||
}
|
||||
}, { deep: true, immediate: true })
|
||||
|
||||
// Expose flyTo method for external use (with space fly animation)
|
||||
const flyTo = async (lat: number, lng: number, zoom = 8) => {
|
||||
if (!mapRef.value) return
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
<!-- Hubs Tab -->
|
||||
<template v-if="activeTab === 'hubs'">
|
||||
<HubCard
|
||||
v-for="hub in hubs"
|
||||
:key="hub.uuid"
|
||||
v-for="(hub, index) in hubs"
|
||||
:key="hub.uuid ?? index"
|
||||
:hub="hub"
|
||||
selectable
|
||||
:is-selected="selectedId === hub.uuid"
|
||||
@@ -37,16 +37,20 @@
|
||||
|
||||
<!-- Offers Tab -->
|
||||
<template v-if="activeTab === 'offers'">
|
||||
<OfferCard
|
||||
v-for="offer in offers"
|
||||
:key="offer.uuid"
|
||||
:offer="offer"
|
||||
selectable
|
||||
compact
|
||||
:is-selected="selectedId === offer.uuid"
|
||||
<OfferResultCard
|
||||
v-for="(offer, index) in offersWithPrice"
|
||||
:key="offer.uuid ?? index"
|
||||
:supplier-name="offer.supplierName"
|
||||
:location-name="offer.locationName"
|
||||
:product-name="offer.productName || offer.title || undefined"
|
||||
:price-per-unit="offer.pricePerUnit ? Number(offer.pricePerUnit) : null"
|
||||
:quantity="offer.quantity"
|
||||
:currency="offer.currency"
|
||||
:unit="offer.unit"
|
||||
:stages="[]"
|
||||
@select="selectOffer(offer)"
|
||||
/>
|
||||
<Text v-if="offers.length === 0" tone="muted" size="sm" class="text-center py-4">
|
||||
<Text v-if="offersWithPrice.length === 0" tone="muted" size="sm" class="text-center py-4">
|
||||
{{ t('catalogMap.empty.offers') }}
|
||||
</Text>
|
||||
</template>
|
||||
@@ -54,8 +58,8 @@
|
||||
<!-- Suppliers Tab -->
|
||||
<template v-if="activeTab === 'suppliers'">
|
||||
<SupplierCard
|
||||
v-for="supplier in suppliers"
|
||||
:key="supplier.uuid"
|
||||
v-for="(supplier, index) in suppliers"
|
||||
:key="supplier.uuid ?? index"
|
||||
:supplier="supplier"
|
||||
selectable
|
||||
:is-selected="selectedId === supplier.uuid"
|
||||
@@ -82,11 +86,16 @@ interface Hub {
|
||||
interface Offer {
|
||||
uuid?: string | null
|
||||
title?: string | null
|
||||
productName?: string | null
|
||||
locationName?: string | null
|
||||
supplierName?: string | null
|
||||
status?: string | null
|
||||
latitude?: number | null
|
||||
longitude?: number | null
|
||||
lines?: any[] | null
|
||||
quantity?: number | string | null
|
||||
pricePerUnit?: number | string | null
|
||||
currency?: string | null
|
||||
unit?: string | null
|
||||
}
|
||||
|
||||
interface Supplier {
|
||||
@@ -114,9 +123,13 @@ const selectedId = ref<string | null>(null)
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const offersWithPrice = computed(() =>
|
||||
(props.offers || []).filter(o => o?.pricePerUnit != null)
|
||||
)
|
||||
|
||||
const tabs = computed(() => [
|
||||
{ id: 'hubs' as const, label: 'catalogMap.tabs.hubs', count: props.hubs.length },
|
||||
{ id: 'offers' as const, label: 'catalogMap.tabs.offers', count: props.offers.length },
|
||||
{ id: 'offers' as const, label: 'catalogMap.tabs.offers', count: offersWithPrice.value.length },
|
||||
{ id: 'suppliers' as const, label: 'catalogMap.tabs.suppliers', count: props.suppliers.length }
|
||||
])
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<div v-if="filters && filters.length > 0" class="p-4 border-b border-base-300">
|
||||
<CatalogFilters
|
||||
:filters="filters"
|
||||
:model-value="selectedFilter"
|
||||
:model-value="selectedFilter ?? 'all'"
|
||||
@update:model-value="$emit('update:selectedFilter', $event)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -13,23 +13,30 @@
|
||||
</Stack>
|
||||
|
||||
<Grid :cols="1" :md="2" :lg="3" :gap="4">
|
||||
<OfferCard
|
||||
v-for="offer in offers"
|
||||
:key="offer.uuid"
|
||||
:offer="offer"
|
||||
<OfferResultCard
|
||||
v-for="(offer, index) in offersWithPrice"
|
||||
:key="offer.uuid ?? index"
|
||||
:supplier-name="offer.supplierName"
|
||||
:location-name="offer.locationName"
|
||||
:product-name="offer.title || undefined"
|
||||
:price-per-unit="offer.pricePerUnit ? Number(offer.pricePerUnit) : null"
|
||||
:quantity="offer.quantity"
|
||||
:currency="offer.currency"
|
||||
:unit="offer.unit"
|
||||
:stages="[]"
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Stack v-if="totalOffers > 0" direction="row" align="center" justify="between">
|
||||
<Text tone="muted">
|
||||
{{ t('common.pagination.showing', { shown: offers.length, total: totalOffers }) }}
|
||||
{{ t('common.pagination.showing', { shown: offersWithPrice.length, total: totalOffers }) }}
|
||||
</Text>
|
||||
<Button v-if="canLoadMore" variant="outline" @click="loadMore">
|
||||
{{ t('common.actions.load_more') }}
|
||||
</Button>
|
||||
</Stack>
|
||||
|
||||
<Stack v-if="offers.length === 0" align="center" gap="2">
|
||||
<Stack v-if="offersWithPrice.length === 0" align="center" gap="2">
|
||||
<Text tone="muted">{{ t('catalogOffersSection.empty.no_offers') }}</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
@@ -46,9 +53,14 @@ interface Offer {
|
||||
uuid?: string | null
|
||||
title?: string | null
|
||||
locationName?: string | null
|
||||
supplierName?: string | null
|
||||
status?: string | null
|
||||
validUntil?: string | null
|
||||
lines?: (OfferLine | null)[] | null
|
||||
quantity?: number | string | null
|
||||
pricePerUnit?: number | string | null
|
||||
currency?: string | null
|
||||
unit?: string | null
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -61,7 +73,10 @@ const props = defineProps<{
|
||||
const localePath = useLocalePath()
|
||||
const { t } = useI18n()
|
||||
|
||||
const totalOffers = computed(() => props.total ?? props.offers.length)
|
||||
const offersWithPrice = computed(() =>
|
||||
(props.offers || []).filter(o => o?.pricePerUnit != null)
|
||||
)
|
||||
const totalOffers = computed(() => props.total ?? offersWithPrice.value.length)
|
||||
const canLoadMore = computed(() => props.canLoadMore ?? false)
|
||||
const loadMore = () => {
|
||||
props.onLoadMore?.()
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
<Grid :cols="1" :md="2" :lg="3" :gap="4">
|
||||
<SupplierCard
|
||||
v-for="supplier in suppliers"
|
||||
:key="supplier.uuid"
|
||||
v-for="(supplier, index) in suppliers"
|
||||
:key="supplier.uuid ?? index"
|
||||
:supplier="supplier"
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
@@ -61,11 +61,10 @@
|
||||
<script setup lang="ts">
|
||||
interface SelectedItem {
|
||||
uuid: string
|
||||
name?: string
|
||||
country?: string
|
||||
name?: string | null
|
||||
country?: string | null
|
||||
latitude?: number | null
|
||||
longitude?: number | null
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
|
||||
@@ -16,16 +16,28 @@
|
||||
]"
|
||||
>
|
||||
<div class="flex flex-col gap-1">
|
||||
<!-- Title -->
|
||||
<Text size="base" weight="semibold" class="truncate">{{ hub.name }}</Text>
|
||||
<!-- Country left, distance right -->
|
||||
<!-- Title + distance/compass -->
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<Text size="base" weight="semibold" class="truncate">{{ hub.name }}</Text>
|
||||
<div class="flex items-center gap-2 text-xs text-base-content/60 whitespace-nowrap">
|
||||
<Text v-if="distanceLabel" size="xs" class="text-base-content/60">{{ distanceLabel }}</Text>
|
||||
<div v-if="bearing !== null" class="flex items-center gap-1">
|
||||
<div class="w-6 h-6 rounded-full border border-base-content/10 bg-base-200/40 flex items-center justify-center">
|
||||
<Icon
|
||||
name="lucide:arrow-up"
|
||||
size="12"
|
||||
class="text-base-content/60"
|
||||
:style="{ transform: `rotate(${bearing}deg)` }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Country -->
|
||||
<div class="flex items-center justify-between">
|
||||
<Text tone="muted" size="sm">
|
||||
{{ countryFlag }} {{ hub.country || t('catalogMap.labels.country_unknown') }}
|
||||
</Text>
|
||||
<span v-if="hub.distance" class="badge badge-neutral badge-dash text-xs">
|
||||
{{ hub.distance }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- Transport icons bottom -->
|
||||
<div v-if="hub.transportTypes?.length" class="flex items-center gap-1 pt-1">
|
||||
@@ -47,12 +59,16 @@ interface Hub {
|
||||
name?: string | null
|
||||
country?: string | null
|
||||
countryCode?: string | null
|
||||
latitude?: number | null
|
||||
longitude?: number | null
|
||||
distance?: string
|
||||
transportTypes?: string[] | null
|
||||
distanceKm?: number | null
|
||||
transportTypes?: (string | null)[] | null
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
hub: Hub
|
||||
origin?: { latitude: number; longitude: number } | null
|
||||
selectable?: boolean
|
||||
isSelected?: boolean
|
||||
linkTo?: string
|
||||
@@ -66,7 +82,7 @@ defineEmits<{
|
||||
const localePath = useLocalePath()
|
||||
const { t } = useI18n()
|
||||
|
||||
const linkable = computed(() => !props.selectable && (props.linkTo || props.hub.uuid))
|
||||
const linkable = computed(() => !props.selectable && !!(props.linkTo || props.hub.uuid))
|
||||
const resolvedLink = computed(() => props.linkTo || localePath(`/catalog/hubs/${props.hub.uuid}`))
|
||||
|
||||
// ISO code to emoji flag
|
||||
@@ -81,5 +97,33 @@ const countryFlag = computed(() => {
|
||||
return '🌍'
|
||||
})
|
||||
|
||||
const hasTransport = (type: string) => props.hub.transportTypes?.includes(type)
|
||||
const hasTransport = (type: string) => props.hub.transportTypes?.some(t => t === type)
|
||||
const distanceLabel = computed(() => {
|
||||
if (props.hub.distance) return props.hub.distance
|
||||
if (props.hub.distanceKm != null) return `${Math.round(props.hub.distanceKm)} km`
|
||||
return ''
|
||||
})
|
||||
|
||||
const toRadians = (deg: number) => (deg * Math.PI) / 180
|
||||
const toDegrees = (rad: number) => (rad * 180) / Math.PI
|
||||
|
||||
const bearing = computed(() => {
|
||||
const origin = props.origin
|
||||
const lat2 = props.hub.latitude
|
||||
const lon2 = props.hub.longitude
|
||||
if (!origin || lat2 == null || lon2 == null) return null
|
||||
const lat1 = origin.latitude
|
||||
const lon1 = origin.longitude
|
||||
if (lat1 == null || lon1 == null) return null
|
||||
|
||||
const φ1 = toRadians(lat1)
|
||||
const φ2 = toRadians(lat2)
|
||||
const Δλ = toRadians(lon2 - lon1)
|
||||
|
||||
const y = Math.sin(Δλ) * Math.cos(φ2)
|
||||
const x = Math.cos(φ1) * Math.sin(φ2) - Math.sin(φ1) * Math.cos(φ2) * Math.cos(Δλ)
|
||||
const θ = Math.atan2(y, x)
|
||||
const deg = (toDegrees(θ) + 360) % 360
|
||||
return deg
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
<template>
|
||||
<Card
|
||||
padding="md"
|
||||
interactive
|
||||
class="cursor-pointer overflow-hidden"
|
||||
:class="{ 'bg-base-200': selected }"
|
||||
@click="$emit('select')"
|
||||
>
|
||||
<div class="relative min-h-14">
|
||||
<!-- Sparkline chart background -->
|
||||
<div v-if="priceHistory.length > 1" class="absolute inset-0 opacity-15">
|
||||
<ClientOnly>
|
||||
<apexchart
|
||||
type="area"
|
||||
height="56"
|
||||
:options="chartOptions"
|
||||
:series="chartSeries"
|
||||
/>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="relative z-10">
|
||||
<Text weight="semibold" size="sm" class="mb-1">{{ name }}</Text>
|
||||
<div class="flex items-center gap-2">
|
||||
<Text v-if="currentPrice" size="sm" class="text-primary font-bold">
|
||||
{{ formattedPrice }}
|
||||
</Text>
|
||||
<span
|
||||
v-if="trend !== 0"
|
||||
class="text-xs font-medium"
|
||||
:class="trend > 0 ? 'text-success' : 'text-error'"
|
||||
>
|
||||
{{ trend > 0 ? '↑' : '↓' }} {{ Math.abs(trend) }}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = withDefaults(defineProps<{
|
||||
name: string
|
||||
currentPrice?: number | null
|
||||
currency?: string | null
|
||||
priceHistory?: number[]
|
||||
selected?: boolean
|
||||
}>(), {
|
||||
priceHistory: () => [],
|
||||
selected: false
|
||||
})
|
||||
|
||||
defineEmits<{
|
||||
select: []
|
||||
}>()
|
||||
|
||||
const formattedPrice = computed(() => {
|
||||
if (!props.currentPrice) return ''
|
||||
const symbol = getCurrencySymbol(props.currency)
|
||||
return `${symbol}${props.currentPrice.toLocaleString()}`
|
||||
})
|
||||
|
||||
const getCurrencySymbol = (currency?: string | null) => {
|
||||
switch (currency?.toUpperCase()) {
|
||||
case 'USD': return '$'
|
||||
case 'EUR': return '€'
|
||||
case 'RUB': return '₽'
|
||||
case 'CNY': return '¥'
|
||||
default: return '$'
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate trend from price history
|
||||
const trend = computed(() => {
|
||||
if (props.priceHistory.length < 2) return 0
|
||||
const first = props.priceHistory[0]
|
||||
const last = props.priceHistory[props.priceHistory.length - 1]
|
||||
if (!first || first === 0) return 0
|
||||
return Math.round(((last - first) / first) * 100)
|
||||
})
|
||||
|
||||
// Chart configuration
|
||||
const chartOptions = computed(() => ({
|
||||
chart: {
|
||||
type: 'area',
|
||||
sparkline: { enabled: true },
|
||||
animations: { enabled: false }
|
||||
},
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
width: 2
|
||||
},
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shadeIntensity: 1,
|
||||
opacityFrom: 0.4,
|
||||
opacityTo: 0.1
|
||||
}
|
||||
},
|
||||
colors: [trend.value >= 0 ? '#22c55e' : '#ef4444'],
|
||||
tooltip: { enabled: false },
|
||||
xaxis: { labels: { show: false } },
|
||||
yaxis: { labels: { show: false } }
|
||||
}))
|
||||
|
||||
const chartSeries = computed(() => [{
|
||||
name: 'Price',
|
||||
data: props.priceHistory.length > 0 ? props.priceHistory : [0]
|
||||
}])
|
||||
</script>
|
||||
504
app/components/catalog/InfoPanel.vue
Normal file
504
app/components/catalog/InfoPanel.vue
Normal file
@@ -0,0 +1,504 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<!-- Header with close button -->
|
||||
<div class="flex-shrink-0 p-4 border-b border-white/10">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div
|
||||
class="flex items-center justify-center w-6 h-6 rounded-full"
|
||||
:style="{ backgroundColor: badgeColor }"
|
||||
>
|
||||
<Icon :name="entityIcon" size="14" class="text-white" />
|
||||
</div>
|
||||
<h3 class="font-semibold text-base text-white">{{ entityName }}</h3>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
v-if="(entityType === 'hub' || entityType === 'supplier') && entity?.uuid"
|
||||
class="rounded-full glass-bright border border-white/30 shadow-lg p-1.5 transition-transform hover:scale-105"
|
||||
@click="emit('pin', entityType, { uuid: entity?.uuid, name: entity?.name })"
|
||||
aria-label="Pin"
|
||||
title="Pin"
|
||||
>
|
||||
<Icon name="lucide:pin" size="16" class="text-white" />
|
||||
</button>
|
||||
<button class="btn btn-ghost btn-xs btn-circle text-white/60 hover:text-white" @click="emit('close')">
|
||||
<Icon name="lucide:x" size="16" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content (scrollable) -->
|
||||
<div class="flex-1 overflow-y-auto p-4">
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="flex items-center justify-center py-8">
|
||||
<span class="loading loading-spinner loading-md text-white" />
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div v-else-if="entity" class="flex flex-col gap-4">
|
||||
<!-- Entity Info Header (text, not card) -->
|
||||
<div class="mb-2">
|
||||
<!-- Location for hub/supplier -->
|
||||
<p v-if="entityLocation" class="text-sm text-white/70 flex items-center gap-1">
|
||||
<Icon name="lucide:map-pin" size="14" />
|
||||
{{ entityLocation }}
|
||||
</p>
|
||||
|
||||
<!-- Price for offer -->
|
||||
<p v-if="entityType === 'offer' && entity?.pricePerUnit" class="text-sm text-white/70 flex items-center gap-1">
|
||||
<Icon name="lucide:tag" size="14" />
|
||||
{{ formatPrice(entity.pricePerUnit) }} {{ entity.currency || 'RUB' }}/{{ entity.unit || 't' }}
|
||||
</p>
|
||||
|
||||
<!-- Supplier for offer (clickable name) -->
|
||||
<button
|
||||
v-if="entityType === 'offer' && entity?.teamUuid"
|
||||
class="text-sm text-primary hover:underline flex items-center gap-1 mt-1"
|
||||
@click="emit('open-info', 'supplier', entity.teamUuid)"
|
||||
>
|
||||
<Icon name="lucide:factory" size="14" />
|
||||
<span v-if="loadingSuppliers" class="loading loading-spinner loading-xs" />
|
||||
<span v-else>{{ supplierDisplayName || $t('catalog.info.supplier') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- KYC Teaser Section (for supplier) -->
|
||||
<section v-if="entityType === 'supplier' && kycTeaser" class="bg-white/5 rounded-lg p-3">
|
||||
<h3 class="text-sm font-semibold text-white/80 mb-2 flex items-center gap-2">
|
||||
<Icon name="lucide:shield-check" size="16" />
|
||||
{{ $t('catalog.info.kycTeaser') }}
|
||||
</h3>
|
||||
|
||||
<div class="flex flex-col gap-2 text-sm">
|
||||
<!-- Company Type -->
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-white/60">{{ $t('catalog.info.companyType') }}</span>
|
||||
<span class="text-white">{{ kycTeaser.companyType }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Registration Year -->
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-white/60">{{ $t('catalog.info.registrationYear') }}</span>
|
||||
<span class="text-white">{{ kycTeaser.registrationYear }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Status -->
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-white/60">{{ $t('catalog.info.status') }}</span>
|
||||
<span :class="kycTeaser.isActive ? 'text-success' : 'text-error'">
|
||||
{{ kycTeaser.isActive ? $t('catalog.info.active') : $t('catalog.info.inactive') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Sources Count -->
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-white/60">{{ $t('catalog.info.sourcesCount') }}</span>
|
||||
<span class="text-white">{{ kycTeaser.sourcesCount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- View Full Profile Button -->
|
||||
<button
|
||||
class="btn btn-ghost btn-xs text-primary mt-3 w-full"
|
||||
@click="emit('open-kyc', kycProfileUuid)"
|
||||
>
|
||||
<Icon name="lucide:external-link" size="14" />
|
||||
{{ $t('catalog.info.viewFullKyc') }}
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<!-- Products Section (for hub/supplier) - hide when product selected -->
|
||||
<section v-if="(entityType === 'hub' || entityType === 'supplier') && !selectedProduct">
|
||||
<h3 class="text-sm font-semibold text-white/80 mb-2 flex items-center gap-2">
|
||||
<Icon name="lucide:package" size="16" />
|
||||
{{ productsSectionTitle }}
|
||||
<span v-if="loadingProducts" class="loading loading-spinner loading-xs" />
|
||||
<span v-else-if="relatedProducts.length > 0" class="text-white/50">({{ relatedProducts.length }})</span>
|
||||
</h3>
|
||||
|
||||
<div v-if="!loadingProducts && relatedProducts.length === 0" class="text-white/50 text-sm py-2">
|
||||
{{ $t('catalog.empty.noProducts') }}
|
||||
</div>
|
||||
<div v-else-if="!loadingProducts" class="flex flex-col gap-2">
|
||||
<div
|
||||
v-for="(product, index) in relatedProducts"
|
||||
:key="product.uuid ?? index"
|
||||
class="relative group"
|
||||
>
|
||||
<ProductCard
|
||||
:product="product"
|
||||
compact
|
||||
selectable
|
||||
@select="onProductSelect(product)"
|
||||
/>
|
||||
<button
|
||||
class="absolute -top-2 -right-2 opacity-0 group-hover:opacity-100 transition-opacity rounded-full glass-bright border border-white/30 shadow-lg p-1.5 hover:scale-105"
|
||||
@click.stop="emit('pin', 'product', product)"
|
||||
aria-label="Pin product"
|
||||
title="Pin"
|
||||
>
|
||||
<Icon name="lucide:pin" size="16" class="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Offers Section (after product selected) -->
|
||||
<section v-if="(entityType === 'hub' || entityType === 'supplier') && selectedProduct">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<h3 class="text-sm font-semibold text-white/80 flex items-center gap-2">
|
||||
<Icon name="lucide:shopping-bag" size="16" />
|
||||
{{ $t('catalog.headers.offers') }}
|
||||
<span v-if="loadingOffers" class="loading loading-spinner loading-xs" />
|
||||
<span v-else-if="offersWithPrice.length > 0" class="text-white/50">({{ offersWithPrice.length }})</span>
|
||||
</h3>
|
||||
<button
|
||||
class="flex items-center gap-2 px-2 py-1 rounded-full border border-white/15 bg-white/10 text-xs text-white/80 hover:bg-white/20 transition-colors"
|
||||
@click="emit('select-product', null)"
|
||||
>
|
||||
<Icon name="lucide:package" size="12" />
|
||||
<span class="max-w-32 truncate">{{ selectedProductName }}</span>
|
||||
<Icon name="lucide:x" size="12" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="!loadingOffers && offersWithPrice.length === 0" class="text-white/50 text-sm py-2">
|
||||
{{ $t('catalog.empty.noOffers') }}
|
||||
</div>
|
||||
<div v-else-if="!loadingOffers" class="flex flex-col gap-2">
|
||||
<OfferResultCard
|
||||
v-for="(offer, index) in offersWithPrice"
|
||||
:key="offer.uuid ?? index"
|
||||
:supplier-name="getOfferSupplierName(offer)"
|
||||
:location-name="offer.country || ''"
|
||||
:product-name="offer.productName"
|
||||
:price-per-unit="offer.pricePerUnit ? Number(offer.pricePerUnit) : null"
|
||||
:quantity="offer.quantity"
|
||||
:currency="offer.currency"
|
||||
:unit="offer.unit"
|
||||
:stages="getOfferStages(offer)"
|
||||
:total-time-seconds="offer.routes?.[0]?.totalTimeSeconds ?? null"
|
||||
@select="onOfferSelect(offer)"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Suppliers Section (for hub only) -->
|
||||
<section v-if="entityType === 'hub' && !selectedProduct">
|
||||
<h3 class="text-sm font-semibold text-white/80 mb-2 flex items-center gap-2">
|
||||
<Icon name="lucide:factory" size="16" />
|
||||
{{ $t('catalog.info.suppliersNearby') }}
|
||||
<span v-if="loadingSuppliers" class="loading loading-spinner loading-xs" />
|
||||
<span v-else-if="relatedSuppliers.length > 0" class="text-white/50">({{ relatedSuppliers.length }})</span>
|
||||
</h3>
|
||||
|
||||
<div v-if="!loadingSuppliers && relatedSuppliers.length === 0" class="text-white/50 text-sm py-2">
|
||||
{{ $t('catalog.info.noSuppliers') }}
|
||||
</div>
|
||||
<div v-else-if="!loadingSuppliers" class="flex flex-col gap-2">
|
||||
<div
|
||||
v-for="(supplier, index) in relatedSuppliers"
|
||||
:key="supplier.uuid ?? index"
|
||||
class="relative group"
|
||||
>
|
||||
<SupplierCard
|
||||
:supplier="supplier"
|
||||
selectable
|
||||
@select="onSupplierSelect(supplier)"
|
||||
/>
|
||||
<button
|
||||
class="absolute -top-2 -right-2 opacity-0 group-hover:opacity-100 transition-opacity rounded-full glass-bright border border-white/30 shadow-lg p-1.5 hover:scale-105"
|
||||
@click.stop="emit('pin', 'supplier', supplier)"
|
||||
aria-label="Pin supplier"
|
||||
title="Pin"
|
||||
>
|
||||
<Icon name="lucide:pin" size="16" class="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Hubs Section (for supplier/offer) -->
|
||||
<section v-if="entityType === 'supplier' || entityType === 'offer'">
|
||||
<h3 class="text-sm font-semibold text-white/80 mb-2 flex items-center gap-2">
|
||||
<Icon name="lucide:warehouse" size="16" />
|
||||
{{ $t('catalog.info.nearestHubs') }}
|
||||
<span v-if="loadingHubs" class="loading loading-spinner loading-xs" />
|
||||
<span v-else-if="relatedHubs.length > 0" class="text-white/50">({{ relatedHubs.length }})</span>
|
||||
</h3>
|
||||
|
||||
<div v-if="!loadingHubs && relatedHubs.length === 0" class="text-white/50 text-sm py-2">
|
||||
{{ $t('catalog.info.noHubs') }}
|
||||
</div>
|
||||
<div v-else-if="!loadingHubs" class="space-y-4">
|
||||
<template v-if="railHubs.length">
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<Card padding="small" class="border border-white/10 bg-white/5">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-8 h-8 rounded-lg bg-white/10 flex items-center justify-center">
|
||||
<Icon name="lucide:train-front" size="16" class="text-white/80" />
|
||||
</div>
|
||||
<div class="text-sm text-white/80">{{ $t('catalog.info.railHubs') }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
<div
|
||||
v-for="(hub, index) in railHubs"
|
||||
:key="hub.uuid ?? index"
|
||||
class="relative group"
|
||||
>
|
||||
<HubCard
|
||||
:hub="hub"
|
||||
:origin="originCoords"
|
||||
selectable
|
||||
@select="onHubSelect(hub)"
|
||||
/>
|
||||
<button
|
||||
class="absolute -top-2 -right-2 opacity-0 group-hover:opacity-100 transition-opacity rounded-full glass-bright border border-white/30 shadow-lg p-1.5 hover:scale-105"
|
||||
@click.stop="emit('pin', 'hub', hub)"
|
||||
aria-label="Pin hub"
|
||||
title="Pin"
|
||||
>
|
||||
<Icon name="lucide:pin" size="16" class="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="seaHubs.length">
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<Card padding="small" class="border border-white/10 bg-white/5">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-8 h-8 rounded-lg bg-white/10 flex items-center justify-center">
|
||||
<Icon name="lucide:ship" size="16" class="text-white/80" />
|
||||
</div>
|
||||
<div class="text-sm text-white/80">{{ $t('catalog.info.seaHubs') }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
<div
|
||||
v-for="(hub, index) in seaHubs"
|
||||
:key="hub.uuid ?? index"
|
||||
class="relative group"
|
||||
>
|
||||
<HubCard
|
||||
:hub="hub"
|
||||
:origin="originCoords"
|
||||
selectable
|
||||
@select="onHubSelect(hub)"
|
||||
/>
|
||||
<button
|
||||
class="absolute -top-2 -right-2 opacity-0 group-hover:opacity-100 transition-opacity rounded-full glass-bright border border-white/30 shadow-lg p-1.5 hover:scale-105"
|
||||
@click.stop="emit('pin', 'hub', hub)"
|
||||
aria-label="Pin hub"
|
||||
title="Pin"
|
||||
>
|
||||
<Icon name="lucide:pin" size="16" class="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { InfoEntityType } from '~/composables/useCatalogSearch'
|
||||
import type {
|
||||
InfoEntity,
|
||||
InfoProductItem,
|
||||
InfoHubItem,
|
||||
InfoSupplierItem,
|
||||
InfoOfferItem
|
||||
} from '~/composables/useCatalogInfo'
|
||||
import type { RouteStage } from '~/composables/graphql/public/geo-generated'
|
||||
|
||||
const props = defineProps<{
|
||||
entityType: InfoEntityType
|
||||
entityId: string
|
||||
entity: InfoEntity | null
|
||||
relatedProducts?: InfoProductItem[]
|
||||
relatedHubs?: InfoHubItem[]
|
||||
relatedSuppliers?: InfoSupplierItem[]
|
||||
relatedOffers?: InfoOfferItem[]
|
||||
selectedProduct?: string | null
|
||||
currentTab?: string
|
||||
loading?: boolean
|
||||
loadingProducts?: boolean
|
||||
loadingHubs?: boolean
|
||||
loadingSuppliers?: boolean
|
||||
loadingOffers?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'close': []
|
||||
'open-info': [type: InfoEntityType, uuid: string]
|
||||
'select-product': [uuid: string | null]
|
||||
'select-offer': [offer: { uuid: string; productUuid?: string | null }]
|
||||
'update:current-tab': [tab: string]
|
||||
'open-kyc': [uuid: string | undefined]
|
||||
'pin': [type: 'product' | 'hub' | 'supplier', item: { uuid?: string | null; name?: string | null }]
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const { entityColors } = useCatalogSearch()
|
||||
|
||||
// Safe accessors for optional arrays
|
||||
const relatedProducts = computed(() => props.relatedProducts ?? [])
|
||||
const relatedHubs = computed(() => props.relatedHubs ?? [])
|
||||
const relatedSuppliers = computed(() => props.relatedSuppliers ?? [])
|
||||
const relatedOffers = computed(() => props.relatedOffers ?? [])
|
||||
const offersWithPrice = computed(() =>
|
||||
relatedOffers.value.filter(o => o?.pricePerUnit != null)
|
||||
)
|
||||
|
||||
const suppliersByUuid = computed(() => {
|
||||
const map = new Map<string, string>()
|
||||
relatedSuppliers.value.forEach(supplier => {
|
||||
if (supplier?.uuid && supplier?.name) {
|
||||
map.set(supplier.uuid, supplier.name)
|
||||
}
|
||||
if (supplier?.teamUuid && supplier?.name) {
|
||||
map.set(supplier.teamUuid, supplier.name)
|
||||
}
|
||||
})
|
||||
return map
|
||||
})
|
||||
|
||||
const getOfferSupplierName = (offer: InfoOfferItem) => {
|
||||
if (offer.supplierName) return offer.supplierName
|
||||
if (offer.supplierUuid && suppliersByUuid.value.has(offer.supplierUuid)) {
|
||||
return suppliersByUuid.value.get(offer.supplierUuid)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const selectedProductName = computed(() => {
|
||||
if (!props.selectedProduct) return ''
|
||||
const match = relatedProducts.value.find(p => p.uuid === props.selectedProduct)
|
||||
return match?.name || props.selectedProduct.slice(0, 8) + '...'
|
||||
})
|
||||
|
||||
// Entity name
|
||||
const entityName = computed(() => {
|
||||
return props.entity?.name || props.entity?.productName || props.entityId.slice(0, 8) + '...'
|
||||
})
|
||||
|
||||
// Entity location (address, city, country)
|
||||
const entityLocation = computed(() => {
|
||||
if (!props.entity) return null
|
||||
const parts = [props.entity.address, props.entity.city, props.entity.country].filter(Boolean)
|
||||
return parts.length > 0 ? parts.join(', ') : null
|
||||
})
|
||||
|
||||
const originCoords = computed(() => {
|
||||
const lat = props.entity?.locationLatitude ?? props.entity?.latitude
|
||||
const lon = props.entity?.locationLongitude ?? props.entity?.longitude
|
||||
if (lat == null || lon == null) return null
|
||||
return { latitude: Number(lat), longitude: Number(lon) }
|
||||
})
|
||||
|
||||
// Products section title based on entity type
|
||||
const productsSectionTitle = computed(() => {
|
||||
return props.entityType === 'hub'
|
||||
? t('catalog.info.productsHere')
|
||||
: t('catalog.info.productsFromSupplier')
|
||||
})
|
||||
|
||||
// Badge color
|
||||
const badgeColor = computed(() => {
|
||||
if (props.entityType === 'hub') return entityColors.hub
|
||||
if (props.entityType === 'supplier') return entityColors.supplier
|
||||
if (props.entityType === 'offer') return entityColors.offer
|
||||
return '#666'
|
||||
})
|
||||
|
||||
const entityIcon = computed(() => {
|
||||
if (props.entityType === 'hub') return 'lucide:warehouse'
|
||||
if (props.entityType === 'supplier') return 'lucide:factory'
|
||||
if (props.entityType === 'offer') return 'lucide:shopping-bag'
|
||||
return 'lucide:info'
|
||||
})
|
||||
|
||||
// Supplier name for offer (from entity or relatedSuppliers)
|
||||
const supplierDisplayName = computed(() => {
|
||||
if (props.entity?.supplierName) return props.entity.supplierName
|
||||
if (props.entity?.teamName) return props.entity.teamName
|
||||
if (relatedSuppliers.value.length > 0 && relatedSuppliers.value[0]?.name) {
|
||||
return relatedSuppliers.value[0].name
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
// Format price
|
||||
const formatPrice = (price: number | string) => {
|
||||
const num = typeof price === 'string' ? parseFloat(price) : price
|
||||
return new Intl.NumberFormat('ru-RU').format(num)
|
||||
}
|
||||
|
||||
const railHubs = computed(() =>
|
||||
relatedHubs.value.filter(h => h.transportTypes?.includes('rail'))
|
||||
)
|
||||
|
||||
const seaHubs = computed(() =>
|
||||
relatedHubs.value.filter(h => h.transportTypes?.includes('sea'))
|
||||
)
|
||||
|
||||
// Mock KYC teaser data (will be replaced with real data later)
|
||||
const kycTeaser = computed(() => {
|
||||
if (props.entityType !== 'supplier') return null
|
||||
// Mock data for now
|
||||
return {
|
||||
companyType: 'ООО',
|
||||
registrationYear: 2018,
|
||||
isActive: true,
|
||||
sourcesCount: 3
|
||||
}
|
||||
})
|
||||
|
||||
// KYC Profile UUID - use real if available, otherwise mock for demo
|
||||
const MOCK_KYC_UUID = 'demo-kyc-profile'
|
||||
const kycProfileUuid = computed(() => {
|
||||
return props.entity?.kycProfileUuid || MOCK_KYC_UUID
|
||||
})
|
||||
|
||||
// Handlers for selecting related items
|
||||
const onProductSelect = (product: InfoProductItem) => {
|
||||
emit('select-product', product.uuid)
|
||||
}
|
||||
|
||||
const onOfferSelect = (offer: InfoOfferItem) => {
|
||||
if (offer.uuid) {
|
||||
emit('select-offer', { uuid: offer.uuid, productUuid: offer.productUuid })
|
||||
}
|
||||
}
|
||||
|
||||
const onHubSelect = (hub: InfoHubItem) => {
|
||||
if (hub.uuid) {
|
||||
emit('open-info', 'hub', hub.uuid)
|
||||
}
|
||||
}
|
||||
|
||||
const onSupplierSelect = (supplier: InfoSupplierItem) => {
|
||||
if (supplier.uuid) {
|
||||
emit('open-info', 'supplier', supplier.uuid)
|
||||
}
|
||||
}
|
||||
|
||||
const getOfferStages = (offer: InfoOfferItem) => {
|
||||
const route = offer.routes?.[0]
|
||||
if (!route?.stages) return []
|
||||
return route.stages
|
||||
.filter((stage): stage is NonNullable<RouteStage> => stage !== null)
|
||||
.map(stage => ({
|
||||
transportType: stage.transportType,
|
||||
distanceKm: stage.distanceKm,
|
||||
travelTimeSeconds: stage.travelTimeSeconds,
|
||||
fromName: stage.fromName
|
||||
}))
|
||||
}
|
||||
</script>
|
||||
304
app/components/catalog/KycBottomSheet.vue
Normal file
304
app/components/catalog/KycBottomSheet.vue
Normal file
@@ -0,0 +1,304 @@
|
||||
<template>
|
||||
<Transition name="kyc-slide">
|
||||
<div
|
||||
v-if="isOpen"
|
||||
class="fixed inset-x-0 bottom-0 z-50 flex flex-col"
|
||||
style="height: 70vh"
|
||||
>
|
||||
<!-- Backdrop (clickable to close) -->
|
||||
<div
|
||||
class="absolute inset-0 -top-[30vh] bg-black/30"
|
||||
@click="emit('close')"
|
||||
/>
|
||||
|
||||
<!-- Sheet content -->
|
||||
<div class="relative flex-1 bg-black/40 backdrop-blur-xl rounded-t-2xl border-t border-white/20 shadow-2xl overflow-hidden">
|
||||
<!-- Header with drag handle and close -->
|
||||
<div class="sticky top-0 z-10 bg-black/30 backdrop-blur-md border-b border-white/10">
|
||||
<div class="flex justify-center py-2">
|
||||
<div class="w-12 h-1.5 bg-white/30 rounded-full" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between px-6 pb-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 bg-primary/20 rounded-xl flex items-center justify-center">
|
||||
<Icon name="lucide:building-2" size="24" class="text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<Text weight="bold" size="lg" class="text-white">{{ companyName }}</Text>
|
||||
<div class="flex items-center gap-2 mt-0.5">
|
||||
<span class="badge badge-success badge-sm">{{ $t('catalog.info.active') }}</span>
|
||||
<span class="badge badge-outline badge-sm text-white/60">{{ companyType }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-ghost btn-sm btn-circle text-white/60 hover:text-white" @click="emit('close')">
|
||||
<Icon name="lucide:x" size="20" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Scrollable content -->
|
||||
<div class="overflow-y-auto h-[calc(70vh-100px)] px-6 py-4">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<!-- Left Column -->
|
||||
<div class="flex flex-col gap-4">
|
||||
<!-- Реквизиты -->
|
||||
<div class="bg-white/5 rounded-xl p-4 border border-white/10">
|
||||
<Text weight="semibold" class="text-white mb-3 flex items-center gap-2">
|
||||
<Icon name="lucide:file-text" size="18" />
|
||||
Реквизиты
|
||||
</Text>
|
||||
<div class="grid grid-cols-2 gap-3 text-sm">
|
||||
<div>
|
||||
<Text tone="muted" size="xs" class="text-white/50">ИНН</Text>
|
||||
<Text class="text-white font-mono">{{ inn }}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text tone="muted" size="xs" class="text-white/50">КПП</Text>
|
||||
<Text class="text-white font-mono">{{ kpp }}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text tone="muted" size="xs" class="text-white/50">ОГРН</Text>
|
||||
<Text class="text-white font-mono">{{ ogrn }}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text tone="muted" size="xs" class="text-white/50">Год регистрации</Text>
|
||||
<Text class="text-white">{{ registrationYear }}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Руководство -->
|
||||
<div class="bg-white/5 rounded-xl p-4 border border-white/10">
|
||||
<Text weight="semibold" class="text-white mb-3 flex items-center gap-2">
|
||||
<Icon name="lucide:user-cog" size="18" />
|
||||
Руководство
|
||||
</Text>
|
||||
<div class="flex items-center gap-3 p-2 bg-white/5 rounded-lg">
|
||||
<div class="avatar placeholder">
|
||||
<div class="w-9 h-9 rounded-full bg-primary text-primary-content text-sm">
|
||||
<span>{{ directorInitials }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Text weight="medium" size="sm" class="text-white">{{ directorName }}</Text>
|
||||
<Text size="xs" class="text-white/50">Генеральный директор</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Учредители -->
|
||||
<div class="bg-white/5 rounded-xl p-4 border border-white/10">
|
||||
<Text weight="semibold" class="text-white mb-3 flex items-center gap-2">
|
||||
<Icon name="lucide:users" size="18" />
|
||||
Учредители
|
||||
</Text>
|
||||
<div class="space-y-2">
|
||||
<div
|
||||
v-for="(founder, i) in founders"
|
||||
:key="i"
|
||||
class="flex items-center justify-between p-2 bg-white/5 rounded-lg"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="avatar placeholder">
|
||||
<div class="w-8 h-8 rounded-full bg-secondary text-secondary-content text-xs">
|
||||
<span>{{ founder.initials }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Text size="sm" class="text-white">{{ founder.name }}</Text>
|
||||
<Text size="xs" class="text-white/50">Физ. лицо</Text>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge badge-primary badge-sm">{{ founder.share }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 pt-3 border-t border-white/10 flex justify-between">
|
||||
<Text size="xs" class="text-white/50">Уставный капитал</Text>
|
||||
<Text weight="semibold" size="sm" class="text-white">{{ authorizedCapital }}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column -->
|
||||
<div class="flex flex-col gap-4">
|
||||
<!-- Контакты -->
|
||||
<div class="bg-white/5 rounded-xl p-4 border border-white/10">
|
||||
<Text weight="semibold" class="text-white mb-3 flex items-center gap-2">
|
||||
<Icon name="lucide:contact" size="18" />
|
||||
Контакты
|
||||
</Text>
|
||||
<div class="space-y-2 text-sm">
|
||||
<div class="flex items-center gap-2 text-white/80">
|
||||
<Icon name="lucide:map-pin" size="14" class="text-white/50" />
|
||||
<span>{{ address }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-white/80">
|
||||
<Icon name="lucide:phone" size="14" class="text-white/50" />
|
||||
<span>{{ phone }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-white/80">
|
||||
<Icon name="lucide:mail" size="14" class="text-white/50" />
|
||||
<span>{{ email }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Финансы -->
|
||||
<div class="bg-white/5 rounded-xl p-4 border border-white/10">
|
||||
<Text weight="semibold" class="text-white mb-3 flex items-center gap-2">
|
||||
<Icon name="lucide:bar-chart-3" size="18" />
|
||||
Финансы (2024)
|
||||
</Text>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<div class="flex justify-between mb-1">
|
||||
<Text size="xs" class="text-white/50">Выручка</Text>
|
||||
<Text size="xs" class="text-success">↑ 15%</Text>
|
||||
</div>
|
||||
<Text weight="bold" class="text-white">{{ revenue }}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex justify-between mb-1">
|
||||
<Text size="xs" class="text-white/50">Чистая прибыль</Text>
|
||||
<Text size="xs" class="text-success">↑ 23%</Text>
|
||||
</div>
|
||||
<Text weight="bold" class="text-white">{{ profit }}</Text>
|
||||
</div>
|
||||
<div class="pt-2 border-t border-white/10 flex justify-between">
|
||||
<Text size="xs" class="text-white/50">Сотрудников</Text>
|
||||
<Text weight="medium" size="sm" class="text-white">{{ employees }}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Арбитраж -->
|
||||
<div class="bg-white/5 rounded-xl p-4 border border-white/10">
|
||||
<Text weight="semibold" class="text-white mb-3 flex items-center gap-2">
|
||||
<Icon name="lucide:scale" size="18" />
|
||||
Арбитражные дела
|
||||
</Text>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="badge badge-warning badge-xs">Истец</span>
|
||||
<Text class="text-white/80">{{ arbitration.plaintiff.count }} дела</Text>
|
||||
</div>
|
||||
<Text class="text-white">{{ arbitration.plaintiff.amount }}</Text>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="badge badge-error badge-xs">Ответчик</span>
|
||||
<Text class="text-white/80">{{ arbitration.defendant.count }} дело</Text>
|
||||
</div>
|
||||
<Text class="text-white">{{ arbitration.defendant.amount }}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ОКВЭД (full width) -->
|
||||
<div class="mt-4 bg-white/5 rounded-xl p-4 border border-white/10">
|
||||
<Text weight="semibold" class="text-white mb-3 flex items-center gap-2">
|
||||
<Icon name="lucide:briefcase" size="18" />
|
||||
Виды деятельности (ОКВЭД)
|
||||
</Text>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-start gap-2 p-2 bg-primary/10 rounded-lg border border-primary/20">
|
||||
<span class="badge badge-primary badge-xs mt-0.5">Осн.</span>
|
||||
<Text size="sm" class="text-white">{{ mainActivity }}</Text>
|
||||
</div>
|
||||
<div
|
||||
v-for="(activity, i) in additionalActivities"
|
||||
:key="i"
|
||||
class="flex items-start gap-2 p-2 bg-white/5 rounded-lg"
|
||||
>
|
||||
<span class="badge badge-ghost badge-xs mt-0.5 text-white/50">Доп.</span>
|
||||
<Text size="sm" class="text-white/80">{{ activity }}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sources footer -->
|
||||
<div class="mt-4 flex items-center justify-between text-xs text-white/40 px-1">
|
||||
<span class="flex items-center gap-1">
|
||||
<Icon name="lucide:database" size="12" />
|
||||
Источники: ЕГРЮЛ, ФНС, Росстат
|
||||
</span>
|
||||
<span>Обновлено: {{ lastUpdated }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Demo notice -->
|
||||
<div class="mt-4 alert bg-info/20 border border-info/30 text-info text-sm">
|
||||
<Icon name="lucide:info" size="16" />
|
||||
<span>{{ $t('kyc.demo.notice') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
isOpen: boolean
|
||||
uuid: string | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'close': []
|
||||
}>()
|
||||
|
||||
// Demo data (will be replaced with real data from API)
|
||||
const isDemo = computed(() => props.uuid === 'demo-kyc-profile')
|
||||
|
||||
const companyName = computed(() => isDemo.value ? 'ООО "АГРОТОРГ ПЛЮС"' : 'Загрузка...')
|
||||
const companyType = computed(() => 'ООО')
|
||||
const inn = computed(() => '7707456789')
|
||||
const kpp = computed(() => '770701001')
|
||||
const ogrn = computed(() => '1157746123456')
|
||||
const registrationYear = computed(() => '2015')
|
||||
const directorName = computed(() => 'Петров Сергей Александрович')
|
||||
const directorInitials = computed(() => 'ПС')
|
||||
const founders = computed(() => [
|
||||
{ name: 'Петров Сергей Александрович', initials: 'ПС', share: 60 },
|
||||
{ name: 'Иванова Анна Петровна', initials: 'ИА', share: 40 }
|
||||
])
|
||||
const authorizedCapital = computed(() => '500 000 ₽')
|
||||
const address = computed(() => 'г. Москва, ул. Складская, д. 15, оф. 301')
|
||||
const phone = computed(() => '+7 (495) 123-45-67')
|
||||
const email = computed(() => 'info@agrotorg-plus.ru')
|
||||
const revenue = computed(() => '245 800 000 ₽')
|
||||
const profit = computed(() => '18 450 000 ₽')
|
||||
const employees = computed(() => '47 человек')
|
||||
const arbitration = computed(() => ({
|
||||
plaintiff: { count: 3, amount: '1 250 000 ₽' },
|
||||
defendant: { count: 1, amount: '320 000 ₽' }
|
||||
}))
|
||||
const mainActivity = computed(() => '46.21 - Торговля оптовая зерном, семенами и кормами')
|
||||
const additionalActivities = computed(() => [
|
||||
'46.11 - Деятельность агентов по оптовой торговле',
|
||||
'52.10 - Деятельность по складированию и хранению'
|
||||
])
|
||||
const lastUpdated = computed(() => new Date().toLocaleDateString('ru-RU'))
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.kyc-slide-enter-active,
|
||||
.kyc-slide-leave-active {
|
||||
transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.kyc-slide-enter-from,
|
||||
.kyc-slide-leave-to {
|
||||
transform: translateY(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.kyc-slide-enter-to,
|
||||
.kyc-slide-leave-from {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
13
app/components/catalog/MapPanel.vue
Normal file
13
app/components/catalog/MapPanel.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<!-- Header: белое стекло (negative margins to expand beyond parent padding) -->
|
||||
<div class="sticky top-0 z-10 -mx-4 -mt-4 px-4 pt-4 pb-3 rounded-t-xl bg-white/90 backdrop-blur-md border-b border-white/20">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
|
||||
<!-- Content: тёмный (negative margins to expand beyond parent padding) -->
|
||||
<div class="flex-1 -mx-4 -mb-4 px-4 pt-3 pb-4 overflow-y-auto">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,118 +0,0 @@
|
||||
<template>
|
||||
<component
|
||||
:is="linkable ? NuxtLink : 'div'"
|
||||
:to="linkable ? localePath(`/catalog/offers/detail/${offer.uuid}`) : undefined"
|
||||
class="block"
|
||||
:class="{ 'cursor-pointer': selectable }"
|
||||
@click="selectable && $emit('select')"
|
||||
>
|
||||
<Card
|
||||
padding="small"
|
||||
:interactive="linkable || selectable"
|
||||
:class="[
|
||||
isSelected && 'ring-2 ring-primary ring-offset-2'
|
||||
]"
|
||||
>
|
||||
<div class="flex flex-col gap-1">
|
||||
<!-- Product title -->
|
||||
<Text size="base" weight="semibold" class="truncate">{{ offer.productName }}</Text>
|
||||
<!-- Quantity -->
|
||||
<div v-if="offer.quantity" class="flex">
|
||||
<span class="badge badge-neutral badge-dash text-xs">
|
||||
{{ t('catalogOfferCard.labels.quantity_with_unit', { quantity: offer.quantity, unit: displayUnit }) }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- Price -->
|
||||
<div v-if="offer.pricePerUnit" class="font-semibold text-primary text-sm">
|
||||
{{ formatPrice(offer.pricePerUnit, offer.currency) }}/{{ displayUnit }}
|
||||
</div>
|
||||
<!-- Country below -->
|
||||
<Text v-if="!compact" tone="muted" size="sm">
|
||||
{{ countryFlag }} {{ offer.locationCountry || offer.locationName || t('catalogOfferCard.labels.country_unknown') }}
|
||||
</Text>
|
||||
</div>
|
||||
</Card>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NuxtLink } from '#components'
|
||||
|
||||
interface Offer {
|
||||
uuid?: string | null
|
||||
// Product
|
||||
productUuid?: string | null
|
||||
productName?: string | null
|
||||
categoryName?: string | null
|
||||
// Location
|
||||
locationUuid?: string | null
|
||||
locationName?: string | null
|
||||
locationCountry?: string | null
|
||||
locationCountryCode?: string | null
|
||||
// Price
|
||||
quantity?: number | string | null
|
||||
unit?: string | null
|
||||
pricePerUnit?: number | string | null
|
||||
currency?: string | null
|
||||
// Misc
|
||||
status?: string | null
|
||||
validUntil?: string | null
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
offer: Offer
|
||||
selectable?: boolean
|
||||
isSelected?: boolean
|
||||
compact?: boolean
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
(e: 'select'): void
|
||||
}>()
|
||||
|
||||
const localePath = useLocalePath()
|
||||
const { t } = useI18n()
|
||||
|
||||
const linkable = computed(() => !props.selectable && props.offer.uuid)
|
||||
|
||||
const formattedDate = computed(() => {
|
||||
if (!props.offer.validUntil) return ''
|
||||
try {
|
||||
return new Intl.DateTimeFormat('ru', {
|
||||
day: 'numeric',
|
||||
month: 'short'
|
||||
}).format(new Date(props.offer.validUntil))
|
||||
} catch {
|
||||
return props.offer.validUntil
|
||||
}
|
||||
})
|
||||
|
||||
const formatPrice = (price: number | string | null | undefined, currency: string | null | undefined) => {
|
||||
if (!price) return ''
|
||||
const num = typeof price === 'string' ? parseFloat(price) : price
|
||||
const curr = currency || 'USD'
|
||||
try {
|
||||
return new Intl.NumberFormat('ru', {
|
||||
style: 'currency',
|
||||
currency: curr,
|
||||
maximumFractionDigits: 0
|
||||
}).format(num)
|
||||
} catch {
|
||||
return `${num} ${curr}`
|
||||
}
|
||||
}
|
||||
|
||||
// ISO code to emoji flag
|
||||
const isoToEmoji = (code: string): string => {
|
||||
return code.toUpperCase().split('').map(char => String.fromCodePoint(0x1F1E6 - 65 + char.charCodeAt(0))).join('')
|
||||
}
|
||||
|
||||
const countryFlag = computed(() => {
|
||||
if (props.offer.locationCountryCode) {
|
||||
return isoToEmoji(props.offer.locationCountryCode)
|
||||
}
|
||||
return '🌍'
|
||||
})
|
||||
|
||||
const displayUnit = computed(() => props.offer.unit || t('catalogOfferCard.labels.default_unit'))
|
||||
</script>
|
||||
@@ -1,58 +1,116 @@
|
||||
<template>
|
||||
<Card padding="md" interactive @click="$emit('select')">
|
||||
<!-- Header: Location + Price -->
|
||||
<div class="flex items-start justify-between mb-3">
|
||||
<div>
|
||||
<Text weight="semibold">{{ locationName || 'Локация' }}</Text>
|
||||
<Text v-if="productName" tone="muted" size="sm">{{ productName }}</Text>
|
||||
<Card padding="md" interactive :class="groupClass" @click="$emit('select')">
|
||||
<!-- Header: Supplier + Price -->
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-6 h-6 rounded-full flex items-center justify-center" style="background-color: #3b82f6">
|
||||
<Icon name="lucide:factory" size="14" class="text-white" />
|
||||
</div>
|
||||
<Text weight="semibold">{{ supplierDisplay }}</Text>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 text-sm text-base-content/70">
|
||||
<Icon name="lucide:map-pin" size="14" class="text-base-content/60" />
|
||||
<span>{{ originDisplay }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="productName" class="flex items-center gap-2 text-sm text-base-content/70">
|
||||
<Icon name="lucide:package" size="14" class="text-base-content/60" />
|
||||
<span>{{ productName }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="quantityDisplay" class="flex items-center gap-2 text-sm text-base-content/70">
|
||||
<Icon name="lucide:scale" size="14" class="text-base-content/60" />
|
||||
<span>{{ quantityDisplay }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-right">
|
||||
<Text v-if="priceDisplay" weight="semibold" class="text-primary text-lg">
|
||||
{{ priceDisplay }}
|
||||
</Text>
|
||||
<Text v-if="durationDisplay" size="xs" class="text-base-content/60">
|
||||
{{ t('catalogOfferCard.labels.duration_label') }} {{ durationDisplay }}
|
||||
</Text>
|
||||
</div>
|
||||
<Text v-if="priceDisplay" weight="semibold" class="text-primary text-lg">
|
||||
{{ priceDisplay }}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<!-- Supplier info -->
|
||||
<SupplierInfoBlock v-if="kycProfileUuid" :kyc-profile-uuid="kycProfileUuid" class="mb-3" />
|
||||
|
||||
<!-- Route stepper -->
|
||||
<RouteStepper
|
||||
v-if="stages.length > 0"
|
||||
:stages="stages"
|
||||
:start-name="startName"
|
||||
:end-name="endName"
|
||||
/>
|
||||
<!-- Route lines -->
|
||||
<div v-if="routeRows.length" class="mt-3 pt-2 border-t border-base-200/60">
|
||||
<div v-for="(row, index) in routeRows" :key="index" class="flex items-center gap-2 text-sm text-base-content/70">
|
||||
<Icon :name="row.icon" size="14" class="text-base-content/60" />
|
||||
<span>{{ row.distanceLabel }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { RouteStage } from './RouteStepper.vue'
|
||||
interface RouteStage {
|
||||
transportType?: string | null
|
||||
distanceKm?: number | null
|
||||
travelTimeSeconds?: number | null
|
||||
fromName?: string | null
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
locationName?: string
|
||||
supplierName?: string
|
||||
productName?: string
|
||||
pricePerUnit?: number | null
|
||||
quantity?: number | string | null
|
||||
currency?: string | null
|
||||
unit?: string | null
|
||||
stages?: RouteStage[]
|
||||
startName?: string
|
||||
endName?: string
|
||||
totalTimeSeconds?: number | null
|
||||
kycProfileUuid?: string | null
|
||||
grouped?: boolean
|
||||
}>(), {
|
||||
stages: () => []
|
||||
stages: () => [],
|
||||
grouped: false
|
||||
})
|
||||
|
||||
defineEmits<{
|
||||
select: []
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const supplierDisplay = computed(() => {
|
||||
return props.supplierName || t('catalogOfferCard.labels.supplier_unknown')
|
||||
})
|
||||
|
||||
const originDisplay = computed(() => {
|
||||
const fromStage = props.stages?.find(stage => stage?.fromName)?.fromName
|
||||
return props.locationName || fromStage || t('catalogOfferCard.labels.origin_unknown')
|
||||
})
|
||||
|
||||
const priceDisplay = computed(() => {
|
||||
if (!props.pricePerUnit) return null
|
||||
if (props.pricePerUnit == null) return null
|
||||
const currSymbol = getCurrencySymbol(props.currency)
|
||||
const unitName = getUnitName(props.unit)
|
||||
const formattedPrice = props.pricePerUnit.toLocaleString()
|
||||
const basePrice = Number(props.pricePerUnit)
|
||||
const totalPrice = basePrice + (logisticsCost.value ?? 0)
|
||||
const formattedPrice = totalPrice.toLocaleString()
|
||||
return `${currSymbol}${formattedPrice}/${unitName}`
|
||||
})
|
||||
|
||||
const quantityDisplay = computed(() => {
|
||||
if (props.quantity == null || props.quantity === '') return null
|
||||
const quantityValue = Number(props.quantity)
|
||||
if (Number.isNaN(quantityValue)) return null
|
||||
const formattedQuantity = quantityValue.toLocaleString()
|
||||
const unitName = getUnitName(props.unit)
|
||||
return t('catalogOfferCard.labels.quantity_with_unit', {
|
||||
quantity: formattedQuantity,
|
||||
unit: unitName
|
||||
})
|
||||
})
|
||||
|
||||
const getCurrencySymbol = (currency?: string | null) => {
|
||||
switch (currency?.toUpperCase()) {
|
||||
case 'USD': return '$'
|
||||
@@ -66,14 +124,104 @@ const getCurrencySymbol = (currency?: string | null) => {
|
||||
const getUnitName = (unit?: string | null) => {
|
||||
switch (unit?.toLowerCase()) {
|
||||
case 'т':
|
||||
case 't':
|
||||
case 'ton':
|
||||
case 'tonne':
|
||||
return 'тонна'
|
||||
return t('catalogOfferCard.labels.default_unit')
|
||||
case 'кг':
|
||||
case 'kg':
|
||||
return 'кг'
|
||||
return t('catalogOfferCard.labels.unit_kg')
|
||||
default:
|
||||
return 'тонна'
|
||||
return t('catalogOfferCard.labels.default_unit')
|
||||
}
|
||||
}
|
||||
|
||||
const formatDistance = (km?: number | null) => {
|
||||
if (km == null) return null
|
||||
const formatted = Math.round(km).toLocaleString()
|
||||
return t('catalogOfferCard.labels.distance_km', { km: formatted })
|
||||
}
|
||||
|
||||
const formatDurationDays = (days?: number | null) => {
|
||||
if (!days) return null
|
||||
const rounded = Math.max(1, Math.ceil(days))
|
||||
return t('catalogOfferCard.labels.duration_days', { days: rounded })
|
||||
}
|
||||
|
||||
const getTransportIcon = (type?: string | null) => {
|
||||
switch (type) {
|
||||
case 'rail':
|
||||
return 'lucide:train-front'
|
||||
case 'sea':
|
||||
return 'lucide:ship'
|
||||
case 'road':
|
||||
case 'auto':
|
||||
default:
|
||||
return 'lucide:truck'
|
||||
}
|
||||
}
|
||||
|
||||
const getTransportRate = (type?: string | null) => {
|
||||
switch (type) {
|
||||
case 'rail':
|
||||
return 0.12
|
||||
case 'sea':
|
||||
return 0.06
|
||||
case 'road':
|
||||
case 'auto':
|
||||
default:
|
||||
return 0.22
|
||||
}
|
||||
}
|
||||
|
||||
const getTransportSpeedPerDay = (type?: string | null) => {
|
||||
switch (type) {
|
||||
case 'rail':
|
||||
return 900
|
||||
case 'sea':
|
||||
return 800
|
||||
case 'road':
|
||||
case 'auto':
|
||||
default:
|
||||
return 600
|
||||
}
|
||||
}
|
||||
|
||||
const logisticsCost = computed(() => {
|
||||
if (!props.stages?.length) return null
|
||||
return props.stages.reduce((sum, stage) => {
|
||||
const km = stage?.distanceKm
|
||||
if (km == null) return sum
|
||||
return sum + km * getTransportRate(stage?.transportType) + 40
|
||||
}, 0)
|
||||
})
|
||||
|
||||
const totalDurationDays = computed(() => {
|
||||
if (!props.stages?.length) return null
|
||||
const stageDays = props.stages.reduce((sum, stage) => {
|
||||
const km = stage?.distanceKm
|
||||
if (km == null) return sum
|
||||
return sum + km / getTransportSpeedPerDay(stage?.transportType)
|
||||
}, 0)
|
||||
const transfers = Math.max(0, props.stages.length - 1) * 0.5
|
||||
const buffer = 1
|
||||
return stageDays + transfers + buffer
|
||||
})
|
||||
|
||||
const durationDisplay = computed(() => formatDurationDays(totalDurationDays.value))
|
||||
|
||||
const groupClass = computed(() => {
|
||||
if (!props.grouped) return ''
|
||||
return 'rounded-none shadow-none hover:shadow-none'
|
||||
})
|
||||
|
||||
const routeRows = computed(() =>
|
||||
(props.stages || [])
|
||||
.filter(stage => stage?.distanceKm != null)
|
||||
.map(stage => ({
|
||||
icon: getTransportIcon(stage?.transportType),
|
||||
distanceLabel: formatDistance(stage?.distanceKm)
|
||||
}))
|
||||
.filter(row => !!row.distanceLabel)
|
||||
)
|
||||
</script>
|
||||
|
||||
391
app/components/catalog/OrderDetailBottomSheet.vue
Normal file
391
app/components/catalog/OrderDetailBottomSheet.vue
Normal file
@@ -0,0 +1,391 @@
|
||||
<template>
|
||||
<Transition name="order-slide">
|
||||
<div
|
||||
v-if="isOpen && orderUuid"
|
||||
class="fixed inset-x-0 bottom-0 z-50 flex justify-center px-3 md:px-4"
|
||||
style="height: 72vh"
|
||||
>
|
||||
<!-- Backdrop (clickable to close) -->
|
||||
<div
|
||||
class="absolute inset-0 -top-[32vh] bg-gradient-to-t from-black/45 via-black/20 to-transparent"
|
||||
@click="emit('close')"
|
||||
/>
|
||||
|
||||
<!-- Sheet content -->
|
||||
<div class="relative flex w-full max-w-[980px] flex-col overflow-hidden rounded-t-[2rem] border border-white/60 bg-base-100/95 shadow-[0_-24px_70px_rgba(15,23,42,0.3)] backdrop-blur-xl">
|
||||
<!-- Header with drag handle and close -->
|
||||
<div class="sticky top-0 z-10 border-b border-base-300 bg-base-100/90">
|
||||
<div class="flex justify-center py-2">
|
||||
<div class="h-1.5 w-12 rounded-full bg-base-content/20" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between px-6 pb-4">
|
||||
<template v-if="hasOrderError">
|
||||
<div class="flex-1">
|
||||
<div class="font-black text-base-content">{{ t('common.error') }}</div>
|
||||
<div class="text-sm text-base-content/60">{{ orderError }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="!isLoadingOrder && order">
|
||||
<div class="flex items-center gap-3 flex-1 min-w-0">
|
||||
<div class="flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-xl bg-primary/15">
|
||||
<Icon name="lucide:package" size="24" class="text-primary" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="truncate text-xl font-black text-base-content">{{ orderTitle }}</div>
|
||||
<div class="mt-0.5 flex items-center gap-2">
|
||||
<span class="badge badge-primary badge-sm">#{{ order.name }}</span>
|
||||
<span v-if="order.status" class="badge badge-outline badge-sm">{{ order.status }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<div class="flex items-center gap-3 flex-1">
|
||||
<div class="h-10 w-10 animate-pulse rounded-xl bg-base-300/70" />
|
||||
<div class="flex-1">
|
||||
<div class="h-5 w-48 animate-pulse rounded bg-base-300/70" />
|
||||
<div class="mt-1 h-4 w-32 animate-pulse rounded bg-base-300/70" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<button class="btn btn-ghost btn-sm btn-circle flex-shrink-0 text-base-content/60 hover:text-base-content" @click="emit('close')">
|
||||
<Icon name="lucide:x" size="20" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Error state -->
|
||||
<div v-if="hasOrderError" class="px-6 py-8 text-center">
|
||||
<div class="mb-4 text-base-content/70">{{ orderError }}</div>
|
||||
<button class="btn btn-sm btn-outline" @click="loadOrder">
|
||||
{{ t('ordersDetail.errors.retry') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Scrollable content -->
|
||||
<div v-else-if="order" class="h-[calc(72vh-110px)] overflow-y-auto px-6 py-4 space-y-4">
|
||||
<!-- Order meta -->
|
||||
<div class="flex flex-wrap gap-2 text-sm">
|
||||
<span v-for="(meta, idx) in orderMeta" :key="idx" class="rounded-full border border-base-300 bg-base-200 px-3 py-1 text-base-content/70">
|
||||
{{ meta }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Route stages -->
|
||||
<div v-if="orderStageItems.length" class="rounded-2xl border border-base-300 bg-base-100 p-4">
|
||||
<div class="mb-3 flex items-center gap-2 text-base-content">
|
||||
<Icon name="lucide:route" size="18" />
|
||||
<span class="text-lg font-black">{{ t('ordersDetail.sections.stages.title', 'Маршрут') }}</span>
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
<div
|
||||
v-for="(stage, idx) in orderStageItems"
|
||||
:key="stage.key || idx"
|
||||
class="flex gap-3"
|
||||
>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="h-3 w-3 rounded-full bg-primary" />
|
||||
<div v-if="idx < orderStageItems.length - 1" class="my-1 w-0.5 flex-1 bg-base-300" />
|
||||
</div>
|
||||
<div class="flex-1 pb-3">
|
||||
<div class="text-sm font-bold text-base-content">{{ stage.from }}</div>
|
||||
<div v-if="stage.to && stage.to !== stage.from" class="mt-0.5 text-xs text-base-content/60">
|
||||
→ {{ stage.to }}
|
||||
</div>
|
||||
<div v-if="stage.meta?.length" class="mt-1 text-xs text-base-content/50">
|
||||
{{ stage.meta.join(' · ') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Timeline -->
|
||||
<div v-if="order.stages?.length" class="rounded-2xl border border-base-300 bg-base-100 p-4">
|
||||
<div class="mb-3 flex items-center gap-2 text-base-content">
|
||||
<Icon name="lucide:calendar" size="18" />
|
||||
<span class="text-lg font-black">{{ t('ordersDetail.sections.timeline.title') }}</span>
|
||||
</div>
|
||||
<GanttTimeline
|
||||
:stages="order.stages"
|
||||
:showLoading="true"
|
||||
:showUnloading="true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Map preview (small) -->
|
||||
<div v-if="orderRoutesForMap.length" class="rounded-2xl border border-base-300 bg-base-100 p-4">
|
||||
<div class="mb-3 flex items-center gap-2 text-base-content">
|
||||
<Icon name="lucide:map" size="18" />
|
||||
<span class="text-lg font-black">{{ t('ordersDetail.sections.map.title', 'Карта') }}</span>
|
||||
</div>
|
||||
<RequestRoutesMap :routes="orderRoutesForMap" :height="200" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading state -->
|
||||
<div v-else class="px-6 py-4 space-y-4">
|
||||
<div class="h-20 animate-pulse rounded-xl bg-base-300/70" />
|
||||
<div class="h-32 animate-pulse rounded-xl bg-base-300/70" />
|
||||
<div class="h-48 animate-pulse rounded-xl bg-base-300/70" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { GetOrderDocument, type GetOrderQueryResult } from '~/composables/graphql/team/orders-generated'
|
||||
import type { RouteStageItem } from '~/components/RouteStagesList.vue'
|
||||
|
||||
// Types from GraphQL
|
||||
type OrderType = NonNullable<GetOrderQueryResult['getOrder']>
|
||||
type StageType = NonNullable<NonNullable<OrderType['stages']>[number]>
|
||||
type CompanyType = NonNullable<StageType['selectedCompany']>
|
||||
|
||||
const props = defineProps<{
|
||||
isOpen: boolean
|
||||
orderUuid: string | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'close': []
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const order = ref<OrderType | null>(null)
|
||||
const isLoadingOrder = ref(false)
|
||||
const hasOrderError = ref(false)
|
||||
const orderError = ref('')
|
||||
|
||||
// Load order when uuid changes
|
||||
watch(() => props.orderUuid, async (uuid) => {
|
||||
if (uuid && props.isOpen) {
|
||||
await loadOrder()
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
// Also load when opening
|
||||
watch(() => props.isOpen, async (open) => {
|
||||
if (open && props.orderUuid) {
|
||||
await loadOrder()
|
||||
} else if (!open) {
|
||||
// Reset state when closing
|
||||
order.value = null
|
||||
hasOrderError.value = false
|
||||
orderError.value = ''
|
||||
}
|
||||
})
|
||||
|
||||
const orderTitle = computed(() => {
|
||||
const source = order.value?.sourceLocationName || t('ordersDetail.labels.source_unknown')
|
||||
const destination = order.value?.destinationLocationName || t('ordersDetail.labels.destination_unknown')
|
||||
return `${source} → ${destination}`
|
||||
})
|
||||
|
||||
const orderMeta = computed(() => {
|
||||
const meta: string[] = []
|
||||
|
||||
const line = order.value?.orderLines?.[0]
|
||||
if (line?.quantity) {
|
||||
meta.push(`${line.quantity} ${line.unit || t('ordersDetail.labels.unit_tons')}`)
|
||||
}
|
||||
if (line?.productName) {
|
||||
meta.push(line.productName)
|
||||
}
|
||||
if (order.value?.totalAmount) {
|
||||
meta.push(formatPrice(order.value.totalAmount, order.value?.currency))
|
||||
}
|
||||
|
||||
const durationDays = getOrderDuration()
|
||||
if (durationDays) {
|
||||
meta.push(`${durationDays} ${t('ordersDetail.labels.delivery_days')}`)
|
||||
}
|
||||
|
||||
return meta
|
||||
})
|
||||
|
||||
const orderRoutesForMap = computed(() => {
|
||||
const stages = (order.value?.stages || [])
|
||||
.filter((stage): stage is StageType => stage !== null)
|
||||
.map((stage) => {
|
||||
if (stage.stageType === 'transport') {
|
||||
if (!stage.sourceLatitude || !stage.sourceLongitude || !stage.destinationLatitude || !stage.destinationLongitude) return null
|
||||
return {
|
||||
fromLat: stage.sourceLatitude,
|
||||
fromLon: stage.sourceLongitude,
|
||||
fromName: stage.sourceLocationName,
|
||||
toLat: stage.destinationLatitude,
|
||||
toLon: stage.destinationLongitude,
|
||||
toName: stage.destinationLocationName,
|
||||
transportType: stage.transportType
|
||||
}
|
||||
}
|
||||
return null
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
if (!stages.length) return []
|
||||
return [{ stages }]
|
||||
})
|
||||
|
||||
// Company summary type
|
||||
interface CompanySummary {
|
||||
name: string | null | undefined
|
||||
totalWeight: number
|
||||
tripsCount: number
|
||||
company: CompanyType | null | undefined
|
||||
}
|
||||
|
||||
const orderStageItems = computed<RouteStageItem[]>(() => {
|
||||
return (order.value?.stages || [])
|
||||
.filter((stage): stage is StageType => stage !== null)
|
||||
.map((stage) => {
|
||||
const isTransport = stage.stageType === 'transport'
|
||||
const from = isTransport ? stage.sourceLocationName : stage.locationName
|
||||
const to = isTransport ? stage.destinationLocationName : stage.locationName
|
||||
|
||||
const meta: string[] = []
|
||||
const dateRange = getStageDateRange(stage)
|
||||
if (dateRange) {
|
||||
meta.push(dateRange)
|
||||
}
|
||||
|
||||
const companies = getCompaniesSummary(stage)
|
||||
companies.forEach((company: CompanySummary) => {
|
||||
meta.push(
|
||||
`${company.name} · ${company.totalWeight || 0}${t('ordersDetail.labels.weight_unit')} · ${company.tripsCount || 0} ${t('ordersDetail.labels.trips')}`
|
||||
)
|
||||
})
|
||||
|
||||
return {
|
||||
key: stage.uuid ?? undefined,
|
||||
from: from ?? undefined,
|
||||
to: to ?? undefined,
|
||||
label: stage.name ?? undefined,
|
||||
meta
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const loadOrder = async () => {
|
||||
if (!props.orderUuid) return
|
||||
|
||||
try {
|
||||
isLoadingOrder.value = true
|
||||
hasOrderError.value = false
|
||||
const { data, error: orderErrorResp } = await useServerQuery('order-detail-sheet', GetOrderDocument, { orderUuid: props.orderUuid }, 'team', 'orders')
|
||||
if (orderErrorResp.value) throw orderErrorResp.value
|
||||
order.value = data.value?.getOrder ?? null
|
||||
} catch (err: unknown) {
|
||||
hasOrderError.value = true
|
||||
orderError.value = err instanceof Error ? err.message : t('ordersDetail.errors.load_failed')
|
||||
} finally {
|
||||
isLoadingOrder.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const formatPrice = (price: number, currency?: string | null) => {
|
||||
if (!price) return t('ordersDetail.labels.price_zero')
|
||||
return new Intl.NumberFormat('ru-RU', {
|
||||
style: 'currency',
|
||||
currency: currency || 'RUB',
|
||||
minimumFractionDigits: 0
|
||||
}).format(price)
|
||||
}
|
||||
|
||||
const getCompaniesSummary = (stage: StageType): CompanySummary[] => {
|
||||
const companies: CompanySummary[] = []
|
||||
if (stage.stageType === 'service' && stage.selectedCompany) {
|
||||
companies.push({
|
||||
name: stage.selectedCompany.name,
|
||||
totalWeight: 0,
|
||||
tripsCount: 0,
|
||||
company: stage.selectedCompany
|
||||
})
|
||||
return companies
|
||||
}
|
||||
|
||||
if (stage.stageType === 'transport' && stage.trips?.length) {
|
||||
const companiesMap = new Map<string, CompanySummary>()
|
||||
stage.trips.forEach((trip) => {
|
||||
if (!trip) return
|
||||
const companyName = trip.company?.name || t('ordersDetail.labels.company_unknown')
|
||||
const weight = trip.plannedWeight || 0
|
||||
if (companiesMap.has(companyName)) {
|
||||
const existing = companiesMap.get(companyName)!
|
||||
existing.totalWeight += weight
|
||||
existing.tripsCount += 1
|
||||
} else {
|
||||
companiesMap.set(companyName, {
|
||||
name: companyName,
|
||||
totalWeight: weight,
|
||||
tripsCount: 1,
|
||||
company: trip.company
|
||||
})
|
||||
}
|
||||
})
|
||||
return Array.from(companiesMap.values())
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
const getOrderDuration = () => {
|
||||
if (!order.value?.stages?.length) return 0
|
||||
let minDate: Date | null = null
|
||||
let maxDate: Date | null = null
|
||||
order.value.stages.forEach((stage) => {
|
||||
if (!stage) return
|
||||
stage.trips?.forEach((trip) => {
|
||||
if (!trip) return
|
||||
const startDate = new Date(trip.plannedLoadingDate || trip.actualLoadingDate || '')
|
||||
const endDate = new Date(trip.plannedUnloadingDate || trip.actualUnloadingDate || '')
|
||||
if (!minDate || startDate < minDate) minDate = startDate
|
||||
if (!maxDate || endDate > maxDate) maxDate = endDate
|
||||
})
|
||||
})
|
||||
if (!minDate || !maxDate) return 0
|
||||
const diffTime = Math.abs((maxDate as Date).getTime() - (minDate as Date).getTime())
|
||||
return Math.ceil(diffTime / (1000 * 60 * 60 * 24))
|
||||
}
|
||||
|
||||
const getStageDateRange = (stage: StageType) => {
|
||||
if (!stage.trips?.length) return t('ordersDetail.labels.dates_undefined')
|
||||
let minDate: Date | null = null
|
||||
let maxDate: Date | null = null
|
||||
stage.trips.forEach((trip) => {
|
||||
if (!trip) return
|
||||
const startDate = new Date(trip.plannedLoadingDate || trip.actualLoadingDate || '')
|
||||
const endDate = new Date(trip.plannedUnloadingDate || trip.actualUnloadingDate || '')
|
||||
if (!minDate || startDate < minDate) minDate = startDate
|
||||
if (!maxDate || endDate > maxDate) maxDate = endDate
|
||||
})
|
||||
if (!minDate || !maxDate) return t('ordersDetail.labels.dates_undefined')
|
||||
const formatDate = (date: Date) => date.toLocaleDateString('ru-RU', { day: 'numeric', month: 'short' })
|
||||
if ((minDate as Date).toDateString() === (maxDate as Date).toDateString()) return formatDate(minDate as Date)
|
||||
return `${formatDate(minDate as Date)} - ${formatDate(maxDate as Date)}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.order-slide-enter-active,
|
||||
.order-slide-leave-active {
|
||||
transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.order-slide-enter-from,
|
||||
.order-slide-leave-to {
|
||||
transform: translateY(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.order-slide-enter-to,
|
||||
.order-slide-leave-from {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
@@ -1,59 +0,0 @@
|
||||
<template>
|
||||
<div class="w-20 h-10">
|
||||
<Line :data="chartData" :options="chartOptions" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Line } from 'vue-chartjs'
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
LineElement,
|
||||
PointElement,
|
||||
LinearScale,
|
||||
CategoryScale,
|
||||
Filler
|
||||
} from 'chart.js'
|
||||
|
||||
ChartJS.register(LineElement, PointElement, LinearScale, CategoryScale, Filler)
|
||||
|
||||
const props = defineProps<{
|
||||
data: number[]
|
||||
}>()
|
||||
|
||||
const isUptrend = computed(() => {
|
||||
if (props.data.length < 2) return true
|
||||
return props.data[props.data.length - 1] >= props.data[0]
|
||||
})
|
||||
|
||||
const lineColor = computed(() => isUptrend.value ? '#22c55e' : '#ef4444')
|
||||
|
||||
const chartData = computed(() => ({
|
||||
labels: props.data.map((_, i) => i.toString()),
|
||||
datasets: [{
|
||||
data: props.data,
|
||||
borderColor: lineColor.value,
|
||||
backgroundColor: `${lineColor.value}20`,
|
||||
borderWidth: 1.5,
|
||||
fill: true,
|
||||
tension: 0.3,
|
||||
pointRadius: 0
|
||||
}]
|
||||
}))
|
||||
|
||||
const chartOptions = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: { display: false },
|
||||
tooltip: { enabled: false }
|
||||
},
|
||||
scales: {
|
||||
x: { display: false },
|
||||
y: { display: false }
|
||||
},
|
||||
elements: {
|
||||
line: { borderCapStyle: 'round' as const }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -9,17 +9,59 @@
|
||||
<Card
|
||||
padding="sm"
|
||||
:interactive="linkable || selectable"
|
||||
class="relative overflow-hidden"
|
||||
:class="[
|
||||
isSelected && 'ring-2 ring-primary ring-offset-2'
|
||||
]"
|
||||
>
|
||||
<Stack gap="2">
|
||||
<Text size="base" weight="semibold">{{ product.name }}</Text>
|
||||
<Text v-if="product.offersCount" tone="muted" size="sm">
|
||||
{{ product.offersCount }} {{ t('catalog.offers', product.offersCount) }}
|
||||
</Text>
|
||||
<Text v-if="product.description && !compact" tone="muted" size="sm">{{ product.description }}</Text>
|
||||
</Stack>
|
||||
<!-- Sparkline background -->
|
||||
<div v-if="effectivePriceHistory.length > 1" class="absolute inset-0 opacity-15">
|
||||
<ClientOnly>
|
||||
<apexchart
|
||||
type="area"
|
||||
height="100%"
|
||||
:options="chartOptions"
|
||||
:series="chartSeries"
|
||||
/>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="relative z-10">
|
||||
<div class="flex items-start gap-3">
|
||||
<!-- Product icon -->
|
||||
<div class="w-10 h-10 shrink-0 bg-primary/10 text-primary rounded-lg flex items-center justify-center">
|
||||
<Icon name="lucide:package" size="20" />
|
||||
</div>
|
||||
|
||||
<!-- Info -->
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="flex items-center justify-between gap-2 mb-1">
|
||||
<Text size="base" weight="semibold" class="truncate">{{ product.name }}</Text>
|
||||
<span
|
||||
v-if="trend !== 0"
|
||||
class="text-xs font-medium shrink-0"
|
||||
:class="trend > 0 ? 'text-success' : 'text-error'"
|
||||
>
|
||||
{{ trend > 0 ? '↑' : '↓' }} {{ Math.abs(trend) }}%
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<Text v-if="product.offersCount" tone="muted" size="sm">
|
||||
{{ product.offersCount }} {{ t('catalog.offers', product.offersCount) }}
|
||||
</Text>
|
||||
<Text v-if="effectivePrice" size="sm" class="text-primary font-bold shrink-0">
|
||||
{{ formattedPrice }}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Text v-if="product.description && !compact" tone="muted" size="sm" class="mt-1">
|
||||
{{ product.description }}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</component>
|
||||
</template>
|
||||
@@ -34,12 +76,17 @@ interface Product {
|
||||
offersCount?: number | null
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
const props = withDefaults(defineProps<{
|
||||
product: Product
|
||||
selectable?: boolean
|
||||
isSelected?: boolean
|
||||
compact?: boolean
|
||||
}>()
|
||||
priceHistory?: number[]
|
||||
currentPrice?: number | null
|
||||
currency?: string | null
|
||||
}>(), {
|
||||
priceHistory: () => []
|
||||
})
|
||||
|
||||
defineEmits<{
|
||||
(e: 'select'): void
|
||||
@@ -48,5 +95,84 @@ defineEmits<{
|
||||
const localePath = useLocalePath()
|
||||
const { t } = useI18n()
|
||||
|
||||
const linkable = computed(() => !props.selectable && props.product.uuid)
|
||||
const linkable = computed(() => !props.selectable && !!props.product.uuid)
|
||||
|
||||
// Generate mock price history based on uuid for consistency
|
||||
const effectivePriceHistory = computed(() => {
|
||||
if (props.priceHistory && props.priceHistory.length > 0) {
|
||||
return props.priceHistory
|
||||
}
|
||||
if (!props.product.uuid) return []
|
||||
const seed = props.product.uuid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
|
||||
const basePrice = 100 + (seed % 200)
|
||||
return Array.from({ length: 7 }, (_, i) => {
|
||||
const variation = Math.sin(seed + i * 0.5) * 20 + Math.cos(seed * 0.3 + i) * 10
|
||||
return Math.round(basePrice + variation)
|
||||
})
|
||||
})
|
||||
|
||||
// Effective price - use provided or last from history
|
||||
const effectivePrice = computed(() => {
|
||||
if (props.currentPrice) return props.currentPrice
|
||||
if (effectivePriceHistory.value.length > 0) {
|
||||
return effectivePriceHistory.value[effectivePriceHistory.value.length - 1]
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
// Price formatting
|
||||
const formattedPrice = computed(() => {
|
||||
if (!effectivePrice.value) return ''
|
||||
const symbol = getCurrencySymbol(props.currency)
|
||||
return `${symbol}${effectivePrice.value.toLocaleString()}`
|
||||
})
|
||||
|
||||
const getCurrencySymbol = (currency?: string | null) => {
|
||||
switch (currency?.toUpperCase()) {
|
||||
case 'USD': return '$'
|
||||
case 'EUR': return '€'
|
||||
case 'RUB': return '₽'
|
||||
case 'CNY': return '¥'
|
||||
default: return '$'
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate trend from price history
|
||||
const trend = computed(() => {
|
||||
if (effectivePriceHistory.value.length < 2) return 0
|
||||
const first = effectivePriceHistory.value[0]
|
||||
const last = effectivePriceHistory.value[effectivePriceHistory.value.length - 1]
|
||||
if (!first || first === 0 || !last) return 0
|
||||
return Math.round(((last - first) / first) * 100)
|
||||
})
|
||||
|
||||
// Chart configuration
|
||||
const chartOptions = computed(() => ({
|
||||
chart: {
|
||||
type: 'area',
|
||||
sparkline: { enabled: true },
|
||||
animations: { enabled: false }
|
||||
},
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
width: 2
|
||||
},
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shadeIntensity: 1,
|
||||
opacityFrom: 0.4,
|
||||
opacityTo: 0.1
|
||||
}
|
||||
},
|
||||
colors: [trend.value >= 0 ? '#22c55e' : '#ef4444'],
|
||||
tooltip: { enabled: false },
|
||||
xaxis: { labels: { show: false } },
|
||||
yaxis: { labels: { show: false } }
|
||||
}))
|
||||
|
||||
const chartSeries = computed(() => [{
|
||||
name: 'Price',
|
||||
data: effectivePriceHistory.value.length > 0 ? effectivePriceHistory.value : [0]
|
||||
}])
|
||||
</script>
|
||||
|
||||
@@ -2,64 +2,6 @@
|
||||
<div class="flex flex-col gap-4">
|
||||
<h3 class="font-semibold text-lg">{{ $t('catalog.quote.title') }}</h3>
|
||||
|
||||
<!-- Product chip -->
|
||||
<div class="form-control">
|
||||
<label class="label py-1">
|
||||
<span class="label-text text-xs text-base-content/70">{{ $t('catalog.filters.product') }}</span>
|
||||
</label>
|
||||
<button
|
||||
v-if="productLabel"
|
||||
class="btn btn-outline btn-sm justify-start gap-2"
|
||||
@click="emit('edit-filter', 'product')"
|
||||
>
|
||||
<Icon name="lucide:package" size="16" />
|
||||
<span class="flex-1 text-left truncate">{{ productLabel }}</span>
|
||||
<span
|
||||
class="btn btn-ghost btn-xs btn-circle"
|
||||
@click.stop="emit('remove-filter', 'product')"
|
||||
>
|
||||
<Icon name="lucide:x" size="14" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="btn btn-ghost btn-sm justify-start gap-2 border border-dashed border-base-content/30"
|
||||
@click="emit('edit-filter', 'product')"
|
||||
>
|
||||
<Icon name="lucide:plus" size="16" class="text-base-content/50" />
|
||||
<span class="text-base-content/50">{{ $t('catalog.quote.selectProduct') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Hub chip -->
|
||||
<div class="form-control">
|
||||
<label class="label py-1">
|
||||
<span class="label-text text-xs text-base-content/70">{{ $t('catalog.filters.hub') }}</span>
|
||||
</label>
|
||||
<button
|
||||
v-if="hubLabel"
|
||||
class="btn btn-outline btn-sm justify-start gap-2"
|
||||
@click="emit('edit-filter', 'hub')"
|
||||
>
|
||||
<Icon name="lucide:map-pin" size="16" />
|
||||
<span class="flex-1 text-left truncate">{{ hubLabel }}</span>
|
||||
<span
|
||||
class="btn btn-ghost btn-xs btn-circle"
|
||||
@click.stop="emit('remove-filter', 'hub')"
|
||||
>
|
||||
<Icon name="lucide:x" size="14" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="btn btn-ghost btn-sm justify-start gap-2 border border-dashed border-base-content/30"
|
||||
@click="emit('edit-filter', 'hub')"
|
||||
>
|
||||
<Icon name="lucide:plus" size="16" class="text-base-content/50" />
|
||||
<span class="text-base-content/50">{{ $t('catalog.quote.selectHub') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Quantity input -->
|
||||
<div class="form-control">
|
||||
<label class="label py-1">
|
||||
|
||||
@@ -1,50 +1,148 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-4 h-full">
|
||||
<div class="flex flex-col h-full">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between flex-shrink-0">
|
||||
<h3 class="font-semibold text-lg">{{ $t('catalog.headers.offers') }}</h3>
|
||||
<span class="badge badge-neutral">{{ offers.length }}</span>
|
||||
<div class="flex-shrink-0 p-4 border-b border-white/10">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="font-semibold text-base text-white">{{ $t('catalog.headers.offers') }}</h3>
|
||||
<span class="badge badge-neutral">{{ totalOffers }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Results section -->
|
||||
<div class="flex-1 overflow-y-auto -mx-1 px-1">
|
||||
<!-- Content (scrollable) -->
|
||||
<div class="flex-1 overflow-y-auto p-4">
|
||||
<div v-if="loading" class="flex items-center justify-center py-8">
|
||||
<span class="loading loading-spinner loading-md" />
|
||||
<span class="loading loading-spinner loading-md text-white" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="offers.length === 0" class="text-center py-8 text-base-content/60">
|
||||
<div v-else-if="offersWithPrice.length === 0" class="text-center py-8 text-white/60">
|
||||
<Icon name="lucide:search-x" size="32" class="mb-2" />
|
||||
<p>{{ $t('catalog.empty.noOffers') }}</p>
|
||||
</div>
|
||||
|
||||
<div v-else class="flex flex-col gap-3">
|
||||
<div
|
||||
v-for="offer in offers"
|
||||
:key="offer.uuid"
|
||||
class="cursor-pointer"
|
||||
@click="emit('select-offer', offer)"
|
||||
>
|
||||
<slot name="offer-card" :offer="offer">
|
||||
<OfferCard :offer="offer" linkable />
|
||||
</slot>
|
||||
</div>
|
||||
<div v-else class="flex flex-col gap-3">
|
||||
<div
|
||||
v-for="group in offerGroups"
|
||||
:key="group.id"
|
||||
class="flex flex-col gap-0"
|
||||
>
|
||||
<div
|
||||
v-if="group.offers.length > 1"
|
||||
class="rounded-2xl overflow-hidden border border-base-200/60 divide-y divide-base-200/60"
|
||||
>
|
||||
<div
|
||||
v-for="offer in group.offers"
|
||||
:key="offer.uuid"
|
||||
class="cursor-pointer"
|
||||
@click="emit('select-offer', offer)"
|
||||
>
|
||||
<OfferResultCard
|
||||
grouped
|
||||
:supplier-name="offer.supplierName"
|
||||
:location-name="offer.country || ''"
|
||||
:product-name="offer.productName"
|
||||
:price-per-unit="offer.pricePerUnit ? Number(offer.pricePerUnit) : null"
|
||||
:quantity="offer.quantity"
|
||||
:currency="offer.currency"
|
||||
:unit="offer.unit"
|
||||
:stages="getOfferStages(offer)"
|
||||
:total-time-seconds="offer.routes?.[0]?.totalTimeSeconds ?? null"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else
|
||||
v-for="offer in group.offers"
|
||||
:key="offer.uuid"
|
||||
class="cursor-pointer"
|
||||
@click="emit('select-offer', offer)"
|
||||
>
|
||||
<OfferResultCard
|
||||
:supplier-name="offer.supplierName"
|
||||
:location-name="offer.country || ''"
|
||||
:product-name="offer.productName"
|
||||
:price-per-unit="offer.pricePerUnit ? Number(offer.pricePerUnit) : null"
|
||||
:quantity="offer.quantity"
|
||||
:currency="offer.currency"
|
||||
:unit="offer.unit"
|
||||
:stages="getOfferStages(offer)"
|
||||
:total-time-seconds="offer.routes?.[0]?.totalTimeSeconds ?? null"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface Offer {
|
||||
uuid: string
|
||||
[key: string]: any
|
||||
productName?: string | null
|
||||
productUuid?: string | null
|
||||
supplierName?: string | null
|
||||
supplierUuid?: string | null
|
||||
quantity?: number | string | null
|
||||
unit?: string | null
|
||||
pricePerUnit?: number | string | null
|
||||
currency?: string | null
|
||||
country?: string | null
|
||||
countryCode?: string | null
|
||||
routes?: Array<{
|
||||
totalTimeSeconds?: number | null
|
||||
stages?: Array<{
|
||||
transportType?: string | null
|
||||
distanceKm?: number | null
|
||||
travelTimeSeconds?: number | null
|
||||
fromName?: string | null
|
||||
} | null> | null
|
||||
} | null> | null
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
loading: boolean
|
||||
interface OfferGroup {
|
||||
id: string
|
||||
offers: Offer[]
|
||||
}>()
|
||||
}
|
||||
|
||||
const emit = defineEmits<{
|
||||
'select-offer': [offer: Offer]
|
||||
}>()
|
||||
|
||||
const props = defineProps<{
|
||||
loading: boolean
|
||||
offers: Offer[]
|
||||
calculations?: OfferGroup[]
|
||||
}>()
|
||||
|
||||
const offersWithPrice = computed(() =>
|
||||
(props.offers || []).filter(o => o?.pricePerUnit != null)
|
||||
)
|
||||
|
||||
const totalOffers = computed(() => {
|
||||
if (props.calculations?.length) {
|
||||
return props.calculations.reduce((sum, calc) => sum + (calc.offers?.length || 0), 0)
|
||||
}
|
||||
return props.offers.length
|
||||
})
|
||||
|
||||
const offerGroups = computed<OfferGroup[]>(() => {
|
||||
if (props.calculations?.length) return props.calculations
|
||||
return offersWithPrice.value.map(offer => ({
|
||||
id: offer.uuid,
|
||||
offers: [offer]
|
||||
}))
|
||||
})
|
||||
|
||||
const getOfferStages = (offer: Offer) => {
|
||||
const route = offer.routes?.[0]
|
||||
if (!route?.stages) return []
|
||||
return route.stages
|
||||
.filter((stage): stage is NonNullable<typeof stage> => stage !== null)
|
||||
.map((stage) => ({
|
||||
transportType: stage.transportType,
|
||||
distanceKm: stage.distanceKm,
|
||||
travelTimeSeconds: stage.travelTimeSeconds,
|
||||
fromName: stage.fromName
|
||||
}))
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,30 +1,22 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-full gap-3">
|
||||
<div class="flex flex-col h-full">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between flex-shrink-0">
|
||||
<h3 class="font-semibold text-lg">{{ title }}</h3>
|
||||
<button class="btn btn-ghost btn-sm btn-circle" @click="emit('close')">
|
||||
<Icon name="lucide:x" size="18" />
|
||||
</button>
|
||||
<div class="flex-shrink-0 p-4 border-b border-white/10">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<h3 class="font-semibold text-base text-white">{{ title }}</h3>
|
||||
<button class="btn btn-ghost btn-xs btn-circle text-white/60 hover:text-white" @click="emit('close')">
|
||||
<Icon name="lucide:x" size="16" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search input -->
|
||||
<div class="flex-shrink-0">
|
||||
<input
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
:placeholder="searchPlaceholder"
|
||||
class="input input-bordered input-sm w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- List -->
|
||||
<div class="flex-1 overflow-y-auto -mx-1 px-1">
|
||||
<!-- Content (scrollable) -->
|
||||
<div class="flex-1 overflow-y-auto p-4">
|
||||
<div v-if="loading" class="flex items-center justify-center py-8">
|
||||
<span class="loading loading-spinner loading-md" />
|
||||
<span class="loading loading-spinner loading-md text-white" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="filteredItems.length === 0" class="text-center py-8 text-base-content/60">
|
||||
<div v-else-if="items.length === 0" class="text-center py-8 text-white/60">
|
||||
<Icon name="lucide:search-x" size="32" class="mb-2" />
|
||||
<p>{{ $t('catalog.empty.noResults') }}</p>
|
||||
</div>
|
||||
@@ -32,40 +24,88 @@
|
||||
<div v-else class="flex flex-col gap-2">
|
||||
<!-- Products -->
|
||||
<template v-if="selectMode === 'product'">
|
||||
<ProductCard
|
||||
v-for="item in filteredItems"
|
||||
:key="item.uuid"
|
||||
:product="item"
|
||||
selectable
|
||||
compact
|
||||
:is-selected="selectedId === item.uuid"
|
||||
@select="onSelect(item)"
|
||||
/>
|
||||
<div
|
||||
v-for="(item, index) in items"
|
||||
:key="item.uuid ?? index"
|
||||
class="relative group"
|
||||
@mouseenter="emit('hover', item.uuid ?? null)"
|
||||
@mouseleave="emit('hover', null)"
|
||||
>
|
||||
<ProductCard
|
||||
:product="item"
|
||||
selectable
|
||||
compact
|
||||
@select="onSelect(item)"
|
||||
/>
|
||||
<button
|
||||
class="absolute -top-2 -right-2 opacity-0 group-hover:opacity-100 transition-opacity rounded-full glass-bright border border-white/30 shadow-lg p-1.5 hover:scale-105"
|
||||
@click.stop="emit('pin', 'product', item)"
|
||||
aria-label="Pin product"
|
||||
title="Pin"
|
||||
>
|
||||
<Icon name="lucide:pin" size="16" class="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Hubs -->
|
||||
<template v-else-if="selectMode === 'hub'">
|
||||
<HubCard
|
||||
v-for="item in filteredItems"
|
||||
:key="item.uuid"
|
||||
:hub="item"
|
||||
selectable
|
||||
:is-selected="selectedId === item.uuid"
|
||||
@select="onSelect(item)"
|
||||
/>
|
||||
<div
|
||||
v-for="(item, index) in items"
|
||||
:key="item.uuid ?? index"
|
||||
class="relative group"
|
||||
@mouseenter="emit('hover', item.uuid ?? null)"
|
||||
@mouseleave="emit('hover', null)"
|
||||
>
|
||||
<HubCard
|
||||
:hub="item"
|
||||
selectable
|
||||
@select="onSelect(item)"
|
||||
/>
|
||||
<button
|
||||
class="absolute -top-2 -right-2 opacity-0 group-hover:opacity-100 transition-opacity rounded-full glass-bright border border-white/30 shadow-lg p-1.5 hover:scale-105"
|
||||
@click.stop="emit('pin', 'hub', item)"
|
||||
aria-label="Pin hub"
|
||||
title="Pin"
|
||||
>
|
||||
<Icon name="lucide:pin" size="16" class="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Suppliers -->
|
||||
<template v-else-if="selectMode === 'supplier'">
|
||||
<SupplierCard
|
||||
v-for="item in filteredItems"
|
||||
:key="item.uuid"
|
||||
:supplier="item"
|
||||
selectable
|
||||
:is-selected="selectedId === item.uuid"
|
||||
@select="onSelect(item)"
|
||||
/>
|
||||
<div
|
||||
v-for="(item, index) in items"
|
||||
:key="item.uuid ?? index"
|
||||
class="relative group"
|
||||
@mouseenter="emit('hover', item.uuid ?? null)"
|
||||
@mouseleave="emit('hover', null)"
|
||||
>
|
||||
<SupplierCard
|
||||
:supplier="item"
|
||||
selectable
|
||||
@select="onSelect(item)"
|
||||
/>
|
||||
<button
|
||||
class="absolute -top-2 -right-2 opacity-0 group-hover:opacity-100 transition-opacity rounded-full glass-bright border border-white/30 shadow-lg p-1.5 hover:scale-105"
|
||||
@click.stop="emit('pin', 'supplier', item)"
|
||||
aria-label="Pin supplier"
|
||||
title="Pin"
|
||||
>
|
||||
<Icon name="lucide:pin" size="16" class="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Infinite scroll sentinel -->
|
||||
<div
|
||||
v-if="hasMore"
|
||||
ref="loadMoreSentinel"
|
||||
class="flex items-center justify-center py-4"
|
||||
>
|
||||
<span v-if="loadingMore" class="loading loading-spinner loading-sm text-white/60" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -77,7 +117,7 @@ import type { SelectMode } from '~/composables/useCatalogSearch'
|
||||
interface Item {
|
||||
uuid?: string | null
|
||||
name?: string | null
|
||||
[key: string]: any
|
||||
country?: string | null
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -85,18 +125,50 @@ const props = defineProps<{
|
||||
products?: Item[]
|
||||
hubs?: Item[]
|
||||
suppliers?: Item[]
|
||||
selectedId?: string
|
||||
loading?: boolean
|
||||
loadingMore?: boolean
|
||||
hasMore?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'select': [type: string, item: Item]
|
||||
'close': []
|
||||
'load-more': []
|
||||
'hover': [uuid: string | null]
|
||||
'pin': [type: 'product' | 'hub' | 'supplier', item: Item]
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const searchQuery = ref('')
|
||||
const loadMoreSentinel = ref<HTMLElement | null>(null)
|
||||
|
||||
// Infinite scroll using IntersectionObserver
|
||||
let observer: IntersectionObserver | null = null
|
||||
|
||||
onMounted(() => {
|
||||
observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
const entry = entries[0]
|
||||
if (entry?.isIntersecting && props.hasMore && !props.loadingMore) {
|
||||
emit('load-more')
|
||||
}
|
||||
},
|
||||
{ threshold: 0.1 }
|
||||
)
|
||||
})
|
||||
|
||||
watch(loadMoreSentinel, (el) => {
|
||||
if (el && observer) {
|
||||
observer.observe(el)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (observer) {
|
||||
observer.disconnect()
|
||||
observer = null
|
||||
}
|
||||
})
|
||||
|
||||
const title = computed(() => {
|
||||
switch (props.selectMode) {
|
||||
@@ -107,15 +179,6 @@ const title = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const searchPlaceholder = computed(() => {
|
||||
switch (props.selectMode) {
|
||||
case 'product': return t('catalog.search.searchProducts')
|
||||
case 'hub': return t('catalog.search.searchHubs')
|
||||
case 'supplier': return t('catalog.search.searchSuppliers')
|
||||
default: return t('catalog.search.placeholder')
|
||||
}
|
||||
})
|
||||
|
||||
const items = computed(() => {
|
||||
switch (props.selectMode) {
|
||||
case 'product': return props.products || []
|
||||
@@ -125,16 +188,7 @@ const items = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const filteredItems = computed(() => {
|
||||
if (!searchQuery.value.trim()) return items.value
|
||||
|
||||
const query = searchQuery.value.toLowerCase()
|
||||
return items.value.filter(item =>
|
||||
item.name?.toLowerCase().includes(query) ||
|
||||
item.country?.toLowerCase().includes(query)
|
||||
)
|
||||
})
|
||||
|
||||
// Select item and emit
|
||||
const onSelect = (item: Item) => {
|
||||
if (props.selectMode && item.uuid) {
|
||||
emit('select', props.selectMode, item)
|
||||
|
||||
@@ -9,35 +9,45 @@
|
||||
<Card
|
||||
padding="small"
|
||||
:interactive="linkable || selectable"
|
||||
class="relative"
|
||||
:class="[
|
||||
isSelected && 'ring-2 ring-primary ring-offset-2'
|
||||
]"
|
||||
>
|
||||
<!-- Verified badge top-right -->
|
||||
<span v-if="supplier.isVerified" class="absolute -top-2 -right-2 badge badge-neutral badge-sm">
|
||||
{{ t('catalogSupplier.badges.verified') }}
|
||||
</span>
|
||||
<div class="flex flex-col gap-1">
|
||||
<!-- Logo -->
|
||||
<div v-if="supplier.logo" class="w-12 h-12 mb-1">
|
||||
<img :src="supplier.logo" :alt="supplier.name || ''" class="w-full h-full object-contain rounded">
|
||||
<div class="flex flex-col gap-3">
|
||||
<!-- Top row: Info + Logo (logo on right) -->
|
||||
<div class="flex gap-3 items-start">
|
||||
<!-- Info (left) -->
|
||||
<div class="min-w-0 flex-1">
|
||||
<!-- Name with verified badge -->
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span v-if="supplier.isVerified" class="text-primary text-sm">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4">
|
||||
<path fill-rule="evenodd" d="M8.603 3.799A4.49 4.49 0 0 1 12 2.25c1.357 0 2.573.6 3.397 1.549a4.49 4.49 0 0 1 3.498 1.307 4.491 4.491 0 0 1 1.307 3.497A4.49 4.49 0 0 1 21.75 12a4.49 4.49 0 0 1-1.549 3.397 4.491 4.491 0 0 1-1.307 3.497 4.491 4.491 0 0 1-3.497 1.307A4.49 4.49 0 0 1 12 21.75a4.49 4.49 0 0 1-3.397-1.549 4.49 4.49 0 0 1-3.498-1.306 4.491 4.491 0 0 1-1.307-3.498A4.49 4.49 0 0 1 2.25 12c0-1.357.6-2.573 1.549-3.397a4.49 4.49 0 0 1 1.307-3.497 4.49 4.49 0 0 1 3.497-1.307Zm7.007 6.387a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
<Text size="base" weight="semibold" class="truncate">{{ supplier.name }}</Text>
|
||||
</div>
|
||||
<!-- Country -->
|
||||
<Text tone="muted" size="sm">
|
||||
{{ countryFlag }} {{ supplier.country || t('catalogMap.labels.country_unknown') }}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<!-- Logo (right) -->
|
||||
<div v-if="supplier.logo" class="w-12 h-12 shrink-0">
|
||||
<img :src="supplier.logo" :alt="supplier.name || ''" class="w-full h-full object-contain rounded">
|
||||
</div>
|
||||
<div v-else class="w-12 h-12 shrink-0 bg-primary/10 text-primary font-bold rounded flex items-center justify-center text-lg">
|
||||
{{ supplier.name?.charAt(0) }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="w-12 h-12 bg-primary/10 text-primary font-bold rounded flex items-center justify-center text-lg mb-1">
|
||||
{{ supplier.name?.charAt(0) }}
|
||||
</div>
|
||||
<!-- Title -->
|
||||
<Text size="base" weight="semibold" class="truncate">{{ supplier.name }}</Text>
|
||||
<!-- Badges -->
|
||||
|
||||
<!-- Bottom row: Badges/Chips -->
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<span class="badge badge-neutral badge-dash text-xs">
|
||||
<span v-if="reliabilityLabel" class="badge badge-neutral badge-sm">
|
||||
{{ reliabilityLabel }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- Country below -->
|
||||
<Text tone="muted" size="sm">
|
||||
{{ countryFlag }} {{ supplier.country || t('catalogMap.labels.country_unknown') }}
|
||||
</Text>
|
||||
</div>
|
||||
</Card>
|
||||
</component>
|
||||
@@ -71,7 +81,7 @@ defineEmits<{
|
||||
const localePath = useLocalePath()
|
||||
const { t } = useI18n()
|
||||
|
||||
const linkable = computed(() => !props.selectable && props.supplier.uuid)
|
||||
const linkable = computed(() => !props.selectable && !!props.supplier.uuid)
|
||||
|
||||
const reliabilityLabel = computed(() => {
|
||||
if (props.supplier.onTimeRate !== undefined && props.supplier.onTimeRate !== null) {
|
||||
|
||||
34
app/components/hero/HeroBackground.vue
Normal file
34
app/components/hero/HeroBackground.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<div class="absolute inset-0 overflow-hidden bg-slate-900">
|
||||
<!-- Lottie animation -->
|
||||
<ClientOnly>
|
||||
<DotLottieVue
|
||||
src="/animations/supply-chain.lottie"
|
||||
autoplay
|
||||
loop
|
||||
:layout="{ fit: 'cover', align: [0.5, 0.5] }"
|
||||
class="absolute top-0 left-0 w-full"
|
||||
:style="{
|
||||
height: '100vh',
|
||||
opacity: 1 - collapseProgress * 0.7,
|
||||
transform: `scale(${1 + collapseProgress * 0.1})`
|
||||
}"
|
||||
/>
|
||||
</ClientOnly>
|
||||
|
||||
<!-- Overlay for text readability - only when hero starts collapsing -->
|
||||
<div
|
||||
v-if="collapseProgress > 0.5"
|
||||
class="absolute inset-0 bg-gradient-to-b from-slate-900/60 via-slate-900/40 to-slate-900/70"
|
||||
:style="{ opacity: (collapseProgress - 0.5) * 2 }"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
||||
|
||||
defineProps<{
|
||||
collapseProgress: number
|
||||
}>()
|
||||
</script>
|
||||
@@ -1,99 +1,211 @@
|
||||
<template>
|
||||
<header class="bg-base-100 shadow-md">
|
||||
<!-- Single row: Logo + Search + Icons -->
|
||||
<div class="flex items-start px-4 lg:px-6 py-3 gap-4">
|
||||
<!-- Left: Logo -->
|
||||
<div class="flex items-center flex-shrink-0 py-2.5">
|
||||
<NuxtLink :to="localePath('/')" class="flex items-center gap-2">
|
||||
<span class="font-bold text-xl">Optovia</span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<header
|
||||
class="relative"
|
||||
:style="{ height: `${height}px` }"
|
||||
>
|
||||
<div class="relative mx-auto max-w-[2200px] px-3 py-2 md:px-4">
|
||||
<div
|
||||
class="flex items-center gap-2"
|
||||
:class="isHeroLayout ? 'items-start' : ''"
|
||||
:style="rowStyle"
|
||||
>
|
||||
<!-- Left: Logo + AI button + Nav links (top aligned) -->
|
||||
<div class="flex items-center flex-shrink-0 rounded-full pill-glass">
|
||||
<div class="flex items-center gap-2 px-4 py-2">
|
||||
<NuxtLink :to="localePath('/')" class="flex items-center gap-2">
|
||||
<span class="font-black text-xl tracking-tight" :class="useWhiteText ? 'text-white' : 'text-base-content'">Optovia</span>
|
||||
</NuxtLink>
|
||||
<button
|
||||
class="w-8 h-8 rounded-full flex items-center justify-center transition-colors"
|
||||
:class="[
|
||||
useWhiteText
|
||||
? (chatOpen ? 'bg-white/20 text-white' : 'text-white/70 hover:text-white hover:bg-white/10')
|
||||
: (chatOpen ? 'bg-base-300 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200')
|
||||
]"
|
||||
aria-label="Toggle AI assistant"
|
||||
@click="$emit('toggle-chat')"
|
||||
>
|
||||
<Icon name="lucide:bot" size="18" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Mode toggle (between Logo and Search) -->
|
||||
<div v-if="showModeToggle" class="flex items-center flex-shrink-0 py-2.5">
|
||||
<div class="join">
|
||||
<button
|
||||
class="btn btn-sm join-item"
|
||||
:class="catalogMode === 'explore' ? 'btn-primary' : 'btn-ghost'"
|
||||
@click="$emit('set-catalog-mode', 'explore')"
|
||||
>
|
||||
{{ $t('catalog.modes.explore') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm join-item"
|
||||
:class="catalogMode === 'quote' ? 'btn-primary' : 'btn-ghost'"
|
||||
@click="$emit('set-catalog-mode', 'quote')"
|
||||
>
|
||||
{{ $t('catalog.modes.quote') }}
|
||||
</button>
|
||||
<!-- Service nav links -->
|
||||
<div v-if="showModeToggle" class="w-px h-6 bg-white/20 self-center" />
|
||||
<div v-if="showModeToggle" class="flex items-center px-3 py-2">
|
||||
<nav class="flex items-center gap-1">
|
||||
<button
|
||||
class="px-3 py-1 text-sm font-medium rounded-full transition-colors"
|
||||
:class="showActiveMode && catalogMode === 'explore' && !isClientArea
|
||||
? (useWhiteText ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content')
|
||||
: (useWhiteText ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200')"
|
||||
@click="$emit('set-catalog-mode', 'explore')"
|
||||
>
|
||||
{{ $t('catalog.modes.explore') }}
|
||||
</button>
|
||||
<NuxtLink
|
||||
:to="localePath('/catalog/product')"
|
||||
class="px-3 py-1 text-sm font-medium rounded-full transition-colors"
|
||||
:class="isQuoteStepPage
|
||||
? (useWhiteText ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content')
|
||||
: (useWhiteText ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200')"
|
||||
>
|
||||
{{ $t('catalog.modes.quote') }}
|
||||
</NuxtLink>
|
||||
<!-- Role switcher: Я клиент + dropdown -->
|
||||
<div v-if="loggedIn" class="flex items-center">
|
||||
<NuxtLink
|
||||
:to="localePath(currentRole === 'SELLER' ? '/clientarea/offers' : '/clientarea/orders')"
|
||||
class="px-3 py-1 text-sm font-medium rounded-lg transition-colors"
|
||||
:class="isClientArea
|
||||
? (useWhiteText ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content')
|
||||
: (useWhiteText ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200')"
|
||||
>
|
||||
{{ currentRole === 'SELLER' ? $t('cabinetNav.roles.seller') : $t('cabinetNav.roles.client') }}
|
||||
</NuxtLink>
|
||||
|
||||
<!-- Dropdown для переключения роли (если есть обе роли) -->
|
||||
<div v-if="hasMultipleRoles" class="dropdown dropdown-end">
|
||||
<button
|
||||
tabindex="0"
|
||||
class="p-1 ml-0.5 transition-colors"
|
||||
:class="useWhiteText ? 'text-white/50 hover:text-white' : 'text-base-content/50 hover:text-base-content'"
|
||||
>
|
||||
<Icon name="lucide:chevron-down" size="14" />
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu bg-base-100 rounded-box z-50 w-48 p-2 shadow-lg border border-base-300">
|
||||
<li>
|
||||
<a
|
||||
:class="{ active: currentRole === 'BUYER' }"
|
||||
@click="$emit('switch-role', 'BUYER')"
|
||||
>
|
||||
{{ $t('cabinetNav.roles.client') }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
:class="{ active: currentRole === 'SELLER' }"
|
||||
@click="$emit('switch-role', 'SELLER')"
|
||||
>
|
||||
{{ $t('cabinetNav.roles.seller') }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Center: Search input (transforms based on mode) -->
|
||||
<div class="flex-1 flex flex-col items-center max-w-2xl mx-auto gap-2">
|
||||
<!-- Quote mode: Segmented input like Airbnb -->
|
||||
<template v-if="catalogMode === 'quote'">
|
||||
<div class="flex items-center gap-3 w-full">
|
||||
<div class="flex items-center flex-1 rounded-full border border-base-300 bg-base-100 shadow-sm divide-x divide-base-300">
|
||||
<!-- Product segment -->
|
||||
<button
|
||||
class="flex-1 px-4 py-2.5 text-left hover:bg-base-200/50 rounded-l-full transition-colors min-w-0"
|
||||
@click="$emit('edit-token', 'product')"
|
||||
<!-- Center: Search input OR Client Area tabs (vertically centered) -->
|
||||
<div
|
||||
class="flex-1 flex flex-col items-center max-w-2xl mx-auto gap-2 transition-all"
|
||||
:class="isHeroLayout ? 'justify-start' : 'justify-center'"
|
||||
:style="centerStyle"
|
||||
>
|
||||
<!-- Hero slot for home page title -->
|
||||
<slot name="hero" />
|
||||
|
||||
<!-- Client Area tabs -->
|
||||
<template v-if="isClientArea">
|
||||
<div class="flex items-center gap-1 rounded-full pill-glass p-1">
|
||||
<!-- BUYER tabs -->
|
||||
<template v-if="currentRole !== 'SELLER'">
|
||||
<NuxtLink
|
||||
:to="localePath('/clientarea/orders')"
|
||||
class="px-4 py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap"
|
||||
:class="isClientAreaTabActive('/clientarea/orders') ? 'bg-primary text-primary-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200/50'"
|
||||
>
|
||||
<div class="text-xs text-base-content/60">{{ $t('catalog.quote.product') }}</div>
|
||||
<div class="font-medium truncate">{{ productLabel || $t('catalog.quote.selectProduct') }}</div>
|
||||
</button>
|
||||
<!-- Hub segment -->
|
||||
<button
|
||||
class="flex-1 px-4 py-2.5 text-left hover:bg-base-200/50 transition-colors min-w-0"
|
||||
@click="$emit('edit-token', 'hub')"
|
||||
{{ $t('cabinetNav.orders') }}
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
:to="localePath('/clientarea/addresses')"
|
||||
class="px-4 py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap"
|
||||
:class="isClientAreaTabActive('/clientarea/addresses') ? 'bg-primary text-primary-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200/50'"
|
||||
>
|
||||
<div class="text-xs text-base-content/60">{{ $t('catalog.quote.hub') }}</div>
|
||||
<div class="font-medium truncate">{{ hubLabel || $t('catalog.quote.selectHub') }}</div>
|
||||
</button>
|
||||
<!-- Quantity segment -->
|
||||
<button
|
||||
class="flex-1 px-4 py-2.5 text-left hover:bg-base-200/50 rounded-r-full transition-colors min-w-0"
|
||||
@click="$emit('edit-token', 'quantity')"
|
||||
{{ $t('cabinetNav.addresses') }}
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
<!-- SELLER tabs -->
|
||||
<template v-else>
|
||||
<NuxtLink
|
||||
:to="localePath('/clientarea/offers')"
|
||||
class="px-4 py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap"
|
||||
:class="isClientAreaTabActive('/clientarea/offers') ? 'bg-primary text-primary-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200/50'"
|
||||
>
|
||||
<div class="text-xs text-base-content/60">{{ $t('catalog.quote.quantity') }}</div>
|
||||
<div class="font-medium">{{ quantity ? `${quantity} ${$t('units.t')}` : '—' }}</div>
|
||||
</button>
|
||||
</div>
|
||||
{{ $t('cabinetNav.myOffers') }}
|
||||
</NuxtLink>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Quote mode: Step-based capsule navigation (like logistics) -->
|
||||
<template v-else-if="catalogMode === 'quote'">
|
||||
<div class="flex items-center w-full rounded-full pill-glass overflow-hidden">
|
||||
<!-- Product segment -->
|
||||
<NuxtLink
|
||||
:to="localePath('/catalog/product')"
|
||||
class="flex-1 px-4 py-2 text-left hover:bg-white/10 rounded-l-full transition-colors min-w-0"
|
||||
>
|
||||
<span class="text-[10px] font-bold uppercase tracking-wider opacity-60">{{ $t('catalog.filters.product') }}</span>
|
||||
<div class="font-medium truncate text-base-content">{{ productLabel || $t('catalog.quote.selectProduct') }}</div>
|
||||
</NuxtLink>
|
||||
<div class="w-px h-8 bg-base-300/40 self-center" />
|
||||
<!-- Hub segment -->
|
||||
<NuxtLink
|
||||
:to="localePath('/catalog/destination')"
|
||||
class="flex-1 px-4 py-2 text-left hover:bg-white/10 transition-colors min-w-0"
|
||||
>
|
||||
<span class="text-[10px] font-bold uppercase tracking-wider opacity-60">{{ $t('catalog.filters.hub') }}</span>
|
||||
<div class="font-medium truncate text-base-content">{{ hubLabel || $t('catalog.quote.selectHub') }}</div>
|
||||
</NuxtLink>
|
||||
<div class="w-px h-8 bg-base-300/40 self-center" />
|
||||
<!-- Quantity segment -->
|
||||
<NuxtLink
|
||||
:to="localePath('/catalog/quantity')"
|
||||
class="flex-1 px-4 py-2 text-left hover:bg-white/10 transition-colors min-w-0"
|
||||
>
|
||||
<span class="text-[10px] font-bold uppercase tracking-wider opacity-60">{{ $t('catalog.filters.quantity') }}</span>
|
||||
<div class="font-medium truncate text-base-content">{{ quantity || '—' }} {{ quantity ? $t('units.t') : '' }}</div>
|
||||
</NuxtLink>
|
||||
<!-- Search button -->
|
||||
<button
|
||||
class="btn btn-primary btn-circle shadow-lg"
|
||||
:disabled="!canSearch"
|
||||
@click="$emit('search')"
|
||||
class="btn btn-primary btn-circle m-1"
|
||||
@click="navigateToSearch"
|
||||
>
|
||||
<Icon name="lucide:search" size="20" />
|
||||
<Icon name="lucide:search" size="18" />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Explore mode: Regular pill input + chips -->
|
||||
<!-- Explore mode: Regular pill input + chips (white glass) -->
|
||||
<template v-else>
|
||||
<!-- Big pill input -->
|
||||
<div
|
||||
class="flex items-center gap-3 w-full px-5 py-3 rounded-full border border-base-300 bg-base-100 focus-within:border-primary focus-within:ring-2 focus-within:ring-primary/20 transition-all cursor-text"
|
||||
class="flex items-center gap-3 w-full px-5 py-3 rounded-full pill-glass focus-within:ring-2 focus-within:ring-primary/20 transition-all cursor-text"
|
||||
@click="focusInput"
|
||||
>
|
||||
<Icon name="lucide:search" size="22" class="text-primary flex-shrink-0" />
|
||||
|
||||
<!-- Tokens + input inline -->
|
||||
<div class="flex items-center gap-2 flex-wrap flex-1 min-w-0">
|
||||
<!-- Active filter tokens -->
|
||||
<!-- Tokens + input inline (no wrap to prevent height change) -->
|
||||
<div class="flex items-center gap-2 flex-1 min-w-0 overflow-hidden">
|
||||
<!-- Active filter tokens (outline style with icon in circle) -->
|
||||
<div
|
||||
v-for="token in activeTokens"
|
||||
:key="token.type"
|
||||
class="badge badge-lg gap-1.5 cursor-pointer hover:opacity-80 transition-all flex-shrink-0 text-white"
|
||||
:style="{ backgroundColor: getTokenColor(token.type) }"
|
||||
class="flex items-center gap-1.5 px-2.5 py-1.5 rounded-full border-2 cursor-pointer hover:opacity-80 transition-all flex-shrink-0"
|
||||
:style="{ borderColor: getTokenColor(token.type), color: getTokenColor(token.type) }"
|
||||
@click.stop="$emit('edit-token', token.type)"
|
||||
>
|
||||
<Icon :name="token.icon" size="14" />
|
||||
<span class="max-w-28 truncate">{{ token.label }}</span>
|
||||
<span
|
||||
class="w-5 h-5 rounded-full flex items-center justify-center flex-shrink-0"
|
||||
:style="{ backgroundColor: getTokenColor(token.type) }"
|
||||
>
|
||||
<Icon :name="getTokenIcon(token.type)" size="12" class="text-white" />
|
||||
</span>
|
||||
<span class="max-w-28 truncate font-medium text-sm">{{ token.label }}</span>
|
||||
<button
|
||||
class="hover:text-error"
|
||||
class="hover:text-error ml-0.5"
|
||||
@click.stop="$emit('remove-token', token.type)"
|
||||
>
|
||||
<Icon name="lucide:x" size="14" />
|
||||
@@ -106,70 +218,61 @@
|
||||
v-model="localSearchQuery"
|
||||
type="text"
|
||||
:placeholder="placeholder"
|
||||
class="flex-1 min-w-32 bg-transparent outline-none text-lg"
|
||||
class="flex-1 min-w-32 bg-transparent outline-none text-lg text-base-content placeholder:text-base-content/50"
|
||||
@input="$emit('update:search-query', localSearchQuery)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chips below -->
|
||||
<div
|
||||
v-if="availableChips.length > 0"
|
||||
class="flex items-center justify-center gap-2"
|
||||
>
|
||||
<button
|
||||
v-for="chip in availableChips"
|
||||
:key="chip.type"
|
||||
class="btn btn-xs btn-ghost gap-1"
|
||||
@click="$emit('start-select', chip.type)"
|
||||
>
|
||||
<Icon name="lucide:plus" size="12" />
|
||||
{{ chip.label }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Right: AI + Globe + Team + User -->
|
||||
<div class="flex items-center gap-1 flex-shrink-0 py-2.5">
|
||||
<!-- AI Assistant button -->
|
||||
<NuxtLink :to="localePath('/clientarea/ai')" class="btn btn-ghost btn-circle btn-sm">
|
||||
<Icon name="lucide:bot" size="18" />
|
||||
</NuxtLink>
|
||||
|
||||
<!-- Globe (language/currency) dropdown -->
|
||||
<div class="dropdown dropdown-end">
|
||||
<button tabindex="0" class="btn btn-ghost btn-circle btn-sm">
|
||||
<Icon name="lucide:globe" size="18" />
|
||||
</button>
|
||||
<div tabindex="0" class="dropdown-content bg-base-100 rounded-box z-50 w-52 p-4 shadow-lg border border-base-300">
|
||||
<div class="font-semibold mb-2">{{ $t('common.language') }}</div>
|
||||
<div class="flex gap-2 mb-4">
|
||||
<NuxtLink
|
||||
v-for="loc in locales"
|
||||
:key="loc.code"
|
||||
:to="switchLocalePath(loc.code)"
|
||||
class="btn btn-sm"
|
||||
:class="locale === loc.code ? 'btn-primary' : 'btn-ghost'"
|
||||
>
|
||||
{{ loc.code.toUpperCase() }}
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div class="font-semibold mb-2">{{ $t('common.theme') }}</div>
|
||||
<!-- Right: Globe + Team + User (top aligned like logo) -->
|
||||
<div class="flex items-center flex-shrink-0 rounded-full pill-glass">
|
||||
<div class="w-px h-6 bg-white/20 self-center" />
|
||||
<div class="flex items-center px-2 py-2">
|
||||
<!-- Globe (language/currency) dropdown -->
|
||||
<div class="dropdown dropdown-end">
|
||||
<button
|
||||
class="btn btn-sm btn-ghost w-full justify-start"
|
||||
@click="$emit('toggle-theme')"
|
||||
tabindex="0"
|
||||
class="w-8 h-8 rounded-full flex items-center justify-center transition-colors"
|
||||
:class="useWhiteText ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'"
|
||||
>
|
||||
<Icon :name="theme === 'night' ? 'lucide:sun' : 'lucide:moon'" size="16" />
|
||||
{{ theme === 'night' ? $t('common.theme_light') : $t('common.theme_dark') }}
|
||||
<Icon name="lucide:globe" size="18" />
|
||||
</button>
|
||||
<div tabindex="0" class="dropdown-content bg-base-100 rounded-box z-50 w-52 p-4 shadow-lg border border-base-300">
|
||||
<div class="font-semibold mb-2">{{ $t('common.language') }}</div>
|
||||
<div class="flex gap-2 mb-4">
|
||||
<NuxtLink
|
||||
v-for="loc in locales"
|
||||
:key="loc.code"
|
||||
:to="switchLocalePath(loc.code)"
|
||||
class="btn btn-sm"
|
||||
:class="locale === loc.code ? 'btn-primary' : 'btn-ghost'"
|
||||
>
|
||||
{{ loc.code.toUpperCase() }}
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div class="font-semibold mb-2">{{ $t('common.theme') }}</div>
|
||||
<button
|
||||
class="btn btn-sm btn-ghost w-full justify-start"
|
||||
@click="$emit('toggle-theme')"
|
||||
>
|
||||
<Icon :name="theme === 'night' ? 'lucide:sun' : 'lucide:moon'" size="16" />
|
||||
{{ theme === 'night' ? $t('common.theme_light') : $t('common.theme_dark') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Team dropdown -->
|
||||
<template v-if="loggedIn && userData?.teams?.length">
|
||||
<div v-if="loggedIn && userData?.teams?.length" class="w-px h-6 bg-white/20 self-center" />
|
||||
<div v-if="loggedIn && userData?.teams?.length" class="flex items-center px-2 py-2">
|
||||
<div class="dropdown dropdown-end">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm gap-1">
|
||||
<button
|
||||
tabindex="0"
|
||||
class="h-8 flex items-center gap-1 px-2 rounded-lg transition-colors"
|
||||
:class="useWhiteText ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'"
|
||||
>
|
||||
<Icon name="lucide:building-2" size="16" />
|
||||
<span class="hidden lg:inline max-w-24 truncate text-xs">
|
||||
{{ userData?.activeTeam?.name || $t('common.selectTeam') }}
|
||||
@@ -195,21 +298,26 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- User menu -->
|
||||
<template v-if="sessionChecked">
|
||||
<div v-if="sessionChecked" class="w-px h-6 bg-white/20 self-center" />
|
||||
<div v-if="sessionChecked" class="flex items-center px-2 py-2">
|
||||
<template v-if="loggedIn">
|
||||
<div class="dropdown dropdown-end">
|
||||
<div tabindex="0" role="button" class="btn btn-ghost btn-circle btn-sm avatar">
|
||||
<div class="w-8 rounded-full">
|
||||
<div v-if="userAvatarSvg" v-html="userAvatarSvg" class="w-full h-full" />
|
||||
<div
|
||||
v-else
|
||||
class="w-full h-full bg-primary flex items-center justify-center text-primary-content font-bold text-xs"
|
||||
>
|
||||
{{ userInitials }}
|
||||
</div>
|
||||
<div
|
||||
tabindex="0"
|
||||
role="button"
|
||||
class="w-8 h-8 rounded-full overflow-hidden ring-2 transition-all cursor-pointer"
|
||||
:class="useWhiteText ? 'ring-white/20 hover:ring-white/40' : 'ring-base-300 hover:ring-primary'"
|
||||
>
|
||||
<div v-if="userAvatarSvg" v-html="userAvatarSvg" class="w-full h-full" />
|
||||
<div
|
||||
v-else
|
||||
class="w-full h-full flex items-center justify-center font-bold text-xs"
|
||||
:class="useWhiteText ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content'"
|
||||
>
|
||||
{{ userInitials }}
|
||||
</div>
|
||||
</div>
|
||||
<ul
|
||||
@@ -236,13 +344,18 @@
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button @click="$emit('sign-in')" class="btn btn-primary btn-sm">
|
||||
<button
|
||||
@click="$emit('sign-in')"
|
||||
class="px-4 py-1.5 rounded-full text-sm font-medium transition-colors"
|
||||
:class="useWhiteText ? 'bg-white/20 text-white hover:bg-white/30' : 'bg-primary text-primary-content hover:bg-primary-focus'"
|
||||
>
|
||||
{{ $t('auth.login') }}
|
||||
</button>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
</template>
|
||||
@@ -253,7 +366,7 @@ import { entityColors } from '~/composables/useCatalogSearch'
|
||||
|
||||
import type { CatalogMode } from '~/composables/useCatalogSearch'
|
||||
|
||||
const props = defineProps<{
|
||||
const props = withDefaults(defineProps<{
|
||||
sessionChecked?: boolean
|
||||
loggedIn?: boolean
|
||||
userAvatarSvg?: string
|
||||
@@ -267,6 +380,9 @@ const props = defineProps<{
|
||||
teams?: Array<{ id?: string; name?: string; logtoOrgId?: string }>
|
||||
} | null
|
||||
isSeller?: boolean
|
||||
// Role switching props
|
||||
hasMultipleRoles?: boolean
|
||||
currentRole?: string
|
||||
// Search props
|
||||
activeTokens?: Array<{ type: string; id: string; label: string; icon: string }>
|
||||
availableChips?: Array<{ type: string; label: string }>
|
||||
@@ -280,36 +396,85 @@ const props = defineProps<{
|
||||
quantity?: string
|
||||
canSearch?: boolean
|
||||
showModeToggle?: boolean
|
||||
}>()
|
||||
showActiveMode?: boolean // Whether to show active state on mode toggle
|
||||
// Glass style applied when header is collapsed
|
||||
isCollapsed?: boolean
|
||||
// Home page flag for transparent background
|
||||
isHomePage?: boolean
|
||||
// Client area flag - shows cabinet tabs instead of search
|
||||
isClientArea?: boolean
|
||||
// AI chat sidebar state
|
||||
chatOpen?: boolean
|
||||
// Dynamic height for hero effect
|
||||
height?: number
|
||||
// Collapse progress for hero layout
|
||||
collapseProgress?: number
|
||||
}>(), {
|
||||
height: 100,
|
||||
collapseProgress: 1
|
||||
})
|
||||
|
||||
defineEmits([
|
||||
'toggle-chat',
|
||||
'toggle-theme',
|
||||
'sign-out',
|
||||
'sign-in',
|
||||
'switch-team',
|
||||
'switch-role',
|
||||
// Search events
|
||||
'start-select',
|
||||
'cancel-select',
|
||||
'edit-token',
|
||||
'remove-token',
|
||||
'update:search-query',
|
||||
'update-quantity',
|
||||
// Quote mode
|
||||
'search',
|
||||
'set-catalog-mode'
|
||||
])
|
||||
|
||||
const localePath = useLocalePath()
|
||||
const route = useRoute()
|
||||
const { locale, locales } = useI18n()
|
||||
const switchLocalePath = useSwitchLocalePath()
|
||||
const { t } = useI18n()
|
||||
const { chatOpen } = toRefs(props)
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// Check if we're on a quote step page
|
||||
const isQuoteStepPage = computed(() => {
|
||||
const path = route.path
|
||||
return path.includes('/catalog/product') ||
|
||||
path.includes('/catalog/destination') ||
|
||||
path.includes('/catalog/quantity') ||
|
||||
path.includes('/catalog/results')
|
||||
})
|
||||
|
||||
// Navigate to search results (quote mode step flow)
|
||||
const navigateToSearch = () => {
|
||||
router.push(localePath('/catalog/product'))
|
||||
}
|
||||
|
||||
// Check if client area tab is active
|
||||
const isClientAreaTabActive = (path: string) => {
|
||||
const currentPath = route.path
|
||||
const localizedPath = localePath(path)
|
||||
return currentPath === localizedPath || currentPath.startsWith(localizedPath + '/')
|
||||
}
|
||||
|
||||
const inputRef = ref<HTMLInputElement>()
|
||||
const localSearchQuery = ref(props.searchQuery || '')
|
||||
const localQuantity = ref(props.quantity || '')
|
||||
|
||||
watch(() => props.searchQuery, (val) => {
|
||||
localSearchQuery.value = val || ''
|
||||
})
|
||||
|
||||
watch(() => props.quantity, (val) => {
|
||||
localQuantity.value = val || ''
|
||||
})
|
||||
|
||||
const focusInput = () => {
|
||||
inputRef.value?.focus()
|
||||
}
|
||||
@@ -339,5 +504,36 @@ const selectModeIcon = computed(() => {
|
||||
const getTokenColor = (type: string) => {
|
||||
return entityColors[type as keyof typeof entityColors] || entityColors.product
|
||||
}
|
||||
</script>
|
||||
|
||||
const getTokenIcon = (type: string) => {
|
||||
const icons: Record<string, string> = {
|
||||
product: 'lucide:shopping-bag',
|
||||
hub: 'lucide:warehouse',
|
||||
supplier: 'lucide:factory'
|
||||
}
|
||||
return icons[type] || 'lucide:tag'
|
||||
}
|
||||
|
||||
const isHeroLayout = computed(() => props.isHomePage && !props.isClientArea)
|
||||
const topRowHeight = 100
|
||||
|
||||
const rowStyle = computed(() => {
|
||||
if (isHeroLayout.value) {
|
||||
return { height: `${topRowHeight}px` }
|
||||
}
|
||||
return { height: `${props.height}px` }
|
||||
})
|
||||
|
||||
const centerStyle = computed(() => {
|
||||
if (!isHeroLayout.value) return {}
|
||||
const heroHeight = props.height || topRowHeight
|
||||
const minTop = 0
|
||||
const maxTop = Math.max(120, Math.round(heroHeight * 0.42))
|
||||
const progress = Math.min(1, Math.max(0, props.collapseProgress || 0))
|
||||
const top = Math.round(maxTop - (maxTop - minTop) * progress)
|
||||
return { marginTop: `${top}px` }
|
||||
})
|
||||
|
||||
// Use white text on dark backgrounds (collapsed or home page with animation)
|
||||
const useWhiteText = computed(() => props.isCollapsed || props.isHomePage)
|
||||
</script>
|
||||
|
||||
@@ -1,39 +1,70 @@
|
||||
<template>
|
||||
<div class="flex flex-col flex-1 min-h-0 relative">
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="absolute inset-0 z-50 flex items-center justify-center bg-base-100/80">
|
||||
<Card padding="lg">
|
||||
<Stack align="center" justify="center" gap="3">
|
||||
<Spinner />
|
||||
<Text tone="muted">{{ $t('catalogLanding.states.loading') }}</Text>
|
||||
</Stack>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div class="fixed inset-0 flex flex-col">
|
||||
<!-- Fullscreen Map -->
|
||||
<div class="absolute inset-0">
|
||||
<ClientOnly>
|
||||
<CatalogMap
|
||||
ref="mapRef"
|
||||
:map-id="mapId"
|
||||
:items="useServerClustering ? [] : itemsWithCoords"
|
||||
:clustered-points="useServerClustering ? clusteredNodes : []"
|
||||
:use-server-clustering="useServerClustering"
|
||||
:point-color="pointColor"
|
||||
:items="isInfoMode ? [] : (useServerClustering ? [] : itemsWithCoords)"
|
||||
:clustered-points="isInfoMode ? [] : (useServerClustering && !useTypedClusters ? clusteredNodes : [])"
|
||||
:clustered-points-by-type="isInfoMode ? undefined : (useServerClustering && useTypedClusters ? clusteredPointsByType : undefined)"
|
||||
:use-server-clustering="useServerClustering && !isInfoMode"
|
||||
:point-color="activePointColor"
|
||||
:entity-type="activeEntityType"
|
||||
:hovered-item-id="hoveredId"
|
||||
:hovered-item="hoveredItem"
|
||||
:related-points="relatedPoints"
|
||||
:info-loading="infoLoading"
|
||||
:fit-padding-left="fitPaddingLeft"
|
||||
@select-item="onMapSelect"
|
||||
@bounds-change="onBoundsChange"
|
||||
/>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
|
||||
<!-- View toggle (top RIGHT overlay) - works in both modes -->
|
||||
<div class="absolute top-20 right-4 z-20 hidden lg:block">
|
||||
<div class="join bg-base-100/95 backdrop-blur shadow-lg rounded-lg">
|
||||
<!-- View mode loading indicator -->
|
||||
<div
|
||||
v-if="clusterLoading || loading"
|
||||
class="absolute top-[116px] left-1/2 -translate-x-1/2 z-30 flex items-center gap-2 pill-glass rounded-full px-4 py-2"
|
||||
>
|
||||
<span class="loading loading-spinner loading-sm text-base-content" />
|
||||
<span class="text-base-content text-sm font-medium">{{ $t('common.loading') }}</span>
|
||||
</div>
|
||||
|
||||
<!-- List button (LEFT, opens panel) - hide when panel is open -->
|
||||
<button
|
||||
v-if="!isPanelOpen"
|
||||
class="absolute top-[116px] left-4 z-20 hidden lg:flex items-center gap-2 pill-glass rounded-full px-3 py-1.5 text-base-content text-sm hover:bg-white/20 transition-colors"
|
||||
@click="openPanel"
|
||||
>
|
||||
<Icon name="lucide:menu" size="16" />
|
||||
<span>{{ $t('catalog.list') }}</span>
|
||||
</button>
|
||||
|
||||
<!-- Filter by bounds checkbox (LEFT, next to panel when open) - only in selection mode -->
|
||||
<label
|
||||
v-if="selectMode !== null"
|
||||
class="absolute top-[116px] left-[calc(1rem+32rem+1rem)] z-20 hidden lg:flex items-center gap-2 pill-glass rounded-full px-3 py-1.5 cursor-pointer text-base-content text-sm hover:bg-white/20 transition-colors"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="filterByBounds"
|
||||
class="checkbox checkbox-xs checkbox-primary"
|
||||
@change="$emit('update:filter-by-bounds', ($event.target as HTMLInputElement).checked)"
|
||||
/>
|
||||
<span>{{ $t('catalog.search.filterByMap') }}</span>
|
||||
</label>
|
||||
|
||||
|
||||
<!-- View toggle (top RIGHT overlay, below header) - hide in info mode or when hideViewToggle -->
|
||||
<div v-if="!isInfoMode && !hideViewToggle" class="absolute top-[116px] right-4 z-20 hidden lg:flex items-center gap-2">
|
||||
<!-- View mode toggle -->
|
||||
<div class="flex gap-1 pill-glass rounded-full p-1">
|
||||
<button
|
||||
class="btn btn-sm join-item gap-2"
|
||||
:class="{ 'btn-active': mapViewMode === 'offers' }"
|
||||
v-if="showOffersToggle"
|
||||
class="flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-bold transition-colors"
|
||||
:class="mapViewMode === 'offers' ? 'bg-white/20 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-white/10'"
|
||||
@click="setMapViewMode('offers')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #f97316">
|
||||
@@ -42,8 +73,9 @@
|
||||
{{ $t('catalog.views.offers') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm join-item gap-2"
|
||||
:class="{ 'btn-active': mapViewMode === 'hubs' }"
|
||||
v-if="showHubsToggle"
|
||||
class="flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-bold transition-colors"
|
||||
:class="mapViewMode === 'hubs' ? 'bg-white/20 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-white/10'"
|
||||
@click="setMapViewMode('hubs')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #22c55e">
|
||||
@@ -52,8 +84,9 @@
|
||||
{{ $t('catalog.views.hubs') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm join-item gap-2"
|
||||
:class="{ 'btn-active': mapViewMode === 'suppliers' }"
|
||||
v-if="showSuppliersToggle"
|
||||
class="flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-bold transition-colors"
|
||||
:class="mapViewMode === 'suppliers' ? 'bg-white/20 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-white/10'"
|
||||
@click="setMapViewMode('suppliers')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #3b82f6">
|
||||
@@ -64,69 +97,86 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Left overlay panel (shown when showPanel is true) -->
|
||||
<div
|
||||
v-if="showPanel"
|
||||
class="absolute top-20 left-4 bottom-4 z-10 w-96 max-w-[calc(100vw-2rem)] hidden lg:block"
|
||||
>
|
||||
<div class="bg-base-300/95 backdrop-blur rounded-xl shadow-lg p-4 h-full overflow-hidden flex flex-col">
|
||||
<slot name="panel" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile bottom sheet -->
|
||||
<div class="lg:hidden absolute bottom-0 left-0 right-0 z-20">
|
||||
<!-- Mobile view toggle -->
|
||||
<div class="flex justify-end px-4 mb-2">
|
||||
<div class="join bg-base-100/95 backdrop-blur shadow-lg rounded-lg">
|
||||
<button
|
||||
class="btn btn-xs join-item gap-1"
|
||||
:class="{ 'btn-active': mapViewMode === 'offers' }"
|
||||
@click="setMapViewMode('offers')"
|
||||
>
|
||||
<span class="w-4 h-4 rounded-full flex items-center justify-center" style="background-color: #f97316">
|
||||
<Icon name="lucide:shopping-bag" size="10" class="text-white" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-xs join-item gap-1"
|
||||
:class="{ 'btn-active': mapViewMode === 'hubs' }"
|
||||
@click="setMapViewMode('hubs')"
|
||||
>
|
||||
<span class="w-4 h-4 rounded-full flex items-center justify-center" style="background-color: #22c55e">
|
||||
<Icon name="lucide:warehouse" size="10" class="text-white" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-xs join-item gap-1"
|
||||
:class="{ 'btn-active': mapViewMode === 'suppliers' }"
|
||||
@click="setMapViewMode('suppliers')"
|
||||
>
|
||||
<span class="w-4 h-4 rounded-full flex items-center justify-center" style="background-color: #3b82f6">
|
||||
<Icon name="lucide:factory" size="10" class="text-white" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile panel (collapsible) - only when showPanel is true -->
|
||||
<!-- Left panel (slides from left when isPanelOpen is true) -->
|
||||
<Transition name="slide-left">
|
||||
<div
|
||||
v-if="showPanel"
|
||||
class="bg-base-300/95 backdrop-blur rounded-t-xl shadow-lg transition-all duration-300"
|
||||
:class="mobilePanelExpanded ? 'h-[60vh]' : 'h-auto'"
|
||||
v-if="isPanelOpen"
|
||||
class="absolute top-[116px] left-4 bottom-4 z-30 max-w-[calc(100vw-2rem)] hidden lg:block"
|
||||
:class="panelWidth"
|
||||
>
|
||||
<!-- Drag handle -->
|
||||
<div
|
||||
class="flex justify-center py-2 cursor-pointer"
|
||||
@click="mobilePanelExpanded = !mobilePanelExpanded"
|
||||
>
|
||||
<div class="w-10 h-1 bg-base-300 rounded-full" />
|
||||
</div>
|
||||
|
||||
<div class="px-4 pb-4 overflow-y-auto" :class="mobilePanelExpanded ? 'h-[calc(60vh-2rem)]' : 'max-h-48'">
|
||||
<div class="bg-white/90 backdrop-blur-[14px] border border-white/50 rounded-[1.1rem] shadow-2xl h-full flex flex-col text-base-content">
|
||||
<slot name="panel" />
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<!-- Mobile bottom sheet -->
|
||||
<div class="lg:hidden absolute bottom-0 left-0 right-0 z-20">
|
||||
<!-- Mobile controls: List button + view toggle -->
|
||||
<div class="flex justify-between px-4 mb-2">
|
||||
<!-- List button (mobile) -->
|
||||
<button
|
||||
class="flex items-center gap-2 pill-glass rounded-full px-3 py-2 text-base-content text-sm font-medium"
|
||||
@click="openPanel"
|
||||
>
|
||||
<Icon name="lucide:menu" size="16" />
|
||||
<span>{{ $t('catalog.list') }}</span>
|
||||
</button>
|
||||
|
||||
<!-- Mobile view toggle - hide in info mode or when hideViewToggle -->
|
||||
<div v-if="!isInfoMode && !hideViewToggle" class="flex gap-1 pill-glass rounded-full p-1">
|
||||
<button
|
||||
v-if="showOffersToggle"
|
||||
class="flex items-center justify-center w-8 h-8 rounded-full transition-colors"
|
||||
:class="mapViewMode === 'offers' ? 'bg-white/20' : 'hover:bg-white/10'"
|
||||
@click="setMapViewMode('offers')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #f97316">
|
||||
<Icon name="lucide:shopping-bag" size="12" class="text-white" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="showHubsToggle"
|
||||
class="flex items-center justify-center w-8 h-8 rounded-full transition-colors"
|
||||
:class="mapViewMode === 'hubs' ? 'bg-white/20' : 'hover:bg-white/10'"
|
||||
@click="setMapViewMode('hubs')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #22c55e">
|
||||
<Icon name="lucide:warehouse" size="12" class="text-white" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="showSuppliersToggle"
|
||||
class="flex items-center justify-center w-8 h-8 rounded-full transition-colors"
|
||||
:class="mapViewMode === 'suppliers' ? 'bg-white/20' : 'hover:bg-white/10'"
|
||||
@click="setMapViewMode('suppliers')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #3b82f6">
|
||||
<Icon name="lucide:factory" size="12" class="text-white" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile panel (collapsible) - only when panel is open -->
|
||||
<Transition name="slide-up">
|
||||
<div
|
||||
v-if="isPanelOpen"
|
||||
class="bg-white rounded-t-3xl shadow-[0_-8px_40px_rgba(0,0,0,0.12)] transition-all duration-300 text-base-content h-[60vh]"
|
||||
>
|
||||
<!-- Drag handle / close -->
|
||||
<div
|
||||
class="flex justify-center py-2 cursor-pointer"
|
||||
@click="closePanel"
|
||||
>
|
||||
<div class="w-10 h-1 bg-base-300 rounded-full" />
|
||||
</div>
|
||||
|
||||
<div class="px-4 pb-4 overflow-y-auto h-[calc(60vh-2rem)]">
|
||||
<slot name="panel" />
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -134,45 +184,233 @@
|
||||
<script setup lang="ts">
|
||||
import type { MapBounds } from '~/components/catalog/CatalogMap.vue'
|
||||
|
||||
const { mapViewMode, setMapViewMode } = useCatalogSearch()
|
||||
const { mapViewMode, setMapViewMode, selectMode, startSelect, cancelSelect } = useCatalogSearch()
|
||||
|
||||
// Panel is open when selectMode is set OR when showPanel prop is true (info/quote)
|
||||
const isPanelOpen = computed(() => props.showPanel || selectMode.value !== null)
|
||||
|
||||
const isDesktop = ref(false)
|
||||
onMounted(() => {
|
||||
const media = window.matchMedia('(min-width: 1024px)')
|
||||
const update = () => {
|
||||
isDesktop.value = media.matches
|
||||
}
|
||||
update()
|
||||
media.addEventListener('change', update)
|
||||
onUnmounted(() => {
|
||||
media.removeEventListener('change', update)
|
||||
})
|
||||
})
|
||||
|
||||
const panelWidthPx = computed(() => {
|
||||
const match = props.panelWidth.match(/w-\[(\d+(?:\.\d+)?)rem\]/)
|
||||
if (match) return Number(match[1]) * 16
|
||||
if (props.panelWidth === 'w-96') return 24 * 16
|
||||
if (props.panelWidth === 'w-80') return 20 * 16
|
||||
return 0
|
||||
})
|
||||
|
||||
const fitPaddingLeft = computed(() => {
|
||||
if (!isPanelOpen.value || !isDesktop.value || panelWidthPx.value === 0) return 0
|
||||
const leftInset = 16
|
||||
const rightInset = 16
|
||||
return leftInset + panelWidthPx.value + rightInset
|
||||
})
|
||||
|
||||
// Open panel based on current mapViewMode
|
||||
const openPanel = () => {
|
||||
const newSelectMode = mapViewMode.value === 'hubs' ? 'hub'
|
||||
: mapViewMode.value === 'suppliers' ? 'supplier'
|
||||
: 'product'
|
||||
startSelect(newSelectMode)
|
||||
}
|
||||
|
||||
// Close panel
|
||||
const closePanel = () => {
|
||||
cancelSelect()
|
||||
}
|
||||
|
||||
// Point color based on map view mode
|
||||
const VIEW_MODE_COLORS = {
|
||||
offers: '#f97316', // orange
|
||||
hubs: '#22c55e', // green
|
||||
suppliers: '#3b82f6' // blue
|
||||
} as const
|
||||
|
||||
const activePointColor = computed(() => VIEW_MODE_COLORS[mapViewMode.value] || VIEW_MODE_COLORS.offers)
|
||||
|
||||
// Entity type for icons based on view mode
|
||||
const VIEW_MODE_ENTITY_TYPES = {
|
||||
offers: 'offer',
|
||||
hubs: 'hub',
|
||||
suppliers: 'supplier'
|
||||
} as const
|
||||
|
||||
const activeEntityType = computed(() => VIEW_MODE_ENTITY_TYPES[mapViewMode.value] || VIEW_MODE_ENTITY_TYPES.offers)
|
||||
|
||||
// Node type for server clustering based on view mode
|
||||
const VIEW_MODE_NODE_TYPES = {
|
||||
offers: 'offer',
|
||||
hubs: 'logistics',
|
||||
suppliers: 'supplier'
|
||||
} as const
|
||||
|
||||
const activeClusterNodeType = computed(() => VIEW_MODE_NODE_TYPES[mapViewMode.value] || VIEW_MODE_NODE_TYPES.offers)
|
||||
|
||||
// Store current bounds for refetching when view mode changes
|
||||
const currentBounds = ref<MapBounds | null>(null)
|
||||
|
||||
interface MapItem {
|
||||
uuid: string
|
||||
uuid?: string | null
|
||||
latitude?: number | null
|
||||
longitude?: number | null
|
||||
name?: string
|
||||
country?: string
|
||||
[key: string]: any
|
||||
name?: string | null
|
||||
country?: string | null
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
loading?: boolean
|
||||
useServerClustering?: boolean
|
||||
clusterNodeType?: string
|
||||
useTypedClusters?: boolean
|
||||
mapId?: string
|
||||
pointColor?: string
|
||||
hoveredId?: string
|
||||
items?: MapItem[]
|
||||
showPanel?: boolean
|
||||
filterByBounds?: boolean
|
||||
infoLoading?: boolean
|
||||
forceInfoMode?: boolean
|
||||
panelWidth?: string
|
||||
hideViewToggle?: boolean
|
||||
showOffersToggle?: boolean
|
||||
showHubsToggle?: boolean
|
||||
showSuppliersToggle?: boolean
|
||||
clusterProductUuid?: string
|
||||
clusterHubUuid?: string
|
||||
clusterSupplierUuid?: string
|
||||
relatedPoints?: Array<{
|
||||
uuid: string
|
||||
name: string
|
||||
latitude: number
|
||||
longitude: number
|
||||
type: 'hub' | 'supplier' | 'offer'
|
||||
}>
|
||||
}>(), {
|
||||
loading: false,
|
||||
useServerClustering: true,
|
||||
clusterNodeType: 'offer',
|
||||
useTypedClusters: false,
|
||||
mapId: 'catalog-map',
|
||||
pointColor: '#f97316',
|
||||
items: () => [],
|
||||
showPanel: false
|
||||
showPanel: false,
|
||||
filterByBounds: false,
|
||||
infoLoading: false,
|
||||
forceInfoMode: false,
|
||||
panelWidth: 'w-96',
|
||||
hideViewToggle: false,
|
||||
showOffersToggle: true,
|
||||
showHubsToggle: true,
|
||||
showSuppliersToggle: true,
|
||||
clusterProductUuid: undefined,
|
||||
clusterHubUuid: undefined,
|
||||
clusterSupplierUuid: undefined,
|
||||
relatedPoints: () => []
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
'select': [item: MapItem]
|
||||
'bounds-change': [bounds: MapBounds]
|
||||
'update:hoveredId': [uuid: string | undefined]
|
||||
'update:filter-by-bounds': [value: boolean]
|
||||
}>()
|
||||
|
||||
// Server-side clustering
|
||||
const nodeTypeRef = computed(() => props.clusterNodeType)
|
||||
const { clusteredNodes, fetchClusters } = useClusteredNodes(undefined, nodeTypeRef)
|
||||
const useTypedClusters = computed(() => props.useTypedClusters && props.useServerClustering)
|
||||
|
||||
const clusterProductUuid = computed(() => props.clusterProductUuid ?? undefined)
|
||||
const clusterHubUuid = computed(() => props.clusterHubUuid ?? undefined)
|
||||
const clusterSupplierUuid = computed(() => props.clusterSupplierUuid ?? undefined)
|
||||
|
||||
// Server-side clustering (single-type mode)
|
||||
const { clusteredNodes, fetchClusters, loading: singleClusterLoading, clearNodes } = useClusteredNodes(
|
||||
undefined,
|
||||
activeClusterNodeType,
|
||||
)
|
||||
|
||||
// Server-side clustering (typed mode)
|
||||
const offerClusters = useClusteredNodes(undefined, ref('offer'))
|
||||
const hubClusters = useClusteredNodes(undefined, ref('logistics'))
|
||||
const supplierClusters = useClusteredNodes(undefined, ref('supplier'))
|
||||
|
||||
const clusteredPointsByType = computed(() => ({
|
||||
offer: offerClusters.clusteredNodes.value,
|
||||
hub: hubClusters.clusteredNodes.value,
|
||||
supplier: supplierClusters.clusteredNodes.value
|
||||
}))
|
||||
|
||||
const activeClusterType = computed<'offer' | 'hub' | 'supplier'>(() => {
|
||||
if (mapViewMode.value === 'hubs') return 'hub'
|
||||
if (mapViewMode.value === 'suppliers') return 'supplier'
|
||||
return 'offer'
|
||||
})
|
||||
|
||||
const clusterLoading = computed(() => {
|
||||
if (!useTypedClusters.value) return singleClusterLoading.value
|
||||
if (activeClusterType.value === 'hub') return hubClusters.loading.value
|
||||
if (activeClusterType.value === 'supplier') return supplierClusters.loading.value
|
||||
return offerClusters.loading.value
|
||||
})
|
||||
|
||||
const clearInactiveClusters = (active: 'offer' | 'hub' | 'supplier') => {
|
||||
if (active !== 'offer') offerClusters.clearNodes()
|
||||
if (active !== 'hub') hubClusters.clearNodes()
|
||||
if (active !== 'supplier') supplierClusters.clearNodes()
|
||||
}
|
||||
|
||||
const fetchActiveClusters = async () => {
|
||||
if (!currentBounds.value) return
|
||||
clearInactiveClusters(activeClusterType.value)
|
||||
if (activeClusterType.value === 'hub') {
|
||||
await hubClusters.fetchClusters(currentBounds.value)
|
||||
return
|
||||
}
|
||||
if (activeClusterType.value === 'supplier') {
|
||||
await supplierClusters.fetchClusters(currentBounds.value)
|
||||
return
|
||||
}
|
||||
await offerClusters.fetchClusters(currentBounds.value)
|
||||
}
|
||||
|
||||
// Refetch clusters when view mode changes
|
||||
watch(mapViewMode, async () => {
|
||||
if (!props.useServerClustering) return
|
||||
if (isInfoMode.value) return
|
||||
if (useTypedClusters.value) {
|
||||
clearInactiveClusters(activeClusterType.value)
|
||||
if (currentBounds.value) {
|
||||
await fetchActiveClusters()
|
||||
}
|
||||
return
|
||||
}
|
||||
// Clear old data first
|
||||
clearNodes()
|
||||
// Refetch with current bounds if available
|
||||
if (currentBounds.value) {
|
||||
await fetchClusters(currentBounds.value)
|
||||
}
|
||||
})
|
||||
|
||||
watch([clusterProductUuid, clusterHubUuid, clusterSupplierUuid], async () => {
|
||||
if (!props.useServerClustering) return
|
||||
if (isInfoMode.value) return
|
||||
if (!currentBounds.value) return
|
||||
if (useTypedClusters.value) {
|
||||
await fetchActiveClusters()
|
||||
return
|
||||
}
|
||||
await fetchClusters(currentBounds.value)
|
||||
})
|
||||
|
||||
// Map refs
|
||||
const mapRef = ref<{ flyTo: (lat: number, lng: number, zoom?: number) => void } | null>(null)
|
||||
@@ -183,6 +421,9 @@ const selectedMapItem = ref<MapItem | null>(null)
|
||||
// Mobile panel state
|
||||
const mobilePanelExpanded = ref(false)
|
||||
|
||||
// Info mode - when relatedPoints are present, hide clusters and show only related points
|
||||
const isInfoMode = computed(() => props.forceInfoMode || (props.relatedPoints && props.relatedPoints.length > 0))
|
||||
|
||||
// Hovered item with coordinates for map highlight
|
||||
const hoveredItem = computed(() => {
|
||||
if (!props.hoveredId) return null
|
||||
@@ -208,23 +449,33 @@ const itemsWithCoords = computed(() =>
|
||||
)
|
||||
|
||||
const onBoundsChange = (bounds: MapBounds) => {
|
||||
currentBounds.value = bounds
|
||||
emit('bounds-change', bounds)
|
||||
if (props.useServerClustering) {
|
||||
fetchClusters(bounds)
|
||||
// Don't fetch clusters when in info mode
|
||||
if (props.useServerClustering && !isInfoMode.value) {
|
||||
if (useTypedClusters.value) {
|
||||
fetchActiveClusters()
|
||||
} else {
|
||||
fetchClusters(bounds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle selection from map
|
||||
const onMapSelect = (uuid: string) => {
|
||||
const onMapSelect = (uuid: string, properties?: Record<string, any>) => {
|
||||
const item = props.items.find(i => i.uuid === uuid)
|
||||
if (item) {
|
||||
selectedMapItem.value = item
|
||||
emit('select', item)
|
||||
} else if (props.useServerClustering) {
|
||||
// For server clustering, item might not be in props.items
|
||||
// Create minimal item with just uuid
|
||||
selectedMapItem.value = { uuid }
|
||||
emit('select', { uuid })
|
||||
// For server clustering, include properties from cluster data
|
||||
const mapItem: MapItem = {
|
||||
uuid,
|
||||
name: properties?.name,
|
||||
...properties
|
||||
}
|
||||
selectedMapItem.value = mapItem
|
||||
emit('select', mapItem)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,5 +488,31 @@ const flyTo = (lat: number, lng: number, zoom = 8) => {
|
||||
mapRef.value?.flyTo(lat, lng, zoom)
|
||||
}
|
||||
|
||||
defineExpose({ flyTo })
|
||||
defineExpose({ flyTo, currentBounds })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Drawer slide animation (desktop - left) */
|
||||
.slide-left-enter-active,
|
||||
.slide-left-leave-active {
|
||||
transition: transform 0.3s ease, opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.slide-left-enter-from,
|
||||
.slide-left-leave-to {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Drawer slide animation (mobile - up) */
|
||||
.slide-up-enter-active,
|
||||
.slide-up-leave-active {
|
||||
transition: transform 0.3s ease, opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.slide-up-enter-from,
|
||||
.slide-up-leave-to {
|
||||
transform: translateY(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Alert.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Alert',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import Button from './Button.vue'
|
||||
|
||||
const meta: Meta<typeof Button> = {
|
||||
title: 'UI/Button',
|
||||
component: Button,
|
||||
render: (args) => ({
|
||||
components: { Button },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<Button v-bind="args">{{ args.label }}</Button>'
|
||||
}),
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: { type: 'select' },
|
||||
options: ['primary', 'outline']
|
||||
}
|
||||
},
|
||||
tags: ['autodocs']
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {
|
||||
label: 'Primary button',
|
||||
variant: 'primary'
|
||||
}
|
||||
}
|
||||
|
||||
export const Outline: Story = {
|
||||
args: {
|
||||
label: 'Outline button',
|
||||
variant: 'outline'
|
||||
}
|
||||
}
|
||||
|
||||
export const FullWidth: Story = {
|
||||
args: {
|
||||
label: 'Full width',
|
||||
variant: 'primary',
|
||||
fullWidth: true
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Card.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Card',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Container.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Container',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './FieldButton.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/FieldButton',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ const props = defineProps({
|
||||
default: '',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
type: String as () => 'button' | 'submit' | 'reset',
|
||||
default: 'button',
|
||||
},
|
||||
chevron: {
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Grid.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Grid',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './GridItem.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/GridItem',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Heading.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Heading',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './IconCircle.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/IconCircle',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Input.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Input',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Pill.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Pill',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Section.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Section',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Select.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Select',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Spinner.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Spinner',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Stack.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Stack',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Text.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Text',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import StoryComponent from './Textarea.vue'
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
title: 'Ui/Textarea',
|
||||
component: StoryComponent,
|
||||
render: (args) => ({
|
||||
components: { StoryComponent },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<StoryComponent v-bind="args" />'
|
||||
})
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {}
|
||||
}
|
||||
@@ -13,96 +13,61 @@ export type Scalars = {
|
||||
Boolean: { input: boolean; output: boolean; }
|
||||
Int: { input: number; output: number; }
|
||||
Float: { input: number; output: number; }
|
||||
Date: { input: any; output: any; }
|
||||
DateTime: { input: string; output: string; }
|
||||
Decimal: { input: any; output: any; }
|
||||
};
|
||||
|
||||
export type OfferType = {
|
||||
__typename?: 'OfferType';
|
||||
categoryName: Scalars['String']['output'];
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
export type Offer = {
|
||||
__typename?: 'Offer';
|
||||
categoryName?: Maybe<Scalars['String']['output']>;
|
||||
createdAt: Scalars['String']['output'];
|
||||
currency: Scalars['String']['output'];
|
||||
description: Scalars['String']['output'];
|
||||
id: Scalars['ID']['output'];
|
||||
locationCountry: Scalars['String']['output'];
|
||||
locationCountryCode: Scalars['String']['output'];
|
||||
description?: Maybe<Scalars['String']['output']>;
|
||||
locationCountry?: Maybe<Scalars['String']['output']>;
|
||||
locationCountryCode?: Maybe<Scalars['String']['output']>;
|
||||
locationLatitude?: Maybe<Scalars['Float']['output']>;
|
||||
locationLongitude?: Maybe<Scalars['Float']['output']>;
|
||||
locationName: Scalars['String']['output'];
|
||||
locationUuid: Scalars['String']['output'];
|
||||
pricePerUnit?: Maybe<Scalars['Decimal']['output']>;
|
||||
locationName?: Maybe<Scalars['String']['output']>;
|
||||
locationUuid?: Maybe<Scalars['String']['output']>;
|
||||
pricePerUnit: Scalars['Float']['output'];
|
||||
productName: Scalars['String']['output'];
|
||||
productUuid: Scalars['String']['output'];
|
||||
quantity: Scalars['Decimal']['output'];
|
||||
status: OffersOfferStatusChoices;
|
||||
quantity: Scalars['Float']['output'];
|
||||
status: Scalars['String']['output'];
|
||||
teamUuid: Scalars['String']['output'];
|
||||
terminusDocumentId: Scalars['String']['output'];
|
||||
terminusSchemaId: Scalars['String']['output'];
|
||||
unit: Scalars['String']['output'];
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
updatedAt: Scalars['String']['output'];
|
||||
uuid: Scalars['String']['output'];
|
||||
validUntil?: Maybe<Scalars['Date']['output']>;
|
||||
workflowError: Scalars['String']['output'];
|
||||
workflowStatus: OffersOfferWorkflowStatusChoices;
|
||||
validUntil?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
/** An enumeration. */
|
||||
export enum OffersOfferStatusChoices {
|
||||
/** Активно */
|
||||
Active = 'ACTIVE',
|
||||
/** Отменено */
|
||||
Cancelled = 'CANCELLED',
|
||||
/** Закрыто */
|
||||
Closed = 'CLOSED',
|
||||
/** Черновик */
|
||||
Draft = 'DRAFT'
|
||||
}
|
||||
|
||||
/** An enumeration. */
|
||||
export enum OffersOfferWorkflowStatusChoices {
|
||||
/** Активен */
|
||||
Active = 'ACTIVE',
|
||||
/** Ошибка */
|
||||
Error = 'ERROR',
|
||||
/** Ожидает обработки */
|
||||
Pending = 'PENDING'
|
||||
}
|
||||
|
||||
export type Product = {
|
||||
__typename?: 'Product';
|
||||
categoryId?: Maybe<Scalars['Int']['output']>;
|
||||
categoryId?: Maybe<Scalars['String']['output']>;
|
||||
categoryName?: Maybe<Scalars['String']['output']>;
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
terminusSchemaId?: Maybe<Scalars['String']['output']>;
|
||||
uuid?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
/** Public schema - no authentication required */
|
||||
export type PublicQuery = {
|
||||
__typename?: 'PublicQuery';
|
||||
/** Get products that have active offers */
|
||||
export type Query = {
|
||||
__typename?: 'Query';
|
||||
getAvailableProducts?: Maybe<Array<Maybe<Product>>>;
|
||||
getOffer?: Maybe<OfferType>;
|
||||
getOffers?: Maybe<Array<Maybe<OfferType>>>;
|
||||
getOffer?: Maybe<Offer>;
|
||||
getOffers?: Maybe<Array<Maybe<Offer>>>;
|
||||
getOffersCount?: Maybe<Scalars['Int']['output']>;
|
||||
getProducts?: Maybe<Array<Maybe<Product>>>;
|
||||
getSupplierProfile?: Maybe<SupplierProfileType>;
|
||||
/** Get supplier profile by team UUID */
|
||||
getSupplierProfileByTeam?: Maybe<SupplierProfileType>;
|
||||
getSupplierProfiles?: Maybe<Array<Maybe<SupplierProfileType>>>;
|
||||
getSupplierProfile?: Maybe<SupplierProfile>;
|
||||
getSupplierProfileByTeam?: Maybe<SupplierProfile>;
|
||||
getSupplierProfiles?: Maybe<Array<Maybe<SupplierProfile>>>;
|
||||
getSupplierProfilesCount?: Maybe<Scalars['Int']['output']>;
|
||||
};
|
||||
|
||||
|
||||
/** Public schema - no authentication required */
|
||||
export type PublicQueryGetOfferArgs = {
|
||||
export type QueryGetOfferArgs = {
|
||||
uuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Public schema - no authentication required */
|
||||
export type PublicQueryGetOffersArgs = {
|
||||
export type QueryGetOffersArgs = {
|
||||
categoryName?: InputMaybe<Scalars['String']['input']>;
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
locationUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -113,8 +78,7 @@ export type PublicQueryGetOffersArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** Public schema - no authentication required */
|
||||
export type PublicQueryGetOffersCountArgs = {
|
||||
export type QueryGetOffersCountArgs = {
|
||||
categoryName?: InputMaybe<Scalars['String']['input']>;
|
||||
locationUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
productUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -123,20 +87,17 @@ export type PublicQueryGetOffersCountArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** Public schema - no authentication required */
|
||||
export type PublicQueryGetSupplierProfileArgs = {
|
||||
export type QueryGetSupplierProfileArgs = {
|
||||
uuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Public schema - no authentication required */
|
||||
export type PublicQueryGetSupplierProfileByTeamArgs = {
|
||||
export type QueryGetSupplierProfileByTeamArgs = {
|
||||
teamUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Public schema - no authentication required */
|
||||
export type PublicQueryGetSupplierProfilesArgs = {
|
||||
export type QueryGetSupplierProfilesArgs = {
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
isVerified?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
@@ -144,51 +105,46 @@ export type PublicQueryGetSupplierProfilesArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** Public schema - no authentication required */
|
||||
export type PublicQueryGetSupplierProfilesCountArgs = {
|
||||
export type QueryGetSupplierProfilesCountArgs = {
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
isVerified?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
};
|
||||
|
||||
/** Профиль поставщика на бирже */
|
||||
export type SupplierProfileType = {
|
||||
__typename?: 'SupplierProfileType';
|
||||
country: Scalars['String']['output'];
|
||||
export type SupplierProfile = {
|
||||
__typename?: 'SupplierProfile';
|
||||
country?: Maybe<Scalars['String']['output']>;
|
||||
countryCode?: Maybe<Scalars['String']['output']>;
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
description: Scalars['String']['output'];
|
||||
id: Scalars['ID']['output'];
|
||||
description?: Maybe<Scalars['String']['output']>;
|
||||
isActive: Scalars['Boolean']['output'];
|
||||
isVerified: Scalars['Boolean']['output'];
|
||||
kycProfileUuid: Scalars['String']['output'];
|
||||
kycProfileUuid?: Maybe<Scalars['String']['output']>;
|
||||
latitude?: Maybe<Scalars['Float']['output']>;
|
||||
logoUrl: Scalars['String']['output'];
|
||||
logoUrl?: Maybe<Scalars['String']['output']>;
|
||||
longitude?: Maybe<Scalars['Float']['output']>;
|
||||
name: Scalars['String']['output'];
|
||||
offersCount?: Maybe<Scalars['Int']['output']>;
|
||||
teamUuid: Scalars['String']['output'];
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
uuid: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
export type GetAvailableProductsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetAvailableProductsQuery = { __typename?: 'PublicQuery', getAvailableProducts?: Array<{ __typename?: 'Product', uuid?: string | null, name?: string | null, categoryId?: number | null, categoryName?: string | null, terminusSchemaId?: string | null } | null> | null };
|
||||
export type GetAvailableProductsQueryResult = { __typename?: 'Query', getAvailableProducts?: Array<{ __typename?: 'Product', uuid?: string | null, name?: string | null, categoryId?: string | null, categoryName?: string | null, terminusSchemaId?: string | null } | null> | null };
|
||||
|
||||
export type GetLocationOffersQueryVariables = Exact<{
|
||||
locationUuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetLocationOffersQuery = { __typename?: 'PublicQuery', getOffers?: Array<{ __typename?: 'OfferType', uuid: string, teamUuid: string, status: OffersOfferStatusChoices, locationUuid: string, locationName: string, locationCountry: string, locationCountryCode: string, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName: string, quantity: any, unit: string, pricePerUnit?: any | null, currency: string, description: string, validUntil?: any | null, createdAt: string, updatedAt: string } | null> | null };
|
||||
export type GetLocationOffersQueryResult = { __typename?: 'Query', getOffers?: Array<{ __typename?: 'Offer', uuid: string, teamUuid: string, status: string, locationUuid?: string | null, locationName?: string | null, locationCountry?: string | null, locationCountryCode?: string | null, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName?: string | null, quantity: number, unit: string, pricePerUnit: number, currency: string, description?: string | null, validUntil?: string | null, createdAt: string, updatedAt: string } | null> | null };
|
||||
|
||||
export type GetOfferQueryVariables = Exact<{
|
||||
uuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetOfferQuery = { __typename?: 'PublicQuery', getOffer?: { __typename?: 'OfferType', uuid: string, teamUuid: string, status: OffersOfferStatusChoices, locationUuid: string, locationName: string, locationCountry: string, locationCountryCode: string, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName: string, quantity: any, unit: string, pricePerUnit?: any | null, currency: string, description: string, validUntil?: any | null, createdAt: string, updatedAt: string } | null };
|
||||
export type GetOfferQueryResult = { __typename?: 'Query', getOffer?: { __typename?: 'Offer', uuid: string, teamUuid: string, status: string, locationUuid?: string | null, locationName?: string | null, locationCountry?: string | null, locationCountryCode?: string | null, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName?: string | null, quantity: number, unit: string, pricePerUnit: number, currency: string, description?: string | null, validUntil?: string | null, createdAt: string, updatedAt: string } | null };
|
||||
|
||||
export type GetOffersQueryVariables = Exact<{
|
||||
productUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -200,47 +156,47 @@ export type GetOffersQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetOffersQuery = { __typename?: 'PublicQuery', getOffersCount?: number | null, getOffers?: Array<{ __typename?: 'OfferType', uuid: string, teamUuid: string, locationUuid: string, locationName: string, locationCountry: string, locationCountryCode: string, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName: string, quantity: any, unit: string, pricePerUnit?: any | null, currency: string, description: string, validUntil?: any | null, createdAt: string, updatedAt: string } | null> | null };
|
||||
export type GetOffersQueryResult = { __typename?: 'Query', getOffersCount?: number | null, getOffers?: Array<{ __typename?: 'Offer', uuid: string, teamUuid: string, locationUuid?: string | null, locationName?: string | null, locationCountry?: string | null, locationCountryCode?: string | null, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName?: string | null, quantity: number, unit: string, pricePerUnit: number, currency: string, description?: string | null, validUntil?: string | null, createdAt: string, updatedAt: string } | null> | null };
|
||||
|
||||
export type GetProductQueryVariables = Exact<{
|
||||
uuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetProductQuery = { __typename?: 'PublicQuery', getProducts?: Array<{ __typename?: 'Product', uuid?: string | null, name?: string | null, categoryId?: number | null, categoryName?: string | null, terminusSchemaId?: string | null } | null> | null };
|
||||
export type GetProductQueryResult = { __typename?: 'Query', getProducts?: Array<{ __typename?: 'Product', uuid?: string | null, name?: string | null, categoryId?: string | null, categoryName?: string | null, terminusSchemaId?: string | null } | null> | null };
|
||||
|
||||
export type GetProductOffersQueryVariables = Exact<{
|
||||
productUuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetProductOffersQuery = { __typename?: 'PublicQuery', getOffers?: Array<{ __typename?: 'OfferType', uuid: string, teamUuid: string, status: OffersOfferStatusChoices, locationUuid: string, locationName: string, locationCountry: string, locationCountryCode: string, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName: string, quantity: any, unit: string, pricePerUnit?: any | null, currency: string, description: string, validUntil?: any | null, createdAt: string, updatedAt: string } | null> | null };
|
||||
export type GetProductOffersQueryResult = { __typename?: 'Query', getOffers?: Array<{ __typename?: 'Offer', uuid: string, teamUuid: string, status: string, locationUuid?: string | null, locationName?: string | null, locationCountry?: string | null, locationCountryCode?: string | null, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName?: string | null, quantity: number, unit: string, pricePerUnit: number, currency: string, description?: string | null, validUntil?: string | null, createdAt: string, updatedAt: string } | null> | null };
|
||||
|
||||
export type GetProductsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetProductsQuery = { __typename?: 'PublicQuery', getProducts?: Array<{ __typename?: 'Product', uuid?: string | null, name?: string | null, categoryId?: number | null, categoryName?: string | null, terminusSchemaId?: string | null } | null> | null };
|
||||
export type GetProductsQueryResult = { __typename?: 'Query', getProducts?: Array<{ __typename?: 'Product', uuid?: string | null, name?: string | null, categoryId?: string | null, categoryName?: string | null, terminusSchemaId?: string | null } | null> | null };
|
||||
|
||||
export type GetSupplierOffersQueryVariables = Exact<{
|
||||
teamUuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetSupplierOffersQuery = { __typename?: 'PublicQuery', getOffers?: Array<{ __typename?: 'OfferType', uuid: string, teamUuid: string, status: OffersOfferStatusChoices, locationUuid: string, locationName: string, locationCountry: string, locationCountryCode: string, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName: string, quantity: any, unit: string, pricePerUnit?: any | null, currency: string, description: string, validUntil?: any | null, createdAt: string, updatedAt: string } | null> | null };
|
||||
export type GetSupplierOffersQueryResult = { __typename?: 'Query', getOffers?: Array<{ __typename?: 'Offer', uuid: string, teamUuid: string, status: string, locationUuid?: string | null, locationName?: string | null, locationCountry?: string | null, locationCountryCode?: string | null, locationLatitude?: number | null, locationLongitude?: number | null, productUuid: string, productName: string, categoryName?: string | null, quantity: number, unit: string, pricePerUnit: number, currency: string, description?: string | null, validUntil?: string | null, createdAt: string, updatedAt: string } | null> | null };
|
||||
|
||||
export type GetSupplierProfileQueryVariables = Exact<{
|
||||
uuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetSupplierProfileQuery = { __typename?: 'PublicQuery', getSupplierProfile?: { __typename?: 'SupplierProfileType', uuid: string, teamUuid: string, kycProfileUuid: string, name: string, description: string, country: string, logoUrl: string, isVerified: boolean, isActive: boolean, offersCount?: number | null } | null };
|
||||
export type GetSupplierProfileQueryResult = { __typename?: 'Query', getSupplierProfile?: { __typename?: 'SupplierProfile', uuid: string, teamUuid: string, kycProfileUuid?: string | null, name: string, description?: string | null, country?: string | null, logoUrl?: string | null, isVerified: boolean, isActive: boolean, offersCount?: number | null, latitude?: number | null, longitude?: number | null } | null };
|
||||
|
||||
export type GetSupplierProfileByTeamQueryVariables = Exact<{
|
||||
teamUuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetSupplierProfileByTeamQuery = { __typename?: 'PublicQuery', getSupplierProfileByTeam?: { __typename?: 'SupplierProfileType', uuid: string, teamUuid: string, kycProfileUuid: string, name: string, description: string, country: string, logoUrl: string, isVerified: boolean, isActive: boolean, offersCount?: number | null } | null };
|
||||
export type GetSupplierProfileByTeamQueryResult = { __typename?: 'Query', getSupplierProfileByTeam?: { __typename?: 'SupplierProfile', uuid: string, teamUuid: string, kycProfileUuid?: string | null, name: string, description?: string | null, country?: string | null, logoUrl?: string | null, isVerified: boolean, isActive: boolean, offersCount?: number | null } | null };
|
||||
|
||||
export type GetSupplierProfilesQueryVariables = Exact<{
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -249,17 +205,17 @@ export type GetSupplierProfilesQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetSupplierProfilesQuery = { __typename?: 'PublicQuery', getSupplierProfilesCount?: number | null, getSupplierProfiles?: Array<{ __typename?: 'SupplierProfileType', uuid: string, teamUuid: string, name: string, description: string, country: string, countryCode?: string | null, logoUrl: string, offersCount?: number | null, latitude?: number | null, longitude?: number | null } | null> | null };
|
||||
export type GetSupplierProfilesQueryResult = { __typename?: 'Query', getSupplierProfilesCount?: number | null, getSupplierProfiles?: Array<{ __typename?: 'SupplierProfile', uuid: string, teamUuid: string, name: string, description?: string | null, country?: string | null, countryCode?: string | null, logoUrl?: string | null, offersCount?: number | null, latitude?: number | null, longitude?: number | null } | null> | null };
|
||||
|
||||
|
||||
export const GetAvailableProductsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAvailableProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAvailableProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"categoryId"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"terminusSchemaId"}}]}}]}}]} as unknown as DocumentNode<GetAvailableProductsQuery, GetAvailableProductsQueryVariables>;
|
||||
export const GetLocationOffersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetLocationOffers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"locationUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"status"},"value":{"kind":"StringValue","value":"ACTIVE","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetLocationOffersQuery, GetLocationOffersQueryVariables>;
|
||||
export const GetOfferDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOffer"},"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":"getOffer"},"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":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetOfferQuery, GetOfferQueryVariables>;
|
||||
export const GetOffersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOffers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"categoryName"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}},"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"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"locationUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"categoryName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"categoryName"}}},{"kind":"Argument","name":{"kind":"Name","value":"teamUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"getOffersCount"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"locationUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"categoryName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"categoryName"}}},{"kind":"Argument","name":{"kind":"Name","value":"teamUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}}}]}]}}]} as unknown as DocumentNode<GetOffersQuery, GetOffersQueryVariables>;
|
||||
export const GetProductDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProduct"},"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":"getProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"categoryId"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"terminusSchemaId"}}]}}]}}]} as unknown as DocumentNode<GetProductQuery, GetProductQueryVariables>;
|
||||
export const GetProductOffersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProductOffers"},"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":"getOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"status"},"value":{"kind":"StringValue","value":"ACTIVE","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetProductOffersQuery, GetProductOffersQueryVariables>;
|
||||
export const GetProductsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"categoryId"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"terminusSchemaId"}}]}}]}}]} as unknown as DocumentNode<GetProductsQuery, GetProductsQueryVariables>;
|
||||
export const GetSupplierOffersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSupplierOffers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"status"},"value":{"kind":"StringValue","value":"ACTIVE","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetSupplierOffersQuery, GetSupplierOffersQueryVariables>;
|
||||
export const GetSupplierProfileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSupplierProfile"},"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":"getSupplierProfile"},"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":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"kycProfileUuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"logoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"isVerified"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"offersCount"}}]}}]}}]} as unknown as DocumentNode<GetSupplierProfileQuery, GetSupplierProfileQueryVariables>;
|
||||
export const GetSupplierProfileByTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSupplierProfileByTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getSupplierProfileByTeam"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"kycProfileUuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"logoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"isVerified"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"offersCount"}}]}}]}}]} as unknown as DocumentNode<GetSupplierProfileByTeamQuery, GetSupplierProfileByTeamQueryVariables>;
|
||||
export const GetSupplierProfilesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSupplierProfiles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"country"}},"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"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getSupplierProfiles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"country"},"value":{"kind":"Variable","name":{"kind":"Name","value":"country"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"logoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"offersCount"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}}]}},{"kind":"Field","name":{"kind":"Name","value":"getSupplierProfilesCount"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"country"},"value":{"kind":"Variable","name":{"kind":"Name","value":"country"}}}]}]}}]} as unknown as DocumentNode<GetSupplierProfilesQuery, GetSupplierProfilesQueryVariables>;
|
||||
export const GetAvailableProductsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAvailableProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAvailableProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"categoryId"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"terminusSchemaId"}}]}}]}}]} as unknown as DocumentNode<GetAvailableProductsQueryResult, GetAvailableProductsQueryVariables>;
|
||||
export const GetLocationOffersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetLocationOffers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"locationUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"status"},"value":{"kind":"StringValue","value":"ACTIVE","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetLocationOffersQueryResult, GetLocationOffersQueryVariables>;
|
||||
export const GetOfferDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOffer"},"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":"getOffer"},"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":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetOfferQueryResult, GetOfferQueryVariables>;
|
||||
export const GetOffersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOffers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"categoryName"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}},"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"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"locationUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"categoryName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"categoryName"}}},{"kind":"Argument","name":{"kind":"Name","value":"teamUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"getOffersCount"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"locationUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"locationUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"categoryName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"categoryName"}}},{"kind":"Argument","name":{"kind":"Name","value":"teamUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}}}]}]}}]} as unknown as DocumentNode<GetOffersQueryResult, GetOffersQueryVariables>;
|
||||
export const GetProductDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProduct"},"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":"getProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"categoryId"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"terminusSchemaId"}}]}}]}}]} as unknown as DocumentNode<GetProductQueryResult, GetProductQueryVariables>;
|
||||
export const GetProductOffersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProductOffers"},"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":"getOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"status"},"value":{"kind":"StringValue","value":"ACTIVE","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetProductOffersQueryResult, GetProductOffersQueryVariables>;
|
||||
export const GetProductsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"categoryId"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"terminusSchemaId"}}]}}]}}]} as unknown as DocumentNode<GetProductsQueryResult, GetProductsQueryVariables>;
|
||||
export const GetSupplierOffersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSupplierOffers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"status"},"value":{"kind":"StringValue","value":"ACTIVE","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"locationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountry"}},{"kind":"Field","name":{"kind":"Name","value":"locationCountryCode"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"categoryName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetSupplierOffersQueryResult, GetSupplierOffersQueryVariables>;
|
||||
export const GetSupplierProfileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSupplierProfile"},"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":"getSupplierProfile"},"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":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"kycProfileUuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"logoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"isVerified"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"offersCount"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}}]}}]}}]} as unknown as DocumentNode<GetSupplierProfileQueryResult, GetSupplierProfileQueryVariables>;
|
||||
export const GetSupplierProfileByTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSupplierProfileByTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getSupplierProfileByTeam"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"kycProfileUuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"logoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"isVerified"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"offersCount"}}]}}]}}]} as unknown as DocumentNode<GetSupplierProfileByTeamQueryResult, GetSupplierProfileByTeamQueryVariables>;
|
||||
export const GetSupplierProfilesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSupplierProfiles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"country"}},"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"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getSupplierProfiles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"country"},"value":{"kind":"Variable","name":{"kind":"Name","value":"country"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"teamUuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"logoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"offersCount"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}}]}},{"kind":"Field","name":{"kind":"Name","value":"getSupplierProfilesCount"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"country"},"value":{"kind":"Variable","name":{"kind":"Name","value":"country"}}}]}]}}]} as unknown as DocumentNode<GetSupplierProfilesQueryResult, GetSupplierProfilesQueryVariables>;
|
||||
@@ -13,27 +13,21 @@ export type Scalars = {
|
||||
Boolean: { input: boolean; output: boolean; }
|
||||
Int: { input: number; output: number; }
|
||||
Float: { input: number; output: number; }
|
||||
JSONString: { input: any; output: any; }
|
||||
JSON: { input: Record<string, unknown>; output: Record<string, unknown>; }
|
||||
};
|
||||
|
||||
/** Cluster or individual point for map display. */
|
||||
export type ClusterPointType = {
|
||||
__typename?: 'ClusterPointType';
|
||||
/** 1 for single point, >1 for cluster */
|
||||
export type ClusterPoint = {
|
||||
__typename?: 'ClusterPoint';
|
||||
count?: Maybe<Scalars['Int']['output']>;
|
||||
/** Zoom level to expand cluster */
|
||||
expansionZoom?: Maybe<Scalars['Int']['output']>;
|
||||
/** UUID for points, 'cluster-N' for clusters */
|
||||
id?: Maybe<Scalars['String']['output']>;
|
||||
latitude?: Maybe<Scalars['Float']['output']>;
|
||||
longitude?: Maybe<Scalars['Float']['output']>;
|
||||
/** Node name (only for single points) */
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
/** Edge between two nodes (route). */
|
||||
export type EdgeType = {
|
||||
__typename?: 'EdgeType';
|
||||
export type Edge = {
|
||||
__typename?: 'Edge';
|
||||
distanceKm?: Maybe<Scalars['Float']['output']>;
|
||||
toLatitude?: Maybe<Scalars['Float']['output']>;
|
||||
toLongitude?: Maybe<Scalars['Float']['output']>;
|
||||
@@ -43,21 +37,12 @@ export type EdgeType = {
|
||||
travelTimeSeconds?: Maybe<Scalars['Int']['output']>;
|
||||
};
|
||||
|
||||
/** Auto + rail edges for a node, rail uses nearest rail node. */
|
||||
export type NodeConnectionsType = {
|
||||
__typename?: 'NodeConnectionsType';
|
||||
autoEdges?: Maybe<Array<Maybe<EdgeType>>>;
|
||||
hub?: Maybe<NodeType>;
|
||||
railEdges?: Maybe<Array<Maybe<EdgeType>>>;
|
||||
railNode?: Maybe<NodeType>;
|
||||
};
|
||||
|
||||
/** Logistics node with edges to neighbors. */
|
||||
export type NodeType = {
|
||||
__typename?: 'NodeType';
|
||||
export type Node = {
|
||||
__typename?: 'Node';
|
||||
country?: Maybe<Scalars['String']['output']>;
|
||||
countryCode?: Maybe<Scalars['String']['output']>;
|
||||
edges?: Maybe<Array<Maybe<EdgeType>>>;
|
||||
distanceKm?: Maybe<Scalars['Float']['output']>;
|
||||
edges?: Maybe<Array<Maybe<Edge>>>;
|
||||
latitude?: Maybe<Scalars['Float']['output']>;
|
||||
longitude?: Maybe<Scalars['Float']['output']>;
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
@@ -66,86 +51,100 @@ export type NodeType = {
|
||||
uuid?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
/** Offer node with location and product info. */
|
||||
export type OfferNodeType = {
|
||||
__typename?: 'OfferNodeType';
|
||||
export type NodeConnections = {
|
||||
__typename?: 'NodeConnections';
|
||||
autoEdges?: Maybe<Array<Maybe<Edge>>>;
|
||||
hub?: Maybe<Node>;
|
||||
railEdges?: Maybe<Array<Maybe<Edge>>>;
|
||||
railNode?: Maybe<Node>;
|
||||
};
|
||||
|
||||
export type OfferNode = {
|
||||
__typename?: 'OfferNode';
|
||||
country?: Maybe<Scalars['String']['output']>;
|
||||
countryCode?: Maybe<Scalars['String']['output']>;
|
||||
currency?: Maybe<Scalars['String']['output']>;
|
||||
distanceKm?: Maybe<Scalars['Float']['output']>;
|
||||
latitude?: Maybe<Scalars['Float']['output']>;
|
||||
longitude?: Maybe<Scalars['Float']['output']>;
|
||||
pricePerUnit?: Maybe<Scalars['String']['output']>;
|
||||
productName?: Maybe<Scalars['String']['output']>;
|
||||
productUuid?: Maybe<Scalars['String']['output']>;
|
||||
quantity?: Maybe<Scalars['String']['output']>;
|
||||
supplierName?: Maybe<Scalars['String']['output']>;
|
||||
supplierUuid?: Maybe<Scalars['String']['output']>;
|
||||
unit?: Maybe<Scalars['String']['output']>;
|
||||
uuid?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
/** Route options for a product source to the destination. */
|
||||
export type ProductRouteOptionType = {
|
||||
__typename?: 'ProductRouteOptionType';
|
||||
export type OfferWithRoute = {
|
||||
__typename?: 'OfferWithRoute';
|
||||
country?: Maybe<Scalars['String']['output']>;
|
||||
countryCode?: Maybe<Scalars['String']['output']>;
|
||||
currency?: Maybe<Scalars['String']['output']>;
|
||||
distanceKm?: Maybe<Scalars['Float']['output']>;
|
||||
routes?: Maybe<Array<Maybe<RoutePathType>>>;
|
||||
latitude?: Maybe<Scalars['Float']['output']>;
|
||||
longitude?: Maybe<Scalars['Float']['output']>;
|
||||
pricePerUnit?: Maybe<Scalars['String']['output']>;
|
||||
productName?: Maybe<Scalars['String']['output']>;
|
||||
productUuid?: Maybe<Scalars['String']['output']>;
|
||||
quantity?: Maybe<Scalars['String']['output']>;
|
||||
routes?: Maybe<Array<Maybe<RoutePath>>>;
|
||||
supplierName?: Maybe<Scalars['String']['output']>;
|
||||
supplierUuid?: Maybe<Scalars['String']['output']>;
|
||||
unit?: Maybe<Scalars['String']['output']>;
|
||||
uuid?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type Product = {
|
||||
__typename?: 'Product';
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
offersCount?: Maybe<Scalars['Int']['output']>;
|
||||
uuid?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type ProductRouteOption = {
|
||||
__typename?: 'ProductRouteOption';
|
||||
distanceKm?: Maybe<Scalars['Float']['output']>;
|
||||
routes?: Maybe<Array<Maybe<RoutePath>>>;
|
||||
sourceLat?: Maybe<Scalars['Float']['output']>;
|
||||
sourceLon?: Maybe<Scalars['Float']['output']>;
|
||||
sourceName?: Maybe<Scalars['String']['output']>;
|
||||
sourceUuid?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
/** Unique product from offers. */
|
||||
export type ProductType = {
|
||||
__typename?: 'ProductType';
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
/** Number of offers for this product */
|
||||
offersCount?: Maybe<Scalars['Int']['output']>;
|
||||
uuid?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
/** Root query. */
|
||||
export type Query = {
|
||||
__typename?: 'Query';
|
||||
/** Get auto route between two points via GraphHopper */
|
||||
autoRoute?: Maybe<RouteType>;
|
||||
/** Get clustered nodes for map display (server-side clustering) */
|
||||
clusteredNodes?: Maybe<Array<Maybe<ClusterPointType>>>;
|
||||
/** List of countries that have logistics hubs */
|
||||
hubCountries?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
|
||||
/** Get nearest hubs to an offer location */
|
||||
hubsNearOffer?: Maybe<Array<Maybe<NodeType>>>;
|
||||
/** Find nearest logistics nodes to given coordinates */
|
||||
nearestNodes?: Maybe<Array<Maybe<NodeType>>>;
|
||||
/** Get node by UUID with all edges to neighbors */
|
||||
node?: Maybe<NodeType>;
|
||||
/** Get auto + rail edges for a node (rail uses nearest rail node) */
|
||||
nodeConnections?: Maybe<NodeConnectionsType>;
|
||||
/** Get all nodes (without edges for performance) */
|
||||
nodes?: Maybe<Array<Maybe<NodeType>>>;
|
||||
/** Get total count of nodes (with optional transport/country filter) */
|
||||
nodesCount?: Maybe<Scalars['Int']['output']>;
|
||||
/** Get route from a specific offer to hub */
|
||||
offerToHub?: Maybe<ProductRouteOptionType>;
|
||||
/** Get offers for a product with routes to hub (auto → rail* → auto) */
|
||||
offersByHub?: Maybe<Array<Maybe<ProductRouteOptionType>>>;
|
||||
/** Get all offers for a product */
|
||||
offersByProduct?: Maybe<Array<Maybe<OfferNodeType>>>;
|
||||
/** Get offers from a supplier for a specific product */
|
||||
offersBySupplierProduct?: Maybe<Array<Maybe<OfferNodeType>>>;
|
||||
/** Get unique products from all offers */
|
||||
products?: Maybe<Array<Maybe<ProductType>>>;
|
||||
/** Get products offered by a supplier */
|
||||
productsBySupplier?: Maybe<Array<Maybe<ProductType>>>;
|
||||
/** Get products available near a hub */
|
||||
productsNearHub?: Maybe<Array<Maybe<ProductType>>>;
|
||||
/** Get rail route between two points via OpenRailRouting */
|
||||
railRoute?: Maybe<RouteType>;
|
||||
/** Get unique suppliers from all offers */
|
||||
suppliers?: Maybe<Array<Maybe<SupplierType>>>;
|
||||
autoRoute?: Maybe<Route>;
|
||||
clusteredNodes: Array<ClusterPoint>;
|
||||
hubCountries: Array<Scalars['String']['output']>;
|
||||
hubsForProduct: Array<Node>;
|
||||
hubsList: Array<Node>;
|
||||
hubsNearOffer: Array<Node>;
|
||||
nearestHubs: Array<Node>;
|
||||
nearestNodes: Array<Node>;
|
||||
nearestOffers: Array<OfferWithRoute>;
|
||||
nearestSuppliers: Array<Supplier>;
|
||||
node?: Maybe<Node>;
|
||||
nodeConnections?: Maybe<NodeConnections>;
|
||||
nodes: Array<Node>;
|
||||
nodesCount: Scalars['Int']['output'];
|
||||
offerToHub?: Maybe<ProductRouteOption>;
|
||||
offersByHub: Array<ProductRouteOption>;
|
||||
offersByProduct: Array<OfferNode>;
|
||||
offersBySupplierProduct: Array<OfferNode>;
|
||||
products: Array<Product>;
|
||||
productsBySupplier: Array<Product>;
|
||||
productsList: Array<Product>;
|
||||
productsNearHub: Array<Product>;
|
||||
railRoute?: Maybe<Route>;
|
||||
routeToCoordinate?: Maybe<ProductRouteOption>;
|
||||
suppliers: Array<Supplier>;
|
||||
suppliersForProduct: Array<Supplier>;
|
||||
suppliersList: Array<Supplier>;
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryAutoRouteArgs = {
|
||||
fromLat: Scalars['Float']['input'];
|
||||
fromLon: Scalars['Float']['input'];
|
||||
@@ -154,7 +153,6 @@ export type QueryAutoRouteArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryClusteredNodesArgs = {
|
||||
east: Scalars['Float']['input'];
|
||||
nodeType?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -166,14 +164,39 @@ export type QueryClusteredNodesArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryHubsForProductArgs = {
|
||||
productUuid: Scalars['String']['input'];
|
||||
radiusKm?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryHubsListArgs = {
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
east?: InputMaybe<Scalars['Float']['input']>;
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
north?: InputMaybe<Scalars['Float']['input']>;
|
||||
offset?: InputMaybe<Scalars['Int']['input']>;
|
||||
south?: InputMaybe<Scalars['Float']['input']>;
|
||||
transportType?: InputMaybe<Scalars['String']['input']>;
|
||||
west?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryHubsNearOfferArgs = {
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
offerUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryNearestHubsArgs = {
|
||||
lat: Scalars['Float']['input'];
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
lon: Scalars['Float']['input'];
|
||||
productUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
radius?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryNearestNodesArgs = {
|
||||
lat: Scalars['Float']['input'];
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
@@ -181,13 +204,30 @@ export type QueryNearestNodesArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryNearestOffersArgs = {
|
||||
hubUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
lat: Scalars['Float']['input'];
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
lon: Scalars['Float']['input'];
|
||||
productUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
radius?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryNearestSuppliersArgs = {
|
||||
lat: Scalars['Float']['input'];
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
lon: Scalars['Float']['input'];
|
||||
productUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
radius?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryNodeArgs = {
|
||||
uuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryNodeConnectionsArgs = {
|
||||
limitAuto?: InputMaybe<Scalars['Int']['input']>;
|
||||
limitRail?: InputMaybe<Scalars['Int']['input']>;
|
||||
@@ -195,31 +235,35 @@ export type QueryNodeConnectionsArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryNodesArgs = {
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
east?: InputMaybe<Scalars['Float']['input']>;
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
north?: InputMaybe<Scalars['Float']['input']>;
|
||||
offset?: InputMaybe<Scalars['Int']['input']>;
|
||||
search?: InputMaybe<Scalars['String']['input']>;
|
||||
south?: InputMaybe<Scalars['Float']['input']>;
|
||||
transportType?: InputMaybe<Scalars['String']['input']>;
|
||||
west?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryNodesCountArgs = {
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
east?: InputMaybe<Scalars['Float']['input']>;
|
||||
north?: InputMaybe<Scalars['Float']['input']>;
|
||||
south?: InputMaybe<Scalars['Float']['input']>;
|
||||
transportType?: InputMaybe<Scalars['String']['input']>;
|
||||
west?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryOfferToHubArgs = {
|
||||
hubUuid: Scalars['String']['input'];
|
||||
offerUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryOffersByHubArgs = {
|
||||
hubUuid: Scalars['String']['input'];
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
@@ -227,33 +271,38 @@ export type QueryOffersByHubArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryOffersByProductArgs = {
|
||||
productUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryOffersBySupplierProductArgs = {
|
||||
productUuid: Scalars['String']['input'];
|
||||
supplierUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryProductsBySupplierArgs = {
|
||||
supplierUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryProductsListArgs = {
|
||||
east?: InputMaybe<Scalars['Float']['input']>;
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
north?: InputMaybe<Scalars['Float']['input']>;
|
||||
offset?: InputMaybe<Scalars['Int']['input']>;
|
||||
south?: InputMaybe<Scalars['Float']['input']>;
|
||||
west?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryProductsNearHubArgs = {
|
||||
hubUuid: Scalars['String']['input'];
|
||||
radiusKm?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
|
||||
/** Root query. */
|
||||
export type QueryRailRouteArgs = {
|
||||
fromLat: Scalars['Float']['input'];
|
||||
fromLon: Scalars['Float']['input'];
|
||||
@@ -261,17 +310,44 @@ export type QueryRailRouteArgs = {
|
||||
toLon: Scalars['Float']['input'];
|
||||
};
|
||||
|
||||
/** Complete route through graph with multiple stages. */
|
||||
export type RoutePathType = {
|
||||
__typename?: 'RoutePathType';
|
||||
stages?: Maybe<Array<Maybe<RouteStageType>>>;
|
||||
|
||||
export type QueryRouteToCoordinateArgs = {
|
||||
lat: Scalars['Float']['input'];
|
||||
lon: Scalars['Float']['input'];
|
||||
offerUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QuerySuppliersForProductArgs = {
|
||||
productUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QuerySuppliersListArgs = {
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
east?: InputMaybe<Scalars['Float']['input']>;
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
north?: InputMaybe<Scalars['Float']['input']>;
|
||||
offset?: InputMaybe<Scalars['Int']['input']>;
|
||||
south?: InputMaybe<Scalars['Float']['input']>;
|
||||
west?: InputMaybe<Scalars['Float']['input']>;
|
||||
};
|
||||
|
||||
export type Route = {
|
||||
__typename?: 'Route';
|
||||
distanceKm?: Maybe<Scalars['Float']['output']>;
|
||||
geometry?: Maybe<Scalars['JSON']['output']>;
|
||||
};
|
||||
|
||||
export type RoutePath = {
|
||||
__typename?: 'RoutePath';
|
||||
stages?: Maybe<Array<Maybe<RouteStage>>>;
|
||||
totalDistanceKm?: Maybe<Scalars['Float']['output']>;
|
||||
totalTimeSeconds?: Maybe<Scalars['Int']['output']>;
|
||||
};
|
||||
|
||||
/** Single stage in a multi-hop route. */
|
||||
export type RouteStageType = {
|
||||
__typename?: 'RouteStageType';
|
||||
export type RouteStage = {
|
||||
__typename?: 'RouteStage';
|
||||
distanceKm?: Maybe<Scalars['Float']['output']>;
|
||||
fromLat?: Maybe<Scalars['Float']['output']>;
|
||||
fromLon?: Maybe<Scalars['Float']['output']>;
|
||||
@@ -285,17 +361,12 @@ export type RouteStageType = {
|
||||
travelTimeSeconds?: Maybe<Scalars['Int']['output']>;
|
||||
};
|
||||
|
||||
/** Route between two points with geometry. */
|
||||
export type RouteType = {
|
||||
__typename?: 'RouteType';
|
||||
export type Supplier = {
|
||||
__typename?: 'Supplier';
|
||||
distanceKm?: Maybe<Scalars['Float']['output']>;
|
||||
/** GeoJSON LineString coordinates */
|
||||
geometry?: Maybe<Scalars['JSONString']['output']>;
|
||||
};
|
||||
|
||||
/** Unique supplier from offers. */
|
||||
export type SupplierType = {
|
||||
__typename?: 'SupplierType';
|
||||
latitude?: Maybe<Scalars['Float']['output']>;
|
||||
longitude?: Maybe<Scalars['Float']['output']>;
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
uuid?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
@@ -307,7 +378,7 @@ export type GetAutoRouteQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetAutoRouteQuery = { __typename?: 'Query', autoRoute?: { __typename?: 'RouteType', distanceKm?: number | null, geometry?: any | null } | null };
|
||||
export type GetAutoRouteQueryResult = { __typename?: 'Query', autoRoute?: { __typename?: 'Route', distanceKm?: number | null, geometry?: Record<string, unknown> | null } | null };
|
||||
|
||||
export type GetClusteredNodesQueryVariables = Exact<{
|
||||
west: Scalars['Float']['input'];
|
||||
@@ -320,98 +391,19 @@ export type GetClusteredNodesQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetClusteredNodesQuery = { __typename?: 'Query', clusteredNodes?: Array<{ __typename?: 'ClusterPointType', id?: string | null, latitude?: number | null, longitude?: number | null, count?: number | null, expansionZoom?: number | null, name?: string | null } | null> | null };
|
||||
export type GetClusteredNodesQueryResult = { __typename?: 'Query', clusteredNodes: Array<{ __typename?: 'ClusterPoint', id?: string | null, latitude?: number | null, longitude?: number | null, count?: number | null, expansionZoom?: number | null, name?: string | null }> };
|
||||
|
||||
export type GetHubCountriesQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetHubCountriesQuery = { __typename?: 'Query', hubCountries?: Array<string | null> | null };
|
||||
|
||||
export type GetHubsNearOfferQueryVariables = Exact<{
|
||||
offerUuid: Scalars['String']['input'];
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetHubsNearOfferQuery = { __typename?: 'Query', hubsNearOffer?: Array<{ __typename?: 'NodeType', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, transportTypes?: Array<string | null> | null } | null> | null };
|
||||
export type GetHubCountriesQueryResult = { __typename?: 'Query', hubCountries: Array<string> };
|
||||
|
||||
export type GetNodeQueryVariables = Exact<{
|
||||
uuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetNodeQuery = { __typename?: 'Query', node?: { __typename?: 'NodeType', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, syncedAt?: string | null, edges?: Array<{ __typename?: 'EdgeType', toUuid?: string | null, toName?: string | null, toLatitude?: number | null, toLongitude?: number | null, distanceKm?: number | null, travelTimeSeconds?: number | null, transportType?: string | null } | null> | null } | null };
|
||||
|
||||
export type GetNodeConnectionsQueryVariables = Exact<{
|
||||
uuid: Scalars['String']['input'];
|
||||
limitAuto?: InputMaybe<Scalars['Int']['input']>;
|
||||
limitRail?: InputMaybe<Scalars['Int']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetNodeConnectionsQuery = { __typename?: 'Query', nodeConnections?: { __typename?: 'NodeConnectionsType', hub?: { __typename?: 'NodeType', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, syncedAt?: string | null } | null, railNode?: { __typename?: 'NodeType', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, syncedAt?: string | null } | null, autoEdges?: Array<{ __typename?: 'EdgeType', toUuid?: string | null, toName?: string | null, toLatitude?: number | null, toLongitude?: number | null, distanceKm?: number | null, travelTimeSeconds?: number | null, transportType?: string | null } | null> | null, railEdges?: Array<{ __typename?: 'EdgeType', toUuid?: string | null, toName?: string | null, toLatitude?: number | null, toLongitude?: number | null, distanceKm?: number | null, travelTimeSeconds?: number | null, transportType?: string | null } | null> | null } | null };
|
||||
|
||||
export type GetNodesQueryVariables = Exact<{
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
offset?: InputMaybe<Scalars['Int']['input']>;
|
||||
transportType?: InputMaybe<Scalars['String']['input']>;
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetNodesQuery = { __typename?: 'Query', nodesCount?: number | null, nodes?: Array<{ __typename?: 'NodeType', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, syncedAt?: string | null, transportTypes?: Array<string | null> | null } | null> | null };
|
||||
|
||||
export type GetOfferToHubQueryVariables = Exact<{
|
||||
offerUuid: Scalars['String']['input'];
|
||||
hubUuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetOfferToHubQuery = { __typename?: 'Query', offerToHub?: { __typename?: 'ProductRouteOptionType', sourceUuid?: string | null, sourceName?: string | null, sourceLat?: number | null, sourceLon?: number | null, distanceKm?: number | null, routes?: Array<{ __typename?: 'RoutePathType', totalDistanceKm?: number | null, totalTimeSeconds?: number | null, stages?: Array<{ __typename?: 'RouteStageType', fromUuid?: string | null, fromName?: string | null, fromLat?: number | null, fromLon?: number | null, toUuid?: string | null, toName?: string | null, toLat?: number | null, toLon?: number | null, distanceKm?: number | null, travelTimeSeconds?: number | null, transportType?: string | null } | null> | null } | null> | null } | null };
|
||||
|
||||
export type GetOffersByHubQueryVariables = Exact<{
|
||||
hubUuid: Scalars['String']['input'];
|
||||
productUuid: Scalars['String']['input'];
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetOffersByHubQuery = { __typename?: 'Query', offersByHub?: Array<{ __typename?: 'ProductRouteOptionType', sourceUuid?: string | null, sourceName?: string | null, sourceLat?: number | null, sourceLon?: number | null, distanceKm?: number | null, routes?: Array<{ __typename?: 'RoutePathType', totalDistanceKm?: number | null, totalTimeSeconds?: number | null, stages?: Array<{ __typename?: 'RouteStageType', fromUuid?: string | null, fromName?: string | null, fromLat?: number | null, fromLon?: number | null, toUuid?: string | null, toName?: string | null, toLat?: number | null, toLon?: number | null, distanceKm?: number | null, travelTimeSeconds?: number | null, transportType?: string | null } | null> | null } | null> | null } | null> | null };
|
||||
|
||||
export type GetOffersByProductQueryVariables = Exact<{
|
||||
productUuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetOffersByProductQuery = { __typename?: 'Query', offersByProduct?: Array<{ __typename?: 'OfferNodeType', uuid?: string | null, productUuid?: string | null, productName?: string | null, supplierUuid?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, pricePerUnit?: string | null, currency?: string | null, quantity?: string | null, unit?: string | null } | null> | null };
|
||||
|
||||
export type GetOffersBySupplierProductQueryVariables = Exact<{
|
||||
supplierUuid: Scalars['String']['input'];
|
||||
productUuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetOffersBySupplierProductQuery = { __typename?: 'Query', offersBySupplierProduct?: Array<{ __typename?: 'OfferNodeType', uuid?: string | null, productUuid?: string | null, productName?: string | null, supplierUuid?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, pricePerUnit?: string | null, currency?: string | null, quantity?: string | null, unit?: string | null } | null> | null };
|
||||
|
||||
export type GetProductsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetProductsQuery = { __typename?: 'Query', products?: Array<{ __typename?: 'ProductType', uuid?: string | null, name?: string | null, offersCount?: number | null } | null> | null };
|
||||
|
||||
export type GetProductsBySupplierQueryVariables = Exact<{
|
||||
supplierUuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetProductsBySupplierQuery = { __typename?: 'Query', productsBySupplier?: Array<{ __typename?: 'ProductType', uuid?: string | null, name?: string | null, offersCount?: number | null } | null> | null };
|
||||
|
||||
export type GetProductsNearHubQueryVariables = Exact<{
|
||||
hubUuid: Scalars['String']['input'];
|
||||
radiusKm?: InputMaybe<Scalars['Float']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetProductsNearHubQuery = { __typename?: 'Query', productsNearHub?: Array<{ __typename?: 'ProductType', uuid?: string | null, name?: string | null, offersCount?: number | null } | null> | null };
|
||||
export type GetNodeQueryResult = { __typename?: 'Query', node?: { __typename?: 'Node', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, transportTypes?: Array<string | null> | null } | null };
|
||||
|
||||
export type GetRailRouteQueryVariables = Exact<{
|
||||
fromLat: Scalars['Float']['input'];
|
||||
@@ -421,27 +413,90 @@ export type GetRailRouteQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetRailRouteQuery = { __typename?: 'Query', railRoute?: { __typename?: 'RouteType', distanceKm?: number | null, geometry?: any | null } | null };
|
||||
export type GetRailRouteQueryResult = { __typename?: 'Query', railRoute?: { __typename?: 'Route', distanceKm?: number | null, geometry?: Record<string, unknown> | null } | null };
|
||||
|
||||
export type GetSuppliersQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
export type HubsListQueryVariables = Exact<{
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
offset?: InputMaybe<Scalars['Int']['input']>;
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
transportType?: InputMaybe<Scalars['String']['input']>;
|
||||
west?: InputMaybe<Scalars['Float']['input']>;
|
||||
south?: InputMaybe<Scalars['Float']['input']>;
|
||||
east?: InputMaybe<Scalars['Float']['input']>;
|
||||
north?: InputMaybe<Scalars['Float']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetSuppliersQuery = { __typename?: 'Query', suppliers?: Array<{ __typename?: 'SupplierType', uuid?: string | null } | null> | null };
|
||||
export type HubsListQueryResult = { __typename?: 'Query', hubsList: Array<{ __typename?: 'Node', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, transportTypes?: Array<string | null> | null }> };
|
||||
|
||||
export type NearestHubsQueryVariables = Exact<{
|
||||
lat: Scalars['Float']['input'];
|
||||
lon: Scalars['Float']['input'];
|
||||
radius?: InputMaybe<Scalars['Float']['input']>;
|
||||
productUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
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<GetAutoRouteQuery, GetAutoRouteQueryVariables>;
|
||||
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<GetClusteredNodesQuery, GetClusteredNodesQueryVariables>;
|
||||
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<GetHubCountriesQuery, GetHubCountriesQueryVariables>;
|
||||
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<GetHubsNearOfferQuery, GetHubsNearOfferQueryVariables>;
|
||||
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<GetNodeQuery, GetNodeQueryVariables>;
|
||||
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<GetNodeConnectionsQuery, GetNodeConnectionsQueryVariables>;
|
||||
export const GetNodesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetNodes"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"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":"country"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"nodes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}},{"kind":"Argument","name":{"kind":"Name","value":"transportType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transportType"}}},{"kind":"Argument","name":{"kind":"Name","value":"country"},"value":{"kind":"Variable","name":{"kind":"Name","value":"country"}}}],"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":"transportTypes"}}]}},{"kind":"Field","name":{"kind":"Name","value":"nodesCount"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"transportType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transportType"}}},{"kind":"Argument","name":{"kind":"Name","value":"country"},"value":{"kind":"Variable","name":{"kind":"Name","value":"country"}}}]}]}}]} as unknown as DocumentNode<GetNodesQuery, GetNodesQueryVariables>;
|
||||
export const GetOfferToHubDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOfferToHub"},"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":"hubUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"offerToHub"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"offerUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offerUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"hubUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"hubUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sourceUuid"}},{"kind":"Field","name":{"kind":"Name","value":"sourceName"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLat"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLon"}},{"kind":"Field","name":{"kind":"Name","value":"distanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"routes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalDistanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"totalTimeSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"stages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fromUuid"}},{"kind":"Field","name":{"kind":"Name","value":"fromName"}},{"kind":"Field","name":{"kind":"Name","value":"fromLat"}},{"kind":"Field","name":{"kind":"Name","value":"fromLon"}},{"kind":"Field","name":{"kind":"Name","value":"toUuid"}},{"kind":"Field","name":{"kind":"Name","value":"toName"}},{"kind":"Field","name":{"kind":"Name","value":"toLat"}},{"kind":"Field","name":{"kind":"Name","value":"toLon"}},{"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<GetOfferToHubQuery, GetOfferToHubQueryVariables>;
|
||||
export const GetOffersByHubDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOffersByHub"},"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":"productUuid"}},"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":"offersByHub"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"hubUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"hubUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"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":"sourceUuid"}},{"kind":"Field","name":{"kind":"Name","value":"sourceName"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLat"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLon"}},{"kind":"Field","name":{"kind":"Name","value":"distanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"routes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalDistanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"totalTimeSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"stages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fromUuid"}},{"kind":"Field","name":{"kind":"Name","value":"fromName"}},{"kind":"Field","name":{"kind":"Name","value":"fromLat"}},{"kind":"Field","name":{"kind":"Name","value":"fromLon"}},{"kind":"Field","name":{"kind":"Name","value":"toUuid"}},{"kind":"Field","name":{"kind":"Name","value":"toName"}},{"kind":"Field","name":{"kind":"Name","value":"toLat"}},{"kind":"Field","name":{"kind":"Name","value":"toLon"}},{"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<GetOffersByHubQuery, GetOffersByHubQueryVariables>;
|
||||
export const GetOffersByProductDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOffersByProduct"},"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":"offersByProduct"},"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"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"supplierUuid"}},{"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":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}}]}}]}}]} as unknown as DocumentNode<GetOffersByProductQuery, GetOffersByProductQueryVariables>;
|
||||
export const GetOffersBySupplierProductDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOffersBySupplierProduct"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"supplierUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"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":"offersBySupplierProduct"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"supplierUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"supplierUuid"}}},{"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"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"supplierUuid"}},{"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":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}}]}}]}}]} as unknown as DocumentNode<GetOffersBySupplierProductQuery, GetOffersBySupplierProductQueryVariables>;
|
||||
export const GetProductsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProducts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"products"},"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<GetProductsQuery, GetProductsQueryVariables>;
|
||||
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<GetProductsBySupplierQuery, GetProductsBySupplierQueryVariables>;
|
||||
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<GetProductsNearHubQuery, GetProductsNearHubQueryVariables>;
|
||||
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<GetRailRouteQuery, GetRailRouteQueryVariables>;
|
||||
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<GetSuppliersQuery, GetSuppliersQueryVariables>;
|
||||
export type NearestHubsQueryResult = { __typename?: 'Query', nearestHubs: Array<{ __typename?: 'Node', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, transportTypes?: Array<string | null> | null }> };
|
||||
|
||||
export type NearestOffersQueryVariables = Exact<{
|
||||
lat: Scalars['Float']['input'];
|
||||
lon: Scalars['Float']['input'];
|
||||
radius?: InputMaybe<Scalars['Float']['input']>;
|
||||
productUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
hubUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type NearestOffersQueryResult = { __typename?: 'Query', nearestOffers: Array<{ __typename?: 'OfferWithRoute', uuid?: string | null, productUuid?: string | null, productName?: string | null, supplierUuid?: string | null, supplierName?: string | null, latitude?: number | null, longitude?: number | null, country?: string | null, countryCode?: string | null, pricePerUnit?: string | null, currency?: string | null, quantity?: string | null, unit?: string | null, distanceKm?: number | null, routes?: Array<{ __typename?: 'RoutePath', totalDistanceKm?: number | null, totalTimeSeconds?: number | null, stages?: Array<{ __typename?: 'RouteStage', fromUuid?: string | null, fromName?: string | null, fromLat?: number | null, fromLon?: number | null, toUuid?: string | null, toName?: string | null, toLat?: number | null, toLon?: number | null, distanceKm?: number | null, travelTimeSeconds?: number | null, transportType?: string | null } | null> | null } | null> | null }> };
|
||||
|
||||
export type NearestSuppliersQueryVariables = Exact<{
|
||||
lat: Scalars['Float']['input'];
|
||||
lon: Scalars['Float']['input'];
|
||||
radius?: InputMaybe<Scalars['Float']['input']>;
|
||||
productUuid?: InputMaybe<Scalars['String']['input']>;
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type NearestSuppliersQueryResult = { __typename?: 'Query', nearestSuppliers: Array<{ __typename?: 'Supplier', uuid?: string | null }> };
|
||||
|
||||
export type ProductsListQueryVariables = Exact<{
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
offset?: InputMaybe<Scalars['Int']['input']>;
|
||||
west?: InputMaybe<Scalars['Float']['input']>;
|
||||
south?: InputMaybe<Scalars['Float']['input']>;
|
||||
east?: InputMaybe<Scalars['Float']['input']>;
|
||||
north?: InputMaybe<Scalars['Float']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type ProductsListQueryResult = { __typename?: 'Query', productsList: Array<{ __typename?: 'Product', uuid?: string | null, name?: string | null, offersCount?: number | null }> };
|
||||
|
||||
export type SuppliersListQueryVariables = Exact<{
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
offset?: InputMaybe<Scalars['Int']['input']>;
|
||||
country?: InputMaybe<Scalars['String']['input']>;
|
||||
west?: InputMaybe<Scalars['Float']['input']>;
|
||||
south?: InputMaybe<Scalars['Float']['input']>;
|
||||
east?: InputMaybe<Scalars['Float']['input']>;
|
||||
north?: InputMaybe<Scalars['Float']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type SuppliersListQueryResult = { __typename?: 'Query', suppliersList: Array<{ __typename?: 'Supplier', uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | 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<GetAutoRouteQueryResult, GetAutoRouteQueryVariables>;
|
||||
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<GetClusteredNodesQueryResult, GetClusteredNodesQueryVariables>;
|
||||
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<GetHubCountriesQueryResult, GetHubCountriesQueryVariables>;
|
||||
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":"transportTypes"}}]}}]}}]} as unknown as DocumentNode<GetNodeQueryResult, GetNodeQueryVariables>;
|
||||
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<GetRailRouteQueryResult, GetRailRouteQueryVariables>;
|
||||
export const HubsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"HubsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"country"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"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":"west"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"south"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"east"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"north"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hubsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}},{"kind":"Argument","name":{"kind":"Name","value":"country"},"value":{"kind":"Variable","name":{"kind":"Name","value":"country"}}},{"kind":"Argument","name":{"kind":"Name","value":"transportType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transportType"}}},{"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"}}}],"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<HubsListQueryResult, HubsListQueryVariables>;
|
||||
export const NearestHubsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NearestHubs"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"lat"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"lon"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"radius"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}},"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":"nearestHubs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lat"},"value":{"kind":"Variable","name":{"kind":"Name","value":"lat"}}},{"kind":"Argument","name":{"kind":"Name","value":"lon"},"value":{"kind":"Variable","name":{"kind":"Name","value":"lon"}}},{"kind":"Argument","name":{"kind":"Name","value":"radius"},"value":{"kind":"Variable","name":{"kind":"Name","value":"radius"}}},{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"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<NearestHubsQueryResult, NearestHubsQueryVariables>;
|
||||
export const NearestOffersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NearestOffers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"lat"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"lon"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"radius"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"hubUuid"}},"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":"nearestOffers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lat"},"value":{"kind":"Variable","name":{"kind":"Name","value":"lat"}}},{"kind":"Argument","name":{"kind":"Name","value":"lon"},"value":{"kind":"Variable","name":{"kind":"Name","value":"lon"}}},{"kind":"Argument","name":{"kind":"Name","value":"radius"},"value":{"kind":"Variable","name":{"kind":"Name","value":"radius"}}},{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"kind":"Argument","name":{"kind":"Name","value":"hubUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"hubUuid"}}},{"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":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"supplierUuid"}},{"kind":"Field","name":{"kind":"Name","value":"supplierName"}},{"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":"pricePerUnit"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"distanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"routes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalDistanceKm"}},{"kind":"Field","name":{"kind":"Name","value":"totalTimeSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"stages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fromUuid"}},{"kind":"Field","name":{"kind":"Name","value":"fromName"}},{"kind":"Field","name":{"kind":"Name","value":"fromLat"}},{"kind":"Field","name":{"kind":"Name","value":"fromLon"}},{"kind":"Field","name":{"kind":"Name","value":"toUuid"}},{"kind":"Field","name":{"kind":"Name","value":"toName"}},{"kind":"Field","name":{"kind":"Name","value":"toLat"}},{"kind":"Field","name":{"kind":"Name","value":"toLon"}},{"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<NearestOffersQueryResult, NearestOffersQueryVariables>;
|
||||
export const NearestSuppliersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NearestSuppliers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"lat"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"lon"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"radius"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}},"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":"nearestSuppliers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lat"},"value":{"kind":"Variable","name":{"kind":"Name","value":"lat"}}},{"kind":"Argument","name":{"kind":"Name","value":"lon"},"value":{"kind":"Variable","name":{"kind":"Name","value":"lon"}}},{"kind":"Argument","name":{"kind":"Name","value":"radius"},"value":{"kind":"Variable","name":{"kind":"Name","value":"radius"}}},{"kind":"Argument","name":{"kind":"Name","value":"productUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"productUuid"}}},{"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"}}]}}]}}]} as unknown as DocumentNode<NearestSuppliersQueryResult, NearestSuppliersQueryVariables>;
|
||||
export const ProductsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProductsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"west"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"south"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"east"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"north"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"productsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}},{"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"}}}],"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<ProductsListQueryResult, ProductsListQueryVariables>;
|
||||
export const SuppliersListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SuppliersList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"offset"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"country"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"west"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"south"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"east"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"north"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"suppliersList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"offset"},"value":{"kind":"Variable","name":{"kind":"Name","value":"offset"}}},{"kind":"Argument","name":{"kind":"Name","value":"country"},"value":{"kind":"Variable","name":{"kind":"Name","value":"country"}}},{"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"}}}],"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"}}]}}]}}]} as unknown as DocumentNode<SuppliersListQueryResult, SuppliersListQueryVariables>;
|
||||
@@ -13,12 +13,10 @@ export type Scalars = {
|
||||
Boolean: { input: boolean; output: boolean; }
|
||||
Int: { input: number; output: number; }
|
||||
Float: { input: number; output: number; }
|
||||
DateTime: { input: string; output: string; }
|
||||
};
|
||||
|
||||
/** Full company data (requires auth). */
|
||||
export type CompanyFullType = {
|
||||
__typename?: 'CompanyFullType';
|
||||
export type CompanyFull = {
|
||||
__typename?: 'CompanyFull';
|
||||
activities?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
|
||||
address?: Maybe<Scalars['String']['output']>;
|
||||
capital?: Maybe<Scalars['String']['output']>;
|
||||
@@ -26,45 +24,35 @@ export type CompanyFullType = {
|
||||
director?: Maybe<Scalars['String']['output']>;
|
||||
inn?: Maybe<Scalars['String']['output']>;
|
||||
isActive?: Maybe<Scalars['Boolean']['output']>;
|
||||
lastUpdated?: Maybe<Scalars['DateTime']['output']>;
|
||||
lastUpdated?: Maybe<Scalars['String']['output']>;
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
ogrn?: Maybe<Scalars['String']['output']>;
|
||||
registrationYear?: Maybe<Scalars['Int']['output']>;
|
||||
sources?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
|
||||
};
|
||||
|
||||
/** Public company data (teaser). */
|
||||
export type CompanyTeaserType = {
|
||||
__typename?: 'CompanyTeaserType';
|
||||
/** Company type: ООО, АО, ИП, etc. */
|
||||
export type CompanyTeaser = {
|
||||
__typename?: 'CompanyTeaser';
|
||||
companyType?: Maybe<Scalars['String']['output']>;
|
||||
/** Is company active */
|
||||
isActive?: Maybe<Scalars['Boolean']['output']>;
|
||||
/** Year of registration */
|
||||
registrationYear?: Maybe<Scalars['Int']['output']>;
|
||||
/** Number of data sources */
|
||||
sourcesCount?: Maybe<Scalars['Int']['output']>;
|
||||
};
|
||||
|
||||
/** Public queries - no authentication required. */
|
||||
export type PublicQuery = {
|
||||
__typename?: 'PublicQuery';
|
||||
health?: Maybe<Scalars['String']['output']>;
|
||||
/** Get full KYC profile data by UUID (requires auth) */
|
||||
kycProfileFull?: Maybe<CompanyFullType>;
|
||||
/** Get public KYC profile teaser data by UUID */
|
||||
kycProfileTeaser?: Maybe<CompanyTeaserType>;
|
||||
export type Query = {
|
||||
__typename?: 'Query';
|
||||
health: Scalars['String']['output'];
|
||||
kycProfileFull?: Maybe<CompanyFull>;
|
||||
kycProfileTeaser?: Maybe<CompanyTeaser>;
|
||||
};
|
||||
|
||||
|
||||
/** Public queries - no authentication required. */
|
||||
export type PublicQueryKycProfileFullArgs = {
|
||||
export type QueryKycProfileFullArgs = {
|
||||
profileUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
/** Public queries - no authentication required. */
|
||||
export type PublicQueryKycProfileTeaserArgs = {
|
||||
export type QueryKycProfileTeaserArgs = {
|
||||
profileUuid: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
@@ -73,15 +61,15 @@ export type GetKycProfileFullQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetKycProfileFullQuery = { __typename?: 'PublicQuery', kycProfileFull?: { __typename?: 'CompanyFullType', inn?: string | null, ogrn?: string | null, name?: string | null, companyType?: string | null, registrationYear?: number | null, isActive?: boolean | null, address?: string | null, director?: string | null, capital?: string | null, activities?: Array<string | null> | null, sources?: Array<string | null> | null, lastUpdated?: string | null } | null };
|
||||
export type GetKycProfileFullQueryResult = { __typename?: 'Query', kycProfileFull?: { __typename?: 'CompanyFull', inn?: string | null, ogrn?: string | null, name?: string | null, companyType?: string | null, registrationYear?: number | null, isActive?: boolean | null, address?: string | null, director?: string | null, capital?: string | null, activities?: Array<string | null> | null, sources?: Array<string | null> | null, lastUpdated?: string | null } | null };
|
||||
|
||||
export type GetKycProfileTeaserQueryVariables = Exact<{
|
||||
profileUuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetKycProfileTeaserQuery = { __typename?: 'PublicQuery', kycProfileTeaser?: { __typename?: 'CompanyTeaserType', companyType?: string | null, registrationYear?: number | null, isActive?: boolean | null, sourcesCount?: number | null } | null };
|
||||
export type GetKycProfileTeaserQueryResult = { __typename?: 'Query', kycProfileTeaser?: { __typename?: 'CompanyTeaser', companyType?: string | null, registrationYear?: number | null, isActive?: boolean | null, sourcesCount?: number | null } | null };
|
||||
|
||||
|
||||
export const GetKycProfileFullDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetKycProfileFull"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"profileUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"kycProfileFull"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"profileUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"profileUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inn"}},{"kind":"Field","name":{"kind":"Name","value":"ogrn"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"companyType"}},{"kind":"Field","name":{"kind":"Name","value":"registrationYear"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"director"}},{"kind":"Field","name":{"kind":"Name","value":"capital"}},{"kind":"Field","name":{"kind":"Name","value":"activities"}},{"kind":"Field","name":{"kind":"Name","value":"sources"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdated"}}]}}]}}]} as unknown as DocumentNode<GetKycProfileFullQuery, GetKycProfileFullQueryVariables>;
|
||||
export const GetKycProfileTeaserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetKycProfileTeaser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"profileUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"kycProfileTeaser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"profileUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"profileUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"companyType"}},{"kind":"Field","name":{"kind":"Name","value":"registrationYear"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"sourcesCount"}}]}}]}}]} as unknown as DocumentNode<GetKycProfileTeaserQuery, GetKycProfileTeaserQueryVariables>;
|
||||
export const GetKycProfileFullDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetKycProfileFull"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"profileUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"kycProfileFull"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"profileUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"profileUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inn"}},{"kind":"Field","name":{"kind":"Name","value":"ogrn"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"companyType"}},{"kind":"Field","name":{"kind":"Name","value":"registrationYear"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"director"}},{"kind":"Field","name":{"kind":"Name","value":"capital"}},{"kind":"Field","name":{"kind":"Name","value":"activities"}},{"kind":"Field","name":{"kind":"Name","value":"sources"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdated"}}]}}]}}]} as unknown as DocumentNode<GetKycProfileFullQueryResult, GetKycProfileFullQueryVariables>;
|
||||
export const GetKycProfileTeaserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetKycProfileTeaser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"profileUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"kycProfileTeaser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"profileUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"profileUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"companyType"}},{"kind":"Field","name":{"kind":"Name","value":"registrationYear"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"sourcesCount"}}]}}]}}]} as unknown as DocumentNode<GetKycProfileTeaserQueryResult, GetKycProfileTeaserQueryVariables>;
|
||||
@@ -61,15 +61,15 @@ export type TeamTransaction = {
|
||||
export type GetTeamBalanceQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetTeamBalanceQuery = { __typename?: 'TeamQuery', teamBalance?: { __typename?: 'TeamBalance', balance: number, creditsPosted: number, debitsPosted: number, exists: boolean } | null };
|
||||
export type GetTeamBalanceQueryResult = { __typename?: 'TeamQuery', teamBalance?: { __typename?: 'TeamBalance', balance: number, creditsPosted: number, debitsPosted: number, exists: boolean } | null };
|
||||
|
||||
export type GetTeamTransactionsQueryVariables = Exact<{
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTeamTransactionsQuery = { __typename?: 'TeamQuery', teamTransactions?: Array<{ __typename?: 'TeamTransaction', id: string, amount: number, timestamp?: number | null, code?: number | null, codeName?: string | null, direction: string, counterpartyUuid?: string | null } | null> | null };
|
||||
export type GetTeamTransactionsQueryResult = { __typename?: 'TeamQuery', teamTransactions?: Array<{ __typename?: 'TeamTransaction', id: string, amount: number, timestamp?: number | null, code?: number | null, codeName?: string | null, direction: string, counterpartyUuid?: string | null } | null> | null };
|
||||
|
||||
|
||||
export const GetTeamBalanceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamBalance"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamBalance"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"balance"}},{"kind":"Field","name":{"kind":"Name","value":"creditsPosted"}},{"kind":"Field","name":{"kind":"Name","value":"debitsPosted"}},{"kind":"Field","name":{"kind":"Name","value":"exists"}}]}}]}}]} as unknown as DocumentNode<GetTeamBalanceQuery, GetTeamBalanceQueryVariables>;
|
||||
export const GetTeamTransactionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamTransactions"},"variableDefinitions":[{"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":"teamTransactions"},"arguments":[{"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":"id"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"codeName"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"counterpartyUuid"}}]}}]}}]} as unknown as DocumentNode<GetTeamTransactionsQuery, GetTeamTransactionsQueryVariables>;
|
||||
export const GetTeamBalanceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamBalance"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamBalance"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"balance"}},{"kind":"Field","name":{"kind":"Name","value":"creditsPosted"}},{"kind":"Field","name":{"kind":"Name","value":"debitsPosted"}},{"kind":"Field","name":{"kind":"Name","value":"exists"}}]}}]}}]} as unknown as DocumentNode<GetTeamBalanceQueryResult, GetTeamBalanceQueryVariables>;
|
||||
export const GetTeamTransactionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamTransactions"},"variableDefinitions":[{"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":"teamTransactions"},"arguments":[{"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":"id"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"codeName"}},{"kind":"Field","name":{"kind":"Name","value":"direction"}},{"kind":"Field","name":{"kind":"Name","value":"counterpartyUuid"}}]}}]}}]} as unknown as DocumentNode<GetTeamTransactionsQueryResult, GetTeamTransactionsQueryVariables>;
|
||||
@@ -13,10 +13,10 @@ export type Scalars = {
|
||||
Boolean: { input: boolean; output: boolean; }
|
||||
Int: { input: number; output: number; }
|
||||
Float: { input: number; output: number; }
|
||||
Date: { input: any; output: any; }
|
||||
Date: { input: string; output: string; }
|
||||
DateTime: { input: string; output: string; }
|
||||
Decimal: { input: any; output: any; }
|
||||
JSONString: { input: any; output: any; }
|
||||
Decimal: { input: string; output: string; }
|
||||
JSONString: { input: Record<string, unknown>; output: Record<string, unknown>; }
|
||||
};
|
||||
|
||||
export type CreateOffer = {
|
||||
@@ -198,23 +198,23 @@ export type CreateOfferMutationVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateOfferMutation = { __typename?: 'TeamMutation', createOffer?: { __typename?: 'CreateOffer', success?: boolean | null, message?: string | null, workflowId?: string | null, offerUuid?: string | null } | null };
|
||||
export type CreateOfferMutationResult = { __typename?: 'TeamMutation', createOffer?: { __typename?: 'CreateOffer', success?: boolean | null, message?: string | null, workflowId?: string | null, offerUuid?: string | null } | null };
|
||||
|
||||
export type CreateRequestMutationVariables = Exact<{
|
||||
input: RequestInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateRequestMutation = { __typename?: 'TeamMutation', createRequest?: { __typename?: 'CreateRequest', request?: { __typename?: 'RequestType', uuid: string, productUuid: string, quantity: any, sourceLocationUuid: string, userId: string } | null } | null };
|
||||
export type CreateRequestMutationResult = { __typename?: 'TeamMutation', createRequest?: { __typename?: 'CreateRequest', request?: { __typename?: 'RequestType', uuid: string, productUuid: string, quantity: string, sourceLocationUuid: string, userId: string } | null } | null };
|
||||
|
||||
export type GetRequestsQueryVariables = Exact<{
|
||||
userId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetRequestsQuery = { __typename?: 'TeamQuery', getRequests?: Array<{ __typename?: 'RequestType', uuid: string, productUuid: string, quantity: any, sourceLocationUuid: string, userId: string } | null> | null };
|
||||
export type GetRequestsQueryResult = { __typename?: 'TeamQuery', getRequests?: Array<{ __typename?: 'RequestType', uuid: string, productUuid: string, quantity: string, sourceLocationUuid: string, userId: string } | null> | null };
|
||||
|
||||
|
||||
export const CreateOfferDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOffer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OfferInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOffer"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"workflowId"}},{"kind":"Field","name":{"kind":"Name","value":"offerUuid"}}]}}]}}]} as unknown as DocumentNode<CreateOfferMutation, CreateOfferMutationVariables>;
|
||||
export const CreateRequestDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateRequest"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"RequestInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createRequest"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"request"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}}]}}]}}]}}]} as unknown as DocumentNode<CreateRequestMutation, CreateRequestMutationVariables>;
|
||||
export const GetRequestsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetRequests"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getRequests"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}}]}}]}}]} as unknown as DocumentNode<GetRequestsQuery, GetRequestsQueryVariables>;
|
||||
export const CreateOfferDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOffer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OfferInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOffer"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"workflowId"}},{"kind":"Field","name":{"kind":"Name","value":"offerUuid"}}]}}]}}]} as unknown as DocumentNode<CreateOfferMutationResult, CreateOfferMutationVariables>;
|
||||
export const CreateRequestDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateRequest"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"RequestInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createRequest"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"request"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}}]}}]}}]}}]} as unknown as DocumentNode<CreateRequestMutationResult, CreateRequestMutationVariables>;
|
||||
export const GetRequestsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetRequests"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getRequests"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"productUuid"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationUuid"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}}]}}]}}]} as unknown as DocumentNode<GetRequestsQueryResult, GetRequestsQueryVariables>;
|
||||
@@ -114,13 +114,13 @@ export type GetOrderQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetOrderQuery = { __typename?: 'TeamQuery', getOrder?: { __typename?: 'OrderType', uuid?: string | null, name?: string | null, status?: string | null, totalAmount?: number | null, currency?: string | null, sourceLocationName?: string | null, destinationLocationName?: string | null, createdAt?: string | null, notes?: string | null, orderLines?: Array<{ __typename?: 'OrderLineType', uuid?: string | null, productName?: string | null, quantity?: number | null, unit?: string | null, subtotal?: number | null } | null> | null, stages?: Array<{ __typename?: 'StageType', uuid?: string | null, name?: string | null, stageType?: string | null, transportType?: string | null, sourceLocationName?: string | null, sourceLatitude?: number | null, sourceLongitude?: number | null, destinationLocationName?: string | null, destinationLatitude?: number | null, destinationLongitude?: number | null, locationName?: string | null, locationLatitude?: number | null, locationLongitude?: number | null, selectedCompany?: { __typename?: 'CompanyType', uuid?: string | null, name?: string | null, taxId?: string | null, country?: string | null, countryCode?: string | null, active?: boolean | null } | null, trips?: Array<{ __typename?: 'TripType', uuid?: string | null, name?: string | null, plannedLoadingDate?: string | null, actualLoadingDate?: string | null, plannedUnloadingDate?: string | null, actualUnloadingDate?: string | null, realLoadingDate?: string | null, plannedWeight?: number | null, weightAtLoading?: number | null, weightAtUnloading?: number | null, company?: { __typename?: 'CompanyType', uuid?: string | null, name?: string | null, taxId?: string | null, country?: string | null, countryCode?: string | null, active?: boolean | null } | null } | null> | null } | null> | null } | null };
|
||||
export type GetOrderQueryResult = { __typename?: 'TeamQuery', getOrder?: { __typename?: 'OrderType', uuid?: string | null, name?: string | null, status?: string | null, totalAmount?: number | null, currency?: string | null, sourceLocationName?: string | null, destinationLocationName?: string | null, createdAt?: string | null, notes?: string | null, orderLines?: Array<{ __typename?: 'OrderLineType', uuid?: string | null, productName?: string | null, quantity?: number | null, unit?: string | null, subtotal?: number | null } | null> | null, stages?: Array<{ __typename?: 'StageType', uuid?: string | null, name?: string | null, stageType?: string | null, transportType?: string | null, sourceLocationName?: string | null, sourceLatitude?: number | null, sourceLongitude?: number | null, destinationLocationName?: string | null, destinationLatitude?: number | null, destinationLongitude?: number | null, locationName?: string | null, locationLatitude?: number | null, locationLongitude?: number | null, selectedCompany?: { __typename?: 'CompanyType', uuid?: string | null, name?: string | null, taxId?: string | null, country?: string | null, countryCode?: string | null, active?: boolean | null } | null, trips?: Array<{ __typename?: 'TripType', uuid?: string | null, name?: string | null, plannedLoadingDate?: string | null, actualLoadingDate?: string | null, plannedUnloadingDate?: string | null, actualUnloadingDate?: string | null, realLoadingDate?: string | null, plannedWeight?: number | null, weightAtLoading?: number | null, weightAtUnloading?: number | null, company?: { __typename?: 'CompanyType', uuid?: string | null, name?: string | null, taxId?: string | null, country?: string | null, countryCode?: string | null, active?: boolean | null } | null } | null> | null } | null> | null } | null };
|
||||
|
||||
export type GetTeamOrdersQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetTeamOrdersQuery = { __typename?: 'TeamQuery', getTeamOrders?: Array<{ __typename?: 'OrderType', uuid?: string | null, name?: string | null, status?: string | null, totalAmount?: number | null, currency?: string | null, sourceLocationName?: string | null, sourceLatitude?: number | null, sourceLongitude?: number | null, destinationLocationName?: string | null, createdAt?: string | null, orderLines?: Array<{ __typename?: 'OrderLineType', uuid?: string | null, productName?: string | null, quantity?: number | null, unit?: string | null } | null> | null, stages?: Array<{ __typename?: 'StageType', uuid?: string | null, name?: string | null, stageType?: string | null, transportType?: string | null, sourceLatitude?: number | null, sourceLongitude?: number | null, destinationLatitude?: number | null, destinationLongitude?: number | null, sourceLocationName?: string | null, destinationLocationName?: string | null, trips?: Array<{ __typename?: 'TripType', uuid?: string | null, name?: string | null, plannedLoadingDate?: string | null, actualLoadingDate?: string | null, plannedUnloadingDate?: string | null, actualUnloadingDate?: string | null, realLoadingDate?: string | null } | null> | null } | null> | null } | null> | null };
|
||||
export type GetTeamOrdersQueryResult = { __typename?: 'TeamQuery', getTeamOrders?: Array<{ __typename?: 'OrderType', uuid?: string | null, name?: string | null, status?: string | null, totalAmount?: number | null, currency?: string | null, sourceLocationName?: string | null, sourceLatitude?: number | null, sourceLongitude?: number | null, destinationLocationName?: string | null, createdAt?: string | null, orderLines?: Array<{ __typename?: 'OrderLineType', uuid?: string | null, productName?: string | null, quantity?: number | null, unit?: string | null } | null> | null, stages?: Array<{ __typename?: 'StageType', uuid?: string | null, name?: string | null, stageType?: string | null, transportType?: string | null, sourceLatitude?: number | null, sourceLongitude?: number | null, destinationLatitude?: number | null, destinationLongitude?: number | null, sourceLocationName?: string | null, destinationLocationName?: string | null, trips?: Array<{ __typename?: 'TripType', uuid?: string | null, name?: string | null, plannedLoadingDate?: string | null, actualLoadingDate?: string | null, plannedUnloadingDate?: string | null, actualUnloadingDate?: string | null, realLoadingDate?: string | null } | null> | null } | null> | null } | null> | null };
|
||||
|
||||
|
||||
export const GetOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"totalAmount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"notes"}},{"kind":"Field","name":{"kind":"Name","value":"orderLines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"}}]}},{"kind":"Field","name":{"kind":"Name","value":"stages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"stageType"}},{"kind":"Field","name":{"kind":"Name","value":"transportType"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"selectedCompany"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"taxId"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"active"}}]}},{"kind":"Field","name":{"kind":"Name","value":"trips"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"plannedLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"actualLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"plannedUnloadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"actualUnloadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"realLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"plannedWeight"}},{"kind":"Field","name":{"kind":"Name","value":"weightAtLoading"}},{"kind":"Field","name":{"kind":"Name","value":"weightAtUnloading"}},{"kind":"Field","name":{"kind":"Name","value":"company"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"taxId"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"active"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode<GetOrderQuery, GetOrderQueryVariables>;
|
||||
export const GetTeamOrdersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamOrders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getTeamOrders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"totalAmount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"orderLines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}}]}},{"kind":"Field","name":{"kind":"Name","value":"stages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"stageType"}},{"kind":"Field","name":{"kind":"Name","value":"transportType"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"trips"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"plannedLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"actualLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"plannedUnloadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"actualUnloadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"realLoadingDate"}}]}}]}}]}}]}}]} as unknown as DocumentNode<GetTeamOrdersQuery, GetTeamOrdersQueryVariables>;
|
||||
export const GetOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderUuid"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderUuid"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderUuid"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"totalAmount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"notes"}},{"kind":"Field","name":{"kind":"Name","value":"orderLines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"}}]}},{"kind":"Field","name":{"kind":"Name","value":"stages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"stageType"}},{"kind":"Field","name":{"kind":"Name","value":"transportType"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationName"}},{"kind":"Field","name":{"kind":"Name","value":"locationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"locationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"selectedCompany"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"taxId"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"active"}}]}},{"kind":"Field","name":{"kind":"Name","value":"trips"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"plannedLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"actualLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"plannedUnloadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"actualUnloadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"realLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"plannedWeight"}},{"kind":"Field","name":{"kind":"Name","value":"weightAtLoading"}},{"kind":"Field","name":{"kind":"Name","value":"weightAtUnloading"}},{"kind":"Field","name":{"kind":"Name","value":"company"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"taxId"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"active"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode<GetOrderQueryResult, GetOrderQueryVariables>;
|
||||
export const GetTeamOrdersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamOrders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getTeamOrders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"totalAmount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"orderLines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"productName"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unit"}}]}},{"kind":"Field","name":{"kind":"Name","value":"stages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"stageType"}},{"kind":"Field","name":{"kind":"Name","value":"transportType"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLatitude"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLongitude"}},{"kind":"Field","name":{"kind":"Name","value":"sourceLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"destinationLocationName"}},{"kind":"Field","name":{"kind":"Name","value":"trips"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"plannedLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"actualLoadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"plannedUnloadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"actualUnloadingDate"}},{"kind":"Field","name":{"kind":"Name","value":"realLoadingDate"}}]}}]}}]}}]}}]} as unknown as DocumentNode<GetTeamOrdersQueryResult, GetTeamOrdersQueryVariables>;
|
||||
@@ -203,57 +203,57 @@ export type CreateTeamAddressMutationVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateTeamAddressMutation = { __typename?: 'TeamMutation', createTeamAddress?: { __typename?: 'CreateTeamAddressMutation', success?: boolean | null, message?: string | null, workflowId?: string | null } | null };
|
||||
export type CreateTeamAddressMutationResult = { __typename?: 'TeamMutation', createTeamAddress?: { __typename?: 'CreateTeamAddressMutation', success?: boolean | null, message?: string | null, workflowId?: string | null } | null };
|
||||
|
||||
export type DeleteTeamAddressMutationVariables = Exact<{
|
||||
uuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type DeleteTeamAddressMutation = { __typename?: 'TeamMutation', deleteTeamAddress?: { __typename?: 'DeleteTeamAddressMutation', success?: boolean | null, message?: string | null } | null };
|
||||
export type DeleteTeamAddressMutationResult = { __typename?: 'TeamMutation', deleteTeamAddress?: { __typename?: 'DeleteTeamAddressMutation', success?: boolean | null, message?: string | null } | null };
|
||||
|
||||
export type GetTeamQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetTeamQuery = { __typename?: 'TeamQuery', team?: { __typename?: 'Team', uuid: string, name: string, selectedLocation?: { __typename?: 'SelectedLocation', type?: string | null, uuid?: string | null } | null } | null };
|
||||
export type GetTeamQueryResult = { __typename?: 'TeamQuery', team?: { __typename?: 'Team', uuid: string, name: string, selectedLocation?: { __typename?: 'SelectedLocation', type?: string | null, uuid?: string | null } | null } | null };
|
||||
|
||||
export type GetTeamAddressesQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetTeamAddressesQuery = { __typename?: 'TeamQuery', teamAddresses?: Array<{ __typename?: 'TeamAddress', uuid: string, name: string, address: string, latitude?: number | null, longitude?: number | null, countryCode?: string | null, isDefault?: boolean | null } | null> | null };
|
||||
export type GetTeamAddressesQueryResult = { __typename?: 'TeamQuery', teamAddresses?: Array<{ __typename?: 'TeamAddress', uuid: string, name: string, address: string, latitude?: number | null, longitude?: number | null, countryCode?: string | null, isDefault?: boolean | null } | null> | null };
|
||||
|
||||
export type GetTeamMembersQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetTeamMembersQuery = { __typename?: 'TeamQuery', teamMembers?: Array<{ __typename?: 'TeamMember', role: TeamsAppTeamMemberRoleChoices, joinedAt?: string | null, user?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, phone?: string | null, avatarId?: string | null } | null } | null> | null };
|
||||
export type GetTeamMembersQueryResult = { __typename?: 'TeamQuery', teamMembers?: Array<{ __typename?: 'TeamMember', role: TeamsAppTeamMemberRoleChoices, joinedAt?: string | null, user?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, phone?: string | null, avatarId?: string | null } | null } | null> | null };
|
||||
|
||||
export type InviteMemberMutationVariables = Exact<{
|
||||
input: InviteMemberInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type InviteMemberMutation = { __typename?: 'TeamMutation', inviteMember?: { __typename?: 'InviteMemberMutation', success?: boolean | null, message?: string | null } | null };
|
||||
export type InviteMemberMutationResult = { __typename?: 'TeamMutation', inviteMember?: { __typename?: 'InviteMemberMutation', success?: boolean | null, message?: string | null } | null };
|
||||
|
||||
export type SetSelectedLocationMutationVariables = Exact<{
|
||||
input: SetSelectedLocationInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type SetSelectedLocationMutation = { __typename?: 'TeamMutation', setSelectedLocation?: { __typename?: 'SetSelectedLocationMutation', success?: boolean | null, message?: string | null, selectedLocation?: { __typename?: 'SelectedLocation', type?: string | null, uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null } | null } | null };
|
||||
export type SetSelectedLocationMutationResult = { __typename?: 'TeamMutation', setSelectedLocation?: { __typename?: 'SetSelectedLocationMutation', success?: boolean | null, message?: string | null, selectedLocation?: { __typename?: 'SelectedLocation', type?: string | null, uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null } | null } | null };
|
||||
|
||||
export type UpdateTeamAddressMutationVariables = Exact<{
|
||||
input: UpdateTeamAddressInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateTeamAddressMutation = { __typename?: 'TeamMutation', updateTeamAddress?: { __typename?: 'UpdateTeamAddressMutation', success?: boolean | null, message?: string | null, address?: { __typename?: 'TeamAddress', uuid: string, name: string, address: string, latitude?: number | null, longitude?: number | null, countryCode?: string | null, isDefault?: boolean | null } | null } | null };
|
||||
export type UpdateTeamAddressMutationResult = { __typename?: 'TeamMutation', updateTeamAddress?: { __typename?: 'UpdateTeamAddressMutation', success?: boolean | null, message?: string | null, address?: { __typename?: 'TeamAddress', uuid: string, name: string, address: string, latitude?: number | null, longitude?: number | null, countryCode?: string | null, isDefault?: boolean | null } | null } | null };
|
||||
|
||||
|
||||
export const CreateTeamAddressDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateTeamAddress"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateTeamAddressInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createTeamAddress"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"workflowId"}}]}}]}}]} as unknown as DocumentNode<CreateTeamAddressMutation, CreateTeamAddressMutationVariables>;
|
||||
export const DeleteTeamAddressDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteTeamAddress"},"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":"deleteTeamAddress"},"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":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]} as unknown as DocumentNode<DeleteTeamAddressMutation, DeleteTeamAddressMutationVariables>;
|
||||
export const GetTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"selectedLocation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"uuid"}}]}}]}}]}}]} as unknown as DocumentNode<GetTeamQuery, GetTeamQueryVariables>;
|
||||
export const GetTeamAddressesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamAddresses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamAddresses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"isDefault"}}]}}]}}]} as unknown as DocumentNode<GetTeamAddressesQuery, GetTeamAddressesQueryVariables>;
|
||||
export const GetTeamMembersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamMembers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamMembers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"joinedAt"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"avatarId"}}]}}]}}]}}]} as unknown as DocumentNode<GetTeamMembersQuery, GetTeamMembersQueryVariables>;
|
||||
export const InviteMemberDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InviteMember"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"InviteMemberInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inviteMember"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]} as unknown as DocumentNode<InviteMemberMutation, InviteMemberMutationVariables>;
|
||||
export const SetSelectedLocationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SetSelectedLocation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SetSelectedLocationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"setSelectedLocation"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"selectedLocation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"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"}}]}}]}}]}}]} as unknown as DocumentNode<SetSelectedLocationMutation, SetSelectedLocationMutationVariables>;
|
||||
export const UpdateTeamAddressDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateTeamAddress"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateTeamAddressInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateTeamAddress"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"address"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"isDefault"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateTeamAddressMutation, UpdateTeamAddressMutationVariables>;
|
||||
export const CreateTeamAddressDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateTeamAddress"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateTeamAddressInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createTeamAddress"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"workflowId"}}]}}]}}]} as unknown as DocumentNode<CreateTeamAddressMutationResult, CreateTeamAddressMutationVariables>;
|
||||
export const DeleteTeamAddressDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteTeamAddress"},"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":"deleteTeamAddress"},"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":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]} as unknown as DocumentNode<DeleteTeamAddressMutationResult, DeleteTeamAddressMutationVariables>;
|
||||
export const GetTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"selectedLocation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"uuid"}}]}}]}}]}}]} as unknown as DocumentNode<GetTeamQueryResult, GetTeamQueryVariables>;
|
||||
export const GetTeamAddressesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamAddresses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamAddresses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"isDefault"}}]}}]}}]} as unknown as DocumentNode<GetTeamAddressesQueryResult, GetTeamAddressesQueryVariables>;
|
||||
export const GetTeamMembersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamMembers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamMembers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"joinedAt"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"avatarId"}}]}}]}}]}}]} as unknown as DocumentNode<GetTeamMembersQueryResult, GetTeamMembersQueryVariables>;
|
||||
export const InviteMemberDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InviteMember"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"InviteMemberInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inviteMember"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]} as unknown as DocumentNode<InviteMemberMutationResult, InviteMemberMutationVariables>;
|
||||
export const SetSelectedLocationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SetSelectedLocation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SetSelectedLocationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"setSelectedLocation"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"selectedLocation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"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"}}]}}]}}]}}]} as unknown as DocumentNode<SetSelectedLocationMutationResult, SetSelectedLocationMutationVariables>;
|
||||
export const UpdateTeamAddressDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateTeamAddress"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateTeamAddressInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateTeamAddress"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"address"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"latitude"}},{"kind":"Field","name":{"kind":"Name","value":"longitude"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"isDefault"}}]}}]}}]}}]} as unknown as DocumentNode<UpdateTeamAddressMutationResult, UpdateTeamAddressMutationVariables>;
|
||||
@@ -14,7 +14,7 @@ export type Scalars = {
|
||||
Int: { input: number; output: number; }
|
||||
Float: { input: number; output: number; }
|
||||
DateTime: { input: string; output: string; }
|
||||
JSONString: { input: any; output: any; }
|
||||
JSONString: { input: Record<string, unknown>; output: Record<string, unknown>; }
|
||||
};
|
||||
|
||||
/** Create KYC Application for Russian company. */
|
||||
@@ -110,21 +110,21 @@ export type CreateKycApplicationRussiaMutationVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateKycApplicationRussiaMutation = { __typename?: 'UserMutation', createKycApplicationRussia?: { __typename?: 'CreateKYCApplicationRussia', success?: boolean | null, kycApplication?: { __typename?: 'KYCApplicationType', uuid: string, contactEmail: string, createdAt: string, countryData?: any | null } | null } | null };
|
||||
export type CreateKycApplicationRussiaMutationResult = { __typename?: 'UserMutation', createKycApplicationRussia?: { __typename?: 'CreateKYCApplicationRussia', success?: boolean | null, kycApplication?: { __typename?: 'KYCApplicationType', uuid: string, contactEmail: string, createdAt: string, countryData?: Record<string, unknown> | null } | null } | null };
|
||||
|
||||
export type GetKycRequestRussiaQueryVariables = Exact<{
|
||||
uuid: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetKycRequestRussiaQuery = { __typename?: 'UserQuery', kycRequest?: { __typename?: 'KYCApplicationType', uuid: string, userId: string, teamName: string, countryCode: string, contactPerson: string, contactEmail: string, contactPhone: string, approvedBy?: string | null, approvedAt?: string | null, createdAt: string, updatedAt: string, countryData?: any | null } | null };
|
||||
export type GetKycRequestRussiaQueryResult = { __typename?: 'UserQuery', kycRequest?: { __typename?: 'KYCApplicationType', uuid: string, userId: string, teamName: string, countryCode: string, contactPerson: string, contactEmail: string, contactPhone: string, approvedBy?: string | null, approvedAt?: string | null, createdAt: string, updatedAt: string, countryData?: Record<string, unknown> | null } | null };
|
||||
|
||||
export type GetKycRequestsRussiaQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetKycRequestsRussiaQuery = { __typename?: 'UserQuery', kycRequests?: Array<{ __typename?: 'KYCApplicationType', uuid: string, userId: string, teamName: string, countryCode: string, contactPerson: string, contactEmail: string, contactPhone: string, approvedBy?: string | null, approvedAt?: string | null, createdAt: string, updatedAt: string, countryData?: any | null } | null> | null };
|
||||
export type GetKycRequestsRussiaQueryResult = { __typename?: 'UserQuery', kycRequests?: Array<{ __typename?: 'KYCApplicationType', uuid: string, userId: string, teamName: string, countryCode: string, contactPerson: string, contactEmail: string, contactPhone: string, approvedBy?: string | null, approvedAt?: string | null, createdAt: string, updatedAt: string, countryData?: Record<string, unknown> | null } | null> | null };
|
||||
|
||||
|
||||
export const CreateKycApplicationRussiaDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateKYCApplicationRussia"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"KYCApplicationRussiaInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createKycApplicationRussia"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"kycApplication"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"contactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"countryData"}}]}}]}}]}}]} as unknown as DocumentNode<CreateKycApplicationRussiaMutation, CreateKycApplicationRussiaMutationVariables>;
|
||||
export const GetKycRequestRussiaDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetKYCRequestRussia"},"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":"kycRequest"},"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":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"teamName"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"contactPerson"}},{"kind":"Field","name":{"kind":"Name","value":"contactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"contactPhone"}},{"kind":"Field","name":{"kind":"Name","value":"approvedBy"}},{"kind":"Field","name":{"kind":"Name","value":"approvedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"countryData"}}]}}]}}]} as unknown as DocumentNode<GetKycRequestRussiaQuery, GetKycRequestRussiaQueryVariables>;
|
||||
export const GetKycRequestsRussiaDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetKYCRequestsRussia"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"kycRequests"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"teamName"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"contactPerson"}},{"kind":"Field","name":{"kind":"Name","value":"contactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"contactPhone"}},{"kind":"Field","name":{"kind":"Name","value":"approvedBy"}},{"kind":"Field","name":{"kind":"Name","value":"approvedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"countryData"}}]}}]}}]} as unknown as DocumentNode<GetKycRequestsRussiaQuery, GetKycRequestsRussiaQueryVariables>;
|
||||
export const CreateKycApplicationRussiaDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateKYCApplicationRussia"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"KYCApplicationRussiaInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createKycApplicationRussia"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}},{"kind":"Field","name":{"kind":"Name","value":"kycApplication"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"contactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"countryData"}}]}}]}}]}}]} as unknown as DocumentNode<CreateKycApplicationRussiaMutationResult, CreateKycApplicationRussiaMutationVariables>;
|
||||
export const GetKycRequestRussiaDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetKYCRequestRussia"},"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":"kycRequest"},"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":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"teamName"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"contactPerson"}},{"kind":"Field","name":{"kind":"Name","value":"contactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"contactPhone"}},{"kind":"Field","name":{"kind":"Name","value":"approvedBy"}},{"kind":"Field","name":{"kind":"Name","value":"approvedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"countryData"}}]}}]}}]} as unknown as DocumentNode<GetKycRequestRussiaQueryResult, GetKycRequestRussiaQueryVariables>;
|
||||
export const GetKycRequestsRussiaDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetKYCRequestsRussia"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"kycRequests"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"teamName"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"contactPerson"}},{"kind":"Field","name":{"kind":"Name","value":"contactEmail"}},{"kind":"Field","name":{"kind":"Name","value":"contactPhone"}},{"kind":"Field","name":{"kind":"Name","value":"approvedBy"}},{"kind":"Field","name":{"kind":"Name","value":"approvedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"countryData"}}]}}]}}]} as unknown as DocumentNode<GetKycRequestsRussiaQueryResult, GetKycRequestsRussiaQueryVariables>;
|
||||
@@ -146,31 +146,31 @@ export type CreateTeamMutationVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateTeamMutation = { __typename?: 'UserMutation', createTeam?: { __typename?: 'CreateTeamMutation', team?: { __typename?: 'Team', id?: string | null, name: string, teamType?: string | null } | null } | null };
|
||||
export type CreateTeamMutationResult = { __typename?: 'UserMutation', createTeam?: { __typename?: 'CreateTeamMutation', team?: { __typename?: 'Team', id?: string | null, name: string, teamType?: string | null } | null } | null };
|
||||
|
||||
export type GetMeQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetMeQuery = { __typename?: 'UserQuery', me?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, activeTeamId?: string | null, activeTeam?: { __typename?: 'Team', id?: string | null, name: string, logtoOrgId?: string | null, teamType?: string | null, selectedLocation?: { __typename?: 'SelectedLocation', type?: string | null, uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null } | null } | null, teams?: Array<{ __typename?: 'Team', id?: string | null, name: string, logtoOrgId?: string | null, teamType?: string | null } | null> | null } | null };
|
||||
export type GetMeQueryResult = { __typename?: 'UserQuery', me?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, activeTeamId?: string | null, activeTeam?: { __typename?: 'Team', id?: string | null, name: string, logtoOrgId?: string | null, teamType?: string | null, selectedLocation?: { __typename?: 'SelectedLocation', type?: string | null, uuid?: string | null, name?: string | null, latitude?: number | null, longitude?: number | null } | null } | null, teams?: Array<{ __typename?: 'Team', id?: string | null, name: string, logtoOrgId?: string | null, teamType?: string | null } | null> | null } | null };
|
||||
|
||||
export type GetMeProfileQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetMeProfileQuery = { __typename?: 'UserQuery', me?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, phone?: string | null, avatarId?: string | null, activeTeamId?: string | null, activeTeam?: { __typename?: 'Team', id?: string | null, name: string } | null } | null };
|
||||
export type GetMeProfileQueryResult = { __typename?: 'UserQuery', me?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, phone?: string | null, avatarId?: string | null, activeTeamId?: string | null, activeTeam?: { __typename?: 'Team', id?: string | null, name: string } | null } | null };
|
||||
|
||||
export type GetTeamQueryVariables = Exact<{
|
||||
teamId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTeamQuery = { __typename?: 'UserQuery', getTeam?: { __typename?: 'TeamWithMembers', id?: string | null, name: string, members?: Array<{ __typename?: 'TeamMember', role?: string | null, joinedAt?: string | null, user?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null } | null } | null> | null, invitations?: Array<{ __typename?: 'TeamInvitation', uuid: string, email?: string | null, role?: string | null, status?: string | null, createdAt?: string | null } | null> | null } | null };
|
||||
export type GetTeamQueryResult = { __typename?: 'UserQuery', getTeam?: { __typename?: 'TeamWithMembers', id?: string | null, name: string, members?: Array<{ __typename?: 'TeamMember', role?: string | null, joinedAt?: string | null, user?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null } | null } | null> | null, invitations?: Array<{ __typename?: 'TeamInvitation', uuid: string, email?: string | null, role?: string | null, status?: string | null, createdAt?: string | null } | null> | null } | null };
|
||||
|
||||
export type SwitchTeamMutationVariables = Exact<{
|
||||
teamId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type SwitchTeamMutation = { __typename?: 'UserMutation', switchTeam?: { __typename?: 'SwitchTeamMutation', user?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, activeTeamId?: string | null, activeTeam?: { __typename?: 'Team', id?: string | null, name: string } | null } | null } | null };
|
||||
export type SwitchTeamMutationResult = { __typename?: 'UserMutation', switchTeam?: { __typename?: 'SwitchTeamMutation', user?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, activeTeamId?: string | null, activeTeam?: { __typename?: 'Team', id?: string | null, name: string } | null } | null } | null };
|
||||
|
||||
export type UpdateUserMutationVariables = Exact<{
|
||||
userId: Scalars['String']['input'];
|
||||
@@ -178,12 +178,12 @@ export type UpdateUserMutationVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateUserMutation = { __typename?: 'UserMutation', updateUser?: { __typename?: 'UpdateUserMutation', user?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, phone?: string | null, avatarId?: string | null, activeTeamId?: string | null, activeTeam?: { __typename?: 'Team', id?: string | null, name: string } | null } | null } | null };
|
||||
export type UpdateUserMutationResult = { __typename?: 'UserMutation', updateUser?: { __typename?: 'UpdateUserMutation', user?: { __typename?: 'User', id?: string | null, firstName?: string | null, lastName?: string | null, phone?: string | null, avatarId?: string | null, activeTeamId?: string | null, activeTeam?: { __typename?: 'Team', id?: string | null, name: string } | null } | null } | null };
|
||||
|
||||
|
||||
export const CreateTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateTeamInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createTeam"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"teamType"}}]}}]}}]}}]} as unknown as DocumentNode<CreateTeamMutation, CreateTeamMutationVariables>;
|
||||
export const GetMeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMe"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeamId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"logtoOrgId"}},{"kind":"Field","name":{"kind":"Name","value":"teamType"}},{"kind":"Field","name":{"kind":"Name","value":"selectedLocation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"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":"teams"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"logtoOrgId"}},{"kind":"Field","name":{"kind":"Name","value":"teamType"}}]}}]}}]}}]} as unknown as DocumentNode<GetMeQuery, GetMeQueryVariables>;
|
||||
export const GetMeProfileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMeProfile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"avatarId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeamId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<GetMeProfileQuery, GetMeProfileQueryVariables>;
|
||||
export const GetTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getTeam"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"members"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"joinedAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"invitations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]}}]} as unknown as DocumentNode<GetTeamQuery, GetTeamQueryVariables>;
|
||||
export const SwitchTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SwitchTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"switchTeam"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeamId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]} as unknown as DocumentNode<SwitchTeamMutation, SwitchTeamMutationVariables>;
|
||||
export const UpdateUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateUserInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateUser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"avatarId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeamId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UpdateUserMutation, UpdateUserMutationVariables>;
|
||||
export const CreateTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateTeamInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createTeam"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"teamType"}}]}}]}}]}}]} as unknown as DocumentNode<CreateTeamMutationResult, CreateTeamMutationVariables>;
|
||||
export const GetMeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMe"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeamId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"logtoOrgId"}},{"kind":"Field","name":{"kind":"Name","value":"teamType"}},{"kind":"Field","name":{"kind":"Name","value":"selectedLocation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"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":"teams"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"logtoOrgId"}},{"kind":"Field","name":{"kind":"Name","value":"teamType"}}]}}]}}]}}]} as unknown as DocumentNode<GetMeQueryResult, GetMeQueryVariables>;
|
||||
export const GetMeProfileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMeProfile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"avatarId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeamId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode<GetMeProfileQueryResult, GetMeProfileQueryVariables>;
|
||||
export const GetTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getTeam"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"members"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"joinedAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"invitations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uuid"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]}}]} as unknown as DocumentNode<GetTeamQueryResult, GetTeamQueryVariables>;
|
||||
export const SwitchTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SwitchTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"switchTeam"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeamId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]} as unknown as DocumentNode<SwitchTeamMutationResult, SwitchTeamMutationVariables>;
|
||||
export const UpdateUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateUserInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateUser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"avatarId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeamId"}},{"kind":"Field","name":{"kind":"Name","value":"activeTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]} as unknown as DocumentNode<UpdateUserMutationResult, UpdateUserMutationVariables>;
|
||||
@@ -1,9 +1,18 @@
|
||||
import { GetNodesDocument, GetHubCountriesDocument } from '~/composables/graphql/public/geo-generated'
|
||||
import type { HubsListQueryResult, NearestHubsQueryResult } from '~/composables/graphql/public/geo-generated'
|
||||
import { HubsListDocument, GetHubCountriesDocument, NearestHubsDocument } from '~/composables/graphql/public/geo-generated'
|
||||
|
||||
const PAGE_SIZE = 24
|
||||
const PAGE_SIZE = 500
|
||||
|
||||
// Type from codegen - exported for use in pages
|
||||
export type CatalogHubItem = NonNullable<NonNullable<HubsListQueryResult['hubsList']>[number]>
|
||||
export type CatalogNearestHubItem = NonNullable<NonNullable<NearestHubsQueryResult['nearestHubs']>[number]>
|
||||
|
||||
// Internal aliases
|
||||
type HubItem = CatalogHubItem
|
||||
type NearestHubItem = CatalogNearestHubItem
|
||||
|
||||
// Shared state across list and map views
|
||||
const items = ref<any[]>([])
|
||||
const items = ref<Array<HubItem | NearestHubItem>>([])
|
||||
const total = ref(0)
|
||||
const selectedFilter = ref('all')
|
||||
const selectedCountry = ref('all')
|
||||
@@ -11,6 +20,8 @@ const countries = ref<string[]>([])
|
||||
const isLoading = ref(false)
|
||||
const isLoadingMore = ref(false)
|
||||
const isInitialized = ref(false)
|
||||
const filterProductUuid = ref<string | null>(null)
|
||||
const filterBounds = ref<{ west: number; south: number; east: number; north: number } | null>(null)
|
||||
|
||||
export function useCatalogHubs() {
|
||||
const { t } = useI18n()
|
||||
@@ -34,7 +45,7 @@ export function useCatalogHubs() {
|
||||
)
|
||||
|
||||
const itemsByCountry = computed(() => {
|
||||
const grouped = new Map<string, any[]>()
|
||||
const grouped = new Map<string, Array<HubItem | NearestHubItem>>()
|
||||
items.value.forEach(hub => {
|
||||
const country = hub.country || t('catalogMap.labels.country_unknown')
|
||||
if (!grouped.has(country)) grouped.set(country, [])
|
||||
@@ -50,17 +61,56 @@ export function useCatalogHubs() {
|
||||
const fetchPage = async (offset: number, replace = false) => {
|
||||
if (replace) isLoading.value = true
|
||||
try {
|
||||
// If filtering by product, use nearestHubs (graph-based)
|
||||
if (filterProductUuid.value) {
|
||||
const data = await execute(
|
||||
NearestHubsDocument,
|
||||
{
|
||||
lat: 0,
|
||||
lon: 0,
|
||||
productUuid: filterProductUuid.value,
|
||||
useGraph: true,
|
||||
limit: 500 // Increased limit for global search
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
)
|
||||
const next = (data?.nearestHubs || []).filter((h): h is NearestHubItem => h !== null)
|
||||
items.value = next
|
||||
total.value = next.length
|
||||
isInitialized.value = true
|
||||
return
|
||||
}
|
||||
|
||||
// Default: fetch all hubs with filters using hubsList
|
||||
const transportType = selectedFilter.value === 'all' ? null : selectedFilter.value
|
||||
const country = selectedCountry.value === 'all' ? null : selectedCountry.value
|
||||
|
||||
const data = await execute(
|
||||
GetNodesDocument,
|
||||
{ limit: PAGE_SIZE, offset, transportType, country },
|
||||
HubsListDocument,
|
||||
{
|
||||
limit: PAGE_SIZE,
|
||||
offset,
|
||||
transportType,
|
||||
country,
|
||||
...(filterBounds.value && {
|
||||
west: filterBounds.value.west,
|
||||
south: filterBounds.value.south,
|
||||
east: filterBounds.value.east,
|
||||
north: filterBounds.value.north
|
||||
})
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
)
|
||||
const next = data?.nodes || []
|
||||
const next = (data?.hubsList || []).filter((h): h is HubItem => h !== null)
|
||||
items.value = replace ? next : items.value.concat(next)
|
||||
total.value = data?.nodesCount ?? total.value
|
||||
// hubsList doesn't return total count, estimate from fetched items
|
||||
if (replace) {
|
||||
total.value = next.length < PAGE_SIZE ? next.length : next.length + PAGE_SIZE
|
||||
} else if (next.length < PAGE_SIZE) {
|
||||
total.value = items.value.length
|
||||
}
|
||||
isInitialized.value = true
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
@@ -70,7 +120,7 @@ export function useCatalogHubs() {
|
||||
const loadCountries = async () => {
|
||||
try {
|
||||
const data = await execute(GetHubCountriesDocument, {}, 'public', 'geo')
|
||||
countries.value = data?.hubCountries || []
|
||||
countries.value = (data?.hubCountries || []).filter((c): c is string => c !== null)
|
||||
} catch (e) {
|
||||
console.error('Failed to load hub countries', e)
|
||||
}
|
||||
@@ -93,6 +143,30 @@ export function useCatalogHubs() {
|
||||
}
|
||||
})
|
||||
|
||||
const setProductFilter = (uuid: string | null) => {
|
||||
if (filterProductUuid.value === uuid) return // Early return if unchanged
|
||||
filterProductUuid.value = uuid
|
||||
fetchPage(0, true)
|
||||
}
|
||||
|
||||
const setBoundsFilter = (bounds: { west: number; south: number; east: number; north: number } | null) => {
|
||||
// Early return if bounds haven't changed
|
||||
const prev = filterBounds.value
|
||||
const same = prev === bounds || (
|
||||
prev && bounds &&
|
||||
prev.west === bounds.west &&
|
||||
prev.south === bounds.south &&
|
||||
prev.east === bounds.east &&
|
||||
prev.north === bounds.north
|
||||
)
|
||||
if (same) return
|
||||
|
||||
filterBounds.value = bounds
|
||||
if (isInitialized.value) {
|
||||
fetchPage(0, true)
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize data if not already loaded
|
||||
const init = async () => {
|
||||
if (!isInitialized.value && items.value.length === 0) {
|
||||
@@ -117,6 +191,8 @@ export function useCatalogHubs() {
|
||||
canLoadMore,
|
||||
fetchPage,
|
||||
loadMore,
|
||||
init
|
||||
init,
|
||||
setProductFilter,
|
||||
setBoundsFilter
|
||||
}
|
||||
}
|
||||
|
||||
556
app/composables/useCatalogInfo.ts
Normal file
556
app/composables/useCatalogInfo.ts
Normal file
@@ -0,0 +1,556 @@
|
||||
import type { InfoEntityType } from './useCatalogSearch'
|
||||
import type {
|
||||
GetNodeQueryResult,
|
||||
NearestHubsQueryResult,
|
||||
NearestOffersQueryResult
|
||||
} from '~/composables/graphql/public/geo-generated'
|
||||
import {
|
||||
GetNodeDocument,
|
||||
NearestOffersDocument,
|
||||
NearestHubsDocument
|
||||
} from '~/composables/graphql/public/geo-generated'
|
||||
import type {
|
||||
GetOfferQueryResult,
|
||||
GetSupplierProfileQueryResult
|
||||
} from '~/composables/graphql/public/exchange-generated'
|
||||
import {
|
||||
GetOfferDocument,
|
||||
GetSupplierProfileDocument,
|
||||
GetSupplierOffersDocument
|
||||
} from '~/composables/graphql/public/exchange-generated'
|
||||
|
||||
// Types from codegen
|
||||
type NodeEntity = NonNullable<GetNodeQueryResult['node']>
|
||||
type OfferEntity = NonNullable<GetOfferQueryResult['getOffer']>
|
||||
type SupplierProfile = NonNullable<GetSupplierProfileQueryResult['getSupplierProfile']>
|
||||
type HubItem = NonNullable<NonNullable<NearestHubsQueryResult['nearestHubs']>[number]>
|
||||
type OfferItem = NonNullable<NonNullable<NearestOffersQueryResult['nearestOffers']>[number]>
|
||||
|
||||
// Product type (aggregated from offers)
|
||||
export interface InfoProductItem {
|
||||
uuid: string
|
||||
name: string
|
||||
offersCount?: number
|
||||
}
|
||||
|
||||
// Re-export types for InfoPanel
|
||||
export type InfoHubItem = HubItem
|
||||
export type InfoSupplierItem = SupplierProfile
|
||||
export type InfoOfferItem = OfferItem
|
||||
|
||||
// Extended entity type with all known fields (NO index signature!)
|
||||
export interface InfoEntity {
|
||||
uuid?: string | null
|
||||
name?: string | null
|
||||
// Node coordinates
|
||||
latitude?: number | null
|
||||
longitude?: number | null
|
||||
// Location fields
|
||||
address?: string | null
|
||||
city?: string | null
|
||||
country?: string | null
|
||||
// Offer coordinates (different field names)
|
||||
locationLatitude?: number | null
|
||||
locationLongitude?: number | null
|
||||
locationUuid?: string | null
|
||||
locationName?: string | null
|
||||
// Offer fields
|
||||
productUuid?: string | null
|
||||
productName?: string | null
|
||||
teamUuid?: string | null
|
||||
teamName?: string | null
|
||||
pricePerUnit?: number | string | null
|
||||
currency?: string | null
|
||||
unit?: string | null
|
||||
// Enriched field from supplier profile
|
||||
supplierName?: string | null
|
||||
// KYC profile reference
|
||||
kycProfileUuid?: string | null
|
||||
}
|
||||
|
||||
// Helper to get coordinates from entity (handles both node and offer patterns)
|
||||
function getEntityCoords(e: InfoEntity | null): { lat: number; lon: number } | null {
|
||||
if (!e) return null
|
||||
// Try offer coords first (locationLatitude/locationLongitude)
|
||||
const lat = e.locationLatitude ?? e.latitude
|
||||
const lon = e.locationLongitude ?? e.longitude
|
||||
if (lat != null && lon != null) {
|
||||
return { lat, lon }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function useCatalogInfo() {
|
||||
const { execute } = useGraphQL()
|
||||
|
||||
// State with proper types
|
||||
const entity = ref<InfoEntity | null>(null)
|
||||
const entityType = ref<InfoEntityType | null>(null)
|
||||
const relatedProducts = ref<InfoProductItem[]>([])
|
||||
const relatedHubs = ref<HubItem[]>([])
|
||||
const relatedSuppliers = ref<SupplierProfile[]>([])
|
||||
const relatedOffers = ref<OfferItem[]>([])
|
||||
const selectedProduct = ref<string | null>(null)
|
||||
const activeTab = ref<string>('products')
|
||||
const isLoading = ref(false)
|
||||
|
||||
// Separate loading states for each tab
|
||||
const isLoadingProducts = ref(false)
|
||||
const isLoadingHubs = ref(false)
|
||||
const isLoadingSuppliers = ref(false)
|
||||
const isLoadingOffers = ref(false)
|
||||
|
||||
// Load hub info: hub details + products + suppliers (in parallel)
|
||||
const loadHubInfo = async (uuid: string) => {
|
||||
try {
|
||||
// Load hub node details
|
||||
const nodeData = await execute(GetNodeDocument, { uuid }, 'public', 'geo')
|
||||
entity.value = nodeData?.node ?? null
|
||||
|
||||
const coords = getEntityCoords(entity.value)
|
||||
if (!coords) {
|
||||
console.warn('Hub has no coordinates')
|
||||
return
|
||||
}
|
||||
|
||||
// Set default active tab to offers (first step shows products)
|
||||
activeTab.value = 'offers'
|
||||
|
||||
// Load products AND suppliers in parallel
|
||||
isLoadingProducts.value = true
|
||||
isLoadingSuppliers.value = true
|
||||
|
||||
// Load products (offers grouped by product) and extract suppliers
|
||||
execute(
|
||||
NearestOffersDocument,
|
||||
{
|
||||
lat: coords.lat,
|
||||
lon: coords.lon,
|
||||
hubUuid: uuid,
|
||||
limit: 500
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
).then(offersData => {
|
||||
// Group offers by product
|
||||
const productsMap = new Map<string, InfoProductItem>()
|
||||
const suppliersMap = new Map<string, { uuid: string; name: string; latitude?: number | null; longitude?: number | null }>()
|
||||
|
||||
offersData?.nearestOffers?.forEach(offer => {
|
||||
if (!offer) return
|
||||
// Products
|
||||
if (offer.productUuid && offer.productName) {
|
||||
const existing = productsMap.get(offer.productUuid)
|
||||
if (existing) {
|
||||
existing.offersCount = (existing.offersCount || 0) + 1
|
||||
} else {
|
||||
productsMap.set(offer.productUuid, {
|
||||
uuid: offer.productUuid,
|
||||
name: offer.productName,
|
||||
offersCount: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Suppliers (extract from offers)
|
||||
if (offer.supplierUuid && !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((p): p is SupplierProfile => p != null)
|
||||
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 + hubs (in parallel)
|
||||
const loadSupplierInfo = async (uuid: string) => {
|
||||
try {
|
||||
// Load supplier node details (might be geo node)
|
||||
const nodeData = await execute(GetNodeDocument, { uuid }, 'public', 'geo')
|
||||
entity.value = nodeData?.node ?? null
|
||||
|
||||
// Also try to get supplier profile from exchange API for additional details
|
||||
try {
|
||||
const profileData = await execute(
|
||||
GetSupplierProfileDocument,
|
||||
{ uuid },
|
||||
'public',
|
||||
'exchange'
|
||||
)
|
||||
if (profileData?.getSupplierProfile) {
|
||||
entity.value = { ...entity.value, ...profileData.getSupplierProfile }
|
||||
}
|
||||
} catch (e) {
|
||||
// Supplier profile might not exist, ignore
|
||||
}
|
||||
|
||||
if (!entity.value?.latitude || !entity.value?.longitude) {
|
||||
console.warn('Supplier has no coordinates')
|
||||
return
|
||||
}
|
||||
|
||||
// Set default active tab to offers (first step shows products)
|
||||
activeTab.value = 'offers'
|
||||
|
||||
// Load products AND hubs in parallel
|
||||
isLoadingProducts.value = true
|
||||
isLoadingHubs.value = true
|
||||
|
||||
// Load products from supplier offers (no geo radius)
|
||||
execute(
|
||||
GetSupplierOffersDocument,
|
||||
{ teamUuid: uuid },
|
||||
'public',
|
||||
'exchange'
|
||||
).then(offersData => {
|
||||
const productsMap = new Map<string, InfoProductItem>()
|
||||
offersData?.getOffers?.forEach(offer => {
|
||||
if (!offer?.productUuid || !offer.productName) return
|
||||
const existing = productsMap.get(offer.productUuid)
|
||||
if (existing) {
|
||||
existing.offersCount = (existing.offersCount || 0) + 1
|
||||
} else {
|
||||
productsMap.set(offer.productUuid, {
|
||||
uuid: offer.productUuid,
|
||||
name: offer.productName,
|
||||
offersCount: 1
|
||||
})
|
||||
}
|
||||
})
|
||||
relatedProducts.value = Array.from(productsMap.values())
|
||||
}).finally(() => {
|
||||
isLoadingProducts.value = false
|
||||
})
|
||||
|
||||
// Load hubs near supplier
|
||||
execute(
|
||||
NearestHubsDocument,
|
||||
{
|
||||
lat: entity.value.latitude,
|
||||
lon: entity.value.longitude,
|
||||
sourceUuid: entity.value.uuid,
|
||||
limit: 12
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
).then(hubsData => {
|
||||
relatedHubs.value = (hubsData?.nearestHubs || []).filter((h): h is HubItem => h !== null)
|
||||
}).finally(() => {
|
||||
isLoadingHubs.value = false
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error loading supplier info:', error)
|
||||
isLoadingProducts.value = false
|
||||
isLoadingHubs.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// Load offer info: offer details + supplier + hubs
|
||||
const loadOfferInfo = async (uuid: string) => {
|
||||
try {
|
||||
// Load offer details from exchange API
|
||||
const offerData = await execute(GetOfferDocument, { uuid }, 'public', 'exchange')
|
||||
entity.value = offerData?.getOffer ?? null
|
||||
|
||||
const coords = getEntityCoords(entity.value)
|
||||
if (!coords) {
|
||||
console.warn('Offer has no coordinates')
|
||||
return
|
||||
}
|
||||
|
||||
// Set default active tab to hubs
|
||||
activeTab.value = 'hubs'
|
||||
|
||||
// Set product as "related product" (single item)
|
||||
if (entity.value?.productUuid && entity.value?.productName) {
|
||||
relatedProducts.value = [
|
||||
{
|
||||
uuid: entity.value.productUuid,
|
||||
name: entity.value.productName
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// Load hubs near offer coordinates
|
||||
isLoadingHubs.value = true
|
||||
execute(
|
||||
NearestHubsDocument,
|
||||
{
|
||||
lat: coords.lat,
|
||||
lon: coords.lon,
|
||||
sourceUuid: entity.value?.uuid ?? null,
|
||||
limit: 12
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
).then(hubsData => {
|
||||
relatedHubs.value = (hubsData?.nearestHubs || []).filter((h): h is HubItem => h !== null)
|
||||
}).finally(() => {
|
||||
isLoadingHubs.value = false
|
||||
})
|
||||
|
||||
// If offer has supplier UUID, load supplier profile
|
||||
if (entity.value?.teamUuid) {
|
||||
isLoadingSuppliers.value = true
|
||||
execute(
|
||||
GetSupplierProfileDocument,
|
||||
{ uuid: entity.value.teamUuid },
|
||||
'public',
|
||||
'exchange'
|
||||
).then(supplierData => {
|
||||
const supplier = supplierData?.getSupplierProfile
|
||||
relatedSuppliers.value = supplier ? [supplier] : []
|
||||
// Enrich entity with supplier name for display
|
||||
if (supplier?.name && entity.value) {
|
||||
entity.value = { ...entity.value, supplierName: supplier.name }
|
||||
}
|
||||
}).catch(() => {
|
||||
// Supplier might not exist
|
||||
}).finally(() => {
|
||||
isLoadingSuppliers.value = false
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading offer info:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Load offers for hub after product selection
|
||||
const loadOffersForHub = async (hubUuid: string, productUuid: string) => {
|
||||
try {
|
||||
const hub = entity.value
|
||||
if (!hub?.latitude || !hub?.longitude) {
|
||||
console.warn('Hub has no coordinates')
|
||||
return
|
||||
}
|
||||
|
||||
// Load offers
|
||||
isLoadingOffers.value = true
|
||||
isLoadingSuppliers.value = true
|
||||
|
||||
try {
|
||||
// Find offers near hub for this product WITH routes calculated on backend
|
||||
const offersData = await execute(
|
||||
NearestOffersDocument,
|
||||
{
|
||||
lat: hub.latitude,
|
||||
lon: hub.longitude,
|
||||
productUuid,
|
||||
hubUuid, // Pass hubUuid to get routes calculated on backend
|
||||
limit: 12
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
)
|
||||
|
||||
// Offers already include routes from backend
|
||||
relatedOffers.value = (offersData?.nearestOffers || []).filter((o): o is OfferItem => o !== null)
|
||||
isLoadingOffers.value = false
|
||||
|
||||
// Extract unique suppliers from offers (use supplierUuid from offers)
|
||||
const supplierUuids = new Set<string>()
|
||||
relatedOffers.value.forEach(offer => {
|
||||
if (offer.supplierUuid) {
|
||||
supplierUuids.add(offer.supplierUuid)
|
||||
}
|
||||
})
|
||||
|
||||
// Load supplier profiles (limit to 12)
|
||||
const suppliers: SupplierProfile[] = []
|
||||
for (const uuid of Array.from(supplierUuids).slice(0, 12)) {
|
||||
try {
|
||||
const supplierData = await execute(
|
||||
GetSupplierProfileDocument,
|
||||
{ uuid },
|
||||
'public',
|
||||
'exchange'
|
||||
)
|
||||
if (supplierData?.getSupplierProfile) {
|
||||
suppliers.push(supplierData.getSupplierProfile)
|
||||
}
|
||||
} catch (e) {
|
||||
// Supplier might not exist
|
||||
}
|
||||
}
|
||||
relatedSuppliers.value = suppliers
|
||||
} finally {
|
||||
isLoadingOffers.value = false
|
||||
isLoadingSuppliers.value = false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading offers for hub:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Load offers for supplier after product selection
|
||||
const loadOffersForSupplier = async (_supplierUuid: string, productUuid: string) => {
|
||||
try {
|
||||
const supplier = entity.value
|
||||
if (!supplier?.latitude || !supplier?.longitude) {
|
||||
console.warn('Supplier has no coordinates')
|
||||
return
|
||||
}
|
||||
|
||||
isLoadingOffers.value = true
|
||||
isLoadingHubs.value = true
|
||||
|
||||
try {
|
||||
let hubUuid: string | null = relatedHubs.value?.[0]?.uuid ?? null
|
||||
if (!hubUuid && supplier.uuid) {
|
||||
const hubsData = await execute(
|
||||
NearestHubsDocument,
|
||||
{
|
||||
lat: supplier.latitude,
|
||||
lon: supplier.longitude,
|
||||
sourceUuid: supplier.uuid,
|
||||
limit: 1
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
)
|
||||
const hub = (hubsData?.nearestHubs || []).find((h): h is HubItem => h !== null)
|
||||
if (hub?.uuid) {
|
||||
hubUuid = hub.uuid
|
||||
if (!relatedHubs.value.length) {
|
||||
relatedHubs.value = [hub]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find offers near supplier for this product
|
||||
const offersData = await execute(
|
||||
NearestOffersDocument,
|
||||
{
|
||||
lat: supplier.latitude,
|
||||
lon: supplier.longitude,
|
||||
productUuid,
|
||||
...(hubUuid ? { hubUuid } : {}),
|
||||
limit: 12
|
||||
},
|
||||
'public',
|
||||
'geo'
|
||||
)
|
||||
|
||||
relatedOffers.value = (offersData?.nearestOffers || []).filter((o): o is OfferItem => {
|
||||
if (!o) return false
|
||||
if (!supplier.uuid) return true
|
||||
return o.supplierUuid === supplier.uuid
|
||||
})
|
||||
isLoadingOffers.value = false
|
||||
} finally {
|
||||
isLoadingOffers.value = false
|
||||
isLoadingHubs.value = false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading offers for supplier:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Select product (triggers offers loading)
|
||||
const selectProduct = async (productUuid: string) => {
|
||||
selectedProduct.value = productUuid
|
||||
|
||||
if (!entity.value) return
|
||||
|
||||
// Use stored entity type instead of inferring from properties
|
||||
if (entityType.value === 'hub' && entity.value.uuid) {
|
||||
await loadOffersForHub(entity.value.uuid, productUuid)
|
||||
activeTab.value = 'offers'
|
||||
} else if (entityType.value === 'supplier' && entity.value.uuid) {
|
||||
await loadOffersForSupplier(entity.value.uuid, productUuid)
|
||||
activeTab.value = 'offers'
|
||||
}
|
||||
}
|
||||
|
||||
// Set active tab
|
||||
const setActiveTab = (tab: string) => {
|
||||
activeTab.value = tab
|
||||
}
|
||||
|
||||
// Main load method - dispatches to specific loaders
|
||||
const loadInfo = async (type: InfoEntityType, uuid: string) => {
|
||||
isLoading.value = true
|
||||
clearInfo() // Clear previous data
|
||||
entityType.value = type // Store entity type
|
||||
|
||||
try {
|
||||
if (type === 'hub') {
|
||||
await loadHubInfo(uuid)
|
||||
} else if (type === 'supplier') {
|
||||
await loadSupplierInfo(uuid)
|
||||
} else if (type === 'offer') {
|
||||
await loadOfferInfo(uuid)
|
||||
}
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// Clear all info data
|
||||
const clearInfo = () => {
|
||||
entity.value = null
|
||||
entityType.value = null
|
||||
relatedProducts.value = []
|
||||
relatedHubs.value = []
|
||||
relatedSuppliers.value = []
|
||||
relatedOffers.value = []
|
||||
selectedProduct.value = null
|
||||
activeTab.value = 'products'
|
||||
isLoadingProducts.value = false
|
||||
isLoadingHubs.value = false
|
||||
isLoadingSuppliers.value = false
|
||||
isLoadingOffers.value = false
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
entity,
|
||||
relatedProducts,
|
||||
relatedHubs,
|
||||
relatedSuppliers,
|
||||
relatedOffers,
|
||||
selectedProduct,
|
||||
activeTab,
|
||||
isLoading,
|
||||
isLoadingProducts,
|
||||
isLoadingHubs,
|
||||
isLoadingSuppliers,
|
||||
isLoadingOffers,
|
||||
|
||||
// Actions
|
||||
loadInfo,
|
||||
selectProduct,
|
||||
setActiveTab,
|
||||
clearInfo
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user