Files
testCursor/test.html
T
Торов Михаил ДмитриевичandCursor 6da9fd27a7 Initial commit: React app prototype
Add test.html UI component and app.js entry point.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 12:08:40 +03:00

294 lines
15 KiB
HTML
Raw 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.
import React, { useState, useEffect } from 'react';
import {
Package,
ArrowRightLeft,
Clock,
FileText,
CheckCircle2,
ClipboardList,
Bot,
Info,
Layers,
ChevronRight,
Smartphone
} from 'lucide-react';
// Корпоративные цвета Koblik Group
const COLORS = {
primary: '#FF9E00', // Фирменный оранжевый
dark: '#414449', // Корпоративный графитовый
background: '#F8F9FA',
text: '#2D2F33',
white: '#FFFFFF'
};
export default function App() {
const [currentTime, setCurrentTime] = useState(new Date());
useEffect(() => {
const timer = setInterval(() => setCurrentTime(new Date()), 1000);
return () => clearInterval(timer);
}, []);
// Список активных приоритетных документов в работе
const priorityDocuments = [
{
id: "Заказ № 1042-88",
client: 'ООО "Вектор"',
total: 1250,
picked: 875,
type: 'Отгрузка',
priority: 'Высокий'
},
{
id: "Заказ № 1042-95",
client: 'АО "АгроТех"',
total: 400,
picked: 380,
type: 'Кросс-докинг',
priority: 'Критический'
},
{
id: "Приемка № 884-П",
client: 'Завод "Деталь"',
total: 2000,
picked: 450,
type: 'Приемка',
priority: 'Средний'
}
];
// Данные активности сотрудников: ТСД заменено на Номер заказа
const tsdActivity = [
{ orderId: 'ЗКЗ-1042-88', worker: 'Иванов И.А.', item: 'Вал карданный L=1200', quantity: 12, unit: 'шт', itemStatus: 'arrived' },
{ orderId: 'ЗКЗ-1042-95', worker: 'Смирнов А.В.', item: 'Подшипник 206 (закрытый)', quantity: 48, unit: 'шт', itemStatus: 'planned' },
{ orderId: 'ЗКЗ-1042-92', worker: 'Петрова Е.С.', item: 'Редуктор цилиндрический Ц2У', quantity: 2, unit: 'шт', itemStatus: 'arrived' },
{ orderId: 'ЗКЗ-1042-89', worker: 'Сидоров К.М.', item: 'Звездочка Z-24 t=19.05', quantity: 120, unit: 'шт', itemStatus: 'planned' },
];
const containerMoves = [
{ id: 1, container: 'CONT-8892', robot: 'RBT-14', from: 'Приемка', to: 'A-12-04', status: 'В пути', statusType: 'moving' },
{ id: 2, container: 'CONT-1024', robot: 'RBT-02', from: 'B-05-01', to: 'Отгрузка', status: 'Ожидает ТС', statusType: 'waiting' },
{ id: 3, container: 'CONT-5531', robot: 'RBT-09', from: 'Консолидация', to: 'Буфер', status: 'В пути', statusType: 'moving' },
];
const getStatusBadge = (type, text) => {
const styles = {
moving: "bg-orange-50 text-orange-700 border-orange-200",
waiting: "bg-slate-100 text-slate-600 border-slate-200",
error: "bg-red-50 text-red-700 border-red-200",
processing: "bg-[#FF9E00] text-white border-[#E68E00]",
new: "bg-slate-50 text-slate-500 border-slate-200",
done: "bg-green-50 text-green-700 border-green-200"
};
return (
<span className={`px-2.5 py-0.5 text-[10px] font-bold rounded uppercase tracking-wider border ${styles[type] || 'bg-gray-100'}`}>
{text}
</span>
);
};
return (
<div className="min-h-screen bg-[#F8F9FA] text-[#2D2F33] font-sans">
{/* Шапка KOBLIK */}
<header className="bg-[#414449] text-white px-8 py-4 shadow-lg flex justify-between items-center border-b-4 border-[#FF9E00]">
<div className="flex items-center gap-6">
<div className="bg-white px-4 py-2 rounded flex items-center">
<svg width="130" height="32" viewBox="0 0 130 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 2V30H6.5V18.5L13 30H20.5L12 15.5L19.5 2H12.5L6.5 13V2H0Z" fill="#414449"/>
<path d="M23 16C23 8 28.5 2 36.5 2C44.5 2 50 8 50 16C50 24 44.5 30 36.5 30C28.5 30 23 24 23 16ZM43.5 16C43.5 11 41 8 36.5 8C32 8 29.5 11 29.5 16C29.5 21 32 24 36.5 24C41 24 43.5 21 43.5 16Z" fill="#414449"/>
<path d="M54 2H65C69 2 72 4 72 8C72 10.5 70.5 12.5 68.5 13.5C71 14.5 73 17 73 20C73 25 69.5 30 64 30H54V2ZM66.5 11.5C66.5 10 65.5 9 64 9H60.5V14H64C65.5 14 66.5 13 66.5 11.5ZM66.5 20.5C66.5 19 65.5 18 64 18H60.5V23H64C65.5 23 66.5 22 66.5 20.5Z" fill="#414449"/>
<path d="M78 2H84.5V23H97V30H78V2Z" fill="#414449"/>
<rect x="101" y="2" width="6.5" height="6.5" fill="#FF9E00"/>
<path d="M101 11H107.5V30H101V11Z" fill="#414449"/>
<path d="M112 2V30H118.5V18.5L124 30H130L124.5 18.5L130 2H123L118.5 11.5V2H112Z" fill="#414449"/>
</svg>
</div>
<h1 className="text-xl font-black tracking-widest uppercase hidden md:block">WMS Dashboard</h1>
</div>
<div className="flex items-center gap-4">
<div className="flex flex-col items-end mr-4">
<span className="text-[10px] uppercase text-slate-400 font-bold tracking-widest text-right">Текущее время</span>
<div className="text-xl font-mono font-bold text-[#FF9E00]">
{currentTime.toLocaleTimeString('ru-RU')}
</div>
</div>
<div className="bg-[#56595F] p-2 rounded-full">
<Clock className="w-5 h-5 text-[#FF9E00]" />
</div>
</div>
</header>
<main className="p-6 max-w-[1600px] mx-auto space-y-6">
{/* СЕКЦИЯ: ПРИОРИТЕТНЫЕ ЗАДАНИЯ В РАБОТЕ */}
<section className="space-y-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Layers className="w-5 h-5 text-[#414449]" />
<h2 className="text-sm font-black uppercase tracking-[0.2em] text-[#414449]">Приоритетные задания</h2>
</div>
<span className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">Всего в работе: {priorityDocuments.length}</span>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{priorityDocuments.map((doc, index) => {
const progress = Math.round((doc.picked / doc.total) * 100);
return (
<div key={index} className="bg-white rounded-xl shadow-md border-l-4 border-[#FF9E00] p-4 flex flex-col justify-between hover:shadow-lg transition-shadow">
<div className="flex justify-between items-start mb-3">
<div>
<div className="flex items-center gap-2 mb-1">
<span className={`text-[9px] font-black px-1.5 py-0.5 rounded uppercase ${
doc.priority === 'Критический' ? 'bg-red-100 text-red-600' : 'bg-orange-100 text-orange-700'
}`}>
{doc.priority}
</span>
<span className="text-slate-400 text-[9px] font-bold uppercase tracking-tighter">{doc.type}</span>
</div>
<h3 className="font-black text-[#414449] text-lg">{doc.id}</h3>
<p className="text-slate-500 text-xs truncate max-w-[150px]">{doc.client}</p>
</div>
<FileText className="w-5 h-5 text-slate-300" />
</div>
<div className="space-y-2">
<div className="flex justify-between items-end">
<span className="text-xs font-bold text-slate-400">{doc.picked} / {doc.total} ед.</span>
<span className="text-[#FF9E00] font-black text-sm">{progress}%</span>
</div>
<div className="h-1.5 w-full bg-slate-100 rounded-full overflow-hidden">
<div
className="h-full bg-[#FF9E00] transition-all duration-500"
style={{ width: `${progress}%` }}
></div>
</div>
</div>
</div>
);
})}
</div>
</section>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Операторы ТСД (Активность по заказам) */}
<section className="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden flex flex-col">
<div className="px-6 py-4 border-b border-slate-100 bg-[#414449] flex items-center justify-between">
<div className="flex items-center gap-3">
<Smartphone className="w-5 h-5 text-[#FF9E00]" />
<h3 className="font-black text-white uppercase text-xs tracking-[0.2em]">Операторы ТСД</h3>
</div>
</div>
<div className="overflow-x-auto">
<table className="w-full text-left">
<thead className="bg-slate-50">
<tr className="text-[10px] uppercase tracking-wider text-slate-400 border-b border-slate-200">
<th className="px-6 py-4 font-black">Сотрудник / Заказ</th>
<th className="px-6 py-4 font-black">Номенклатура и план</th>
<th className="px-6 py-4 font-black text-right">Наличие в зоне</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
{tsdActivity.map((task, index) => (
<tr key={index} className="hover:bg-slate-50 transition-colors">
<td className="px-6 py-4">
<div className="font-bold text-[#414449] text-sm">{task.worker}</div>
<div className="text-[10px] font-mono font-bold text-[#FF9E00] mt-0.5">{task.orderId}</div>
</td>
<td className="px-6 py-4">
<div className="flex flex-col">
<div className={`text-xs font-bold ${task.itemStatus === 'arrived' ? 'text-slate-800' : 'text-slate-500'}`}>
{task.item}
</div>
<div className="flex items-center gap-1 mt-1">
<span className="text-[10px] text-slate-400 uppercase font-bold">Потребность:</span>
<span className={`text-xs font-black ${task.itemStatus === 'arrived' ? 'text-[#FF9E00]' : 'text-slate-400'}`}>
{task.quantity} {task.unit}.
</span>
</div>
</div>
</td>
<td className="px-6 py-4 text-right">
{task.itemStatus === 'arrived' ? (
<span className="inline-flex items-center px-2 py-1 rounded bg-emerald-50 text-emerald-700 border border-emerald-200 text-[9px] font-black uppercase tracking-wider">
В зоне отбора
</span>
) : (
<span className="inline-flex items-center px-2 py-1 rounded bg-slate-100 text-slate-500 border border-slate-200 text-[9px] font-black uppercase tracking-wider">
Ожидает подвоза
</span>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</section>
{/* Логистика роботов */}
<section className="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden flex flex-col">
<div className="px-6 py-4 border-b border-slate-100 bg-[#414449] flex items-center justify-between">
<div className="flex items-center gap-3">
<Bot className="w-5 h-5 text-[#FF9E00]" />
<h3 className="font-black text-white uppercase text-xs tracking-[0.2em]">Логистика роботов</h3>
</div>
</div>
<div className="overflow-x-auto">
<table className="w-full text-left">
<thead className="bg-slate-50">
<tr className="text-[10px] uppercase tracking-wider text-slate-400 border-b border-slate-200">
<th className="px-6 py-4 font-black">ID Тары</th>
<th className="px-6 py-4 font-black">Маршрут</th>
<th className="px-6 py-4 font-black">Юнит</th>
<th className="px-6 py-4 font-black text-right">Статус</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
{containerMoves.map((move) => (
<tr key={move.id} className="hover:bg-slate-50 transition-colors">
<td className="px-6 py-4 font-mono font-black text-[#414449] text-sm">
{move.container}
</td>
<td className="px-6 py-4">
<div className="flex items-center gap-2 text-[11px]">
<span className="text-slate-400 font-medium">{move.from}</span>
<ArrowRightLeft className="w-3 h-3 text-[#FF9E00]" />
<span className="font-bold text-slate-800">{move.to}</span>
</div>
</td>
<td className="px-6 py-4">
<div className="inline-flex items-center gap-1.5 px-2 py-1 rounded bg-[#414449] text-[#FF9E00] font-mono text-[10px] font-black">
{move.robot}
</div>
</td>
<td className="px-6 py-4 text-right">
{getStatusBadge(move.statusType, move.status)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</section>
</div>
</main>
<footer className="mt-8 py-6 bg-white border-t border-slate-200 text-center">
<div className="text-slate-400 text-[10px] font-black uppercase tracking-[0.3em] flex justify-center items-center gap-2">
<span>KOBLIK GROUP</span>
<span className="text-[#FF9E00]"></span>
<span>WMS Logistics Control System</span>
<span className="text-[#FF9E00]"></span>
<span>{new Date().getFullYear()}</span>
</div>
</footer>
</div>
);
}