import Crafter.CppDOM; import std; using namespace Crafter; using namespace Crafter::CppDOMBindings; // Structure to represent a note struct Note { std::uint32_t id; std::string content; }; void RenderNotes(); // Global vector to store notes std::vector notes; // Create the head section HtmlElementView* head = new HtmlElementView("head", R"( Note Taking App )"); // Create the body section HtmlElementView* body = new HtmlElementView("body", R"(

📝 Note Taking App

Add New Note


Your Notes

)"); HtmlElementView* addNoteBtn = new HtmlElementView("addNoteBtn"); HtmlElementView* noteInput = new HtmlElementView("noteInput"); // Function to fetch all notes from the backend void FetchNotes() { HtmlElementView loadingIndicator("loading"); loadingIndicator.SetInnerHTML("

Loading notes...

"); // Make HTTP request to backend Fetch("http://localhost:3000/getNotes", [](std::string content) { // Parse response - each note is separated by \n\n notes.clear(); // Simple parsing of note data std::uint_fast32_t pos = 0; std::uint_fast32_t prevPos = 0; while ((pos = content.find('\n', prevPos)) != std::string::npos) { if (pos > prevPos) { // Extract ID std::string idStr = content.substr(prevPos, pos - prevPos); std::uint_fast32_t id = std::stoul(idStr); // Find the next newline for content std::uint_fast32_t contentStart = pos + 1; std::uint_fast32_t contentEnd = content.find('\n', contentStart); if (contentEnd != std::string::npos) { std::string noteContent = content.substr(contentStart, contentEnd - contentStart); notes.push_back({id, noteContent}); } } prevPos = content.find('\n', pos) + 1; if (prevPos >= content.length()) break; } // Update UI with notes //RenderNotes(); }); } // Function to add a new note via the backend void AddNote(const std::string& content) { if (content.empty()) return; HtmlElementView loadingIndicator("loading"); loadingIndicator.SetInnerHTML("

Saving note...

"); // Make POST request to create note Fetch("http://localhost:3000/createNote", content, [](std::string content) {}); } // Function to delete a note via the backend void DeleteNote(std::uint32_t id) { HtmlElementView loadingIndicator("loading"); loadingIndicator.SetInnerHTML("

Deleting note...

"); // Make POST request to delete note Fetch("http://localhost:3000/deleteNote", std::to_string(id), [](std::string content) { FetchNotes(); }); } // Function to render all notes to the DOM void RenderNotes() { HtmlElementView notesContainer("notesContainer"); if (notes.empty()) { notesContainer.SetInnerHTML("

No notes yet. Add one below!

"); return; } std::string html = "
"; for (const Note& note : notes) { html += std::format( R"(
{}
)", note.id, note.content, note.id ); } html += "
"; notesContainer.SetInnerHTML(html); // Add event listeners to delete buttons for (const Note& note : notes) { HtmlElementView deleteBtn(std::format("note-{}-delete", note.id)); deleteBtn.AddClickListener([id = note.id](MouseEvent event) { DeleteNote(id); }); } } std::string* currentNoteValue = new std::string(); // Main function int main() { // Initialize the app FetchNotes(); // Add input listener to track textarea changes noteInput->AddInputListener([&](InputEvent event) { *currentNoteValue += event.data; std::cout << *currentNoteValue << std::endl; }); // Add click listener to add note button addNoteBtn->AddClickListener([&](MouseEvent event) { std::cout << "click!" << std::endl; std::cout << *currentNoteValue << std::endl; // Use the captured value from input event if (!currentNoteValue->empty()) { AddNote(*currentNoteValue); // Clear the textarea by setting its value to empty string noteInput->SetInnerHTML(""); *currentNoteValue = ""; // Reset the stored value } }); }