-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
129 lines (111 loc) · 4.01 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
const html = todos => `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Tasks</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css" rel="stylesheet"></link>
</head>
<body class="bg-black text-white">
<div class="w-full h-full flex content-center justify-center mt-8">
<div id="todo" class="shadow-md rounded px-8 pt-6 py-8 mb-4" style="width: 620px">
<h1 class="block text-white-400 text-md font-bold mb-2" style="font-size: 24px; margin-bottom: 12px">Tasks</h1>
<div class="flex" style="margin-bottom: 32px">
<input class="shadow appearance-none border w-full py-2 px-3 text-black leading-tight focus:outline-none focus:shadow-outline" type="text" name="name" placeholder="Type your new task here"></input>
<button class="bg-purple-500 hover:bg-purple-800 text-white font-bold ml-2 py-2 px-4 focus:outline-none focus:shadow-outline" id="create" type="submit">Add</button>
</div>
<div class="mt-4" id="todos"></div>
</div>
</div>
</body>
<script>
window.todos = ${todos}
var updateTodos = function() {
fetch("/", { method: 'PUT', body: JSON.stringify({ todos: window.todos }) })
populateTodos()
}
var completeTodo = function(evt) {
var checkbox = evt.target
var todoElement = checkbox.parentNode
var newTodoSet = [].concat(window.todos)
var todo = newTodoSet.find(t => t.id == todoElement.dataset.todo)
todo.completed = !todo.completed
window.todos = newTodoSet
updateTodos()
}
var populateTodos = function() {
var todoContainer = document.querySelector("#todos")
todoContainer.innerHTML = null
window.todos.forEach(todo => {
var el = document.createElement("div")
el.className = "py-4"
el.style.borderTop = "1px solid #ffffffaa"
el.dataset.todo = todo.id
var name = document.createElement("span")
name.className = todo.completed ? "line-through" : ""
name.textContent = todo.name
var checkbox = document.createElement("input")
checkbox.className = "mx-4"
checkbox.type = "checkbox"
checkbox.checked = todo.completed ? 1 : 0
checkbox.addEventListener('click', completeTodo)
el.appendChild(checkbox)
el.appendChild(name)
todoContainer.prepend(el)
})
}
populateTodos()
var createTodo = function() {
var input = document.querySelector("input[name=name]")
if (input.value.length) {
window.todos = [].concat(todos, { id: window.todos.length + 1, name: input.value, completed: false })
input.value = ""
updateTodos()
}
}
document.querySelector("#create").addEventListener('click', createTodo)
</script>
</html>
`
const defaultData = { todos: [] }
const setCache = (key, data) => TODOS.put(key, data)
const getCache = key => TODOS.get(key)
async function getTodos(request) {
const ip = request.headers.get('CF-Connecting-IP')
const cacheKey = `data-${ip}`
let data
const cache = await getCache(cacheKey)
if (!cache) {
await setCache(cacheKey, JSON.stringify(defaultData))
data = defaultData
} else {
data = JSON.parse(cache)
}
const body = html(JSON.stringify(data.todos || []).replace(/</g, "\\u003c"))
return new Response(body, {
headers: { 'Content-Type': 'text/html' },
})
}
async function updateTodos(request) {
const body = await request.text()
const ip = request.headers.get('CF-Connecting-IP')
const cacheKey = `data-${ip}`
try {
JSON.parse(body)
await setCache(cacheKey, body)
return new Response(body, { status: 200 })
} catch (err) {
return new Response(err, { status: 500 })
}
}
async function handleRequest(request) {
if (request.method === 'PUT') {
return updateTodos(request)
} else {
return getTodos(request)
}
}
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})