From cab18ddfe968d012c47437212091155e74d8a542 Mon Sep 17 00:00:00 2001 From: Tamer <53710372+DrTamerAldwairi@users.noreply.github.com> Date: Tue, 27 Oct 2020 09:59:04 -0400 Subject: [PATCH 001/108] Setting up GitHub Classroom Feedback From ba51ac38073e0d3036f2aafdd4cb74ce3668b942 Mon Sep 17 00:00:00 2001 From: Tamer <53710372+DrTamerAldwairi@users.noreply.github.com> Date: Tue, 27 Oct 2020 09:59:05 -0400 Subject: [PATCH 002/108] Update GitHub Classroom Feedback From ef5219bb5bb9ec151e9da01a599a8385bdc2b25e Mon Sep 17 00:00:00 2001 From: Tamer <53710372+DrTamerAldwairi@users.noreply.github.com> Date: Tue, 27 Oct 2020 09:59:06 -0400 Subject: [PATCH 003/108] Setting up GitHub Classroom Feedback From 94ee3f2c0e9d99602c7268794669dfac5ee4dba0 Mon Sep 17 00:00:00 2001 From: SebTota Date: Tue, 27 Oct 2020 11:26:02 -0400 Subject: [PATCH 004/108] added basic web app script --- main.py | 19 +++++++++++++++++++ requirements.txt | 1 + 2 files changed, 20 insertions(+) create mode 100644 main.py create mode 100644 requirements.txt diff --git a/main.py b/main.py new file mode 100644 index 0000000..cea48fb --- /dev/null +++ b/main.py @@ -0,0 +1,19 @@ +from flask import Flask +# from flask_cors import CORS + +app = Flask(__name__) +# CORS(app) + + +@app.route('/home', methods=['GET']) +def home(): + return "This is the home" + + +@app.route('/login', methods=['POST']) +def login(): + return "This is the login" + + +if __name__ == '__main__': + app.run() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8ab6294 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +flask \ No newline at end of file From edacfc8d529338915752387dcccf03f45fce9bc8 Mon Sep 17 00:00:00 2001 From: SebTota Date: Wed, 28 Oct 2020 14:10:49 -0400 Subject: [PATCH 005/108] split frontend and backend --- main.py => backend/main.py | 0 requirements.txt => backend/requirements.txt | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename main.py => backend/main.py (100%) rename requirements.txt => backend/requirements.txt (100%) diff --git a/main.py b/backend/main.py similarity index 100% rename from main.py rename to backend/main.py diff --git a/requirements.txt b/backend/requirements.txt similarity index 100% rename from requirements.txt rename to backend/requirements.txt From 7b30aa3e82925eace1dfe09a0e2b0c32069e212c Mon Sep 17 00:00:00 2001 From: Shravanth Surapaneni Date: Sun, 1 Nov 2020 18:35:47 -0500 Subject: [PATCH 006/108] python scripts for login done --- backend/main.py | 45 ++++++++++++++++++++++++++++++++++++++++----- backend/src/auth.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 backend/src/auth.py diff --git a/backend/main.py b/backend/main.py index cea48fb..92fe2f7 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1,18 +1,53 @@ -from flask import Flask -# from flask_cors import CORS +from flask import Flask, jsonify, request +from flask_cors import CORS +from src import auth + +# name = request.headers["name"] # localhost:5000/login headers= {'name': 'someones name} +# name = request.args["name"] # localhost:5000/login?name=sebastian app = Flask(__name__) -# CORS(app) +CORS(app) + + +@app.route('/', methods=['GET']) +def main_page(): + return "Camping Trip Planner Home" @app.route('/home', methods=['GET']) def home(): - return "This is the home" + return jsonify({'name': 'Sebastian Tota'}) @app.route('/login', methods=['POST']) def login(): - return "This is the login" + data = request.get_json(force=True) # Force body to be read as JSON + email = data.get('email') + password = data.get('password') + g_recaptcha_response = data.get('recap_response') + + # Verify recaptcha is authenticated before checking password (prevent bot spamming) + if not auth.verify_recaptcha(g_recaptcha_response): + # Failed re-captcha verification + return jsonify({'status': 401, 'error': 'failed-recaptcha'}) + + # Authenticate users account and password + if auth.verify_password(email, password): + # Password is correct, return temporary session ID + return jsonify({'status': 200, 'email': email, 'session_id': '123abc456def'}) + else: + # Incorrect password specified, return Unauthorized Code + return jsonify({'status': 401, 'error': 'incorrect-password'}) + + +@app.route('/signup', methods=['POST']) +def signup(): + return "" + + +@app.route('/forgotPassword', methods=['POST']) +def forgot_password(): + return "" if __name__ == '__main__': diff --git a/backend/src/auth.py b/backend/src/auth.py new file mode 100644 index 0000000..9b4be7c --- /dev/null +++ b/backend/src/auth.py @@ -0,0 +1,37 @@ +import requests +import os +import bcrypt +import hashlib +import base64 + +# Global variables +g_recaptcha_secret = os.getenv('recaptcha-secret') + + +def verify_recaptcha(g_recaptcha_response) -> bool: + recap_status = requests.post('https://www.google.com/recaptcha/api/siteverify', data={ + 'secret': g_recaptcha_secret, + 'response': g_recaptcha_response + }) + return recap_status.json()['success'] + + +def new_user(email, password): + # Encode password to allow longer length passwords (limitation of bcrypt = 72 character max length) + encoded_pass = base64.b64encode(hashlib.sha256(password.encode('utf-8')).digest()) + # Hash encoded password with salt + # pass_hash includes hash and salt + pass_hash = bcrypt.hashpw(encoded_pass, bcrypt.gensalt()) + + # TODO Add new user to the Users db table + + +def verify_password(email, password) -> bool: + # Encode password to allow longer length passwords (limitation of bcrypt = 72 character max length) + encoded_pass = base64.b64encode(hashlib.sha256(password.encode('utf-8')).digest()) + + # TODO Get hashed password from db based on email (check if email exists first) + # Get hashed password from db + hashed_pass = b'$2b$12$mrPTNVwF3VYvmmhTfO/mi.BxiMfoSY7bo717veVkq10VCAngzI1fW' + + return bcrypt.checkpw(encoded_pass, hashed_pass) From 6043a2cf2864e5be79bf2fa331dd65d78eb707dd Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Sun, 1 Nov 2020 18:38:26 -0500 Subject: [PATCH 007/108] Front end logic for basic login system. Recapctcha security protocol. --- frontend/index.html | 53 ++++++++++++++++++++++++ frontend/login.html | 88 +++++++++++++++++++++++++++++++++++++++ frontend/profile.html | 38 +++++++++++++++++ frontend/script.js | 96 +++++++++++++++++++++++++++++++++++++++++++ frontend/style.css | 24 +++++++++++ 5 files changed, 299 insertions(+) create mode 100644 frontend/index.html create mode 100644 frontend/login.html create mode 100644 frontend/profile.html create mode 100644 frontend/script.js create mode 100644 frontend/style.css diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..fc1492d --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,53 @@ + + + + + Camping Trip Planner + + + + + + + + + + + +
+ +
+ +
+
+

Some text about how our application works and is super great :)

+

This is a link to our repository.

+ + + +
+
+
+ + + + \ No newline at end of file diff --git a/frontend/login.html b/frontend/login.html new file mode 100644 index 0000000..e056372 --- /dev/null +++ b/frontend/login.html @@ -0,0 +1,88 @@ + + + + + Sign In + + + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+ + + +

Forgot Password

