feat: 添加产品经理和全栈开发角色资源文件
初始化产品经理和全栈开发角色的相关资源文件,包括角色定义、知识库、思维模式和执行流程文档
This commit is contained in:
160
docs/ui/components/photo-modal.tsx
Normal file
160
docs/ui/components/photo-modal.tsx
Normal file
@ -0,0 +1,160 @@
|
||||
"use client"
|
||||
|
||||
import { useEffect } from "react"
|
||||
import Image from "next/image"
|
||||
import { X, ChevronLeft, ChevronRight, Camera, MapPin, Calendar } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
|
||||
interface PhotoModalProps {
|
||||
photo: any
|
||||
onClose: () => void
|
||||
onPrev: () => void
|
||||
onNext: () => void
|
||||
}
|
||||
|
||||
export function PhotoModal({ photo, onClose, onPrev, onNext }: PhotoModalProps) {
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
switch (e.key) {
|
||||
case "Escape":
|
||||
onClose()
|
||||
break
|
||||
case "ArrowLeft":
|
||||
onPrev()
|
||||
break
|
||||
case "ArrowRight":
|
||||
onNext()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", handleKeyDown)
|
||||
document.body.style.overflow = "hidden"
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("keydown", handleKeyDown)
|
||||
document.body.style.overflow = "unset"
|
||||
}
|
||||
}, [onClose, onPrev, onNext])
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 bg-black/95 flex items-center justify-center p-4">
|
||||
{/* Close button */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="absolute top-4 right-4 z-10 text-white hover:bg-white/10"
|
||||
onClick={onClose}
|
||||
>
|
||||
<X className="h-6 w-6" />
|
||||
</Button>
|
||||
|
||||
{/* Navigation buttons */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="absolute left-4 top-1/2 -translate-y-1/2 z-10 text-white hover:bg-white/10"
|
||||
onClick={onPrev}
|
||||
>
|
||||
<ChevronLeft className="h-8 w-8" />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="absolute right-4 top-1/2 -translate-y-1/2 z-10 text-white hover:bg-white/10"
|
||||
onClick={onNext}
|
||||
>
|
||||
<ChevronRight className="h-8 w-8" />
|
||||
</Button>
|
||||
|
||||
<div className="w-full max-w-7xl mx-auto grid lg:grid-cols-3 gap-6 h-full max-h-[90vh]">
|
||||
{/* Main image */}
|
||||
<div className="lg:col-span-2 relative flex items-center justify-center">
|
||||
<div className="relative w-full h-full max-h-[80vh] flex items-center justify-center">
|
||||
<Image
|
||||
src={photo.src || "/placeholder.svg"}
|
||||
alt={photo.title}
|
||||
width={1200}
|
||||
height={800}
|
||||
className="max-w-full max-h-full object-contain"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Photo information */}
|
||||
<div className="lg:col-span-1 overflow-y-auto">
|
||||
<Card className="bg-white/95 backdrop-blur-sm">
|
||||
<CardContent className="p-6">
|
||||
<div className="space-y-6">
|
||||
{/* Title and description */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-light text-gray-900 mb-2">{photo.title}</h2>
|
||||
<p className="text-gray-600 leading-relaxed">{photo.description}</p>
|
||||
</div>
|
||||
|
||||
{/* Tags */}
|
||||
<div>
|
||||
<h3 className="text-sm font-medium text-gray-900 mb-2">标签</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{photo.tags.map((tag: string) => (
|
||||
<Badge key={tag} variant="secondary">
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Date and location */}
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
<div className="flex items-center gap-2 text-gray-600">
|
||||
<Calendar className="h-4 w-4" />
|
||||
<span className="text-sm">拍摄时间:{photo.date}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-gray-600">
|
||||
<MapPin className="h-4 w-4" />
|
||||
<span className="text-sm">拍摄地点:{photo.exif.location}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* EXIF information */}
|
||||
<div>
|
||||
<h3 className="text-sm font-medium text-gray-900 mb-3 flex items-center gap-2">
|
||||
<Camera className="h-4 w-4" />
|
||||
拍摄参数
|
||||
</h3>
|
||||
<div className="space-y-2 text-sm text-gray-600">
|
||||
<div className="flex justify-between">
|
||||
<span>相机:</span>
|
||||
<span className="font-medium">{photo.exif.camera}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>镜头:</span>
|
||||
<span className="font-medium">{photo.exif.lens}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>参数:</span>
|
||||
<span className="font-medium">{photo.exif.settings}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Keyboard shortcuts */}
|
||||
<div className="pt-4 border-t border-gray-200">
|
||||
<h3 className="text-sm font-medium text-gray-900 mb-2">快捷键</h3>
|
||||
<div className="text-xs text-gray-500 space-y-1">
|
||||
<div>ESC - 关闭</div>
|
||||
<div>← → - 切换图片</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user