优化数据结构和交互逻辑,添加方便编辑数据的机器人/参赛历史数据文件
This commit is contained in:
parent
d9da27ce1f
commit
c906a2c013
@ -1,10 +1,11 @@
|
||||
"use client"
|
||||
import { useState } from "react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { ArrowLeft } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
|
||||
import { robotsByYear } from "@/lib/robot-data"
|
||||
|
||||
export default function HistoryPage() {
|
||||
// 历届队员数据
|
||||
@ -120,54 +121,58 @@ export default function HistoryPage() {
|
||||
},
|
||||
]
|
||||
|
||||
// 历届机器人数据
|
||||
const robots = [
|
||||
{
|
||||
year: "2023-2024",
|
||||
models: [
|
||||
{
|
||||
name: "Sentinel MK-III",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
description: "我们的旗舰防御机器人,配备先进装甲板和360°旋转炮塔系统。",
|
||||
achievements: ["区域赛最佳设计奖", "全国赛技术挑战赛亚军"],
|
||||
},
|
||||
{
|
||||
name: "Striker X2",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
description: "高机动性攻击单元,设计用于快速交战和战略定位。",
|
||||
achievements: ["区域赛最佳性能奖"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
year: "2022-2023",
|
||||
models: [
|
||||
{
|
||||
name: "Sentinel MK-II",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
description: "Sentinel系列的第二代,增强了火力和防御能力。",
|
||||
achievements: ["全国赛最佳工程奖", "区域赛冠军"],
|
||||
},
|
||||
{
|
||||
name: "Scout Drone Alpha",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
description: "我们的第一款侦察无人机,提供战场情报和有限的攻击能力。",
|
||||
achievements: ["创新设计奖"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
year: "2021-2022",
|
||||
models: [
|
||||
{
|
||||
name: "Sentinel MK-I",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
description: "Sentinel系列的初代机型,为后续发展奠定了基础。",
|
||||
achievements: ["区域赛最佳新秀奖"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
// 使用 useState 来跟踪当前悬停的成员
|
||||
const [hoveredMember, setHoveredMember] = useState<number | null>(null)
|
||||
|
||||
// 成员卡片组件
|
||||
const MemberCard = ({ member, index }: { member: any; index: number }) => {
|
||||
const isHovered = hoveredMember === index
|
||||
|
||||
return (
|
||||
<div
|
||||
className="relative"
|
||||
onMouseEnter={() => setHoveredMember(index)}
|
||||
onMouseLeave={() => setHoveredMember(null)}
|
||||
>
|
||||
<div
|
||||
className={`border border-white/10 p-4 card-hover-effect text-center cursor-pointer transition-all duration-200 ${isHovered ? "bg-background/80" : ""}`}
|
||||
>
|
||||
<div className="w-20 h-20 rounded-full overflow-hidden mx-auto mb-3">
|
||||
<Image
|
||||
src={member.photo || "/placeholder.svg"}
|
||||
alt={member.name}
|
||||
width={80}
|
||||
height={80}
|
||||
className="object-cover w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
<h4 className="font-bold">{member.name}</h4>
|
||||
<p className="text-xs text-muted-foreground">{member.role}</p>
|
||||
</div>
|
||||
|
||||
{/* 优化的扩展信息部分 - 更自然的动画 */}
|
||||
<div
|
||||
className={`absolute left-0 right-0 bg-primary/10 backdrop-blur-md border border-primary/30 p-4 transition-all duration-300 ease-out z-20 ${
|
||||
isHovered
|
||||
? "opacity-100 transform translate-y-0 scale-100"
|
||||
: "opacity-0 transform -translate-y-4 scale-95 pointer-events-none"
|
||||
}`}
|
||||
style={{
|
||||
top: "100%",
|
||||
transformOrigin: "top center",
|
||||
}}
|
||||
>
|
||||
<div className="space-y-2">
|
||||
<h5 className="font-bold text-primary">{member.name} - 现状</h5>
|
||||
<p className="text-sm font-medium">{member.destination}</p>
|
||||
<div className="pt-2 border-t border-white/10">
|
||||
<p className="text-sm italic">"{member.message}"</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="min-h-screen bg-background">
|
||||
@ -186,61 +191,35 @@ export default function HistoryPage() {
|
||||
<section className="mb-16">
|
||||
<h2 className="text-2xl font-bold mb-6 border-l-4 border-primary pl-4">历届队员</h2>
|
||||
|
||||
{teamMembers.map((team, index) => (
|
||||
<div key={index} className="mb-12">
|
||||
{teamMembers.map((team, teamIndex) => (
|
||||
<div key={teamIndex} className="mb-12">
|
||||
<h3 className="text-xl font-bold mb-4 text-primary">{team.year} 赛季</h3>
|
||||
<p className="mb-4">队长: {team.captain}</p>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4">
|
||||
{team.members.map((member, idx) => (
|
||||
<TooltipProvider key={idx}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div className="border border-white/10 p-4 card-hover-effect text-center cursor-pointer">
|
||||
<div className="w-20 h-20 rounded-full overflow-hidden mx-auto mb-3">
|
||||
<Image
|
||||
src={member.photo || "/placeholder.svg"}
|
||||
alt={member.name}
|
||||
width={80}
|
||||
height={80}
|
||||
className="object-cover w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
<h4 className="font-bold">{member.name}</h4>
|
||||
<p className="text-xs text-muted-foreground">{member.role}</p>
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
side="right"
|
||||
className="max-w-xs p-4 bg-background/95 backdrop-blur-md border border-white/10"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
<h5 className="font-bold text-primary">{member.name} - 现状</h5>
|
||||
<p className="text-sm font-medium">{member.destination}</p>
|
||||
<div className="pt-2 border-t border-white/10">
|
||||
<p className="text-sm italic">"{member.message}"</p>
|
||||
</div>
|
||||
</div>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
{team.members.map((member, memberIndex) => (
|
||||
<MemberCard
|
||||
key={memberIndex}
|
||||
member={member}
|
||||
index={teamIndex * 100 + memberIndex} // 创建唯一索引
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
|
||||
{/* 历届机器人部分 */}
|
||||
{/* 历届机器人部分 - 使用共享数据 */}
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold mb-6 border-l-4 border-primary pl-4">历届机器人</h2>
|
||||
|
||||
{robots.map((year, index) => (
|
||||
{robotsByYear.map((year, index) => (
|
||||
<div key={index} className="mb-12">
|
||||
<h3 className="text-xl font-bold mb-4 text-primary">{year.year} 赛季机器人</h3>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{year.models.map((robot, idx) => (
|
||||
<Card key={idx} className="border-white/10 bg-background/60 backdrop-blur-sm card-hover-effect">
|
||||
{year.models.map((robot) => (
|
||||
<Card key={robot.id} className="border-white/10 bg-background/60 backdrop-blur-sm card-hover-effect">
|
||||
<CardHeader>
|
||||
<CardTitle>{robot.name}</CardTitle>
|
||||
</CardHeader>
|
||||
@ -265,6 +244,13 @@ export default function HistoryPage() {
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<Link href={`/robots#${robot.id}`}>
|
||||
<Button variant="outline" size="sm" className="w-full border-white/10 button-hover-effect">
|
||||
查看详情
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
|
@ -19,9 +19,7 @@ const notoSansSC = Noto_Sans_SC({
|
||||
export const metadata: Metadata = {
|
||||
title: "Simba Robotics | RoboMaster Team",
|
||||
description:
|
||||
"Simba Robotics official website, a competitive robotics team participating in the RoboMaster competition.",
|
||||
generator: 'v0.dev'
|
||||
}
|
||||
"Simba Robotics 是来自黑龙江大学的 RoboMaster 竞赛团队,致力于推动机器人技术的创新与发展。我们专注于设计和开发高性能的机器人系统,参与国内外各类机器人竞赛。",}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
@ -41,6 +39,3 @@ export default function RootLayout({
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
import './globals.css'
|
23
app/privacy/layout.tsx
Normal file
23
app/privacy/layout.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import type React from "react"
|
||||
import type { Metadata } from "next"
|
||||
import Header from "@/components/header"
|
||||
import Footer from "@/components/footer"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Privacy Policy | Simba Robotics",
|
||||
description: "Privacy policy for Simba Robotics website and services.",
|
||||
}
|
||||
|
||||
export default function PrivacyLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>) {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
{children}
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
}
|
95
app/privacy/page.tsx
Normal file
95
app/privacy/page.tsx
Normal file
@ -0,0 +1,95 @@
|
||||
import Link from "next/link"
|
||||
import { ArrowLeft } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
export default function PrivacyPolicy() {
|
||||
return (
|
||||
<main className="min-h-screen bg-background pt-16">
|
||||
<div className="container mx-auto px-4 py-16">
|
||||
<div className="mb-8">
|
||||
<Link href="/">
|
||||
<Button variant="ghost" className="button-hover-effect mb-4">
|
||||
<ArrowLeft className="mr-2 h-4 w-4" /> 返回首页
|
||||
</Button>
|
||||
</Link>
|
||||
<h1 className="text-4xl font-bold mb-2">隐私政策</h1>
|
||||
<p className="text-muted-foreground">最后更新: 2023年12月1日</p>
|
||||
</div>
|
||||
|
||||
<div className="prose prose-invert max-w-none">
|
||||
<p>
|
||||
Simba
|
||||
Robotics(以下简称"我们")非常重视您的隐私。本隐私政策旨在向您说明我们如何收集、使用、披露和保护您的个人信息。
|
||||
</p>
|
||||
|
||||
<h2>信息收集</h2>
|
||||
<p>我们可能会收集以下类型的信息:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>个人识别信息</strong>
|
||||
:当您与我们联系、申请加入团队或参与我们的活动时,我们可能会收集您的姓名、电子邮件地址、电话号码和教育背景等信息。
|
||||
</li>
|
||||
<li>
|
||||
<strong>使用数据</strong>
|
||||
:我们可能会收集有关您如何访问和使用我们网站的信息,包括您的IP地址、浏览器类型、访问时间以及您查看的页面。
|
||||
</li>
|
||||
<li>
|
||||
<strong>设备信息</strong>
|
||||
:我们可能会收集有关您用于访问我们网站的设备的信息,包括硬件型号、操作系统和版本、唯一设备标识符等。
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>信息使用</h2>
|
||||
<p>我们可能会将收集到的信息用于以下目的:</p>
|
||||
<ul>
|
||||
<li>提供、维护和改进我们的网站和服务</li>
|
||||
<li>处理您的团队申请或其他请求</li>
|
||||
<li>发送与团队活动、比赛和招募相关的通知</li>
|
||||
<li>监控和分析网站使用情况和趋势</li>
|
||||
<li>检测、预防和解决技术问题</li>
|
||||
</ul>
|
||||
|
||||
<h2>信息共享</h2>
|
||||
<p>我们不会出售或出租您的个人信息给第三方。但在以下情况下,我们可能会共享您的信息:</p>
|
||||
<ul>
|
||||
<li>经您同意</li>
|
||||
<li>遵守法律要求</li>
|
||||
<li>保护我们的权利和财产</li>
|
||||
<li>与我们的合作伙伴共享,以支持我们的运营(这些合作伙伴有义务保密您的信息)</li>
|
||||
</ul>
|
||||
|
||||
<h2>数据安全</h2>
|
||||
<p>
|
||||
我们采取合理的措施来保护您的个人信息不被未经授权的访问、使用或披露。然而,请注意,互联网上的数据传输或电子存储不是100%安全的。
|
||||
</p>
|
||||
|
||||
<h2>Cookie使用</h2>
|
||||
<p>
|
||||
我们的网站可能使用"cookies"来增强用户体验。您的网络浏览器将这些cookies放在您的硬盘上以记录目的。您可以选择拒绝cookies,但这可能会影响您使用我们网站的某些部分。
|
||||
</p>
|
||||
|
||||
<h2>第三方链接</h2>
|
||||
<p>
|
||||
我们的网站可能包含指向第三方网站的链接。我们对这些网站的隐私政策或内容不负责任。我们建议您阅读您访问的任何第三方网站的隐私政策。
|
||||
</p>
|
||||
|
||||
<h2>儿童隐私</h2>
|
||||
<p>
|
||||
我们的网站不针对13岁以下的儿童。我们不会故意收集13岁以下儿童的个人识别信息。如果您是父母或监护人,并且您认为您的孩子向我们提供了个人信息,请联系我们。
|
||||
</p>
|
||||
|
||||
<h2>隐私政策的变更</h2>
|
||||
<p>我们可能会不时更新我们的隐私政策。我们会在本页上发布任何更改,并在重大更改时通过电子邮件或网站通知您。</p>
|
||||
|
||||
<h2>联系我们</h2>
|
||||
<p>如果您对本隐私政策有任何疑问,请通过以下方式联系我们:</p>
|
||||
<p>
|
||||
<strong>电子邮件</strong>:contact@simbarobotics.com
|
||||
<br />
|
||||
<strong>地址</strong>:Room 602, Physics Building, Heilongjiang University
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
23
app/robots/layout.tsx
Normal file
23
app/robots/layout.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import type React from "react"
|
||||
import type { Metadata } from "next"
|
||||
import Header from "@/components/header"
|
||||
import Footer from "@/components/footer"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Robots | Simba Robotics",
|
||||
description: "Explore the robots developed by Simba Robotics team for RoboMaster competitions.",
|
||||
}
|
||||
|
||||
export default function RobotsLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>) {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
{children}
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
}
|
3
app/robots/loading.tsx
Normal file
3
app/robots/loading.tsx
Normal file
@ -0,0 +1,3 @@
|
||||
export default function Loading() {
|
||||
return null
|
||||
}
|
138
app/robots/page.tsx
Normal file
138
app/robots/page.tsx
Normal file
@ -0,0 +1,138 @@
|
||||
"use client"
|
||||
import { useEffect, useRef } from "react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { useSearchParams } from "next/navigation"
|
||||
import { ArrowLeft } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import { robots } from "@/lib/robot-data"
|
||||
|
||||
export default function RobotsPage() {
|
||||
const searchParams = useSearchParams()
|
||||
const highlightedRobot = searchParams.get("highlight")
|
||||
const robotRefs = useRef<{ [key: string]: HTMLDivElement | null }>({})
|
||||
|
||||
// 滚动到高亮的机器人
|
||||
useEffect(() => {
|
||||
if (highlightedRobot && robotRefs.current[highlightedRobot]) {
|
||||
robotRefs.current[highlightedRobot]?.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "start",
|
||||
})
|
||||
}
|
||||
}, [highlightedRobot])
|
||||
|
||||
return (
|
||||
<main className="min-h-screen bg-background pt-16">
|
||||
<div className="container mx-auto px-4 py-16">
|
||||
<div className="mb-8">
|
||||
<Link href="/">
|
||||
<Button variant="ghost" className="button-hover-effect mb-4">
|
||||
<ArrowLeft className="mr-2 h-4 w-4" /> 返回首页
|
||||
</Button>
|
||||
</Link>
|
||||
<h1 className="text-4xl font-bold mb-2">机器人展示</h1>
|
||||
<p className="text-muted-foreground">探索 Simba Robotics 为 RoboMaster 竞赛开发的机器人</p>
|
||||
</div>
|
||||
|
||||
{/* 机器人列表 */}
|
||||
<div className="space-y-16">
|
||||
{robots.map((robot) => (
|
||||
<div
|
||||
key={robot.id}
|
||||
id={robot.id}
|
||||
ref={(el) => (robotRefs.current[robot.id] = el)}
|
||||
className={`scroll-mt-24 ${highlightedRobot === robot.id ? "ring-2 ring-primary p-4" : ""}`}
|
||||
>
|
||||
<div className="flex flex-col lg:flex-row gap-8">
|
||||
<div className="lg:w-1/2">
|
||||
<div className="relative">
|
||||
<div className="absolute -inset-4 bg-primary/10 blur-xl"></div>
|
||||
<div className="overflow-hidden border border-white/10 relative z-10">
|
||||
<Image
|
||||
src={robot.image || "/placeholder.svg"}
|
||||
alt={robot.name}
|
||||
width={600}
|
||||
height={400}
|
||||
className="w-full h-auto"
|
||||
/>
|
||||
<div className="absolute top-0 right-0 bg-primary text-primary-foreground text-xs px-3 py-1">
|
||||
{robot.category}
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-0 p-4">
|
||||
<p className="text-xs text-primary font-mono">{robot.year}</p>
|
||||
<h3 className="text-xl font-bold">{robot.name}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4 mt-4">
|
||||
{robot.gallery.map((image, idx) => (
|
||||
<div key={idx} className="overflow-hidden border border-white/10 card-hover-effect">
|
||||
<Image
|
||||
src={image || "/placeholder.svg"}
|
||||
alt={`${robot.name} gallery ${idx + 1}`}
|
||||
width={300}
|
||||
height={200}
|
||||
className="w-full h-auto"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="lg:w-1/2">
|
||||
<h2 className="text-3xl font-bold mb-4">{robot.name}</h2>
|
||||
<p className="text-muted-foreground mb-6 leading-relaxed">{robot.description}</p>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
||||
{robot.specs.map((spec, idx) => (
|
||||
<Card key={idx} className="border-white/10 bg-background/60 backdrop-blur-sm card-hover-effect">
|
||||
<CardContent className="p-4 flex flex-col items-center text-center">
|
||||
<div className="p-2 bg-primary/10 rounded-full mb-2">{spec.icon}</div>
|
||||
<h4 className="text-xs font-bold">{spec.name}</h4>
|
||||
<p className="text-sm text-muted-foreground">{spec.value}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mb-6">
|
||||
<h3 className="font-bold mb-2 text-primary">主要特点:</h3>
|
||||
<ul className="space-y-1 pl-5 list-disc text-muted-foreground">
|
||||
{robot.features.map((feature, idx) => (
|
||||
<li key={idx}>{feature}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="mb-6">
|
||||
<h3 className="font-bold mb-2 text-primary">获得荣誉:</h3>
|
||||
<ul className="space-y-1 pl-5 list-disc text-muted-foreground">
|
||||
{robot.achievements.map((achievement, idx) => (
|
||||
<li key={idx}>{achievement}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="font-bold mb-2 text-primary">开发团队:</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{robot.team.map((member, idx) => (
|
||||
<div key={idx} className="px-3 py-1 bg-primary/10 text-sm flex items-center gap-1">
|
||||
<span>{member.name}</span>
|
||||
<span className="text-xs text-muted-foreground">({member.role})</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
23
app/teams/layout.tsx
Normal file
23
app/teams/layout.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import type React from "react"
|
||||
import type { Metadata } from "next"
|
||||
import Header from "@/components/header"
|
||||
import Footer from "@/components/footer"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Team Groups | Simba Robotics",
|
||||
description: "Learn more about the specialized groups within Simba Robotics team.",
|
||||
}
|
||||
|
||||
export default function TeamsLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>) {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
{children}
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
}
|
260
app/teams/page.tsx
Normal file
260
app/teams/page.tsx
Normal file
@ -0,0 +1,260 @@
|
||||
"use client"
|
||||
import { useState } from "react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { ArrowLeft } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
|
||||
export default function TeamsPage() {
|
||||
const [activeTab, setActiveTab] = useState("mest")
|
||||
|
||||
const teams = [
|
||||
{
|
||||
id: "mest",
|
||||
name: "机械架构组",
|
||||
code: "MEST",
|
||||
icon: "/icons/mest.svg",
|
||||
description:
|
||||
"机械架构组负责设计和制造机器人的物理结构,包括底盘、武器系统和机械部件。我们的工作是机器人的骨骼和肌肉,确保它们能够承受比赛中的各种挑战。",
|
||||
responsibilities: ["3D 建模与 CAD 出图", "CNC 加工制造", "机械结构分析与优化", "结构装配与测试"],
|
||||
projects: [
|
||||
{
|
||||
title: "轻量化底盘设计",
|
||||
description: "通过拓扑优化和材料选择,减轻机器人底盘重量30%,同时保持结构强度。",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
},
|
||||
{
|
||||
title: "模块化武器系统",
|
||||
description: "开发可快速更换的模块化武器系统,适应不同比赛场景和对手特点。",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
},
|
||||
],
|
||||
skills: ["SolidWorks", "AutoCAD", "有限元分析", "材料学", "加工工艺", "3D打印"],
|
||||
members: [
|
||||
{
|
||||
name: "彭戈",
|
||||
role: "组长",
|
||||
photo: "/placeholder.svg?height=100&width=100",
|
||||
},
|
||||
{
|
||||
name: "闫芃森",
|
||||
role: "机械工程师",
|
||||
photo: "/placeholder.svg?height=100&width=100",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "elct",
|
||||
name: "电传测控组",
|
||||
code: "ELCT",
|
||||
icon: "/icons/elct.svg",
|
||||
description:
|
||||
"电传测控组开发机器人的配电与控制系统,涵盖电路设计、功率管理和嵌入式开发。我们是机器人的神经系统,使其能够感知环境并执行精确动作。",
|
||||
responsibilities: [
|
||||
"电路设计与 PCB Layout",
|
||||
"功率管理系统设计",
|
||||
"电机控制和驱动开发",
|
||||
"传感器集成与信号处理",
|
||||
"控制理论应用",
|
||||
],
|
||||
projects: [
|
||||
{
|
||||
title: "高效功率管理系统",
|
||||
description: "设计能够优化电池使用的功率管理系统,延长机器人作战时间20%。",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
},
|
||||
{
|
||||
title: "实时控制系统",
|
||||
description: "基于STM32的实时控制系统,实现毫秒级响应和精确的运动控制。",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
},
|
||||
],
|
||||
skills: ["电路设计", "PCB Layout", "嵌入式编程", "控制理论", "信号处理", "RTOS"],
|
||||
members: [
|
||||
{
|
||||
name: "陈卓文",
|
||||
role: "组长",
|
||||
photo: "/placeholder.svg?height=100&width=100",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "vsag",
|
||||
name: "视觉算法组",
|
||||
code: "VSAG",
|
||||
icon: "/icons/vsag.svg",
|
||||
description:
|
||||
"视觉算法组开发计算机视觉和人工智能系统,使机器人能够感知和理解周围环境,实现自主操作。我们是机器人的眼睛和大脑,赋予它智能决策能力。",
|
||||
responsibilities: ["计算机视觉算法开发", "对象识别与跟踪", "机器学习模型训练", "实时图像处理优化"],
|
||||
projects: [
|
||||
{
|
||||
title: "实时目标检测系统",
|
||||
description: "基于深度学习的目标检测系统,能够在复杂背景下识别和跟踪对手机器人。",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
},
|
||||
{
|
||||
title: "自主导航算法",
|
||||
description: "结合视觉和传感器数据的自主导航算法,使机器人能够在场地中精确定位和规划路径。",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
},
|
||||
],
|
||||
skills: ["Python", "OpenCV", "TensorFlow/PyTorch", "SLAM", "ROS", "C++"],
|
||||
members: [
|
||||
{
|
||||
name: "黄瑞",
|
||||
role: "组长",
|
||||
photo: "/placeholder.svg?height=100&width=100",
|
||||
},
|
||||
{
|
||||
name: "韩翔宇",
|
||||
role: "视觉工程师",
|
||||
photo: "/placeholder.svg?height=100&width=100",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "pram",
|
||||
name: "宣传筹划组",
|
||||
code: "PRAM",
|
||||
icon: "/icons/pram.svg",
|
||||
description:
|
||||
"宣传筹划组管理团队品牌、文档、社交媒体和外联工作,以宣传我们的团队并获得赞助,并规划赛季任务、维护战队开发环境。我们是团队的声音和桥梁。",
|
||||
responsibilities: ["平面与视觉设计", "社交媒体运营", "招商引资", "战队开发平台运维与项目管理"],
|
||||
projects: [
|
||||
{
|
||||
title: "品牌重塑计划",
|
||||
description: "重新设计团队视觉识别系统,提升品牌形象和认知度。",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
},
|
||||
{
|
||||
title: "赞助合作项目",
|
||||
description: "与多家企业建立赞助合作关系,为团队提供资金和技术支持。",
|
||||
image: "/placeholder.svg?height=300&width=400",
|
||||
},
|
||||
],
|
||||
skills: ["平面设计", "内容创作", "项目管理", "商务谈判", "社交媒体运营", "活动策划"],
|
||||
members: [
|
||||
{
|
||||
name: "李佳睿",
|
||||
role: "组长",
|
||||
photo: "/placeholder.svg?height=100&width=100",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const activeTeam = teams.find((team) => team.id === activeTab) || teams[0]
|
||||
|
||||
return (
|
||||
<main className="min-h-screen bg-background pt-16">
|
||||
<div className="container mx-auto px-4 py-16">
|
||||
<div className="mb-8">
|
||||
<Link href="/">
|
||||
<Button variant="ghost" className="button-hover-effect mb-4">
|
||||
<ArrowLeft className="mr-2 h-4 w-4" /> 返回首页
|
||||
</Button>
|
||||
</Link>
|
||||
<h1 className="text-4xl font-bold mb-2">团队小组</h1>
|
||||
<p className="text-muted-foreground">了解 Simba Robotics 各专业小组的详细信息</p>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="mest" value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||
<TabsList className="grid grid-cols-2 md:grid-cols-4 gap-2 bg-transparent">
|
||||
{teams.map((team) => (
|
||||
<TabsTrigger
|
||||
key={team.id}
|
||||
value={team.id}
|
||||
className="data-[state=active]:bg-primary/20 data-[state=active]:text-primary border border-white/10"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Image src={team.icon || "/placeholder.svg"} alt={team.name} width={24} height={24} />
|
||||
<span className="hidden md:inline">{team.name}</span>
|
||||
<span className="md:hidden">{team.code}</span>
|
||||
</div>
|
||||
</TabsTrigger>
|
||||
))}
|
||||
</TabsList>
|
||||
|
||||
<div className="mt-8 border border-white/10 p-6 card-hover-effect">
|
||||
<div className="flex flex-col md:flex-row gap-6 items-start">
|
||||
<div className="md:w-1/3">
|
||||
<div className="flex items-center gap-4 mb-6">
|
||||
<div className="p-4 bg-primary/10">
|
||||
<Image src={activeTeam.icon || "/placeholder.svg"} alt={activeTeam.name} width={48} height={48} />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold">{activeTeam.name}</h2>
|
||||
<p className="text-sm font-mono text-primary">{activeTeam.code}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-muted-foreground mb-6 leading-relaxed">{activeTeam.description}</p>
|
||||
|
||||
<div className="mb-6">
|
||||
<h3 className="font-bold mb-2 text-primary">核心职责:</h3>
|
||||
<ul className="space-y-1 pl-5 list-disc text-muted-foreground">
|
||||
{activeTeam.responsibilities.map((item, idx) => (
|
||||
<li key={idx}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="font-bold mb-2 text-primary">技能要求:</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{activeTeam.skills.map((skill, idx) => (
|
||||
<span key={idx} className="px-2 py-1 bg-primary/10 text-xs rounded-sm">
|
||||
{skill}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="md:w-2/3">
|
||||
<h3 className="text-xl font-bold mb-4 border-l-4 border-primary pl-4">代表项目</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8">
|
||||
{activeTeam.projects.map((project, idx) => (
|
||||
<div key={idx} className="border border-white/10 overflow-hidden card-hover-effect">
|
||||
<Image
|
||||
src={project.image || "/placeholder.svg"}
|
||||
alt={project.title}
|
||||
width={400}
|
||||
height={300}
|
||||
className="w-full h-48 object-cover"
|
||||
/>
|
||||
<div className="p-4">
|
||||
<h4 className="font-bold mb-2">{project.title}</h4>
|
||||
<p className="text-sm text-muted-foreground">{project.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h3 className="text-xl font-bold mb-4 border-l-4 border-primary pl-4">小组成员</h3>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
{activeTeam.members.map((member, idx) => (
|
||||
<div key={idx} className="border border-white/10 p-4 text-center card-hover-effect">
|
||||
<div className="w-16 h-16 rounded-full overflow-hidden mx-auto mb-2">
|
||||
<Image
|
||||
src={member.photo || "/placeholder.svg"}
|
||||
alt={member.name}
|
||||
width={64}
|
||||
height={64}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<h4 className="font-bold">{member.name}</h4>
|
||||
<p className="text-xs text-muted-foreground">{member.role}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Tabs>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
23
app/terms/layout.tsx
Normal file
23
app/terms/layout.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import type React from "react"
|
||||
import type { Metadata } from "next"
|
||||
import Header from "@/components/header"
|
||||
import Footer from "@/components/footer"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Terms of Service | Simba Robotics",
|
||||
description: "Terms of service for Simba Robotics website and services.",
|
||||
}
|
||||
|
||||
export default function TermsLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>) {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
{children}
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
}
|
94
app/terms/page.tsx
Normal file
94
app/terms/page.tsx
Normal file
@ -0,0 +1,94 @@
|
||||
import Link from "next/link"
|
||||
import { ArrowLeft } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
export default function TermsOfService() {
|
||||
return (
|
||||
<main className="min-h-screen bg-background pt-16">
|
||||
<div className="container mx-auto px-4 py-16">
|
||||
<div className="mb-8">
|
||||
<Link href="/">
|
||||
<Button variant="ghost" className="button-hover-effect mb-4">
|
||||
<ArrowLeft className="mr-2 h-4 w-4" /> 返回首页
|
||||
</Button>
|
||||
</Link>
|
||||
<h1 className="text-4xl font-bold mb-2">服务条款</h1>
|
||||
<p className="text-muted-foreground">最后更新: 2025年4月19日</p>
|
||||
</div>
|
||||
|
||||
<div className="prose prose-invert max-w-none">
|
||||
<p>
|
||||
欢迎访问 Simba Robotics
|
||||
网站。请仔细阅读以下条款和条件,因为它们适用于您对我们网站的访问和使用。通过访问或使用我们的网站,您同意受这些条款的约束。如果您不同意这些条款,请不要使用我们的网站。
|
||||
</p>
|
||||
|
||||
<h2>使用许可</h2>
|
||||
<p>
|
||||
Simba Robotics
|
||||
授予您访问和个人使用本网站的有限许可,但不授予您下载(除缓存外)或修改网站或其任何部分的权利,除非获得我们的明确书面同意。此许可不包括:
|
||||
</p>
|
||||
<ul>
|
||||
<li>网站或其内容的商业使用</li>
|
||||
<li>网站内容的收集和使用</li>
|
||||
<li>对网站或其内容的任何衍生使用</li>
|
||||
<li>下载或复制账户信息</li>
|
||||
<li>使用数据挖掘、机器人或类似的数据收集和提取工具</li>
|
||||
</ul>
|
||||
<p>
|
||||
未经我们明确书面许可,您不得复制、复制、销售、转售、访问或以其他方式利用本网站或其任何部分用于任何商业目的。
|
||||
</p>
|
||||
|
||||
<h2>知识产权</h2>
|
||||
<p>
|
||||
本网站及其全部内容、功能和设计元素,包括但不限于文本、图形、徽标、图标、图像、音频剪辑、下载、数据编译、软件和代码,均为
|
||||
Simba Robotics 或其内容提供商的财产,受中国和国际版权、商标、专利、商业秘密和其他知识产权法律的保护。
|
||||
</p>
|
||||
|
||||
<h2>用户行为</h2>
|
||||
<p>您同意在使用我们的网站时:</p>
|
||||
<ul>
|
||||
<li>不会违反任何适用的法律或法规</li>
|
||||
<li>不会侵犯他人的权利</li>
|
||||
<li>不会干扰网站的正常运行</li>
|
||||
<li>不会尝试未经授权访问我们的系统</li>
|
||||
<li>不会引入病毒、特洛伊木马或其他有害材料</li>
|
||||
</ul>
|
||||
|
||||
<h2>免责声明</h2>
|
||||
<p>
|
||||
本网站及其内容按"原样"和"可用"的基础提供,没有任何形式的保证,无论是明示的还是暗示的。Simba Robotics
|
||||
不保证网站将无错误或不间断运行,也不保证缺陷将被纠正,或者网站或提供它的服务器没有病毒或其他有害成分。
|
||||
</p>
|
||||
|
||||
<h2>责任限制</h2>
|
||||
<p>
|
||||
在任何情况下,Simba Robotics
|
||||
及其管理人员、董事、员工或代理人都不对因使用或无法使用我们的网站或网站上的任何内容而导致的任何损害(包括但不限于直接、间接、附带、惩罚性和后果性损害)负责,无论是基于保证、合同、侵权还是任何其他法律理论,无论我们是否被告知此类损害的可能性。
|
||||
</p>
|
||||
|
||||
<h2>链接到第三方网站</h2>
|
||||
<p>
|
||||
我们的网站可能包含指向第三方网站的链接,这些网站不由 Simba Robotics
|
||||
拥有或控制。我们对这些网站的内容、隐私政策或做法不负责任,也不对其进行审查。您应该了解,当您离开我们的网站时,我们的条款和政策不再适用。
|
||||
</p>
|
||||
|
||||
<h2>条款变更</h2>
|
||||
<p>
|
||||
我们保留随时修改这些条款的权利。修改后的条款将在发布后立即生效。您继续使用网站将被视为接受修改后的条款。
|
||||
</p>
|
||||
|
||||
<h2>适用法律</h2>
|
||||
<p>这些条款和您与 Simba Robotics 之间的关系将受中华人民共和国法律管辖,不考虑其冲突法规定。</p>
|
||||
|
||||
<h2>联系我们</h2>
|
||||
<p>如果您对这些服务条款有任何疑问,请通过以下方式联系我们:</p>
|
||||
<p>
|
||||
<strong>电子邮件</strong>:contact@simba-robotics.com
|
||||
<br />
|
||||
<strong>地址</strong>:602 实验室, 电子工程学院, 黑龙江大学。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
@ -1,34 +1,8 @@
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Trophy, Medal, Award, Star } from "lucide-react"
|
||||
import Link from "next/link"
|
||||
import { achievements } from "@/lib/achievement-data"
|
||||
|
||||
export default function AchievementsSection() {
|
||||
const achievements = [
|
||||
{
|
||||
year: "2025",
|
||||
title: "RoboMaster 高校联盟赛 辽宁站",
|
||||
position: "三等奖",
|
||||
icon: <Award className="h-8 w-8 text-primary" />,
|
||||
description:
|
||||
"与 32 支来自辽宁周边城市的大学参赛队伍同台竞技,直接对阵的队伍有:哈尔滨工业大学 I Hiter 战队、北京邮电大学 鸿雁 战队、沈阳工业大学辽阳分校 赫兹矩阵战队。",
|
||||
},
|
||||
{
|
||||
year: "2024",
|
||||
title: "RoboMaster 高校联盟赛 山东站",
|
||||
position: "三等奖",
|
||||
icon: <Award className="h-8 w-8 text-primary" />,
|
||||
description:
|
||||
"与 32 支来自山东周边城市的大学参赛队伍同台竞技,直接对阵的队伍有:北方工业大学 DreamTeam 战队、哈尔滨工业大学威海 HERO 战队。",
|
||||
},
|
||||
{
|
||||
year: "2017",
|
||||
title: "RoboMaster 区域赛 东部赛区",
|
||||
position: "三等奖",
|
||||
icon: <Star className="h-8 w-8 text-primary" />,
|
||||
description:
|
||||
"与 29 支大学参赛队伍同台竞技。",
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<section id="achievements" className="py-20 relative overflow-hidden">
|
||||
<div className="absolute inset-0 grid-pattern opacity-20" />
|
||||
@ -52,22 +26,24 @@ export default function AchievementsSection() {
|
||||
<div className="md:w-2/3">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{achievements.map((achievement, index) => (
|
||||
<Card key={index} className="border-white/10 bg-background/60 backdrop-blur-sm card-hover-effect">
|
||||
<CardHeader className="flex flex-row items-center gap-4 pb-2 border-b border-white/10">
|
||||
<div className="p-2 bg-primary/10">{achievement.icon}</div>
|
||||
<div>
|
||||
<CardTitle className="text-xl">{achievement.title}</CardTitle>
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<span className="text-primary font-mono">{achievement.year}</span>
|
||||
<span>•</span>
|
||||
<span>{achievement.position}</span>
|
||||
<Link key={index} href={achievement.link} target="_blank" rel="noopener noreferrer">
|
||||
<Card className="border-white/10 bg-background/60 backdrop-blur-sm card-hover-effect transition-all duration-300 hover:translate-y-[-5px]">
|
||||
<CardHeader className="flex flex-row items-center gap-4 pb-2 border-b border-white/10">
|
||||
<div className="p-2 bg-primary/10">{achievement.icon}</div>
|
||||
<div>
|
||||
<CardTitle className="text-xl">{achievement.title}</CardTitle>
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<span className="text-primary font-mono">{achievement.year}</span>
|
||||
<span>•</span>
|
||||
<span>{achievement.position}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-4">
|
||||
<p className="text-muted-foreground leading-relaxed">{achievement.description}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-4">
|
||||
<p className="text-muted-foreground leading-relaxed">{achievement.description}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,20 +7,20 @@ export default function ContactSection() {
|
||||
const contactInfo = [
|
||||
{
|
||||
icon: <Mail className="h-5 w-5 text-primary" />,
|
||||
title: "邮件",
|
||||
title: "Email",
|
||||
details: "contact@simbarobotics.com",
|
||||
link: "mailto:contact@simbarobotics.com",
|
||||
},
|
||||
{
|
||||
icon: <Phone className="h-5 w-5 text-primary" />,
|
||||
title: "电话",
|
||||
details: "+86 139 3616 9908",
|
||||
link: "tel:+8613936169908",
|
||||
title: "Phone",
|
||||
details: "+1 (123) 456-7890",
|
||||
link: "tel:+11234567890",
|
||||
},
|
||||
{
|
||||
icon: <MapPin className="h-5 w-5 text-primary" />,
|
||||
title: "地址",
|
||||
details: "602实验室, 物理实验楼, 黑龙江大学",
|
||||
details: "602 实验室, 电子工程学院, 黑龙江大学",
|
||||
link: "https://www.bing.com/maps?&ty=18&q=%E9%BB%91%E9%BE%99%E6%B1%9F%E5%A4%A7%E5%AD%A6-%E7%94%B5%E5%AD%90%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2&ss=ypid.YN4067x5856225&mb=45.709873~126.616074~45.704718~126.624132&description=%E9%BB%91%E9%BE%99%E6%B1%9F%E7%9C%81%E5%93%88%E5%B0%94%E6%BB%A8%E5%B8%82%E5%AD%A6%E5%BA%9C%E8%B7%AF74%E5%8F%B7&cardbg=%23333333&dt=1744891200000&tt=%E9%BB%91%E9%BE%99%E6%B1%9F%E5%A4%A7%E5%AD%A6-%E7%94%B5%E5%AD%90%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2&tsts0=%2526ty%253D18%2526q%253D%2525E9%2525BB%252591%2525E9%2525BE%252599%2525E6%2525B1%25259F%2525E5%2525A4%2525A7%2525E5%2525AD%2525A6-%2525E7%252594%2525B5%2525E5%2525AD%252590%2525E5%2525B7%2525A5%2525E7%2525A8%25258B%2525E5%2525AD%2525A6%2525E9%252599%2525A2%2526ss%253Dypid.YN4067x5856225%2526mb%253D45.709873~126.616074~45.704718~126.624132%2526description%253D%2525E9%2525BB%252591%2525E9%2525BE%252599%2525E6%2525B1%25259F%2525E7%25259C%252581%2525E5%252593%252588%2525E5%2525B0%252594%2525E6%2525BB%2525A8%2525E5%2525B8%252582%2525E5%2525AD%2525A6%2525E5%2525BA%25259C%2525E8%2525B7%2525AF74%2525E5%25258F%2525B7%2526cardbg%253D%252523333333%2526dt%253D1744891200000&tstt0=%E9%BB%91%E9%BE%99%E6%B1%9F%E5%A4%A7%E5%AD%A6-%E7%94%B5%E5%AD%90%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2&cp=45.707282~126.619347&lvl=18.469374&pi=0&ftst=0&ftics=False&v=2&sV=2&form=S00027",
|
||||
},
|
||||
]
|
||||
@ -52,12 +52,7 @@ export default function ContactSection() {
|
||||
{
|
||||
icon: <MessageSquare className="h-5 w-5" />,
|
||||
name: "微信公众号",
|
||||
link: "#wechat-qrcode",
|
||||
onClick: (e: { preventDefault: () => void }) => {
|
||||
e.preventDefault()
|
||||
// 这里可以添加显示微信二维码的逻辑,例如打开一个模态框
|
||||
alert("扫描二维码关注我们的微信公众号:SimbaRobotics")
|
||||
},
|
||||
link: "https://weixin.qq.com/r/simbarobotics",
|
||||
},
|
||||
]
|
||||
|
||||
@ -109,7 +104,6 @@ export default function ContactSection() {
|
||||
rel="noopener noreferrer"
|
||||
className="p-3 bg-primary/10 hover:bg-primary/20 transition-colors card-hover-effect"
|
||||
aria-label={social.name}
|
||||
onClick={social.onClick}
|
||||
>
|
||||
{social.icon}
|
||||
</a>
|
||||
|
@ -95,10 +95,10 @@ export default function Footer() {
|
||||
<div className="border-t border-white/10 mt-12 pt-6 flex flex-col md:flex-row justify-between items-center">
|
||||
<p className="text-sm text-muted-foreground">© {currentYear} Simba Robotics. 保留一切权利。</p>
|
||||
<div className="flex gap-4 mt-4 md:mt-0">
|
||||
<Link href="#" className="text-xs text-muted-foreground hover:text-primary transition-colors">
|
||||
<Link href="/privacy" className="text-xs text-muted-foreground hover:text-primary transition-colors">
|
||||
隐私政策
|
||||
</Link>
|
||||
<Link href="#" className="text-xs text-muted-foreground hover:text-primary transition-colors">
|
||||
<Link href="/terms" className="text-xs text-muted-foreground hover:text-primary transition-colors">
|
||||
服务条款
|
||||
</Link>
|
||||
</div>
|
||||
|
@ -3,6 +3,7 @@
|
||||
import { useState, useEffect } from "react"
|
||||
import Link from "next/link"
|
||||
import Image from "next/image"
|
||||
import { usePathname } from "next/navigation"
|
||||
import { Menu, X } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { cn } from "@/lib/utils"
|
||||
@ -11,37 +12,42 @@ export default function Header() {
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false)
|
||||
const [scrolled, setScrolled] = useState(false)
|
||||
const [activeSection, setActiveSection] = useState("home")
|
||||
const pathname = usePathname()
|
||||
const isHomePage = pathname === "/"
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setScrolled(window.scrollY > 10)
|
||||
|
||||
// Determine active section based on scroll position
|
||||
const sections = ["home", "about", "team-groups", "achievements", "robots", "contact"]
|
||||
for (const section of sections.reverse()) {
|
||||
const element = document.getElementById(section)
|
||||
if (element && window.scrollY >= element.offsetTop - 100) {
|
||||
setActiveSection(section)
|
||||
break
|
||||
// 只在主页上确定活动部分
|
||||
if (isHomePage) {
|
||||
// Determine active section based on scroll position
|
||||
const sections = ["home", "about", "team-groups", "achievements", "robots", "contact"]
|
||||
for (const section of sections.reverse()) {
|
||||
const element = document.getElementById(section)
|
||||
if (element && window.scrollY >= element.offsetTop - 100) {
|
||||
setActiveSection(section)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", handleScroll)
|
||||
return () => window.removeEventListener("scroll", handleScroll)
|
||||
}, [])
|
||||
}, [isHomePage])
|
||||
|
||||
const toggleMenu = () => {
|
||||
setIsMenuOpen(!isMenuOpen)
|
||||
}
|
||||
|
||||
const navLinks = [
|
||||
{ name: "主页", href: "#home", id: "home", en: "INDEX" },
|
||||
{ name: "关于", href: "#about", id: "about", en: "INFORMATION" },
|
||||
{ name: "团队", href: "#team-groups", id: "team-groups", en: "OPERATOR" },
|
||||
{ name: "成就", href: "#achievements", id: "achievements", en: "GAMEPLAY" },
|
||||
{ name: "机器人", href: "#robots", id: "robots", en: "ROBOTS" },
|
||||
{ name: "联系我们", href: "#contact", id: "contact", en: "NEWS" },
|
||||
{ name: "主页", href: isHomePage ? "#home" : "/#home", id: "home", en: "INDEX" },
|
||||
{ name: "关于", href: isHomePage ? "#about" : "/#about", id: "about", en: "INFORMATION" },
|
||||
{ name: "团队", href: isHomePage ? "#team-groups" : "/#team-groups", id: "team-groups", en: "OPERATOR" },
|
||||
{ name: "成就", href: isHomePage ? "#achievements" : "/#achievements", id: "achievements", en: "GAMEPLAY" },
|
||||
{ name: "机器人", href: isHomePage ? "#robots" : "/#robots", id: "robots", en: "ROBOTS" },
|
||||
{ name: "联系我们", href: isHomePage ? "#contact" : "/#contact", id: "contact", en: "NEWS" },
|
||||
]
|
||||
|
||||
return (
|
||||
@ -68,7 +74,7 @@ export default function Header() {
|
||||
href={link.href}
|
||||
className={cn(
|
||||
"px-6 py-2 flex flex-col items-center text-sm transition-colors",
|
||||
activeSection === link.id
|
||||
isHomePage && activeSection === link.id
|
||||
? "text-foreground nav-active"
|
||||
: "text-muted-foreground hover:text-foreground",
|
||||
)}
|
||||
@ -97,7 +103,7 @@ export default function Header() {
|
||||
href={link.href}
|
||||
className={cn(
|
||||
"px-4 py-3 border-b border-border/30 transition-colors flex items-center justify-between",
|
||||
activeSection === link.id ? "text-primary" : "text-muted-foreground",
|
||||
isHomePage && activeSection === link.id ? "text-primary" : "text-muted-foreground",
|
||||
)}
|
||||
onClick={() => setIsMenuOpen(false)}
|
||||
>
|
||||
|
@ -2,52 +2,17 @@
|
||||
|
||||
import { useRef, useState, useEffect } from "react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { ChevronLeft, ChevronRight, Info } from "lucide-react"
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
|
||||
import { robots } from "@/lib/robot-data"
|
||||
|
||||
export default function RobotsShowcase() {
|
||||
const scrollContainerRef = useRef<HTMLDivElement>(null)
|
||||
const [activeIndex, setActiveIndex] = useState(0)
|
||||
|
||||
const robots = [
|
||||
{
|
||||
id: 1,
|
||||
name: "初号步兵",
|
||||
image: "/placeholder.svg?height=400&width=600",
|
||||
category: "INFANTRY",
|
||||
description:
|
||||
"Our flagship defense robot, equipped with advanced armor plating and a 360° rotating turret system.",
|
||||
specs: ["Weight: 15kg", "Max Speed: 3m/s", "Battery Life: 30min", "Weapon: Launcher"],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "初号英雄",
|
||||
image: "/placeholder.svg?height=400&width=600",
|
||||
category: "HERO",
|
||||
description: "High-mobility attack unit designed for rapid engagement and strategic positioning.",
|
||||
specs: ["Weight: 12kg", "Max Speed: 4.5m/s", "Battery Life: 25min", "Weapon: Dual Launcher System"],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "零号哨兵",
|
||||
image: "/placeholder.svg?height=400&width=600",
|
||||
category: "SENTRY",
|
||||
description:
|
||||
"Lightweight reconnaissance drone providing battlefield intelligence and limited attack capabilities.",
|
||||
specs: ["Weight: 2kg", "Max Speed: 10m/s", "Flight Time: 15min", "Sensors: 4K Camera, Infrared"],
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "零号工程",
|
||||
image: "/placeholder.svg?height=400&width=600",
|
||||
category: "ENGINEER",
|
||||
description: "Specialized support unit capable of on-field repairs and resource management during matches.",
|
||||
specs: ["Weight: 18kg", "Max Speed: 2m/s", "Battery Life: 40min", "Tools: Mechanical Arm, Repair Module"],
|
||||
},
|
||||
]
|
||||
|
||||
// 创建一个循环数组,用于无限滚动
|
||||
const displayRobots = [...robots]
|
||||
|
||||
@ -124,7 +89,7 @@ export default function RobotsShowcase() {
|
||||
<div className="relative">
|
||||
<Image
|
||||
src={robot.image || "/placeholder.svg"}
|
||||
alt={robot.name}
|
||||
alt={robot.displayName}
|
||||
width={350}
|
||||
height={200}
|
||||
className="w-full h-48 object-cover"
|
||||
@ -139,7 +104,7 @@ export default function RobotsShowcase() {
|
||||
|
||||
<div className="p-4">
|
||||
<div className="flex justify-between items-start mb-2">
|
||||
<h3 className="text-xl font-bold">{robot.name}</h3>
|
||||
<h3 className="text-xl font-bold">{robot.displayName}</h3>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
@ -151,7 +116,7 @@ export default function RobotsShowcase() {
|
||||
<div className="space-y-2">
|
||||
<p className="font-bold">技术参数:</p>
|
||||
<ul className="text-xs space-y-1">
|
||||
{robot.specs.map((spec, specIndex) => (
|
||||
{robot.simpleSpecs.map((spec, specIndex) => (
|
||||
<li key={specIndex}>{spec}</li>
|
||||
))}
|
||||
</ul>
|
||||
@ -161,11 +126,13 @@ export default function RobotsShowcase() {
|
||||
</TooltipProvider>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-muted-foreground mb-4 leading-relaxed">{robot.description}</p>
|
||||
<p className="text-sm text-muted-foreground mb-4 leading-relaxed">{robot.shortDescription}</p>
|
||||
|
||||
<Button variant="outline" size="sm" className="w-full border-white/10 button-hover-effect">
|
||||
查看详情
|
||||
</Button>
|
||||
<Link href={`/robots#${robot.id}`}>
|
||||
<Button variant="outline" size="sm" className="w-full border-white/10 button-hover-effect">
|
||||
查看详情
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { ChevronRight } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
|
||||
export default function TeamGroupsSection() {
|
||||
const groups = [
|
||||
@ -7,21 +10,14 @@ export default function TeamGroupsSection() {
|
||||
name: "机械架构组",
|
||||
code: "MEST",
|
||||
icon: "/icons/mest.svg",
|
||||
description:
|
||||
"负责设计和制造机器人的物理结构,包括底盘、武器系统和机械部件。",
|
||||
responsibilities: [
|
||||
"3D 建模与 CAD 出图",
|
||||
"CNC 加工制造",
|
||||
"机械结构分析与优化",
|
||||
"结构装配与测试",
|
||||
],
|
||||
description: "负责设计和制造机器人的物理结构,包括底盘、武器系统和机械部件。",
|
||||
responsibilities: ["3D 建模与 CAD 出图", "CNC 加工制造", "机械结构分析与优化", "结构装配与测试"],
|
||||
},
|
||||
{
|
||||
name: "电传测控组",
|
||||
code: "ELCT",
|
||||
icon: "/icons/elct.svg",
|
||||
description:
|
||||
"开发机器人的配电与控制系统, 涵盖电路设计、功率管理和嵌入式开发。",
|
||||
description: "开发机器人的配电与控制系统, 涵盖电路设计、功率管理和嵌入式开发。",
|
||||
responsibilities: [
|
||||
"电路设计与 PCB Layout",
|
||||
"功率管理系统设计",
|
||||
@ -34,14 +30,8 @@ export default function TeamGroupsSection() {
|
||||
name: "视觉算法组",
|
||||
code: "VSAG",
|
||||
icon: "/icons/vsag.svg",
|
||||
description:
|
||||
"开发计算机视觉和人工智能系统,使机器人能够感知和理解周围环境,实现自主操作。",
|
||||
responsibilities: [
|
||||
"计算机视觉算法开发",
|
||||
"对象识别与跟踪",
|
||||
"机器学习模型训练",
|
||||
"实时图像处理优化",
|
||||
],
|
||||
description: "开发计算机视觉和人工智能系统,使机器人能够感知和理解周围环境,实现自主操作。",
|
||||
responsibilities: ["计算机视觉算法开发", "对象识别与跟踪", "机器学习模型训练", "实时图像处理优化"],
|
||||
},
|
||||
{
|
||||
name: "宣传筹划组",
|
||||
@ -49,12 +39,7 @@ export default function TeamGroupsSection() {
|
||||
icon: "/icons/pram.svg",
|
||||
description:
|
||||
"管理团队品牌、文档、社交媒体和外联工作,以宣传我们的团队并获得赞助,并规划赛季任务、维护战队开发环境。",
|
||||
responsibilities: [
|
||||
"平面与视觉设计",
|
||||
"社交媒体运营",
|
||||
"招商引资",
|
||||
"战队开发平台运维与项目管理",
|
||||
],
|
||||
responsibilities: ["平面与视觉设计", "社交媒体运营", "招商引资", "战队开发平台运维与项目管理"],
|
||||
},
|
||||
]
|
||||
|
||||
@ -108,6 +93,16 @@ export default function TeamGroupsSection() {
|
||||
<li key={idx}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<Link href={`/teams?tab=${group.code.toLowerCase()}`}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="mt-4 w-full border border-white/10 button-hover-effect"
|
||||
>
|
||||
了解更多 <ChevronRight className="ml-1 h-4 w-4" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
31
lib/achievement-data.ts
Normal file
31
lib/achievement-data.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { Trophy, Medal, Award, Star } from "lucide-react"
|
||||
import React from "react"
|
||||
|
||||
export const achievements = [
|
||||
{
|
||||
year: "2025",
|
||||
title: "RoboMaster 高校联盟赛 辽宁站 3V3对抗赛",
|
||||
position: "三等奖",
|
||||
icon: React.createElement(Award, { className: "h-8 w-8 text-primary" }),
|
||||
description:
|
||||
"与 32 支来自辽宁周边城市的大学参赛队伍同台竞技,直接对阵的队伍有:哈尔滨工业大学 I Hiter 战队、北京邮电大学 鸿雁 战队、沈阳工业大学辽阳分校 赫兹矩阵战队。",
|
||||
link: "https://www.robomaster.com/zh-CN/resource/pages/announcement/1830",
|
||||
},
|
||||
{
|
||||
year: "2024",
|
||||
title: "RoboMaster 高校联盟赛 山东站 3V3对抗赛",
|
||||
position: "三等奖",
|
||||
icon: React.createElement(Award, { className: "h-8 w-8 text-primary" }),
|
||||
description:
|
||||
"与 32 支来自山东周边城市的大学参赛队伍同台竞技,直接对阵的队伍有:北方工业大学 DreamTeam 战队、哈尔滨工业大学威海 HERO 战队。",
|
||||
link: "https://www.robomaster.com/zh-CN/resource/pages/announcement/1802",
|
||||
},
|
||||
{
|
||||
year: "2023",
|
||||
title: "RoboMaster 高校联盟赛 黑龙江站 步兵对抗赛",
|
||||
position: "三等奖",
|
||||
icon: React.createElement(Star, { className: "h-8 w-8 text-primary" }),
|
||||
description: "与多支来自黑龙江周边城市的大学参赛队伍同台竞技。 ",
|
||||
link: "https://www.robomaster.com/zh-CN/resource/pages/announcement/1596",
|
||||
},
|
||||
]
|
176
lib/robot-data.ts
Normal file
176
lib/robot-data.ts
Normal file
@ -0,0 +1,176 @@
|
||||
import { Shield, Gauge, Zap, Cpu } from "lucide-react"
|
||||
import React from "react"
|
||||
|
||||
export const robots = [
|
||||
{
|
||||
id: "sentinel-mk-iii",
|
||||
name: "Sentinel MK-III",
|
||||
displayName: "初号步兵",
|
||||
category: "INFANTRY",
|
||||
year: "2023-2024",
|
||||
image: "/placeholder.svg?height=400&width=600",
|
||||
description:
|
||||
"我们的旗舰防御机器人,配备先进装甲板和360°旋转炮塔系统。Sentinel MK-III 是我们最新一代的步兵机器人,专为RoboMaster比赛设计,具有出色的防御能力和火力输出。",
|
||||
shortDescription:
|
||||
"Our flagship defense robot, equipped with advanced armor plating and a 360° rotating turret system.",
|
||||
specs: [
|
||||
{ icon: React.createElement(Shield, { className: "h-8 w-8 text-primary" }), name: "装甲", value: "复合装甲板" },
|
||||
{ icon: React.createElement(Gauge, { className: "h-8 w-8 text-primary" }), name: "最大速度", value: "3m/s" },
|
||||
{ icon: React.createElement(Zap, { className: "h-8 w-8 text-primary" }), name: "电池续航", value: "30分钟" },
|
||||
{ icon: React.createElement(Cpu, { className: "h-8 w-8 text-primary" }), name: "控制系统", value: "STM32F4" },
|
||||
],
|
||||
simpleSpecs: ["Weight: 15kg", "Max Speed: 3m/s", "Battery Life: 30min", "Weapon: Launcher"],
|
||||
features: [
|
||||
"高精度云台系统,实现毫秒级目标锁定",
|
||||
"模块化设计,便于快速维修和更换部件",
|
||||
"先进的散热系统,确保长时间作战能力",
|
||||
"自主导航和目标识别能力",
|
||||
],
|
||||
achievements: ["区域赛最佳设计奖", "全国赛技术挑战赛亚军"],
|
||||
gallery: [
|
||||
"/placeholder.svg?height=300&width=400",
|
||||
"/placeholder.svg?height=300&width=400",
|
||||
"/placeholder.svg?height=300&width=400",
|
||||
],
|
||||
team: [
|
||||
{ name: "彭戈", role: "机械设计" },
|
||||
{ name: "陈卓文", role: "电控系统" },
|
||||
{ name: "黄瑞", role: "视觉算法" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "striker-x2",
|
||||
name: "Striker X2",
|
||||
displayName: "初号英雄",
|
||||
category: "HERO",
|
||||
year: "2023-2024",
|
||||
image: "/placeholder.svg?height=400&width=600",
|
||||
description:
|
||||
"高机动性攻击单元,设计用于快速交战和战略定位。Striker X2 是我们的英雄机器人,具有更高的火力和机动性,能够在比赛中担任进攻核心的角色。",
|
||||
shortDescription: "High-mobility attack unit designed for rapid engagement and strategic positioning.",
|
||||
specs: [
|
||||
{ icon: React.createElement(Shield, { className: "h-8 w-8 text-primary" }), name: "装甲", value: "轻量化装甲" },
|
||||
{ icon: React.createElement(Gauge, { className: "h-8 w-8 text-primary" }), name: "最大速度", value: "4.5m/s" },
|
||||
{ icon: React.createElement(Zap, { className: "h-8 w-8 text-primary" }), name: "电池续航", value: "25分钟" },
|
||||
{ icon: React.createElement(Cpu, { className: "h-8 w-8 text-primary" }), name: "控制系统", value: "STM32H7" },
|
||||
],
|
||||
simpleSpecs: ["Weight: 12kg", "Max Speed: 4.5m/s", "Battery Life: 25min", "Weapon: Dual Launcher System"],
|
||||
features: [
|
||||
"双发射机构,提供更高的火力输出",
|
||||
"高性能底盘,实现快速机动和精确控制",
|
||||
"先进的弹道计算系统,提高射击精度",
|
||||
"轻量化设计,提升整体性能",
|
||||
],
|
||||
achievements: ["区域赛最佳性能奖"],
|
||||
gallery: ["/placeholder.svg?height=300&width=400", "/placeholder.svg?height=300&width=400"],
|
||||
team: [
|
||||
{ name: "闫芃森", role: "机械设计" },
|
||||
{ name: "陈卓文", role: "电控系统" },
|
||||
{ name: "韩翔宇", role: "视觉算法" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "sentinel-mk-ii",
|
||||
name: "Sentinel MK-II",
|
||||
displayName: "二号步兵",
|
||||
category: "INFANTRY",
|
||||
year: "2022-2023",
|
||||
image: "/placeholder.svg?height=400&width=600",
|
||||
description:
|
||||
"Sentinel系列的第二代,增强了火力和防御能力。MK-II 在前代基础上进行了全面升级,特别是在控制系统和火力输出方面有显著提升。",
|
||||
shortDescription: "Second generation of the Sentinel series with enhanced firepower and defensive capabilities.",
|
||||
specs: [
|
||||
{ icon: React.createElement(Shield, { className: "h-8 w-8 text-primary" }), name: "装甲", value: "标准装甲板" },
|
||||
{ icon: React.createElement(Gauge, { className: "h-8 w-8 text-primary" }), name: "最大速度", value: "2.8m/s" },
|
||||
{ icon: React.createElement(Zap, { className: "h-8 w-8 text-primary" }), name: "电池续航", value: "28分钟" },
|
||||
{ icon: React.createElement(Cpu, { className: "h-8 w-8 text-primary" }), name: "控制系统", value: "STM32F4" },
|
||||
],
|
||||
simpleSpecs: ["Weight: 14kg", "Max Speed: 2.8m/s", "Battery Life: 28min", "Weapon: Standard Launcher"],
|
||||
features: ["改进的云台稳定系统", "优化的弹道计算算法", "增强的装甲防护", "更高效的功率管理系统"],
|
||||
achievements: ["全国赛最佳工程奖", "区域赛冠军"],
|
||||
gallery: ["/placeholder.svg?height=300&width=400", "/placeholder.svg?height=300&width=400"],
|
||||
team: [
|
||||
{ name: "林小明", role: "机械设计" },
|
||||
{ name: "陈志强", role: "电控系统" },
|
||||
{ name: "黄海", role: "视觉算法" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "scout-drone-alpha",
|
||||
name: "Scout Drone Alpha",
|
||||
displayName: "零号哨兵",
|
||||
category: "AERIAL",
|
||||
year: "2022-2023",
|
||||
image: "/placeholder.svg?height=400&width=600",
|
||||
description:
|
||||
"我们的第一款侦察无人机,提供战场情报和有限的攻击能力。Scout Drone Alpha 是我们首次尝试空中单元,为地面机器人提供战场态势感知。",
|
||||
shortDescription:
|
||||
"Lightweight reconnaissance drone providing battlefield intelligence and limited attack capabilities.",
|
||||
specs: [
|
||||
{ icon: React.createElement(Shield, { className: "h-8 w-8 text-primary" }), name: "装甲", value: "最小化装甲" },
|
||||
{ icon: React.createElement(Gauge, { className: "h-8 w-8 text-primary" }), name: "最大速度", value: "10m/s" },
|
||||
{ icon: React.createElement(Zap, { className: "h-8 w-8 text-primary" }), name: "电池续航", value: "15分钟" },
|
||||
{ icon: React.createElement(Cpu, { className: "h-8 w-8 text-primary" }), name: "控制系统", value: "Pixhawk" },
|
||||
],
|
||||
simpleSpecs: ["Weight: 2kg", "Max Speed: 10m/s", "Flight Time: 15min", "Sensors: 4K Camera, Infrared"],
|
||||
features: [
|
||||
"高清摄像头,提供实时战场画面",
|
||||
"轻量化设计,提高机动性和续航时间",
|
||||
"自主避障系统",
|
||||
"与地面单元的数据链路系统",
|
||||
],
|
||||
achievements: ["创新设计奖"],
|
||||
gallery: ["/placeholder.svg?height=300&width=400"],
|
||||
team: [
|
||||
{ name: "林小明", role: "机械设计" },
|
||||
{ name: "黄海", role: "视觉算法" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "sentinel-mk-i",
|
||||
name: "Sentinel MK-I",
|
||||
displayName: "零号工程",
|
||||
category: "ENGINEER",
|
||||
year: "2021-2022",
|
||||
image: "/placeholder.svg?height=400&width=600",
|
||||
description:
|
||||
"Sentinel系列的初代机型,为后续发展奠定了基础。作为我们的第一代步兵机器人,MK-I 虽然在技术上相对简单,但建立了团队的基础设计理念。",
|
||||
shortDescription: "Specialized support unit capable of on-field repairs and resource management during matches.",
|
||||
specs: [
|
||||
{ icon: React.createElement(Shield, { className: "h-8 w-8 text-primary" }), name: "装甲", value: "基础装甲板" },
|
||||
{ icon: React.createElement(Gauge, { className: "h-8 w-8 text-primary" }), name: "最大速度", value: "2.5m/s" },
|
||||
{ icon: React.createElement(Zap, { className: "h-8 w-8 text-primary" }), name: "电池续航", value: "25分钟" },
|
||||
{ icon: React.createElement(Cpu, { className: "h-8 w-8 text-primary" }), name: "控制系统", value: "STM32F1" },
|
||||
],
|
||||
simpleSpecs: ["Weight: 18kg", "Max Speed: 2m/s", "Battery Life: 40min", "Tools: Mechanical Arm, Repair Module"],
|
||||
features: ["基础云台系统", "手动控制为主,辅助自动化功能", "模块化底盘设计", "简单的视觉识别系统"],
|
||||
achievements: ["区域赛最佳新秀奖"],
|
||||
gallery: ["/placeholder.svg?height=300&width=400"],
|
||||
team: [
|
||||
{ name: "王建国", role: "视觉算法" },
|
||||
{ name: "李明", role: "机械设计" },
|
||||
{ name: "张伟", role: "电控系统" },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
// 按年份分组的机器人数据,用于历史页面
|
||||
export const robotsByYear = [
|
||||
{
|
||||
year: "2023-2024",
|
||||
models: robots.filter((robot) => robot.year === "2023-2024"),
|
||||
},
|
||||
{
|
||||
year: "2022-2023",
|
||||
models: robots.filter((robot) => robot.year === "2022-2023"),
|
||||
},
|
||||
{
|
||||
year: "2021-2022",
|
||||
models: robots.filter((robot) => robot.year === "2021-2022"),
|
||||
},
|
||||
]
|
||||
|
||||
// 获取单个机器人数据
|
||||
export function getRobotById(id: string) {
|
||||
return robots.find((robot) => robot.id === id) || null
|
||||
}
|
@ -1,19 +1,5 @@
|
||||
let userConfig = undefined
|
||||
try {
|
||||
// try to import ESM first
|
||||
userConfig = await import('./v0-user-next.config.mjs')
|
||||
} catch (e) {
|
||||
try {
|
||||
// fallback to CJS import
|
||||
userConfig = await import("./v0-user-next.config");
|
||||
} catch (innerError) {
|
||||
// ignore error
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: 'export',
|
||||
eslint: {
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
@ -23,30 +9,6 @@ const nextConfig = {
|
||||
images: {
|
||||
unoptimized: true,
|
||||
},
|
||||
experimental: {
|
||||
webpackBuildWorker: true,
|
||||
parallelServerBuildTraces: true,
|
||||
parallelServerCompiles: true,
|
||||
},
|
||||
}
|
||||
|
||||
if (userConfig) {
|
||||
// ESM imports will have a "default" property
|
||||
const config = userConfig.default || userConfig
|
||||
|
||||
for (const key in config) {
|
||||
if (
|
||||
typeof nextConfig[key] === 'object' &&
|
||||
!Array.isArray(nextConfig[key])
|
||||
) {
|
||||
nextConfig[key] = {
|
||||
...nextConfig[key],
|
||||
...config[key],
|
||||
}
|
||||
} else {
|
||||
nextConfig[key] = config[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default nextConfig
|
||||
|
54
package.json
54
package.json
@ -10,33 +10,33 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^3.9.1",
|
||||
"@radix-ui/react-accordion": "^1.2.2",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.4",
|
||||
"@radix-ui/react-aspect-ratio": "^1.1.1",
|
||||
"@radix-ui/react-avatar": "^1.1.2",
|
||||
"@radix-ui/react-checkbox": "^1.1.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.2",
|
||||
"@radix-ui/react-context-menu": "^2.2.4",
|
||||
"@radix-ui/react-dialog": "^1.1.4",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.4",
|
||||
"@radix-ui/react-hover-card": "^1.1.4",
|
||||
"@radix-ui/react-label": "^2.1.1",
|
||||
"@radix-ui/react-menubar": "^1.1.4",
|
||||
"@radix-ui/react-navigation-menu": "^1.2.3",
|
||||
"@radix-ui/react-popover": "^1.1.4",
|
||||
"@radix-ui/react-progress": "^1.1.1",
|
||||
"@radix-ui/react-radio-group": "^1.2.2",
|
||||
"@radix-ui/react-scroll-area": "^1.2.2",
|
||||
"@radix-ui/react-select": "^2.1.4",
|
||||
"@radix-ui/react-separator": "^1.1.1",
|
||||
"@radix-ui/react-slider": "^1.2.2",
|
||||
"@radix-ui/react-slot": "^1.1.1",
|
||||
"@radix-ui/react-switch": "^1.1.2",
|
||||
"@radix-ui/react-tabs": "^1.1.2",
|
||||
"@radix-ui/react-toast": "^1.2.4",
|
||||
"@radix-ui/react-toggle": "^1.1.1",
|
||||
"@radix-ui/react-toggle-group": "^1.1.1",
|
||||
"@radix-ui/react-tooltip": "^1.1.6",
|
||||
"@radix-ui/react-accordion": "1.2.2",
|
||||
"@radix-ui/react-alert-dialog": "1.1.4",
|
||||
"@radix-ui/react-aspect-ratio": "1.1.1",
|
||||
"@radix-ui/react-avatar": "1.1.2",
|
||||
"@radix-ui/react-checkbox": "1.1.3",
|
||||
"@radix-ui/react-collapsible": "1.1.2",
|
||||
"@radix-ui/react-context-menu": "2.2.4",
|
||||
"@radix-ui/react-dialog": "1.1.4",
|
||||
"@radix-ui/react-dropdown-menu": "2.1.4",
|
||||
"@radix-ui/react-hover-card": "1.1.4",
|
||||
"@radix-ui/react-label": "2.1.1",
|
||||
"@radix-ui/react-menubar": "1.1.4",
|
||||
"@radix-ui/react-navigation-menu": "1.2.3",
|
||||
"@radix-ui/react-popover": "1.1.4",
|
||||
"@radix-ui/react-progress": "1.1.1",
|
||||
"@radix-ui/react-radio-group": "1.2.2",
|
||||
"@radix-ui/react-scroll-area": "1.2.2",
|
||||
"@radix-ui/react-select": "2.1.4",
|
||||
"@radix-ui/react-separator": "1.1.1",
|
||||
"@radix-ui/react-slider": "1.2.2",
|
||||
"@radix-ui/react-slot": "1.1.1",
|
||||
"@radix-ui/react-switch": "1.1.2",
|
||||
"@radix-ui/react-tabs": "1.1.2",
|
||||
"@radix-ui/react-toast": "1.2.4",
|
||||
"@radix-ui/react-toggle": "1.1.1",
|
||||
"@radix-ui/react-toggle-group": "1.1.1",
|
||||
"@radix-ui/react-tooltip": "1.1.6",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
|
Loading…
x
Reference in New Issue
Block a user