Files
webapp/app/components/catalog/RouteStepper.vue
Ruslan Bakiev 5b620f77b3
All checks were successful
Build Docker Image / build (push) Successful in 4m57s
Improve hub page: new RouteStepper, HubProductCard with ApexCharts
- Redesign RouteStepper: nodes connected by lines with distance on line
- Add HubProductCard component with sparkline chart background
- Auto-select first product when hub page loads
- Remove placeholder with package-x icon
- Add ApexCharts plugin for charts
- Pass startName/endName to RouteStepper for route visualization
2026-01-15 15:45:26 +07:00

84 lines
2.4 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="flex items-center w-full py-2">
<!-- Start node -->
<div class="flex flex-col items-center shrink-0">
<div class="w-3 h-3 rounded-full bg-primary border-2 border-primary"></div>
<Text v-if="startName" size="xs" tone="muted" class="mt-1 max-w-16 truncate text-center">{{ startName }}</Text>
</div>
<!-- Stages (line + transport icon + distance -> node) -->
<template v-for="(stage, i) in stages" :key="i">
<!-- Line segment with transport icon and distance -->
<div class="flex-1 flex flex-col items-center mx-1 min-w-12">
<!-- Line with icon in the middle -->
<div class="flex items-center w-full">
<div class="h-0.5 bg-primary/60 flex-1"></div>
<span class="px-1.5 text-sm" :title="getTransportName(stage.transportType)">
{{ getTransportIcon(stage.transportType) }}
</span>
<div class="h-0.5 bg-primary/60 flex-1"></div>
</div>
<!-- Distance label -->
<Text size="xs" tone="muted" class="mt-0.5 whitespace-nowrap">
{{ formatDistance(stage.distanceKm) }} км
</Text>
</div>
<!-- Intermediate/End node -->
<div class="flex flex-col items-center shrink-0">
<div
class="rounded-full border-2"
:class="i === stages.length - 1 ? 'w-3 h-3 bg-success border-success' : 'w-2.5 h-2.5 bg-base-100 border-primary'"
></div>
<Text v-if="i === stages.length - 1 && endName" size="xs" tone="muted" class="mt-1 max-w-16 truncate text-center">
{{ endName }}
</Text>
</div>
</template>
</div>
</template>
<script setup lang="ts">
export interface RouteStage {
transportType?: string | null
distanceKm?: number | null
}
defineProps<{
stages: RouteStage[]
startName?: string
endName?: string
}>()
const getTransportIcon = (type?: string | null) => {
switch (type) {
case 'rail':
return '🚂'
case 'sea':
return '🚢'
case 'road':
case 'auto':
default:
return '🚛'
}
}
const getTransportName = (type?: string | null) => {
switch (type) {
case 'rail':
return 'Ж/Д'
case 'sea':
return 'Море'
case 'road':
case 'auto':
default:
return 'Авто'
}
}
const formatDistance = (km?: number | null) => {
if (!km) return '0'
return Math.round(km).toLocaleString()
}
</script>