feat: add recent plans history to homepage
This commit is contained in:
76
components/recent-plans.tsx
Normal file
76
components/recent-plans.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
"use client"
|
||||
|
||||
import { useEffect, useState } from "react"
|
||||
import Link from "next/link"
|
||||
import { History, ChevronRight, X } from "lucide-react"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
type RecentPlan = {
|
||||
id: string
|
||||
title: string
|
||||
lastVisited: number
|
||||
}
|
||||
|
||||
export function RecentPlans({ lang, dict }: { lang: string, dict: { title: string, noPlans: string, clear: string } }) {
|
||||
const [plans, setPlans] = useState<RecentPlan[]>([])
|
||||
const [mounted, setMounted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true)
|
||||
const stored = localStorage.getItem("csp_recent_plans")
|
||||
if (stored) {
|
||||
try {
|
||||
const parsed = JSON.parse(stored)
|
||||
setPlans(parsed.sort((a: RecentPlan, b: RecentPlan) => b.lastVisited - a.lastVisited))
|
||||
} catch (e) {
|
||||
console.error("Failed to parse recent plans", e)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
const removePlan = (id: string, e: React.MouseEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
const newPlans = plans.filter(p => p.id !== id)
|
||||
setPlans(newPlans)
|
||||
localStorage.setItem("csp_recent_plans", JSON.stringify(newPlans))
|
||||
}
|
||||
|
||||
if (!mounted || plans.length === 0) return null
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base font-medium flex items-center gap-2">
|
||||
<History className="w-4 h-4" />
|
||||
{dict.title}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-2">
|
||||
{plans.map((plan) => (
|
||||
<Link
|
||||
key={plan.id}
|
||||
href={`/${lang}/dashboard/${plan.id}`}
|
||||
className="group flex items-center justify-between p-3 rounded-lg border bg-card hover:bg-accent/50 transition-colors"
|
||||
>
|
||||
<div className="font-medium truncate mr-4">
|
||||
{plan.title}
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-muted-foreground">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
onClick={(e) => removePlan(plan.id, e)}
|
||||
>
|
||||
<X className="w-3.5 h-3.5" />
|
||||
</Button>
|
||||
<ChevronRight className="w-4 h-4" />
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user