49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import Link from "next/link";
|
||
|
|
import { X } from "lucide-react";
|
||
|
|
import { useJobs } from "@/components/layout/jobs-provider";
|
||
|
|
import { cn } from "@/lib/utils";
|
||
|
|
import { Button } from "@/components/ui/button";
|
||
|
|
|
||
|
|
const tone: Record<string, string> = {
|
||
|
|
success: "border-success-border bg-success-bg text-success",
|
||
|
|
error: "border-danger-border bg-danger-bg text-danger",
|
||
|
|
warning: "border-warning-border bg-warning-bg text-warning",
|
||
|
|
info: "border-border bg-card text-foreground",
|
||
|
|
};
|
||
|
|
|
||
|
|
export function LatestToast() {
|
||
|
|
const { latestToast, dismissToast } = useJobs();
|
||
|
|
if (!latestToast) return null;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
className={cn(
|
||
|
|
"tool-card mb-4 flex items-start gap-2 px-3 py-2.5 text-[13px]",
|
||
|
|
tone[latestToast.type] ?? tone.info
|
||
|
|
)}
|
||
|
|
>
|
||
|
|
<div className="min-w-0 flex-1">
|
||
|
|
<p className="font-medium">{latestToast.title}</p>
|
||
|
|
{latestToast.message && (
|
||
|
|
<p className="mt-0.5 opacity-80">{latestToast.message}</p>
|
||
|
|
)}
|
||
|
|
{latestToast.href && (
|
||
|
|
<Link href={latestToast.href} className="mt-1 inline-block text-[12px] underline">
|
||
|
|
前往查看
|
||
|
|
</Link>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
<Button
|
||
|
|
size="sm"
|
||
|
|
variant="ghost"
|
||
|
|
className="h-7 w-7 shrink-0 p-0"
|
||
|
|
onClick={dismissToast}
|
||
|
|
aria-label="關閉"
|
||
|
|
>
|
||
|
|
<X className="h-3.5 w-3.5" />
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|