mirror of
https://github.com/peter-tanner/todo-list.git
synced 2024-11-30 10:50:18 +08:00
Integrated very basic firebase database into app
This commit is contained in:
parent
be62724b91
commit
26e1b1dc2f
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -21,3 +21,6 @@
|
|||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Secret
|
||||
firebaseconfig.js
|
15876
package-lock.json
generated
Normal file
15876
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -6,6 +6,7 @@
|
|||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
"firebase": "^9.5.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "4.0.3",
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
const RESET_ACTION = {
|
||||
type: "RESET",
|
||||
};
|
||||
|
||||
export default RESET_ACTION;
|
3
src/action.js
Normal file
3
src/action.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const RESET_ACTION = {
|
||||
type: "RESET",
|
||||
};
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useReducer, useState } from "react";
|
||||
import RESET_ACTION from "./RESET_ACTION";
|
||||
import { RESET_ACTION } from "./action";
|
||||
import { dbWriteTask, newTaskId } from "./firebase";
|
||||
|
||||
export function AddTask(props) {
|
||||
const [showForm, setShowForm] = useState(false);
|
||||
|
@ -23,12 +24,20 @@ export function AddTask(props) {
|
|||
function AddTaskForm(props) {
|
||||
const { addTask, show, toggleForm } = props;
|
||||
|
||||
const INITIAL_STATE = { name: "", description: "", date: "" };
|
||||
const INITIAL_STATE = {
|
||||
done: false,
|
||||
name: "",
|
||||
description: "",
|
||||
date: "",
|
||||
taskId: -1,
|
||||
};
|
||||
const reducer = (state, event) => {
|
||||
if (event.type === RESET_ACTION.type) {
|
||||
return INITIAL_STATE;
|
||||
} else {
|
||||
return { ...state, [event.target.name]: event.target.value };
|
||||
switch (event.type) {
|
||||
case RESET_ACTION.type:
|
||||
return INITIAL_STATE;
|
||||
default:
|
||||
// Form
|
||||
return { ...state, [event.target.name]: event.target.value };
|
||||
}
|
||||
};
|
||||
const [task, setTask] = useReducer(reducer, INITIAL_STATE);
|
||||
|
@ -38,8 +47,9 @@ function AddTaskForm(props) {
|
|||
}
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
console.log(task);
|
||||
task.taskId = newTaskId();
|
||||
addTask(task);
|
||||
dbWriteTask(task);
|
||||
setTask(RESET_ACTION);
|
||||
event.preventDefault();
|
||||
};
|
||||
|
|
36
src/firebase.js
Normal file
36
src/firebase.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Import the functions you need from the SDKs you need
|
||||
import { initializeApp } from "firebase/app";
|
||||
import { firebaseConfig } from "./firebaseconfig";
|
||||
import { getDatabase, ref, onValue, set, get, remove } from "firebase/database";
|
||||
|
||||
// TODO: Add SDKs for Firebase products that you want to use
|
||||
// https://firebase.google.com/docs/web/setup#available-libraries
|
||||
|
||||
// Initialize Firebase
|
||||
const app = initializeApp(firebaseConfig);
|
||||
// Get a reference to the database service
|
||||
const database = getDatabase(app);
|
||||
|
||||
const taskIdRef = ref(database, "taskId");
|
||||
var currentTaskId;
|
||||
onValue(taskIdRef, (snapshot) => {
|
||||
currentTaskId = snapshot.val();
|
||||
});
|
||||
|
||||
export function newTaskId() {
|
||||
const value = currentTaskId;
|
||||
set(taskIdRef, value + 1);
|
||||
return value;
|
||||
}
|
||||
|
||||
export function dbWriteTask(task) {
|
||||
set(ref(database, "tasks/" + task.taskId), task);
|
||||
}
|
||||
|
||||
export function dbDeleteTask(task) {
|
||||
remove(ref(database, "tasks/" + task.taskId));
|
||||
}
|
||||
|
||||
export async function dbGetTasks() {
|
||||
return get(ref(database, "tasks"));
|
||||
}
|
66
src/index.js
66
src/index.js
|
@ -1,31 +1,63 @@
|
|||
import React, { useState } from "react";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import ReactDom from "react-dom";
|
||||
import AddTask from "./addtask";
|
||||
import { dbDeleteTask, dbGetTasks } from "./firebase";
|
||||
import { Task, TaskList } from "./tasklist";
|
||||
|
||||
// Example task
|
||||
// { name: "example task", description: "Amogus sus" };
|
||||
|
||||
function Root() {
|
||||
const [taskNumber, setTaskNumber] = useState(0);
|
||||
const [tasks, setTasks] = useState([]);
|
||||
|
||||
const addNewTask = (props) => {
|
||||
setTasks((tasks) => [
|
||||
...tasks,
|
||||
<Task
|
||||
{...props}
|
||||
key={taskNumber}
|
||||
taskId={taskNumber}
|
||||
deleteTask={deleteTask}
|
||||
/>,
|
||||
]);
|
||||
setTaskNumber((taskNumber) => taskNumber + 1);
|
||||
const addTask = useCallback(
|
||||
(props) => {
|
||||
setTasks((tasks) => [
|
||||
...tasks,
|
||||
<Task
|
||||
task={props}
|
||||
key={props.taskId}
|
||||
deleteTask={deleteTask}
|
||||
/>,
|
||||
]);
|
||||
},
|
||||
[setTasks]
|
||||
);
|
||||
|
||||
const deleteTask = (task) => {
|
||||
dbDeleteTask(task);
|
||||
setTasks((tasks) =>
|
||||
tasks.filter(
|
||||
(otherTask) => otherTask.props.task.taskId !== task.taskId
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const deleteTask = (id) => {
|
||||
setTasks((tasks) => tasks.filter((task) => task.props.taskId !== id));
|
||||
};
|
||||
// Run on startup - load tasks from firebase db.
|
||||
useEffect(() => {
|
||||
async function initializeTasks() {
|
||||
let snapshot;
|
||||
try {
|
||||
snapshot = await dbGetTasks();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
let tasks = {};
|
||||
if (snapshot.exists()) {
|
||||
tasks = snapshot.val();
|
||||
}
|
||||
|
||||
if (tasks) {
|
||||
// eslint-disable-next-line
|
||||
for (const [_, value] of Object.entries(tasks)) {
|
||||
addTask(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initializeTasks();
|
||||
}, [addTask]);
|
||||
|
||||
return (
|
||||
<div className="container mt-3">
|
||||
|
@ -33,7 +65,7 @@ function Root() {
|
|||
<h1>Task list</h1>
|
||||
</div>
|
||||
<section>
|
||||
<AddTask addTask={addNewTask} />
|
||||
<AddTask addTask={addTask} />
|
||||
<h1>Tasks</h1>
|
||||
<TaskList tasks={tasks} />
|
||||
</section>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { useState } from "react";
|
||||
import { useReducer } from "react";
|
||||
import { dbWriteTask } from "./firebase";
|
||||
|
||||
export function TaskList(props) {
|
||||
const { tasks } = props;
|
||||
|
@ -23,8 +24,16 @@ export function TaskList(props) {
|
|||
}
|
||||
|
||||
export function Task(props) {
|
||||
const { taskId, name, description, date, deleteTask } = props;
|
||||
const [done, setDone] = useState(false);
|
||||
const { task: task_, deleteTask } = props;
|
||||
|
||||
const reducer = (state, event) => ({ ...state, [event.name]: event.value });
|
||||
const [task, setTask] = useReducer(reducer, task_);
|
||||
|
||||
const setDone = (done) => {
|
||||
setTask({ name: "done", value: done });
|
||||
task.done = done; // Need to update variable as well
|
||||
dbWriteTask(task);
|
||||
};
|
||||
|
||||
const deleteBtn = (done) => {
|
||||
if (done) {
|
||||
|
@ -34,7 +43,7 @@ export function Task(props) {
|
|||
type="button"
|
||||
className="btn btn-danger"
|
||||
value="Delete"
|
||||
onClick={() => deleteTask(taskId)}
|
||||
onClick={() => deleteTask(task)}
|
||||
/>
|
||||
</td>
|
||||
);
|
||||
|
@ -47,22 +56,22 @@ export function Task(props) {
|
|||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
value={done}
|
||||
onClick={() => setDone(!done)}
|
||||
checked={task.done}
|
||||
onChange={() => setDone(!task.done)}
|
||||
></input>
|
||||
</td>
|
||||
<td>
|
||||
<p>{name}</p>
|
||||
<p>{task.name}</p>
|
||||
</td>
|
||||
<td style={{ whiteSpace: "pre" }}>
|
||||
<p>{description}</p>
|
||||
<p>{task.description}</p>
|
||||
</td>
|
||||
<td>
|
||||
{date === ""
|
||||
{task.date === ""
|
||||
? ""
|
||||
: new Date(Date.parse(date)).toLocaleDateString()}
|
||||
: new Date(Date.parse(task.date)).toLocaleDateString()}
|
||||
</td>
|
||||
{deleteBtn(done)}
|
||||
{deleteBtn(task.done)}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user