+
+
+ +
+ + +
+
+ + + +
+
+ + + + + + + \ No newline at end of file diff --git a/frontend/profile.html b/frontend/profile.html new file mode 100644 index 0000000..ba5d11b --- /dev/null +++ b/frontend/profile.html @@ -0,0 +1,38 @@ + + + + + Camping Trip Planner - Profile + + + + + + + + + +
+ +
+ + + \ No newline at end of file diff --git a/frontend/script.js b/frontend/script.js new file mode 100644 index 0000000..8d9a4d9 --- /dev/null +++ b/frontend/script.js @@ -0,0 +1,96 @@ +const serverAddress = "http://localhost:5000" + +const warning_incorrectPass = document.getElementById('label_incorrect-password'); +const warning_recaptchaError = document.getElementById('label_recaptcha-error'); + +if(1 === 1) { + document.getElementById('nav_profile').style.display = "inline"; +} + +async function apiCallGet(url){ + // Make api call and wait for response before returning + // Add CORS header to allow cross origin resource sharing + const response = await fetch(url, { + mode: 'cors', + headers: { + 'Access-Control-Allow-Origin': '*' + } + }); + return await response.json(); +} + +function buttonClickGet() { + apiCallGet("http://localhost:5000/home").then(ret => { + alert(ret['name']); + }); +} + +async function getIpAddress() { + const response = await fetch('https://api.ipify.org/?format=json', { + mode: 'no-cors', + headers: { + 'Access-Control-Allow-Origin': '*' + }, + }); + return await response.json(); +} + +//--- Sign In Process ---// +async function signInPost(data) { + // Make POST request submitting + // Add CORS header to allow cross origin resource sharing + const response = await fetch(serverAddress + '/login', { + method: 'POST', + headers: { + 'Access-Control-Allow-Origin': '*' + }, + body: JSON.stringify(data) + }); + // Wait for response from server, then parse the body of the response in json format + return await response.json(); +} + +function signIn() { + // Reset sign in warnings + warning_incorrectPass.style.display = 'none'; + warning_recaptchaError.style.display = 'none'; + + // Get recaptcha response + const g_recaptcha_response = document.getElementById('g-recaptcha-response').value; + + // Don't process request unless recaptcha is complete + if (g_recaptcha_response === '') { + warning_recaptchaError.style.display = 'inline'; + return; + } + + // Get client IP address for robust recaptcha verification + /*const ip_address = getIpAddress().then(ret => { + console.log(ret); + return ret; + })*/ + + signInPost({ + "email": document.getElementById('input_email').value, + "password": document.getElementById('input_password').value, + "recap_response": g_recaptcha_response + }).then(ret => { + if (ret['status'] === 401) { + // Unauthorized error + if (ret['error'] === 'incorrect-password') { + // Incorrect password + // Show incorrect password indicator + warning_incorrectPass.style.display = 'inline'; + } else if(ret['error'] === 'failed-recaptcha') { + // recaptcha verification failed + warning_recaptchaError.style.display = 'inline'; + } + grecaptcha.reset(); // Refresh captcha + } else { + // Logged in successful + window.location.href="/frontend/profile.html"; + } + }); +} + +//--- End of sign in process ---// \ No newline at end of file diff --git a/frontend/style.css b/frontend/style.css new file mode 100644 index 0000000..bf0f848 --- /dev/null +++ b/frontend/style.css @@ -0,0 +1,24 @@ +.logo { + margin-bottom: 50px; +} + +#form_signin { + width: 300px; + margin: auto; +} + +.btn_sign-in { + width: 100% !important; + margin-bottom: 10px; +} + +.warning-text { + color: #ff0000; +} + +.center { + text-align: center; +} +.hidden { + display: none; +} \ No newline at end of file From 714ff7b66d6d02ee1282e2c2c1931b42989417bc Mon Sep 17 00:00:00 2001 From: SebTota Date: Sun, 1 Nov 2020 19:41:24 -0500 Subject: [PATCH 008/108] Create CNAME --- CNAME | 1 + 1 file changed, 1 insertion(+) create mode 100644 CNAME diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..d4faa2d --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +camping.sebtota.com \ No newline at end of file From 194f364062ee29095450664b6a4872d745b00a71 Mon Sep 17 00:00:00 2001 From: SebTota Date: Sun, 1 Nov 2020 20:15:30 -0500 Subject: [PATCH 009/108] Delete CNAME --- CNAME | 1 - 1 file changed, 1 deletion(-) delete mode 100644 CNAME diff --git a/CNAME b/CNAME deleted file mode 100644 index d4faa2d..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -camping.sebtota.com \ No newline at end of file From 24932091c190958f4a8b4767aec6294f4eae0e0a Mon Sep 17 00:00:00 2001 From: matthewvday Date: Mon, 2 Nov 2020 14:18:18 -0500 Subject: [PATCH 010/108] Adding README --- README.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..79d8cc1 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# Camping Trip Planner +## by Ryan O'Connor, Sebastian Tota, Shravanth Surapaneni, Marcus Anestad and Matthew Day + +### Project Overview +_The goal of the project is to create an application for camping/outdoor trips. The project +functionality includes planning, responsibility sharing, and photo uploading. Users of the app +will be able to create a trip and invite friends. The focus of the planning section includes gear lists, +food menus, directions, and maps. Responsibility sharing includes signing up for bringing food/gear, keeping track of +how much each person spends, and a system for reimbursement after the trip. Finally, after the trip members can upload and +make comments on photos._ + +### Vision Statement +_For a group of adventure seekers who are planning an outdoors activity together the Camping +Trip Planner is a web app that allows groups to plan a trip together in a more intuitive and seamless +way unlike Google Sheets which takes longer to create._ + +### Personas + +#### Julia, a college student + +_Julia, age 21, is a senior CS major at Temple University in Philadelphia. +She grew up in Montgomery County, where she would enjoy hikes around the Wissahickon +with her family growing up. This extended to a true passion for outdoor activities and +does them to relax and escape the stresses of her daily life._ + +_With an increase in course difficulty on top of living in the age of COVID, +Julia relies heavily on weekly social distanced outings with her friends to +maintain her sanity. On a recent trip to the Poconos for some camping, her group +realized they forgot to bring anything substantial for dinner. Being out in the middle of +nowhere they had to drive 50 minutes to a supermarket to remedy the situation, cutting heavily +into there time with each other and nature. Being a person that is highly involved in the world of +new software technology, Julia wondered if there was an app that could help prevent an incident like +this in the future. Luckily, she stumbled across the Camping Trip Planner app. Since then, +every trip goes off without a hitch._ + +### Project Board + +_https://trello.com/b/uclUHtIM/camping-trip-planner_ \ No newline at end of file From 7ef7f2fea456365ab4706de63381ea4f8192ddcc Mon Sep 17 00:00:00 2001 From: Matthew Day <59927653+matthewvday@users.noreply.github.com> Date: Mon, 2 Nov 2020 14:27:44 -0500 Subject: [PATCH 011/108] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 79d8cc1..aeb08f5 100644 --- a/README.md +++ b/README.md @@ -28,11 +28,11 @@ Julia relies heavily on weekly social distanced outings with her friends to maintain her sanity. On a recent trip to the Poconos for some camping, her group realized they forgot to bring anything substantial for dinner. Being out in the middle of nowhere they had to drive 50 minutes to a supermarket to remedy the situation, cutting heavily -into there time with each other and nature. Being a person that is highly involved in the world of +into their time with each other and nature. Being a person that is highly involved in the world of new software technology, Julia wondered if there was an app that could help prevent an incident like this in the future. Luckily, she stumbled across the Camping Trip Planner app. Since then, every trip goes off without a hitch._ ### Project Board -_https://trello.com/b/uclUHtIM/camping-trip-planner_ \ No newline at end of file +_https://trello.com/b/uclUHtIM/camping-trip-planner_ From 596bb6d183a23387ab8582143395a154c2a23867 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor <59928691+ryan-SWE@users.noreply.github.com> Date: Mon, 2 Nov 2020 14:43:46 -0500 Subject: [PATCH 012/108] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index aeb08f5..51a4496 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,19 @@ new software technology, Julia wondered if there was an app that could help prev this in the future. Luckily, she stumbled across the Camping Trip Planner app. Since then, every trip goes off without a hitch._ +#### Juan, a father + +_Juan is a parent of two. His family always looks forward to going on a yearly summer +canoe trips with the Smith’s. Juan is a doctor and pretty inexperienced when it comes +to new technology. However he loves learning new things. He hears about Camping Trip +Planner and excitedly calls Mr. Smith. They are easily able to set up profiles and +create a trip._ + +_Now they are easily able to organize and plan the trip. They are also able to get +their children (Smith, John, Smitty, and Johnny) involved and begin to teach them +everything that goes into organizing such a trip. They have a great time and plan +on using Camping Trip Planner for planning their trip next year._ + ### Project Board _https://trello.com/b/uclUHtIM/camping-trip-planner_ From 98890f3fd5b1109fcea2aa104ee086de75a9a578 Mon Sep 17 00:00:00 2001 From: SebTota Date: Mon, 2 Nov 2020 15:01:25 -0500 Subject: [PATCH 013/108] Added persona - Sebastian T --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 51a4496..bdfda3c 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,12 @@ their children (Smith, John, Smitty, and Johnny) involved and begin to teach the everything that goes into organizing such a trip. They have a great time and plan on using Camping Trip Planner for planning their trip next year._ +#### Tracy, a middle school teacher + +_Tracy, a middle school English teacher, is getting ready to take her class on a camping trip. Every year, the 8th-grade class takes a 3-day trip to the local campground as a celebration for graduating from middle school. This is Tracys first year taking her class, and she is worried about helping her students plan for the trip._ + +_With the Camping Trip Planner, she can sign all her students up into a single trip list to make sure enough supplies are brought, without over packing the busses. Rather than speaking to each student individually in the hopes they remember to bring what they are asked to bring, she makes a list of all the necessities, and has the student assign themselves to certain items. This way, Tracy can keep track of what has been tracked, and what is still missing._ + ### Project Board _https://trello.com/b/uclUHtIM/camping-trip-planner_ From 93d66670b6f194d8028e1441aad5ed5d1266a689 Mon Sep 17 00:00:00 2001 From: shravanth1862 <52979079+shravanth1862@users.noreply.github.com> Date: Mon, 2 Nov 2020 22:15:11 -0500 Subject: [PATCH 014/108] Update README.md shravanth's persona added --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index bdfda3c..760d5cb 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,18 @@ _Tracy, a middle school English teacher, is getting ready to take her class on a _With the Camping Trip Planner, she can sign all her students up into a single trip list to make sure enough supplies are brought, without over packing the busses. Rather than speaking to each student individually in the hopes they remember to bring what they are asked to bring, she makes a list of all the necessities, and has the student assign themselves to certain items. This way, Tracy can keep track of what has been tracked, and what is still missing._ +#### Tyler, a boy scout troop leader +_Tyler is is the troop leader for his son's boy scout troop. He wants to take his troop camping this weeknd +to teach them outdoor skills. However, he can't expect a bunch of middle schoolers to remember to bring everything, he needed +to find an effecient way to organize everything in preperation for the trip. As we all know the boy scout motto is: "Always be prepared", +so clearly had to think of everything._ + +_So, to deal with this he asks the parents of the kids in his troop for ideas and one of them suggests, Camping Trip Planner. +Tyler, looked into it and found that Camping Trip Planner not only lets him create a list for his trip, but also allows him to +add people to share the list with so that they could also collaborate and use it as a checklist. Tyler had found his solution, +he was able to add all the parents of the kids in his troop, and this way he has a way to keep track of everything and no longer +has to rely on the kids to make sure they had everything they needed._ + ### Project Board _https://trello.com/b/uclUHtIM/camping-trip-planner_ From 730540299ce448ceb1e3478cc626b2f24cc7a7f7 Mon Sep 17 00:00:00 2001 From: shravanth1862 <52979079+shravanth1862@users.noreply.github.com> Date: Mon, 2 Nov 2020 22:15:55 -0500 Subject: [PATCH 015/108] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 760d5cb..968a5f2 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ _With the Camping Trip Planner, she can sign all her students up into a single t #### Tyler, a boy scout troop leader _Tyler is is the troop leader for his son's boy scout troop. He wants to take his troop camping this weeknd to teach them outdoor skills. However, he can't expect a bunch of middle schoolers to remember to bring everything, he needed -to find an effecient way to organize everything in preperation for the trip. As we all know the boy scout motto is: "Always be prepared", +to find an effecient way to organize everything in preperation for the trip. As we all know the boy scout motto is: "Be prepared", so clearly had to think of everything._ _So, to deal with this he asks the parents of the kids in his troop for ideas and one of them suggests, Camping Trip Planner. From fef6b617d63d74ec59538f9a997e665e2f26c2c2 Mon Sep 17 00:00:00 2001 From: shravanth1862 <52979079+shravanth1862@users.noreply.github.com> Date: Mon, 2 Nov 2020 22:23:27 -0500 Subject: [PATCH 016/108] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 968a5f2..a741520 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ _So, to deal with this he asks the parents of the kids in his troop for ideas an Tyler, looked into it and found that Camping Trip Planner not only lets him create a list for his trip, but also allows him to add people to share the list with so that they could also collaborate and use it as a checklist. Tyler had found his solution, he was able to add all the parents of the kids in his troop, and this way he has a way to keep track of everything and no longer -has to rely on the kids to make sure they had everything they needed._ +has to rely on the kids to make sure they have everything they will need._ ### Project Board From bdba51f3fb5cb6d9d8a4a01fd2fa4a26b818a19a Mon Sep 17 00:00:00 2001 From: SebTota Date: Tue, 3 Nov 2020 18:41:15 -0500 Subject: [PATCH 017/108] split repo and removed backend scripts --- index.html | 53 +++++++++++++++++++++++++++++ login.html | 88 +++++++++++++++++++++++++++++++++++++++++++++++ profile.html | 38 +++++++++++++++++++++ script.js | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 24 +++++++++++++ 5 files changed, 299 insertions(+) create mode 100644 index.html create mode 100644 login.html create mode 100644 profile.html create mode 100644 script.js create mode 100644 style.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..fc1492d --- /dev/null +++ b/index.html @@ -0,0 +1,53 @@ + + + + + Camping Trip Planner + + + + + + + + + + + +
+ +
+ +
+
+

Some text about how our application works and is super great :)

+

This is a link to our repository.

+ + + +
+
+
+ + + + \ No newline at end of file diff --git a/login.html b/login.html new file mode 100644 index 0000000..e056372 --- /dev/null +++ b/login.html @@ -0,0 +1,88 @@ + + + + + Sign In + + + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+ + + +

Forgot Password

+
+
+ +
+ + +
+
+ + + +
+
+ + + + + + + \ No newline at end of file diff --git a/profile.html b/profile.html new file mode 100644 index 0000000..ba5d11b --- /dev/null +++ b/profile.html @@ -0,0 +1,38 @@ + + + + + Camping Trip Planner - Profile + + + + + + + + + +
+ +
+ + + \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..8d9a4d9 --- /dev/null +++ b/script.js @@ -0,0 +1,96 @@ +const serverAddress = "http://localhost:5000" + +const warning_incorrectPass = document.getElementById('label_incorrect-password'); +const warning_recaptchaError = document.getElementById('label_recaptcha-error'); + +if(1 === 1) { + document.getElementById('nav_profile').style.display = "inline"; +} + +async function apiCallGet(url){ + // Make api call and wait for response before returning + // Add CORS header to allow cross origin resource sharing + const response = await fetch(url, { + mode: 'cors', + headers: { + 'Access-Control-Allow-Origin': '*' + } + }); + return await response.json(); +} + +function buttonClickGet() { + apiCallGet("http://localhost:5000/home").then(ret => { + alert(ret['name']); + }); +} + +async function getIpAddress() { + const response = await fetch('https://api.ipify.org/?format=json', { + mode: 'no-cors', + headers: { + 'Access-Control-Allow-Origin': '*' + }, + }); + return await response.json(); +} + +//--- Sign In Process ---// +async function signInPost(data) { + // Make POST request submitting + // Add CORS header to allow cross origin resource sharing + const response = await fetch(serverAddress + '/login', { + method: 'POST', + headers: { + 'Access-Control-Allow-Origin': '*' + }, + body: JSON.stringify(data) + }); + // Wait for response from server, then parse the body of the response in json format + return await response.json(); +} + +function signIn() { + // Reset sign in warnings + warning_incorrectPass.style.display = 'none'; + warning_recaptchaError.style.display = 'none'; + + // Get recaptcha response + const g_recaptcha_response = document.getElementById('g-recaptcha-response').value; + + // Don't process request unless recaptcha is complete + if (g_recaptcha_response === '') { + warning_recaptchaError.style.display = 'inline'; + return; + } + + // Get client IP address for robust recaptcha verification + /*const ip_address = getIpAddress().then(ret => { + console.log(ret); + return ret; + })*/ + + signInPost({ + "email": document.getElementById('input_email').value, + "password": document.getElementById('input_password').value, + "recap_response": g_recaptcha_response + }).then(ret => { + if (ret['status'] === 401) { + // Unauthorized error + if (ret['error'] === 'incorrect-password') { + // Incorrect password + // Show incorrect password indicator + warning_incorrectPass.style.display = 'inline'; + } else if(ret['error'] === 'failed-recaptcha') { + // recaptcha verification failed + warning_recaptchaError.style.display = 'inline'; + } + grecaptcha.reset(); // Refresh captcha + } else { + // Logged in successful + window.location.href="/frontend/profile.html"; + } + }); +} + +//--- End of sign in process ---// \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..bf0f848 --- /dev/null +++ b/style.css @@ -0,0 +1,24 @@ +.logo { + margin-bottom: 50px; +} + +#form_signin { + width: 300px; + margin: auto; +} + +.btn_sign-in { + width: 100% !important; + margin-bottom: 10px; +} + +.warning-text { + color: #ff0000; +} + +.center { + text-align: center; +} +.hidden { + display: none; +} \ No newline at end of file From 0a366d7240095a7d76b4f208115c7e955d61853b Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Tue, 3 Nov 2020 20:16:22 -0500 Subject: [PATCH 018/108] Removed redundant folders --- backend/main.py | 54 ---------------------- backend/requirements.txt | 1 - backend/src/auth.py | 37 ---------------- frontend/index.html | 53 ---------------------- frontend/login.html | 88 ------------------------------------ frontend/profile.html | 38 ---------------- frontend/script.js | 96 ---------------------------------------- frontend/style.css | 24 ---------- 8 files changed, 391 deletions(-) delete mode 100644 backend/main.py delete mode 100644 backend/requirements.txt delete mode 100644 backend/src/auth.py delete mode 100644 frontend/index.html delete mode 100644 frontend/login.html delete mode 100644 frontend/profile.html delete mode 100644 frontend/script.js delete mode 100644 frontend/style.css diff --git a/backend/main.py b/backend/main.py deleted file mode 100644 index 92fe2f7..0000000 --- a/backend/main.py +++ /dev/null @@ -1,54 +0,0 @@ -from flask import Flask, jsonify, request -from flask_cors import CORS -from src import auth - -# name = request.headers["name"] # localhost:5000/login headers= {'name': 'someones name} -# name = request.args["name"] # localhost:5000/login?name=sebastian - -app = Flask(__name__) -CORS(app) - - -@app.route('/', methods=['GET']) -def main_page(): - return "Camping Trip Planner Home" - - -@app.route('/home', methods=['GET']) -def home(): - return jsonify({'name': 'Sebastian Tota'}) - - -@app.route('/login', methods=['POST']) -def login(): - data = request.get_json(force=True) # Force body to be read as JSON - email = data.get('email') - password = data.get('password') - g_recaptcha_response = data.get('recap_response') - - # Verify recaptcha is authenticated before checking password (prevent bot spamming) - if not auth.verify_recaptcha(g_recaptcha_response): - # Failed re-captcha verification - return jsonify({'status': 401, 'error': 'failed-recaptcha'}) - - # Authenticate users account and password - if auth.verify_password(email, password): - # Password is correct, return temporary session ID - return jsonify({'status': 200, 'email': email, 'session_id': '123abc456def'}) - else: - # Incorrect password specified, return Unauthorized Code - return jsonify({'status': 401, 'error': 'incorrect-password'}) - - -@app.route('/signup', methods=['POST']) -def signup(): - return "" - - -@app.route('/forgotPassword', methods=['POST']) -def forgot_password(): - return "" - - -if __name__ == '__main__': - app.run() diff --git a/backend/requirements.txt b/backend/requirements.txt deleted file mode 100644 index 8ab6294..0000000 --- a/backend/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -flask \ No newline at end of file diff --git a/backend/src/auth.py b/backend/src/auth.py deleted file mode 100644 index 9b4be7c..0000000 --- a/backend/src/auth.py +++ /dev/null @@ -1,37 +0,0 @@ -import requests -import os -import bcrypt -import hashlib -import base64 - -# Global variables -g_recaptcha_secret = os.getenv('recaptcha-secret') - - -def verify_recaptcha(g_recaptcha_response) -> bool: - recap_status = requests.post('https://www.google.com/recaptcha/api/siteverify', data={ - 'secret': g_recaptcha_secret, - 'response': g_recaptcha_response - }) - return recap_status.json()['success'] - - -def new_user(email, password): - # Encode password to allow longer length passwords (limitation of bcrypt = 72 character max length) - encoded_pass = base64.b64encode(hashlib.sha256(password.encode('utf-8')).digest()) - # Hash encoded password with salt - # pass_hash includes hash and salt - pass_hash = bcrypt.hashpw(encoded_pass, bcrypt.gensalt()) - - # TODO Add new user to the Users db table - - -def verify_password(email, password) -> bool: - # Encode password to allow longer length passwords (limitation of bcrypt = 72 character max length) - encoded_pass = base64.b64encode(hashlib.sha256(password.encode('utf-8')).digest()) - - # TODO Get hashed password from db based on email (check if email exists first) - # Get hashed password from db - hashed_pass = b'$2b$12$mrPTNVwF3VYvmmhTfO/mi.BxiMfoSY7bo717veVkq10VCAngzI1fW' - - return bcrypt.checkpw(encoded_pass, hashed_pass) diff --git a/frontend/index.html b/frontend/index.html deleted file mode 100644 index fc1492d..0000000 --- a/frontend/index.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Camping Trip Planner - - - - - - - - - - - -
- -
- -
-
-

Some text about how our application works and is super great :)

