Fix: Featured images resolution, NewsCard redesign, and settings configurability
This commit is contained in:
parent
43dd3770b9
commit
a446a70854
@ -2,15 +2,22 @@ import { APPWRITE_ALMEIRA_CONFIG } from '@/lib/appwrite';
|
|||||||
import { createAdminClient } from '@/lib/appwrite.server';
|
import { createAdminClient } from '@/lib/appwrite.server';
|
||||||
import { Query } from 'node-appwrite';
|
import { Query } from 'node-appwrite';
|
||||||
import { NewsCard } from '@/components/NewsCard';
|
import { NewsCard } from '@/components/NewsCard';
|
||||||
import { Loader2, Sparkles } from 'lucide-react';
|
import { Sparkles } from 'lucide-react';
|
||||||
|
|
||||||
async function fetchClasificadosData() {
|
async function fetchClasificadosData() {
|
||||||
try {
|
try {
|
||||||
const client = await createAdminClient();
|
const client = await createAdminClient();
|
||||||
|
|
||||||
// 1. Settings for count
|
// 1. Settings
|
||||||
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
||||||
const postsCount = settingsRes.documents.length > 0 ? (settingsRes.documents[0].classifieds_count || 9) : 9;
|
const settings = settingsRes.documents.length > 0 ? settingsRes.documents[0] : {};
|
||||||
|
|
||||||
|
const postsCount = settings.classifieds_count || 9;
|
||||||
|
const cardSettings = {
|
||||||
|
showCategory: settings.news_card_show_category ?? false,
|
||||||
|
showFooterDate: settings.news_card_show_footer_date ?? true,
|
||||||
|
footerText: settings.news_card_footer_text || ""
|
||||||
|
};
|
||||||
|
|
||||||
// 2. Get CLASIFICADO type ID
|
// 2. Get CLASIFICADO type ID
|
||||||
const typeRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'publication_types', [
|
const typeRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'publication_types', [
|
||||||
@ -27,17 +34,27 @@ async function fetchClasificadosData() {
|
|||||||
Query.limit(postsCount)
|
Query.limit(postsCount)
|
||||||
]);
|
]);
|
||||||
posts = postsRes.documents;
|
posts = postsRes.documents;
|
||||||
|
|
||||||
|
// 3. Resolve Media
|
||||||
|
const mediaIds = posts.map(p => p.imagen_destacada_id).filter(id => id && typeof id === 'string');
|
||||||
|
if (mediaIds.length > 0) {
|
||||||
|
const mediaRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', [
|
||||||
|
Query.equal('$id', mediaIds)
|
||||||
|
]);
|
||||||
|
const mediaMap = new Map(mediaRes.documents.map(m => [m.$id, m]));
|
||||||
|
posts = posts.map(p => ({ ...p, resolved_media: mediaMap.get(p.imagen_destacada_id) }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { posts };
|
return { posts, cardSettings };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Clasificados fetch error", e);
|
console.error("Clasificados fetch error", e);
|
||||||
return { posts: [] };
|
return { posts: [], cardSettings: { showCategory: false, showFooterDate: true, footerText: "" } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function ClasificadosPage() {
|
export default async function ClasificadosPage() {
|
||||||
const { posts } = await fetchClasificadosData();
|
const { posts, cardSettings } = await fetchClasificadosData();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="animate-fade-in relative min-h-screen">
|
<main className="animate-fade-in relative min-h-screen">
|
||||||
@ -90,9 +107,10 @@ export default async function ClasificadosPage() {
|
|||||||
{posts.map((post) => {
|
{posts.map((post) => {
|
||||||
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
|
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
|
||||||
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
|
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
|
||||||
let imagenUrl = null;
|
let imagenUrl = post.og_image_url || null;
|
||||||
if (post.imagen_destacada_id) {
|
|
||||||
imagenUrl = `${ENDPOINT}/storage/buckets/${post.imagen_destacada_id.bucket_id}/files/${post.imagen_destacada_id.file_id}/preview?project=${PROJECT_ID}&width=800&height=500&quality=85`;
|
if (post.resolved_media) {
|
||||||
|
imagenUrl = `${ENDPOINT}/storage/buckets/${post.resolved_media.bucket_id}/files/${post.resolved_media.file_id}/preview?project=${PROJECT_ID}&width=800&height=500&quality=85`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -101,10 +119,13 @@ export default async function ClasificadosPage() {
|
|||||||
id={post.$id}
|
id={post.$id}
|
||||||
slug={post.slug || post.$id}
|
slug={post.slug || post.$id}
|
||||||
titulo={post.titulo}
|
titulo={post.titulo}
|
||||||
resumen={post.resumen_redes || post.contenido?.substring(0, 100).replace(/<[^>]*>?/gm, '') + '...'}
|
resumen={post.resumen_redes || post.contenido?.replace(/<[^>]*>?/gm, '').substring(0, 150) + '...'}
|
||||||
tipo="Aviso"
|
tipo="Aviso"
|
||||||
fecha={post.fecha_publicacion || post.$createdAt}
|
fecha={post.fecha_publicacion || post.$createdAt}
|
||||||
imagenUrl={imagenUrl}
|
imagenUrl={imagenUrl}
|
||||||
|
showCategory={cardSettings.showCategory}
|
||||||
|
showFooterDate={cardSettings.showFooterDate}
|
||||||
|
footerText={cardSettings.footerText}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -2,15 +2,22 @@ import { APPWRITE_ALMEIRA_CONFIG } from '@/lib/appwrite';
|
|||||||
import { createAdminClient } from '@/lib/appwrite.server';
|
import { createAdminClient } from '@/lib/appwrite.server';
|
||||||
import { Query } from 'node-appwrite';
|
import { Query } from 'node-appwrite';
|
||||||
import { NewsCard } from '@/components/NewsCard';
|
import { NewsCard } from '@/components/NewsCard';
|
||||||
import { Loader2, Calendar } from 'lucide-react';
|
import { Calendar } from 'lucide-react';
|
||||||
|
|
||||||
async function fetchEventosData() {
|
async function fetchEventosData() {
|
||||||
try {
|
try {
|
||||||
const client = await createAdminClient();
|
const client = await createAdminClient();
|
||||||
|
|
||||||
// 1. Settings for count
|
// 1. Settings
|
||||||
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
||||||
const postsCount = settingsRes.documents.length > 0 ? (settingsRes.documents[0].events_count || 9) : 9;
|
const settings = settingsRes.documents.length > 0 ? settingsRes.documents[0] : {};
|
||||||
|
|
||||||
|
const postsCount = settings.events_count || 9;
|
||||||
|
const cardSettings = {
|
||||||
|
showCategory: settings.news_card_show_category ?? false,
|
||||||
|
showFooterDate: settings.news_card_show_footer_date ?? true,
|
||||||
|
footerText: settings.news_card_footer_text || ""
|
||||||
|
};
|
||||||
|
|
||||||
// 2. Get EVENTO type ID
|
// 2. Get EVENTO type ID
|
||||||
const typeRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'publication_types', [
|
const typeRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'publication_types', [
|
||||||
@ -27,17 +34,27 @@ async function fetchEventosData() {
|
|||||||
Query.limit(postsCount)
|
Query.limit(postsCount)
|
||||||
]);
|
]);
|
||||||
posts = postsRes.documents;
|
posts = postsRes.documents;
|
||||||
|
|
||||||
|
// 3. Resolve Media
|
||||||
|
const mediaIds = posts.map(p => p.imagen_destacada_id).filter(id => id && typeof id === 'string');
|
||||||
|
if (mediaIds.length > 0) {
|
||||||
|
const mediaRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', [
|
||||||
|
Query.equal('$id', mediaIds)
|
||||||
|
]);
|
||||||
|
const mediaMap = new Map(mediaRes.documents.map(m => [m.$id, m]));
|
||||||
|
posts = posts.map(p => ({ ...p, resolved_media: mediaMap.get(p.imagen_destacada_id) }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { posts };
|
return { posts, cardSettings };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Eventos fetch error", e);
|
console.error("Eventos fetch error", e);
|
||||||
return { posts: [] };
|
return { posts: [], cardSettings: { showCategory: false, showFooterDate: true, footerText: "" } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function EventosPage() {
|
export default async function EventosPage() {
|
||||||
const { posts } = await fetchEventosData();
|
const { posts, cardSettings } = await fetchEventosData();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="animate-fade-in relative min-h-screen">
|
<main className="animate-fade-in relative min-h-screen">
|
||||||
@ -90,9 +107,10 @@ export default async function EventosPage() {
|
|||||||
{posts.map((post) => {
|
{posts.map((post) => {
|
||||||
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
|
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
|
||||||
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
|
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
|
||||||
let imagenUrl = null;
|
let imagenUrl = post.og_image_url || null;
|
||||||
if (post.imagen_destacada_id) {
|
|
||||||
imagenUrl = `${ENDPOINT}/storage/buckets/${post.imagen_destacada_id.bucket_id}/files/${post.imagen_destacada_id.file_id}/preview?project=${PROJECT_ID}&width=800&height=500&quality=85`;
|
if (post.resolved_media) {
|
||||||
|
imagenUrl = `${ENDPOINT}/storage/buckets/${post.resolved_media.bucket_id}/files/${post.resolved_media.file_id}/preview?project=${PROJECT_ID}&width=800&height=500&quality=85`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -101,10 +119,13 @@ export default async function EventosPage() {
|
|||||||
id={post.$id}
|
id={post.$id}
|
||||||
slug={post.slug || post.$id}
|
slug={post.slug || post.$id}
|
||||||
titulo={post.titulo}
|
titulo={post.titulo}
|
||||||
resumen={post.resumen_redes || post.contenido?.substring(0, 100).replace(/<[^>]*>?/gm, '') + '...'}
|
resumen={post.resumen_redes || post.contenido?.replace(/<[^>]*>?/gm, '').substring(0, 150) + '...'}
|
||||||
tipo="Evento"
|
tipo="Evento"
|
||||||
fecha={post.fecha_publicacion || post.$createdAt}
|
fecha={post.fecha_publicacion || post.$createdAt}
|
||||||
imagenUrl={imagenUrl}
|
imagenUrl={imagenUrl}
|
||||||
|
showCategory={cardSettings.showCategory}
|
||||||
|
showFooterDate={cardSettings.showFooterDate}
|
||||||
|
footerText={cardSettings.footerText}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -37,9 +37,17 @@ export default async function NoticiaDetail({ params }: { params: { slug: string
|
|||||||
|
|
||||||
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
|
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
|
||||||
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
|
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
|
||||||
let imagenUrl = null;
|
let imagenUrl = post.og_image_url || null;
|
||||||
|
|
||||||
if (post.imagen_destacada_id) {
|
if (post.imagen_destacada_id) {
|
||||||
imagenUrl = `${ENDPOINT}/storage/buckets/${post.imagen_destacada_id.bucket_id}/files/${post.imagen_destacada_id.file_id}/preview?project=${PROJECT_ID}&width=1200&height=600&quality=90`;
|
// En vista de detalle, resolvemos el documento de media
|
||||||
|
try {
|
||||||
|
const client = await createAdminClient();
|
||||||
|
const mediaRes = await client.databases.getDocument(APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', post.imagen_destacada_id);
|
||||||
|
if (mediaRes) {
|
||||||
|
imagenUrl = `${ENDPOINT}/storage/buckets/${mediaRes.bucket_id}/files/${mediaRes.file_id}/preview?project=${PROJECT_ID}&width=1200&height=600&quality=90`;
|
||||||
|
}
|
||||||
|
} catch(e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fechaObj = new Date(post.fecha_publicacion || post.$createdAt);
|
const fechaObj = new Date(post.fecha_publicacion || post.$createdAt);
|
||||||
|
|||||||
@ -3,16 +3,22 @@ import { createAdminClient } from '@/lib/appwrite.server';
|
|||||||
import { Query } from 'node-appwrite';
|
import { Query } from 'node-appwrite';
|
||||||
import { NewsCard } from '@/components/NewsCard';
|
import { NewsCard } from '@/components/NewsCard';
|
||||||
import { GlobalSidebar } from '@/components/AdWrappers';
|
import { GlobalSidebar } from '@/components/AdWrappers';
|
||||||
import { RadioTower, Sparkles, ChevronDown, Loader2 } from 'lucide-react';
|
import { RadioTower, Sparkles, ChevronDown } from 'lucide-react';
|
||||||
import { Suspense } from 'react';
|
|
||||||
|
|
||||||
async function fetchHomeData() {
|
async function fetchHomeData() {
|
||||||
try {
|
try {
|
||||||
const client = await createAdminClient();
|
const client = await createAdminClient();
|
||||||
|
|
||||||
// 1. Settings for count
|
// 1. Settings
|
||||||
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
||||||
const postsCount = settingsRes.documents.length > 0 ? (settingsRes.documents[0].feed_count || settingsRes.documents[0].post_count || 9) : 9;
|
const settings = settingsRes.documents.length > 0 ? settingsRes.documents[0] : {};
|
||||||
|
|
||||||
|
const postsCount = settings.feed_count || settings.post_count || 9;
|
||||||
|
const cardSettings = {
|
||||||
|
showCategory: settings.news_card_show_category ?? false,
|
||||||
|
showFooterDate: settings.news_card_show_footer_date ?? true,
|
||||||
|
footerText: settings.news_card_footer_text || ""
|
||||||
|
};
|
||||||
|
|
||||||
// 2. Get NOTICIA type ID
|
// 2. Get NOTICIA type ID
|
||||||
const typeRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'publication_types', [
|
const typeRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'publication_types', [
|
||||||
@ -29,17 +35,31 @@ async function fetchHomeData() {
|
|||||||
Query.limit(postsCount)
|
Query.limit(postsCount)
|
||||||
]);
|
]);
|
||||||
posts = postsRes.documents;
|
posts = postsRes.documents;
|
||||||
|
|
||||||
|
// 3. Resolve Media documents for images
|
||||||
|
const mediaIds = posts.map(p => p.imagen_destacada_id).filter(id => id && typeof id === 'string');
|
||||||
|
if (mediaIds.length > 0) {
|
||||||
|
const mediaRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', [
|
||||||
|
Query.equal('$id', mediaIds)
|
||||||
|
]);
|
||||||
|
const mediaMap = new Map(mediaRes.documents.map(m => [m.$id, m]));
|
||||||
|
|
||||||
|
posts = posts.map(p => ({
|
||||||
|
...p,
|
||||||
|
resolved_media: mediaMap.get(p.imagen_destacada_id)
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { posts };
|
return { posts, cardSettings };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Home fetch error", e);
|
console.error("Home fetch error", e);
|
||||||
return { posts: [] };
|
return { posts: [], cardSettings: { showCategory: false, showFooterDate: true, footerText: "" } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
const { posts } = await fetchHomeData();
|
const { posts, cardSettings } = await fetchHomeData();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="animate-fade-in relative">
|
<main className="animate-fade-in relative">
|
||||||
@ -110,9 +130,10 @@ export default async function Home() {
|
|||||||
{posts.map((post) => {
|
{posts.map((post) => {
|
||||||
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
|
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
|
||||||
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
|
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
|
||||||
let imagenUrl = null;
|
let imagenUrl = post.og_image_url || null;
|
||||||
if (post.imagen_destacada_id) {
|
|
||||||
imagenUrl = `${ENDPOINT}/storage/buckets/${post.imagen_destacada_id.bucket_id}/files/${post.imagen_destacada_id.file_id}/preview?project=${PROJECT_ID}&width=800&height=500&quality=85`;
|
if (post.resolved_media) {
|
||||||
|
imagenUrl = `${ENDPOINT}/storage/buckets/${post.resolved_media.bucket_id}/files/${post.resolved_media.file_id}/preview?project=${PROJECT_ID}&width=800&height=500&quality=85`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -121,10 +142,13 @@ export default async function Home() {
|
|||||||
id={post.$id}
|
id={post.$id}
|
||||||
slug={post.slug || post.$id}
|
slug={post.slug || post.$id}
|
||||||
titulo={post.titulo}
|
titulo={post.titulo}
|
||||||
resumen={post.resumen_redes || post.contenido?.substring(0, 100).replace(/<[^>]*>?/gm, '') + '...'}
|
resumen={post.resumen_redes || post.contenido?.replace(/<[^>]*>?/gm, '').substring(0, 150) + '...'}
|
||||||
tipo="Noticia"
|
tipo="Noticia"
|
||||||
fecha={post.fecha_publicacion || post.$createdAt}
|
fecha={post.fecha_publicacion || post.$createdAt}
|
||||||
imagenUrl={imagenUrl}
|
imagenUrl={imagenUrl}
|
||||||
|
showCategory={cardSettings.showCategory}
|
||||||
|
showFooterDate={cardSettings.showFooterDate}
|
||||||
|
footerText={cardSettings.footerText}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -1,7 +1,31 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { ArrowUpRight, Calendar } from 'lucide-react';
|
import { ArrowUpRight, Calendar } from 'lucide-react';
|
||||||
|
|
||||||
export const NewsCard = ({ id, slug, titulo, resumen, tipo, fecha, imagenUrl }: any) => {
|
interface NewsCardProps {
|
||||||
|
id: string;
|
||||||
|
slug: string;
|
||||||
|
titulo: string;
|
||||||
|
resumen: string;
|
||||||
|
tipo?: string;
|
||||||
|
fecha: string;
|
||||||
|
imagenUrl?: string | null;
|
||||||
|
showCategory?: boolean;
|
||||||
|
showFooterDate?: boolean;
|
||||||
|
footerText?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NewsCard = ({
|
||||||
|
id,
|
||||||
|
slug,
|
||||||
|
titulo,
|
||||||
|
resumen,
|
||||||
|
tipo,
|
||||||
|
fecha,
|
||||||
|
imagenUrl,
|
||||||
|
showCategory = false,
|
||||||
|
showFooterDate = true,
|
||||||
|
footerText
|
||||||
|
}: NewsCardProps) => {
|
||||||
// Formatear fecha
|
// Formatear fecha
|
||||||
const fechaObj = new Date(fecha);
|
const fechaObj = new Date(fecha);
|
||||||
const fechaFormateada = fechaObj.toLocaleDateString('es-ES', { day: '2-digit', month: 'short', year: 'numeric' });
|
const fechaFormateada = fechaObj.toLocaleDateString('es-ES', { day: '2-digit', month: 'short', year: 'numeric' });
|
||||||
@ -14,22 +38,24 @@ export const NewsCard = ({ id, slug, titulo, resumen, tipo, fecha, imagenUrl }:
|
|||||||
{imagenUrl ? (
|
{imagenUrl ? (
|
||||||
<img src={imagenUrl} alt={titulo} className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110" />
|
<img src={imagenUrl} alt={titulo} className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110" />
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-full flex items-center justify-center text-slate-600 font-bold uppercase tracking-widest text-sm bg-[radial-gradient(ellipse_at_center,_var(--tw-gradient-stops))] from-slate-800 to-slate-900">
|
<div className="w-full h-full flex items-center justify-center bg-[radial-gradient(ellipse_at_center,_var(--tw-gradient-stops))] from-slate-800 to-slate-900">
|
||||||
Almeira Media
|
{/* No placeholder text as per user request */}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Badge/Tag */}
|
{/* Badge/Tag - Habilitable por prop */}
|
||||||
<div className="absolute top-4 left-4 z-20">
|
{showCategory && (
|
||||||
<span className="px-3 py-1.5 rounded-full text-xs font-bold uppercase tracking-wider backdrop-blur-md border border-white/20 bg-black/40 text-cyan-300 shadow-[0_0_10px_rgba(6,182,212,0.2)]">
|
<div className="absolute top-4 left-4 z-20">
|
||||||
{tipo?.toUpperCase() || 'NOTICIA'}
|
<span className="px-3 py-1.5 rounded-full text-xs font-bold uppercase tracking-wider backdrop-blur-md border border-white/20 bg-black/40 text-cyan-300 shadow-[0_0_10px_rgba(6,182,212,0.2)]">
|
||||||
</span>
|
{tipo?.toUpperCase() || 'NOTICIA'}
|
||||||
</div>
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Contenido */}
|
{/* Contenido */}
|
||||||
<div className="flex flex-col flex-grow p-6 relative z-20">
|
<div className="flex flex-col flex-grow p-6 relative z-20">
|
||||||
<div className="flex items-center gap-2 text-cyan-500/80 text-xs font-bold tracking-widest uppercase mb-4">
|
<div className="flex items-center gap-2 text-cyan-500/80 text-sm font-bold tracking-widest uppercase mb-4">
|
||||||
<Calendar size={14} />
|
<Calendar size={14} />
|
||||||
<span>{fechaFormateada}</span>
|
<span>{fechaFormateada}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -45,7 +71,14 @@ export const NewsCard = ({ id, slug, titulo, resumen, tipo, fecha, imagenUrl }:
|
|||||||
{/* Footer del card */}
|
{/* Footer del card */}
|
||||||
<div className="mt-auto pt-5 border-t border-white/10 flex items-center justify-between">
|
<div className="mt-auto pt-5 border-t border-white/10 flex items-center justify-between">
|
||||||
<span className="text-xs font-black tracking-widest uppercase text-cyan-500 group-hover:text-cyan-300 transition-colors">
|
<span className="text-xs font-black tracking-widest uppercase text-cyan-500 group-hover:text-cyan-300 transition-colors">
|
||||||
Expandir Registro
|
{showFooterDate ? (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Calendar size={12} />
|
||||||
|
{fechaFormateada}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
footerText || "Ver más"
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<div className="w-8 h-8 rounded-full bg-white/5 flex items-center justify-center border border-white/10 group-hover:bg-cyan-500 group-hover:border-cyan-400 group-hover:text-slate-950 transition-all">
|
<div className="w-8 h-8 rounded-full bg-white/5 flex items-center justify-center border border-white/10 group-hover:bg-cyan-500 group-hover:border-cyan-400 group-hover:text-slate-950 transition-all">
|
||||||
<ArrowUpRight size={16} className="transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
|
<ArrowUpRight size={16} className="transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
|
||||||
|
|||||||
@ -20,26 +20,52 @@ export default async function NewsTicker() {
|
|||||||
// Since 'createSessionClient' uses the session cookie, we might have issues on public incognito pages.
|
// Since 'createSessionClient' uses the session cookie, we might have issues on public incognito pages.
|
||||||
// The user previously used Admin API key for everything or a local backdoor.
|
// The user previously used Admin API key for everything or a local backdoor.
|
||||||
|
|
||||||
// Settings
|
// Settings const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
||||||
const settingsRes = await sessionClient.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []);
|
const settings: any = settingsRes.documents.length > 0 ? settingsRes.documents[0] : {};
|
||||||
const tickerCount = settingsRes.documents.length > 0 ? settingsRes.documents[0].ticker_count : 10;
|
const tickerCount = settings.ticker_count || 10;
|
||||||
|
|
||||||
// Get Type ID for "Noticia"
|
// 2. Get NOTICIA type ID
|
||||||
const typeRes = await sessionClient.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'publication_types', [
|
const typeRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'publication_types', [
|
||||||
Query.equal('codigo', 'NOTICIA')
|
Query.equal('codigo', 'NOTICIA')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (typeRes.documents.length > 0) {
|
let newsItems: any[] = [];
|
||||||
const typeId = typeRes.documents[0].$id;
|
if (typeRes.documents.length > 0) {
|
||||||
|
const typeId = typeRes.documents[0].$id;
|
||||||
|
|
||||||
const postsRes = await sessionClient.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'posts', [
|
const postsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'posts', [
|
||||||
Query.equal('tipo_publicacion_id', typeId),
|
Query.equal('tipo_publicacion_id', typeId),
|
||||||
Query.equal('estado', 'Publicado'),
|
Query.equal('estado', 'Publicado'),
|
||||||
Query.orderDesc('fecha_publicacion'),
|
Query.orderDesc('fecha_publicacion'),
|
||||||
Query.limit(tickerCount)
|
Query.limit(tickerCount)
|
||||||
]);
|
]);
|
||||||
noticias = postsRes.documents;
|
|
||||||
}
|
// Resolve Media
|
||||||
|
const mediaIds = postsRes.documents.map(p => p.imagen_destacada_id).filter(id => id && typeof id === 'string');
|
||||||
|
const mediaMap = new Map();
|
||||||
|
if (mediaIds.length > 0) {
|
||||||
|
const mediaRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', [
|
||||||
|
Query.equal('$id', mediaIds)
|
||||||
|
]);
|
||||||
|
mediaRes.documents.forEach(m => mediaMap.set(m.$id, m));
|
||||||
|
}
|
||||||
|
|
||||||
|
newsItems = postsRes.documents.map(post => {
|
||||||
|
const media = mediaMap.get(post.imagen_destacada_id);
|
||||||
|
let imagenUrl = post.og_image_url || null;
|
||||||
|
if (media) {
|
||||||
|
imagenUrl = `${process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1'}/storage/buckets/${media.bucket_id}/files/${media.file_id}/preview?project=${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c'}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: post.$id,
|
||||||
|
titulo: post.titulo,
|
||||||
|
slug: post.slug || post.$id,
|
||||||
|
imagenUrl
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
noticias = newsItems; // Assign resolved news items to 'noticias'
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Ticker fetch error", e);
|
console.error("Ticker fetch error", e);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user