if (length > 185) return 9;
if (length > 145) return 8;
if (length > 105) return 7;
if (length > 65) return 6;
return 5;
}
function getNoteFontSize(text) {
const length = String(text || "").length;
if (length > 185) return "19px";
if (length > 145) return "21px";
if (length > 105) return "23px";
if (length > 65) return "25px";
return "clamp(22px, 2vw, 30px)";
}
function createNoteElement(note, index) {
const slot = noteSlots[index % noteSlots.length];
const noteColor = note.color || categoryStyles[note.category] || "ink";
const noteText = note.body || note.title || "";
const author = note.author || "guest";
const rowStart = note.rowStart || getRowStart(note.row, slot.rowStart);
const rowSpan = note.span || getNoteSpan(noteText);
const article = document.createElement("article");
article.className = `note user-note ${noteColor}`;
article.dataset.category = note.category;
article.dataset.userId = note.id;
article.style.setProperty("--note-col", note.col || slot.col);
article.style.setProperty("--note-row", `${rowStart} / span ${rowSpan}`);
article.style.setProperty("--note-tilt", note.tilt || slot.tilt);
article.style.setProperty("--note-font-size", note.fontSize || getNoteFontSize(noteText));
article.innerHTML = `
${isOwner ? `
` : ""}
${escapeHTML(note.category)}
${escapeHTML(author)}
${escapeHTML(noteText)}
`;
return article;
}
function createEmptyState() {
const emptyState = document.createElement("button");
emptyState.className = "drop-zone empty-state";
emptyState.type = "button";
emptyState.innerHTML = `
+
Pin your first note
`;
emptyState.addEventListener("click", openComposer);
return emptyState;
}
function renderSavedNotes() {
noteBoard.replaceChildren();
if (!savedNotes.length) {
noteBoard.appendChild(createEmptyState());
return;
}
savedNotes.forEach((note, index) => {
noteBoard.appendChild(createNoteElement(note, index));
});
}
function renderNotes() {
const notes = document.querySelectorAll("[data-category]");
const query = searchInput.value.trim().toLowerCase();
notes.forEach((note) => {
const matchesSearch = note.textContent.toLowerCase().includes(query);
const matchesCategory = activeCategory === "all" || note.dataset.category === activeCategory;
note.style.display = matchesSearch && matchesCategory ? "" : "none";
});
filterButton.firstChild.textContent = activeCategory === "all"
? "Filter "
: `${activeCategory} `;
}
function openComposer() {
composer.classList.toggle("open");
if (composer.classList.contains("open")) {
composer.setAttribute("aria-hidden", "false");
noteForm.elements.body.focus();
} else {
composer.setAttribute("aria-hidden", "true");
}
}
function closeComposer() {
composer.classList.remove("open");
composer.setAttribute("aria-hidden", "true");
noteForm.reset();
}
renderSavedNotes();
renderNotes();
searchInput.addEventListener("input", renderNotes);
openComposerButton.addEventListener("click", openComposer);
closeComposerButton.addEventListener("click", closeComposer);
noteBoard.addEventListener("click", (event) => {
const deleteButton = event.target.closest(".note-delete");
if (!deleteButton || !isOwner) {
return;
}
const note = deleteButton.closest(".user-note");
if (!note) {
return;
}
savedNotes = savedNotes.filter((savedNote) => savedNote.id !== note.dataset.userId);
saveNotes();
renderSavedNotes();
renderNotes();
});
composer.addEventListener("click", (event) => {
if (event.target === composer) {
closeComposer();
}
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && composer.classList.contains("open")) {
closeComposer();
}
});
filterButton.addEventListener("click", () => {
const currentIndex = categories.indexOf(activeCategory);
activeCategory = categories[(currentIndex + 1) % categories.length];
renderNotes();
});
noteForm.addEventListener("submit", (event) => {
event.preventDefault();
const formData = new FormData(noteForm);
const category = formData.get("category");
const slot = noteSlots[savedNotes.length % noteSlots.length];
const body = formData.get("body").trim();
const newNote = {
id: crypto.randomUUID ? crypto.randomUUID() : `note-${Date.now()}`,
body,
category,
color: categoryStyles[category],
author: isOwner ? "ewsuziee" : "guest",
createdAt: new Date().toISOString(),
col: slot.col,
rowStart: slot.rowStart,
span: getNoteSpan(body),
tilt: slot.tilt,
fontSize: getNoteFontSize(body)
};
savedNotes.push(newNote);
saveNotes();
renderSavedNotes();
renderNotes();
closeComposer();
});