← back to Norma
components/email-analyzer/AngleCheckboxes.tsx
101 lines
'use client';
import { SlidersHorizontal } from 'lucide-react';
export const ANGLE_OPTIONS: Array<{ key: string; label: string; prompt: string }> = [
{ key: 'urgency', label: 'Add urgency', prompt: 'Sharpen the urgency — make clear why action must be taken now.' },
{ key: 'statistics', label: 'Add statistics', prompt: 'Incorporate 1-2 specific statistics or data points relevant to the topic.' },
{ key: 'local', label: 'Local impact', prompt: 'Add a local/state-level angle so the reader sees the impact in their community.' },
{ key: 'story', label: 'Personal story', prompt: 'Add a short human/personal story or testimonial to increase emotional resonance.' },
{ key: 'cta', label: 'Stronger CTA', prompt: 'Strengthen the call-to-action so the next step is unmistakable and easy.' },
{ key: 'donation', label: 'Donation ask', prompt: 'Add or strengthen a donation ask with a clear amount and why it matters.' },
{ key: 'policy', label: 'Policy citation', prompt: 'Reference specific pending legislation, regulation, or policy positions.' },
{ key: 'quote', label: 'Leader quote', prompt: 'Work in a quote from a recognized leader or expert on this topic.' },
];
interface AngleCheckboxesProps {
selected: string[];
onChange: (next: string[]) => void;
}
export default function AngleCheckboxes({ selected, onChange }: AngleCheckboxesProps) {
function toggle(key: string) {
if (selected.includes(key)) {
onChange(selected.filter((k) => k !== key));
} else {
onChange([...selected, key]);
}
}
return (
<div className="card" style={{ padding: 12 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
<SlidersHorizontal size={14} style={{ color: 'var(--color-lane-b)' }} />
<span style={{ fontSize: 13, fontWeight: 600, color: 'var(--color-text)' }}>
Analysis Angles
</span>
{selected.length > 0 && (
<span
className="badge badge-success"
style={{ marginLeft: 'auto', fontSize: 10 }}
>
{selected.length} selected
</span>
)}
</div>
<div style={{ fontSize: 10, color: 'var(--color-text-muted)', marginBottom: 10 }}>
Check angles to apply on the next rewrite.
</div>
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(2, minmax(0,1fr))',
gap: 6,
}}
>
{ANGLE_OPTIONS.map((opt) => {
const on = selected.includes(opt.key);
return (
<label
key={opt.key}
style={{
display: 'flex',
alignItems: 'center',
gap: 6,
padding: '6px 8px',
borderRadius: 'var(--radius-sm)',
border: `1px solid ${on ? 'var(--color-primary)' : 'var(--color-border)'}`,
background: on ? 'rgba(16,185,129,0.08)' : 'var(--color-surface-el)',
cursor: 'pointer',
fontSize: 11,
color: on ? 'var(--color-text)' : 'var(--color-text-secondary)',
transition: 'var(--transition)',
}}
>
<input
type="checkbox"
checked={on}
onChange={() => toggle(opt.key)}
style={{ accentColor: 'var(--color-primary)', width: 12, height: 12 }}
/>
<span>{opt.label}</span>
</label>
);
})}
</div>
</div>
);
}
/** Build the instruction fragment appended to rewrite prompts when angles are selected. */
export function buildAngleInstruction(selected: string[]): string {
if (selected.length === 0) return '';
const prompts = ANGLE_OPTIONS
.filter((o) => selected.includes(o.key))
.map((o) => `• ${o.prompt}`)
.join('\n');
return `\n\nALSO APPLY THESE ANGLES:\n${prompts}`;
}