diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..9c6b59de40102169eddd43cd29661877f83d3745 --- /dev/null +++ b/readme.txt @@ -0,0 +1,10 @@ +Instructions on running the ServicePoints website: +1) clone the git repo +2) navigate into the servicePoints folder on terminal +3) run "source env/bin/activate" +4) run "bin/servicePointsRun" +5) in a browser, navigate to "http://localhost:8000/" +6) you should be able to user servicePoints from here + +If anything goes wrong in your testing process +or you have any questions reach out at aebopp@umich.edu \ No newline at end of file diff --git a/servicePoints/templates/create.html b/servicePoints/templates/create.html index a6ad121a28229cd1b45e97a4004b08717e77efa0..efc879f34a3b87983da69212c280edbbf1b22013 100644 --- a/servicePoints/templates/create.html +++ b/servicePoints/templates/create.html @@ -6,14 +6,19 @@ Want to register an organization with your new account account? <a href="/accounts/createOrg/">Register as organization leader</a> </p> - +<p> + Once you select an organization to join, a request will be sent for approval. + Until approved, your organization will appear as 'None.' +</p> <form action="/accounts/create/" method="post" enctype="multipart/form-data"> <p> <label for="orgName">Select an Organization:</label> <select name="orgName" id="orgName"> <option value="NONE">Choose Later</option> {% for org in orgs %} + {% if org.orgName != 'NONE' %} <option value="{{org.orgName}}">{{org.orgName}}</option> + {%endif%} {% endfor %} </select> </p> diff --git a/servicePoints/templates/manageOrg.html b/servicePoints/templates/manageOrg.html index ba47d52c0abbcd78958c81c7b4c837c2d7d73847..a74df24b5ff1204af2e1bae34974d1d4164f2a7e 100644 --- a/servicePoints/templates/manageOrg.html +++ b/servicePoints/templates/manageOrg.html @@ -16,6 +16,26 @@ <input type="submit" name="delete" value="delete your student org"/> </form> </p> + <p> + Pending Member Requests: + </p> + {% for member in pending %} + <p> + <form action="/accounts/manageOrg/" method="post" enctype="multipart/form-data"> + Name: {{member.fullname}} + <br>Username: {{member.username}} + <br>Email: {{member.email}} + <br>Pre-Existing Hours: {{member.hours}} + <input type="hidden" name="user" value="{{member.username}}"/> + <input type="submit" name="add" value="Add Member"/> + <input type="submit" name="deny" value="Deny Member"/> + </form> + </p> + {% endfor %} + + <p> + Current Members: + </p> {% for member in members %} {% if username == member.username %} {{member.fullname}} ({{member.username}}) diff --git a/servicePoints/templates/userProfile.html b/servicePoints/templates/userProfile.html index c3a0c83ca90bc23239cfa3392c1cc77ae1145841..fc2eae66552251b79d52ffe8970d4c34eb3b7498 100644 --- a/servicePoints/templates/userProfile.html +++ b/servicePoints/templates/userProfile.html @@ -5,23 +5,68 @@ <title>Profile</title> <a href="/">Home</a> + <a href="/accounts/logout/" style="float: right;">logout</a> </head> <body> <h1 style="text-align:center">Profile</h1> - <a href="/accounts/logout/">logout</a> - <a href="/accounts/delete/">delete</a> + <p> + Full Name: {{fullname}} + </p> + {% if pending == 0 %} + <p> + Student Organization: {{org}} + </p> + {%endif%} + {% if pending == 1 %} + <p> + Student Organization: Your request is pending. Requesting to join another organization while your request is pending will cancel your original request. + </p> + {%endif%} + </p> + <p> + Email: {{email}} + </p> + <a href="/accounts/delete/">delete account</a> + + {% if leader == 0 %} <form action="/accounts/profile/" method="post"> <p> <label for="orgName">Select an Organization:</label> <select name="orgName" id="orgName"> {% for org in orgs %} + {% if org.orgName != 'NONE' %} <option value="{{org.orgName}}">{{org.orgName}}</option> + {%endif%} {% endfor %} </select> - </p> <input type="submit" name="signup" value="Update Org" /> + </p> + </form> + <form action="/accounts/profile/" method="post"> + <p> + <input type="submit" name="noOrg" value="Leave Organization Without Joining Another" /> + </p> +</form> + {% endif %} + + <form action="/accounts/profile/" method="post"> + <p> + Change your full name: + <input type="text" name="fullname" /> + <input type="submit" name="fullname" value="Change Full Name" /> + </p> + + </form> + + <form action="/accounts/profile/" method="post"> + <p> + Change your email: + <input type="text" name="email" /> + <input type="submit" name="email" value="Change Email" /> + </p> + </form> </body> diff --git a/servicePoints/views/__pycache__/accounts.cpython-36.pyc b/servicePoints/views/__pycache__/accounts.cpython-36.pyc index e717c9c740dd3fc38e388768906081600b17fd87..13c2c31e5423a4b2afbad9734437419e5b288607 100644 Binary files a/servicePoints/views/__pycache__/accounts.cpython-36.pyc and b/servicePoints/views/__pycache__/accounts.cpython-36.pyc differ diff --git a/servicePoints/views/accounts.py b/servicePoints/views/accounts.py index 08b955ff19a6642f162bf90eb08d6ce7743f3885..85ebb15dc22d320d3220b8c97d6e93401ea827e5 100644 --- a/servicePoints/views/accounts.py +++ b/servicePoints/views/accounts.py @@ -66,6 +66,13 @@ def create(): if cursor.fetchone() is not None or name == "pending": return flask.redirect(flask.url_for('duplicateUsername', prev='create')) + + if len(str(flask.request.form['password'])) is 0 or len(str(flask.request.form['fullname'])) is 0: + return flask.redirect(flask.url_for('incompleteForm', prev="create")) + + if len(str(flask.request.form['username'])) is 0 or len(str(flask.request.form['email'])) is 0: + return flask.redirect(flask.url_for('incompleteForm', prev="create")) + cursor.execute('SELECT * FROM orgs WHERE orgName=?', to_join) if cursor.fetchone() is None: if orgName == "NONE": @@ -75,12 +82,6 @@ def create(): else: return flask.redirect(flask.url_for('orgNotFound')) - if len(str(flask.request.form['password'])) is 0 or len(str(flask.request.form['fullname'])) is 0: - return flask.redirect(flask.url_for('incompleteForm', prev="create")) - - if len(str(flask.request.form['username'])) is 0 or len(str(flask.request.form['email'])) is 0: - return flask.redirect(flask.url_for('incompleteForm', prev="create")) - flask.session['username'] = flask.request.form['username'] flask.session['fullname'] = flask.request.form['fullname'] flask.session['orgName'] = flask.request.form['orgName'] @@ -89,11 +90,15 @@ def create(): pw = hash_pass(flask.session['password']) data = (flask.session['username'], flask.session['fullname'], - flask.session['email'], flask.session['orgName'], + flask.session['email'], 'NONE', pw, 0) + pendingData = (flask.session['username'], flask.session['fullname'], + flask.session['email'], flask.session['orgName'], 0) cur = servicePoints.model.get_db() cur.execute("INSERT INTO users(username, fullname, email, orgName, " "password, hours) VALUES (?, ?, ?, ?, ?, ?)", data) + cur.execute("INSERT INTO pendingOrgs(username, fullname, email, orgName, " + "hours) VALUES (?, ?, ?, ?, ?)", pendingData) return flask.redirect(flask.url_for('index')) @@ -343,28 +348,82 @@ def food(): def profile(): if flask.request.method == 'POST': - orgName = str(flask.request.form['orgName']) - username = str(flask.session['username']) - cur = servicePoints.model.get_db() - curOrg = cur.execute('SELECT orgName FROM users WHERE username = ?', - (username,)) - org = curOrg.fetchone() - cur.execute('UPDATE users SET orgName = ? WHERE username = ?', - (orgName, username,)) - if org == "NONE": - cur.execute('DELETE from orgs WHERE username = ?', + if 'orgName' in flask.request.form: + orgName = str(flask.request.form['orgName']) + username = str(flask.session['username']) + cur = servicePoints.model.get_db() + curOrg = cur.execute('SELECT orgName FROM users WHERE username = ?', (username,)) - leadercur = cur.execute('SELECT username from orgs WHERE orgName = ?', - (orgName,)) - leader = leadercur.fetchone() - cur.execute('UPDATE requests SET leader = ? WHERE member = ?', - (leader["username"], username,)) - return flask.redirect(flask.url_for('index')) + org = curOrg.fetchone() + curOrg = cur.execute('SELECT fullname, email, hours FROM users WHERE username = ?', + (username,)) + userInfo = curOrg.fetchone() + pendingData = (flask.session['username'], userInfo['fullname'], + userInfo['email'], orgName, userInfo['hours']) + cursor = cur.execute('SELECT * FROM pendingOrgs WHERE username =:who', {"who": username}) + tryfetch = cursor.fetchone() + if tryfetch is not None: + cur.execute("DELETE from pendingOrgs WHERE username = ?", (username,)) + cur.execute("INSERT INTO pendingOrgs(username, fullname, email, orgName, " + "hours) VALUES (?, ?, ?, ?, ?)", pendingData) + if org == "NONE": + cur.execute('DELETE from orgs WHERE username = ?', + (username,)) + leadercur = cur.execute('SELECT username from orgs WHERE orgName = ?', + (orgName,)) + leader = leadercur.fetchone() + cur.execute('UPDATE requests SET leader = ? WHERE member = ?', + (leader["username"], username,)) + elif 'noOrg' in flask.request.form: + username = str(flask.session['username']) + cur = servicePoints.model.get_db() + cursor = cur.execute('SELECT * FROM pendingOrgs WHERE username =:who', {"who": username}) + tryfetch = cursor.fetchone() + if tryfetch is not None: + cur.execute("DELETE from pendingOrgs WHERE username = ?", (username,)) + cur.execute("UPDATE users SET orgName = 'NONE' WHERE username = ?", + (username,)) + cur.execute("UPDATE requests SET leader = 'pending' WHERE member = ?", + (username,)) + elif 'fullname' in flask.request.form: + fullName = str(flask.request.form['fullname']) + username = str(flask.session['username']) + cur = servicePoints.model.get_db() + cur.execute('UPDATE users SET fullname = ? WHERE username = ?', + (fullName, username,)) + elif 'email' in flask.request.form: + email = str(flask.request.form['email']) + username = str(flask.session['username']) + cur = servicePoints.model.get_db() + cur.execute('UPDATE users SET email = ? WHERE username = ?', + (email, username,)) cursor = servicePoints.model.get_db() cur = cursor.execute("SELECT * FROM orgs") + username = flask.session['username'] orgs = cur.fetchall() - context = {"orgs": orgs} + cur = cursor.execute("SELECT fullname, email, orgName from users WHERE username = ?", (username,)) + user = cur.fetchone() + studentOrgCur = cursor.execute('SELECT orgName, hours FROM users WHERE ' + 'username =:who', + {"who": username}) + results = studentOrgCur.fetchone() + leaderCur = cursor.execute('SELECT orgName FROM orgs WHERE ' + 'username =:who', + {"who": username}) + tryfetch = leaderCur.fetchone() + if tryfetch is None or tryfetch["orgName"] == "NONE": + leader = 0 + else: + leader = 1 + cur = cursor.execute('SELECT * FROM pendingOrgs WHERE username =:who', {"who": username}) + tryfetch = cur.fetchone() + if tryfetch is None: + pending = 0 + else: + pending = 1 + context = {"orgs": orgs, "fullname": user["fullname"], "email": user["email"], + "org": user["orgName"], "leader": leader, "pending": pending} return render_template('userProfile.html', **context) @servicePoints.app.route('/images/<path:filename>', methods=['GET', 'POST']) @@ -492,9 +551,36 @@ def manageOrg(): username = flask.session["username"] if flask.request.method == 'POST': if 'delete' in flask.request.form: - return flask.redirect(flask.url_for('confirmDeleteOrg')) + cursor = servicePoints.model.get_db() + leaderCur = cursor.execute('SELECT orgName FROM orgs WHERE ' + 'username =:who', + {"who": username}) + results = leaderCur.fetchone() + orgName = results["orgName"] + cursor.execute("DELETE from orgs WHERE orgName = ?", (orgName,)) + cursor.execute("UPDATE users SET orgName = 'NONE' WHERE orgName = ?", (orgName,)) + cursor.execute("UPDATE requests SET leader = 'pending' WHERE leader = ?", + (username,)) + return flask.redirect(flask.url_for('index')) + if 'add' in flask.request.form: + cursor = servicePoints.model.get_db() + leaderCur = cursor.execute('SELECT orgName FROM orgs WHERE ' + 'username =:who', + {"who": username}) + results = leaderCur.fetchone() + orgName = results["orgName"] + cursor.execute("DELETE from pendingOrgs WHERE username = ?", (flask.request.form["user"],)) + cursor.execute('UPDATE users SET orgName = ? WHERE username = ? ', (orgName, flask.request.form["user"],)) + cursor.execute("UPDATE requests SET leader = ? WHERE member = ?", + (username, flask.request.form["user"],)) + if 'deny' in flask.request.form: + cursor = servicePoints.model.get_db() + cursor.execute("DELETE from pendingOrgs WHERE username = ?", (flask.request.form["user"],)) if 'remove' in flask.request.form: - return flask.redirect(flask.url_for('confirmRemoveMember')) + cursor = servicePoints.model.get_db() + cursor.execute("UPDATE users SET orgName = 'NONE' WHERE username = ? ", (flask.request.form["user"],)) + cursor.execute("UPDATE requests SET leader = 'pending' WHERE member = ?", + (flask.request.form["user"],)) cursor = servicePoints.model.get_db() leaderCur = cursor.execute('SELECT orgName FROM orgs WHERE ' 'username =:who', @@ -503,7 +589,11 @@ def manageOrg(): orgName = results["orgName"] membersCur = cursor.execute('SELECT username, fullname FROM users WHERE orgname =:who', {"who": orgName}) members = membersCur.fetchall() - context = {'org': orgName, 'members': members, 'username': username} + pendingCur = cursor.execute('SELECT username, fullname, email, hours FROM pendingOrgs WHERE ' + 'orgName =:who', + {"who": orgName}) + pending = pendingCur.fetchall() + context = {'org': orgName, 'members': members, 'username': username, 'pending': pending} return render_template('manageOrg.html', **context) return flask.redirect(flask.url_for('login')) diff --git a/sql/schema.sql b/sql/schema.sql index 540be41e3f075f6619d20ff958047e370134d7b2..e651dbf85f88a03f65bb275fd670530d2b1ca338 100644 --- a/sql/schema.sql +++ b/sql/schema.sql @@ -16,11 +16,24 @@ CREATE TABLE orgs( PRIMARY KEY(orgName) ); +CREATE TABLE pendingOrgs( + username VARCHAR(20) NOT NULL, + fullname VARCHAR(40) NOT NULL, + email VARCHAR(40) NOT NULL, + orgName VARCHAR(40) NOT NULL, + hours INTEGER NOT NULL, + PRIMARY KEY(username) + FOREIGN KEY(username) REFERENCES users(username) ON UPDATE CASCADE + ON DELETE CASCADE +); + CREATE TABLE tutors( username VARCHAR(20) NOT NULL, subject VARCHAR(40) NOT NULL, time VARCHAR(80) NOT NULL, PRIMARY KEY(username) + FOREIGN KEY(username) REFERENCES users(username) ON UPDATE CASCADE + ON DELETE CASCADE ); CREATE TABLE requests( diff --git a/var/images/c0cf17efda2368530bb66b4e2fb68456865edbbdaa67c99783de324711384437.jpg b/var/images/c0cf17efda2368530bb66b4e2fb68456865edbbdaa67c99783de324711384437.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b7f849e6e752e3a8331fe22bb1261a55ce6965e8 Binary files /dev/null and b/var/images/c0cf17efda2368530bb66b4e2fb68456865edbbdaa67c99783de324711384437.jpg differ diff --git a/var/images/e7f4305f380d8eadfe6640bced697c42bb582eee646155db4b795aa98cc87410.png b/var/images/e7f4305f380d8eadfe6640bced697c42bb582eee646155db4b795aa98cc87410.png new file mode 100644 index 0000000000000000000000000000000000000000..48a0421a993a9b49e185ae0e18bd31aaa4f6088a Binary files /dev/null and b/var/images/e7f4305f380d8eadfe6640bced697c42bb582eee646155db4b795aa98cc87410.png differ diff --git a/var/servicePoints.sqlite3 b/var/servicePoints.sqlite3 index bf426cb1ca7b04a0d73fa1d08fcf065e2379ac4e..6783b9ce0615ff90dab41579c79b0393d4f22b88 100644 Binary files a/var/servicePoints.sqlite3 and b/var/servicePoints.sqlite3 differ