Download src/components/Navbar.tsx from phucsd/PrintCal: direct link, hf CLI and curl.
- Browser
- Download file 5.12 kB
-
https://huggingface.co/spaces/phucsd/PrintCal/resolve/main/src/components/Navbar.tsx
- Command line
-
hf download hf://spaces/phucsd/PrintCal/src/components/Navbar.tsx
-
curl -L -o Navbar.tsx https://huggingface.co/spaces/phucsd/PrintCal/resolve/main/src/components/Navbar.tsx
5.12 kB
| 'use client'; | |
| import React from 'react'; | |
| import { | |
| Printer, | |
| Calculator, | |
| ClipboardList, | |
| FileSpreadsheet, | |
| Cpu, | |
| Scissors, | |
| Users, | |
| Settings, | |
| Sparkles, | |
| } from 'lucide-react'; | |
| export type ActiveTab = | |
| | 'calculator' | |
| | 'orders' | |
| | 'papers' | |
| | 'machines' | |
| | 'finishing' | |
| | 'customers' | |
| | 'settings'; | |
| interface NavbarProps { | |
| activeTab: ActiveTab; | |
| setActiveTab: (tab: ActiveTab) => void; | |
| orderCount?: number; | |
| } | |
| export const Navbar: React.FC<NavbarProps> = ({ | |
| activeTab, | |
| setActiveTab, | |
| orderCount = 0, | |
| }) => { | |
| const navItems = [ | |
| { id: 'calculator', label: 'Tính Giá In', icon: Calculator, badge: null }, | |
| { id: 'orders', label: 'Đơn Hàng & Báo Giá', icon: ClipboardList, badge: orderCount > 0 ? orderCount : null }, | |
| { id: 'papers', label: 'Kho Giá Giấy', icon: FileSpreadsheet, badge: null }, | |
| { id: 'machines', label: 'Bảng Giá In Máy', icon: Cpu, badge: null }, | |
| { id: 'finishing', label: 'Gia Công Sau In', icon: Scissors, badge: null }, | |
| { id: 'customers', label: 'Khách Hàng', icon: Users, badge: null }, | |
| { id: 'settings', label: 'Cài Đặt', icon: Settings, badge: null }, | |
| ] as const; | |
| return ( | |
| <header className="bg-slate-900 border-b border-slate-800 text-white sticky top-0 z-40 shadow-md"> | |
| <div className="max-w-7xl mx-auto px-4 sm:px-6"> | |
| <div className="flex items-center justify-between h-16"> | |
| {/* Logo & Brand */} | |
| <div className="flex items-center gap-3 cursor-pointer" onClick={() => setActiveTab('calculator')}> | |
| <div className="w-10 h-10 rounded-xl bg-gradient-to-tr from-blue-600 via-indigo-600 to-cyan-400 flex items-center justify-center shadow-lg shadow-blue-500/30"> | |
| <Printer className="w-5 h-5 text-white" /> | |
| </div> | |
| <div> | |
| <div className="flex items-center gap-1.5"> | |
| <span className="font-black text-lg tracking-wider text-white">PrintCal</span> | |
| <span className="text-[10px] uppercase font-bold tracking-widest px-1.5 py-0.5 rounded bg-blue-500/20 text-blue-400 border border-blue-500/30 flex items-center gap-1"> | |
| <Sparkles className="w-2.5 h-2.5" /> ERP Pro | |
| </span> | |
| </div> | |
| <p className="text-[11px] text-slate-400 hidden sm:block">Tính Giá In Offset & In Nhanh Thông Minh</p> | |
| </div> | |
| </div> | |
| {/* Navigation Links */} | |
| <nav className="hidden lg:flex items-center gap-1"> | |
| {navItems.map((item) => { | |
| const Icon = item.icon; | |
| const isActive = activeTab === item.id; | |
| return ( | |
| <button | |
| key={item.id} | |
| onClick={() => setActiveTab(item.id as ActiveTab)} | |
| className={`flex items-center gap-2 px-3 py-2 rounded-lg text-xs font-medium transition-all ${ | |
| isActive | |
| ? 'bg-blue-600 text-white shadow-sm font-semibold' | |
| : 'text-slate-300 hover:text-white hover:bg-slate-800/80' | |
| }`} | |
| > | |
| <Icon className="w-4 h-4" /> | |
| <span>{item.label}</span> | |
| {item.badge !== null && ( | |
| <span className="px-1.5 py-0.2 bg-rose-500 text-white text-[10px] font-bold rounded-full"> | |
| {item.badge} | |
| </span> | |
| )} | |
| </button> | |
| ); | |
| })} | |
| </nav> | |
| <div className="flex items-center gap-2 text-xs"> | |
| <div className="hidden sm:flex items-center gap-1.5 px-2.5 py-1 bg-emerald-500/10 border border-emerald-500/20 text-emerald-400 rounded-full font-medium text-[11px]"> | |
| <span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" /> | |
| <span>Sẵn sàng</span> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Mobile menu tab bar */} | |
| <div className="lg:hidden flex items-center gap-1 overflow-x-auto py-2 border-t border-slate-800/80 text-xs no-scrollbar"> | |
| {navItems.map((item) => { | |
| const Icon = item.icon; | |
| const isActive = activeTab === item.id; | |
| return ( | |
| <button | |
| key={item.id} | |
| onClick={() => setActiveTab(item.id as ActiveTab)} | |
| className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg whitespace-nowrap text-xs transition-colors shrink-0 ${ | |
| isActive | |
| ? 'bg-blue-600 text-white font-medium' | |
| : 'text-slate-300 hover:text-white hover:bg-slate-800' | |
| }`} | |
| > | |
| <Icon className="w-3.5 h-3.5" /> | |
| <span>{item.label}</span> | |
| {item.badge !== null && ( | |
| <span className="px-1 bg-rose-500 text-white text-[9px] font-bold rounded-full"> | |
| {item.badge} | |
| </span> | |
| )} | |
| </button> | |
| ); | |
| })} | |
| </div> | |
| </div> | |
| </header> | |
| ); | |
| }; | |