diff --git a/image.png b/image.png deleted file mode 100644 index 1a1237d..0000000 Binary files a/image.png and /dev/null differ diff --git a/location_app/app/functions/auth/base.py b/location_app/app/functions/auth/base.py index 494fcab..412809d 100644 --- a/location_app/app/functions/auth/base.py +++ b/location_app/app/functions/auth/base.py @@ -1,57 +1,87 @@ import sqlite3 as sql from datetime import datetime -"""Validation for fields""" -database_user = "app/databases/users.db" # Taking the databases -database_locations = 'app/databases/locations.db' +database_user = "app/databases/users.db" +database_locations = "app/databases/locations.db" + def create(): + """ + Creates a user database if it doesn't exist + """ with sql.connect(database_user) as cur: - try: # Tries the sql table - cur.execute("CREATE TABLE UserDatabase(username VARCHAR2(20), password VARCHAR2(20), realname VARCHAR2(20), dob VARCHAR2(20), weight VARCHAR2(20));") + try: + cur.execute(""" + CREATE TABLE UserDatabase(username VARCHAR2(20), + password VARCHAR2(20), + realname VARCHAR2(20), + dob VARCHAR2(20), + color VARCHAR2(20), + weight VARCHAR2(20)); + """) except: pass - -def user_exists(username): # Checks for username + +def user_exists(username): + """ + Returns true or false depending on if the user exists + """ with sql.connect(database_user) as cur: - com = f"SELECT count(*) FROM UserDatabase WHERE username='{username}';" - print(com) - res = cur.execute(com).fetchone()[0] - if res == 0: + res = cur.execute(f""" + SELECT count(*) + FROM UserDatabase + WHERE username='{username}'; + """) + if res.fetchone()[0] == 0: return False else: return True -def tid_exists(username): # Checks for tid +def tid_exists(username): + """ + Returns true or false depending on if there is any data + for that username in the database + """ with sql.connect(database_locations) as cur: - com = f"SELECT count(*) FROM Location WHERE tid='{username}';" - print(com) - res = cur.execute(com).fetchone()[0] - if res == 0: + res = cur.execute(f""" + SELECT count(*) + FROM Location + WHERE tid='{username}'; + """) + if res.fetchone()[0] == 0: return False else: return True -def compare(username, value_in, value_type): # Comparing +def compare(username, value_in, value_type): + """ + Takes in username, value and type and checks if they match with + the ones already saved in the database + """ with sql.connect(database_user) as cur: - com = f"SELECT {value_type} FROM UserDatabase WHERE username='{username}';" - print(com) - res = cur.execute(com).fetchone()[0] - print(f"comparing - {value_in} == {res}") - if value_in == res: + res = cur.execute(f""" + SELECT {value_type} + FROM UserDatabase + WHERE username='{username}'; + """) + if value_in == res.fetchone()[0]: return True else: return False - -def check_month(month, day): # Checks the month and day + +def check_month(month, day): + """ + Takes in month and day and checks if the day + is valid for that month + """ if month in [1, 3, 5, 7, 8, 10, 12]: if (day > 0 and day <= 31): return True else: return False elif month == 2: - if (day > 0 and day <= 28): # Checking February + if (day > 0 and day <= 28): return True else: return False @@ -61,7 +91,12 @@ def check_month(month, day): # Ch else: return False -def check_date(day, month, year): # Checks full date + +def check_date(day, month, year): + """ + Takes in a date and checks if it's in the future and then calls + check_month to see if the month/day are valid + """ today = datetime.today().strftime('%Y-%m-%d').split("-") if int(year) > int(today[0]): return False diff --git a/location_app/app/functions/auth/change_password.py b/location_app/app/functions/auth/change_password.py index 107a648..900ce4d 100644 --- a/location_app/app/functions/auth/change_password.py +++ b/location_app/app/functions/auth/change_password.py @@ -1,17 +1,25 @@ import sqlite3 as sql -from app.functions.auth import base # Imports base for later use +from app.functions.auth import base database_user = "app/databases/users.db" -def change_password(data): # Changing password + +def change_password(data): + """ + Function to allow password change + """ base.create() _status = check_pass_data(data) if _status == "success": - new_password(data) + update_password(data) return _status - -def check_pass_data(data): # Checking password data + + +def check_pass_data(data): + """ + Function to check password data is valid + """ _status = check_empty(data) if _status == "ok": if base.tid_exists(data['username']): @@ -26,7 +34,11 @@ def check_pass_data(data): # Checki return _status -def check_empty(data): # Checks the entry to see if empty + +def check_empty(data): + """ + Function to if the fields are empty + """ if data['username'] == "": return "empty_id" elif data['day'] == "0": @@ -42,12 +54,19 @@ def check_empty(data): # Checks else: return "ok" -def new_password(data): # Updates database with new password + + +def update_password(data): + """ + Function to update new password in the database + """ con = sql.connect(database_user) cur = con.cursor() - com = f"UPDATE UserDatabase SET password='{data['password']}' WHERE username='{data['username']}';" - print(com) - cur.execute(com) + cur.execute(f""" + UPDATE UserDatabase + SET password='{data['password']}' + WHERE username='{data['username']}'; + """) con.commit() cur.close() con.close() \ No newline at end of file diff --git a/location_app/app/functions/auth/create_profile.py b/location_app/app/functions/auth/create_profile.py index 7b925c5..54d63f5 100644 --- a/location_app/app/functions/auth/create_profile.py +++ b/location_app/app/functions/auth/create_profile.py @@ -1,25 +1,34 @@ -import sqlite3 as sql # Imports sql for use within database +import sqlite3 as sql from app.functions.auth import base database_user = "app/databases/users.db" -def create_profile(data): # Creating new data for a new user + +def create_profile(data): + """ + Function to create new profile + """ base.create() _status = check_prof_data(data) if _status == "success": make_user(data) return _status - -def check_prof_data(data): # Checking new - print(data) + + +def check_prof_data(data): + """ + Function to the validity of profile data + """ _status = check_empty(data) if _status == "ok": if base.tid_exists(data['username']): if not base.user_exists(data['username']): if not (data['password'] == data['r_password']): return "pass_no_match" - elif not base.check_date(data['day'], data['month'], data['year']): + elif not base.check_date(data['day'], + data['month'], + data['year']): return "wrong_date" else: return "success" @@ -29,7 +38,11 @@ def check_prof_data(data): # Ch return "no_id" return _status + def check_empty(data): + """ + Function to check if the fields are filled + """ if data['username'] == "": return "empty_id" elif data['realname'] == "": @@ -49,13 +62,24 @@ def check_empty(data): else: return "ok" + + def make_user(data): + """ + Function to add new user to the database + """ con = sql.connect(database_user) cur = con.cursor() _date = f"{data['day']}-{data['month']}-{data['year']}" - com = f"INSERT INTO UserDatabase values('{data['username']}','{data['password']}','{data['realname']}','{_date}','{data['weight']}');" - print(com) - cur.execute(com) + cur.execute(f""" + INSERT INTO UserDatabase + values('{data['username']}', + '{data['password']}', + '{data['realname']}', + '{_date}', + '{data['color']}', + '{data['weight']}'); + """) con.commit() cur.close() con.close() \ No newline at end of file diff --git a/location_app/app/functions/auth/login.py b/location_app/app/functions/auth/login.py index 067858e..933b71f 100644 --- a/location_app/app/functions/auth/login.py +++ b/location_app/app/functions/auth/login.py @@ -3,24 +3,38 @@ from app.functions.auth import base def login(data): + """ + Function to start to start the login + """ base.create() l_status = check_login_data(data) return l_status + + def check_login_data(data): + """ + Function to check the login data + """ _status = check_empty(data) if _status == "ok": if data['username'] == "admin": return "success" if not base.user_exists(data['username']): return "no_id" - if not base.compare(data['username'], data['password'], "password"): + if not base.compare(data['username'], + data['password'], + "password"): return "wrong_pass" return "success" else: return _status + def check_empty(data): + """ + Function to check whether the fields are filled + """ if data['username'] == "": return "empty_id" elif data['password'] == "": diff --git a/location_app/app/functions/data_tools/data_getter.py b/location_app/app/functions/data_tools/data_getter.py index 128e11e..7467641 100644 --- a/location_app/app/functions/data_tools/data_getter.py +++ b/location_app/app/functions/data_tools/data_getter.py @@ -2,34 +2,72 @@ import sqlite3 as sql import time -database_user = "app/databases/users.db" # Grabs the database +database_user = "app/databases/users.db" database_locations = "app/databases/locations.db" - # user -def get_user_for(username): +def get_user_for(username): + """ + Returns data from the database for the specified username + """ with sql.connect(database_user) as cur: - res = cur.execute(f"SELECT username, realname, dob, weight FROM UserDatabase WHERE username='{username}';").fetchone() - return [res, get_filtered_data_for(username)] # Returns required data - + res = cur.execute(f""" + SELECT username, realname, dob, color, weight + FROM UserDatabase + WHERE username='{username}'; + """) + user_data = res.fetchone() + return [user_data, get_filtered_data_for(username)] + +def update_data_for(username, data): + """ + Updates color and weight for the specified user + """ + con = sql.connect(database_user) + cur = con.cursor() + cur.execute(f""" + UPDATE UserDatabase + SET color = '{data['color']}', weight = '{data['weight']}' + WHERE username='{username}'; + """) + con.commit() + cur.close() + con.close() - # freq def get_all_tids(): + """ + Returns a list of all unique id's + """ with sql.connect(database_locations) as cur: - tids = cur.execute("SELECT DISTINCT tid From Location;") + tids = cur.execute(""" + SELECT DISTINCT tid + From Location; + """) tids_list = list(map(lambda x: x[0], tids)) return tids_list + def get_frequency_for(data_type, tid): + """ + Goes through a column and finds a value that is repeating + the most times and returns it with the percentage + """ with sql.connect(database_locations) as cur: - data = cur.execute(f"SELECT {data_type} From Location WHERE tid = '{tid}';") + data = cur.execute(f""" + SELECT {data_type} + From Location + WHERE tid = '{tid}'; + """) data_list = list(map(lambda x: x[0], data)) frequent_data = max(set(data_list), key = data_list.count) - frequency_data = str(int((data_list.count(frequent_data)/len(data_list)) * 100)) - return [frequent_data, frequency_data] - + frequency_data = data_list.count(frequent_data) / len(data_list) + return [frequent_data, int(frequency_data * 100)] + def get_filtered_data_for(tid): + """ + Gets frequencies for most visited road and city + """ data_city = get_frequency_for('city', tid) data_road = get_frequency_for('road', tid) return [data_city, data_road] @@ -37,12 +75,26 @@ def get_filtered_data_for(tid): # main def get_locations_for(username): + """ + Returns a full detailed list of all location entries for + the specified username, if the username is admin then it + returns a list of all location entries + """ locations = [] with sql.connect(database_locations) as cur: if username == 'admin': - res = cur.execute(f"SELECT DISTINCT * From Location ORDER BY tid, tst DESC;") + res = cur.execute(f""" + SELECT DISTINCT * + From Location + ORDER BY tid, tst DESC; + """) else: - res = cur.execute(f"SELECT DISTINCT * From Location WHERE tid='{username}' ORDER BY tst DESC;") + res = cur.execute(f""" + SELECT DISTINCT * + From Location + WHERE tid='{username}' + ORDER BY tst DESC; + """) for tid, lon, lat, city, road, _date, _time, tst, in res: locations.append([tid, lon, lat, city, road, _date, _time]) return locations @@ -50,23 +102,60 @@ def get_locations_for(username): # map def get_weight_for(username): + """ + Returns weight for the specified username + """ + with sql.connect(database_user) as cur: + res = cur.execute(f""" + SELECT weight + From UserDatabase + WHERE username='{username}'; + """) + _weight = res.fetchone()[0] + return int(_weight) + +def get_color_for(username): + """ + Returns hex code color for the specified username + """ with sql.connect(database_user) as cur: - res = cur.execute(f"SELECT weight From UserDatabase WHERE username='{username}';").fetchone()[0] - return int(res) + res = cur.execute(f""" + SELECT color + From UserDatabase + WHERE username='{username}'; + """) + _color = res.fetchone()[0] + return _color def get_map_locations_for(username): + """ + Returns a list of all location entries for that username + and sorts them by date + """ locations = [] with sql.connect(database_locations) as cur: - res = cur.execute(f"SELECT DISTINCT longitude, latitude, date, time From Location WHERE tid='{username}' ORDER BY tst DESC;") + res = cur.execute(f""" + SELECT DISTINCT longitude, latitude, date, time + From Location + WHERE tid='{username}' + ORDER BY tst DESC; + """) for lon, lat, _date, _time, in res: locations.append([lon, lat, _date, _time]) return locations def get_map_location_dates(username): + """ + Returns a list of all unique dates from all location entries + """ date_list = [] with sql.connect(database_locations) as cur: - res = cur.execute(f"SELECT DISTINCT date From Location WHERE tid='{username}' ORDER BY tst DESC;") + res = cur.execute(f""" + SELECT DISTINCT date + From Location + WHERE tid='{username}' + ORDER BY tst DESC; + """) for _date, in res: date_list.append(_date) return date_list - diff --git a/location_app/app/mqtt/__init__.py b/location_app/app/mqtt/__init__.py index ba52a04..5bc0865 100644 --- a/location_app/app/mqtt/__init__.py +++ b/location_app/app/mqtt/__init__.py @@ -1,7 +1,12 @@ -from flask_mqtt import Mqtt # MQTT using flask +from flask_mqtt import Mqtt from app.mqtt import mqtt_message_handler + def init_app(app): + """ + Function to connect the mqtt to the app and setup + on connect and on message callbacks + """ mqtt = Mqtt(app) @mqtt.on_connect() diff --git a/location_app/app/mqtt/mqtt_message_handler.py b/location_app/app/mqtt/mqtt_message_handler.py index 3195779..7aa51a7 100644 --- a/location_app/app/mqtt/mqtt_message_handler.py +++ b/location_app/app/mqtt/mqtt_message_handler.py @@ -1,33 +1,51 @@ -from geopy.geocoders import Nominatim # Imports nominatim API +from geopy.geocoders import Nominatim import sqlite3 as sql import json, os, time database_locations = 'app/databases/locations.db' + def getMsg(msg): - con = sql.connect(database_locations) # connecys to db, amkes cursor + """ + Takes in a message from the mqtt and saves the data inside + a database if one exists, if not creates it + """ + con = sql.connect(database_locations) cur = con.cursor() - geolocator = Nominatim(user_agent="Web_app") # starts nominatim - try: # Tries SQL to create table - cur.execute("CREATE TABLE Location(tid VARCHAR2(2), longitude NUMBER(10,6), latitude NUMBER(10,6), city VARCHAR2(20), road VARCHAR2(30), date VARCHAR2(20), time VARCHAR2(20), tst INT(15));") + geolocator = Nominatim(user_agent = "Trackmaster") + try: + cur.execute(""" + CREATE TABLE Location(tid VARCHAR2(2), + longitude NUMBER(10,6), + latitude NUMBER(10,6), + city VARCHAR2(20), + road VARCHAR2(30), + date VARCHAR2(20), + time VARCHAR2(20), + tst INT(15)); + """) except: - pass + pass data = json.loads(msg.payload.decode("utf8")) - tid = data["tid"] - lat = data["lat"] - lon = data["lon"] location = geolocator.reverse(f"{data['lat']},{data['lon']}") - city = location.raw["address"]["city"] # Puts data into small array to be used later + city = location.raw["address"]["city"] road = location.raw["address"]["road"] tst = data["tst"] - _time = time.strftime('%H:%M:%S', time.localtime(tst))#sets time format - _date = time.strftime('%d-%m-%Y', time.localtime(tst)) - com = f"INSERT INTO Location values('{tid}','{lon}','{lat}','{city}','{road}','{_date}','{_time}','{tst}');" - print(com) - cur.execute(com) - - con.commit() # commits changes to db + _time = time.strftime("%H:%M:%S", time.localtime(tst)) + _date = time.strftime("%d-%m-%Y", time.localtime(tst)) + cur.execute(f""" + INSERT INTO Location values('{data["tid"]}', + '{data["lon"]}', + '{data["lat"]}', + '{city}', + '{road}', + '{_date}', + '{_time}', + '{tst}'); + """) + print(f"{data['tid']} -- {_date} {_time}") + con.commit() cur.close() - con.close()# # closes connection + con.close() \ No newline at end of file diff --git a/location_app/app/routes/__init__.py b/location_app/app/routes/__init__.py index 2764b46..f8accde 100644 --- a/location_app/app/routes/__init__.py +++ b/location_app/app/routes/__init__.py @@ -6,7 +6,12 @@ from .profile import prof_bl from .average import average_bl from .picture import picture_bl + def init_app(app): + """ + Registers all blueprints to the app with + the appropriate url prefix + """ app.register_blueprint(index_bl) app.register_blueprint(main_bl, url_prefix="/main") app.register_blueprint(map_bl, url_prefix="/map") diff --git a/location_app/app/routes/average.py b/location_app/app/routes/average.py index 36c22f2..0593cd1 100644 --- a/location_app/app/routes/average.py +++ b/location_app/app/routes/average.py @@ -1,10 +1,15 @@ -from flask import Blueprint, render_template, request, url_for, escape, redirect, session +from flask import (Blueprint, render_template, request, + url_for, escape, redirect, session) from app.functions.data_tools import data_getter -average_bl = Blueprint('average', __name__) +average_bl = Blueprint('average', __name__) @average_bl.route("/", methods = ["GET"]) def index(): + """ + Renders the average index page with locations from the user + """ + _locations = data_getter.get_locations_for(session['username']) return render_template("average/index.html", - locations = data_getter.get_locations_for(session['username'])) + locations = _locations) diff --git a/location_app/app/routes/index.py b/location_app/app/routes/index.py index 0b086ce..5bb5d26 100644 --- a/location_app/app/routes/index.py +++ b/location_app/app/routes/index.py @@ -1,10 +1,16 @@ from flask import Blueprint, url_for, redirect, session -index_bl = Blueprint('index', __name__) + +index_bl = Blueprint('index', __name__) @index_bl.route("/", methods = ["GET", "POST"]) def index(): + """ + If there is user data saved in cookies it goes to + the main page otherwise it will go to the login page + """ user = session.get('username') + session['advanced'] = 0 if user: return redirect(url_for('main.index')) else: diff --git a/location_app/app/routes/login.py b/location_app/app/routes/login.py index 9d61769..18a4205 100644 --- a/location_app/app/routes/login.py +++ b/location_app/app/routes/login.py @@ -1,44 +1,77 @@ -from flask import Blueprint, render_template, request, url_for, escape, redirect, session +from flask import (Blueprint, render_template, request, + url_for, redirect, session) from app.functions.auth.login import login from app.functions.auth.create_profile import create_profile from app.functions.auth.change_password import change_password from datetime import datetime -login_bl = Blueprint('login', __name__) DAYS = [i for i in range(1,32)] -MONTHS = [("January", 1), ("February", 2), ("March", 3), ("April", 4), ("May", 5), ("June", 6), ("July", 7), ("August", 8), ("September", 9), ("October", 10), ("November", 11), ("December", 12)] -YEARS = list(reversed([i for i in range(1900, (int(datetime.today().strftime('%Y')) + 1))])) +MONTHS = [("January", 1), ("February", 2), + ("March", 3), ("April", 4), + ("May", 5), ("June", 6), + ("July", 7), ("August", 8), + ("September", 9), ("October", 10), + ("November", 11), ("December", 12)] +this_year = int(datetime.today().strftime('%Y')) +YEARS = list(reversed([i for i in range(1900, this_year + 1)])) + +login_bl = Blueprint('login', __name__) @login_bl.route("/", methods = ["GET", "POST"]) def index(): + """ + Renders the login page, handles POST requests for logging in + and displays errors on the page also takes the user to the + main page after successful login + """ if request.method == "POST": _status = login(request.form) if _status == "success": session["username"] = request.form["username"] return redirect(url_for('main.index')) else: - return render_template("login/index.html", status = _status) - return render_template("login/index.html", status = "0") + return render_template("login/index.html", + status = _status) + return render_template("login/index.html", + status = "0") @login_bl.route("/create_account", methods = ["GET", "POST"]) def create_account(): + """ + Renders the login page, handles POST requests for creating + an account and displays errors on the page also takes the user + back to the login page after creating the account + """ if request.method == "POST": _status = create_profile(request.form) if _status == "success": return redirect(url_for('login.index')) else: - return render_template("login/create.html", status = _status, days = DAYS, months = MONTHS, years = YEARS) - return render_template("login/create.html", status = "0", days = DAYS, months = MONTHS, years = YEARS) + return render_template("login/create.html", + status = _status, + time = [DAYS, MONTHS, YEARS]) + return render_template("login/create.html", + status = "0", + time = [DAYS, MONTHS, YEARS]) @login_bl.route("/forgot_password", methods = ["GET", "POST"]) def forgot_password(): + """ + Renders the login page, handles POST requests + and displays errors on the page also takes the user back to + the login page after changing the password + """ if request.method == "POST": _status = change_password(request.form) if _status == "success": return redirect(url_for('login.index')) else: - return render_template("login/forgot.html", status = _status, days = DAYS, months = MONTHS, years = YEARS) - return render_template("login/forgot.html", status = "0", days = DAYS, months = MONTHS, years = YEARS) \ No newline at end of file + return render_template("login/forgot.html", + status = _status, + time = [DAYS, MONTHS, YEARS]) + return render_template("login/forgot.html", + status = "0", + time = [DAYS, MONTHS, YEARS]) \ No newline at end of file diff --git a/location_app/app/routes/main.py b/location_app/app/routes/main.py index dfaa3ec..02a3c47 100644 --- a/location_app/app/routes/main.py +++ b/location_app/app/routes/main.py @@ -1,14 +1,35 @@ -from flask import Blueprint, render_template, request, url_for, escape, redirect, session +from flask import (Blueprint, render_template, + url_for, redirect, session) from app.functions.data_tools import data_getter + main_bl = Blueprint('main', __name__) @main_bl.route("/") def index(): + """ + Renders the main page with users locations and preffered view + """ + _locations = data_getter.get_locations_for(session['username']) return render_template("main/index.html", - locations = data_getter.get_locations_for(session['username'])) + locations = _locations, + advanced = session['advanced']) + +@main_bl.route("/advanced") +def advanced(): + """ + Changes the preffered view and saves it in cookies + """ + if session['advanced'] == 0: + session['advanced'] = 1 + else: + session['advanced'] = 0 + return redirect(url_for('main.index')) @main_bl.route("/logout") def logout(): + """ + Deletes users data from cookies and goes to the login page + """ session['username'] = "" return redirect(url_for('index.index')) \ No newline at end of file diff --git a/location_app/app/routes/map.py b/location_app/app/routes/map.py index 7a48c0b..cf9010c 100644 --- a/location_app/app/routes/map.py +++ b/location_app/app/routes/map.py @@ -1,12 +1,22 @@ -from flask import Blueprint, render_template, request, session, url_for, escape, redirect +from flask import Blueprint, render_template, session from app.functions.data_tools import data_getter + map_bl = Blueprint('map', __name__) @map_bl.route("/", methods = ["GET", "POST"]) def index(): + """ + Renders the map page with all the data + thats needed for calculations + """ + _locations = data_getter.get_map_locations_for(session['username']) + _dates = data_getter.get_map_location_dates(session['username']) + _weight = data_getter.get_weight_for(session['username']) + _color = data_getter.get_color_for(session['username']) return render_template("map/index.html", - locations = data_getter.get_map_locations_for(session['username']), - dates = data_getter.get_map_location_dates(session['username']), - weight = data_getter.get_weight_for(session['username'])) + locations = _locations, + dates = _dates, + weight = _weight, + color = _color) diff --git a/location_app/app/routes/picture.py b/location_app/app/routes/picture.py index 6e744ea..915b0d0 100644 --- a/location_app/app/routes/picture.py +++ b/location_app/app/routes/picture.py @@ -1,8 +1,8 @@ from flask import Blueprint, render_template, request, url_for, escape, redirect, session from app.functions.data_tools import data_getter -picture_bl = Blueprint('picture', __name__) +picture_bl = Blueprint('picture', __name__) @picture_bl.route("/", methods = ["GET"]) def index(): diff --git a/location_app/app/routes/profile.py b/location_app/app/routes/profile.py index d0ba9a0..749fa94 100644 --- a/location_app/app/routes/profile.py +++ b/location_app/app/routes/profile.py @@ -1,11 +1,25 @@ -from flask import Blueprint, render_template, request, url_for, escape, redirect, session +from flask import (Blueprint, render_template, request, + url_for, redirect, session) from app.functions.data_tools import data_getter prof_bl = Blueprint('prof', __name__) @prof_bl.route("/", methods = ["GET", "POST"]) def index(): + """ + Renders the profile page with user data and handles + changing of the weight and color through POST method + """ + if request.method == "POST": + data = request.form + data_getter.update_data_for(session['username'], data) + _user = data_getter.get_user_for(session['username']) + _locations = data_getter.get_map_locations_for(session['username']) + _dates = data_getter.get_map_location_dates(session['username']) return render_template("profile/index.html", - user = data_getter.get_user_for(session['username']), - locations = data_getter.get_map_locations_for(session['username']), - dates = data_getter.get_map_location_dates(session['username'])) + user = _user, + locations = _locations, + dates = _dates) + + + \ No newline at end of file diff --git a/location_app/app/static/css/login/create.css b/location_app/app/static/css/login/create.css index 54cd98e..16af9dc 100644 --- a/location_app/app/static/css/login/create.css +++ b/location_app/app/static/css/login/create.css @@ -3,8 +3,8 @@ display: grid; height: 100%; width: 100%; - grid-template-columns: 25% 50% 25%; - grid-template-rows: 5vh auto 5vh; + grid-template-columns: 1fr 2fr 1fr; + grid-template-rows: 5vw auto auto; grid-template-areas: '. . .' '. box .' @@ -16,7 +16,7 @@ grid-area: box; display: grid; grid-template-columns: 1fr 2.5fr 2.5fr 1fr; - grid-template-rows: 1fr 5fr 2fr auto auto 1fr; + grid-template-rows: 1fr 5fr 2fr auto auto 1.5fr; border-radius : 20px; grid-template-areas: '. . . .' @@ -50,21 +50,23 @@ } .form_inside { display: grid; - grid-template-columns: 2fr 2fr; - grid-template-rows: 0.25fr 1.5fr 0.15fr 1.5fr 0.15fr 1.5fr 0.15fr 1.5fr 0.15fr 1.5fr 1.5fr auto; + grid-template-columns: 1fr; + grid-template-rows: 1vw auto 1vw auto 1vw auto 1vw auto 1vw auto 1vw auto auto auto; grid-template-areas: - '. .' - 'user user' - '. .' - 'name name' - '. .' - 'dob dob' - '. .' - 'weight weight' - '. .' - 'pass pass' - 'r_pass r_pass' - 'c_button c_button'; + '.' + 'user' + '.' + 'name' + '.' + 'dob' + '.' + 'colorr' + '.' + 'weight' + '.' + 'pass' + 'r_pass' + 'c_button'; } .username { display: grid; @@ -72,57 +74,55 @@ align-content: center; grid-area: user; } -.username_text { - margin-bottom: 1px; - font-size: 1.5vw; -} .realname { display: grid; justify-content: center stretch; align-content: center; grid-area: name; } -.realname_text { - margin-bottom: 1px; - font-size: 1.5vw; -} .dob { display: grid; justify-content: center stretch; align-content: center; grid-area: dob; } -.dob_text { - margin-bottom: 1px; +.dob select { font-size: 1.5vw; } -.weight { +.colorr { display: grid; justify-content: center stretch; align-content: center; - grid-area: weight; + grid-area: colorr; +} +.colorr input { + height: 30px; } -.weight_text { +.text { margin-bottom: 1px; font-size: 1.5vw; } +.weight { + display: grid; + justify-content: center stretch; + align-content: center; + grid-area: weight; +} .password { display: grid; justify-content: center stretch; align-content: center; grid-area: pass; } -.password_text { - margin-bottom: 1px; - font-size: 1.5vw; -} .r_password { display: grid; + padding-top: 1vw; justify-content: center stretch; align-content: center; grid-area: r_pass; } .create_button_area { + padding-top: 1vw; align-content: center; grid-area: c_button; } diff --git a/location_app/app/static/css/login/forgot.css b/location_app/app/static/css/login/forgot.css index 9df056d..a6e6347 100644 --- a/location_app/app/static/css/login/forgot.css +++ b/location_app/app/static/css/login/forgot.css @@ -16,7 +16,7 @@ grid-area: box; display: grid; grid-template-columns: 1fr 2.5fr 2.5fr 1fr; - grid-template-rows: 1.5fr 5fr 2fr auto auto 1fr; + grid-template-rows: 1.5fr 5fr 2fr auto auto 1.5fr; border-radius : 20px; grid-template-areas: '. . . .' @@ -50,7 +50,7 @@ .form_inside { display: grid; grid-template-columns: 2fr 2fr; - grid-template-rows: 0.5fr 1.5fr 0.5fr 1.5fr 0.5fr 1.5fr 1.5fr auto; + grid-template-rows: 1vw auto 1vw auto 1vw auto auto auto; grid-template-areas: '. .' 'user user' @@ -77,6 +77,9 @@ align-content: center; grid-area: dob; } +.dob select { + font-size: 1.5vw; +} .dob_text { margin-bottom: 1px; font-size: 2vw; @@ -93,16 +96,17 @@ } .r_password { display: grid; + padding-top: 1vw; justify-content: center stretch; align-content: center; grid-area: r_pass; } .forgot_button_area { + padding-top: 1vw; grid-area: forgot_button; } .forgot_button { font-size: 2vw; - border-radius: 10em; } .error_text { color: red; diff --git a/location_app/app/static/css/login/index.css b/location_app/app/static/css/login/index.css index 6b09b89..65012b1 100644 --- a/location_app/app/static/css/login/index.css +++ b/location_app/app/static/css/login/index.css @@ -16,7 +16,7 @@ grid-area: box; display: grid; grid-template-columns: 1fr 2.5fr 2.5fr 1fr; - grid-template-rows: 1.5fr 5fr 2fr auto auto 1fr; + grid-template-rows: 1.5fr 5fr 2fr auto auto 1.5fr; border-radius : 20px; grid-template-areas: '. . . .' @@ -52,8 +52,7 @@ justify-content: start; align-content: center; grid-template-columns: 2fr 2fr; -/* grid-template-rows: 0.5fr 1.5fr 0.5fr 1.5fr 0.5fr 1.5fr 1.5fr; */ - grid-template-rows: 20px auto 20px auto 20px auto auto; + grid-template-rows: 1vw auto 1vw auto 1vw auto auto; grid-template-areas: '. .' 'user user' @@ -67,7 +66,6 @@ display: grid; grid-area: btns; grid-template-columns: 1fr 1fr 0.2fr 1fr; - grid-template-areas: 'f_pass f_pass . login_button'; } diff --git a/location_app/app/static/css/main/index.css b/location_app/app/static/css/main/index.css index e812c73..5a7a08c 100644 --- a/location_app/app/static/css/main/index.css +++ b/location_app/app/static/css/main/index.css @@ -1,19 +1,38 @@ +.content_main { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: auto auto; + grid-template-areas: + 'titl' + 'tablee'; +} .table_main { width: 100%; border-width: 0; + grid-area: tablee; } .table_title { + color: black; + text-decoration: none; margin: 1vh; + display: grid; font-size: 4vw; + grid-area: titl; + justify-content: center; } .table_main th { margin: 1vh; padding: 1vh; + font-size: 3vw; +} +.basic { + text-align: center; font-size: 2vw; + margin: 0.3vh; } -.table_main td { +.advanced { text-align: center; - font-size: 1.4vw; + font-size: 1.5vw; margin: 0.3vh; } .table_main tr:nth-child(even) { diff --git a/location_app/app/static/css/map/index.css b/location_app/app/static/css/map/index.css index e69de29..21e7183 100644 --- a/location_app/app/static/css/map/index.css +++ b/location_app/app/static/css/map/index.css @@ -0,0 +1,31 @@ +.content_main { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: auto auto; + grid-template-areas: + 'dates' + 'map'; +} +.map { + grid-area: map; +} +.dates { + grid-area: dates; + display: grid; + grid-template-columns: 3fr 1fr 2fr; + grid-template-rows: 1fr; + grid-template-areas: + 'selection . bm_1'; + padding-bottom: 30px; +} +.bm_1 { + grid-area: bm_1; +} +.selection { + grid-area: selection; + display: grid; + align-items: center; +} +.selection select { + font-size: 2vw; +} \ No newline at end of file diff --git a/location_app/app/static/css/profile/index.css b/location_app/app/static/css/profile/index.css index 8547669..27a4206 100644 --- a/location_app/app/static/css/profile/index.css +++ b/location_app/app/static/css/profile/index.css @@ -1,7 +1,7 @@ .content_main { display: grid; - grid-template-columns: 0.5fr 0.5fr 0.5fr 0.5fr; - grid-template-rows: 1fr 0.5fr 0.5fr 1fr 0.5fr 1fr 0.5fr 1fr 0.5fr 0.5fr 1fr 0.5fr 1fr; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-rows: 1fr 0.5fr 0.5fr 1fr 0.5fr 1fr 0.5fr auto 0.5fr 0.5fr 1fr 0.5fr 1fr; grid-template-areas: 'p_title p_title p_title p_title' '. . . .' @@ -10,7 +10,7 @@ 'date type p_pic p_pic' 'date1 type1 p_pic p_pic' 'colorr weight p_pic p_pic' - 'colorr1 weight1 p_pic p_pic' + 'updates updates p_pic p_pic' '. . . .' 'city tcal cal speed' 'city1 tcal1 cal1 speed1' @@ -53,6 +53,17 @@ .weight { grid-area: weight; } +.updates { + grid-area: updates; +} +.updates form { + grid-area: updates; + display: grid; + grid-template-columns: 2fr 1fr 1fr; + grid-template-rows: auto; + grid-template-areas: + 'colorr1 weight1 submit'; +} .city { grid-area: city; } @@ -86,12 +97,29 @@ .date1 { grid-area: date1; } +.submit { + grid-area: submit; +} +.submit button{ + font-size: 1.5vw; +} .weight1 { + display: grid; + align-content: center; grid-area: weight1; } .color1 { + display: grid; + align-content: center; grid-area: colorr1; } +.weight1 input{ + width: 70%; +} +.color1 input{ + height: 3vw; + width: 30%; +} .city1 { grid-area: city1; } diff --git a/location_app/app/static/js/map/index.js b/location_app/app/static/js/map/index.js index cb489d3..de74959 100644 --- a/location_app/app/static/js/map/index.js +++ b/location_app/app/static/js/map/index.js @@ -1,34 +1,43 @@ +//MAP var map; var locations; var state; var weight; -// IMAGES +// IMAGES FOR MAP OBJECTS var normalMarker = "/static/img/map/dot.svg"; var startMarker = "/static/img/map/start.svg"; var endMarker = "/static/img/map/end.svg"; -// SCALES +// SCALES FOR MAP OBJECTS var startScale = 2; var endScale = 0.7; var fScale = 0.6; var hScale = 1; var lineW = 5; -// COLORS +// COLORS FOR MAP OBJECTS var normalColor = "#ff0000"; var highStartMarker = "#ffffff"; var highEndMarker = "#000000"; var highLine = "#000000"; -// TIMERS +// TIMERS FOR MAP OBJECTS var timers = {}; var l_timers = {}; // MAP -function initialize_map(_locations, _weight) { + +/** + * Makes the map from the passed in data, sets click listeners + * and calls all map locations + */ +function initialize_map(_locations, _weight, _color) { locations = _locations; weight = _weight; + normalColor = _color; + set_other_colors(); + map = new ol.Map({ target: "map", layers: [ @@ -42,11 +51,26 @@ function initialize_map(_locations, _weight) { get_map_all_locations(); } +/** + * Sets other colors depending on the favourite color + */ +function set_other_colors() { + console.log(normalColor); +} + +/** + * Deletes everything on the map + */ function reset_map_layers() { layers = map.getLayers(); layers.a = [layers.a[0]]; } +/** + * Centers the map so it shows all the dots on the map + * or if the argument are two dots then it centers the map + * on them + */ function center_map(points = 0) { if(points == 0) { var dot_layers = []; @@ -75,7 +99,28 @@ function center_map(points = 0) { } } +// SELECTION + +/** + * Decides if all locations should be showed or just + * a specific date based on the value in the select form + */ +function get_map_for_selection() { + var div = document.getElementById("date"); + var date = div.options[div.selectedIndex].value; + if(date == "all") { + get_map_all_locations(); + } else { + get_map_for_date(date); + } +} + // ALL LOCATIONS + +/** + * Draws a marker for each location entry and stores the + * date and time in the marker + */ function get_map_all_locations() { state = 1; reset_map_layers(); @@ -92,6 +137,12 @@ function get_map_all_locations() { } // FOR DATE + +/** + * Draws marker for each location entry on a specified date + * and connects them with lines also stores data that can be + * later read by clicking on the marker or the line + */ function get_map_for_date(date) { state = 2; reset_map_layers(); @@ -148,6 +199,11 @@ function get_map_for_date(date) { } // MARKER + +/** + * Draws the marker with set properties and + * returns a reference to that marker + */ function draw_marker(pos1, pos2, _properties) { var marker = new ol.layer.Vector({ source: new ol.source.Vector({ @@ -162,6 +218,9 @@ function draw_marker(pos1, pos2, _properties) { return marker; } +/** + * Returns a marker style with specified values + */ function get_marker_style(color, scale, img, anchor = [0.5, 0.5]) { return new ol.style.Style({ image: new ol.style.Icon({ @@ -177,6 +236,12 @@ function get_marker_style(color, scale, img, anchor = [0.5, 0.5]) { } // LINE + +/** + * Connects 2 locations, does the distance, + * calories, speed and time calculations and stores + * them in line properties + */ function connect_two_locations(loc1, loc2, num) { var pos1 = ol.proj.fromLonLat([loc1[0], loc1[1]]); var pos2 = ol.proj.fromLonLat([loc2[0], loc2[1]]); @@ -195,6 +260,10 @@ function connect_two_locations(loc1, loc2, num) { draw_line(pos1, pos2, line_properties) } +/** + * Draws the line in between 2 positions and applies the + * properties to the line + */ function draw_line(pos1, pos2, _properties) { var line = new ol.layer.Vector({ source: new ol.source.Vector({ @@ -208,6 +277,9 @@ function draw_line(pos1, pos2, _properties) { map.addLayer(line); } +/** + * Returns a line style with specified color + */ function get_line_style(color) { return new ol.style.Style({ stroke: new ol.style.Stroke({ @@ -218,9 +290,17 @@ function get_line_style(color) { } // CLICK LISTENER + +/** + * Sets a click listener on the map which will monitor if a line + * or marker are clicked and in which state and based of that + * will show alerts displaying all the data that was stored + * in the properties of the clicked object + */ function set_click_listener() { map.getViewport().addEventListener("click", function(event) { - var layer = map.forEachFeatureAtPixel(map.getEventPixel(event), function(feature, layer) { + var layer = map.forEachFeatureAtPixel(map.getEventPixel(event), + function(feature, layer) { return layer; }); if(layer) { @@ -236,6 +316,9 @@ function set_click_listener() { }); } +/** + * Takes in an array of strings and makes an alert out of that + */ function show_alert(info) { var text = ""; for(i = 0; i < info.length; i++) { @@ -244,6 +327,10 @@ function show_alert(info) { alert(text); } +/** + * Shows marker data depending on which state it is and if + * it is a special marker + */ function get_dot_data(layer) { if(state == 1) { show_alert(["You were here on", @@ -270,6 +357,9 @@ function get_dot_data(layer) { } } +/** + * Shows line data - only accesible in state 2 + */ function get_line_data(layer) { show_alert(["Distance: " + layer.get('length'), "Time: " + layer.get('time'), @@ -277,6 +367,10 @@ function get_line_data(layer) { "Calories: " + layer.get('calories')]); } +/** + * Highlights the line for 4 seconds and updates it's timer + * in the dictionary based on its number + */ function highlight_line(line) { line.setStyle(get_line_style(highLine)); clearTimeout(l_timers[line.get('number')]); @@ -285,6 +379,10 @@ function highlight_line(line) { }, 4000); } +/** + * Highlights the marker for 4 seconds and updates it's timer + * in the dictionary based on its number + */ function highlight_marker(marker, color) { marker.setStyle(get_marker_style(color, hScale, normalMarker)); marker.setZIndex(100); @@ -294,6 +392,10 @@ function highlight_marker(marker, color) { }, 4000); } +/** + * Finds the start and the end of a line and if they aren't + * special markers it highlights them + */ function get_start_end(layer) { var start; var end; diff --git a/location_app/app/static/js/math.js b/location_app/app/static/js/math.js index e3b7a81..25de622 100644 --- a/location_app/app/static/js/math.js +++ b/location_app/app/static/js/math.js @@ -1,10 +1,17 @@ // TIME + +/** + * Returns a difference between 2 dates in seconds + */ function get_time(loc1, loc2) { var miliseconds = Math.abs(new Date('1998/01/01 ' + loc1[3]) - new Date('1998/01/01 ' + loc2[3])); return (miliseconds / 1000); } +/** + * Formats time given in seconds + */ function format_time(seconds) { var miliseconds = seconds * 1000; if(seconds > 60) { @@ -16,10 +23,18 @@ function format_time(seconds) { } // DISTANCE + +/** + * Transfers an angle from degrees to radians + */ function toRad(x) { return x * Math.PI / 180; } +/** + * Calculates distance in meters between 2 points + * using Haversine formula + */ function get_distance(loc1, loc2) { var x1 = loc2[1] - loc1[1]; var dLat = toRad(x1); @@ -33,6 +48,9 @@ function get_distance(loc1, loc2) { return (distance * 1000); } +/** + * Formats distance given in meters + */ function format_distance(distance) { if (distance > 1000) { return (Math.round((distance / 1000) * 100) / 100) + " kilometers"; @@ -42,6 +60,10 @@ function format_distance(distance) { } // SPEED + +/** + * Returns speed in km/h between 2 points + */ function get_speed(loc1, loc2) { var distance = get_distance(loc1, loc2); var time = get_time(loc1, loc2); @@ -50,11 +72,18 @@ function get_speed(loc1, loc2) { return (speed * 3.6); } +/** + * Formats speed given in km/h + */ function format_speed(speed) { return (Math.round(speed * 100) / 100) + " km/h"; } // CALORIES + +/** + * Returns MET based of users speed + */ function get_MET(speed) { if ( 1 <= speed && speed < 3) { return 2; @@ -75,6 +104,9 @@ function get_MET(speed) { } } +/** + * Returns calories burned between 2 points + */ function get_calories(loc1, loc2) { var speed = get_speed(loc1, loc2); var time = get_time(loc1, loc2); @@ -83,6 +115,9 @@ function get_calories(loc1, loc2) { return (((met * 3.5 * weight) / 200) * (time/60)); } +/** + * Formats calories given in cal + */ function format_calories(calories) { if (calories > 1000) { return (Math.round(calories / 10) / 100) + " kcal"; diff --git a/location_app/app/static/js/profile/index.js b/location_app/app/static/js/profile/index.js index fcf9a37..9cc0ccd 100644 --- a/location_app/app/static/js/profile/index.js +++ b/location_app/app/static/js/profile/index.js @@ -1,32 +1,37 @@ +// USER var locations; var weight; var dates; +// DATA var distance = 0; var calories = 0; var tdistance = 0; var tcalories = 0; var tspeed = 0; -var color; -function setup(_locations, _weight, _dates, _color) { +/** + * Runs the calculations for dates and displays the calculated data + * after the page loads + */ +function setup(_locations, _weight, _dates) { locations = _locations; weight = _weight; dates = _dates; - color = _color; - - window.onload = function(){ + window.onload = function() { cycle_through_dates(); - console.log(document.getElementById("qw").textContent); - document.getElementById("type").innerHTML = '

