feat: Add screenshots to asset management system introduction

Includes JPG and PNG image files for visual representation of the asset management system's features and interface.
This commit is contained in:
pazz09adk-glitch
2026-03-30 19:36:19 +08:00
parent 8893228a5d
commit 9c4f39df51
14 changed files with 297 additions and 277 deletions

View File

@@ -0,0 +1 @@
# This file ensures the directory is tracked by the system.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,6 @@
# 系统截图存放目录
请将您的系统截图上传到此目录下。
上传后,请确保文件名与代码中的引用一致(例如:`dashboard.png`, `asset-list.png` 等)。
目前代码中预设的路径为:`/assets/screenshots/文件名.png`

Binary file not shown.

View File

@@ -22,7 +22,7 @@ import {
CheckCircle2,
Zap
} from 'lucide-react';
import { motion, AnimatePresence } from 'motion/react';
import { motion } from 'motion/react';
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
@@ -32,9 +32,8 @@ function cn(...inputs: ClassValue[]) {
// --- Components ---
const Navbar = ({ activeTab, setActiveTab }: { activeTab: string, setActiveTab: (tab: string) => void }) => {
const Navbar = () => {
const [isScrolled, setIsScrolled] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
useEffect(() => {
const handleScroll = () => setIsScrolled(window.scrollY > 20);
@@ -42,119 +41,93 @@ const Navbar = ({ activeTab, setActiveTab }: { activeTab: string, setActiveTab:
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const tabs = [
{ id: 'asset', label: '资产管理系统' },
{ id: 'rental', label: '车辆租赁系统' },
];
return (
<nav className={cn(
"fixed top-0 left-0 right-0 z-50 transition-all duration-300 border-b",
isScrolled ? "bg-white/80 backdrop-blur-md py-3 border-slate-200" : "bg-transparent py-5 border-transparent"
)}>
<div className="max-w-7xl mx-auto px-6 flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="w-10 h-10 bg-blue-600 rounded-lg flex items-center justify-center text-white font-bold text-xl">1</div>
<span className="text-xl font-bold tracking-tight text-slate-900">OneOS <span className="text-blue-600">Solutions</span></span>
<div className="max-w-7xl mx-auto px-6 flex items-center justify-between relative h-16 md:h-20">
{/* Left: Logo */}
<div className="flex items-center">
<div className="h-10 md:h-12 flex items-center justify-center overflow-hidden">
<img src="/assets/screenshots/logo.png" alt="Logo" className="h-full w-auto object-contain" referrerPolicy="no-referrer" />
</div>
</div>
{/* Center: Title */}
<div className="absolute left-1/2 -translate-x-1/2 flex items-center whitespace-nowrap">
<span className="text-xl md:text-2xl font-bold tracking-tight text-slate-900">OneOS <span className="text-brand">Solutions</span></span>
</div>
{/* Desktop Tabs */}
<div className="hidden md:flex items-center gap-1 bg-slate-100 p-1 rounded-full">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={cn(
"px-6 py-2 rounded-full text-sm font-medium transition-all",
activeTab === tab.id
? "bg-white text-blue-600 shadow-sm"
: "text-slate-600 hover:text-slate-900"
)}
>
{tab.label}
</button>
))}
</div>
<div className="hidden md:block">
<button className="bg-slate-900 text-white px-5 py-2.5 rounded-full text-sm font-medium hover:bg-slate-800 transition-colors">
</button>
</div>
{/* Mobile Menu Toggle */}
<button className="md:hidden p-2" onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}>
{isMobileMenuOpen ? <X /> : <Menu />}
</button>
{/* Right: Spacer to maintain layout if needed, but not strictly necessary with absolute center */}
<div className="hidden md:block w-12" />
</div>
{/* Mobile Menu */}
<AnimatePresence>
{isMobileMenuOpen && (
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
className="absolute top-full left-0 right-0 bg-white border-b border-slate-200 p-6 md:hidden shadow-xl"
>
<div className="flex flex-col gap-4">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => {
setActiveTab(tab.id);
setIsMobileMenuOpen(false);
}}
className={cn(
"text-left py-3 px-4 rounded-xl text-lg font-medium",
activeTab === tab.id ? "bg-blue-50 text-blue-600" : "text-slate-600"
)}
>
{tab.label}
</button>
))}
<hr className="border-slate-100" />
<button className="bg-blue-600 text-white py-4 rounded-xl font-bold">
</button>
</div>
</motion.div>
)}
</AnimatePresence>
</nav>
);
};
const Hero = ({ title, subtitle, badge }: { title: string, subtitle: string, badge: string }) => (
<section className="relative pt-32 pb-20 md:pt-48 md:pb-32 overflow-hidden">
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full -z-10 opacity-30">
<div className="absolute top-[-10%] left-[-10%] w-[40%] h-[40%] bg-blue-400 rounded-full blur-[120px]" />
<div className="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] bg-indigo-400 rounded-full blur-[120px]" />
{/* Premium Mesh Gradient Background */}
<div className="absolute inset-0 -z-10">
{/* Base Layer - Very subtle green tint */}
<div className="absolute inset-0 bg-emerald-50/20" />
{/* Mesh Blobs - Slightly more vibrant but still soft */}
<div className="absolute top-[-10%] left-[-10%] w-[70%] h-[70%] bg-emerald-200/40 rounded-full blur-[120px] animate-pulse" style={{ animationDuration: '10s' }} />
<div className="absolute bottom-[-10%] right-[-10%] w-[70%] h-[70%] bg-teal-200/40 rounded-full blur-[120px] animate-pulse" style={{ animationDuration: '15s' }} />
<div className="absolute top-[20%] right-[10%] w-[50%] h-[50%] bg-emerald-100/30 rounded-full blur-[100px]" />
{/* Subtle overall gradient overlay */}
<div className="absolute inset-0 bg-gradient-to-b from-emerald-50/30 via-transparent to-white" />
{/* Noise Texture Overlay */}
<div className="absolute inset-0 opacity-[0.03] pointer-events-none" style={{ backgroundImage: 'url("https://grainy-gradients.vercel.app/noise.svg")' }} />
{/* Geometric Grid */}
<div className="absolute inset-0 opacity-[0.1]" style={{
backgroundImage: `linear-gradient(#065f46 1px, transparent 1px), linear-gradient(90deg, #065f46 1px, transparent 1px)`,
backgroundSize: '60px 60px'
}} />
{/* Central Spotlight */}
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full max-w-6xl h-full bg-[radial-gradient(circle_at_50%_40%,#fff_0%,transparent_80%)]" />
{/* Accent Lines */}
<div className="absolute top-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-brand/20 to-transparent" />
<div className="absolute bottom-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-emerald-100 to-transparent" />
</div>
<div className="max-w-7xl mx-auto px-6 text-center">
<div className="max-w-7xl mx-auto px-6 text-center relative">
{/* Floating Decorative Elements */}
<motion.div
animate={{ y: [0, -20, 0] }}
transition={{ duration: 4, repeat: Infinity, ease: "easeInOut" }}
className="absolute -top-20 -left-20 w-40 h-40 bg-brand/5 rounded-3xl rotate-12 blur-xl hidden lg:block"
/>
<motion.div
animate={{ y: [0, 20, 0] }}
transition={{ duration: 5, repeat: Infinity, ease: "easeInOut" }}
className="absolute top-60 -right-20 w-56 h-56 bg-teal-500/5 rounded-full blur-3xl hidden lg:block"
/>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
transition={{ duration: 0.8, ease: "easeOut" }}
>
<span className="inline-block px-4 py-1.5 rounded-full bg-blue-50 text-blue-600 text-xs font-bold uppercase tracking-wider mb-6">
{badge}
</span>
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white/80 backdrop-blur-sm border border-brand-muted shadow-sm mb-8">
<span className="w-2 h-2 rounded-full bg-brand animate-pulse" />
<span className="text-brand text-xs font-bold uppercase tracking-wider">
{badge}
</span>
</div>
<h1 className="text-5xl md:text-7xl font-black text-slate-900 mb-8 leading-[1.1] tracking-tight">
{title}
</h1>
<p className="text-xl text-slate-600 max-w-3xl mx-auto mb-10 leading-relaxed">
{subtitle}
</p>
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
<button className="w-full sm:w-auto bg-blue-600 text-white px-8 py-4 rounded-2xl font-bold text-lg hover:bg-blue-700 transition-all shadow-lg shadow-blue-200 flex items-center justify-center gap-2">
<ArrowRight size={20} />
</button>
<button className="w-full sm:w-auto bg-white text-slate-900 border border-slate-200 px-8 py-4 rounded-2xl font-bold text-lg hover:bg-slate-50 transition-all">
</button>
</div>
</motion.div>
</div>
</section>
@@ -168,7 +141,7 @@ const FeatureCard = ({ icon: Icon, title, description, delay }: { icon: any, tit
transition={{ duration: 0.5, delay }}
className="bg-white p-8 rounded-3xl border border-slate-100 shadow-sm hover:shadow-xl hover:-translate-y-1 transition-all group"
>
<div className="w-14 h-14 bg-blue-50 text-blue-600 rounded-2xl flex items-center justify-center mb-6 group-hover:bg-blue-600 group-hover:text-white transition-colors">
<div className="w-14 h-14 bg-brand-light text-brand rounded-2xl flex items-center justify-center mb-6 group-hover:bg-brand group-hover:text-white transition-colors">
<Icon size={28} />
</div>
<h3 className="text-xl font-bold text-slate-900 mb-3">{title}</h3>
@@ -183,11 +156,14 @@ const SectionHeading = ({ title, subtitle, centered = true }: { title: string, s
</div>
);
const ScreenshotPlaceholder = ({ label, description, src, type = "web" }: { label: string, description: string, src?: string, type?: "web" | "mobile" }) => (
<div className={cn(
"relative bg-slate-100 rounded-2xl overflow-hidden border border-slate-200 group cursor-pointer shadow-sm",
type === "mobile" ? "aspect-[9/19.5] max-w-[280px] mx-auto" : "aspect-video w-full"
)}>
const ScreenshotPlaceholder = ({ label, description, src, type = "web", onClick }: { label: string, description: string, src?: string, type?: "web" | "mobile", onClick?: () => void }) => (
<div
onClick={onClick}
className={cn(
"relative bg-slate-100 rounded-2xl overflow-hidden border border-slate-200 group cursor-pointer shadow-sm transition-all hover:ring-2 hover:ring-brand/50",
type === "mobile" ? "aspect-[9/19.5] w-full" : "aspect-video w-full"
)}
>
{src ? (
<img
src={src}
@@ -204,18 +180,52 @@ const ScreenshotPlaceholder = ({ label, description, src, type = "web" }: { labe
<p className="text-xs text-slate-500">{description}</p>
</div>
)}
<div className="absolute inset-0 bg-blue-600/0 group-hover:bg-blue-600/5 transition-colors pointer-events-none" />
<div className="absolute inset-0 bg-brand/0 group-hover:bg-brand/5 transition-colors pointer-events-none" />
<div className="absolute bottom-4 right-4 bg-white/90 backdrop-blur px-3 py-1 rounded-full text-[10px] font-bold text-slate-600 border border-white/50 shadow-sm z-10">
{type === "mobile" ? "移动端界面" : "Web端界面"}
</div>
</div>
);
const Lightbox = ({ src, onClose }: { src: string | null, onClose: () => void }) => {
if (!src) return null;
return (
<div
className="fixed inset-0 z-[100] bg-slate-900/90 backdrop-blur-sm flex items-center justify-center p-4 md:p-10 cursor-zoom-out"
onClick={onClose}
>
<motion.div
initial={{ scale: 0.9, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
className="relative max-w-5xl w-full max-h-full flex items-center justify-center"
onClick={(e) => e.stopPropagation()}
>
<img
src={src}
alt="Large view"
className="max-w-full max-h-[90vh] object-contain rounded-xl shadow-2xl"
referrerPolicy="no-referrer"
/>
<button
onClick={onClose}
className="absolute -top-12 right-0 text-white hover:text-brand-accent transition-colors p-2"
>
<X size={32} />
</button>
</motion.div>
</div>
);
};
// --- Main Content Sections ---
const AssetManagementSystem = () => {
const [selectedImage, setSelectedImage] = useState<string | null>(null);
return (
<div className="space-y-32 pb-20">
<div className="space-y-20 pb-20">
<Lightbox src={selectedImage} onClose={() => setSelectedImage(null)} />
<Hero
badge="OneOS 核心产品"
title="企业级资产管理中枢"
@@ -235,7 +245,7 @@ const AssetManagementSystem = () => {
<FeatureCard
icon={BarChart3}
title="实时可视化大屏"
description="提供资产分布热力图、利用率分析、折旧成本报表等多维度视图,辅助资源优化配置。"
description="构建可视化运营视图,聚合核心数据分析。直观呈现资产分布与利用效率,支撑资源优化配置,驱动资产价值最大化。"
delay={0.2}
/>
<FeatureCard
@@ -247,7 +257,7 @@ const AssetManagementSystem = () => {
<FeatureCard
icon={Smartphone}
title="多端协同集成"
description="支持PC管理后台 + 移动端扫码操作,无缝对接企业现有ERP、财务及OA系统。"
description="支持PC管理后台 + 移动端扫码操作,对接企业现有ERP、财务及OA系统。"
delay={0.4}
/>
</div>
@@ -270,7 +280,7 @@ const AssetManagementSystem = () => {
{ title: "接入层", desc: "全面支持Web端、移动端及第三方系统API接入。" }
].map((item, i) => (
<div key={i} className="flex gap-4">
<div className="mt-1 flex-shrink-0 w-6 h-6 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center">
<div className="mt-1 flex-shrink-0 w-6 h-6 rounded-full bg-brand-light text-brand flex items-center justify-center">
<CheckCircle2 size={14} />
</div>
<div>
@@ -282,10 +292,10 @@ const AssetManagementSystem = () => {
</div>
</div>
<div className="bg-white p-10 rounded-[40px] shadow-2xl shadow-slate-200 border border-slate-100 relative overflow-hidden">
<div className="absolute top-0 right-0 w-32 h-32 bg-blue-50 rounded-bl-full -z-0" />
<div className="absolute top-0 right-0 w-32 h-32 bg-brand-light rounded-bl-full -z-0" />
<div className="relative z-10 flex flex-col items-center gap-8">
<div className="w-48 h-48 rounded-full border-4 border-dashed border-blue-200 flex items-center justify-center p-4">
<div className="w-full h-full bg-blue-600 rounded-full flex flex-col items-center justify-center text-white text-center">
<div className="w-48 h-48 rounded-full border-4 border-dashed border-brand-muted flex items-center justify-center p-4">
<div className="w-full h-full bg-brand rounded-full flex flex-col items-center justify-center text-white text-center">
<Database size={32} className="mb-2" />
<span className="text-xs font-bold uppercase tracking-widest"></span>
</div>
@@ -303,103 +313,6 @@ const AssetManagementSystem = () => {
</div>
</section>
{/* Modules Showcase */}
<section className="max-w-7xl mx-auto px-6">
<SectionHeading title="关键功能模块展示" subtitle="直观、易用、专业的管理界面" />
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<div className="space-y-4">
<ScreenshotPlaceholder
label="资产全景视图"
description="展示资产总览、分类统计、分布情况。"
src="input_file_1.png"
/>
<div className="px-2">
<h4 className="font-bold text-slate-900">1. </h4>
<p className="text-sm text-slate-500"></p>
</div>
</div>
<div className="space-y-4">
<ScreenshotPlaceholder
label="资产详情卡片"
description="展示单个资产的全息档案。"
src="input_file_0.png"
/>
<div className="px-2">
<h4 className="font-bold text-slate-900">2. </h4>
<p className="text-sm text-slate-500"></p>
</div>
</div>
<div className="space-y-4">
<ScreenshotPlaceholder
label="业务流程引擎"
description="展示资产流转的自动化审批。"
src="input_file_3.png"
/>
<div className="px-2">
<h4 className="font-bold text-slate-900">3. </h4>
<p className="text-sm text-slate-500"></p>
</div>
</div>
<div className="space-y-4">
<ScreenshotPlaceholder
label="移动端操作"
description="现场扫码盘点或操作。"
type="mobile"
src="input_file_4.png"
/>
<div className="px-2 text-center">
<h4 className="font-bold text-slate-900">4. </h4>
<p className="text-sm text-slate-500">便</p>
</div>
</div>
<div className="space-y-4 md:col-span-2">
<ScreenshotPlaceholder
label="报表与导出"
description="数据统计分析能力。"
src="input_file_2.png"
/>
<div className="px-2">
<h4 className="font-bold text-slate-900">5. </h4>
<p className="text-sm text-slate-500">Excel功能</p>
</div>
</div>
</div>
</section>
{/* Security */}
<section className="max-w-5xl mx-auto px-6">
<div className="bg-slate-900 rounded-[40px] p-12 text-white flex flex-col md:flex-row items-center gap-12">
<div className="w-24 h-24 bg-blue-600 rounded-3xl flex items-center justify-center flex-shrink-0">
<ShieldCheck size={48} />
</div>
<div>
<h3 className="text-3xl font-bold mb-4"></h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-8">
<div>
<h4 className="text-blue-400 font-bold mb-2"></h4>
<p className="text-slate-400 text-sm leading-relaxed">OneOS平台的安全机制</p>
</div>
<div>
<h4 className="text-blue-400 font-bold mb-2"></h4>
<p className="text-slate-400 text-sm leading-relaxed">RBAC权限管理</p>
</div>
</div>
</div>
</div>
</section>
</div>
);
};
const VehicleRentalSystem = () => {
return (
<div className="space-y-32 pb-20">
<Hero
badge="业务能力全景介绍"
title="车辆租赁业务管理系统"
subtitle="覆盖租赁全生命周期,从业务源头到资金结算的端到端闭环管理,保障业务安全、高效、可追溯。"
/>
{/* Business Cycle */}
<section className="max-w-7xl mx-auto px-6">
<SectionHeading title="业务闭环:覆盖租赁全生命周期" />
@@ -412,7 +325,7 @@ const VehicleRentalSystem = () => {
{ icon: Settings, title: "资金结算", desc: "账务闭环。自动化生成应收应付账单,实现费用、违章、保险等精准核算。" }
].map((step, i) => (
<div key={i} className="bg-white p-8 rounded-3xl border border-slate-100 shadow-sm text-center">
<div className="w-16 h-16 bg-blue-600 text-white rounded-2xl flex items-center justify-center mx-auto mb-6 shadow-lg shadow-blue-100">
<div className="w-16 h-16 bg-brand text-white rounded-2xl flex items-center justify-center mx-auto mb-6 shadow-lg shadow-brand-muted">
<step.icon size={32} />
</div>
<h3 className="text-xl font-bold text-slate-900 mb-3">{step.title}</h3>
@@ -453,12 +366,12 @@ const VehicleRentalSystem = () => {
<div key={i} className="bg-white p-10 rounded-[32px] border border-slate-200 shadow-sm">
<div className="flex items-center justify-between mb-6">
<h3 className="text-2xl font-bold text-slate-900">{mod.title}</h3>
<span className="px-3 py-1 bg-blue-50 text-blue-600 text-[10px] font-black uppercase rounded-full tracking-wider">{mod.tag}</span>
<span className="px-3 py-1 bg-brand-light text-brand text-[10px] font-black uppercase rounded-full tracking-wider">{mod.tag}</span>
</div>
<ul className="space-y-4">
{mod.items.map((item, j) => (
<li key={j} className="flex gap-3 text-slate-600 text-sm">
<div className="mt-1 flex-shrink-0 w-4 h-4 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center">
<div className="mt-1 flex-shrink-0 w-4 h-4 rounded-full bg-brand-light text-brand flex items-center justify-center">
<ChevronRight size={10} />
</div>
{item}
@@ -471,60 +384,161 @@ const VehicleRentalSystem = () => {
</div>
</section>
{/* Why Choose Us */}
{/* Modules Showcase */}
<section className="max-w-7xl mx-auto px-6">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-center">
<div>
<SectionHeading
centered={false}
title="为什么选择我们的系统?"
subtitle="将复杂的租赁流程固化到系统中,降低风险,提升效率。"
<SectionHeading title="关键功能模块展示" subtitle="直观、易用、专业的管理界面" />
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
{/* 01 工作台 */}
<div className="space-y-6">
<ScreenshotPlaceholder
label="工作台"
description="任务流程一屏统管,业务处理高效协同。"
src="/assets/screenshots/01.jpg"
onClick={() => setSelectedImage("/assets/screenshots/01.jpg")}
/>
<div className="space-y-8">
{[
{ title: "业务流程标准化", desc: "降低人为操作失误风险,确保业务合规。" },
{ title: "资产安全保障", desc: "验车拍照、GPS监控、违章预警全方位保护。" },
{ title: "资金管理零误差", desc: "自动化计费与结算,每一笔收入支出清晰可查。" },
{ title: "数据驱动增长", desc: "洞察业务瓶颈,优化运营策略。" }
].map((item, i) => (
<div key={i} className="flex gap-4">
<div className="w-12 h-12 bg-slate-900 text-white rounded-2xl flex items-center justify-center flex-shrink-0">
<Zap size={20} />
</div>
<div>
<h4 className="text-lg font-bold text-slate-900">{item.title}</h4>
<p className="text-slate-500 text-sm">{item.desc}</p>
</div>
</div>
))}
<div className="px-2">
<h4 className="text-xl font-bold text-slate-900 mb-2">01. </h4>
<p className="text-brand font-medium mb-3"></p>
<p className="text-slate-500 text-sm leading-relaxed">
</p>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-4 pt-12">
<ScreenshotPlaceholder
label="移动端验车"
description="拍照上传,电子存证"
type="mobile"
src="input_file_5.png"
/>
<ScreenshotPlaceholder
label="车辆状态看板"
description="实时掌握车队动态"
src="input_file_0.png"
/>
{/* 02 车辆档案 */}
<div className="space-y-6">
<ScreenshotPlaceholder
label="车辆全生命周期档案"
description="一屏掌控所有细节"
src="/assets/screenshots/02.jpg"
onClick={() => setSelectedImage("/assets/screenshots/02.jpg")}
/>
<div className="px-2">
<h4 className="text-xl font-bold text-slate-900 mb-2">02. </h4>
<p className="text-brand font-medium mb-3"></p>
<p className="text-slate-500 text-sm leading-relaxed">
</p>
</div>
<div className="space-y-4">
<ScreenshotPlaceholder
label="合同审批流"
description="流程可视化"
src="input_file_3.png"
/>
<ScreenshotPlaceholder
label="结算报表"
description="一键生成账单"
type="mobile"
src="input_file_6.png"
/>
</div>
{/* 03 业务闭环 */}
<div className="space-y-6">
<ScreenshotPlaceholder
label="全链路业务闭环"
description="覆盖车辆运营全生命周期"
src="/assets/screenshots/03.jpg"
onClick={() => setSelectedImage("/assets/screenshots/03.jpg")}
/>
<div className="px-2">
<h4 className="text-xl font-bold text-slate-900 mb-2">03. </h4>
<p className="text-brand font-medium mb-3"></p>
<p className="text-slate-500 text-sm leading-relaxed">
</p>
</div>
</div>
{/* 04 结算体系 */}
<div className="space-y-6">
<ScreenshotPlaceholder
label="费用明细透明可视"
description="构建信任结算体系"
src="/assets/screenshots/04.png"
onClick={() => setSelectedImage("/assets/screenshots/04.png")}
/>
<div className="px-2">
<h4 className="text-xl font-bold text-slate-900 mb-2">04. </h4>
<p className="text-brand font-medium mb-3"></p>
<p className="text-slate-500 text-sm leading-relaxed">
ETC补缴
</p>
</div>
</div>
{/* 05 移动小程序 */}
<div className="md:col-span-2 bg-slate-50 rounded-[40px] p-8 md:p-12 overflow-hidden">
<div className="max-w-4xl mb-12">
<h4 className="text-2xl font-bold text-slate-900 mb-4">05. </h4>
<p className="text-brand text-lg font-medium mb-4"></p>
<p className="text-slate-500 leading-relaxed mb-4">
线
</p>
</div>
<div className="relative group/scroll">
<div
id="mobile-scroll-container"
className="flex gap-6 overflow-x-auto pb-8 snap-x no-scrollbar scroll-smooth"
>
{[
{ src: "/assets/screenshots/05.png", label: "首页概览" },
{ src: "/assets/screenshots/06.png", label: "验车流程" },
{ src: "/assets/screenshots/07.png", label: "费用录入" },
{ src: "/assets/screenshots/08.png", label: "任务列表" },
{ src: "/assets/screenshots/09.png", label: "个人中心" },
{ src: "/assets/screenshots/05.png", label: "消息通知" },
{ src: "/assets/screenshots/06.png", label: "系统设置" },
{ src: "/assets/screenshots/07.png", label: "数据分析" },
{ src: "/assets/screenshots/08.png", label: "审批中心" },
{ src: "/assets/screenshots/09.png", label: "资产看板" },
].map((img, i) => (
<div key={i} className="flex-shrink-0 snap-center w-[240px] md:w-[280px]">
<ScreenshotPlaceholder
label={img.label}
description="移动端实时操作"
type="mobile"
src={img.src}
onClick={() => setSelectedImage(img.src)}
/>
</div>
))}
</div>
{/* Navigation Buttons */}
<button
onClick={() => {
const el = document.getElementById('mobile-scroll-container');
if (el) el.scrollBy({ left: -300, behavior: 'smooth' });
}}
className="absolute left-4 top-1/2 -translate-y-1/2 w-12 h-12 bg-white/90 backdrop-blur rounded-full shadow-xl flex items-center justify-center text-slate-900 hover:bg-brand hover:text-white transition-all opacity-0 group-hover/scroll:opacity-100 z-20"
>
<ChevronRight size={24} className="rotate-180" />
</button>
<button
onClick={() => {
const el = document.getElementById('mobile-scroll-container');
if (el) el.scrollBy({ left: 300, behavior: 'smooth' });
}}
className="absolute right-4 top-1/2 -translate-y-1/2 w-12 h-12 bg-white/90 backdrop-blur rounded-full shadow-xl flex items-center justify-center text-slate-900 hover:bg-brand hover:text-white transition-all opacity-0 group-hover/scroll:opacity-100 z-20"
>
<ChevronRight size={24} />
</button>
<div className="absolute left-0 top-0 bottom-8 w-20 bg-gradient-to-r from-slate-50 to-transparent pointer-events-none z-10" />
<div className="absolute right-0 top-0 bottom-8 w-20 bg-gradient-to-l from-slate-50 to-transparent pointer-events-none z-10" />
</div>
</div>
</div>
</section>
{/* Security */}
<section className="max-w-5xl mx-auto px-6">
<div className="bg-slate-900 rounded-[40px] p-12 text-white flex flex-col md:flex-row items-center gap-12">
<div className="w-24 h-24 bg-brand rounded-3xl flex items-center justify-center flex-shrink-0">
<ShieldCheck size={48} />
</div>
<div>
<h3 className="text-3xl font-bold mb-4"></h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-8">
<div>
<h4 className="text-brand-accent font-bold mb-2"></h4>
<p className="text-slate-400 text-sm leading-relaxed">OneOS平台的安全机制</p>
</div>
<div>
<h4 className="text-brand-accent font-bold mb-2"></h4>
<p className="text-slate-400 text-sm leading-relaxed">RBAC权限管理</p>
</div>
</div>
</div>
</div>
@@ -537,16 +551,13 @@ const Footer = () => (
<footer className="bg-slate-50 border-t border-slate-200 py-20">
<div className="max-w-7xl mx-auto px-6">
<div className="flex flex-col md:flex-row justify-between items-center gap-8">
<div className="flex items-center gap-2">
<div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center text-white font-bold">1</div>
<span className="text-lg font-bold tracking-tight text-slate-900">OneOS <span className="text-blue-600">Solutions</span></span>
</div>
<p className="text-slate-500 text-sm">© 2026 OneOS . .</p>
<div className="flex gap-6">
<a href="#" className="text-slate-400 hover:text-blue-600 transition-colors"></a>
<a href="#" className="text-slate-400 hover:text-blue-600 transition-colors"></a>
<a href="#" className="text-slate-400 hover:text-blue-600 transition-colors"></a>
<div className="flex items-center gap-3">
<div className="h-8 flex items-center justify-center overflow-hidden">
<img src="/assets/screenshots/logo.png" alt="Logo" className="h-full w-auto object-contain" referrerPolicy="no-referrer" />
</div>
<span className="text-lg font-bold tracking-tight text-slate-900">OneOS <span className="text-brand">Solutions</span></span>
</div>
<p className="text-slate-500 text-sm">© 2026 OneOS . .</p>
</div>
</div>
</footer>
@@ -555,24 +566,12 @@ const Footer = () => (
// --- Main App ---
export default function App() {
const [activeTab, setActiveTab] = useState('asset');
return (
<div className="min-h-screen bg-white font-sans selection:bg-blue-100 selection:text-blue-600">
<Navbar activeTab={activeTab} setActiveTab={setActiveTab} />
<div className="min-h-screen bg-white font-sans selection:bg-brand-light selection:text-brand">
<Navbar />
<main>
<AnimatePresence mode="wait">
<motion.div
key={activeTab}
initial={{ opacity: 0, x: 10 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -10 }}
transition={{ duration: 0.4 }}
>
{activeTab === 'asset' ? <AssetManagementSystem /> : <VehicleRentalSystem />}
</motion.div>
</AnimatePresence>
<AssetManagementSystem />
</main>
<Footer />

View File

@@ -3,6 +3,10 @@
@theme {
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
--color-brand: #065f46;
--color-brand-light: #ecfdf5;
--color-brand-muted: #d1fae5;
--color-brand-accent: #10b981;
}
@layer base {
@@ -10,3 +14,13 @@
@apply antialiased text-slate-900;
}
}
@layer utilities {
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
}