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