82 lines
2.0 KiB
TypeScript
82 lines
2.0 KiB
TypeScript
"use client"
|
|
|
|
import { Card, CardContent } from "@/components/ui/card"
|
|
import { Camera, MapPin, Calendar, Hash } from "lucide-react"
|
|
|
|
interface Photo {
|
|
id: number
|
|
src: string
|
|
title: string
|
|
description: string
|
|
category: string
|
|
tags: string[]
|
|
date: string
|
|
exif: {
|
|
camera: string
|
|
lens: string
|
|
settings: string
|
|
location: string
|
|
}
|
|
}
|
|
|
|
interface TimelineStatsProps {
|
|
photos: Photo[]
|
|
}
|
|
|
|
export function TimelineStats({ photos }: TimelineStatsProps) {
|
|
// Calculate statistics
|
|
const totalPhotos = photos.length
|
|
const uniqueLocations = new Set(photos.map((p) => p.exif.location)).size
|
|
const uniqueCameras = new Set(photos.map((p) => p.exif.camera)).size
|
|
const dateRange =
|
|
photos.length > 0
|
|
? {
|
|
start: new Date(Math.min(...photos.map((p) => new Date(p.date).getTime()))),
|
|
end: new Date(Math.max(...photos.map((p) => new Date(p.date).getTime()))),
|
|
}
|
|
: null
|
|
|
|
const stats = [
|
|
{
|
|
icon: Camera,
|
|
label: "总作品数",
|
|
value: totalPhotos,
|
|
color: "text-blue-600",
|
|
},
|
|
{
|
|
icon: MapPin,
|
|
label: "拍摄地点",
|
|
value: uniqueLocations,
|
|
color: "text-green-600",
|
|
},
|
|
{
|
|
icon: Hash,
|
|
label: "使用设备",
|
|
value: uniqueCameras,
|
|
color: "text-purple-600",
|
|
},
|
|
{
|
|
icon: Calendar,
|
|
label: "创作时间",
|
|
value: dateRange ? `${dateRange.start.getFullYear()}-${dateRange.end.getFullYear()}` : "N/A",
|
|
color: "text-orange-600",
|
|
},
|
|
]
|
|
|
|
return (
|
|
<div className="mb-12">
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
{stats.map((stat, index) => (
|
|
<Card key={index} className="border-0 shadow-sm">
|
|
<CardContent className="p-4 text-center">
|
|
<stat.icon className={`h-6 w-6 mx-auto mb-2 ${stat.color}`} />
|
|
<div className="text-2xl font-light text-gray-900 mb-1">{stat.value}</div>
|
|
<div className="text-sm text-gray-500">{stat.label}</div>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|