-

This is a link to our repository.

- - - -
-
-
- - - - \ No newline at end of file diff --git a/frontend/login.html b/frontend/login.html deleted file mode 100644 index e056372..0000000 --- a/frontend/login.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - Sign In - - - - - - - - - - - - -
- -
- -
-
-
- - -
-
- - - -

Forgot Password

-
-
- -
- - -
-
- - - -
-
- - - - - - - \ No newline at end of file diff --git a/frontend/profile.html b/frontend/profile.html deleted file mode 100644 index ba5d11b..0000000 --- a/frontend/profile.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - Camping Trip Planner - Profile - - - - - - - - - -
- -
- - - \ No newline at end of file diff --git a/frontend/script.js b/frontend/script.js deleted file mode 100644 index 8d9a4d9..0000000 --- a/frontend/script.js +++ /dev/null @@ -1,96 +0,0 @@ -const serverAddress = "http://localhost:5000" - -const warning_incorrectPass = document.getElementById('label_incorrect-password'); -const warning_recaptchaError = document.getElementById('label_recaptcha-error'); - -if(1 === 1) { - document.getElementById('nav_profile').style.display = "inline"; -} - -async function apiCallGet(url){ - // Make api call and wait for response before returning - // Add CORS header to allow cross origin resource sharing - const response = await fetch(url, { - mode: 'cors', - headers: { - 'Access-Control-Allow-Origin': '*' - } - }); - return await response.json(); -} - -function buttonClickGet() { - apiCallGet("http://localhost:5000/home").then(ret => { - alert(ret['name']); - }); -} - -async function getIpAddress() { - const response = await fetch('https://api.ipify.org/?format=json', { - mode: 'no-cors', - headers: { - 'Access-Control-Allow-Origin': '*' - }, - }); - return await response.json(); -} - -//--- Sign In Process ---// -async function signInPost(data) { - // Make POST request submitting - // Add CORS header to allow cross origin resource sharing - const response = await fetch(serverAddress + '/login', { - method: 'POST', - headers: { - 'Access-Control-Allow-Origin': '*' - }, - body: JSON.stringify(data) - }); - // Wait for response from server, then parse the body of the response in json format - return await response.json(); -} - -function signIn() { - // Reset sign in warnings - warning_incorrectPass.style.display = 'none'; - warning_recaptchaError.style.display = 'none'; - - // Get recaptcha response - const g_recaptcha_response = document.getElementById('g-recaptcha-response').value; - - // Don't process request unless recaptcha is complete - if (g_recaptcha_response === '') { - warning_recaptchaError.style.display = 'inline'; - return; - } - - // Get client IP address for robust recaptcha verification - /*const ip_address = getIpAddress().then(ret => { - console.log(ret); - return ret; - })*/ - - signInPost({ - "email": document.getElementById('input_email').value, - "password": document.getElementById('input_password').value, - "recap_response": g_recaptcha_response - }).then(ret => { - if (ret['status'] === 401) { - // Unauthorized error - if (ret['error'] === 'incorrect-password') { - // Incorrect password - // Show incorrect password indicator - warning_incorrectPass.style.display = 'inline'; - } else if(ret['error'] === 'failed-recaptcha') { - // recaptcha verification failed - warning_recaptchaError.style.display = 'inline'; - } - grecaptcha.reset(); // Refresh captcha - } else { - // Logged in successful - window.location.href="/frontend/profile.html"; - } - }); -} - -//--- End of sign in process ---// \ No newline at end of file diff --git a/frontend/style.css b/frontend/style.css deleted file mode 100644 index bf0f848..0000000 --- a/frontend/style.css +++ /dev/null @@ -1,24 +0,0 @@ -.logo { - margin-bottom: 50px; -} - -#form_signin { - width: 300px; - margin: auto; -} - -.btn_sign-in { - width: 100% !important; - margin-bottom: 10px; -} - -.warning-text { - color: #ff0000; -} - -.center { - text-align: center; -} -.hidden { - display: none; -} \ No newline at end of file From 092453685af8226461aaba329ebc67f92fe99612 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Tue, 3 Nov 2020 20:56:29 -0500 Subject: [PATCH 019/108] created signup form --- signup.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 signup.html diff --git a/signup.html b/signup.html new file mode 100644 index 0000000..5e47e80 --- /dev/null +++ b/signup.html @@ -0,0 +1,65 @@ + + + + + Sign Up + + + + + + + + + + + +
+ +
+ + + + +
+
+
+ + + We'll never share your email. +
+
+ + +
+ + +
+
+ + + + + + + + + From af2f5fa57622c60248f72fe3fae6b51fe741bc7e Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Tue, 3 Nov 2020 20:57:06 -0500 Subject: [PATCH 020/108] added sign up to nav bar --- index.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index fc1492d..12c6b8c 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ - + @@ -33,6 +33,11 @@ Profile + @@ -50,4 +55,5 @@ - \ No newline at end of file + + From 8ab595cf23ff9d3b82771bc96200dd38fde22082 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Tue, 3 Nov 2020 20:59:53 -0500 Subject: [PATCH 021/108] Sign up method headers --- script.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/script.js b/script.js index 8d9a4d9..ef8e9d3 100644 --- a/script.js +++ b/script.js @@ -93,4 +93,21 @@ function signIn() { }); } -//--- End of sign in process ---// \ No newline at end of file +//--- End of sign in process ---// + + + +//--- Sign Up process ---// + + +async function signInPost(data) { + + +} + +function signUp() { + +} + +//--- End of Sign Up Process ---// + From 7d28f984fd5c7d3d7309f26c8c72d67c24a21d36 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Tue, 3 Nov 2020 21:00:40 -0500 Subject: [PATCH 022/108] signup format --- style.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/style.css b/style.css index bf0f848..480bf20 100644 --- a/style.css +++ b/style.css @@ -7,6 +7,11 @@ margin: auto; } +#form_signup { + width: 300px; + margin: auto; +} + .btn_sign-in { width: 100% !important; margin-bottom: 10px; @@ -21,4 +26,4 @@ } .hidden { display: none; -} \ No newline at end of file +} From 310a1f3bebcdb5645d2e86392728299de206f5d6 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Tue, 3 Nov 2020 21:01:06 -0500 Subject: [PATCH 023/108] Update nav bar, sign up button on-click redirect --- login.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/login.html b/login.html index e056372..e1bf944 100644 --- a/login.html +++ b/login.html @@ -33,6 +33,11 @@ Profile + @@ -76,7 +81,7 @@

Create a new account here

From ca9287156df588e27e34cf1775ddb5d384e215a2 Mon Sep 17 00:00:00 2001 From: SebTota Date: Tue, 3 Nov 2020 21:10:56 -0500 Subject: [PATCH 024/108] Create CNAME --- CNAME | 1 + 1 file changed, 1 insertion(+) create mode 100644 CNAME diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..d4faa2d --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +camping.sebtota.com \ No newline at end of file From a4915edb46b74e5f027462be1dab951563dcf9b0 Mon Sep 17 00:00:00 2001 From: SebTota Date: Tue, 3 Nov 2020 21:14:05 -0500 Subject: [PATCH 025/108] Fixed redirection link. --- index.html | 4 ++-- login.html | 4 ++-- profile.html | 4 ++-- script.js | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/index.html b/index.html index fc1492d..748c076 100644 --- a/index.html +++ b/index.html @@ -27,10 +27,10 @@ Home (current) diff --git a/login.html b/login.html index e056372..0bf21c6 100644 --- a/login.html +++ b/login.html @@ -24,13 +24,13 @@ diff --git a/profile.html b/profile.html index ba5d11b..5a954a4 100644 --- a/profile.html +++ b/profile.html @@ -21,10 +21,10 @@ diff --git a/login.html b/login.html index e1bf944..1d6a6d7 100644 --- a/login.html +++ b/login.html @@ -24,18 +24,18 @@ diff --git a/profile.html b/profile.html index ba5d11b..5a954a4 100644 --- a/profile.html +++ b/profile.html @@ -21,10 +21,10 @@ From e7275ff9cd9c37458d7fc4962e8881523ba3005b Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Wed, 4 Nov 2020 12:36:26 -0500 Subject: [PATCH 029/108] Split name into two fields --- script.js | 24 ++++++++++-------------- signup.html | 8 ++++++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/script.js b/script.js index cde1a52..de02987 100644 --- a/script.js +++ b/script.js @@ -101,11 +101,16 @@ function signIn() { //check if forms are valid function validateForm() { - let name = document.getElementById("userName").value; + let firstName = document.getElementById("userFirstName").value; + let lastName = document.getElementById("userLastName").value; let email = document.getElementById("userEmail").value; - if (name == "") { - alert("Name must be filled out"); + if (firstName == "") { + alert("First name must be filled out"); + return false; + } + if (lastName == "") { + alert("Last name must be filled out"); return false; } if (email == "") { @@ -126,18 +131,9 @@ function validateForm() { alert("Password must match"); return false; } - signUp(); -} - -async function signInPost(data) { - - -} - -function signUp() { + //signUp(); alert("thus spake zarathustra"); - } -//--- End of Sign Up Process ---// + diff --git a/signup.html b/signup.html index ba6e10e..8eeb97d 100644 --- a/signup.html +++ b/signup.html @@ -42,8 +42,12 @@
- - + + +
+
+ +
From 5b90092320a8ac10debd4f0f8f1cd929a399ce7a Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Wed, 4 Nov 2020 12:39:35 -0500 Subject: [PATCH 030/108] Fixed bug where password could be left blank --- script.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/script.js b/script.js index de02987..6182173 100644 --- a/script.js +++ b/script.js @@ -117,6 +117,14 @@ function validateForm() { alert("Email must be filled out"); return false; } + if (document.getElementById("userPassword").value == "") { + alert("Password must be filled out"); + return false; + } + if (document.getElementById("userConfirmPassword").value == "") { + alert("Please confirm password"); + return false; + } var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; From 79efa330cb6a2b613aa46e44369a5180f72f3ea8 Mon Sep 17 00:00:00 2001 From: SebTota Date: Wed, 4 Nov 2020 18:47:25 -0500 Subject: [PATCH 031/108] Fixed changed on sign up page. --- index.html | 5 +---- login.html | 46 +++++++++++++++++++++++++++++++++++++--------- profile.html | 7 ++----- script.js | 46 +++++++++++++++++++++++++++++++++++----------- signup.html | 2 +- 5 files changed, 76 insertions(+), 30 deletions(-) diff --git a/index.html b/index.html index c1d8110..8072144 100644 --- a/index.html +++ b/index.html @@ -26,16 +26,13 @@ -
diff --git a/login.html b/login.html index 1d6a6d7..d393382 100644 --- a/login.html +++ b/login.html @@ -23,19 +23,16 @@ @@ -55,7 +52,7 @@

Forgot Password

- +
@@ -78,10 +75,41 @@
diff --git a/profile.html b/profile.html index 5a954a4..8844c23 100644 --- a/profile.html +++ b/profile.html @@ -20,13 +20,10 @@ - + From 3abe4c6389fbccd7fe2b053a674b84ead1bfaf83 Mon Sep 17 00:00:00 2001 From: SebTota Date: Fri, 6 Nov 2020 18:37:22 -0500 Subject: [PATCH 032/108] Finished user sign authentication system. --- index.html | 8 +-- login.html | 29 +++++----- profile.html | 8 +++ script.js | 146 +++++++++++++++++++++++++++++++++++---------------- 4 files changed, 128 insertions(+), 63 deletions(-) diff --git a/index.html b/index.html index 8072144..c57edf0 100644 --- a/index.html +++ b/index.html @@ -31,9 +31,12 @@ @@ -43,9 +46,6 @@

Some text about how our application works and is super great :)

This is a link to our repository.

