feat: ficha por cliente en portafolio (conexiones, accesos, logo, módulos)
Cada tenant tiene una ficha con plataformas, invitaciones por email, logo de marca y toggles de módulos visibles en el portal cliente. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import ClientIntegrationsPanel from '@/components/ClientIntegrationsPanel';
|
||||
import ClientFicha from '@/components/ClientFicha';
|
||||
import { createClient } from '@/lib/supabase/server';
|
||||
import { redirect } from 'next/navigation';
|
||||
import {
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export default async function ClienteIntegrationsPage({
|
||||
export default async function ClienteFichaPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ id: string }>;
|
||||
@@ -37,5 +37,5 @@ export default async function ClienteIntegrationsPage({
|
||||
}
|
||||
}
|
||||
|
||||
return <ClientIntegrationsPanel tenantId={id} tenantName={name} />;
|
||||
return <ClientFicha tenantId={id} initialName={name} />;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,21 @@ import React from 'react';
|
||||
import { createClient } from '@/lib/supabase/server';
|
||||
import { logoutAction } from '@/app/auth/actions';
|
||||
import { cookies } from 'next/headers';
|
||||
import { VIEW_TENANT_NAME_COOKIE } from '@/lib/agency';
|
||||
import {
|
||||
VIEW_TENANT_COOKIE,
|
||||
VIEW_TENANT_NAME_COOKIE,
|
||||
homeTenantId,
|
||||
isAgencyRole,
|
||||
serviceHeaders,
|
||||
supabaseUrl,
|
||||
userRole,
|
||||
} from '@/lib/agency';
|
||||
import DashboardShell from '@/components/DashboardShell';
|
||||
import {
|
||||
DashboardModuleId,
|
||||
TenantSettings,
|
||||
resolveTenantModules,
|
||||
} from '@/lib/tenant-modules';
|
||||
|
||||
export default async function DashboardLayout({
|
||||
children,
|
||||
@@ -15,13 +28,56 @@ export default async function DashboardLayout({
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
|
||||
const role =
|
||||
user?.user_metadata?.role || user?.app_metadata?.role || 'client';
|
||||
const company = user?.user_metadata?.company || '4Ventures Central';
|
||||
const role = userRole(user);
|
||||
const company =
|
||||
(user?.user_metadata?.company as string) ||
|
||||
(user?.app_metadata?.company as string) ||
|
||||
'4Ventures Central';
|
||||
const email = user?.email || 'usuario@4ventures.es';
|
||||
const isAgency = role === 'admin' || role === 'team';
|
||||
const isAgency = isAgencyRole(role);
|
||||
const cookieStore = await cookies();
|
||||
const viewName = cookieStore.get(VIEW_TENANT_NAME_COOKIE)?.value;
|
||||
const viewId = cookieStore.get(VIEW_TENANT_COOKIE)?.value || null;
|
||||
const ownId = homeTenantId(user);
|
||||
|
||||
let enabledModules: Record<DashboardModuleId, boolean> | null = null;
|
||||
let clientLogoUrl: string | null = null;
|
||||
let brandLabel = company;
|
||||
|
||||
// Client users (and agency zoomed into a client for branding): load ficha settings
|
||||
const brandingTenantId = isAgency ? viewId : ownId;
|
||||
if (brandingTenantId) {
|
||||
const headers = serviceHeaders();
|
||||
if (headers) {
|
||||
const [tRes, iRes] = await Promise.all([
|
||||
fetch(
|
||||
`${supabaseUrl()}/rest/v1/tenants?id=eq.${encodeURIComponent(brandingTenantId)}&select=name,logo_url,settings`,
|
||||
{ headers, cache: 'no-store' }
|
||||
),
|
||||
fetch(
|
||||
`${supabaseUrl()}/rest/v1/integrations?tenant_id=eq.${encodeURIComponent(brandingTenantId)}&select=provider,status,enabled`,
|
||||
{ headers, cache: 'no-store' }
|
||||
),
|
||||
]);
|
||||
if (tRes.ok) {
|
||||
const rows = await tRes.json();
|
||||
const t = rows[0];
|
||||
if (t) {
|
||||
brandLabel = t.name || brandLabel;
|
||||
if (t.logo_url) {
|
||||
clientLogoUrl = `/api/branding/logo?tenantId=${encodeURIComponent(brandingTenantId)}`;
|
||||
}
|
||||
const integrations = iRes.ok ? await iRes.json() : [];
|
||||
if (!isAgency) {
|
||||
enabledModules = resolveTenantModules(
|
||||
(t.settings || {}) as TenantSettings,
|
||||
integrations || []
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<DashboardShell
|
||||
@@ -30,6 +86,11 @@ export default async function DashboardLayout({
|
||||
role={role}
|
||||
isAgency={isAgency}
|
||||
viewName={viewName}
|
||||
enabledModules={enabledModules}
|
||||
clientLogoUrl={
|
||||
isAgency && viewId ? clientLogoUrl : !isAgency ? clientLogoUrl : null
|
||||
}
|
||||
brandLabel={brandLabel}
|
||||
logoutAction={logoutAction}
|
||||
>
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user