Files
photography/frontend/components/photo-modal.tsx
xujiang 0e9d9b9010
Some checks failed
Deploy Frontend / deploy (push) Failing after 1m39s
fix: 修复 ESLint 配置和代码检查错误
- 安装 ESLint 和 eslint-config-next 依赖
- 创建 .eslintrc.json 配置文件,使用 Next.js 严格模式
- 修复 TypeScript 代码中的类型错误:
  - 移除 any 类型,使用具体的类型定义
  - 修复未使用的函数参数和变量
  - 优化组件类型定义
- 现在 CI/CD 可以成功通过 lint 检查
2025-07-09 09:10:11 +08:00

163 lines
5.5 KiB
TypeScript
Raw Permalink 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"
import { Photo } from '@/lib/queries'
interface PhotoModalProps {
photo: Photo
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>
)
}