- Create CreatePlanModal component with Headless UI Dialog - Implement dark mode support throughout plans UI - Update plans/page.tsx with professional card layout - Update plans/[id]/page.tsx with consistent styling - Add proper spacing, typography, and color consistency - Implement smooth animations and transitions - Add success/error message feedback - Improve form UX with better input styling
86 lines
2.7 KiB
TypeScript
86 lines
2.7 KiB
TypeScript
/**
|
|
* Server-side API functions
|
|
* Estas funções são executadas APENAS no servidor (não no cliente)
|
|
*/
|
|
|
|
import { cookies, headers } from 'next/headers';
|
|
|
|
const API_BASE_URL = process.env.API_INTERNAL_URL || 'http://backend:8080';
|
|
|
|
interface AgencyBrandingData {
|
|
logo_url?: string;
|
|
primary_color?: string;
|
|
secondary_color?: string;
|
|
name?: string;
|
|
}
|
|
|
|
/**
|
|
* Busca os dados de branding da agência no servidor
|
|
* Usa o subdomínio do request para identificar a agência
|
|
*/
|
|
export async function getAgencyBranding(): Promise<AgencyBrandingData | null> {
|
|
try {
|
|
// Pegar o hostname do request
|
|
const headersList = await headers();
|
|
const hostname = headersList.get('host') || '';
|
|
|
|
// Extrair subdomain (remover porta se houver)
|
|
const hostnameWithoutPort = hostname.split(':')[0];
|
|
const subdomain = hostnameWithoutPort.split('.')[0];
|
|
|
|
console.log(`[ServerAPI] Full hostname: ${hostname}, Without port: ${hostnameWithoutPort}, Subdomain: ${subdomain}`);
|
|
|
|
if (!subdomain || subdomain === 'localhost' || subdomain === 'www') {
|
|
console.log(`[ServerAPI] Invalid subdomain, skipping: ${subdomain}`);
|
|
return null;
|
|
}
|
|
|
|
// Buscar dados da agência pela API
|
|
const url = `${API_BASE_URL}/api/tenant/config?subdomain=${subdomain}`;
|
|
console.log(`[ServerAPI] Fetching agency config from: ${url}`);
|
|
|
|
const response = await fetch(url, {
|
|
cache: 'no-store', // Sempre buscar dados atualizados
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.error(`[ServerAPI] Failed to fetch agency branding for ${subdomain}: ${response.status}`);
|
|
return null;
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log(`[ServerAPI] Agency branding data for ${subdomain}:`, JSON.stringify(data));
|
|
return data as AgencyBrandingData;
|
|
} catch (error) {
|
|
console.error('[ServerAPI] Error fetching agency branding:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Busca apenas o logo da agência (para metadata)
|
|
*/
|
|
export async function getAgencyLogo(): Promise<string | null> {
|
|
const branding = await getAgencyBranding();
|
|
return branding?.logo_url || null;
|
|
}
|
|
|
|
/**
|
|
* Busca as cores da agência (para passar ao client component)
|
|
*/
|
|
export async function getAgencyColors(): Promise<{ primary: string; secondary: string } | null> {
|
|
const branding = await getAgencyBranding();
|
|
|
|
if (branding?.primary_color && branding?.secondary_color) {
|
|
return {
|
|
primary: branding.primary_color,
|
|
secondary: branding.secondary_color,
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|