- - -
diff --git a/login.html b/login.html index d393382..92dcd69 100644 --- a/login.html +++ b/login.html @@ -31,8 +31,11 @@ @@ -78,29 +81,29 @@
- - + +
- - + +
- + We'll never share your email.
- - + +
- - + +
@@ -109,7 +112,7 @@
diff --git a/profile.html b/profile.html index 8844c23..ee71379 100644 --- a/profile.html +++ b/profile.html @@ -27,6 +27,14 @@ Profile (current) + diff --git a/script.js b/script.js index e47e9a4..a4583ca 100644 --- a/script.js +++ b/script.js @@ -1,4 +1,9 @@ -const serverAddress = "https://api2.sebtota.com:5000" +const serverAddress = "http://localhost:5000" + +const nav_signIn = document.getElementById('nav_sign-in') +const nav_signOut = document.getElementById('nav_sign-out') +const nav_profile = document.getElementById('nav_profile') + const warning_incorrectPass = document.getElementById('label_incorrect-password'); const warning_recaptchaErrorSignIn = document.getElementById('label_recaptcha-error-signin'); @@ -6,41 +11,34 @@ const warning_recaptchaErrorSignUp = document.getElementById('label_recaptcha-er const warning_passwordConfirmation = document.getElementById('label__pass_conf'); -const input_signupPass = document.getElementById("userPassword"); -const input_signupPassConf = document.getElementById("userConfirmPassword"); - +const input_signupPass = document.getElementById("input_user-pass"); +const input_signupPassConf = document.getElementById("input_user-confirm-pass"); -if(1 === 1) { - document.getElementById('nav_profile').style.display = "inline"; -} -async function apiCallGet(url){ - // Make api call and wait for response before returning - // Add CORS header to allow cross origin resource sharing - const response = await fetch(url, { - mode: 'cors', +//--- Check User Login (Session) ---// +async function checkLoginGet() { + const response = await fetch(serverAddress + '/checkLogin', { + method: 'GET', + credentials: 'include', headers: { - 'Access-Control-Allow-Origin': '*' + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Credentials': 'true' } }); return await response.json(); } -function buttonClickGet() { - apiCallGet("http://localhost:5000/home").then(ret => { - alert(ret['name']); - }); -} +checkLoginGet().then(ret => { + if (ret['status'] === 200) { + // Signed in + nav_signOut.style.display = "inline"; + nav_profile.style.display = "inline"; + } else { + nav_signIn.style.display = "inline"; + } +}); -async function getIpAddress() { - const response = await fetch('https://api.ipify.org/?format=json', { - mode: 'no-cors', - headers: { - 'Access-Control-Allow-Origin': '*' - }, - }); - return await response.json(); -} +//--- END Check User Login ---// //--- Sign In Process ---// async function signInPost(data) { @@ -48,8 +46,10 @@ async function signInPost(data) { // Add CORS header to allow cross origin resource sharing const response = await fetch(serverAddress + '/login', { method: 'POST', + credentials: 'include', headers: { - 'Access-Control-Allow-Origin': '*' + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Credentials': 'true' }, body: JSON.stringify(data) }); @@ -103,9 +103,26 @@ function signIn() { //--- End of sign in process ---// +//--- Sign Out Process ---// +async function signOutPost() { + const response = await fetch(serverAddress + '/logout', { + method: 'GET', + credentials: 'include', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Credentials': 'true' + } + }); + return await response.json(); +} -//--- Sign Up process ---// +function signOut() { + signOutPost().then(ret => { + console.log("signed out"); + }) +} +//--- Sign Up Process ---// function confirmPass() { if (input_signupPass.value !== input_signupPassConf.value) { warning_passwordConfirmation.style.display = 'inline'; @@ -114,6 +131,59 @@ function confirmPass() { } } +async function signUpPost(data) { + // Make POST request submitting new account + // Add CORS header to allow cross origin resource sharing + const response = await fetch(serverAddress + '/signup', { + method: 'POST', + headers: { + 'Access-Control-Allow-Origin': '*' + }, + body: JSON.stringify(data) + }); + // Wait for response from server, then parse the body of the response in json format + return await response.json(); +} + +function signUp() { + // Reset sign in warnings + warning_recaptchaErrorSignUp.style.display = 'none'; + + // Get recaptcha response + const g_recaptcha_response = document.getElementById('g-recaptcha-response-1').value; + + // Don't process request unless recaptcha is complete + if (g_recaptcha_response === '') { + warning_recaptchaErrorSignUp.style.display = 'inline'; + return; + } + + signUpPost({ + "first_name": document.getElementById('input_user-first-name').value, + "last_name": document.getElementById('input_user-last-name').value, + "email": document.getElementById('input_user-email').value, + "password": input_signupPass.value, + "password_conf": input_signupPassConf.value, + "recap_response": g_recaptcha_response + }).then(ret => { + if (ret['status'] === 401) { + // Unauthorized error + if (ret['error'] === 'incorrect-password') { + // Incorrect password + // Show incorrect password indicator + warning_incorrectPass.style.display = 'inline'; + } else if(ret['error'] === 'failed-recaptcha') { + // recaptcha verification failed + warning_recaptchaErrorSignIn.style.display = 'inline'; + } + grecaptcha.reset(); // Refresh captcha + } else { + // Logged in successful + window.location.href="profile.html"; + } + }); +} + //check if forms are valid function validateForm() { let firstName = document.getElementById("userFirstName").value; @@ -152,20 +222,4 @@ function validateForm() { signUp(); } - -function signUp() { - // Reset sign in warnings - warning_recaptchaErrorSignUp.style.display = 'none'; - - // Get recaptcha response - const g_recaptcha_response = document.getElementById('g-recaptcha-response-1').value; - - // Don't process request unless recaptcha is complete - if (g_recaptcha_response === '') { - warning_recaptchaErrorSignUp.style.display = 'inline'; - return; - } -} - - - +//--- END SIGN UP PROCESS ---// From b209cbd3152a075382629174aa88164bf14011d5 Mon Sep 17 00:00:00 2001 From: SebTota Date: Fri, 6 Nov 2020 18:40:35 -0500 Subject: [PATCH 033/108] Fixed server address. --- script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script.js b/script.js index a4583ca..c0191ce 100644 --- a/script.js +++ b/script.js @@ -1,4 +1,4 @@ -const serverAddress = "http://localhost:5000" +const serverAddress = "https://api2.sebtota.com:5000" const nav_signIn = document.getElementById('nav_sign-in') const nav_signOut = document.getElementById('nav_sign-out') From cbed197ab017e9ea2465d0d3346e8ef4c99cc602 Mon Sep 17 00:00:00 2001 From: SebTota Date: Fri, 6 Nov 2020 18:56:44 -0500 Subject: [PATCH 034/108] removed unused file --- signup.html | 81 ----------------------------------------------------- 1 file changed, 81 deletions(-) delete mode 100644 signup.html diff --git a/signup.html b/signup.html deleted file mode 100644 index 5c54fbd..0000000 --- a/signup.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - Sign Up - - - - - - - - - - - -
- -
- - - - -
-
-
- - -
-
- - -
-
- - - - We'll never share your email. -
-
- - -
-
- - -
- - -
-
- - - - - - - - - From c2a7c83eb31d1cc12b8f299c05b07ac41c244981 Mon Sep 17 00:00:00 2001 From: SebTota Date: Wed, 11 Nov 2020 12:16:13 -0500 Subject: [PATCH 035/108] Added stuff --- profile.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++- script.js | 26 ++++++++++++++------- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/profile.html b/profile.html index ee71379..bd97256 100644 --- a/profile.html +++ b/profile.html @@ -23,7 +23,7 @@ - @@ -38,6 +38,69 @@ + + +
+
+

+

Adventurist

+
+
+
+
+
+
+

Group List

+
+
+ +
+
+
+
+
+

Example List

+
+
+
    +
  • +
    +
    + +
    +
    +
    +
    +

    Example List Item

    +
    +

    First Last

    +
    +
  • +
  • +
    +
    + +
    +
    +
    +
    +

    Example List Item

    +
    +

    First Last

    +
    +
  • +
+
+
+
+
\ No newline at end of file diff --git a/script.js b/script.js index c0191ce..20e5e16 100644 --- a/script.js +++ b/script.js @@ -1,4 +1,4 @@ -const serverAddress = "https://api2.sebtota.com:5000" +const serverAddress = "http://localhost:5000" const nav_signIn = document.getElementById('nav_sign-in') const nav_signOut = document.getElementById('nav_sign-out') @@ -14,6 +14,8 @@ const warning_passwordConfirmation = document.getElementById('label__pass_conf') const input_signupPass = document.getElementById("input_user-pass"); const input_signupPassConf = document.getElementById("input_user-confirm-pass"); +let profile; + //--- Check User Login (Session) ---// async function checkLoginGet() { @@ -21,7 +23,7 @@ async function checkLoginGet() { method: 'GET', credentials: 'include', headers: { - 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Origin': 'http://localhost:5000', 'Access-Control-Allow-Credentials': 'true' } }); @@ -33,6 +35,9 @@ checkLoginGet().then(ret => { // Signed in nav_signOut.style.display = "inline"; nav_profile.style.display = "inline"; + profile = ret['profile'] + console.log(profile); + document.getElementById('profile-name').textContent = profile['full_name']; } else { nav_signIn.style.display = "inline"; } @@ -48,7 +53,7 @@ async function signInPost(data) { method: 'POST', credentials: 'include', headers: { - 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Origin': 'http://localhost:5000', 'Access-Control-Allow-Credentials': 'true' }, body: JSON.stringify(data) @@ -63,7 +68,8 @@ function signIn() { warning_recaptchaErrorSignIn.style.display = 'none'; // Get recaptcha response - const g_recaptcha_response = document.getElementById('g-recaptcha-response').value; + // const g_recaptcha_response = document.getElementById('g-recaptcha-response').value; + const g_recaptcha_response = '123'; // Don't process request unless recaptcha is complete if (g_recaptcha_response === '') { @@ -88,11 +94,14 @@ function signIn() { // Incorrect password // Show incorrect password indicator warning_incorrectPass.style.display = 'inline'; - } else if(ret['error'] === 'failed-recaptcha') { + } + /* + if(ret['error'] === 'failed-recaptcha') { // recaptcha verification failed warning_recaptchaErrorSignIn.style.display = 'inline'; } grecaptcha.reset(); // Refresh captcha + */ } else { // Logged in successful window.location.href="profile.html"; @@ -107,17 +116,18 @@ function signIn() { async function signOutPost() { const response = await fetch(serverAddress + '/logout', { method: 'GET', - credentials: 'include', headers: { - 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Origin': 'http://localhost:5000', 'Access-Control-Allow-Credentials': 'true' - } + }, + credentials: 'include' }); return await response.json(); } function signOut() { signOutPost().then(ret => { + console.log(ret); console.log("signed out"); }) } From 4d4e7d18c7f21819ca8b40b91270b2805e39f52e Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Sat, 14 Nov 2020 17:44:20 -0500 Subject: [PATCH 036/108] Added example group request template. --- profile.html | 34 ++++++++++++++++++++++++++++++++++ script.js | 4 +++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/profile.html b/profile.html index bd97256..4e2f1d4 100644 --- a/profile.html +++ b/profile.html @@ -48,6 +48,40 @@
+
+
+

New Group Requests

+
+
+
    +
  • +
    +
    +

    Example Group Name

    +
    +

    Person Who Sent Invite

    +
    +
    + + +
    +
  • +
  • +
    +
    +

    Example Group Name

    +
    +

    Person Who Sent Invite

    +
    +
    + + +
    +
  • +
+
+
+

Group List

diff --git a/script.js b/script.js index 20e5e16..181573c 100644 --- a/script.js +++ b/script.js @@ -54,6 +54,7 @@ async function signInPost(data) { credentials: 'include', headers: { 'Access-Control-Allow-Origin': 'http://localhost:5000', + 'CORS_SUPPORTS_CREDENTIALS': 'true', 'Access-Control-Allow-Credentials': 'true' }, body: JSON.stringify(data) @@ -115,9 +116,10 @@ function signIn() { //--- Sign Out Process ---// async function signOutPost() { const response = await fetch(serverAddress + '/logout', { - method: 'GET', + method: 'POST', headers: { 'Access-Control-Allow-Origin': 'http://localhost:5000', + 'CORS_SUPPORTS_CREDENTIALS': 'true', 'Access-Control-Allow-Credentials': 'true' }, credentials: 'include' From c8a8a1f4a50ccea9fac3015e1ad0215a922e767f Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Mon, 16 Nov 2020 09:22:57 -0500 Subject: [PATCH 037/108] Added group invite display to profile page --- profile.html | 45 +++---------------- profile.js | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++ script.js | 8 +++- style.css | 25 +++++++++++ 4 files changed, 158 insertions(+), 40 deletions(-) create mode 100644 profile.js diff --git a/profile.html b/profile.html index 4e2f1d4..670c6d8 100644 --- a/profile.html +++ b/profile.html @@ -12,6 +12,10 @@ +
+
+
+
-
    -
  • -
    -
    -

    Example Group Name

    -
    -

    Person Who Sent Invite

    -
    -
    - - -
    -
  • -
  • -
    -
    -

    Example Group Name

    -
    -

    Person Who Sent Invite

    -
    -
    - - -
    -
  • +
@@ -104,19 +84,7 @@
    -
  • -
    -
    - -
    -
    -
    -
    -

    Example List Item

    -
    -

    First Last

    -
    -
  • +
  • @@ -136,5 +104,6 @@
    + \ No newline at end of file diff --git a/profile.js b/profile.js new file mode 100644 index 0000000..862721f --- /dev/null +++ b/profile.js @@ -0,0 +1,120 @@ +function createGroupInviteListItem(groupName, inviteFrom, requestUuid) { + const newListItem = document.createElement('li'); + newListItem.classList.add('list-group-item'); + + const textDiv = document.createElement('div'); + textDiv.style.width = '70%'; + textDiv.style.float = 'left'; + + const groupNameText = document.createElement('p'); + groupNameText.classList.add('md1'); + groupNameText.innerText = groupName; + + const groupInvitedByText = document.createElement('p'); + groupInvitedByText.classList.add('small'); + groupInvitedByText.style.marginBottom = '0'; + groupInvitedByText.innerText= inviteFrom; + + const buttonDiv = document.createElement('div'); + buttonDiv.style.width = '30%'; + buttonDiv.style.float = 'right'; + + const acceptButton = document.createElement('button'); + acceptButton.onclick = function() { acceptGroupInvite(requestUuid, newListItem) }; + acceptButton.innerText = 'Accept'; + acceptButton.classList.add('group-accept-button'); + acceptButton.classList.add('btn'); + acceptButton.classList.add('btn-success'); + acceptButton.classList.add('btn-sm'); + acceptButton.type = 'button'; + + const declineButton = document.createElement('button'); + declineButton.onclick = function() { declineGroupInvite(requestUuid, newListItem) }; + declineButton.innerText = 'Decline'; + declineButton.classList.add('group-decline-button'); + declineButton.classList.add('btn'); + declineButton.classList.add('btn-danger'); + declineButton.classList.add('btn-sm'); + declineButton.type = 'button'; + + newListItem.appendChild(textDiv); + textDiv.appendChild(groupNameText); + textDiv.appendChild(groupInvitedByText); + newListItem.appendChild(buttonDiv); + buttonDiv.appendChild(acceptButton); + buttonDiv.appendChild(declineButton); + + return newListItem; +} + +async function getGroupRequests() { + const response = await fetch(serverAddress + '/getGroupInvites', { + method: 'GET', + credentials: 'include', + headers: { + 'Access-Control-Allow-Origin': 'http://localhost:5000', + 'Access-Control-Allow-Credentials': 'true' + } + }); + return await response.json(); +} + +async function acceptGroupInviteRequest(requestUuid) { + const response = await fetch(serverAddress + '/acceptGroupInvite', { + method: 'POST', + credentials: 'include', + headers: { + 'Access-Control-Allow-Origin': 'http://localhost:5000', + 'Access-Control-Allow-Credentials': 'true' + }, + body: JSON.stringify({'request-uuid': requestUuid}) + }); + return await response.json(); +} + +async function declineGroupInviteRequest(requestUuid) { + const response = await fetch(serverAddress + '/declineGroupInvite', { + method: 'POST', + credentials: 'include', + headers: { + 'Access-Control-Allow-Origin': 'http://localhost:5000', + 'Access-Control-Allow-Credentials': 'true' + }, + body: JSON.stringify({'request-uuid': requestUuid}) + }); + return await response.json(); +} + +function declineGroupInvite(requestUuid, buttonElement) { + $("#loader").show(); + declineGroupInviteRequest(requestUuid).then(ret => { + if (ret['status'] === 200) { + buttonElement.remove(); + } + console.log(ret); + $("#loader").hide(); + }); +} + +function acceptGroupInvite(requestUuid, buttonElement) { + $("#loader").show(); + acceptGroupInviteRequest(requestUuid).then(ret => { + if (ret['status'] === 200) { + buttonElement.remove(); + } + console.log(ret); + $("#loader").hide(); + }); +} + +getGroupRequests().then(ret => { + if (ret['status'] === 200) { + const invites = ret['invites']; + console.log(invites); + for (let i = 0; i < invites.length; i++) { + document.getElementById('group-invite-list').appendChild( + createGroupInviteListItem(invites[i]['group-name'], invites[i]['invite-from'], invites[i]['request-uuid']) + ) + } + } +}); \ No newline at end of file diff --git a/script.js b/script.js index 181573c..3252791 100644 --- a/script.js +++ b/script.js @@ -41,6 +41,7 @@ checkLoginGet().then(ret => { } else { nav_signIn.style.display = "inline"; } + $("#loader").hide(); }); //--- END Check User Login ---// @@ -53,8 +54,7 @@ async function signInPost(data) { method: 'POST', credentials: 'include', headers: { - 'Access-Control-Allow-Origin': 'http://localhost:5000', - 'CORS_SUPPORTS_CREDENTIALS': 'true', + 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true' }, body: JSON.stringify(data) @@ -235,3 +235,7 @@ function validateForm() { } //--- END SIGN UP PROCESS ---// + + + + diff --git a/style.css b/style.css index 480bf20..9776c68 100644 --- a/style.css +++ b/style.css @@ -27,3 +27,28 @@ .hidden { display: none; } + +.group-accept-button { + width: 100%; + margin-bottom: 3px; +} + +.group-decline-button { + width: 100%; +} + +.loader-div { + width: 100%; + height: 100vh; + position: fixed; +} + +.loader { + width: 4em !important; + height: 4em !important; + left: 50%; + top: 50%; + margin-left: -2em; + margin-top: -2em; + position: fixed !important; +} \ No newline at end of file From 76c2c0ef2a288ded19e9e8ebcd53b8b2abc4557d Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Tue, 17 Nov 2020 11:13:51 -0500 Subject: [PATCH 038/108] Uncommented sign up form check --- profile.html | 2 +- profile.js | 5 +++++ script.js | 14 +++++++------- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/profile.html b/profile.html index 670c6d8..0b0f7f9 100644 --- a/profile.html +++ b/profile.html @@ -52,7 +52,7 @@

-
+
+ \ No newline at end of file diff --git a/profile.html b/profile.html index 6612028..9a04c28 100644 --- a/profile.html +++ b/profile.html @@ -4,6 +4,8 @@ Camping Trip Planner - Profile + + @@ -17,56 +19,58 @@
- -
- - -
-
-

-

Adventurist

-
-
- diff --git a/login.html b/login.html index 7035a34..8f8c1fd 100644 --- a/login.html +++ b/login.html @@ -45,7 +45,7 @@ Login
diff --git a/profile.html b/profile.html index 9a04c28..f16bd3a 100644 --- a/profile.html +++ b/profile.html @@ -41,7 +41,7 @@ Login
diff --git a/script.js b/script.js index 00740d7..9667945 100644 --- a/script.js +++ b/script.js @@ -116,6 +116,12 @@ function signOut() { }) } +$('#nav_sign-out').on('click',function (e){ + e.preventDefault(); + signOut(); + window.location.href="index.html"; +}); + //--- Sign Up Process ---// function confirmPass() { if (input_signupPass.value !== input_signupPassConf.value) { From e8cf1da40c4d40624bbe89e43cbe8fcc014300f8 Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 13:34:55 -0500 Subject: [PATCH 046/108] Added check login to sign out. --- script.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/script.js b/script.js index 9667945..1a3331b 100644 --- a/script.js +++ b/script.js @@ -26,16 +26,6 @@ async function checkLoginGet() { return await response.json(); } -checkLoginGet().then(ret => { - if (ret['status'] === 200) { - // Signed in - nav_signOut.style.display = "inline"; - nav_profile.style.display = "inline"; - nav_signIn.style.display = "none"; - } - $("#loader").hide(); -}); - //--- END Check User Login ---// //--- Sign In Process ---// @@ -120,6 +110,16 @@ $('#nav_sign-out').on('click',function (e){ e.preventDefault(); signOut(); window.location.href="index.html"; + + checkLoginGet().then(ret => { + if (ret['status'] === 200) { + // Signed in + nav_signOut.style.display = "inline"; + nav_profile.style.display = "inline"; + nav_signIn.style.display = "none"; + } + $("#loader").hide(); + }); }); //--- Sign Up Process ---// From aec254ff9edcd06319ae817a0dae62e6689e7d6f Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 13:38:48 -0500 Subject: [PATCH 047/108] Removed check login from profile page script. --- profile.js | 77 +++++++++++++++++++++--------------------------------- 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/profile.js b/profile.js index fcf9d14..39642c7 100644 --- a/profile.js +++ b/profile.js @@ -129,58 +129,41 @@ function acceptGroupInvite(requestUuid, buttonElement) { }); } -getGroupRequests().then(ret => { - if (ret['status'] === 200) { - const invites = ret['invites']; - console.log(invites); - if (invites.length > 0) { - $("#new-group-requests").show(); - } - - for (let i = 0; i < invites.length; i++) { - document.getElementById('group-invite-list').appendChild( - createGroupInviteListItem(invites[i]['group-name'], invites[i]['invite-from'], invites[i]['request-uuid']) - ) +$( document ).ready(function() { + getGroupRequests().then(ret => { + if (ret['status'] === 200) { + const invites = ret['invites']; + console.log(invites); + + if (invites.length > 0) { + $("#new-group-requests").show(); + } + + for (let i = 0; i < invites.length; i++) { + document.getElementById('group-invite-list').appendChild( + createGroupInviteListItem(invites[i]['group-name'], invites[i]['invite-from'], invites[i]['request-uuid']) + ) + } } - } -}); + }); -getGroupList().then(ret => { - console.log(ret); - console.log(ret['status']); - if (ret['status'] === 200) { - console.log("Creating group list"); - const groups = ret['groups']; - console.log(groups); - - for (let i = 0; i < groups.length; i++) { - document.getElementById('group-list').appendChild( - createGroupListItem(groups[i]['group-name'], groups[i]['group-uuid']) - ) + getGroupList().then(ret => { + console.log(ret); + console.log(ret['status']); + if (ret['status'] === 200) { + console.log("Creating group list"); + const groups = ret['groups']; + console.log(groups); + + for (let i = 0; i < groups.length; i++) { + document.getElementById('group-list').appendChild( + createGroupListItem(groups[i]['group-name'], groups[i]['group-uuid']) + ) + } } - } -}); - -async function checkLoginGet() { - const response = await fetch(serverAddress + '/checkLogin', { - method: 'GET', - credentials: 'include', }); - return await response.json(); -} +}); -checkLoginGet().then(ret => { - if (ret['status'] === 200) { - // Signed in - nav_signOut.style.display = "inline"; - nav_profile.style.display = "inline"; - nav_signIn.style.display = "none"; - profile = ret['profile'] - console.log(profile); - document.getElementById('profile-name').textContent = profile['full_name']; - } - $("#loader").hide(); -}); From 10fc1afaaecb9ae58c3a714fcf04ce444bf97329 Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 13:48:46 -0500 Subject: [PATCH 048/108] Changed sign in status check. --- script.js | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/script.js b/script.js index 1a3331b..4f2a73b 100644 --- a/script.js +++ b/script.js @@ -16,15 +16,23 @@ const input_signupPassConf = document.getElementById("input_user-confirm-pass"); let profile; +if (sessionStorage.getItem('status') != null) { + // Signed in + nav_signOut.style.display = "inline"; + nav_profile.style.display = "inline"; + nav_signIn.style.display = "none"; +} else { + window.location.href="login.html"; +} //--- Check User Login (Session) ---// -async function checkLoginGet() { +/*async function checkLoginGet() { const response = await fetch(serverAddress + '/checkLogin', { method: 'GET', credentials: 'include' }); return await response.json(); -} +}*/ //--- END Check User Login ---// @@ -82,6 +90,10 @@ function signIn() { */ } else { // Logged in successful + jQuery(window).load(function() { + sessionStorage.setItem('status','logged-in'); + }); + window.location.href="profile.html"; } }); @@ -103,23 +115,18 @@ function signOut() { signOutPost().then(ret => { console.log(ret); console.log("signed out"); + $("#loader").hide(); + + jQuery(window).load(function() { + sessionStorage.setItem('status', null) + }); + window.location.href="index.html"; }) } $('#nav_sign-out').on('click',function (e){ e.preventDefault(); signOut(); - window.location.href="index.html"; - - checkLoginGet().then(ret => { - if (ret['status'] === 200) { - // Signed in - nav_signOut.style.display = "inline"; - nav_profile.style.display = "inline"; - nav_signIn.style.display = "none"; - } - $("#loader").hide(); - }); }); //--- Sign Up Process ---// From d1f40e510bfec1565c2cdfa1699596753d77f56e Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 13:50:54 -0500 Subject: [PATCH 049/108] Temp fix for stuck login page. --- group.js | 9 +++++++++ login.js | 9 +++++++++ profile.js | 9 +++++++++ script.js | 9 --------- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/group.js b/group.js index e07f402..95d488c 100644 --- a/group.js +++ b/group.js @@ -1,3 +1,12 @@ +if (sessionStorage.getItem('status') != null) { + // Signed in + nav_signOut.style.display = "inline"; + nav_profile.style.display = "inline"; + nav_signIn.style.display = "none"; +} else { + window.location.href="login.html"; +} + async function sendGroupInvitePost(data) { const response = await fetch(serverAddress + '/inviteUser', { method: 'POST', diff --git a/login.js b/login.js index 1ebb3f2..042e408 100644 --- a/login.js +++ b/login.js @@ -1,3 +1,12 @@ +if (sessionStorage.getItem('status') != null) { + // Signed in + nav_signOut.style.display = "inline"; + nav_profile.style.display = "inline"; + nav_signIn.style.display = "none"; +} else { + window.location.href="login.html"; +} + const urlParams = new URLSearchParams(window.location.search); const signupCheck = urlParams.get('signup'); diff --git a/profile.js b/profile.js index 39642c7..d2afa9f 100644 --- a/profile.js +++ b/profile.js @@ -1,3 +1,12 @@ +if (sessionStorage.getItem('status') != null) { + // Signed in + nav_signOut.style.display = "inline"; + nav_profile.style.display = "inline"; + nav_signIn.style.display = "none"; +} else { + window.location.href="login.html"; +} + function createGroupInviteListItem(groupName, inviteFrom, requestUuid) { const newListItem = document.createElement('li'); newListItem.classList.add('list-group-item'); diff --git a/script.js b/script.js index 4f2a73b..564eef7 100644 --- a/script.js +++ b/script.js @@ -16,15 +16,6 @@ const input_signupPassConf = document.getElementById("input_user-confirm-pass"); let profile; -if (sessionStorage.getItem('status') != null) { - // Signed in - nav_signOut.style.display = "inline"; - nav_profile.style.display = "inline"; - nav_signIn.style.display = "none"; -} else { - window.location.href="login.html"; -} - //--- Check User Login (Session) ---// /*async function checkLoginGet() { const response = await fetch(serverAddress + '/checkLogin', { From e2b256d9af228bfa5574caa536bbab2977bccb6c Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 13:52:14 -0500 Subject: [PATCH 050/108] Removed login check on login page. --- login.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/login.js b/login.js index 042e408..1ebb3f2 100644 --- a/login.js +++ b/login.js @@ -1,12 +1,3 @@ -if (sessionStorage.getItem('status') != null) { - // Signed in - nav_signOut.style.display = "inline"; - nav_profile.style.display = "inline"; - nav_signIn.style.display = "none"; -} else { - window.location.href="login.html"; -} - const urlParams = new URLSearchParams(window.location.search); const signupCheck = urlParams.get('signup'); From ea69c5d866339d8d3d3cddf0cfdadae786ad8005 Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 13:55:34 -0500 Subject: [PATCH 051/108] Fixed jquery load. --- script.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/script.js b/script.js index 564eef7..593861c 100644 --- a/script.js +++ b/script.js @@ -81,10 +81,7 @@ function signIn() { */ } else { // Logged in successful - jQuery(window).load(function() { - sessionStorage.setItem('status','logged-in'); - }); - + sessionStorage.setItem('status','logged-in'); window.location.href="profile.html"; } }); @@ -108,9 +105,7 @@ function signOut() { console.log("signed out"); $("#loader").hide(); - jQuery(window).load(function() { - sessionStorage.setItem('status', null) - }); + sessionStorage.setItem('status', null); window.location.href="index.html"; }) } From 508f756e2900679708dc2fa0114bb26c7b94f237 Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 14:25:43 -0500 Subject: [PATCH 052/108] Fixed server ip address. --- script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script.js b/script.js index 593861c..85836ce 100644 --- a/script.js +++ b/script.js @@ -1,4 +1,4 @@ -const serverAddress = "https://api2.sebtota.com:5000" +const serverAddress = "https://camping.sebtota.com:5000" const nav_signIn = document.getElementById('nav_sign-in') const nav_signOut = document.getElementById('nav_sign-out') From e043fa8ae2de5d0c8da77fe8e94cd76f5df65852 Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 14:53:47 -0500 Subject: [PATCH 053/108] Removed unused function. --- script.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/script.js b/script.js index 85836ce..49c6ca4 100644 --- a/script.js +++ b/script.js @@ -15,18 +15,6 @@ const input_signupPass = document.getElementById("input_user-pass"); const input_signupPassConf = document.getElementById("input_user-confirm-pass"); let profile; - -//--- Check User Login (Session) ---// -/*async function checkLoginGet() { - const response = await fetch(serverAddress + '/checkLogin', { - method: 'GET', - credentials: 'include' - }); - return await response.json(); -}*/ - -//--- END Check User Login ---// - //--- Sign In Process ---// async function signInPost(data) { // Make POST request submitting From 730a559ec05c5c6f528e284a04202986601e3ec3 Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 15:05:04 -0500 Subject: [PATCH 054/108] Take user to profile page if already logged in. --- login.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/login.js b/login.js index 1ebb3f2..d798918 100644 --- a/login.js +++ b/login.js @@ -1,3 +1,7 @@ +if (sessionStorage.getItem('status') != null) { + window.location.href="profile.html"; +} + const urlParams = new URLSearchParams(window.location.search); const signupCheck = urlParams.get('signup'); From 3ca9740f7129774a280ad96f1fa311eb0e35239c Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 17:28:44 -0500 Subject: [PATCH 055/108] Code cleanup --- group.js | 2 +- index.js | 8 +++ login.html | 2 +- login.js | 157 ++++++++++++++++++++++++++++++++++++++++++++++++- profile.js | 22 +++---- script.js | 167 ----------------------------------------------------- 6 files changed, 178 insertions(+), 180 deletions(-) create mode 100644 index.js diff --git a/group.js b/group.js index 95d488c..b150b23 100644 --- a/group.js +++ b/group.js @@ -1,4 +1,4 @@ -if (sessionStorage.getItem('status') != null) { +if (sessionStorage.getItem('status') === 'logged-in') { // Signed in nav_signOut.style.display = "inline"; nav_profile.style.display = "inline"; diff --git a/index.js b/index.js new file mode 100644 index 0000000..caa8244 --- /dev/null +++ b/index.js @@ -0,0 +1,8 @@ +if (sessionStorage.getItem('status') === 'logged-in') { + // Signed in + nav_signOut.style.display = "inline"; + nav_profile.style.display = "inline"; + nav_signIn.style.display = "none"; +} else { + window.location.href="login.html"; +} \ No newline at end of file diff --git a/login.html b/login.html index 8f8c1fd..388d61d 100644 --- a/login.html +++ b/login.html @@ -134,7 +134,7 @@ - + \ No newline at end of file diff --git a/login.js b/login.js index d798918..76af687 100644 --- a/login.js +++ b/login.js @@ -1,10 +1,165 @@ -if (sessionStorage.getItem('status') != null) { +if (sessionStorage.getItem('status') === 'logged-in') { window.location.href="profile.html"; } const urlParams = new URLSearchParams(window.location.search); const signupCheck = urlParams.get('signup'); +//--- Sign In Process ---// +async function signInPost(data) { + // Make POST request submitting + // Add CORS header to allow cross origin resource sharing + const response = await fetch(serverAddress + '/login', { + method: 'POST', + credentials: 'include', + body: JSON.stringify(data) + }); + // Wait for response from server, then parse the body of the response in json format + return await response.json(); +} + +function signIn() { + // Reset sign in warnings + warning_incorrectPass.style.display = 'none'; + warning_recaptchaErrorSignIn.style.display = 'none'; + + // Get recaptcha response + const g_recaptcha_response = document.getElementById('g-recaptcha-response').value; + + // Don't process request unless recaptcha is complete + if (g_recaptcha_response === '') { + warning_recaptchaErrorSignIn.style.display = 'inline'; + return; + } + + signInPost({ + "email": document.getElementById('input_email').value, + "password": document.getElementById('input_password').value, + "recap_response": g_recaptcha_response + }).then(ret => { + if (ret['status'] === 401) { + // Unauthorized error + if (ret['error'] === 'incorrect-password') { + // Incorrect password + // Show incorrect password indicator + warning_incorrectPass.style.display = 'inline'; + } + + if(ret['error'] === 'failed-recaptcha') { + // recaptcha verification failed + warning_recaptchaErrorSignIn.style.display = 'inline'; + } + grecaptcha.reset(); // Refresh captcha + } else { + // Logged in successful + sessionStorage.setItem('status','logged-in'); + window.location.href="profile.html"; + } + }); +} +//--- End of sign in process ---// + + +//--- Sign Up Process ---// +function confirmPass() { + if (input_signupPass.value !== input_signupPassConf.value) { + warning_passwordConfirmation.style.display = 'inline'; + } else { + warning_passwordConfirmation.style.display = 'none'; + } +} + +async function signUpPost(data) { + // Make POST request submitting new account + // Add CORS header to allow cross origin resource sharing + const response = await fetch(serverAddress + '/signup', { + method: 'POST', + credentials: 'include', + body: JSON.stringify(data) + }); + // Wait for response from server, then parse the body of the response in json format + return await response.json(); +} + +function signUp() { + validateForm(); + + // Reset sign in warnings + warning_recaptchaErrorSignUp.style.display = 'none'; + + // Get recaptcha response + const g_recaptcha_response = document.getElementById('g-recaptcha-response-1').value; + + // Don't process request unless recaptcha is complete + if (g_recaptcha_response === '') { + warning_recaptchaErrorSignUp.style.display = 'inline'; + return; + } + + signUpPost({ + "first_name": document.getElementById('input_user-first-name').value, + "last_name": document.getElementById('input_user-last-name').value, + "email": document.getElementById('input_user-email').value, + "password": input_signupPass.value, + "password_conf": input_signupPassConf.value, + "recap_response": g_recaptcha_response + }).then(ret => { + if (ret['status'] === 401) { + // Unauthorized error + if (ret['error'] === 'incorrect-password') { + // Incorrect password + // Show incorrect password indicator + warning_incorrectPass.style.display = 'inline'; + } else if(ret['error'] === 'failed-recaptcha') { + // recaptcha verification failed + warning_recaptchaErrorSignIn.style.display = 'inline'; + } + grecaptcha.reset(); // Refresh captcha + } else { + // Logged in successful + window.location.href="profile.html"; + } + }); +} + +//check if forms are valid +function validateForm() { + let firstName = document.getElementById("input_user-first-name").value; + let lastName = document.getElementById("input_user-last-name").value; + let email = document.getElementById("input_user-email").value; + + if (firstName == "") { + alert("First name must be filled out"); + return false; + } + if (lastName == "") { + alert("Last name must be filled out"); + return false; + } + if (email == "") { + alert("Email must be filled out"); + return false; + } + if (document.getElementById("input_password").value == "") { + alert("Password must be filled out"); + return false; + } + if (document.getElementById("input_user-confirm-pass").value == "") { + alert("Please confirm password"); + return false; + } + + var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; + + if (reg.test(email) == false) + { + alert('Invalid Email Address'); + return false; + } +} + +//--- END SIGN UP PROCESS ---// + if (signupCheck === 'true') { $('#modal_sign-up').modal('toggle'); } \ No newline at end of file diff --git a/profile.js b/profile.js index d2afa9f..1d2d46f 100644 --- a/profile.js +++ b/profile.js @@ -1,12 +1,3 @@ -if (sessionStorage.getItem('status') != null) { - // Signed in - nav_signOut.style.display = "inline"; - nav_profile.style.display = "inline"; - nav_signIn.style.display = "none"; -} else { - window.location.href="login.html"; -} - function createGroupInviteListItem(groupName, inviteFrom, requestUuid) { const newListItem = document.createElement('li'); newListItem.classList.add('list-group-item'); @@ -172,7 +163,18 @@ $( document ).ready(function() { } } }); -}); + if (sessionStorage.getItem('status') === 'logged-in') { + // Signed in + nav_signOut.style.display = "inline"; + nav_profile.style.display = "inline"; + nav_signIn.style.display = "none"; + } else { + window.location.href="login.html"; + } + + $("#loader").hide(); + +}); diff --git a/script.js b/script.js index 49c6ca4..9fb33e1 100644 --- a/script.js +++ b/script.js @@ -4,7 +4,6 @@ const nav_signIn = document.getElementById('nav_sign-in') const nav_signOut = document.getElementById('nav_sign-out') const nav_profile = document.getElementById('nav_profile') - const warning_incorrectPass = document.getElementById('label_incorrect-password'); const warning_recaptchaErrorSignIn = document.getElementById('label_recaptcha-error-signin'); const warning_recaptchaErrorSignUp = document.getElementById('label_recaptcha-error-signup'); @@ -15,68 +14,6 @@ const input_signupPass = document.getElementById("input_user-pass"); const input_signupPassConf = document.getElementById("input_user-confirm-pass"); let profile; -//--- Sign In Process ---// -async function signInPost(data) { - // Make POST request submitting - // Add CORS header to allow cross origin resource sharing - const response = await fetch(serverAddress + '/login', { - method: 'POST', - credentials: 'include', - body: JSON.stringify(data) - }); - // Wait for response from server, then parse the body of the response in json format - return await response.json(); -} - -function signIn() { - // Reset sign in warnings - warning_incorrectPass.style.display = 'none'; - warning_recaptchaErrorSignIn.style.display = 'none'; - - // Get recaptcha response - const g_recaptcha_response = document.getElementById('g-recaptcha-response').value; - - // Don't process request unless recaptcha is complete - if (g_recaptcha_response === '') { - warning_recaptchaErrorSignIn.style.display = 'inline'; - return; - } - - // Get client IP address for robust recaptcha verification - /*const ip_address = getIpAddress().then(ret => { - console.log(ret); - return ret; - })*/ - - signInPost({ - "email": document.getElementById('input_email').value, - "password": document.getElementById('input_password').value, - "recap_response": g_recaptcha_response - }).then(ret => { - if (ret['status'] === 401) { - // Unauthorized error - if (ret['error'] === 'incorrect-password') { - // Incorrect password - // Show incorrect password indicator - warning_incorrectPass.style.display = 'inline'; - } - /* - if(ret['error'] === 'failed-recaptcha') { - // recaptcha verification failed - warning_recaptchaErrorSignIn.style.display = 'inline'; - } - grecaptcha.reset(); // Refresh captcha - */ - } else { - // Logged in successful - sessionStorage.setItem('status','logged-in'); - window.location.href="profile.html"; - } - }); -} - -//--- End of sign in process ---// - //--- Sign Out Process ---// async function signOutPost() { @@ -102,107 +39,3 @@ $('#nav_sign-out').on('click',function (e){ e.preventDefault(); signOut(); }); - -//--- Sign Up Process ---// -function confirmPass() { - if (input_signupPass.value !== input_signupPassConf.value) { - warning_passwordConfirmation.style.display = 'inline'; - } else { - warning_passwordConfirmation.style.display = 'none'; - } -} - -async function signUpPost(data) { - // Make POST request submitting new account - // Add CORS header to allow cross origin resource sharing - const response = await fetch(serverAddress + '/signup', { - method: 'POST', - credentials: 'include', - body: JSON.stringify(data) - }); - // Wait for response from server, then parse the body of the response in json format - return await response.json(); -} - -function signUp() { - validateForm(); - - // Reset sign in warnings - warning_recaptchaErrorSignUp.style.display = 'none'; - - // Get recaptcha response - const g_recaptcha_response = document.getElementById('g-recaptcha-response-1').value; - - // Don't process request unless recaptcha is complete - if (g_recaptcha_response === '') { - warning_recaptchaErrorSignUp.style.display = 'inline'; - return; - } - - signUpPost({ - "first_name": document.getElementById('input_user-first-name').value, - "last_name": document.getElementById('input_user-last-name').value, - "email": document.getElementById('input_user-email').value, - "password": input_signupPass.value, - "password_conf": input_signupPassConf.value, - "recap_response": g_recaptcha_response - }).then(ret => { - if (ret['status'] === 401) { - // Unauthorized error - if (ret['error'] === 'incorrect-password') { - // Incorrect password - // Show incorrect password indicator - warning_incorrectPass.style.display = 'inline'; - } else if(ret['error'] === 'failed-recaptcha') { - // recaptcha verification failed - warning_recaptchaErrorSignIn.style.display = 'inline'; - } - grecaptcha.reset(); // Refresh captcha - } else { - // Logged in successful - window.location.href="profile.html"; - } - }); -} - -//check if forms are valid -function validateForm() { - let firstName = document.getElementById("input_user-first-name").value; - let lastName = document.getElementById("input_user-last-name").value; - let email = document.getElementById("input_user-email").value; - - if (firstName == "") { - alert("First name must be filled out"); - return false; - } - if (lastName == "") { - alert("Last name must be filled out"); - return false; - } - if (email == "") { - alert("Email must be filled out"); - return false; - } - if (document.getElementById("input_password").value == "") { - alert("Password must be filled out"); - return false; - } - if (document.getElementById("input_user-confirm-pass").value == "") { - alert("Please confirm password"); - return false; - } - - var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; - - if (reg.test(email) == false) - { - alert('Invalid Email Address'); - return false; - } -} - -//--- END SIGN UP PROCESS ---// - - - - From ebd59ca15332f7d8e231db673dc3e4d21ac00d15 Mon Sep 17 00:00:00 2001 From: Seb Tota Date: Fri, 20 Nov 2020 17:33:15 -0500 Subject: [PATCH 056/108] Remove login check on login page. --- login.js | 4 ---- script.js | 2 -- 2 files changed, 6 deletions(-) diff --git a/login.js b/login.js index 76af687..e6fd051 100644 --- a/login.js +++ b/login.js @@ -1,7 +1,3 @@ -if (sessionStorage.getItem('status') === 'logged-in') { - window.location.href="profile.html"; -} - const urlParams = new URLSearchParams(window.location.search); const signupCheck = urlParams.get('signup'); diff --git a/script.js b/script.js index 9fb33e1..b6fc649 100644 --- a/script.js +++ b/script.js @@ -13,8 +13,6 @@ const warning_passwordConfirmation = document.getElementById('label__pass_conf') const input_signupPass = document.getElementById("input_user-pass"); const input_signupPassConf = document.getElementById("input_user-confirm-pass"); -let profile; - //--- Sign Out Process ---// async function signOutPost() { const response = await fetch(serverAddress + '/logout', { From 683d331fee61fa55694a8dc406644f3fd1028d5d Mon Sep 17 00:00:00 2001 From: SebTota Date: Fri, 20 Nov 2020 17:54:27 -0500 Subject: [PATCH 057/108] Fixed file import. --- login.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/login.html b/login.html index 388d61d..0ec9bc8 100644 --- a/login.html +++ b/login.html @@ -135,6 +135,6 @@ - + \ No newline at end of file From 4e5ffb231a9bb8a936cb56d283ab9859810bf18d Mon Sep 17 00:00:00 2001 From: SebTota Date: Fri, 20 Nov 2020 17:55:46 -0500 Subject: [PATCH 058/108] Added missing file import on main page. --- index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/index.html b/index.html index 6b97121..928d0c9 100644 --- a/index.html +++ b/index.html @@ -85,6 +85,7 @@ + From 69d755abf23b547cd022b5ee563de02342821019 Mon Sep 17 00:00:00 2001 From: SebTota Date: Fri, 20 Nov 2020 18:00:58 -0500 Subject: [PATCH 059/108] Minor bug fixes. --- group.html | 3 --- index.js | 2 -- profile.html | 5 +---- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/group.html b/group.html index dc7e2a7..64845e5 100644 --- a/group.html +++ b/group.html @@ -23,9 +23,6 @@ + + + + From 36e0eb03bea6b6edd28bec514d2e5894faa3afed Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Fri, 27 Nov 2020 20:46:01 -0500 Subject: [PATCH 074/108] Added functions for populating dataTable --- group.js | 84 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 12 deletions(-) diff --git a/group.js b/group.js index ad25eee..a6b94fd 100644 --- a/group.js +++ b/group.js @@ -1,7 +1,13 @@ + + +//DataTable = dt; + const urlParams = new URLSearchParams(window.location.search); const groupName = decodeURIComponent(urlParams.get('group-name')); const groupUuid = urlParams.get('group-uuid'); +let listUuid; + if (getCookie('active') === 'true') { // Signed in nav_signOut.style.display = "inline"; @@ -44,19 +50,25 @@ async function getLists() { return await response.json(); } -function createListItem(groupName, groupUuid) { +async function getElements() { + + const response = await fetch(serverAddress + '/getElementsByList?list-uuid=' +listUuid, { + method: 'GET', + credentials: 'include', + redirect: 'follow' + }); + return await response.json(); +} + +function createListItem(item) { const listItem = document.createElement('li'); - listItem.classList.add('list-group-item'); + listItem.classList.add('list-item'); + listItem.textContent = item; const listTitle = document.createElement('p'); listTitle.classList.add('md1'); listTitle.style.marginBottom = '0'; - const listLink = document.createElement('a'); - listLink.href = 'group.html?group-uuid=' + groupUuid + '&group-name=' + groupName; - listLink.textContent = groupName; - - listTitle.appendChild(listLink); listItem.appendChild(listTitle); return listItem; @@ -69,14 +81,62 @@ $( document ).ready(function() { console.log(ret['status']); if (ret['status'] === 200) { console.log("Creating group page lists"); + // const lists = ret['lists']; + // console.log(lists); + const lists = ret['lists']; console.log(lists); - for (let i = 0; i < lists.length; i++) { - document.getElementById('group-lists').appendChild( - createListItem(lists[i]['group-name'], lists[i]['group-uuid']) - ) - } + listUuid = lists[0]['list-id']; + //print(listUuid); + + //populate individual list + getElements().then(ret => { + console.log(ret); + console.log(ret['status']); + if (ret['status'] === 200) { + console.log("Creating list display"); + } + const elements = ret['elements']; + console.log(elements); + + $("single-list-entry").append("
    "); + + let dataSet = []; + + console.log(139); + for (let i = 0; i < elements.length; i++) { + dataSet.push([elements[i]['item-name'], elements[i]['item-quantity'], elements[i]['item-cost'], elements[i]['item-description'], elements[i]['item-status']]); + console.log(dataSet); + console.log(143); + } + console.log(144); + + $(document).ready(function() { + $('#data-table').DataTable( { + data: dataSet, + 'columnDefs': [{ + 'targets': 0, + "width": "20%", + 'searchable':false, + 'orderable':false, + 'className': 'dt-body-center', + 'render': function (data, type, full, meta){ + return ''; + } + + }], + columns: [ + { title: "Item Name" }, + { title: "Quantity" }, + { title: "Price" }, + { title: "Description." }, + { title: "Status" }, + ] + } ); + } ); + + }); } }); From d18643aa3f6629e2f694fee73c6dd90da8479a98 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Fri, 27 Nov 2020 20:46:30 -0500 Subject: [PATCH 075/108] Datatable css styling --- style.css | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 1 deletion(-) diff --git a/style.css b/style.css index de4c896..a8919e8 100644 --- a/style.css +++ b/style.css @@ -88,4 +88,135 @@ body { margin-left: -2em; margin-top: -2em; position: fixed !important; -} \ No newline at end of file +} + +.ui { + height: 100vh; + display: grid; +} + +.listHorizontal { + color: #b6d8cf; + font-size:30px; + padding:0; + text-transform: uppercase; + list-style-type: none; + display:flex; + justify-content:space-evenly; +} + +.list-inline > div{ + float: left; + display: inline; +} + +table.dataTable { + margin: 0 auto; + clear: both; + width: 100%; +} + +table.dataTable thead th { + padding: 3px 18px 3px 10px; + border-bottom: 1px solid black; + font-weight: bold; + cursor: pointer; + *cursor: hand; +} + +table.dataTable tfoot th { + padding: 3px 18px 3px 10px; + border-top: 1px solid black; + font-weight: bold; +} + +table.dataTable td { + padding: 3px 10px; +} + +table.dataTable td.center, +table.dataTable td.dataTables_empty { + text-align: center; +} + +table.dataTable tr.odd { background-color: #E2E4FF; } +table.dataTable tr.even { background-color: white; } + +table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; } +table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; } +table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; } +table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; } +table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; } +table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } + + +/* + * Table wrapper + */ +.dataTables_wrapper { + position: relative; + clear: both; + *zoom: 1; +} + + +/* + * Page length menu + */ +.dataTables_length { + float: left; +} + + +/* + * Filter + */ +.dataTables_filter { + float: right; + text-align: right; +} + + +/* + * Table information + */ +.dataTables_info { + clear: both; + float: left; +} + +/* + * Processing indicator + */ +.dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 250px; + height: 30px; + margin-left: -125px; + margin-top: -15px; + padding: 14px 0 2px 0; + border: 1px solid #ddd; + text-align: center; + color: #999; + font-size: 14px; + background-color: white; +} + +table.dataTable th:active { + outline: none; +} + + +/* + * Scrolling + */ +.dataTables_scroll { + clear: both; +} + +.dataTables_scrollBody { + *margin-top: -1px; +} + From 6ff9b07b32120aca40f4598f005b8225305940db Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Sun, 29 Nov 2020 16:10:53 -0500 Subject: [PATCH 076/108] Multi-table display --- group.html | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/group.html b/group.html index e5fe163..5fa15ac 100644 --- a/group.html +++ b/group.html @@ -60,8 +60,13 @@

    -
    -
    DataTable
    +
    DataTable
    +
    +
    +
    +
    +
    + From b069c084809b97eb6a17f43be36c9c80410de60f Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Sun, 29 Nov 2020 16:11:27 -0500 Subject: [PATCH 077/108] Cleaned up code. Multi-table functionality. --- group.js | 128 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 54 deletions(-) diff --git a/group.js b/group.js index a6b94fd..027abb6 100644 --- a/group.js +++ b/group.js @@ -74,71 +74,91 @@ function createListItem(item) { return listItem; } -$( document ).ready(function() { +function getTableDivId(num){ + switch(num) { + case num = 0: + return "#data-table1" + case num = 1: + return "#data-table2" + case num = 2: + return "#data-table3" + case num = 3: + return "#data-table4" + case num = 4: + return "#data-table5" + } +} +//render a single table +function renderTable(tableDivId){ + getElements().then(ret => { + console.log(ret); + console.log(ret['status']); + if (ret['status'] === 200) { + console.log("Creating list display"); + + const elements = ret['elements']; + console.log(elements); + + let dataSet = []; + console.log(139); + for (let i = 0; i < elements.length; i++) { + dataSet.push([0, elements[i]['item-name'], elements[i]['item-quantity'], elements[i]['item-cost'], elements[i]['item-description'], elements[i]['item-status']]); + console.log(dataSet); + console.log(143); + } + console.log(144); + + $(document).ready(function () { + $(tableDivId).DataTable({ + data: dataSet, + 'columnDefs': [{ + 'targets': 0, + "width": "20%", + 'searchable': false, + 'orderable': false, + 'className': 'dt-body-center', + 'render': function (data, type, full, meta) { + return ''; + }, + order: [[1, 'asc']] + + }], + columns: [ + {title: " ", width: '50px'}, + {title: "Item Name", width: '120px'}, + {title: "Quantity", width: '100px'}, + {title: "Price", width: '100px'}, + {title: "Description", width: '200px'}, + {title: "Status"}, + ] + }); + //$("div.toolbar").html('Custom tool bar! Text/images etc.'); + }); + } + }); +} + + +$( document ).ready(function() { + //get the lists belonging to this group getLists().then(ret => { console.log(ret); console.log(ret['status']); if (ret['status'] === 200) { console.log("Creating group page lists"); - // const lists = ret['lists']; - // console.log(lists); - const lists = ret['lists']; console.log(lists); - listUuid = lists[0]['list-id']; - //print(listUuid); - //populate individual list - getElements().then(ret => { - console.log(ret); - console.log(ret['status']); - if (ret['status'] === 200) { - console.log("Creating list display"); - } - const elements = ret['elements']; - console.log(elements); - - $("single-list-entry").append("
      "); - - let dataSet = []; - - console.log(139); - for (let i = 0; i < elements.length; i++) { - dataSet.push([elements[i]['item-name'], elements[i]['item-quantity'], elements[i]['item-cost'], elements[i]['item-description'], elements[i]['item-status']]); - console.log(dataSet); - console.log(143); - } - console.log(144); - - $(document).ready(function() { - $('#data-table').DataTable( { - data: dataSet, - 'columnDefs': [{ - 'targets': 0, - "width": "20%", - 'searchable':false, - 'orderable':false, - 'className': 'dt-body-center', - 'render': function (data, type, full, meta){ - return ''; - } - - }], - columns: [ - { title: "Item Name" }, - { title: "Quantity" }, - { title: "Price" }, - { title: "Description." }, - { title: "Status" }, - ] - } ); - } ); - - }); + for(let j = 0; j < lists.length; j++) + { + listUuid = lists[j]['list-id']; + renderTable(getTableDivId(j)); + } } }); -}); \ No newline at end of file +}); + From 79fc96e98dfb3f8dad62d5d13b7065831740cfe0 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Sun, 29 Nov 2020 22:57:33 -0500 Subject: [PATCH 078/108] CSS Stylings --- style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/style.css b/style.css index a8919e8..dd5b753 100644 --- a/style.css +++ b/style.css @@ -48,6 +48,11 @@ body { text-align: center; } +.group-header-center { + text-align: center; + margin-top:116px; +} + .center-div { margin: auto; width: 100%; From ac20604a881297ae9291c1b0354a62f4bcf28eb0 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Sun, 29 Nov 2020 23:07:44 -0500 Subject: [PATCH 079/108] Css datatable button import, additional list display, create list button --- group.html | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/group.html b/group.html index 5fa15ac..0fe45bb 100644 --- a/group.html +++ b/group.html @@ -11,8 +11,12 @@ + + + + @@ -57,19 +61,57 @@

      - +   +
      + +
      + -
      DataTable
      +

      +   +

      +   +

      +   +

      +   +

      - + + From c4ba92283967c60bebd59218071e354af340900a Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Sun, 29 Nov 2020 23:08:59 -0500 Subject: [PATCH 080/108] Creation of new lists, list limit of five, rendering of table headers, add item button (sans functionality) --- group.js | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/group.js b/group.js index 027abb6..791ac95 100644 --- a/group.js +++ b/group.js @@ -7,6 +7,7 @@ const groupName = decodeURIComponent(urlParams.get('group-name')); const groupUuid = urlParams.get('group-uuid'); let listUuid; +let listCount; if (getCookie('active') === 'true') { // Signed in @@ -39,6 +40,40 @@ function sendGroupInvite() { }) } + +async function newListPost(data) { + // Make POST request submitting new account + // Add CORS header to allow cross origin resource sharing + const response = await fetch(serverAddress + '/createList?group-uuid=\' +groupUuid', { + method: 'POST', + credentials: 'include', + redirect: 'follow', + body: JSON.stringify(data) + }); + // Wait for response from server, then parse the body of the response in json format + return await response.json(); +} + +function createNewList() { + + if(listCount === 5){ + alert( 'Please consider a pro membership if you would like to have more than 5 lists :)'); + return; + } + + newListPost({ + "name": document.getElementById('input_user-list-name').value, + "group-uuid": groupUuid + }).then(ret => { + if (ret['status'] === 400) { + } + else{ + $('#modal_new-list').modal('hide'); + window.location.reload(true); + } + }); +} + document.getElementById('group-name-display').textContent = groupName; async function getLists() { @@ -89,8 +124,9 @@ function getTableDivId(num){ } } + //render a single table -function renderTable(tableDivId){ +function renderTable(tableDivId, temp){ getElements().then(ret => { console.log(ret); console.log(ret['status']); @@ -101,13 +137,15 @@ function renderTable(tableDivId){ console.log(elements); let dataSet = []; - console.log(139); + for (let i = 0; i < elements.length; i++) { dataSet.push([0, elements[i]['item-name'], elements[i]['item-quantity'], elements[i]['item-cost'], elements[i]['item-description'], elements[i]['item-status']]); console.log(dataSet); - console.log(143); } - console.log(144); + + let headerDiv = tableDivId.concat("Header"); + headerDiv = headerDiv.substr(1, headerDiv.length); + document.getElementById(headerDiv).textContent = temp; $(document).ready(function () { $(tableDivId).DataTable({ @@ -131,6 +169,15 @@ function renderTable(tableDivId){ {title: "Price", width: '100px'}, {title: "Description", width: '200px'}, {title: "Status"}, + ], + dom: 'Bfrtip', + buttons: [ + { + text: 'Add item', + action: function ( e, dt, node, config ) { + alert( 'Button activated' ); + } + } ] }); //$("div.toolbar").html('Custom tool bar! Text/images etc.'); @@ -149,12 +196,14 @@ $( document ).ready(function() { console.log("Creating group page lists"); const lists = ret['lists']; console.log(lists); + listCount = lists.length; //populate individual list for(let j = 0; j < lists.length; j++) { listUuid = lists[j]['list-id']; - renderTable(getTableDivId(j)); + console.log(lists[j]['list-name']); + renderTable(getTableDivId(j), lists[j]['list-name']); } } }); From c70658c82099aa0599f7e87f6376f3d5613ec6ca Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Mon, 30 Nov 2020 00:59:55 -0500 Subject: [PATCH 081/108] New item modal stylings --- style.css | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/style.css b/style.css index dd5b753..92e8783 100644 --- a/style.css +++ b/style.css @@ -225,3 +225,12 @@ table.dataTable th:active { *margin-top: -1px; } +#new_list { + width: 300px; + margin: auto; +} + +#new_item { + width: 300px; + margin: auto; +} \ No newline at end of file From 46601ae7668ced2e884e23b04ce9bad173d562b0 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Mon, 30 Nov 2020 01:00:40 -0500 Subject: [PATCH 082/108] New item functions --- group.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/group.js b/group.js index 791ac95..aba8d6a 100644 --- a/group.js +++ b/group.js @@ -124,9 +124,47 @@ function getTableDivId(num){ } } +async function newItemPost(data) { + console.log(data); + // Make POST request submitting new account + // Add CORS header to allow cross origin resource sharing + const response = await fetch(serverAddress + '/addElementToList', { + method: 'POST', + credentials: 'include', + redirect: 'follow', + body: JSON.stringify(data) + }); + // Wait for response from server, then parse the body of the response in json format + return await response.json(); +} + +function addNewItem(){ + newItemPost({ + 'list-id' : document.getElementById('list-id').value, + 'element-name' : document.getElementById('input_user-item-name').value, + 'element-description' : document.getElementById('input_user-item-description').value, + 'element-quantity' : document.getElementById('input_user-item-quantity').value, + 'element_cost': document.getElementById('input_user-item-cost').value, + 'element-user-id' : 100, + 'element_status': document.getElementById('input_user-item-status').value + + }).then(ret => { + if (ret['status'] === 400) { + } + else{ + $('#modal_new-item').modal('hide'); + window.location.reload(true); + } + }); +} + +function addItemModal(listId){ + document.getElementById('list-id').value = listId; + $('#modal_add-item').modal('show'); +} //render a single table -function renderTable(tableDivId, temp){ +function renderTable(tableDivId, temp, listId){ getElements().then(ret => { console.log(ret); console.log(ret['status']); @@ -175,7 +213,8 @@ function renderTable(tableDivId, temp){ { text: 'Add item', action: function ( e, dt, node, config ) { - alert( 'Button activated' ); + //alert( 'Button activated' ); + addItemModal(listId); } } ] @@ -201,9 +240,12 @@ $( document ).ready(function() { //populate individual list for(let j = 0; j < lists.length; j++) { - listUuid = lists[j]['list-id']; + listUuid = lists[j]['list-uuid']; + console.log(lists[j]['list-name']); - renderTable(getTableDivId(j), lists[j]['list-name']); + let listId = lists[j]['list-id']; + let listName = lists[j]['list-name']; + renderTable(getTableDivId(j), listName , listId); } } }); From 4b6d0fa0d0267bf390b20f3ff81cb92e1da40c7c Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Mon, 30 Nov 2020 01:01:01 -0500 Subject: [PATCH 083/108] New item Modal --- group.html | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/group.html b/group.html index 0fe45bb..d52dac4 100644 --- a/group.html +++ b/group.html @@ -97,7 +97,7 @@
      +
      + +
      +

      Group List

      @@ -75,4 +80,33 @@ - \ No newline at end of file + + + + +
      From bf512dfe58daf705484cb0bb08125f72a934b540 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Mon, 30 Nov 2020 09:48:04 -0500 Subject: [PATCH 088/108] Create new group functions --- profile.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/profile.js b/profile.js index 111d49a..bd80db9 100644 --- a/profile.js +++ b/profile.js @@ -143,6 +143,32 @@ function acceptGroupInvite(requestUuid, buttonElement) { }); } +async function newGroupPost(data) { + console.log(data); + const response = await fetch(serverAddress + '/createGroup', { + method: 'POST', + credentials: 'include', + redirect: 'follow', + body: JSON.stringify(data) + }); + return await response.json(); +} + +function newGroup() { + $("#loader").show(); + newGroupPost({ + 'group-name': document.getElementById('input_user-group-name').value, + }).then(ret => { + if (ret['status'] === 200) { + $('#modal_new-group').modal('hide'); + window.location.reload(true); + } + console.log(ret); + checkGroupInvite(); + $("#loader").hide(); + }); +} + $( document ).ready(function() { From 7f38a41acf8b3e25cf0a174be2291692460db5d5 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Mon, 30 Nov 2020 09:48:16 -0500 Subject: [PATCH 089/108] Create new group --- style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/style.css b/style.css index 813d7e5..9e74c52 100644 --- a/style.css +++ b/style.css @@ -238,4 +238,9 @@ table.dataTable th:active { #delete_list { width: 300px; margin: auto; +} + +#new_group{ + width: 300px; + margin: auto; } \ No newline at end of file From 4288d0b91c17d8bcc7242e8f14c46144392e6a60 Mon Sep 17 00:00:00 2001 From: SebTota Date: Mon, 30 Nov 2020 12:32:03 -0500 Subject: [PATCH 090/108] Update script.js --- script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script.js b/script.js index b7eda4c..299481e 100644 --- a/script.js +++ b/script.js @@ -1,4 +1,4 @@ -const serverAddress = "http://localhost:5000" +const serverAddress = "https://camping.sebtota.com:5000" const nav_signIn = document.getElementById('nav_sign-in') const nav_signOut = document.getElementById('nav_sign-out') From 560953110add6f0f38d805d30df5955861b6b280 Mon Sep 17 00:00:00 2001 From: SebTota Date: Mon, 30 Nov 2020 16:05:55 -0500 Subject: [PATCH 091/108] Bug fixes. --- login.html | 16 ---------------- login.js | 2 +- profile.js | 5 +++++ 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/login.html b/login.html index 4403227..2c19957 100644 --- a/login.html +++ b/login.html @@ -70,28 +70,12 @@
      -
      - - -

      -
      - - diff --git a/login.js b/login.js index c1b2305..74ec96e 100644 --- a/login.js +++ b/login.js @@ -139,7 +139,7 @@ function validateForm() { alert("Email must be filled out"); return false; } - if (document.getElementById("input_password").value == "") { + if (document.getElementById("input_user-pass").value == "") { alert("Password must be filled out"); return false; } diff --git a/profile.js b/profile.js index f372b87..5fefcd9 100644 --- a/profile.js +++ b/profile.js @@ -172,6 +172,11 @@ function newGroup() { function generateGroupList() { + const groupList = document.getElementById('group-list') + while (groupList.firstChild) { + groupList.removeChild(groupList.firstChild); + } + getGroupList().then(ret => { console.log(ret); console.log(ret['status']); From 6c6036b482c31437866edc430773cc4b881f4f53 Mon Sep 17 00:00:00 2001 From: SebTota Date: Mon, 30 Nov 2020 20:48:46 -0500 Subject: [PATCH 092/108] Change group name in url params. --- group.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/group.js b/group.js index e4954a5..f69772f 100644 --- a/group.js +++ b/group.js @@ -73,11 +73,26 @@ function expandTextarea(element) { element.style.height = element.scrollHeight + "px"; } +function changeUrlVar(param, newVal) { + let url = window.location.href; + const urlParams = window.location.href.split("?")[1].split("&"); + for (let i = 0; i < urlParams.length; i++) { + console.log(urlParams[i]); + console.log(urlParams[i].split("=")[0]); + if (urlParams[i].split("=")[0] === param) { + console.log("Chaning"); + url = url.replace(urlParams[i], urlParams[i].split("=")[0] + "=" + newVal); + location.href = url; + } + } +} + function renameGroup(newName) { createRequest('/renameGroup','POST', { 'group-uuid': groupUuid, 'new-name': newName }).then(ret => { + changeUrlVar('group-name', newName); console.log("Changed name"); console.log(ret); }) From 566333d02492559d0cde1ae71dfcdd0604ffd875 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Mon, 30 Nov 2020 23:15:21 -0500 Subject: [PATCH 093/108] Editing item --- group.js | 148 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 114 insertions(+), 34 deletions(-) diff --git a/group.js b/group.js index f69772f..a2902eb 100644 --- a/group.js +++ b/group.js @@ -6,6 +6,8 @@ const groupUuid = urlParams.get('group-uuid'); let listUuid; let listCount; +let selectedItem; +let elementUuid; if (getCookie('active') === 'true') { // Signed in @@ -73,26 +75,11 @@ function expandTextarea(element) { element.style.height = element.scrollHeight + "px"; } -function changeUrlVar(param, newVal) { - let url = window.location.href; - const urlParams = window.location.href.split("?")[1].split("&"); - for (let i = 0; i < urlParams.length; i++) { - console.log(urlParams[i]); - console.log(urlParams[i].split("=")[0]); - if (urlParams[i].split("=")[0] === param) { - console.log("Chaning"); - url = url.replace(urlParams[i], urlParams[i].split("=")[0] + "=" + newVal); - location.href = url; - } - } -} - function renameGroup(newName) { createRequest('/renameGroup','POST', { 'group-uuid': groupUuid, 'new-name': newName }).then(ret => { - changeUrlVar('group-name', newName); console.log("Changed name"); console.log(ret); }) @@ -173,7 +160,7 @@ function createListItem(item) { //get the div id for the table we are currently rendering function getTableDivId(num){ - switch(num) { + switch(num) { case num = 0: return "#data-table1" case num = 1: @@ -206,6 +193,7 @@ async function newItemPost(data) { function addNewItem(){ newItemPost({ 'list-id' : document.getElementById('list-id').value, + 'element-name' : document.getElementById('input_user-item-name').value, 'element-description' : document.getElementById('input_user-item-description').value, 'element-quantity' : document.getElementById('input_user-item-quantity').value, @@ -258,13 +246,89 @@ function deleteList(){ }); } +//db delete Item +async function deleteItemPost() { + console.log("250 " + elementUuid); + const response = await fetch(serverAddress + '/deleteElementFromList?element-uuid=' +elementUuid, { + method: 'POST', + credentials: 'include', + redirect: 'follow', + }); + // Wait for response from server, then parse the body of the response in json format + return await response.json(); +} + +//deleteItem +function deleteItem(elementId){ + deleteItemPost({ + "element-uuid" : elementId + }).then(ret => { + if (ret['status'] === 400) { + } + else{ + } + }); +} + +//db edit item +async function editItemPost(data) { + console.log(data); + const response = await fetch(serverAddress + '/addElementToList', { + method: 'POST', + credentials: 'include', + redirect: 'follow', + body: JSON.stringify(data) + }); + // Wait for response from server, then parse the body of the response in json format + return await response.json(); +} + +//editing item +function editItem(){ + console.log(291); + newItemPost({ + 'list-id' : document.getElementById('edit-list-id').value, + + 'element-name' : document.getElementById("edit-item-name").value, + 'element-description' : document.getElementById('edit-item-description').value, + 'element-quantity' : document.getElementById("edit-item-quantity").value, + 'element_cost': document.getElementById('edit-item-cost').value, + 'element-user-id' : 100, + 'element_status': document.getElementById('edit-item-status').value + + }).then(ret => { + if (ret['status'] === 400) { + } + else{ + console.log("305 " + selectedItem[6]); + deleteItem(selectedItem[6]); + window.location.reload(true); + } + }); +} + + + +//show modal to edit selected item +function editItemModal(listId, elementId){ + document.getElementById('edit-list-id').value = listId; + + document.getElementById("edit-item-name").value = selectedItem[1]; + document.getElementById("edit-item-quantity").value = selectedItem[2]; + document.getElementById("edit-item-cost").value = selectedItem[3]; + document.getElementById("edit-item-description").value = selectedItem[4]; + document.getElementById("edit-item-status").value = selectedItem[5]; + + document.getElementById( "edit-element-id").value = selectedItem[6]; + $("#edit-item-modal").modal('show'); +} + //show modal to confirm list deletion function deleteListModal(listId){ document.getElementById('list-uuid').value = listId; $('#modal_delete_list').modal('show'); } - //render a single table function renderTable(tableDivId, temp, listId, listUuid){ getElements().then(ret => { @@ -279,7 +343,7 @@ function renderTable(tableDivId, temp, listId, listUuid){ let dataSet = []; for (let i = 0; i < elements.length; i++) { - dataSet.push([0, elements[i]['item-name'], elements[i]['item-quantity'], elements[i]['item-cost'], elements[i]['item-description'], elements[i]['item-status'], '']); + dataSet.push([0, elements[i]['item-name'], elements[i]['item-quantity'], elements[i]['item-cost'], elements[i]['item-description'], elements[i]['item-status'], elements[i]["item-uuid"]]); console.log(dataSet); } @@ -289,18 +353,21 @@ function renderTable(tableDivId, temp, listId, listUuid){ $(document).ready(function () { - $('#tableDivId').on('click', 'a.editor_remove', function (e) { - e.preventDefault(); + /* $('#tableDivId').on('click', 'a.editor_remove', function (e) { + e.preventDefault(); - editor.remove( $(this).closest('tr'), { - title: 'Delete record', - message: 'Are you sure you wish to remove this record?', - buttons: 'Delete' - } ); - } ); + editor.remove( $(this).closest('tr'), { + title: 'Delete record', + message: 'Are you sure you wish to remove this record?', + buttons: 'Delete' + } ); + } );*/ $(tableDivId).DataTable({ data: dataSet, + select: { + style: 'single' + }, 'columnDefs': [{ 'targets': 0, "width": "20%", @@ -319,14 +386,14 @@ function renderTable(tableDivId, temp, listId, listUuid){ {title: "Quantity", width: '100px'}, {title: "Price", width: '100px'}, {title: "Description", width: '200px'}, - {title: "Status", width: '70px'}, - {title: "Action"} + {title: "Bought (T/F)", width: '70px'}, + { "visible": false, "targets": 6 } ], - /* "initComplete": function(oSettings) { - $(this).on('click', "i.fa.fa-minus-square", function(e) { - table.row( $(this).closest('tr') ).remove().draw(); - }); - },*/ + /* "initComplete": function(oSettings) { + $(this).on('click', "i.fa.fa-minus-square", function(e) { + table.row( $(this).closest('tr') ).remove().draw(); + }); + },*/ dom: 'Bfrtip', buttons: [ { @@ -336,11 +403,23 @@ function renderTable(tableDivId, temp, listId, listUuid){ addItemModal(listId); } }, + { + text: 'Edit selected item', + action: function ( e, dt, node, config ) { + selectedItem = $.map(this.row('.selected').data(), function (item) { + console.log("Item " + item); + return item + }); + elementUuid = selectedItem[6]; + editItemModal(listId, selectedItem[6]); + this.row('.selected').remove().draw( false ); + } + }, { text: 'Delete List', action: function ( e, dt, node, config ) { //alert( 'Button activated' ); - deleteListModal(listUuid); + deleteListModal(listId, selectedItem[6]); } } ] @@ -378,3 +457,4 @@ $( document ).ready(function() { }); + From 8021fbe1fa5e77cbf5d4c3c00bd076886f7dbb92 Mon Sep 17 00:00:00 2001 From: Ryan O'Connor Date: Mon, 30 Nov 2020 23:15:32 -0500 Subject: [PATCH 094/108] Editing item html --- group.html | 64 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/group.html b/group.html index 37b924e..43427fe 100644 --- a/group.html +++ b/group.html @@ -19,6 +19,7 @@ + @@ -70,7 +71,7 @@
      - +

      @@ -148,23 +149,23 @@
      - +
      + - - - +