diff --git a/src/app/logistics/page.tsx b/src/app/logistics/page.tsx
new file mode 100644
index 0000000..023949e
--- /dev/null
+++ b/src/app/logistics/page.tsx
@@ -0,0 +1,10 @@
+import { AuthGuard } from "@/components/auth-guard";
+import { LogisticsDashboard } from "@/components/logistics/logistics-dashboard";
+
+export default function LogisticsPage() {
+ return (
+
+
+
+ );
+}
diff --git a/src/components/dashboard/sidebar.tsx b/src/components/dashboard/sidebar.tsx
index 9b46382..6992dd0 100644
--- a/src/components/dashboard/sidebar.tsx
+++ b/src/components/dashboard/sidebar.tsx
@@ -83,11 +83,22 @@ export function Sidebar() {
}
const handleSuppliesClick = () => {
- // Для фулфилмент кабинетов используем новый роут
- if (user?.organization?.type === 'FULFILLMENT') {
- router.push('/fulfillment-supplies')
- } else {
- router.push('/supplies')
+ // Для каждого типа кабинета свой роут
+ switch (user?.organization?.type) {
+ case 'FULFILLMENT':
+ router.push('/fulfillment-supplies')
+ break
+ case 'SELLER':
+ router.push('/supplies')
+ break
+ case 'WHOLESALE':
+ router.push('/supplies')
+ break
+ case 'LOGIST':
+ router.push('/logistics')
+ break
+ default:
+ router.push('/supplies')
}
}
@@ -103,7 +114,7 @@ export function Sidebar() {
const isServicesActive = pathname.startsWith('/services')
const isWarehouseActive = pathname.startsWith('/warehouse')
const isEmployeesActive = pathname.startsWith('/employees')
- const isSuppliesActive = pathname.startsWith('/supplies') || pathname.startsWith('/fulfillment-supplies')
+ const isSuppliesActive = pathname.startsWith('/supplies') || pathname.startsWith('/fulfillment-supplies') || pathname.startsWith('/logistics')
const isPartnersActive = pathname.startsWith('/partners')
return (
@@ -270,8 +281,8 @@ export function Sidebar() {
)}
- {/* Поставки - для селлеров и фулфилмент */}
- {(user?.organization?.type === 'SELLER' || user?.organization?.type === 'FULFILLMENT') && (
+ {/* Мои поставки - для селлеров */}
+ {user?.organization?.type === 'SELLER' && (
+ )}
+
+ {/* Входящие поставки - для фулфилмент */}
+ {user?.organization?.type === 'FULFILLMENT' && (
+
+ )}
+
+ {/* Отгрузки - для оптовиков */}
+ {user?.organization?.type === 'WHOLESALE' && (
+
+ )}
+
+ {/* Перевозки - для логистов */}
+ {user?.organization?.type === 'LOGIST' && (
+
)}
diff --git a/src/components/logistics/logistics-dashboard.tsx b/src/components/logistics/logistics-dashboard.tsx
new file mode 100644
index 0000000..fa1a76b
--- /dev/null
+++ b/src/components/logistics/logistics-dashboard.tsx
@@ -0,0 +1,285 @@
+"use client";
+
+import { useState } from "react";
+import { Card } from "@/components/ui/card";
+import { Button } from "@/components/ui/button";
+import { Badge } from "@/components/ui/badge";
+import { Sidebar } from "@/components/dashboard/sidebar";
+import { useSidebar } from "@/hooks/useSidebar";
+import {
+ Truck,
+ Plus,
+ MapPin,
+ Clock,
+ Package,
+ TrendingUp,
+ AlertTriangle,
+ Navigation,
+} from "lucide-react";
+
+// Мок данные для перевозок
+const mockLogistics = [
+ {
+ id: "1",
+ routeNumber: "LOG-001",
+ from: "Садовод",
+ fromAddress: "Москва, 14-й км МКАД",
+ to: "SFERAV Logistics",
+ toAddress: "Москва, ул. Складская, 15",
+ status: "in_transit",
+ distance: "45 км",
+ estimatedTime: "1 ч 30 мин",
+ cargo: "Смартфоны (50 шт.)",
+ price: 15000,
+ createdDate: "2024-01-10",
+ },
+ {
+ id: "2",
+ routeNumber: "LOG-002",
+ from: "SFERAV Logistics",
+ fromAddress: "Москва, ул. Складская, 15",
+ to: "Коледино WB",
+ toAddress: "МО, г. Подольск, Коледино",
+ status: "delivered",
+ distance: "62 км",
+ estimatedTime: "2 ч 15 мин",
+ cargo: "Одежда (120 шт.)",
+ price: 22000,
+ createdDate: "2024-01-09",
+ },
+ {
+ id: "3",
+ routeNumber: "LOG-003",
+ from: "Тверь Ozon",
+ fromAddress: "г. Тверь, ул. Складская, 88",
+ to: "SFERAV Logistics",
+ toAddress: "Москва, ул. Складская, 15",
+ status: "planned",
+ distance: "178 км",
+ estimatedTime: "3 ч 45 мин",
+ cargo: "Электроника (75 шт.)",
+ price: 35000,
+ createdDate: "2024-01-11",
+ },
+];
+
+export function LogisticsDashboard() {
+ const { getSidebarMargin } = useSidebar();
+
+ const formatCurrency = (amount: number) => {
+ return new Intl.NumberFormat("ru-RU", {
+ style: "currency",
+ currency: "RUB",
+ minimumFractionDigits: 0,
+ }).format(amount);
+ };
+
+ const formatDate = (dateString: string) => {
+ return new Date(dateString).toLocaleDateString("ru-RU", {
+ day: "2-digit",
+ month: "2-digit",
+ year: "numeric",
+ });
+ };
+
+ const getStatusBadge = (status: string) => {
+ const statusConfig = {
+ planned: {
+ color: "text-blue-300 border-blue-400/30",
+ label: "Запланировано",
+ },
+ in_transit: {
+ color: "text-yellow-300 border-yellow-400/30",
+ label: "В пути",
+ },
+ delivered: {
+ color: "text-green-300 border-green-400/30",
+ label: "Доставлено",
+ },
+ cancelled: { color: "text-red-300 border-red-400/30", label: "Отменено" },
+ };
+
+ const config =
+ statusConfig[status as keyof typeof statusConfig] || statusConfig.planned;
+
+ return (
+
+ {config.label}
+
+ );
+ };
+
+ const getTotalRevenue = () => {
+ return mockLogistics.reduce((sum, route) => sum + route.price, 0);
+ };
+
+ const getInTransitCount = () => {
+ return mockLogistics.filter((route) => route.status === "in_transit")
+ .length;
+ };
+
+ const getDeliveredCount = () => {
+ return mockLogistics.filter((route) => route.status === "delivered").length;
+ };
+
+ return (
+
+
+
+
+ {/* Заголовок */}
+
+
+
Перевозки
+
+ Управление логистическими маршрутами
+
+
+
+
+
+ {/* Статистика */}
+
+
+
+
+
+
+
+
Всего маршрутов
+
+ {mockLogistics.length}
+
+
+
+
+
+
+
+
+
+
+
+
В пути
+
+ {getInTransitCount()}
+
+
+
+
+
+
+
+
+
+
Доставлено
+
+ {getDeliveredCount()}
+
+
+
+
+
+
+
+
+
+
+
+
Выручка
+
+ {formatCurrency(getTotalRevenue())}
+
+
+
+
+
+
+ {/* Список маршрутов */}
+
+
+
+ Активные маршруты
+
+
+ {mockLogistics.map((route) => (
+
+
+
+
+
+ {route.routeNumber}
+
+ {getStatusBadge(route.status)}
+
+
+
+
+
+
+
+
+ {route.from}
+
+
+ {route.fromAddress}
+
+
+
+
+
+
+
+ {route.to}
+
+
+ {route.toAddress}
+
+
+
+
+
+
+
+
+
+
+ {route.distance} • {route.estimatedTime}
+
+
+
+
+
+
+
+ Создано: {formatDate(route.createdDate)}
+
+
+ {formatCurrency(route.price)}
+
+
+
+
+
+ ))}
+
+
+
+
+
+
+ );
+}