Files
photography/docs/ui/components/photo-modal.tsx
iriver ff20f6f23a feat: 添加产品经理和全栈开发角色资源文件
初始化产品经理和全栈开发角色的相关资源文件,包括角色定义、知识库、思维模式和执行流程文档
2025-07-21 22:47:16 +08:00

161 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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>
)
}