fix: vídeos en Social y notas Superhuman por día desde Drive
Los docs de seguimiento son Google Docs embebidos: se exportan, se parten por fecha y se acumulan. Social renderiza VIDEO/REELS y trae vídeos de página. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -14,7 +14,6 @@ import {
|
||||
Send,
|
||||
} from 'lucide-react';
|
||||
import { PageHeader } from '@/components/ui';
|
||||
import { useDateRange } from '@/components/DateRangeContext';
|
||||
|
||||
type Entry = {
|
||||
id: string;
|
||||
@@ -49,14 +48,7 @@ function typeTone(t: string) {
|
||||
return 'bg-violet-50 text-violet-800 border-violet-200';
|
||||
}
|
||||
|
||||
function inRange(isoDate: string | undefined | null, since: string, until: string) {
|
||||
if (!isoDate) return true; // keep undated notes visible
|
||||
const d = isoDate.slice(0, 10);
|
||||
return d >= since && d <= until;
|
||||
}
|
||||
|
||||
export default function SeguimientoBoard() {
|
||||
const { since, until, label: rangeLabel } = useDateRange();
|
||||
const [data, setData] = useState<Payload | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [err, setErr] = useState<string | null>(null);
|
||||
@@ -90,13 +82,14 @@ export default function SeguimientoBoard() {
|
||||
const filteredEntries = useMemo(() => {
|
||||
const entries = data?.entries || [];
|
||||
const q = query.trim().toLowerCase();
|
||||
// Histórico completo (más reciente → más antiguo). El periodo del header
|
||||
// no oculta notas: el doc Superhuman/Drive acumula todos los días.
|
||||
return entries.filter((e) => {
|
||||
if (!inRange(e.occurred_at, since, until)) return false;
|
||||
if (!q) return true;
|
||||
const blob = `${e.title} ${e.summary || ''} ${e.body_md || ''}`.toLowerCase();
|
||||
return blob.includes(q);
|
||||
});
|
||||
}, [data, query, since, until]);
|
||||
}, [data, query]);
|
||||
|
||||
async function saveNote() {
|
||||
if (!noteBody.trim()) return;
|
||||
@@ -136,7 +129,7 @@ export default function SeguimientoBoard() {
|
||||
body: JSON.stringify({
|
||||
tenantId: data.tenantId,
|
||||
exportBodies: true,
|
||||
maxEntries: 80,
|
||||
maxEntries: 120,
|
||||
}),
|
||||
});
|
||||
const json = await res.json().catch(() => ({}));
|
||||
@@ -195,7 +188,7 @@ export default function SeguimientoBoard() {
|
||||
<PageHeader
|
||||
eyebrow="Operación"
|
||||
title="Seguimiento"
|
||||
description={`${data.label} · notas e histórico del equipo (periodo ${rangeLabel}). Ads y KPIs están en Métricas.`}
|
||||
description={`${data.label} · histórico de notas (más reciente primero). El periodo del header no filtra este timeline.`}
|
||||
/>
|
||||
|
||||
<section className="rounded-2xl border border-gray-200 bg-white p-5 space-y-3">
|
||||
|
||||
@@ -63,6 +63,7 @@ type SocialPost = {
|
||||
platform: 'facebook' | 'instagram';
|
||||
message?: string;
|
||||
mediaUrl?: string | null;
|
||||
thumbnailUrl?: string | null;
|
||||
permalink?: string | null;
|
||||
createdAt?: string | null;
|
||||
likes: number;
|
||||
@@ -73,6 +74,13 @@ type SocialPost = {
|
||||
mediaType?: string | null;
|
||||
};
|
||||
|
||||
function isVideoPost(p: SocialPost): boolean {
|
||||
const t = (p.mediaType || '').toUpperCase();
|
||||
if (t.includes('VIDEO') || t === 'REELS' || t === 'REEL') return true;
|
||||
const url = p.mediaUrl || '';
|
||||
return /\.mp4($|\?)/i.test(url) || /video/i.test(url);
|
||||
}
|
||||
|
||||
const CHANNELS: {
|
||||
id: string;
|
||||
label: string;
|
||||
@@ -307,10 +315,19 @@ export default function SocialDashboard({
|
||||
className="rounded-2xl border border-gray-200 bg-white overflow-hidden flex flex-col"
|
||||
>
|
||||
<div className="relative aspect-square bg-gray-100">
|
||||
{p.mediaUrl ? (
|
||||
{p.mediaUrl && isVideoPost(p) ? (
|
||||
<video
|
||||
src={p.mediaUrl}
|
||||
poster={p.thumbnailUrl || undefined}
|
||||
className="absolute inset-0 w-full h-full object-cover"
|
||||
controls
|
||||
playsInline
|
||||
preload="metadata"
|
||||
/>
|
||||
) : p.mediaUrl || p.thumbnailUrl ? (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={p.mediaUrl}
|
||||
src={p.thumbnailUrl || p.mediaUrl || ''}
|
||||
alt=""
|
||||
className="absolute inset-0 w-full h-full object-cover"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user