Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
REACT_APP_FIREBASE_API_KEY="PASTE VALUE HERE"
REACT_APP_FIREBASE_AUTHDOMAIN="PASTE VALUE HERE"
REACT_APP_FIREBASE_PROJECT_ID="PASTE VALUE HERE"
REACT_APP_FIREBASE_STORAGEBUCKET="PASTE VALUE HERE"
REACT_APP_FIREBASE_MESSAGINGSENDERID="PASTE VALUE HERE"
REACT_APP_FIREBASE_APPID="PASTE VALUE HERE"
REACT_APP_FIREBASE_MEASUREMENTID="PASTE VALUE HERE"
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
## Exercise 1
## Exercise 3

This exercise is to edit and remove items from a todo list
This exercise is to add authentication using localstorage and [react-router](https://reactrouter.com/web/guides/quick-start)

### To do

- [ ] Edit to-do
- [ ] Remove to-do
- [ ] Add login page route (`/login`) with login form that accepts user name and password. Use [react-hook-form](https://react-hook-form.com/)
- [ ] Redirect the user to the `/login` route if they are not logged-in
- [ ] Restrict the user from viewing the tasks if they are not logged-in (using [react-router](https://reactrouter.com/web/guides/quick-start))
- [ ] Update userContext with logged in user information
- [ ] Store tasks with author information
- [ ] Display tasks with author information (any author can view all tasks)
- [ ] Display a 404 page if the user navigates to a route that does not exist

### Setup Instructions

- Fork the repo
- Clone the repo
- Setup Firebase project and copy config credentials
- Rename `.env.example` to `.env.local`
- Copy Firebase credentials to `.env.local`
- Install dependencies using `yarn`
- Run locally using `yarn start`

### Submission Instructions

- Make changes on a separate branch
- Fork the repo
- Commit changes to your repo using `git add .` and `git commit -m [commit message]`
- Submit PR to the branch
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "^8.2.10",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.3",
Expand Down
104 changes: 70 additions & 34 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
import { useState, useEffect } from "react";
import React from "react";
import firebase from "firebase/app";
import "firebase/firestore";

import { AuthContext, AuthProvider } from "./context/auth";

import "./App.css";

const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTHDOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGEBUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGINGSENDERID,
appId: process.env.REACT_APP_FIREBASE_APPID,
measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENTID,
};
//This check is to avoid firebase re-initializing multiple times
if (typeof window !== "undefined" && !firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
//Load firebase firestore
const db = firebase.firestore();

const App = () => {
const [title, setTitle] = useState("");
const [tasks, setTasks] = useState([]);
const [title, setTitle] = React.useState("");
const [tasks, setTasks] = React.useState([]);

const user = React.useContext(AuthContext);
console.log(user);

useEffect(() => {
React.useEffect(() => {
//Check if localstorage is
const storedTasks = JSON.parse(window.localStorage.getItem("tasks"));
console.log(storedTasks);
Expand All @@ -14,8 +38,18 @@ const App = () => {
}
}, []);

React.useEffect(() => {
db.collection("todos").onSnapshot((querySnapshot) => {
var todos = [];
querySnapshot.forEach((doc) => {
todos.push(doc.data().title);
});
console.log("Current todos: ", todos);
});
}, []);

//UseEffect re-renders application whenever dependency objects are changed
useEffect(() => {
React.useEffect(() => {
//Save to localstorage whenever tasks is updated
if (tasks.length > 0) {
console.log("save tasks to localstorage");
Expand Down Expand Up @@ -45,36 +79,38 @@ const App = () => {
};

return (
<div className="App">
<div>
<input
type="text"
name="task_title"
value={title}
placeholder="Add task here"
onChange={handleFieldChange}
/>
<button type="button" onClick={handleSubmit}>
Add task
</button>
</div>
<AuthProvider>
<div className="App">
<div>
<input
type="text"
name="task_title"
value={title}
placeholder="Add task here"
onChange={handleFieldChange}
/>
<button type="button" onClick={handleSubmit}>
Add task
</button>
</div>

<ul>
{tasks?.length > 0
? tasks.map((item, index) => (
<li key={index}>
{item}
<button type="button" onClick={handleEdit}>
Edit
</button>
<button type="button" onClick={handleRemove}>
Delete
</button>
</li>
))
: "Nothing in list"}
</ul>
</div>
<ul>
{tasks?.length > 0
? tasks.map((item, index) => (
<li key={index}>
{item}
<button type="button" onClick={handleEdit}>
Edit
</button>
<button type="button" onClick={handleRemove}>
Delete
</button>
</li>
))
: "Nothing in list"}
</ul>
</div>
</AuthProvider>
);
};

Expand Down
10 changes: 10 additions & 0 deletions src/context/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from "react";
const user = {
name: "Prince Charles",
age: "99",
};
export const AuthContext = React.createContext(user);

export const AuthProvider = ({ children }) => {
return <AuthContext.Provider value={user}>{children}</AuthContext.Provider>;
};
12 changes: 6 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
Expand Down
Loading