// screen-extra.jsx — Search results, multi-step Add Idea page, Notifications panel const { useState: useExState, useMemo: useExMemo, useRef: useExRef, useEffect: useExEffect } = React; /* ---------------------------------------------------------------- Search results ----------------------------------------------------------------- */ function SearchResults({ query, setSearch, openIdea, openUser, votes, onVote }) { const Icon = window.Icon; const [tab, setTab] = useExState('ideas'); const q = query.trim().toLowerCase(); const ideaHits = useExMemo(() => !q ? [] : window.IDEAS.filter(i => i.title.toLowerCase().includes(q) || i.category.toLowerCase().includes(q) || i.desc.toLowerCase().includes(q)), [q]); const userHits = useExMemo(() => { if (!q) return []; const seen = new Set(); return window.IDEAS.filter(i => { const m = i.author.toLowerCase().includes(q); if (m && !seen.has(i.author)) { seen.add(i.author); return true; } return false; }) .map(i => ({ name: i.author, role: i.role, av: i.avatar })); }, [q]); const list = tab === 'ideas' ? ideaHits : userHits; return (
Search
{q ? <>Results for “{query}” · {ideaHits.length + userHits.length} matches : 'Type to search ideas and people across IdeaMint.'}
{list.length === 0 ? (
{q ? 'No matches found' : 'Start typing to search'}
{q ? 'Try a different keyword or check the People tab.' : 'Search by idea title, category, or owner name.'}
{q &&
{['Technology', 'Carbon', 'AI', 'Mohamed'].map(s => )}
}
) : tab === 'ideas' ? (
{ideaHits.map(i => (
openIdea(i)}>
{i.title}

{i.desc}

{i.author}
onVote(i.id, d)} />
))}
) : (
{userHits.map((u, idx) => (
openUser(u)}>
{u.name}
{u.role}
))}
)}
); } /* ---------------------------------------------------------------- Multi-step Add Idea (full page) ----------------------------------------------------------------- */ // Suggested tags per category const SUGGESTED_TAGS = { Technology: ['AI', 'automation', 'productivity', 'integration', 'data', 'cloud', 'mobile', 'analytics', 'security', 'API'], Business: ['revenue', 'cost-saving', 'strategy', 'growth', 'efficiency', 'process', 'KPI', 'ROI', 'partnership', 'market'], Marketing: ['branding', 'campaign', 'social-media', 'engagement', 'SEO', 'content', 'conversion', 'awareness', 'leads', 'CRM'], Design: ['UX', 'UI', 'accessibility', 'design-system', 'prototype', 'usability', 'visual', 'workflow', 'user-research', 'mobile'], Operations: ['logistics', 'supply-chain', 'compliance', 'workflow', 'quality', 'reporting', 'onboarding', 'SLA', 'cost', 'training'], }; const DEFAULT_TAGS = ['innovation', 'team', 'pilot', 'research', 'improvement', 'customer', 'internal', 'cross-team', 'sustainability', 'agile']; function AddIdeaPage({ goBack, onSubmit }) { const Icon = window.Icon; const [step, setStep] = useExState(0); const [form, setForm] = useExState({ title: '', cat: '', desc: '', tags: [], tagInput: '' }); const [catOpen, setCatOpen] = useExState(false); const [tagOpen, setTagOpen] = useExState(false); const [aiState, setAiState] = useExState('idle'); // idle | thinking | done | error const [aiDraft, setAiDraft] = useExState(''); // streamed preview text const tagBoxRef = useExRef(null); const set = (k, v) => setForm(f => ({ ...f, [k]: v })); const addTag = (e) => { if (e.key === 'Enter' && form.tagInput.trim() && form.tags.length < 5) { e.preventDefault(); set('tags', [...form.tags, form.tagInput.trim()]); set('tagInput', ''); } }; // Close tag dropdown on outside click useExEffect(() => { const handler = (e) => { if (tagBoxRef.current && !tagBoxRef.current.contains(e.target)) setTagOpen(false); }; document.addEventListener('mousedown', handler); return () => document.removeEventListener('mousedown', handler); }, []); const suggestedTags = (SUGGESTED_TAGS[form.cat] || DEFAULT_TAGS).filter(t => !form.tags.includes(t)); const generateWithAI = async () => { if (!form.title.trim()) return; setAiState('thinking'); setAiDraft(''); try { const result = await window.API.generateIdea(form.title, form.cat, form.desc); // Animate the text typing in const text = result.description || ''; setAiDraft(''); setAiState('done'); // Typewriter effect let i = 0; const tick = () => { i += 3; setAiDraft(text.slice(0, i)); if (i < text.length) requestAnimationFrame(tick); else set('desc', text); }; requestAnimationFrame(tick); // Pre-fill suggested tags from AI if user hasn't added any if (result.tags?.length && form.tags.length === 0) { set('tags', result.tags.slice(0, 5)); } } catch { setAiState('error'); setTimeout(() => setAiState('idle'), 3000); } }; const steps = ['Details', 'Media', 'Review']; const step0Valid = form.title.trim() && form.cat && form.desc.trim() && form.tags.length > 0; const next = () => setStep(s => Math.min(2, s + 1)); const back = () => setStep(s => Math.max(0, s - 1)); return (
Add new idea
Share something worth building — it takes about a minute.
{/* stepper */}
{steps.map((s, i) => (
{i < step ? : i + 1}
{s}
{i < steps.length - 1 &&
} ))}
{step === 0 && (
set('title', e.target.value)} placeholder="Enter your idea's general title" />
{catOpen && (
{window.CATEGORIES.map(c => ( ))}
)}