From 0cb4aa0c81414fe43f63f1b8eb97264598dda5a0 Mon Sep 17 00:00:00 2001 From: Claire Ko Date: Wed, 3 May 2023 18:30:57 -0400 Subject: [PATCH 1/3] [Final Sprint] Added user backend to the frontend + Added fly.io deployment for frontend --- frontend/.dockerignore | 25 +++++++++++++++++++ frontend/Dockerfile | 16 ++++++++++++ frontend/fly.toml | 37 ++++++++++++++++++++++++++++ frontend/src/backend-adapter.ts | 7 +++--- frontend/src/components/TodoItem.tsx | 2 +- frontend/src/views/Login.tsx | 30 +++++++++++++--------- frontend/src/views/SignUp.tsx | 31 +++++++++++++++++++---- 7 files changed, 128 insertions(+), 20 deletions(-) create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile create mode 100644 frontend/fly.toml diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..9bc0f93 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,25 @@ +# flyctl launch added from .gitignore +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +node_modules +.pnp +**/.pnp.js + +# testing +coverage + +# production +build + +# misc +**/.DS_Store +**/.env.local +**/.env.development.local +**/.env.test.local +**/.env.production.local + +**/npm-debug.log* +**/yarn-debug.log* +**/yarn-error.log* +fly.toml diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..fc4e0b5 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,16 @@ +FROM node:alpine3.11 +MAINTAINER DONEApp + +# Change working directory +WORKDIR /usr/src/app + +# Install App Dependencies +COPY package*.json ./ +RUN npm install + +# Copy App Source +COPY . . +#TODO Run any build scripts here + +EXPOSE 3000 +CMD [ "npm", "run", "start" ] diff --git a/frontend/fly.toml b/frontend/fly.toml new file mode 100644 index 0000000..4e637ee --- /dev/null +++ b/frontend/fly.toml @@ -0,0 +1,37 @@ +# fly.toml file generated for done-app on 2023-05-02T23:21:35-04:00 + +app = "done-app" +kill_signal = "SIGINT" +kill_timeout = 5 +processes = [] + +[env] + +[experimental] + auto_rollback = true + +[[services]] + http_checks = [] + internal_port = 8080 + processes = ["app"] + protocol = "tcp" + script_checks = [] + [services.concurrency] + hard_limit = 25 + soft_limit = 20 + type = "connections" + + [[services.ports]] + force_https = true + handlers = ["http"] + port = 80 + + [[services.ports]] + handlers = ["tls", "http"] + port = 443 + + [[services.tcp_checks]] + grace_period = "1s" + interval = "15s" + restart_limit = 0 + timeout = "2s" diff --git a/frontend/src/backend-adapter.ts b/frontend/src/backend-adapter.ts index 65ead96..06785be 100644 --- a/frontend/src/backend-adapter.ts +++ b/frontend/src/backend-adapter.ts @@ -78,17 +78,18 @@ export async function addUser(user) { const response = await instance.get("users/" + user.username); if (response.data.length == 0) { await instance.post("users/", user) + return true } else { - throw new Error("Username already exists.") + return false } } export async function authenticateUser(username: string, password: string) { const response = await instance.get("users/" + username) if (response.data.length == 0) { - throw new Error("Username doesn't exist.") + return false } - const user = response.data + const user = response.data[0] if (user.password === password) { return true } diff --git a/frontend/src/components/TodoItem.tsx b/frontend/src/components/TodoItem.tsx index 1e062d3..0890b9c 100644 --- a/frontend/src/components/TodoItem.tsx +++ b/frontend/src/components/TodoItem.tsx @@ -20,7 +20,7 @@ const Todo: React.FC = ({ todo, updateTodo, deleteTodo, saveTodo, date}) let completed = todo.completed.filter((x) => sameDay(x.date,date)) let status = (completed.length > 0) - + const checkTodo: string = status ? `line-through` : "" const checkDone: string = status ? `Card-done` : 'Card' const [showEdit, setShowEdit] = useState(false) diff --git a/frontend/src/views/Login.tsx b/frontend/src/views/Login.tsx index 5988c9c..db4235c 100644 --- a/frontend/src/views/Login.tsx +++ b/frontend/src/views/Login.tsx @@ -2,13 +2,13 @@ import React, { useState, useEffect } from 'react' import { signin, signup, userFind, checkLogin } from '../api/Login'; import { useNavigate, useLocation, Link } from 'react-router-dom' import ErrorMessage from '../components/core/Error'; -// import app from '../api/Firebase'; +import {addUser, authenticateUser} from '../backend-adapter' const Login = ({setNavState, setUsername}) => { const [username, setLocalUsername] = useState('') const [password, setPassword] = useState('') // Hold error text. - const [error, setError] = useState(''); + const [error, setError] = useState(false); const navigate = useNavigate(); const location = useLocation(); @@ -69,7 +69,7 @@ const Login = ({setNavState, setUsername}) => {

