Skip to content

Commit db260cd

Browse files
authored
betere id afhandeling en aapassing voor nieuwe offline_manager
1 parent 778fa6e commit db260cd

1 file changed

Lines changed: 36 additions & 70 deletions

File tree

index.html

Lines changed: 36 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@
3434
.safe-header { padding-top: calc(1rem + env(safe-area-inset-top, 0px)); padding-bottom: 1rem; }
3535
#loading-overlay { background: #0f172a; position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; transition: opacity 0.5s; }
3636
.sortable-ghost { opacity: 0.4; background: #334155; }
37+
.calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.5rem; }
3738
</style>
3839
</head>
3940
<body class="bg-dark-900 text-slate-100 min-h-screen flex flex-col items-center overflow-hidden">
4041

4142
<div id="loading-overlay">
4243
<div class="flex flex-col items-center">
4344
<i class="fa-solid fa-circle-notch fa-spin text-4xl text-emerald-500 mb-4"></i>
44-
<p class="text-gray-400 animate-pulse text-sm">Data synchroniseren...</p>
45+
<p class="text-gray-400 animate-pulse text-sm">Lijsten laden...</p>
4546
</div>
4647
</div>
4748

@@ -155,9 +156,10 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
155156
<script type="module">
156157
import OfflineManager from './offline_manager.js';
157158

158-
const APP_NAME = 'supermarkey';
159-
const CLIENT_ID = 'sandman';
160-
const API_URL = 'http://10.10.2.20:5000';
159+
// CONFIGURATIE
160+
const APP_NAME = 'superlijst';
161+
const CLIENT_ID = 'jouw-unieke-id'; // Tip: kan ook uit localStorage komen
162+
const API_URL = 'http://localhost:5000';
161163

162164
const manager = new OfflineManager(API_URL, CLIENT_ID, APP_NAME);
163165

@@ -169,47 +171,27 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
169171
const DataService = {
170172
getLists: async () => {
171173
const lists = await manager.getSmartCollection('lists');
172-
// Belangrijk: we gebruiken hier unieke mapping om duplicaten te voorkomen
173-
const uniqueMap = new Map();
174-
(lists || []).forEach(l => {
175-
const id = l._id || l.id;
176-
if (id) uniqueMap.set(id, l);
177-
});
178-
return Array.from(uniqueMap.values()).map(l => ({ id: l._id || l.id, data: l }));
174+
return lists.map(l => ({ id: l._id || l.id, data: l }));
179175
},
180176
saveList: async (listObj) => {
181-
// DEXIE FIX: Het 'id' veld van Dexie mag NOOIT handmatig overschreven worden.
182-
// We sturen alleen de payload en het _id voor de database mee.
183-
const payload = {
184-
name: listObj.name,
185-
items: listObj.items
186-
};
187-
188-
// Als er al een _id is, voegen we die toe aan de payload voor een UPDATE
189-
if (listObj._id) {
190-
payload._id = listObj._id;
191-
}
192-
193-
const result = await manager.saveSmartDocument('lists', payload);
194-
return result;
177+
// De manager V3 handelt _id en duplicaten nu zelf af!
178+
return await manager.saveSmartDocument('lists', listObj);
195179
},
196180
deleteList: async (id) => {
181+
// Gebruik gateway direct voor delete
197182
await manager.gateway.deleteDocument('lists', id);
198183
await manager.refreshCache('lists');
199184
},
200185
getHistory: async () => {
201186
const history = await manager.getSmartCollection('history');
202-
return (history || []).map(h => h.data || h);
187+
return history;
203188
},
204189
addHistory: async (entry) => {
205190
await manager.saveSmartDocument('history', entry);
206191
},
207192
clearHistory: async () => {
208-
const history = await manager.getSmartCollection('history');
209-
for (const item of history) {
210-
await manager.gateway.deleteDocument('history', item._id || item.id);
211-
}
212-
await manager.refreshCache('history');
193+
// Gebruik de Smart Clear van de manager V3
194+
await manager.clearSmartCollection('history');
213195
}
214196
};
215197

