test2

Administrador
13 de febrero de 20263 min10
test2

# Actualizar app/blog/[slug]/page.tsx

$articuloConImagenAdaptativa = @'

import { query } from '@/lib/db'

import { notFound } from 'next/navigation'

import Link from 'next/link'

import { Calendar, User, Eye, ArrowLeft } from 'lucide-react'

import SidebarBlog from '../components/SidebarBlog'

import BlogImage from '../components/BlogImage'

export async function generateMetadata({ params }) {

const { slug } = await params

const articulos = await query(

'SELECT title, excerpt, featured_image FROM posts WHERE slug = ? AND published = 1',

[slug]

) as any[]

if (articulos.length === 0) return { title: 'Artículo no encontrado' }

return {

title: ${articulos[0].title} - CambiCash Blog,

description: articulos[0].excerpt,

openGraph: {

title: articulos[0].title,

description: articulos[0].excerpt,

images: articulos[0].featured_image ? [{

url: articulos[0].featured_image,

width: 1200,

height: 630,

alt: articulos[0].title

}] : [],

}

}

}

export default async function ArticuloPage({ params }) {

const { slug } = await params

const articulos = await query(`

SELECT

p.*,

u.name as author_name,

GROUP_CONCAT(c.name) as categories,

GROUP_CONCAT(c.slug) as category_slugs

FROM posts p

LEFT JOIN users u ON p.author_id = u.id

LEFT JOIN post_categories pc ON p.id = pc.post_id

LEFT JOIN categories c ON pc.category_id = c.id

WHERE p.slug = ? AND p.published = 1

GROUP BY p.id

`, [slug]) as any[]

if (articulos.length === 0) notFound()

const articulo = articulos[0]

const categorias = articulo.categories ? articulo.categories.split(',') : []

await query('UPDATE posts SET views = views + 1 WHERE id = ?', [articulo.id])

return (

<div className="min-h-screen bg-gray-50">

{/* Barra de navegación */}

<div className="bg-white border-b sticky top-0 z-10">

<div className="container mx-auto px-4 py-3 md:py-4">

<Link

href="/blog"

className="inline-flex items-center gap-1 md:gap-2 text-sm md:text-base text-gray-600 hover:text-blue-600"

>

<ArrowLeft className="w-4 h-4 md:w-5 md:h-5" />

Volver al Blog

</Link>

</div>

</div>

{/* Hero del artículo con imagen adaptativa */}

<div className="relative bg-gray-900">

{/* Imagen de fondo (hero) */}

<div className="relative h-48 sm:h-64 md:h-80 lg:h-96">

<BlogImage

src={articulo.featured_image}

alt={articulo.title}

type="hero"

priority={true}

/>

<div className="absolute inset-0 bg-black/40" />

</div>

{/* Título y metadatos sobre la imagen */}

<div className="absolute bottom-0 left-0 right-0 p-4 md:p-8 text-white">

<div className="container mx-auto">

<div className="max-w-3xl">

{/* Categorías */}

<div className="flex flex-wrap gap-1 md:gap-2 mb-2 md:mb-4">

{categorias.map((cat, idx) => (

<span

key={idx}

className="px-2 md:px-3 py-0.5 md:py-1 bg-blue-600 text-white text-xs md:text-sm rounded-full"

>

{cat}

</span>

))}

</div>

<h1 className="text-xl sm:text-2xl md:text-3xl lg:text-4xl xl:text-5xl font-bold mb-2 md:mb-4 line-clamp-3">

{articulo.title}

</h1>

<div className="flex flex-wrap items-center gap-2 md:gap-4 text-xs md:text-sm text-gray-200">

<span className="flex items-center gap-1">

<User className="w-3 h-3 md:w-4 md:h-4" />

{articulo.author_name || 'CambiCash'}

</span>

<span className="flex items-center gap-1">

<Calendar className="w-3 h-3 md:w-4 md:h-4" />

{new Date(articulo.published_at).toLocaleDateString('es-PE', {

day: 'numeric',

month: 'long',

year: 'numeric'

})}

</span>

<span className="flex items-center gap-1">

<Eye className="w-3 h-3 md:w-4 md:h-4" />

{articulo.views || 0} vistas

</span>

</div>

</div>

</div>

</div>

</div>

{/* Contenido */}

<div className="container mx-auto px-4 py-6 md:py-12">

<div className="grid lg:grid-cols-3 gap-6 md:gap-8">

<div className="lg:col-span-2">

<article className="bg-white rounded-xl md:rounded-2xl shadow-lg p-4 md:p-8">

<div

className="prose prose-sm sm:prose-base md:prose-lg max-w-none"

dangerouslySetInnerHTML={{ __html: articulo.content }}

/>

</article>

</div>

<SidebarBlog />

</div>

</div>

</div>

)

}

'@

# Guardar el archivo

$articuloConImagenAdaptativa | Out-File -LiteralPath "C:\Users\JULIO\Desktop\cambicash-blog-final\app\blog\[slug]\page.tsx" -Encoding UTF8 -Force

Newsletter

Recibe análisis del dólar y consejos financieros directamente en tu correo.

Sin spam, solo información relevante.

Comentarios (0)

Cargando comentarios...