DONE

-
{ + { e.preventDefault() // signin(username, password) // .then((res: any) => { @@ -79,21 +79,29 @@ const Login = ({setNavState, setUsername}) => { // }); // get session - let result = true + console.log(username, password) + let result = await authenticateUser(username,password) + setNavState(result); - setUsername(username); - navigate('/todo') - setLocalUsername('') - setPassword('') + if(result){ + console.log(username) + setUsername(username); + navigate('/todo') + setLocalUsername('') + setPassword('') + } else { + console.log("failed to login") + setError(true) + } }} >
- setLocalUsername(e.target.value)} type="text" id="username" name="username" placeholder="Username" required /> + {setLocalUsername(e.target.value); setError(false);}} type="text" id="username" name="username" placeholder="Username" required />
- setPassword(e.target.value)} type="password" id="password" name="password" placeholder="Password" required /> + {setPassword(e.target.value); setError(false);}} type="password" id="password" name="password" placeholder="Password" required />
@@ -103,8 +111,8 @@ const Login = ({setNavState, setUsername}) => {

Sign Up Here

- { error ? : null }
+ { error ? "Failed to login!" : null }
diff --git a/frontend/src/views/SignUp.tsx b/frontend/src/views/SignUp.tsx index febde4f..ce6c901 100644 --- a/frontend/src/views/SignUp.tsx +++ b/frontend/src/views/SignUp.tsx @@ -2,12 +2,14 @@ import React, {useState, useEffect} from 'react' import { signup } from '../api/Login'; import ErrorMessage from '../components/core/Error'; import { useNavigate, Link } from 'react-router-dom' +import {addUser, authenticateUser} from '../backend-adapter' const Signup = () => { const [username, setUsername] = useState('') const [password, setPassword] = useState('') const [fname, setFName] = useState('') const [lname, setLName] = useState('') + const [failed, setFailed] = useState(false) // Hold error text. const [error, setError] = useState(''); @@ -24,7 +26,7 @@ const Signup = () => {

Create an account

Get started with DONE!

-
{ + { e.preventDefault() // signup(username, password, fname, lname) // .then((res) => { @@ -33,10 +35,28 @@ const Signup = () => { // setError(err.message); // }); console.log(username, password, fname, lname); - setUsername('') - setPassword('') - setFName('') - setLName('') + const user = { + first_name: fname, + last_name: lname, + username: username, + password: password + } + + let result = await addUser(user) + + if(result){ + console.log("success") + navigate('/') + setUsername('') + setPassword('') + setFName('') + setLName('') + setFailed(false) + } else { + console.log("failed") + setFailed(true) + } + }} >
@@ -60,6 +80,7 @@ const Signup = () => { { error ? : null }
+ { failed ? "Failed to sign up!" : null }
From c1266c51538ae13a7c080c23077e103637f29a10 Mon Sep 17 00:00:00 2001 From: Claire Ko Date: Wed, 3 May 2023 18:33:28 -0400 Subject: [PATCH 2/3] [Final Sprint] Updated error color to red --- frontend/src/views/Login.tsx | 3 ++- frontend/src/views/SignUp.tsx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/views/Login.tsx b/frontend/src/views/Login.tsx index db4235c..88c2ba4 100644 --- a/frontend/src/views/Login.tsx +++ b/frontend/src/views/Login.tsx @@ -112,7 +112,8 @@ const Login = ({setNavState, setUsername}) => { Sign Up Here

- { error ? "Failed to login!" : null } + { error ?

Failed to login!

: null } + diff --git a/frontend/src/views/SignUp.tsx b/frontend/src/views/SignUp.tsx index ce6c901..f958943 100644 --- a/frontend/src/views/SignUp.tsx +++ b/frontend/src/views/SignUp.tsx @@ -80,7 +80,7 @@ const Signup = () => { { error ? : null } - { failed ? "Failed to sign up!" : null } + { failed ?

Failed to sign up!

: null } From cc4ec0e5f562298079bf2dbd7c390e4c3b07aaae Mon Sep 17 00:00:00 2001 From: Claire Ko Date: Wed, 3 May 2023 20:03:12 -0400 Subject: [PATCH 3/3] [Final Sprint] Incorporated history clicks in frontend + updated UI --- frontend/src/backend-adapter.ts | 9 ++++++--- frontend/src/index.css | 24 ++++++++++++++++++------ frontend/src/views/HistoryView.tsx | 4 +++- frontend/src/views/Login.tsx | 8 ++------ frontend/src/views/SignUp.tsx | 4 ++-- frontend/src/views/TodoList.tsx | 2 +- 6 files changed, 32 insertions(+), 19 deletions(-) diff --git a/frontend/src/backend-adapter.ts b/frontend/src/backend-adapter.ts index 66efc8f..a45a4a5 100644 --- a/frontend/src/backend-adapter.ts +++ b/frontend/src/backend-adapter.ts @@ -84,9 +84,12 @@ export async function addUser(user) { } } -export async function updateUser(user) { - const id = user.username - await instance.put("tasks/" + id, user).then((response) => response.data) +export async function updateUser(username) { + const response = await instance.get("users/" + username) + const user = response.data[0] + user.history_clicks += 1 + console.log("updated user:", user) + await instance.put("users/" + username, user).then((response) => response.data) } export async function authenticateUser(username: string, password: string) { diff --git a/frontend/src/index.css b/frontend/src/index.css index 86dfea2..3c4ce9c 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -27,26 +27,39 @@ body { display: flex; justify-content: space-between; align-items: center; - background: #8f4edb; + background: #2c4b82; padding: 0.5rem 1rem; border-bottom: 1px solid #333333; + border-radius: 20px; } +.Title { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5rem 1rem; + border-bottom: 1px solid #333333; + border-top: 1px solid #333333; +} + + .Card-done { display: flex; justify-content: space-between; align-items: center; - background: #61ad6c; + background: #2c8278; padding: 0.5rem 1rem; border-bottom: 1px solid #333333; + border-radius: 20px; } .Card--text { width: 80%; + color: #fff; } .Card--text h1 { - color: #212426; + color: #fff; } .Card--button { @@ -96,7 +109,7 @@ body { } .Form button { - background: #8f4edb; + background: #2c4b82; color: #fff; padding: 0.5rem 1rem; border-radius: 20px; @@ -105,8 +118,7 @@ body { } .line-through { - text-decoration: line-through; - color: #585858 !important; + color: #fff !important; } .hide-button { diff --git a/frontend/src/views/HistoryView.tsx b/frontend/src/views/HistoryView.tsx index 32cb566..9dab220 100644 --- a/frontend/src/views/HistoryView.tsx +++ b/frontend/src/views/HistoryView.tsx @@ -5,13 +5,15 @@ import Dropdown from 'react-bootstrap/Dropdown'; import { getAllTasks, getTask, updateTask2, deleteTask, addTask, ITask } from '../backend-adapter' import Button from 'react-bootstrap/Button'; import { CalendarView } from '../components/CalendarView'; - +import {updateUser} from '../backend-adapter' export default function History({username}) { const [selectedDate, setSelectedDate] = useState(new Date()); const [allTasks, setAllTasks] = useState([]); + updateUser(username) + const fetchTodos = () => { getAllTasks(username) .then((curr) => { diff --git a/frontend/src/views/Login.tsx b/frontend/src/views/Login.tsx index 88c2ba4..6a927e0 100644 --- a/frontend/src/views/Login.tsx +++ b/frontend/src/views/Login.tsx @@ -1,17 +1,13 @@ import React, { useState, useEffect } from 'react' -import { signin, signup, userFind, checkLogin } from '../api/Login'; import { useNavigate, useLocation, Link } from 'react-router-dom' -import ErrorMessage from '../components/core/Error'; -import {addUser, authenticateUser} from '../backend-adapter' +import {authenticateUser} from '../backend-adapter' const Login = ({setNavState, setUsername}) => { const [username, setLocalUsername] = useState('') const [password, setPassword] = useState('') - // Hold error text. const [error, setError] = useState(false); const navigate = useNavigate(); - const location = useLocation(); setNavState(false) @@ -112,7 +108,7 @@ const Login = ({setNavState, setUsername}) => { Sign Up Here

- { error ?

Failed to login!

: null } + { error ?
Failed to login!
: null } diff --git a/frontend/src/views/SignUp.tsx b/frontend/src/views/SignUp.tsx index f958943..f35af9c 100644 --- a/frontend/src/views/SignUp.tsx +++ b/frontend/src/views/SignUp.tsx @@ -2,7 +2,7 @@ import React, {useState, useEffect} from 'react' import { signup } from '../api/Login'; import ErrorMessage from '../components/core/Error'; import { useNavigate, Link } from 'react-router-dom' -import {addUser, authenticateUser} from '../backend-adapter' +import {addUser} from '../backend-adapter' const Signup = () => { const [username, setUsername] = useState('') @@ -80,7 +80,7 @@ const Signup = () => { { error ? : null } - { failed ?

Failed to sign up!

: null } + { failed ?
Failed to sign up!
: null } diff --git a/frontend/src/views/TodoList.tsx b/frontend/src/views/TodoList.tsx index f32edc1..b86b625 100644 --- a/frontend/src/views/TodoList.tsx +++ b/frontend/src/views/TodoList.tsx @@ -217,7 +217,7 @@ const convertFileToBase64 = (file: File) => { return (
-
+

TODO: { weekday[date.getDay()]}, {format(date, "MMMM do")}