CoolFace
Apppublic

admin08077/Githubgemini

sourceHugging Faceotherupdated 10mo agoView on Hugging Face
0likes
DigitalWhiteboard-BCTMhEnP.js.map1 linesDownload Raw Back to assets
1{"version":3,"file":"DigitalWhiteboard-BCTMhEnP.js","sources":["../../components/features/DigitalWhiteboard.tsx"],"sourcesContent":["import React, { useState, useCallback } from 'react';\nimport { SparklesIcon, DigitalWhiteboardIcon } from '../icons.tsx';\nimport { useLocalStorage } from '../../hooks/useLocalStorage.ts';\nimport { summarizeNotesStream } from '../../services/index.ts';\nimport { LoadingSpinner } from '../shared/index.tsx';\nimport { MarkdownRenderer } from '../shared/index.tsx';\n\ninterface Note {\n    id: number;\n    text: string;\n    x: number;\n    y: number;\n    color: string;\n}\n\nconst colors = ['bg-yellow-400', 'bg-green-400', 'bg-blue-400', 'bg-pink-400', 'bg-purple-400', 'bg-orange-400'];\nconst textColors = ['text-yellow-900', 'text-green-900', 'text-blue-900', 'text-pink-900', 'text-purple-900', 'text-orange-900'];\n\nexport const DigitalWhiteboard: React.FC = () => {\n    const [notes, setNotes] = useLocalStorage<Note[]>('devcore_whiteboard_notes', []);\n    const [dragging, setDragging] = useState<{ id: number; offsetX: number; offsetY: number } | null>(null);\n    const [isSummarizing, setIsSummarizing] = useState(false);\n    const [summary, setSummary] = useState('');\n\n    const handleSummarize = useCallback(async () => {\n        if (notes.length === 0) return;\n        setIsSummarizing(true);\n        setSummary('');\n        try {\n            const allNotesText = notes.map((n: Note) => `- ${n.text}`).join('\\n');\n            const stream = summarizeNotesStream(allNotesText);\n            let fullResponse = '';\n            for await (const chunk of stream) {\n                fullResponse += chunk;\n                setSummary(fullResponse);\n            }\n        } catch (error) {\n            console.error(error);\n            setSummary('Sorry, an error occurred while summarizing.');\n        } finally {\n            setIsSummarizing(false);\n        }\n    }, [notes]);\n\n    const addNote = () => {\n        const newNote: Note = {\n            id: Date.now(),\n            text: 'New idea...',\n            x: 50,\n            y: 50,\n            color: colors[notes.length % colors.length],\n        };\n        setNotes([...notes, newNote]);\n    };\n    \n    const deleteNote = (id: number, e: React.MouseEvent) => {\n        e.stopPropagation();\n        setNotes(notes.filter((n) => n.id !== id));\n    };\n\n    const updateNote = (id: number, updates: Partial<Note>) => {\n        setNotes(notes.map((n) => n.id === id ? { ...n, ...updates } : n));\n    };\n\n    const onMouseDown = (e: React.MouseEvent<HTMLDivElement>, id: number) => {\n        const target = e.target as HTMLElement;\n        if (target.tagName === 'TEXTAREA' || target.dataset.role === 'button') return;\n        \n        const noteElement = e.currentTarget;\n        const rect = noteElement.getBoundingClientRect();\n        setDragging({ id, offsetX: e.clientX - rect.left, offsetY: e.clientY - rect.top });\n    };\n\n    const onMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n        if (!dragging) return;\n        const boardRect = e.currentTarget.getBoundingClientRect();\n        updateNote(dragging.id, {\n            x: e.clientX - dragging.offsetX - boardRect.left,\n            y: e.clientY - dragging.offsetY - boardRect.top\n        });\n    };\n\n    const onMouseUp = () => setDragging(null);\n\n    return (\n        <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8 text-text-primary\">\n            <header className=\"mb-6 flex justify-between items-center\">\n                 <div>\n                    <h1 className=\"text-3xl font-bold flex items-center\"><DigitalWhiteboardIcon /><span className=\"ml-3\">Digital Whiteboard</span></h1>\n                    <p className=\"text-text-secondary mt-1\">Organize your ideas with interactive sticky notes and AI summaries.</p>\n                </div>\n                <div className=\"flex gap-2\">\n                    <button onClick={handleSummarize} disabled={isSummarizing || notes.length === 0} className=\"btn-primary flex items-center gap-2 px-4 py-2\">\n                        <SparklesIcon/> {isSummarizing ? 'Summarizing...' : 'AI Summarize'}\n                    </button>\n                    <button onClick={addNote} className=\"btn-primary px-6 py-2\">Add Note</button>\n                </div>\n            </header>\n            <div\n                className=\"relative flex-grow bg-background border-2 border-dashed border-border rounded-lg overflow-hidden\"\n                onMouseMove={onMouseMove} onMouseUp={onMouseUp} onMouseLeave={onMouseUp}\n            >\n                {notes.map((note) => (\n                    <div\n                        key={note.id}\n                        className={`group absolute w-56 h-56 p-2 flex flex-col shadow-lg cursor-grab active:cursor-grabbing rounded-md transition-transform duration-100 border border-black/40 ${note.color} ${textColors[colors.indexOf(note.color)]}`}\n                        style={{ top: note.y, left: note.x, transform: dragging?.id === note.id ? 'scale(1.05)' : 'scale(1)' }}\n                        onMouseDown={e => onMouseDown(e, note.id)}\n                    >\n                        <button data-role=\"button\" onClick={(e) => deleteNote(note.id, e)} className=\"absolute -top-2 -right-2 w-6 h-6 rounded-full bg-gray-700 text-white font-bold text-xs flex items-center justify-center opacity-0 group-hover:opacity-100 hover:bg-red-500 transition-all\">&times;</button>\n                        <textarea\n                            value={note.text}\n                            onChange={(e) => updateNote(note.id, { text: e.target.value })}\n                            className=\"w-full h-full bg-transparent resize-none focus:outline-none font-medium p-1\"\n                        />\n                        <div data-role=\"button\" className=\"flex-shrink-0 flex justify-center gap-1 p-1 opacity-0 group-hover:opacity-100 transition-opacity\">\n                            {colors.map((c, i) => <button key={c} onClick={() => updateNote(note.id, { color: c })} className={`w-4 h-4 rounded-full ${c} border border-black/20 ${note.color === c ? 'ring-2 ring-offset-1 ring-black/50' : ''}`}/>)}\n                        </div>\n                    </div>\n                ))}\n            </div>\n             {(isSummarizing || summary) && (\n                 <div className=\"fixed inset-0 bg-gray-900/80 backdrop-blur-sm z-50 flex items-center justify-center\" onClick={() => setSummary('')}>\n                    <div className=\"w-full max-w-2xl bg-surface border border-border rounded-lg shadow-2xl p-6\" onClick={e => e.stopPropagation()}>\n                        <h2 className=\"text-xl font-bold mb-4\">AI Summary of Notes</h2>\n                        {isSummarizing && !summary ? <LoadingSpinner /> : <MarkdownRenderer content={summary} />}\n                    </div>\n                </div>\n            )}\n        </div>\n    );\n};"],"names":["colors","textColors","DigitalWhiteboard","notes","setNotes","useLocalStorage","dragging","setDragging","useState","isSummarizing","setIsSummarizing","summary","setSummary","handleSummarize","useCallback","allNotesText","n","stream","summarizeNotesStream","fullResponse","chunk","error","addNote","newNote","deleteNote","id","e","updateNote","updates","onMouseDown","target","rect","onMouseMove","boardRect","onMouseUp","jsxs","jsx","DigitalWhiteboardIcon","SparklesIcon","note","c","i","LoadingSpinner","MarkdownRenderer"],"mappings":"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"}