website example

This commit is contained in:
Jorijn van der Graaf 2025-11-12 17:50:58 +01:00
commit c4f764e4ce
6 changed files with 198 additions and 182 deletions

View file

@ -12,7 +12,8 @@ struct Note {
void RenderNotes();
// Global vector to store notes
std::vector<Note> notes;
std::vector<Note>* notes = new std::vector<Note>();
std::vector<HtmlElementView>* noteButtons = new std::vector<HtmlElementView>();
// Create the head section
HtmlElementView* head = new HtmlElementView("head", R"(
@ -20,16 +21,22 @@ HtmlElementView* head = new HtmlElementView("head", R"(
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center; /* Horizontal centering */
align-items: center; /* Vertical centering */
}
.app-container {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
width: 50vw;
max-width: 600px;
}
h1 {
color: #333;
@ -44,7 +51,6 @@ HtmlElementView* head = new HtmlElementView("head", R"(
.input-section textarea {
width: 100%;
height: 80px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
resize: vertical;
@ -125,7 +131,6 @@ HtmlElementView* body = new HtmlElementView("body", R"(
<button id="addNoteBtn">Add Note</button>
</div>
<div id="error"></div>
<div id="loading"></div>
<div class="notes-section">
@ -136,121 +141,97 @@ HtmlElementView* body = new HtmlElementView("body", R"(
)");
HtmlElementView* addNoteBtn = new HtmlElementView("addNoteBtn");
HtmlElementView* noteInput = new HtmlElementView("noteInput");
HtmlElementView* loadingIndicator = new HtmlElementView("loading");
HtmlElementView* notesContainer = new HtmlElementView("notesContainer");
// Function to fetch all notes from the backend
void FetchNotes() {
HtmlElementView loadingIndicator("loading");
loadingIndicator.SetInnerHTML("<p>Loading notes...</p>");
loadingIndicator->SetInnerHTML("<p>Loading notes...</p>");
// 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});
}
Fetch("http://localhost:3000/getNotes", [](std::string input) {
notes->clear();
std::istringstream stream(input);
std::string line;
while (std::getline(stream, line)) {
// Skip empty lines
if (line.empty()) continue;
// First line is ID
std::uint32_t id = std::stoi(line);
// Read content until the next empty line
std::string content;
while (std::getline(stream, line) && !line.empty()) {
if (!content.empty()) content += "\n"; // preserve line breaks
content += line;
}
prevPos = content.find('\n', pos) + 1;
if (prevPos >= content.length()) break;
notes->push_back(Note{id, content});
}
// Update UI with notes
//RenderNotes();
loadingIndicator->SetInnerHTML("<p>Notes loaded!</p>");
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("<p>Saving note...</p>");
// 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("<p>Deleting note...</p>");
loadingIndicator->SetInnerHTML("<p>Deleting note...</p>");
// Make POST request to delete note
Fetch("http://localhost:3000/deleteNote", std::to_string(id), [](std::string content) {
FetchNotes();
loadingIndicator->SetInnerHTML("<p>Note deleted!</p>");
});
}
// Function to render all notes to the DOM
void RenderNotes() {
HtmlElementView notesContainer("notesContainer");
if (notes.empty()) {
notesContainer.SetInnerHTML("<p>No notes yet. Add one below!</p>");
if (notes->empty()) {
notesContainer->SetInnerHTML("<p>No notes yet. Add one below!</p>");
return;
}
std::string html = "<div class='notes-list'>";
for (const Note& note : notes) {
noteButtons->clear();
for (const Note& note : *notes) {
html += std::format(
R"(<div class='note-item' id='note-{}'>
<div class='note-content'>{}</div>
<button class='delete-btn' onclick='DeleteNote({})'>Delete</button>
<button id="note-{}-delete" class='delete-btn'>Delete</button>
</div>)",
note.id, note.content, note.id
);
}
html += "</div>";
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) {
notesContainer->SetInnerHTML(html);
for (const Note& note : *notes) {
HtmlElementView& view = noteButtons->emplace_back(std::format("note-{}-delete", note.id));
view.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
}
std::string noteValue = noteInput->GetValue();
std::cout << noteValue << std::endl;
if (!noteValue.empty()) {
loadingIndicator->SetInnerHTML("<p>Saving note...</p>");
Fetch("http://localhost:3000/createNote", noteValue, [&noteValue](std::string content) {
notes->push_back({static_cast<std::uint32_t>(std::stoi(content)), noteValue});
noteInput->SetValue("");
RenderNotes();
loadingIndicator->SetInnerHTML("<p>Saved note!</p>");
});
}
});
}