Download src/components/NoteForm.tsx from jay-hank/Nexova: direct link, hf CLI and curl.
- Browser
- Download file 2.79 kB
-
https://huggingface.co/spaces/jay-hank/Nexova/resolve/main/src/components/NoteForm.tsx
- Command line
-
hf download hf://spaces/jay-hank/Nexova/src/components/NoteForm.tsx
-
curl -L -o NoteForm.tsx https://huggingface.co/spaces/jay-hank/Nexova/resolve/main/src/components/NoteForm.tsx
2.79 kB
| "use client"; | |
| import { useState } from "react"; | |
| const PALETTE = ["#fef08a", "#86efac", "#93c5fd", "#f9a8d4", "#c4b5fd"]; | |
| type Note = { | |
| id: string; | |
| title: string; | |
| content: string; | |
| color: string; | |
| pinned: boolean; | |
| }; | |
| export default function NoteForm({ | |
| initial, | |
| onSave, | |
| onCancel, | |
| }: { | |
| initial: Note | null; | |
| onSave: (data: { title: string; content: string; color: string; pinned: boolean }) => void; | |
| onCancel: () => void; | |
| }) { | |
| const [title, setTitle] = useState(initial?.title ?? ""); | |
| const [content, setContent] = useState(initial?.content ?? ""); | |
| const [color, setColor] = useState(initial?.color ?? PALETTE[0]); | |
| const [pinned, setPinned] = useState(!!initial?.pinned); | |
| const submit = (e: React.FormEvent) => { | |
| e.preventDefault(); | |
| if (!title.trim()) return; | |
| onSave({ title: title.trim(), content: content.trim(), color, pinned }); | |
| }; | |
| return ( | |
| <form onSubmit={submit} className="bg-zinc-900 border border-zinc-800 rounded-xl p-5 mb-6 space-y-4"> | |
| <input | |
| autoFocus | |
| placeholder="Title" | |
| value={title} | |
| onChange={(e) => setTitle(e.target.value)} | |
| className="w-full bg-transparent text-lg font-semibold focus:outline-none placeholder:text-zinc-600" | |
| /> | |
| <textarea | |
| placeholder="Write something..." | |
| value={content} | |
| onChange={(e) => setContent(e.target.value)} | |
| rows={4} | |
| className="w-full bg-transparent text-sm text-zinc-300 focus:outline-none resize-none placeholder:text-zinc-600" | |
| /> | |
| <div className="flex items-center justify-between"> | |
| <div className="flex gap-2 items-center"> | |
| {PALETTE.map((c) => ( | |
| <button | |
| key={c} | |
| type="button" | |
| onClick={() => setColor(c)} | |
| className={`w-6 h-6 rounded-full transition ${color === c ? "ring-2 ring-white scale-110" : "opacity-60 hover:opacity-100"}`} | |
| style={{ backgroundColor: c }} | |
| /> | |
| ))} | |
| <label className="flex items-center gap-1.5 ml-3 text-xs text-zinc-400 cursor-pointer"> | |
| <input | |
| type="checkbox" | |
| checked={pinned} | |
| onChange={(e) => setPinned(e.target.checked)} | |
| className="accent-emerald-500" | |
| /> | |
| Pin | |
| </label> | |
| </div> | |
| <div className="flex gap-2"> | |
| <button type="button" onClick={onCancel} className="px-3 py-1.5 text-sm text-zinc-400 hover:text-white transition"> | |
| Cancel | |
| </button> | |
| <button type="submit" className="px-4 py-1.5 bg-emerald-600 hover:bg-emerald-500 rounded-lg text-sm font-medium transition"> | |
| {initial ? "Update" : "Create"} | |
| </button> | |
| </div> | |
| </div> | |
| </form> | |
| ); | |
| } | |