Created
October 18, 2022 00:24
-
-
Save shawnco/e4d404b7d514f0dbfdfebac012212122 to your computer and use it in GitHub Desktop.
Time Management Web App section 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#nav { | |
list-style-type: none; | |
margin: 0; | |
padding: 0 0 10px 0; | |
} | |
#nav li { | |
display: inline; | |
margin-right: 10px | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {useEffect, useState} from 'react'; | |
const url = 'http://localhost:3001/api/task/today'; | |
const headers = { | |
'Content-Type': 'applicaton/json' | |
}; | |
const API = { | |
async getToday() { | |
const res = await fetch(`${url}`, { | |
method: 'GET', | |
headers | |
}); | |
const {result} = await res.json(); | |
return result; | |
} | |
} | |
const TaskRow = props => { | |
const {task} = props; | |
return <tr> | |
<td>{task.name}</td> | |
<td>{task.cron_string}</td> | |
</tr> | |
} | |
const Home = props => { | |
const [tasks, setTasks] = useState([]); | |
useEffect(() => { | |
async function getTasks() { | |
const data = await API.getToday(); | |
setTasks(data); | |
} | |
getTasks(); | |
}, []); | |
return <> | |
<h1>Today's Incomplete Tasks</h1> | |
<table border='1'> | |
<thead> | |
<tr> | |
<th>Name</th> | |
<th>Cron String</th> | |
</tr> | |
</thead> | |
<tbody> | |
{tasks.map(t => <TaskRow key={t.id} task={t} />)} | |
</tbody> | |
</table> | |
</> | |
} | |
export default Home; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import ReactDOM from 'react-dom/client'; | |
import {BrowserRouter, Routes, Route} from 'react-router-dom'; | |
import App from './App'; | |
import TaskTable from './tasks'; | |
import Workspace from './workspace'; | |
import Home from './home'; | |
import Nav from './nav'; | |
const root = ReactDOM.createRoot(document.getElementById('root')); | |
root.render( | |
<React.StrictMode> | |
<BrowserRouter> | |
<Nav /> | |
<Routes> | |
<Route path='/' element={<App />}> | |
<Route path='' element={<Home />} /> | |
<Route path='tasks' element={<TaskTable />} /> | |
<Route path='workspace' element={<Workspace />} /> | |
</Route> | |
</Routes> | |
</BrowserRouter> | |
</React.StrictMode> | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express'); | |
const cors = require('cors'); | |
const bodyParser = require('body-parser'); | |
const {Sequelize} = require('sequelize'); | |
const path = require('path'); | |
const TaskSchedule = require('./task_schedule'); | |
const Socket = require('./socket'); | |
const db = new Sequelize('task_schedule', 'username', 'password', { | |
host: 'localhost', | |
dialect: 'mysql', | |
operatorAliases: false, | |
pool: { max: 5, min: 0, acquire: 30000, idle: 10000 } | |
}); | |
const Task = db.define('task', { | |
id: { | |
type: Sequelize.INTEGER, | |
primaryKey: true, | |
autoIncrement: true | |
}, | |
name: Sequelize.STRING, | |
cron_string: Sequelize.STRING, | |
completed: Sequelize.BOOLEAN | |
}, { | |
freezeTableName: true, | |
timestamps: false | |
}); | |
const TaskNote = db.define('task_note', { | |
id: { | |
type: Sequelize.INTEGER, | |
primaryKey: true, | |
autoIncrement: true | |
}, | |
task: Sequelize.INTEGER, | |
time: Sequelize.DATE, | |
content: Sequelize.TEXT | |
}, { | |
freezeTableName: true, | |
timestamps: false | |
}); | |
const TaskFunctions = { | |
async getAll() { | |
return Task.findAll(); | |
}, | |
async get(id) { | |
return Task.findByPk(id); | |
}, | |
async create(data) { | |
const task = Task.create({ | |
name: data.name, | |
cron_string: data.cron_string | |
}); | |
return task; | |
}, | |
async update(id, data) { | |
const task = await Task.findByPk(id); | |
task.name = data.name || task.name; | |
task.cron_string = data.cron_string || task.cron_string; | |
task.completed = [true, false].includes(data.completed) ? data.completed : task.completed; | |
await task.save(); | |
return task; | |
}, | |
async del(id) { | |
const task = await Task.destroy({where: {id}}); | |
return id; | |
}, | |
async getIncomplete() { | |
return Task.findAll({where: {completed: false}}); | |
}, | |
async getByIds(ids) { | |
return Task.findAll({where: {id: ids}}); | |
}, | |
} | |
const TaskNoteFunctions = { | |
async getByTask(task) { | |
return TaskNote.findAll({where:{task}}); | |
}, | |
async create(data) { | |
return TaskNote.create({ | |
task: data.task, | |
time: data.time, | |
content: data.content | |
}); | |
}, | |
async update(id, data) { | |
const note = await TaskNote.findByPk(id); | |
note.content = data.content; | |
return note.save(); | |
}, | |
async del(id) { | |
const note = await TaskNote.destroy({where:{id}}); | |
return id; | |
} | |
} | |
const socket = new Socket(TaskNoteFunctions); | |
const taskSchedule = new TaskSchedule(TaskFunctions, socket); | |
taskSchedule.rebuildSchedule(); | |
const PORT = 3001; | |
const app = express(); | |
app.use(cors()); | |
app.use(bodyParser.json()); | |
app.use(express.static(path.join(__dirname + '/../client'))); | |
app.get('/api/test', (req, res) => { | |
res.send('Hello world!'); | |
}); | |
app.get('/api/task/today', async (req,res)=> { | |
const start = new Date(); | |
start.setHours(0); | |
start.setMinutes(0); | |
start.setSeconds(0); | |
start.setMilliseconds(0); | |
const end = new Date(); | |
end.setHours(23); | |
end.setMinutes(59); | |
end.setSeconds(59); | |
end.setMilliseconds(999); | |
const ids = taskSchedule.getTasksForRange(start.getTime(), end.getTime()); | |
const result = await TaskFunctions.getByIds(ids); | |
res.send({result}); | |
}); | |
app.get('/api/task/all', async (req, res) => { | |
const result = await TaskFunctions.getAll(); | |
res.send({result}); | |
}); | |
app.get('/api/task/:id', async (req, res) => { | |
const result = await TaskFunctions.get(req.params.id); | |
res.send({result}); | |
}); | |
app.post('/api/task', async (req,res) => { | |
const result = await TaskFunctions.create(req.body); | |
await taskSchedule.rebuildSchedule(); | |
res.send({result}); | |
}); | |
app.put('/api/task/:id', async (req, res) => { | |
const result = await TaskFunctions.update(req.params.id, req.body); | |
await taskSchedule.rebuildSchedule(); | |
res.send({result}); | |
}); | |
app.delete('/api/task/:id', async (req,res) => { | |
const result = await TaskFunctions.del(+req.params.id); | |
await taskSchedule.rebuildSchedule(); | |
res.send({result}); | |
}); | |
app.get('/api/task/:id/notes', async (req, res) => { | |
const result = await TaskNoteFunctions.getByTask(+req.params.id); | |
res.send({result}); | |
}); | |
app.post('/api/task/:id/notes', async (req, res) => { | |
const result = await TaskNoteFunctions.create({ | |
id: req.params.id, | |
...req.body | |
}); | |
res.send({result}); | |
}); | |
app.put('/api/task/:id/notes', async (req, res) => { | |
const {id, ...data} = req.body; | |
const result = await TaskNoteFunctions.update(id, data); | |
res.send({result}) | |
}); | |
app.delete('/api/task/:id/notes', async (req, res) => { | |
const {id} = req.body; | |
const result = await TaskNoteFunctions.del(id); | |
res.send({result}) | |
}); | |
app.listen(PORT, () => { | |
console.log(`App is live on port ${PORT}`); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment