diff --git a/src/components/OrganicoDashboard.tsx b/src/components/OrganicoDashboard.tsx index 0f54f20..ff94f88 100644 --- a/src/components/OrganicoDashboard.tsx +++ b/src/components/OrganicoDashboard.tsx @@ -547,15 +547,12 @@ export default function OrganicoDashboard({
- {/* Paneles por sección (no el mismo dashboard en todos) */} + {/* Paneles SEO por sección */} {section.id === 'seo-overview' && ( <>
- +
{seoDaily.length > 0 && ( @@ -589,16 +586,10 @@ export default function OrganicoDashboard({

{seoDaily.map((d) => ( -
+
))} @@ -610,16 +601,10 @@ export default function OrganicoDashboard({

{seoDaily.map((d) => ( -
+
))} @@ -628,7 +613,7 @@ export default function OrganicoDashboard({
)} {totals.days === 0 && ( - + )} )} - {(section.id === 'seo-keywords' || - section.id === 'seo-rankings' || - section.id === 'seo-keyword-magic' || - section.id === 'seo-keyword-gap') && ( - + {section.live === 'seo-foundations' && ( +
+

+ Checklist de auditoría operativa. El estado «OK» de medición + refleja si GA4 + GSC están conectados; el resto lo cierra el equipo. +

+
    + {SEO_FOUNDATIONS.map((f) => { + const ok = + f.id === 'medicion' && + ga4?.status === 'connected' && + gsc?.status === 'connected'; + return ( +
  • +

    + {f.title} + {ok ? ( + + OK + + ) : ( + + Revisar + + )} +

    +

    {f.hint}

    +
  • + ); + })} +
+
+

Estado conexiones

+

GSC: {gsc?.status === 'connected' ? 'conectado' : 'sin conectar'}{gsc?.external_account_id ? ` · ${gsc.external_account_id}` : ''}

+

GA4: {ga4?.status === 'connected' ? 'conectado' : 'sin conectar'}{ga4?.external_account_id ? ` · ${ga4.external_account_id}` : ''}

+
+
)} - {(section.id === 'seo-pages' || - section.id === 'seo-organic' || - section.id === 'seo-traffic-insights' || - section.id === 'seo-compare') && ( + {section.live === 'seo-rankings' && ( +
+
+ Sí hay histórico: posición media diaria en{' '} + organic_daily (acumulamos + nosotros). Las queries actuales vienen live de GSC (ventana ~28d). + No es un rank tracker de 10k KW tipo Semrush. +
+
+ + + +
+ {seoDaily.length > 0 && ( +
+

+ Posición media GSC · histórico diario +

+
+ {organic + .filter((r) => r.day) + .sort((a, b) => String(a.day).localeCompare(String(b.day))) + .slice(-28) + .map((r) => { + const pos = Number(r.gsc_avg_position) || 0; + const h = + pos > 0 ? Math.max(8, Math.min(100, (1 / pos) * 100)) : 4; + return ( +
+
+
+ ); + })} +
+

+ Barras más altas ≈ mejor posición (inverso) +

+
+ )} + a.position - b.position)} + pages={[]} + landings={[]} + focus="queries" + /> +
+ )} + + {section.live === 'seo-trend' && ( +
+
+ + + + +
+ {seoDaily.length > 0 ? ( +
+
+

+ Clics · evolución +

+
+ {seoDaily.map((d) => ( +
+
+
+ ))} +
+
+
+

+ Sesiones orgánicas · evolución +

+
+ {seoDaily.map((d) => ( +
+
+
+ ))} +
+
+
+ ) : ( + + )} +
+ )} + + {section.live === 'seo-pages' && ( )} - {section.id === 'seo-organic' && seoDaily.length > 0 && ( -
-

- Evolución clics orgánicos + {section.live === 'seo-queries' && ( + + )} + + {section.live === 'seo-cross' && ( +

+

+ Cruce: qué URLs rankean (GSC) vs qué landings reciben sesión + orgánica (GA4).

-
- {seoDaily.map((d) => ( -
-
-
- ))} -
+ +
+ )} + + {section.live === 'seo-content' && ( +
+

+ Ideas a partir de queries con impresiones altas y CTR bajo + (oportunidad de mejorar snippet / contenido). +

+ q.impressions >= 50) + .sort((a, b) => a.ctr - b.ctr) + .slice(0, 25)} + pages={[]} + landings={[]} + focus="queries" + />
)} @@ -793,32 +943,6 @@ export default function OrganicoDashboard({ )} - {section.live === 'seo-foundations' && ( -
    - {SEO_FOUNDATIONS.map((f) => { - const ok = - f.id === 'medicion' && - ga4?.status === 'connected' && - gsc?.status === 'connected'; - return ( -
  • -

    - {f.title} -

    -

    {f.hint}

    -
  • - ); - })} -
- )} - {/* Prioridades + notas solo en visión general SEO/GEO */} {(section.id === 'seo-overview' || section.id === 'geo-overview') && (
@@ -930,10 +1054,28 @@ export default function OrganicoDashboard({ )} {section.soon && ( -

- Disponible en breve: informes de ROI IA + tráfico/conversiones GA4 - en un clic. -

+
+

+ Requiere herramienta externa +

+

+ Competencia de dominio, keyword gap y backlinks no salen de + GSC/GA4. Hay que conectar Ahrefs/Semrush (o importar CSV) para + alimentar este panel. Mientras tanto usa las secciones con datos + reales: visión general, rankings, keywords y páginas. +

+
    + {section.actions.map((a) => ( +
  • + + {a} +
  • + ))} +
+
)} {!section.soon && diff --git a/src/lib/organic.ts b/src/lib/organic.ts index c47bc21..709cb8c 100644 --- a/src/lib/organic.ts +++ b/src/lib/organic.ts @@ -213,7 +213,18 @@ export type OrganicoSection = { blurb: string; /** What the user should do next when empty. */ actions: string[]; - live?: 'seo-metrics' | 'geo-metrics' | 'geo-competitors' | 'geo-categories' | 'seo-foundations'; + live?: + | 'seo-metrics' + | 'seo-foundations' + | 'seo-rankings' + | 'seo-trend' + | 'seo-pages' + | 'seo-queries' + | 'seo-cross' + | 'seo-content' + | 'geo-metrics' + | 'geo-competitors' + | 'geo-categories'; soon?: boolean; }; @@ -370,18 +381,18 @@ export const ORGANICO_SECTIONS: OrganicoSection[] = [ soon: true, }, - // ——— SEO ——— + // ——— SEO (solo secciones con datos reales GSC/GA4 o checklist operable) ——— { id: 'seo-overview', pillar: 'seo', group: 'Rendimiento del sitio', label: 'Visión general', blurb: - 'Hazte visible donde busca tu audiencia. Serie diaria desde GA4/GSC — el portal guarda histórico propio (GSC solo ofrece ~16 meses en API).', + 'KPIs diarios GA4 + GSC. El histórico vive en organic_daily (nosotros lo acumulamos; la API de GSC sola no basta).', actions: [ 'Conectar Search Console y GA4', - 'Sincronizar (histórico acumulado en organic_daily)', - 'Definir 3 prioridades del mes', + 'Revisar serie 28d', + 'Definir prioridades del mes', ], live: 'seo-metrics', }, @@ -391,11 +402,11 @@ export const ORGANICO_SECTIONS: OrganicoSection[] = [ group: 'Rendimiento del sitio', label: 'Auditoría del sitio', blurb: - 'Consulta problemas de SEO que limitan posicionamiento: salud, contenido y UX.', + 'Checklist operativo de salud SEO (indexación, arquitectura, CWV, contenido, medición). No es un crawl Semrush: es la base que hay que cerrar con los datos conectados.', actions: [ - 'Auditar indexación y CWV', - 'Corregir errores críticos', - 'Plan de remediación por impacto', + 'Marcar OK/KO por bloque', + 'Priorizar indexación + medición', + 'CWV en landings de conversión', ], live: 'seo-foundations', }, @@ -405,240 +416,97 @@ export const ORGANICO_SECTIONS: OrganicoSection[] = [ group: 'Rendimiento del sitio', label: 'Rastreo de posición', blurb: - 'Rastrea posicionamiento en Google (y más adelante Bing / Modo IA) para keywords de alto valor.', + 'Sí: posición media diaria en organic_daily (histórico nuestro) + ranking actual de queries GSC. No es un rank tracker de 10k KW tipo Semrush; es lo que GSC reporta para tus impresiones reales.', actions: [ - 'Definir cartera de keywords', - 'Registrar posición media GSC', - 'Alertar caídas de top 10', + 'Mirar tendencia de posición media', + 'Atacar queries en pos. 4–15 (quick wins)', + 'Ampliar cartera vía contenido', ], - live: 'seo-metrics', - }, - { - id: 'seo-competition', - pillar: 'seo', - group: 'Análisis de la competencia', - label: 'Visión general del dominio', - blurb: - 'Supera a tu competencia con análisis SEO: tráfico, keywords y estrategias.', - actions: [ - 'Fijar 3 dominios rivales', - 'Comparar autoridad y temáticas', - 'Extraer oportunidades de contenido', - ], - soon: true, + live: 'seo-rankings', }, { id: 'seo-organic', pillar: 'seo', - group: 'Análisis de la competencia', + group: 'Tráfico y páginas', label: 'Posicionamiento orgánico', blurb: - 'Mide visibilidad orgánica y evolución de clics/impresiones frente al mercado.', + 'Evolución de clics e impresiones (visibilidad). Distinto de «Páginas principales».', actions: [ - 'Revisar serie GSC MoM', - 'Identificar queries en ascenso/descenso', - 'Alinear con objetivos de negocio', + 'Leer tendencia MoM de clics', + 'Cruzar con campañas de contenido', + 'Alertar caídas bruscas', ], - live: 'seo-metrics', + live: 'seo-trend', }, { id: 'seo-pages', pillar: 'seo', - group: 'Análisis de la competencia', + group: 'Tráfico y páginas', label: 'Páginas principales', - blurb: 'Landings que concentran tráfico y conversión orgánica.', - actions: [ - 'Listar top páginas por clics', - 'Optimizar títulos/meta y UX', - 'Reforzar enlazado interno', - ], - }, - { - id: 'seo-compare', - pillar: 'seo', - group: 'Análisis de la competencia', - label: 'Comparación de dominios', - blurb: 'Compara tu dominio con rivales en una sola vista.', - actions: [ - 'Elegir métricas comunes (tráfico, KW, backlinks)', - 'Marcar gaps críticos', - 'Asignar owners internos', - ], - }, - { - id: 'seo-keyword-gap', - pillar: 'seo', - group: 'Análisis de la competencia', - label: 'Brecha de palabras clave', blurb: - 'Keywords donde rivales rankean y tú no — hoja de ruta clara.', + 'URLs que concentran clics GSC + landings orgánicas GA4. No es el mismo panel que posicionamiento.', actions: [ - 'Exportar gap vs top rivales', - 'Priorizar por intención de compra', - 'Crear o potenciar páginas', - ], - }, - { - id: 'seo-backlink-gap', - pillar: 'seo', - group: 'Análisis de la competencia', - label: 'Brecha de backlinks', - blurb: - 'Dominios que enlazan a rivales y no a ti: autoridad y confianza.', - actions: [ - 'Listar dominios de referencia únicos de rivales', - 'Pitch / digital PR', - 'Monitorizar nuevos enlaces', + 'Optimizar top 10 URLs', + 'Alinear title/H1/CTA', + 'Enlazar desde hubs', ], + live: 'seo-pages', }, { id: 'seo-keywords', pillar: 'seo', - group: 'Investigación de palabras clave', + group: 'Keywords', label: 'Visión general de keywords', blurb: - 'Palabras clave y prompts con intención de compra para Google y ChatGPT.', + 'Queries reales con impresiones/clics/CTR/posición desde Search Console (28d).', actions: [ - 'Mapear KW → intención → URL', - 'Detectar huecos de cobertura', - 'Alinear con calendario editorial', - ], - }, - { - id: 'seo-keyword-magic', - pillar: 'seo', - group: 'Investigación de palabras clave', - label: 'Keyword Magic / ideas', - blurb: 'Explora ideas de keywords y variantes semánticas.', - actions: [ - 'Sembrar seed keywords del negocio', - 'Agrupar por clusters', - 'Seleccionar quick wins', - ], - }, - { - id: 'seo-strategy', - pillar: 'seo', - group: 'Investigación de palabras clave', - label: 'Keyword Strategy Builder', - blurb: 'Construye la estrategia de keywords del trimestre.', - actions: [ - 'Definir pilares y clusters', - 'Asignar prioridad P1/P2/P3', - 'Vincular a OKRs', - ], - }, - { - id: 'seo-content-ideas', - pillar: 'seo', - group: 'Ideas de contenido', - label: 'Ideas de contenido', - blurb: - 'Temas en tendencia, planes y briefings optimizados para posicionar.', - actions: [ - 'Topic research del mes', - 'Briefs con outline + KW + FAQs', - 'Publicar y medir en GSC', - ], - }, - { - id: 'seo-writing', - pillar: 'seo', - group: 'Ideas de contenido', - label: 'SEO Writing Assistant', - blurb: 'Asistencia para redactar y optimizar on-page.', - actions: [ - 'Revisar densidad y entidades', - 'Mejorar claridad y E-E-A-T', - 'Checklist pre-publicación', - ], - }, - { - id: 'seo-topics', - pillar: 'seo', - group: 'Ideas de contenido', - label: 'Topic Research', - blurb: 'Tendencias de temas que alimentan SEO y GEO.', - actions: [ - 'Cruzar topics con prompts IA', - 'Detectar ángulos diferenciales', - 'Planificar pieza pilar + satélites', - ], - }, - { - id: 'seo-template', - pillar: 'seo', - group: 'Ideas de contenido', - label: 'SEO Content Template', - blurb: 'Plantillas de contenido basadas en lo que rankea.', - actions: [ - 'Analizar SERP / respuestas IA', - 'Definir estructura ganadora', - 'Reutilizar en el equipo', - ], - }, - { - id: 'seo-backlinks', - pillar: 'seo', - group: 'Generación de enlaces', - label: 'Backlinks', - blurb: - 'Gana autoridad con backlinks de calidad que impulsan confianza y SEO.', - actions: [ - 'Auditar perfil actual', - 'Campañas de link earning', - 'Desautorizar tóxicos', - ], - }, - { - id: 'seo-refdomains', - pillar: 'seo', - group: 'Generación de enlaces', - label: 'Dominios de referencia', - blurb: 'Diversidad y calidad de dominios que te enlazan.', - actions: [ - 'Medir referidos únicos', - 'Buscar nichos afines', - 'Relaciones con medios / partners', - ], - }, - { - id: 'seo-backlink-audit', - pillar: 'seo', - group: 'Generación de enlaces', - label: 'Backlink Audit', - blurb: 'Salud del perfil de enlaces y riesgo reputacional.', - actions: [ - 'Clasificar enlaces', - 'Disavow si procede', - 'Informe trimestral', - ], - }, - { - id: 'seo-onpage', - pillar: 'seo', - group: 'Extras', - label: 'On Page SEO Checker', - blurb: 'Comprueba on-page en URLs prioritarias.', - actions: [ - 'Auditar top landings', - 'Corregir title/H1/internal links', - 'Re-crawl', + 'Mapear KW → URL', + 'Separar informativas vs compra', + 'Priorizar quick wins', ], + live: 'seo-queries', }, { id: 'seo-traffic-insights', pillar: 'seo', - group: 'Extras', + group: 'Keywords', label: 'Organic Traffic Insights', blurb: - 'Cruza GSC + GA4: cómo el orgánico mueve tráfico y conversiones reales.', + 'Cruce GSC (páginas) + GA4 (sesiones orgánicas / landings) para ver qué rankea y qué convierte.', actions: [ - 'Conectar GA4', - 'Atribuir landings a leads/ventas', + 'Comparar top pages GSC vs landings GA4', + 'Detectar páginas con clics y poca conversión', 'Informar ROI orgánico', ], - live: 'seo-metrics', + live: 'seo-cross', + }, + { + id: 'seo-competition', + pillar: 'seo', + group: 'Competencia y enlaces', + label: 'Competencia / backlinks', + blurb: + 'Requiere Ahrefs/Semrush u otra fuente de backlinks y dominio rival. No está en GSC/GA4. Aquí solo el marco de trabajo hasta integrar una herramienta.', + actions: [ + 'Fijar 3 dominios rivales', + 'Importar gap KW / backlinks desde herramienta externa', + 'Priorizar 5 acciones/mes', + ], + soon: true, + }, + { + id: 'seo-content-ideas', + pillar: 'seo', + group: 'Contenido', + label: 'Ideas de contenido', + blurb: + 'Briefs a partir de queries GSC con tracción (clics o impresiones altas y CTR bajo).', + actions: [ + 'Partir de queries con CTR bajo', + 'Crear/ampliar pieza', + 'Medir de nuevo en 28d', + ], + live: 'seo-content', }, ];