feat: links cruzados autor->/autor y parodia->/franquicia en posts
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { notFound } from "next/navigation"
|
import { notFound } from "next/navigation"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
import { getPostBySlug, getAllPosts } from "@/lib/db"
|
import { getPostBySlug, getAllPosts, getAuthorSlugByName } from "@/lib/db"
|
||||||
import { PostCard } from "@/components/post-card"
|
import { PostCard } from "@/components/post-card"
|
||||||
import { TagBadge } from "@/components/tag-badge"
|
import { TagBadge } from "@/components/tag-badge"
|
||||||
import { ArrowLeft, BookOpen, ExternalLink } from "lucide-react"
|
import { ArrowLeft, BookOpen, ExternalLink } from "lucide-react"
|
||||||
@@ -78,6 +78,9 @@ export default async function PostDetailPage({
|
|||||||
post.summary.length > 50
|
post.summary.length > 50
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Enlaces cruzados: autor -> página de autor, parodia -> franquicia.
|
||||||
|
const authorSlug = post.artist ? getAuthorSlugByName(post.artist) : null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="pb-16 md:pb-0">
|
<div className="pb-16 md:pb-0">
|
||||||
<Link
|
<Link
|
||||||
@@ -117,11 +120,23 @@ export default async function PostDetailPage({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-wrap items-center gap-2 text-xs sm:text-sm">
|
<div className="flex flex-wrap items-center gap-2 text-xs sm:text-sm">
|
||||||
{post.artist && (
|
{post.artist && authorSlug && (
|
||||||
<TagBadge tag={`artist:${post.artist}`} href={`/tag/${encodeURIComponent(`artist:${post.artist}`)}`} />
|
<Link
|
||||||
|
href={`/autor/${authorSlug}`}
|
||||||
|
className="inline-flex items-center gap-1.5 rounded-full border border-[var(--border)] bg-[var(--surface)] px-2.5 py-1 text-xs text-[var(--foreground)] transition-colors hover:border-[var(--accent)] hover:text-[var(--accent)]"
|
||||||
|
>
|
||||||
|
<span className="text-[var(--muted)]"> artista:</span>
|
||||||
|
{post.artist}
|
||||||
|
</Link>
|
||||||
)}
|
)}
|
||||||
{post.parody && (
|
{post.parody && !["original", "sin parodia"].includes(post.parody) && (
|
||||||
<TagBadge tag={`parody:${post.parody}`} href={`/tag/${encodeURIComponent(`parody:${post.parody}`)}`} />
|
<Link
|
||||||
|
href={`/franquicia/${encodeURIComponent(post.parody)}`}
|
||||||
|
className="inline-flex items-center gap-1.5 rounded-full border border-[var(--border)] bg-[var(--surface)] px-2.5 py-1 text-xs text-[var(--foreground)] transition-colors hover:border-[var(--accent)] hover:text-[var(--accent)]"
|
||||||
|
>
|
||||||
|
<span className="text-[var(--muted)]"> franquicia:</span>
|
||||||
|
{post.parody}
|
||||||
|
</Link>
|
||||||
)}
|
)}
|
||||||
{post.source && (
|
{post.source && (
|
||||||
<span className="tag-pill border border-[var(--border)] text-[var(--muted)]">
|
<span className="tag-pill border border-[var(--border)] text-[var(--muted)]">
|
||||||
|
|||||||
@@ -420,6 +420,23 @@ export function getAuthorBySlug(slug: string): Author | null {
|
|||||||
return row ? rowToAuthor(row) : null
|
return row ? rowToAuthor(row) : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Devuelve el slug de un autor por su nombre (para enlazar desde los posts).
|
||||||
|
// Si el autor no está registrado, lo registra sobre la marcha.
|
||||||
|
export function getAuthorSlugByName(name: string): string | null {
|
||||||
|
const d = getDb()
|
||||||
|
const clean = (name || "").trim()
|
||||||
|
if (!clean || clean === "sin artista" || clean === "dummy") return null
|
||||||
|
|
||||||
|
d.prepare("INSERT OR IGNORE INTO authors(name, slug) VALUES (?, ?)").run(
|
||||||
|
clean,
|
||||||
|
slugify(clean),
|
||||||
|
)
|
||||||
|
const row = d.prepare("SELECT slug FROM authors WHERE name = ?").get(clean) as
|
||||||
|
| { slug: string }
|
||||||
|
| undefined
|
||||||
|
return row ? row.slug : null
|
||||||
|
}
|
||||||
|
|
||||||
export function getSeriesBySlug(slug: string): Series | null {
|
export function getSeriesBySlug(slug: string): Series | null {
|
||||||
const d = getDb()
|
const d = getDb()
|
||||||
const row = d
|
const row = d
|
||||||
|
|||||||
Reference in New Issue
Block a user