Skip to content

Commit

Permalink
Merge pull request #31 from CMU-17-356/claire-branch
Browse files Browse the repository at this point in the history
[Final Sprint] Added frontend fly.io deployment + Connected frontend with backend user api
  • Loading branch information
yinghork authored May 4, 2023
2 parents 9bff10b + cc4ec0e commit 4df28fc
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 35 deletions.
25 changes: 25 additions & 0 deletions frontend/.dockerignore
Original file line number Diff line number Diff line change
@@ -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
16 changes: 16 additions & 0 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -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" ]
37 changes: 37 additions & 0 deletions frontend/fly.toml
Original file line number Diff line number Diff line change
@@ -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"
16 changes: 10 additions & 6 deletions frontend/src/backend-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,26 @@ 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 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) {
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
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/TodoItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const Todo: React.FC<Props> = ({ 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)
Expand Down
24 changes: 18 additions & 6 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -96,7 +109,7 @@ body {
}

.Form button {
background: #8f4edb;
background: #2c4b82;
color: #fff;
padding: 0.5rem 1rem;
border-radius: 20px;
Expand All @@ -105,8 +118,7 @@ body {
}

.line-through {
text-decoration: line-through;
color: #585858 !important;
color: #fff !important;
}

.hide-button {
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/views/HistoryView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<ITodo[]>([]);

updateUser(username)

const fetchTodos = () => {
getAllTasks(username)
.then((curr) => {
Expand Down
35 changes: 20 additions & 15 deletions frontend/src/views/Login.tsx
Original file line number Diff line number Diff line change
@@ -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 app from '../api/Firebase';
import {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();

setNavState(false)

Expand Down Expand Up @@ -69,7 +65,7 @@ const Login = ({setNavState, setUsername}) => {
<div className="card">
<div className="card-body">
<h1 style={{ color: 'blue' }}> DONE</h1>
<form onSubmit={e => {
<form onSubmit={async e => {
e.preventDefault()
// signin(username, password)
// .then((res: any) => {
Expand All @@ -79,21 +75,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)
}

}}
>
<div className="form-group mt-3">
<input className="form-control" value={username} onChange={e => setLocalUsername(e.target.value)} type="text" id="username" name="username" placeholder="Username" required />
<input className="form-control" value={username} onChange={e => {setLocalUsername(e.target.value); setError(false);}} type="text" id="username" name="username" placeholder="Username" required />
</div>
<div className="form-group mt-3">
<input className="form-control" value={password} onChange={e => setPassword(e.target.value)} type="password" id="password" name="password" placeholder="Password" required />
<input className="form-control" value={password} onChange={e => {setPassword(e.target.value); setError(false);}} type="password" id="password" name="password" placeholder="Password" required />
</div>
<div className="form-group form-row mt-3">
<button type="submit" className="btn btn-primary">Log In</button>
Expand All @@ -103,8 +107,9 @@ const Login = ({setNavState, setUsername}) => {
<br></br>
<Link to="/signup">Sign Up Here</Link>
</p>
{ error ? <ErrorMessage message={error} /> : null }
</div>
{ error ? <h5 style={{ color: 'red' }}>Failed to login!</h5> : null }

</form>
</div>
</div>
Expand Down
31 changes: 26 additions & 5 deletions frontend/src/views/SignUp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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} 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('');
Expand All @@ -24,7 +26,7 @@ const Signup = () => {
<div className="card-body">
<h1 style={{ color: 'blue' }}>Create an account</h1>
<p className="text-secondary">Get started with DONE!</p>
<form onSubmit={e => {
<form onSubmit={async e => {
e.preventDefault()
// signup(username, password, fname, lname)
// .then((res) => {
Expand All @@ -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)
}

}}
>
<div className="form-group">
Expand All @@ -60,6 +80,7 @@ const Signup = () => {
{ error ? <ErrorMessage message={error} /> : null }
<button className="btn btn-primary float-right" type="submit">Submit</button>
</div>
{ failed ? <h5 style={{ color: 'red' }}>Failed to sign up!</h5> : null }
</form>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/TodoList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ const convertFileToBase64 = (file: File) => {

return (
<main className='TodoList'>
<div className="Card">
<div className="Title">
<Button onClick={movePrevious}>Previous</Button>
<h1>TODO: { weekday[date.getDay()]}, {format(date, "MMMM do")}</h1>
<Button onClick={moveNext}>Next</Button>
Expand Down

0 comments on commit 4df28fc

Please sign in to comment.