templates/index.html (view raw)
1<!DOCTYPE html>
2<html>
3
4<head>
5 <title>Ricorrenze</title>
6 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
7 <style>
8 body {
9 font-family: Arial, sans-serif;
10 }
11
12 table {
13 width: 100%;
14 border-collapse: collapse;
15 }
16
17 table,
18 th,
19 td {
20 border: 1px solid black;
21 }
22
23 th,
24 td {
25 padding: 10px;
26 text-align: left;
27 }
28
29 th {
30 background-color: #f2f2f2;
31 }
32
33 .small-input {
34 width: 32px;
35 }
36
37 .actions i {
38 cursor: pointer;
39 padding-right: 5px;
40 }
41
42 .cute-button {
43 margin-top: 20px;
44 background-color: #4CAF50;
45 border: none;
46 color: white;
47 padding: 10px 20px;
48 text-align: center;
49 text-decoration: none;
50 display: inline-block;
51 font-size: 16px;
52 margin: 4px 2px;
53 transition-duration: 0.4s;
54 cursor: pointer;
55 border-radius: 12px;
56 }
57
58 .cute-button:hover {
59 background-color: #45a049;
60 }
61
62 .cute-button-red {
63 background-color: #af4c4c;
64 }
65
66 .cute-button-red:hover {
67 background-color: #a14545;
68 }
69
70 .hidden {
71 display: none;
72 }
73 </style>
74</head>
75
76<body>
77 <h1>Ricorrenze</h1>
78 <table id="main-table">
79 <tr>
80 <th>ID</th>
81 <th>Nome</th>
82 <th>Descrizione</th>
83 <th>Data (gg/mm)</th>
84 <th>Notifica</th>
85 <th>Azioni</th>
86 </tr>
87 {{ range .Occurrences }}
88 <tr id="occurrence-{{ .ID }}">
89 <td>{{ .ID }}</td>
90 <td>{{ .Name }}</td>
91 <td>{{ .Description }}</td>
92 <td>{{ padZero .Day }}/{{ padZero .Month }}</td>
93 <td><input type="checkbox" {{if .Notify}}checked{{end}} disabled></td>
94 <td class="actions">
95 <i class="fas fa-edit" title="Edit" onclick="editOccurrence('{{ .ID }}')"></i>
96 <i class="fas fa-trash-alt" title="Delete" onclick="deleteOccurrence('{{ .ID }}')"></i>
97 </td>
98 </tr>
99 {{ end }}
100 <tr id="occurrence-none">
101 <td colspan="6">Nessuna ricorrenza.</td>
102 </tr>
103 </table>
104 <div style="margin-top: 10px; text-align: center;">
105 <button id="add-row-button" class="cute-button" onclick="addNewOccurrenceRow()">
106 <i class="fas fa-plus"></i> Aggiungi</button>
107 <button id="save-row-button" class="cute-button hidden" onclick="saveNewOccurrence()">
108 <i class="fas fa-save"></i> Salva
109 </button>
110 <button id="cancel-row-button" class="cute-button cute-button-red hidden" onclick="cancelNewOccurrence()">
111 <i class="fas fa-times"></i> Annulla
112 </button>
113 </div>
114
115 <script>
116 const hiddenClass = 'hidden';
117 const addButton = document.getElementById('add-row-button');
118 const saveButton = document.getElementById('save-row-button');
119 const cancelButton = document.getElementById('cancel-row-button');
120 const mainTable = document.getElementById('main-table');
121 const noneRow = document.getElementById('occurrence-none');
122
123 function updateNoneRowDisplay() {
124 const rows = mainTable.getElementsByTagName('tr');
125 const l = rows.length
126 console.log(l);
127 if (l === 2) {
128 noneRow.classList.remove(hiddenClass);
129 return;
130 }
131 noneRow.classList.add(hiddenClass);
132 }
133
134 function deleteOccurrence(id) {
135 if (confirm('Sei sicuro di voler eliminare questa ricorrenza?')) {
136 fetch(`/occurrences/${id}`, {
137 method: 'DELETE'
138 })
139 .then(response => {
140 if (!response.ok) {
141 console.error('Error:', response.status);
142 alert('Eliminazione fallita.');
143 return;
144 }
145 const deletedRow = document.getElementById(`occurrence-${id}`);
146 deletedRow.parentElement.removeChild(deletedRow);
147 updateNoneRowDisplay();
148 })
149 .catch(error => {
150 console.error('Error:', error);
151 alert('Non sono riuscito a contattare il backend.');
152 });
153 }
154 }
155
156 function padNumber(input, n=2) {
157 return input.toString().padStart(n, '0');
158 }
159
160 function createRow(id, name, description, day, month, notify) {
161 return `
162 <td>${id}</td>
163 <td>${name}</td>
164 <td>${description}</td>
165 <td>${padNumber(day)}/${padNumber(month)}</td>
166 <td><input type="checkbox" ${notify ? 'checked' : ''} disabled></td>
167 <td class="actions">
168 <i class="fas fa-edit" title="Edit" onclick="editOccurrence(${id})"></i>
169 <i class="fas fa-trash-alt" title="Delete" onclick="deleteOccurrence(${id})"></i>
170 </td>
171 `;
172 }
173
174 function createInputFields(id, name, description, day, month, notify, isNew) {
175 return `
176 <td>${isNew ? '' : id}</td>
177 <td><input type="text" value="${name || ''}" id="${isNew ? 'new' : 'edit'}-name-${id}"></td>
178 <td><input type="text" value="${description || ''}" id="${isNew ? 'new' : 'edit'}-description-${id}"></td>
179 <td><input type="number" value="${day || ''}" id="${isNew ? 'new' : 'edit'}-day-${id}" class="small-input" min="1" max="31"> / <input type="number" value="${month || ''}" id="${isNew ? 'new' : 'edit'}-month-${id}" class="small-input" min="1" max="12"></td>
180 <td><input type="checkbox" id="${isNew ? 'new' : 'edit'}-notify-${id}" ${notify ? 'checked' : ''}></td>
181 <td class="actions">
182 ${isNew ? '' : `
183 <i class="fas fa-save" title="Save" onclick="saveOccurrence(${id})"></i>
184 <i class="fas fa-times" title="Cancel" onclick="cancelEdit(${id}, '${name}', '${description}', ${day}, ${month}, ${notify})"></i>
185 `}
186 </td>
187 `;
188 }
189
190 function editOccurrence(id) {
191 const row = document.getElementById(`occurrence-${id}`);
192 const cells = row.getElementsByTagName('td');
193
194 const name = cells[1].innerText;
195 const description = cells[2].innerText;
196 const [day, month] = cells[3].innerText.split('/');
197 const notify = cells[4].getElementsByTagName('input')[0].checked;
198
199 row.innerHTML = createInputFields(id, name, description, day, month, notify, false);
200 }
201
202 function cancelEdit(id, name, description, day, month, notify) {
203 const row = document.getElementById(`occurrence-${id}`);
204 row.innerHTML = createRow(id, name, description, day, month, notify);
205 }
206
207 function saveOccurrence(id) {
208 const name = document.getElementById(`edit-name-${id}`).value;
209 const description = document.getElementById(`edit-description-${id}`).value;
210 const day = parseInt(document.getElementById(`edit-day-${id}`).value);
211 const month = parseInt(document.getElementById(`edit-month-${id}`).value);
212 const notify = document.getElementById(`edit-notify-${id}`).checked;
213
214 const updatedData = {
215 id: id,
216 name: name,
217 description: description,
218 month: month,
219 day: day,
220 notify: notify
221 };
222
223 fetch('/occurrences', {
224 method: 'POST',
225 headers: {
226 'Content-Type': 'application/json'
227 },
228 body: JSON.stringify(updatedData)
229 })
230 .then(response => {
231 if (!response.ok) {
232 console.error('Error:', response.status);
233 alert('Controlla che i campi siano validi.');
234 return;
235 }
236 updateRow(`occurrence-${id}`, response);
237 })
238 .catch(error => {
239 console.error('Error:', error);
240 alert('Non sono riuscito a contattare il backend.');
241 });
242 }
243
244 function addNewOccurrenceRow() {
245 const table = document.querySelector('table');
246 const newRow = table.insertRow(-1);
247 newRow.id = 'new-occurrence';
248 newRow.innerHTML = createInputFields('new', '', '', '', '', true, true);
249
250 hideAddButton();
251 updateNoneRowDisplay();
252 }
253 function hideAddButton() {
254 addButton.classList.add(hiddenClass);
255 saveButton.classList.remove(hiddenClass);
256 cancelButton.classList.remove(hiddenClass);
257 console.log("hidden");
258 }
259
260 function showAddButton() {
261 addButton.classList.remove(hiddenClass);
262 saveButton.classList.add(hiddenClass);
263 cancelButton.classList.add(hiddenClass);
264 console.log("shown");
265 }
266
267 function updateRow(rowElementId, response) {
268 const newRow = document.getElementById(rowElementId);
269 response.json().then((res) => {
270 newRow.id = `occurrence-${res.id}`;
271 newRow.innerHTML = createRow(res.id, res.name, res.description, res.day, res.month, res.notify);
272 updateNoneRowDisplay()
273 });
274 }
275
276 function saveNewOccurrence() {
277 const name = document.getElementById('new-name-new').value;
278 const description = document.getElementById('new-description-new').value;
279 const day = parseInt(document.getElementById('new-day-new').value);
280 const month = parseInt(document.getElementById('new-month-new').value);
281 const notify = document.getElementById('new-notify-new').checked;
282
283 const newData = {
284 name: name,
285 description: description,
286 month: month,
287 day: day,
288 notify: notify
289 };
290
291 fetch('/occurrences', {
292 method: 'POST',
293 headers: {'Content-Type': 'application/json'},
294 body: JSON.stringify(newData)
295 })
296 .then(response => {
297 if (!response.ok) {
298 console.error('Error:', response.status);
299 alert('Controlla che i campi siano validi.');
300 return;
301 }
302 updateRow('new-occurrence', response);
303 showAddButton();
304 updateNoneRowDisplay();
305 })
306 .catch(error => {
307 console.error('Error:', error);
308 alert('Non sono riuscito a contattare il backend.');
309 });
310 }
311
312 function cancelNewOccurrence() {
313 // Remove the newly added row
314 const newRow = document.getElementById('new-occurrence');
315 newRow.parentNode.removeChild(newRow);
316 showAddButton();
317 updateNoneRowDisplay();
318 }
319
320 updateNoneRowDisplay()
321 </script>
322
323</body>
324
325</html>