-
Notifications
You must be signed in to change notification settings - Fork 0
/
renderer.js
457 lines (369 loc) · 13.8 KB
/
renderer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
// Send a message to the main process
window.electron.ipcRenderer.send("message-from-renderer", "Hello from THE BLACKGEEK");
// Listen for a reply from the main process
window.electron.ipcRenderer.on("reply-from-main", (message) => {
console.log(message); // Should print "Hello from the main process"
const button = document.getElementById("send-message");
button.addEventListener("click", () => {
electron.ipcRenderer.send("message-from-renderer", "Message after button click");
});
});
document.addEventListener("DOMContentLoaded", () => {
let currentNoteId = null; // Variable to store the current note ID
const errorMessage = document.getElementById("showError");
// Function to fetch notes from the database
async function fetchnotes() {
try {
const notes = await window.electron.ipcRenderer.invoke("fetch-note");
// console.log(notes);
// Pass the notes to the displaying functions
createButtons(notes);
} catch (error) {
console.error("Error fetching notes:", error);
}
}
const closeViewModal = document.getElementById("closeView");
closeViewModal.onclick = function () {
viewModal.style.display = "none";
};
// Function to create buttons based on fetched notes
function createButtons(notes) {
const container = document.getElementById("entryDisplay");
// Clear existing elements
container.innerHTML = "";
/*Below i have implemented a logic to check if there a re no notes to display the
a message saying list empty should appear. This is done through checking the lenght of
the notes array. Because if it zero means there are no notes in the database
*/
if (notes.length < 1) {
// console.log("Table Empty");
// create element that displays the empty list element
const emptyMessage = document.createElement("div");
emptyMessage.classList.add("entry-display-no");
const empty = document.createElement("p");
empty.classList.add("empty");
empty.textContent = " Oops !";
const emptySub = document.createElement("p");
emptySub.classList.add("empty-sub");
emptySub.textContent = " Nothing to show, add a new note now!";
// Append the button to the div
emptyMessage.appendChild(empty);
emptyMessage.appendChild(emptySub);
// Append the button to the container
container.appendChild(emptyMessage);
} else {
// console.log("Table Has values");
// Create the button that displays the notes
notes.forEach((note) => {
// Create the main button element
const button = document.createElement("button");
button.type = "button";
button.title = " Click to View";
button.classList.add("btn", "entry", "note");
// Create the inner elements
const noteCategory = document.createElement("div");
noteCategory.classList.add("col-3", "left", "capitalize", "cat");
noteCategory.textContent = note.NOTE_CATEGORY;
const noteTitle = document.createElement("div");
noteTitle.classList.add("col-4", "left", "capitalize", "cat");
noteTitle.textContent = note.NOTE_TITLE;
const noteDate = document.createElement("div");
noteDate.classList.add("col-3", "right", "cat");
noteDate.textContent = note.NOTE_DATE;
const noteContent = document.createElement("div");
noteContent.classList.add("cat");
noteContent.textContent = note.NOTE_CONTENT;
// event for button
button.addEventListener("click", () => {
currentNoteId = note.NOTE_ID; // Store the note ID of clicked
showViewNoteModal(note);
});
// Append inner elements to the button
button.appendChild(noteCategory);
button.appendChild(noteTitle);
button.appendChild(noteDate);
// Append the button to the container
container.appendChild(button);
});
}
}
// Function to show the view note modal
function showViewNoteModal(note) {
const viewModal = document.getElementById("viewModal");
// Populate modal with note details
document.getElementById("showCategory").textContent = note.NOTE_CATEGORY;
document.getElementById("showTitle").textContent = note.NOTE_TITLE;
document.getElementById("showContent").textContent = note.NOTE_CONTENT;
document.getElementById("showDate").textContent = note.NOTE_DATE;
// Show the view note details and hide the edit form
document.getElementById("note-details").style.display = "block";
document.getElementById("edit-note-form").style.display = "none";
// Display the modal
viewModal.style.display = "block";
}
const viewModal = document.getElementById("viewModal");
// When the user clicks anywhere outside of the modal, close it
window.onclick = function (event) {
if (event.target == viewModal) {
viewModal.style.display = "none";
}
};
/*
Below i have implemented the edit logic that allows user to edit and update current note
. First you open the view note modal, then you see edit button which opens a modal similar to
add note modal. The the fields are populated with already exists content so yo can edit through
Validations is undertaken and then you can save.
*/
// Edit note button handler
const editNoteButton = document.getElementById("edit-note-button");
editNoteButton.addEventListener("click", () => {
// Hide the view note details and show the edit form
document.getElementById("note-details").style.display = "none";
document.getElementById("edit-note-form").style.display = "block";
// Populate the edit form with current note details
document.getElementById("edit-note-category").value =
document.getElementById("showCategory").textContent;
document.getElementById("edit-note-title").value =
document.getElementById("showTitle").textContent;
document.getElementById("edit-note-content").value =
document.getElementById("showContent").textContent;
});
// Save edit button handler
const saveEditButton = document.getElementById("save-edit-button");
saveEditButton.addEventListener("click", async () => {
const editedNoteCategory = document.getElementById("edit-note-category").value;
const editedNoteTitle = document.getElementById("edit-note-title").value;
const editedNoteContent = document.getElementById("edit-note-content").value;
// Validation logic for the fields being edited
const textPattern = /^[A-Za-z\s]+$/; // Pattern to allow only letters and spaces
if (!editedNoteCategory || !editedNoteTitle || !editedNoteContent) {
errorMessage.textContent = "All fields must be filled !";
return;
}
if (!textPattern.test(editedNoteTitle)) {
errorMessage.textContent = "Title should only contain letters and spaces.";
return;
}
if (!textPattern.test(editedNoteCategory)) {
errorMessage.textContent = "Category should only contain letters and spaces.";
return;
}
// Updating the note in the database
try {
const result = await window.electron.ipcRenderer.invoke("update-note", {
note_id: currentNoteId,
note_category: editedNoteCategory,
note_title: editedNoteTitle,
note_content: editedNoteContent,
});
console.log("Note updated with ID:", currentNoteId);
// After updating the note, close the modal
viewModal.style.display = "none";
fetchnotes();
countNotes();
} catch (error) {
console.error("Error updating note:", error);
}
});
/*
Below i have implemented the delete note handler from the main process. On top,
there is a var currentNoteId set null and updated on event click to view, then stored
then used to delete the note based on that id.
*/
// Delete note button handler
const deleteNoteButton = document.getElementById("deleteModal");
deleteNoteButton.addEventListener("click", async () => {
if (currentNoteId) {
try {
await window.electron.ipcRenderer.invoke("delete-note", currentNoteId);
console.log("Note deleted with ID:", currentNoteId);
// Close the modal after deletion
viewModal.style.display = "none";
// Fetch notes and count again to update the list
fetchnotes();
countNotes();
} catch (error) {
console.error("Error deleting note:", error);
}
}
});
// Fetch notes initially when the page loads
fetchnotes();
/*
Below function fetches the number of notes available in the table. There is
a handler defined in the main process, However i used the work-around of just getting the
array lenght of the objects fetched by the fetch notes handle.
*/
async function countNotes() {
try {
const notes = await window.electron.ipcRenderer.invoke("fetch-note");
// console.log("count: " + notes.length);
const count = notes.length;
const newCount = String(count).padStart(2, "0");
// Display number of notes
const notesCount = document.getElementById("displayCount");
notesCount.textContent = `Notes: ${newCount}`;
} catch (error) {
console.error("Error fetching notes:", error);
}
}
// fetch note count initially when the page loads
countNotes();
// Get the modal
const modal = document.getElementById("myModal");
// Get the button that opens the modal
const openModalButton = document.getElementById("open-modal-button");
// Get the form
const addNoteForm = document.getElementById("add-note-form");
// open the modal When the add note button is clicked
openModalButton.onclick = function () {
modal.style.display = "block";
};
// close modal when the close button is clicked
const closeButton = document.getElementById("closeModal");
closeButton.onclick = function () {
modal.style.display = "none";
addNoteForm.reset();
errorMessage.textContent = " ";
};
// When the user clicks anywhere outside of the modal, close it
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
errorMessage.textContent = " ";
}
};
// function to format date
function formatDate(date) {
// Array of months in short
const months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
// get date
const dayOfMonth = String(date.getDate()).padStart(2, "0");
const month = months[date.getMonth()];
const year = date.getFullYear();
// return date
return `${month} ${dayOfMonth}, ${year}`;
}
// function to format time
function formatTime(date) {
// get time
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
// return time
return `${hours}:${minutes}`;
}
// get seconds seperately
function countSeconds(date) {
const seconds = String(date.getSeconds()).padStart(2, "0");
return `:${seconds}`;
}
// tick tok every second to update live clock and date
function tick() {
// set current time and date
const currentDate = new Date();
const formattedDate = formatDate(currentDate);
const currentTime = new Date();
const formattedTime = formatTime(currentTime);
const formattedseconds = countSeconds(currentTime);
// display time on screen
const displayTime = document.getElementById("currentTime");
displayTime.textContent = `${formattedTime}${formattedseconds} HRS`;
// display date
const displayDate = document.getElementById("todayDate");
displayDate.textContent = formattedDate;
}
// call tick function
tick();
// Set interval to generate live clock
setInterval(tick, 1000);
/*
Below is the handle to submit the data collected from the form.
*/
// Handle form submission
addNoteForm.addEventListener("submit", async (event) => {
event.preventDefault();
// get elements fo input fields
const noteCategory = document.getElementById("note-category").value;
const noteTitle = document.getElementById("note-title").value;
const noteContent = document.getElementById("note-content").value;
// Validation logic defined below
const textPattern = /^[A-Za-z\s]+$/; // Pattern to allow only letters and spaces
// check if fields are empty
if (!noteCategory || !noteTitle || !noteContent) {
errorMessage.textContent = "All fields must be filled !";
return;
}
// check for symbols in Title and Category
if (!textPattern.test(noteTitle)) {
errorMessage.textContent = "Title should only contain letters and spaces.";
return;
}
if (!textPattern.test(noteCategory)) {
errorMessage.textContent = "Category should only contain letters and spaces.";
return;
}
//format date to post to database
const currentDate = new Date();
const formattedDate = formatDate(currentDate);
const currentTime = new Date();
const formattedTime = formatTime(currentTime);
const fullDate = `${formattedDate} ${formattedTime}`;
console.log(fullDate);
// call API to post values to Database
try {
const result = await window.electron.ipcRenderer.invoke("add-note", {
note_category: noteCategory,
note_title: noteTitle,
note_content: noteContent,
note_date: fullDate,
});
// log ID of added note
console.log("Note added with ID:", result.id);
// After adding the note, close the modal and clear the form
modal.style.display = "none";
addNoteForm.reset();
// fetch notes and count again to update the list
fetchnotes();
countNotes();
} catch (error) {
console.error("Error adding note:", error);
}
});
/* Not killing the dream of allowing top text to be dynamic so added an array of
my desired phrases to be interating as the app is open. */
function setTopText() {
// Array of phrases
const texts = ["Hello Scriber !", "Track your Ideas", "Capture your Thoughts"];
//get random text by random value representing index
const randomIndex = Math.floor(Math.random() * texts.length);
const newText = texts[randomIndex];
// set top text
const topText = document.getElementById("theme");
topText.textContent = newText;
}
// call function initially when the page loads
setTopText();
// change phrase at interval
setInterval(setTopText, 10000);
});
/*
::Developed from scratch with the so purpose of;
1. Learning Desktop App Development with Electron JS
2. Sharpen my JavaScript Coding Skills
3. Writing a Efficient and Clean Code.
Deloveped BY THE BLACKGEEK :)
Happy Note Taking !
*/