Skip to content

Commit

Permalink
feat: save checkbox updates
Browse files Browse the repository at this point in the history
Signed-off-by: Ourchitecture <[email protected]>
  • Loading branch information
ourchitectureio committed Sep 23, 2023
1 parent 7c554da commit 1ea9e9f
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 27 deletions.
11 changes: 11 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,14 @@ test: check
.PHONY: format
format: init
@pnpm format

# This command assumes that a `sync` will result in two pushes:
# 1) pushing the code
# 2) pushing the tags
# As a result, the first code push should kick off a workflow run before the
# `gh run watch` command is issued. However, there is some risk that this
# sequence could run too quickly before the workflow run is available.
.PHONY: sync
sync:
@git-town sync
@gh run watch
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var session = require('express-session')
var indexRouter = require('./routes/index')
var createTodoRouter = require('./routes/createTodo')
var toggleCompletedRouter = require('./routes/toggleCompleted')
var saveAllRouter = require('./routes/saveAll')

var app = express()

Expand Down Expand Up @@ -38,6 +39,7 @@ app.use(express.static(path.join(__dirname, 'public')))
app.use('/', indexRouter)
app.use('/todos/create', createTodoRouter)
app.use('/todos/toggle-completed', toggleCompletedRouter)
app.use('/todos/save-all', saveAllRouter)

// catch 404 and forward to error handler
app.use(function (req, res, next) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
var express = require('express')
var router = express.Router()
const express = require('express')

const TODO_STATUS = {
none: 'none',
completed: 'completed',
}
const { TODO_STATUS } = require('./todos')

const router = express.Router()

const createViewModel = (serverTodos, errorMessage) => {
const areAllCompleted =
serverTodos.filter((todo) => todo.status != TODO_STATUS.completed)
.length == 0

const mapServerTodosToClient = (serverTodos) => {
return serverTodos.map((serverTodo) => {
return {
id: serverTodo.id,
text: serverTodo.text,
isCompleted: serverTodo.status == TODO_STATUS.completed,
}
})
return {
title: 'Web 1.0: Our Todos',
areAllCompleted,
todos: serverTodos.map((serverTodo) => {
return {
id: serverTodo.id,
text: serverTodo.text,
isCompleted: serverTodo.status == TODO_STATUS.completed,
}
}),
error: errorMessage || null,
}
}

/* GET home page. */
Expand All @@ -22,11 +29,9 @@ router.get('/', function (req, res, next) {
req.session.todos = []
}

res.render('index', {
title: 'Our Todos',
todos: mapServerTodosToClient(req.session.todos),
error: req.query.e || null,
})
const viewModel = createViewModel(req.session.todos, req.query.e)

res.render('index', viewModel)
})

module.exports = router
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const express = require('express')

const { TODO_STATUS } = require('./todos')

const router = express.Router()

router.post('/', function (req, res, next) {
if (!req.session.todos) {
req.session.todos = []
}

const originalTodos = req.session.todos

// start with every todo marked as "none"
const updatedTodos = originalTodos.map((todo) => {
todo.status = TODO_STATUS.none
return todo
})

const completedTodoIds = req.body['completed-todo-id']
? Array.isArray(req.body['completed-todo-id'])
? req.body['completed-todo-id']
: [req.body['completed-todo-id']]
: []

for (const completedTodoId of completedTodoIds) {
const todosRequiringCompletion = updatedTodos.filter(
(todo) => todo.id == completedTodoId
)

if (todosRequiringCompletion.length > 1) {
res.status(403)
res.send(
`Unexpected duplicate todos discovered with id: ${completedTodoId}`
)
return
}

if (todosRequiringCompletion.length === 0) {
res.status(403)
res.send(`Unexpected todo id: ${completedTodoId}`)
return
}

todosRequiringCompletion[0].status = TODO_STATUS.completed
}

req.session.todos = updatedTodos

res.redirect('/')
})

module.exports = router
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const TODO_STATUS = {
none: 'none',
completed: 'completed',
}

module.exports = {
TODO_STATUS,
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,25 @@ block content
h1=title
if todos.length > 0
form(method="POST",action="/todos/toggle-completed")
button(type="submit",id="toggle-completed",name="toggle-completed") Toggle completed
if areAllCompleted
button(type="submit",id="toggle-completed",name="toggle-completed",aria-label="Toggle all items as complete or incomplete") &and;
else
button(type="submit",id="toggle-completed",name="toggle-completed",aria-label="Toggle all items as complete or incomplete") &or;
form(method="POST",action="/todos/create")
input(name="new-todo",placeholder="What needs to be done?",value="",autofocus,aria-label="New todo")
button(type="submit") Submit
if error
div(data-testid="error",class="error")= error
main
if todos.length > 0
section(data-testid="main")
ul
each todo in todos
li(data-id=todo.id)
label(for="todo-"+todo.id)
input(type="checkbox",id="todo-"+todo.id,name="todo-"+todo.id,checked=todo.isCompleted)
span #{todo.text}
form(method="POST",action="/todos/save-all")
section(data-testid="main")
ul
each todo in todos
li(data-id=todo.id)
label(for="todo-"+todo.id)
input(type="checkbox",id="todo-"+todo.id,name="completed-todo-id",checked=todo.isCompleted,value=todo.id)
span #{todo.text}
button(type="submit") Save
if todos.length > 0
footer(data-testid="footer") Some footer content

0 comments on commit 1ea9e9f

Please sign in to comment.