- Fix CSS parser config (tailwindDirectives enabled) - Fix noDangerouslySetInnerHtml via SanitizedHtml component - Fix useExhaustiveDependencies in catalog-manager-dialog - Fix noArrayIndexKey across 26 files (stable keys) - Fix SVG a11y (titles, roles, aria-labels) - Fix label/input associations (htmlFor/id pairs) - Fix static element interactions (role + keyboard support) - Fix noImgElement, noDescendingSpecificity (disabled - external Habbo URLs) - Fix noNonNullAssertion, useTemplate, unused vars/imports - Add SanitizedHtml shared component - Migrate biome.json to 2.5.4 schema
78 lines
1.9 KiB
TypeScript
78 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { useTranslations } from "next-intl";
|
|
import { deleteArticle } from "@/actions/admin-articles";
|
|
|
|
export function ArticleCard({
|
|
id,
|
|
title,
|
|
image,
|
|
createdAt,
|
|
author,
|
|
}: {
|
|
id: string;
|
|
title: string;
|
|
image: string;
|
|
createdAt: string | null;
|
|
author?: string;
|
|
}) {
|
|
const t = useTranslations("pages.admin.articles");
|
|
|
|
return (
|
|
<div className="admin-card overflow-hidden flex flex-col">
|
|
<div className="relative w-full aspect-[16/9] bg-[var(--admin-canvas)]">
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img
|
|
src={image || ""}
|
|
alt={title}
|
|
className="w-full h-full object-cover block"
|
|
onError={(e) => {
|
|
e.currentTarget.style.visibility = "hidden";
|
|
}}
|
|
/>
|
|
</div>
|
|
<div className="p-3 flex flex-col flex-1">
|
|
<Link
|
|
href={`/admin/articles/${id}`}
|
|
className="font-semibold text-[var(--admin-text)] hover:text-[var(--admin-accent)] line-clamp-2"
|
|
style={{ textDecoration: "none" }}
|
|
>
|
|
{title}
|
|
</Link>
|
|
<p className="text-xs text-[var(--admin-text-muted)] mt-1 mb-3 flex items-center gap-2 flex-wrap">
|
|
<span>{createdAt ? createdAt.slice(0, 10) : "—"}</span>
|
|
{author ? (
|
|
<>
|
|
<span>·</span>
|
|
<span>{author}</span>
|
|
</>
|
|
) : null}
|
|
</p>
|
|
<div className="flex gap-2 mt-auto">
|
|
<Link
|
|
href={`/admin/articles/${id}`}
|
|
className="btn btn-primary flex-1 text-center"
|
|
>
|
|
{t("edit")}
|
|
</Link>
|
|
<form action={deleteArticle} className="m-0">
|
|
<input type="hidden" name="id" value={id} />
|
|
<button
|
|
type="submit"
|
|
className="btn btn-danger"
|
|
onClick={(e) => {
|
|
if (!window.confirm(t("confirmDelete", { title }))) {
|
|
e.preventDefault();
|
|
}
|
|
}}
|
|
>
|
|
{t("delete")}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|