import { escapeHtml } from "https://deno.land/x/escape_html/mod.ts";
export default async function server(request: Request): Promise<Response> {
const { sqlite } = await import("https://esm.town/v/stevekrouse/sqlite");
const SCHEMA_VERSION = 1
const KEY = new URL(import.meta.url).pathname.split("/").at(-1);
await sqlite.execute(`
CREATE TABLE IF NOT EXISTS ${KEY}_todos_${SCHEMA_VERSION} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT 0
)
`);
const url = new URL(request.url);
if (request.method === "POST") {
const formData = await request.formData();
if (formData.get("action") === "add") {
const content = formData.get("content");
if (content) {
await sqlite.execute(`INSERT INTO ${KEY}_todos_${SCHEMA_VERSION} (content) VALUES (?)`, [content]);
}
} else if (formData.get("action") === "toggle") {
const id = formData.get("id");
await sqlite.execute(`UPDATE ${KEY}_todos_${SCHEMA_VERSION} SET completed = NOT completed WHERE id = ?`, [id]);
} else if (formData.get("action") === "delete") {
const id = formData.get("id");
await sqlite.execute(`DELETE FROM ${KEY}_todos_${SCHEMA_VERSION} WHERE id = ?`, [id]);
}
return new Response(null, { status: 302, headers: { Location: url.pathname }});
}
const todos = await sqlite.execute(`SELECT * FROM ${KEY}_todos_${SCHEMA_VERSION} ORDER BY id DESC`);
const checkboxIcon = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="2" y="2" width="20" height="20" rx="5" stroke="currentColor" stroke-width="2"/>
<path d="M7 13L10 16L17 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>`;
const trashIcon = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 6H5H21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 6V4C8 3.46957 8.21071 2.96086 8.58579 2.58579C8.96086 2.21071 9.46957 2 10 2H14C14.5304 2 15.0391 2.21071 15.4142 2.58579C15.7893 2.96086 16 3.46957 16 4V6M19 6V20C19 20.5304 18.7893 21.0391 18.4142 21.4142C18.0391 21.7893 17.5304 22 17 22H
</svg>`;
const todoListHtml = todos.rows.map(todo => `
<li class="${todo.completed ? 'completed' : ''}">
<span>${escapeHtml(todo.content)}</span>
<div class="actions">
<form method="POST">
<input type="hidden" name="action" value="toggle">
<input type="hidden" name="id" value="${todo.id}">
<button type="submit" class="icon-button toggle">${checkboxIcon}</button>
</form>
<form method="POST">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="${todo.id}">
<button type="submit" class="icon-button delete">${trashIcon}</button>
</form>
</div>
</li>
`).join('');
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>To Do List</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #ffffff;
color: #000000;
}
h1 {
color: #000000;
text-align: center;
margin-bottom: 30px;
font-weight: 700;