feat: add Instagram, Facebook, TikTok and LinkedIn slots
Organic social channels per client in the agency hub, separate from paid Meta Ads. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
36
sql/social_integrations.sql
Normal file
36
sql/social_integrations.sql
Normal file
@@ -0,0 +1,36 @@
|
||||
-- Organic social connection slots per tenant
|
||||
-- Idempotent. (Distinct from meta_ads / paid.)
|
||||
|
||||
alter table public.integrations drop constraint if exists integrations_provider_check;
|
||||
alter table public.integrations
|
||||
add constraint integrations_provider_check
|
||||
check (provider in (
|
||||
'meta_ads',
|
||||
'google_ads',
|
||||
'ga4',
|
||||
'search_console',
|
||||
'tag_manager',
|
||||
'clientify',
|
||||
'klaviyo',
|
||||
'mailchimp',
|
||||
'google_drive',
|
||||
'wordpress',
|
||||
'prestashop',
|
||||
'shopify',
|
||||
'instagram',
|
||||
'facebook',
|
||||
'tiktok',
|
||||
'linkedin'
|
||||
));
|
||||
|
||||
insert into public.integrations (tenant_id, provider, status, label)
|
||||
select t.id, p.provider, 'disconnected', p.label
|
||||
from public.tenants t
|
||||
cross join (
|
||||
values
|
||||
('instagram', 'Instagram'),
|
||||
('facebook', 'Facebook Page'),
|
||||
('tiktok', 'TikTok'),
|
||||
('linkedin', 'LinkedIn')
|
||||
) as p(provider, label)
|
||||
on conflict (tenant_id, provider) do nothing;
|
||||
@@ -58,6 +58,10 @@ export async function POST(req: NextRequest) {
|
||||
['wordpress', 'WordPress'],
|
||||
['prestashop', 'PrestaShop'],
|
||||
['shopify', 'Shopify'],
|
||||
['instagram', 'Instagram'],
|
||||
['facebook', 'Facebook Page'],
|
||||
['tiktok', 'TikTok'],
|
||||
['linkedin', 'LinkedIn'],
|
||||
];
|
||||
await fetch(`${url}/rest/v1/integrations`, {
|
||||
method: 'POST',
|
||||
|
||||
@@ -54,18 +54,18 @@ type AlertRow = {
|
||||
|
||||
const MATRIX_PROVIDERS = [
|
||||
'meta_ads',
|
||||
'google_ads',
|
||||
'clientify',
|
||||
'instagram',
|
||||
'tiktok',
|
||||
'linkedin',
|
||||
'google_drive',
|
||||
'wordpress',
|
||||
] as const;
|
||||
|
||||
const SHORT: Record<string, string> = {
|
||||
meta_ads: 'Meta',
|
||||
google_ads: 'GAds',
|
||||
clientify: 'CRM',
|
||||
instagram: 'IG',
|
||||
tiktok: 'TT',
|
||||
linkedin: 'LI',
|
||||
google_drive: 'Drive',
|
||||
wordpress: 'WP',
|
||||
};
|
||||
|
||||
function healthBadge(h: string) {
|
||||
@@ -241,8 +241,8 @@ export default function AgencyPortfolioBoard() {
|
||||
Panel de control · clientes y conexiones
|
||||
</h3>
|
||||
<p className="text-[11px] text-gray-500 mt-0.5">
|
||||
Cada cliente con su Meta, Google Ads, Clientify, Drive y web
|
||||
(WordPress…). Activa/apaga canales en Conexiones.
|
||||
Cada cliente con ads, redes (IG/TikTok/LinkedIn), Drive y web.
|
||||
Activa/apaga canales en Conexiones.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -31,6 +31,10 @@ const PLACEHOLDERS: Record<string, string> = {
|
||||
wordpress: 'https://sitio.com + Application Password',
|
||||
prestashop: 'https://tienda.com + API key',
|
||||
shopify: 'mitienda.myshopify.com + Admin API token',
|
||||
instagram: '@handle o Instagram Business Account ID',
|
||||
facebook: 'Page ID / facebook.com/…',
|
||||
tiktok: '@handle o Advertiser / Business ID',
|
||||
linkedin: 'Company Page ID / linkedin.com/company/…',
|
||||
};
|
||||
|
||||
export default function ClientIntegrationsPanel({
|
||||
@@ -106,6 +110,7 @@ export default function ClientIntegrationsPanel({
|
||||
|
||||
const groups = [
|
||||
{ id: 'paid', title: 'Paid media' },
|
||||
{ id: 'social', title: 'Redes sociales (orgánico)' },
|
||||
{ id: 'analytics', title: 'Analítica y medición' },
|
||||
{ id: 'crm', title: 'CRM' },
|
||||
{ id: 'email', title: 'Email / lifecycle' },
|
||||
@@ -291,6 +296,15 @@ export default function ClientIntegrationsPanel({
|
||||
fase.
|
||||
</p>
|
||||
)}
|
||||
{(p.id === 'instagram' ||
|
||||
p.id === 'facebook' ||
|
||||
p.id === 'tiktok' ||
|
||||
p.id === 'linkedin') && (
|
||||
<p className="text-[10px] text-gray-500">
|
||||
Orgánico (páginas/perfiles). Distinto de Meta Ads /
|
||||
TikTok Ads. OAuth live y publicación: siguiente fase.
|
||||
</p>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -13,6 +13,10 @@ export const INTEGRATION_PROVIDERS = [
|
||||
{ id: 'wordpress', label: 'WordPress', group: 'cms' },
|
||||
{ id: 'prestashop', label: 'PrestaShop', group: 'cms' },
|
||||
{ id: 'shopify', label: 'Shopify', group: 'cms' },
|
||||
{ id: 'instagram', label: 'Instagram', group: 'social' },
|
||||
{ id: 'facebook', label: 'Facebook Page', group: 'social' },
|
||||
{ id: 'tiktok', label: 'TikTok', group: 'social' },
|
||||
{ id: 'linkedin', label: 'LinkedIn', group: 'social' },
|
||||
] as const;
|
||||
|
||||
export type IntegrationProviderId =
|
||||
|
||||
Reference in New Issue
Block a user