← back to Patty
components/compliance/ComplianceTab.tsx
214 lines
'use client';
import { Shield, AlertTriangle, CheckCircle, Info, ExternalLink } from 'lucide-react';
export default function ComplianceTab() {
return (
<div style={{ padding: '24px' }}>
{/* Header */}
<div className="flex items-center justify-between mb-6">
<div>
<h2 className="text-lg font-semibold" style={{ color: 'var(--color-text)' }}>
Legal Compliance
</h2>
<p className="text-sm mt-1" style={{ color: 'var(--color-text-muted)' }}>
Understand the legal landscape for petition and advocacy activities
</p>
</div>
</div>
{/* Compliance Status */}
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-8">
{[
{
label: 'Organization Type',
value: 'Not Set',
icon: Shield,
color: 'var(--color-warning)',
desc: 'Set your org type for compliance guidance',
},
{
label: 'Email Compliance',
value: 'CAN-SPAM Ready',
icon: CheckCircle,
color: 'var(--color-success)',
desc: 'Unsubscribe links are auto-included',
},
{
label: 'Data Privacy',
value: 'GDPR Aware',
icon: Shield,
color: 'var(--color-success)',
desc: 'Consent tracking is enabled',
},
].map((item, i) => (
<div key={i} className="card" style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
<div
className="w-10 h-10 rounded-lg flex items-center justify-center shrink-0 mt-0.5"
style={{
backgroundColor: `${item.color}15`,
border: `1px solid ${item.color}30`,
}}
>
<item.icon size={18} style={{ color: item.color }} />
</div>
<div>
<div className="text-xs" style={{ color: 'var(--color-text-muted)' }}>
{item.label}
</div>
<div className="text-sm font-semibold" style={{ color: 'var(--color-text)' }}>
{item.value}
</div>
<div className="text-xs mt-0.5" style={{ color: 'var(--color-text-muted)' }}>
{item.desc}
</div>
</div>
</div>
))}
</div>
{/* Organization Types Guide */}
<h3 className="text-sm font-semibold mb-4" style={{ color: 'var(--color-text)' }}>
Organization Type Guide
</h3>
<div className="flex flex-col gap-4 mb-8">
{[
{
type: '501(c)(3) -- Charitable Organization',
rules: [
'Can conduct non-partisan voter education and registration',
'Cannot engage in partisan political activities',
'Limited lobbying (up to 20% of budget under the expenditure test)',
'Petition activities must relate to educational or charitable purpose',
'Cannot endorse or oppose political candidates',
],
color: '#22c55e',
},
{
type: '501(c)(4) -- Social Welfare Organization',
rules: [
'Can engage in unlimited lobbying related to social welfare mission',
'Can participate in some political activities (not primary activity)',
'Petition activities are a core part of the social welfare mission',
'Must report lobbying and political expenditures',
'Donations are not tax-deductible for donors',
],
color: '#3b82f6',
},
{
type: 'Individual / For-Profit',
rules: [
'No tax restrictions on petition or advocacy activities',
'Must comply with campaign finance laws if petition is election-related',
'State-specific lobbying registration may apply',
'CAN-SPAM compliance required for email communications',
'Privacy laws (GDPR, CCPA) apply to signer data collection',
],
color: '#a78bfa',
},
].map((org, i) => (
<div key={i} className="card">
<div className="flex items-center gap-2 mb-3">
<div
className="w-2 h-2 rounded-full"
style={{ backgroundColor: org.color }}
/>
<h4 className="text-sm font-semibold" style={{ color: 'var(--color-text)' }}>
{org.type}
</h4>
</div>
<ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 8 }}>
{org.rules.map((rule, j) => (
<li key={j} className="flex items-start gap-2 text-xs" style={{ color: 'var(--color-text-secondary)' }}>
<CheckCircle size={14} style={{ color: org.color, flexShrink: 0, marginTop: 1 }} />
{rule}
</li>
))}
</ul>
</div>
))}
</div>
{/* Key Compliance Areas */}
<h3 className="text-sm font-semibold mb-4" style={{ color: 'var(--color-text)' }}>
Key Compliance Areas
</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{[
{
title: 'Email Compliance (CAN-SPAM)',
items: [
'Include physical mailing address',
'Provide clear unsubscribe mechanism',
'Honor opt-out requests within 10 business days',
'Use accurate sender information',
],
},
{
title: 'Data Privacy (GDPR / CCPA)',
items: [
'Obtain explicit consent before collecting data',
'Provide data deletion mechanism',
'Document data processing purposes',
'Implement reasonable security measures',
],
},
{
title: 'Petition-Specific Rules',
items: [
'Verify signer identity where required by state law',
'Maintain signature records for audit',
'Disclose petition sponsor/funder',
'Follow state rules for ballot initiative petitions',
],
},
{
title: 'Accessibility (ADA / WCAG)',
items: [
'Petition pages must be screen-reader accessible',
'Provide alt text for all images',
'Ensure keyboard navigation works',
'Maintain sufficient color contrast',
],
},
].map((area, i) => (
<div key={i} className="card">
<h4 className="text-sm font-semibold mb-3" style={{ color: 'var(--color-text)' }}>
{area.title}
</h4>
<ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 6 }}>
{area.items.map((item, j) => (
<li key={j} className="flex items-start gap-2 text-xs" style={{ color: 'var(--color-text-secondary)' }}>
<Info size={12} style={{ color: 'var(--color-text-muted)', flexShrink: 0, marginTop: 2 }} />
{item}
</li>
))}
</ul>
</div>
))}
</div>
{/* Disclaimer */}
<div
className="mt-8 rounded-lg p-4 flex items-start gap-3"
style={{
backgroundColor: 'rgba(245, 158, 11, 0.08)',
border: '1px solid rgba(245, 158, 11, 0.2)',
}}
>
<AlertTriangle size={18} style={{ color: 'var(--color-warning)', flexShrink: 0, marginTop: 2 }} />
<div>
<div className="text-sm font-semibold mb-1" style={{ color: 'var(--color-warning)' }}>
Disclaimer
</div>
<p className="text-xs" style={{ color: 'var(--color-text-secondary)' }}>
This information is provided for general guidance only and does not constitute legal advice.
Consult with a qualified attorney for legal guidance specific to your organization
and jurisdiction. Laws vary by state and locality.
</p>
</div>
</div>
</div>
);
}