' + "Adventurer" + '

'; - document.getElementById("speed").innerHTML = '

' + format_speed(tspeed) + '

'; - document.getElementById("color").style.backgroundColor = color; - document.getElementById("tdist").innerHTML = '

' + format_distance(tdistance) + '

'; - document.getElementById("tcal").innerHTML = '

' + format_calories(tcalories) + '

'; - document.getElementById("cal").innerHTML = '

' + format_calories(calories) + '

'; - document.getElementById("dist").innerHTML = '

' + format_distance(distance) + '

'; + document.getElementById("type").innerHTML = get_type(); + document.getElementById("speed").innerHTML = format_speed(tspeed); + document.getElementById("tdist").innerHTML = format_distance(tdistance); + document.getElementById("tcal").innerHTML = format_calories(tcalories); + document.getElementById("cal").innerHTML = format_calories(calories); + document.getElementById("dist").innerHTML = format_distance(distance); }; } +/** + * Goes through all the dates and does the calculations + * for each date individually + */ function cycle_through_dates() { for(i = 0; i < dates.length; i++) { var this_date_loc = []; @@ -38,11 +43,15 @@ function cycle_through_dates() { } } for(j = 0; j < this_date_loc.length - 1; j++) { - var dis = get_distance(this_date_loc[j], this_date_loc[j + 1]); + var dis = get_distance(this_date_loc[j], + this_date_loc[j + 1]); this_date_dist += dis; - this_date_cal += get_calories(this_date_loc[j], this_date_loc[j + 1]); - var speed = get_speed(this_date_loc[j], this_date_loc[j + 1]); - var time = get_time(this_date_loc[j], this_date_loc[j + 1]); + this_date_cal += get_calories(this_date_loc[j], + this_date_loc[j + 1]); + var speed = get_speed(this_date_loc[j], + this_date_loc[j + 1]); + var time = get_time(this_date_loc[j], + this_date_loc[j + 1]); if(speed > tspeed && dis < 100 && time > 2) { tspeed = speed; } else if(speed > tspeed && time > 10) { @@ -59,3 +68,28 @@ function cycle_through_dates() { } } } + +/** + * Returns a type based on your top distance in a day + */ +function get_type() { + if(tdistance < 1000) { + return "Couch Potato" + } else if(tdistance < 3000) { + return "Couch Potato" + } else if(tdistance < 5000) { + return "Minimalist" + } else if(tdistance < 8000) { + return "Average Joe" + } else if(tdistance < 11000) { + return "Enjoyer" + } else if(tdistance < 14000) { + return "Adventurer" + } else if(tdistance < 17000) { + return "Long Legs" + } else if(tdistance < 21000) { + return "Extreme" + } else { + return "Top Dog" + } +} \ No newline at end of file diff --git a/location_app/app/static/js/test.js b/location_app/app/static/js/test.js deleted file mode 100644 index 6c6dbb7..0000000 --- a/location_app/app/static/js/test.js +++ /dev/null @@ -1,4 +0,0 @@ -function test() { - var a = document.getElementById("month") - console.log(a.options[a.selectedIndex].text); -} \ No newline at end of file diff --git a/location_app/app/templates/login/create.html b/location_app/app/templates/login/create.html index 62cb865..6c40f4b 100644 --- a/location_app/app/templates/login/create.html +++ b/location_app/app/templates/login/create.html @@ -5,7 +5,6 @@ {% block basejs %} - {% endblock %} @@ -23,14 +22,11 @@

