import React, { useCallback, useEffect, useState } from 'react'; import { Link2, RefreshCw, Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { apiFetch } from '@/lib/api'; import { cn } from '@/lib/utils'; const CAP_FIELDS = [ { key: 'linkedin_daily_connection_cap', label: 'Max connects / day', min: 1, max: 200 }, { key: 'linkedin_daily_message_cap', label: 'Max messages / day', min: 1, max: 300 }, { key: 'linkedin_weekly_connection_cap', label: 'Max connects / week', min: 1, max: 1000 }, { key: 'linkedin_weekly_message_cap', label: 'Max messages / week', min: 1, max: 1500 }, ]; export default function LinkedInConnectSettings() { const [loading, setLoading] = useState(true); const [busy, setBusy] = useState(false); const [accounts, setAccounts] = useState([]); const [defaultRefId, setDefaultRefId] = useState(null); const [caps, setCaps] = useState({}); const [savingCapId, setSavingCapId] = useState(null); const load = useCallback(async () => { setLoading(true); try { const r = await apiFetch('/api/unipile/linkedin/campaign-defaults'); const d = r.ok ? await r.json() : {}; const accts = d.accounts || []; setAccounts(accts); setDefaultRefId(d.default_unipile_account_ref_id ?? null); setCaps((prev) => { const next = { ...prev }; accts.forEach((a) => { next[a.id] = { linkedin_daily_connection_cap: a.linkedin_daily_connection_cap ?? 20, linkedin_daily_message_cap: a.linkedin_daily_message_cap ?? 40, linkedin_weekly_connection_cap: a.linkedin_weekly_connection_cap ?? 100, linkedin_weekly_message_cap: a.linkedin_weekly_message_cap ?? 200, }; }); return next; }); } catch { setAccounts([]); } finally { setLoading(false); } }, []); const saveCaps = useCallback(async (accountId) => { const patch = caps[accountId]; if (!patch) return; setSavingCapId(accountId); try { const res = await apiFetch(`/api/unipile/linkedin/accounts/${accountId}/limits`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(patch), }); if (!res.ok) throw new Error('Could not save limits'); } catch (e) { alert(e.message || 'Failed to save limits'); } finally { setSavingCapId(null); } }, [caps]); useEffect(() => { load(); }, [load]); const connectAccount = async () => { setBusy(true); try { const res = await apiFetch('/api/unipile/linkedin/hosted-link', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ label: 'LinkedIn account', }), }); const data = await res.json().catch(() => ({})); if (!res.ok) throw new Error(data.detail || 'Could not start LinkedIn connect'); if (data.url) window.location.href = data.url; } catch (e) { alert(e.message || 'Connect failed'); } finally { setBusy(false); } }; return (
Connect LinkedIn
{loading ? (
) : accounts.length === 0 ? (

Connected accounts: 0

) : (

Connected accounts ({accounts.length}) — default for LinkedIn sequence steps

)}
); }