From edf82bf7fd506ca58ae7c11333242195a80a2ba3 Mon Sep 17 00:00:00 2001
From: markosbenitez
Date: Thu, 11 Jun 2026 16:35:03 -0300
Subject: [PATCH] feat(dashboard): selector de empresa + flag p_all en
_dash_responses
---
app/dashboard/page.tsx | 24 ++++++++++++++
app/globals.css | 8 +++++
.../20260611000001_dash_responses_all.sql | 33 +++++++++++++++++++
3 files changed, 65 insertions(+)
create mode 100644 supabase/migrations/20260611000001_dash_responses_all.sql
diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx
index a38bb7e..1a8c9ff 100644
--- a/app/dashboard/page.tsx
+++ b/app/dashboard/page.tsx
@@ -14,6 +14,14 @@ import { FilterSidebar } from '@/components/dashboard/filter-sidebar'
import type { DashboardFilters } from '@/lib/dashboard-types'
// El survey_id se pasa como query param: /dashboard?survey_id=UUID
+// '00000000-0000-0000-0000-000000000000' = flag p_all (vista agregada de todos los surveys)
+const SURVEY_OPTIONS = [
+ { label: 'Todos', id: '00000000-0000-0000-0000-000000000000' },
+ { label: 'InQuality', id: '30000000-0000-0000-0000-000000000002' },
+ { label: 'Fundación Solidaridad', id: '30000000-0000-0000-0000-000000000003' },
+ { label: 'Demo', id: '30000000-0000-0000-0000-000000000001' },
+]
+
export default function DashboardPage() {
const searchParams = useSearchParams()
const surveyId = searchParams.get('survey_id') ?? '30000000-0000-0000-0000-000000000001'
@@ -40,6 +48,22 @@ export default function DashboardPage() {
Datos agregados · k-anonimato k≥5 · Encuesta Mapeo de Cuidadores 2026
{filters.depto && · Filtro: {filters.depto}}
+
{/* Fila 1: KPIs (span 12) */}
diff --git a/app/globals.css b/app/globals.css
index 29392e1..271b605 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -559,6 +559,14 @@ body {
.db-page-title { font-size: 1.375rem; font-weight: 700; color: #fff; margin: 0 0 4px; }
.db-page-subtitle { font-size: 0.8125rem; color: #9ca3af; margin: 0; }
.db-active-filter { color: var(--color-re-teal); font-weight: 600; }
+.db-survey-nav { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
+.db-survey-link {
+ font-size: 0.75rem; font-weight: 600; padding: 4px 12px; border-radius: 999px;
+ border: 1px solid rgba(67,187,200,0.3); color: #9ca3af; text-decoration: none;
+ transition: all 0.2s ease;
+}
+.db-survey-link:hover { color: #E7E6E5; border-color: var(--color-re-teal); }
+.db-survey-link-active { background: var(--color-re-teal); color: #0F1923; border-color: var(--color-re-teal); }
.db-section { margin-bottom: 16px; }
.db-grid {
display: grid;
diff --git a/supabase/migrations/20260611000001_dash_responses_all.sql b/supabase/migrations/20260611000001_dash_responses_all.sql
new file mode 100644
index 0000000..89f4a08
--- /dev/null
+++ b/supabase/migrations/20260611000001_dash_responses_all.sql
@@ -0,0 +1,33 @@
+-- Migración: agregar flag p_all a _dash_responses
+-- UUID especial '00000000-0000-0000-0000-000000000000' = todos los surveys
+CREATE OR REPLACE FUNCTION public._dash_responses(
+ p_survey_id uuid,
+ p_depto text DEFAULT NULL,
+ p_genero text[] DEFAULT NULL,
+ p_etario text[] DEFAULT NULL,
+ p_modalidad text[] DEFAULT NULL
+)
+RETURNS TABLE(response_id uuid)
+LANGUAGE sql STABLE SECURITY DEFINER
+SET search_path = public
+AS $$
+ SELECT r.id
+ FROM public.responses r
+ WHERE (p_survey_id = '00000000-0000-0000-0000-000000000000'
+ OR r.survey_id = p_survey_id)
+ AND (p_depto IS NULL OR r.qi_zone = p_depto)
+ AND (p_genero IS NULL OR cardinality(p_genero) = 0 OR EXISTS (
+ SELECT 1 FROM public.answers a
+ JOIN public.questions q ON q.id = a.question_id
+ WHERE a.response_id = r.id AND q.code = 'A6'
+ AND a.value #>> '{}' = ANY(p_genero)
+ ))
+ AND (p_etario IS NULL OR cardinality(p_etario) = 0
+ OR r.qi_age_bucket = ANY(p_etario))
+ AND (p_modalidad IS NULL OR cardinality(p_modalidad) = 0 OR EXISTS (
+ SELECT 1 FROM public.answers a
+ JOIN public.questions q ON q.id = a.question_id
+ WHERE a.response_id = r.id AND q.code = 'A7'
+ AND a.value #>> '{}' = ANY(p_modalidad)
+ ));
+$$;