Create Account

-
-

ID:


+

ID:


{% if status == 'no_id' %}

Wrong ID

@@ -41,30 +37,30 @@ {% endif %}
-

Name:


+

Name:


{% if status == 'empty_name' %}

Empty Name

{% endif %}
-

Birthday:


+

Birthday:


@@ -75,15 +71,19 @@

Empty Date

{% endif %}
+
+

Favourite Color:


+ +
-

Weight (kg):


+

Weight (kg):


{% if status == 'empty_weight' %}

Empty Weight

{% endif %}
-

Password:


+

Password:


{% if status == 'empty_pass' %}

Empty Password

diff --git a/location_app/app/templates/login/forgot.html b/location_app/app/templates/login/forgot.html index 301eedf..3306cb6 100644 --- a/location_app/app/templates/login/forgot.html +++ b/location_app/app/templates/login/forgot.html @@ -40,19 +40,19 @@
diff --git a/location_app/app/templates/login/index.html b/location_app/app/templates/login/index.html index 6c9b780..9d7e3b2 100644 --- a/location_app/app/templates/login/index.html +++ b/location_app/app/templates/login/index.html @@ -48,7 +48,7 @@
diff --git a/location_app/app/templates/main/index.html b/location_app/app/templates/main/index.html index c5afb5d..9bc864d 100644 --- a/location_app/app/templates/main/index.html +++ b/location_app/app/templates/main/index.html @@ -28,8 +28,9 @@ {% block body %}
+ {% if advanced %} + Your Locations - @@ -40,7 +41,7 @@ {% for item in locations %} - + @@ -51,6 +52,27 @@ {% endfor %}
Your Locations
ID LongitudeTime
{{ item[0] }} {{ item[1] }} {{ item[2] }}
+ {% else %} + Your Locations + + + + + + + + + {% for item in locations %} + + + + + + + + {% endfor %} +
IDCityRoadDateTime
{{ item[0] }}{{ item[3] }}{{ item[4] }}{{ item[5] }}{{ item[6] }}
+ {% endif %}
{% endblock %} diff --git a/location_app/app/templates/map/index.html b/location_app/app/templates/map/index.html index 79b6b9d..ef471e2 100644 --- a/location_app/app/templates/map/index.html +++ b/location_app/app/templates/map/index.html @@ -37,16 +37,26 @@ {% block body %} -
- +
- - {% for date in dates %} - - {% endfor%} +
+ +
+
+ +
+
+ +
+
{% endblock %} diff --git a/location_app/app/templates/profile/index.html b/location_app/app/templates/profile/index.html index 11a1560..95749f4 100644 --- a/location_app/app/templates/profile/index.html +++ b/location_app/app/templates/profile/index.html @@ -35,7 +35,7 @@ {% block body %}

My profile

@@ -44,7 +44,7 @@ profile
-

ID:

+

ID:

Name:

@@ -91,11 +91,18 @@

{{user[0][2]}}

-
-

{{user[0][3]}}

-
-
-

+
+ +
+ +
+
+ +
+
+ +
+

{{user[1][0][0]}}

@@ -112,8 +119,8 @@

???

-
-

???

+
+

???

???