@@ -224,30 +206,25 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
224206
statDate: new Date(),
225207

226208
init: async () => {
227-
// 1. Initialiseer Dashboard
228209
await app.renderDashboard();
229210

230-
// 2. Verberg loading overlay
231211
const overlay = document.getElementById('loading-overlay');
232212
if(overlay) {
233213
overlay.style.opacity = '0';
234214
setTimeout(() => overlay.remove(), 500);
235215
}
236216

237-
// 3. Sync en refresh
238217
if (navigator.onLine) {
239218
manager.syncOutbox().then(() => app.renderDashboard());
240219
}
241220

242221
window.addEventListener('online', () => {
243-
app.showToast("Verbinding hersteld...");
222+
app.showToast("Verbinding hersteld, sync gestart...");
244223
manager.syncOutbox().then(() => app.renderDashboard());
245224
});
246225

247226
if ('serviceWorker' in navigator) {
248-
window.addEventListener('load', () => {
249-
navigator.serviceWorker.register('./sw.js').catch(e => console.error(e));
250-
});
227+
navigator.serviceWorker.register('./sw.js').catch(e => console.error(e));
251228
}
252229
},
253230

@@ -275,8 +252,6 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
275252
const savedContainer = tpl.getElementById('saved-list-container');
276253
const emptyState = tpl.getElementById('empty-state');
277254

278-
savedContainer.innerHTML = '';
279-
280255
document.getElementById('header-title').innerText = "SuperLijst";
281256
document.getElementById('header-actions').innerHTML = `<button onclick="app.renderStats()" class="text-gray-400 hover:text-white transition"><i class="fa-solid fa-calendar-days text-xl"></i></button>`;
282257

@@ -285,10 +260,9 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
285260
if (lists.length === 0) {
286261
emptyState.classList.remove('hidden');
287262
} else {
288-
lists.sort((a, b) => a.data.name.localeCompare(b.data.name));
289-
lists.forEach(item => {
290-
savedContainer.appendChild(app.createListCard(item, true));
291-
});
263+
// Sorteren op naam
264+
lists.sort((a, b) => (a.data.name || "").localeCompare(b.data.name || ""));
265+
lists.forEach(item => savedContainer.appendChild(app.createListCard(item)));
292266
}
293267
} catch (e) {
294268
console.error(e);
@@ -297,10 +271,10 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
297271
main.appendChild(tpl);
298272
},
299273

