diff --git a/public/admin.html b/public/admin.html
new file mode 100644
index 0000000..930f412
--- /dev/null
+++ b/public/admin.html
@@ -0,0 +1,372 @@
+
+
+
+
+
+ Cabo Voting β Admin
+
+
+
+
+
+
+
+
π Admin Access
+
Enter the admin password to manage the voting app.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Polls: OPEN
+
Click to toggle open/closed state
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/index.html b/public/index.html
index 7633ff2..601bccc 100644
--- a/public/index.html
+++ b/public/index.html
@@ -780,6 +780,10 @@
renderTabs();
render();
}
+ } else if (msg.type === 'option_deleted') {
+ state.options = state.options.filter(o => o.id !== msg.id);
+ renderTabs();
+ render();
} else if (msg.type === 'polls_status') {
state.pollsOpen = msg.open;
updatePollsBadge();
diff --git a/server.js b/server.js
index 548e90b..5de8857 100644
--- a/server.js
+++ b/server.js
@@ -15,6 +15,12 @@ const DATA_FILE = path.join(DATA_DIR, 'votes.json');
app.use(cors());
app.use(express.json());
+
+// Admin panel
+app.get('/admin', (req, res) => {
+ res.sendFile(path.join(__dirname, 'public', 'admin.html'));
+});
+
app.use(express.static(path.join(__dirname, 'public')));
// ββ Data helpers ββββββββββββββββββββββββββββββββββββββββββββββ
@@ -189,6 +195,16 @@ app.post('/api/options/:id/approve', (req, res) => {
res.json({ success: true });
});
+// Delete an option
+app.delete('/api/options/:id', (req, res) => {
+ const idx = data.options.findIndex(o => o.id === req.params.id);
+ if (idx === -1) return res.status(404).json({ error: 'Not found' });
+ data.options.splice(idx, 1);
+ saveData(data);
+ broadcast({ type: 'option_deleted', id: req.params.id });
+ res.json({ success: true });
+});
+
// Remove vote from an option
app.delete('/api/vote/:optionId', (req, res) => {
const { voterName } = req.body;