300-
createListCard: (item, isSaved) => {
274+
createListCard: (item) => {
301275
const div = document.createElement('div');
302276
div.className = "bg-dark-800 p-4 rounded-xl border border-gray-700 hover:border-emerald-500/50 transition flex justify-between items-center group cursor-pointer";
303-
div.onclick = () => app.startEdit(item.data, isSaved ? item.id : null);
277+
div.onclick = () => app.startEdit(item.data);
304278

305279
div.innerHTML = `
306280
<div class="flex items-center gap-3">
@@ -324,22 +298,17 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
324298
}
325299
};
326300
div.appendChild(delBtn);
327-
328301
return div;
329302
},
330303

331-
startEdit: (data, id = null) => {
332-
// Zorg voor een schone kopie van de data
333-
app.currentList = {
334-
name: data.name || '',
335-
items: Array.isArray(data.items) ? [...data.items] : [],
336-
_id: id || data._id || null
337-
};
304+
startEdit: (data) => {
305+
// Schone kopie maken voor bewerken
306+
app.currentList = JSON.parse(JSON.stringify(data));
338307
app.renderEditor();
339308
},
340309

341310
startEmpty: () => {
342-
app.currentList = { name: '', items: [], _id: null };
311+
app.currentList = { name: '', items: [] };
343312
app.renderEditor();
344313
},
345314

@@ -349,7 +318,7 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
349318

350319
const tpl = document.getElementById('tpl-editor').content.cloneNode(true);
351320
const nameInput = tpl.getElementById('list-name-input');
352-
nameInput.value = app.currentList.name;
321+
nameInput.value = app.currentList.name || '';
353322
nameInput.oninput = (e) => app.currentList.name = e.target.value;
354323

355324
const ul = tpl.getElementById('editor-items');
@@ -395,13 +364,10 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
395364
saveOnly: async () => {
396365
if (!app.currentList.name) app.currentList.name = "Naamloze lijst";
397366
try {
398-
const saved = await DataService.saveList(app.currentList);
399-
// Update het ID voor het geval het een nieuwe lijst was
400-
if (saved && saved._id) {
401-
app.currentList._id = saved._id;
402-
}
367+
await DataService.saveList(app.currentList);
403368
app.showToast("Opgeslagen");
404-
setTimeout(() => app.renderDashboard(), 150);
369+
// Geef de manager even tijd om de _id koppeling te doen bij een sync
370+
setTimeout(() => app.renderDashboard(), 200);
405371
} catch (e) {
406372
app.showToast("Opslaan mislukt", "danger");
407373
}
@@ -410,14 +376,11 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
410376
saveAndShop: async () => {
411377
if (!app.currentList.name) app.currentList.name = "Mijn lijst";
412378
if (app.currentList.items.length === 0) {
413-
app.showToast("Lijst is leeg!", "danger");
379+
app.showToast("Voeg eerst producten toe!", "danger");
414380
return;
415381
}
416382
try {
417-
const saved = await DataService.saveList(app.currentList);
418-
if (saved && saved._id) {
419-
app.currentList._id = saved._id;
420-
}
383+
await DataService.saveList(app.currentList);
421384
app.shoppingList = app.currentList.items.map(i => ({ ...i, done: false }));
422385
app.renderShopping();
423386
} catch (e) {
@@ -466,7 +429,11 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
466429
},
467430

468431
finishShopping: async () => {
469-
await DataService.addHistory({ date: new Date().toISOString(), listName: app.currentList.name });
432+
await DataService.addHistory({
433+
date: new Date().toISOString(),
434+
listName: app.currentList.name,
435+
itemCount: app.shoppingList.length
436+
});
470437
app.showToast("Winkelen voltooid!");
471438
app.renderDashboard();
472439
},
@@ -477,7 +444,6 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
477444
main.innerHTML = '';
478445

479446
const tpl = document.getElementById('tpl-stats').content.cloneNode(true);
480-
481447
const year = app.statDate.getFullYear();
482448
const month = app.statDate.getMonth();
483449
tpl.getElementById('stats-month-year').innerText = new Intl.DateTimeFormat('nl-NL', { month: 'long', year: 'numeric' }).format(app.statDate);
@@ -496,7 +462,7 @@ <h2 id="stats-month-year" class="text-lg font-bold text-white capitalize"></h2>
496462
for (let day = 1; day <= daysInMonth; day++) {
497463
const count = monthHistory.filter(h => new Date(h.date).getDate() === day).length;
498464
const div = document.createElement('div');
499-
div.className = `aspect-square rounded-lg flex flex-col items-center justify-center text-sm border ${count > 0 ? 'bg-emerald-500/20 border-emerald-500 text-white' : 'bg-dark-900 border-gray-800 text-gray-500'}`;
465+
div.className = `aspect-square rounded-lg flex flex-col items-center justify-center text-sm border ${count > 0 ? 'bg-emerald-500/20 border-emerald-500 text-white shadow-[0_0_10px_rgba(16,185,129,0.2)]' : 'bg-dark-900 border-gray-800 text-gray-500'}`;
500466
div.innerHTML = `<span>${day}</span>${count > 0 ? `<span class="text-[9px] text-emerald-400 font-bold">+${count}</span>` : ''}`;
501467
daysContainer.appendChild(div);
502468
}

0 commit comments

Comments
 (0)