From 856c32dc6bda4a41b9ff61e4370c8a5fc4f96ded Mon Sep 17 00:00:00 2001 From: Anh-Thy04 Date: Mon, 21 Apr 2025 12:32:38 +0200 Subject: [PATCH] AT map frontend added --- AT_frontend/.gitignore | 2 + AT_frontend/app.py | 152 +++++++++++++++++++++++++++ AT_frontend/forms.py | 33 ++++++ AT_frontend/instance/logs.db | Bin 0 -> 8192 bytes AT_frontend/instance/site.db | Bin 0 -> 16384 bytes AT_frontend/templates/base.html | 50 +++++++++ AT_frontend/templates/dashboard.html | 68 ++++++++++++ AT_frontend/templates/inlog.html | 44 ++++++++ 8 files changed, 349 insertions(+) create mode 100644 AT_frontend/.gitignore create mode 100644 AT_frontend/app.py create mode 100644 AT_frontend/forms.py create mode 100644 AT_frontend/instance/logs.db create mode 100644 AT_frontend/instance/site.db create mode 100644 AT_frontend/templates/base.html create mode 100644 AT_frontend/templates/dashboard.html create mode 100644 AT_frontend/templates/inlog.html diff --git a/AT_frontend/.gitignore b/AT_frontend/.gitignore new file mode 100644 index 0000000..860b323 --- /dev/null +++ b/AT_frontend/.gitignore @@ -0,0 +1,2 @@ +.venv/ +__pychache__/ \ No newline at end of file diff --git a/AT_frontend/app.py b/AT_frontend/app.py new file mode 100644 index 0000000..b1af769 --- /dev/null +++ b/AT_frontend/app.py @@ -0,0 +1,152 @@ +from flask import Flask, render_template, request, redirect, url_for, flash, session +from flask_wtf import FlaskForm +from wtforms import StringField, PasswordField, BooleanField, SubmitField +from wtforms.validators import DataRequired +from functools import wraps +import os +from flask_sqlalchemy import SQLAlchemy +from datetime import datetime + +app = Flask(__name__) +app.config['SECRET_KEY'] = 'your-secret-key' # Change this to a random string + +# Database configuration - update with your friend's database info +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///logs.db' # Change this to match your friend's DB +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +db = SQLAlchemy(app) + +# Simple log model - adjust to match your friend's database structure +class Log(db.Model): + id = db.Column(db.Integer, primary_key=True) + action = db.Column(db.String(100), nullable=False) + timestamp = db.Column(db.DateTime, default=datetime.utcnow) + + def __repr__(self): + return f"Log('{self.action}', '{self.timestamp}')" + +# Keep your existing user dictionary for authentication +users = { + "admin": {"password": "admin123", "role": "admin"}, + "user": {"password": "user123", "role": "user"} +} + +# Add a function to create a new log entry +def add_log(action): + log = Log(action=action) + db.session.add(log) + db.session.commit() + +class LoginForm(FlaskForm): + username = StringField('Username', validators=[DataRequired()]) + password = PasswordField('Password', validators=[DataRequired()]) + remember = BooleanField('Remember Me') + +class GateControlForm(FlaskForm): + open_gate = SubmitField('Open Gate') + close_gate = SubmitField('Close Gate') + check_camera = SubmitField('Check Camera') + debug_mode = BooleanField('Debug Mode') + +def login_required(f): + @wraps(f) + def decorated_function(*args, **kwargs): + if 'logged_in' not in session: + return redirect(url_for('login')) + return f(*args, **kwargs) + return decorated_function + +def admin_required(f): + @wraps(f) + def decorated_function(*args, **kwargs): + if 'role' not in session or session['role'] != 'admin': + flash('You need to be an admin to access this page.') + return redirect(url_for('login')) + return f(*args, **kwargs) + return decorated_function + +@app.route('/') +def index(): + if 'logged_in' in session: + if session['role'] == 'admin': + return redirect(url_for('dashboard')) + return redirect(url_for('user_page')) + return redirect(url_for('login')) + +@app.route('/login', methods=['GET', 'POST']) +def login(): + form = LoginForm() + error = None + + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + + if username in users and users[username]['password'] == password: + session['logged_in'] = True + session['username'] = username + session['role'] = users[username]['role'] + + # Log the login action + add_log(f"User {username} logged in") + + if users[username]['role'] == 'admin': + return redirect(url_for('dashboard')) + else: + return redirect(url_for('user_page')) + else: + # Log the failed login attempt + add_log(f"Failed login attempt for user {username}") + error = 'Invalid credentials. Please try again.' + + return render_template('inlog.html', form=form, error=error) + +@app.route('/dashboard', methods=['GET', 'POST']) +@login_required +@admin_required +def dashboard(): + form = GateControlForm() + gate_status = "Closed" + camera_status = "Inactive" + debug_mode = False + + # Get the most recent logs to display + recent_logs = Log.query.order_by(Log.timestamp.desc()).limit(10).all() + + if form.validate_on_submit(): + if form.open_gate.data: + gate_status = "Open" + add_log("Gate opened by " + session['username']) + elif form.close_gate.data: + gate_status = "Closed" + add_log("Gate closed by " + session['username']) + elif form.check_camera.data: + camera_status = "Active" + add_log("Camera checked by " + session['username']) + + debug_mode = form.debug_mode.data + if debug_mode: + add_log("Debug mode enabled by " + session['username']) + + return render_template('dashboard.html', form=form, gate_status=gate_status, + camera_status=camera_status, debug_mode=debug_mode, + recent_logs=recent_logs) + +@app.route('/user') +@login_required +def user_page(): + add_log(f"User {session['username']} accessed user page") + return "Regular user page - Access restricted" + +@app.route('/logout') +def logout(): + if 'username' in session: + add_log(f"User {session['username']} logged out") + session.clear() + return redirect(url_for('login')) + +# Initialize database +with app.app_context(): + db.create_all() + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/AT_frontend/forms.py b/AT_frontend/forms.py new file mode 100644 index 0000000..1e45ef9 --- /dev/null +++ b/AT_frontend/forms.py @@ -0,0 +1,33 @@ +from flask import Flask, render_template, redirect, url_for +from flask_wtf import FlaskForm +from wtforms import StringField, SubmitField, BooleanField +from wtforms.validators import DataRequired + +app = Flask(__name__) +app.config['SECRET_KEY'] = 'mijngeheimesleutel' + +class GateControlForm(FlaskForm): + open_gate = SubmitField('Open Gate') + close_gate = SubmitField('Close Gate') + debug_mode = BooleanField('Enable Debug Mode') + check_camera = SubmitField('Check Camera') # New button to check camera status + +class InputForm(FlaskForm): + name = StringField('Name', validators=[DataRequired()]) + submit = SubmitField('Submit') + +@app.route('/', methods=['GET', 'POST']) +def dashboard(): + gate_status = "Closed" + debug_mode = False + form = GateControlForm() + if form.validate_on_submit(): + if form.open_gate.data: + gate_status = "Open" + elif form.close_gate.data: + debug_mode = form.debug_mode.data + return render_template('dashboard.html', form=form, gate_status=gate_status, debug_mode=debug_mode) + return render_template('dashboard.html', form=form, gate_status=gate_status, debug_mode=debug_mode) + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/AT_frontend/instance/logs.db b/AT_frontend/instance/logs.db new file mode 100644 index 0000000000000000000000000000000000000000..8efe1ea6e23537ae333964fbba28d0a0f1c70910 GIT binary patch literal 8192 zcmeI1O>Y}T7{}MaH1_(f5K1W&I_Nx`_F-s;5LU=iC@;)2Sp zTzf`B>Sy4<2jBuHBqaJJkhpSbZ>Z0@ja5*IXAhh@k9K9R*T4Obe>?klEr0sS`e2fh z>*Kv)Z$d`@a&LPw7>~$jtv!s(*H6~| zto=~CReQe{SAVbGtzN6HRQ{^`RQa~DQ8^L+5&sx}6Q7SO<$LA3<()E={x1Dm`mS`X zw6gdB4;LyJ2nK?IU?3O>2L4|IaJCq!)|LHqkM#P(!6>_P*h%|jFaieZ9FymO6UGw` z31ier#|4OYijjE=Grl?b7sL{!DS$Cf!P|a8OeI2NkTph#x4eQdMI=&FX*E)C#wQ3F zo+zMNa)CjoeS;9<)PNC2!JFPeQc;J5Rf6~jNl7_3MgyGk58~8;vet+>uY4jGR7DM?4!4Q8Kg-Fh@To;wkDy_2c(#*y9Mml<$zb6^%gtBfa zUmRo~&oRc7f)_pGri^t8%e{~{P711(V4A^E@3@SS1{v4L8wZ?9Zkgs#_l}z~LTT=5 z`QoOnM>_2UgQ{oTV}>K+D!JmMNw}Z_8xVH7*e~vY5!kz3Id>djV+Dp6YH1etU%g~H zGqX5kxIsoO`ZRIjFk;~V literal 0 HcmV?d00001 diff --git a/AT_frontend/instance/site.db b/AT_frontend/instance/site.db new file mode 100644 index 0000000000000000000000000000000000000000..416bb253cac9facdd386415fcb24f93937207b28 GIT binary patch literal 16384 zcmeI(&rZ}p90%~}E>PG6>V?$Am<%VkiICj|S-}`wma=YK7AeKZX*0G1HuTTZKO)}5 zo4$Y#;3LS*)1uvV zn|8N4o%^&j#+=lPLi(a%HJ>)Day>_M9J^c6-f~wa=~gTEp6=&&+LF_FO~Ot*%>UyVaF-<D7cK#uJU?*hvN>b{AGo+aOOk^qcF!M}zq0x`@(1_+ z-3qt5?Tsyy=BtyTjgoP%Frq)2REQV4{B5%Di+B4T%hD*n@5wp#s`4z~?MLO$ZCqqU z`%c7x1OW&@00Izz00bZa0SG_<0uX?}zb&9E!$iNUGdJ+U{8X*Y=4DB&OVNH1aUeke z0uX=z1Rwwb2tWV=5P$##An<<)j288={QY14|35PEnP^|MkD8_3p7}7rGL_yydUELc)&lgo<$ex?r$zm@(q|R&Z>>aQ;^upb1A{I^~t}w9+fhC+eF&DGH ZIpU(Cl4>3?-^D?_&`Uk$d++|B?@xyG4haAN literal 0 HcmV?d00001 diff --git a/AT_frontend/templates/base.html b/AT_frontend/templates/base.html new file mode 100644 index 0000000..8e26039 --- /dev/null +++ b/AT_frontend/templates/base.html @@ -0,0 +1,50 @@ + + + + + + + Admin Dashboard + + + +
+
+ + +
+
+

Admin Dashboard

+
+
+ + +
+ Logout +
+
+ + {%block content%} + + {% endblock %} + \ No newline at end of file diff --git a/AT_frontend/templates/dashboard.html b/AT_frontend/templates/dashboard.html new file mode 100644 index 0000000..db79af8 --- /dev/null +++ b/AT_frontend/templates/dashboard.html @@ -0,0 +1,68 @@ +{%extends 'base.html' %} +{% block content %} +
+
+
+
+
Gate Control Dashboard
+
+ {{ form.hidden_tag() }} +
+ {{ form.open_gate(class="btn btn-dark") }} +
+
+ {{ form.close_gate(class="btn btn-dark") }} +
+
+ {{ form.check_camera(class="btn btn-dark") }} +
+
+ {{ form.debug_mode() }} + +
+
+ +
+
+
Gate Status: {{ gate_status }}
+
Camera Status: {{ camera_status }}
+ {% if debug_mode %} + Debug Mode is Enabled + {% endif %} +
+
+
+
+
+
+
System Logs
+
+ + + + + + + + + + {% for log in recent_logs %} + + + + + + {% endfor %} + +
TimeActionStatus
{{ log.timestamp.strftime('%H:%M:%S') }}{{ log.action }} + + {{ log.status }} + +
+
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/AT_frontend/templates/inlog.html b/AT_frontend/templates/inlog.html new file mode 100644 index 0000000..739c54f --- /dev/null +++ b/AT_frontend/templates/inlog.html @@ -0,0 +1,44 @@ + + + + + + + + Inlog + + + +
+
+

Admin Login

+
+ {{ form.csrf_token }} +
+ + +
+
+ + +
+ Must be 8-20 characters long. +
+
+
+ + +
+ {% if error %} +
+ {{ error }} +
+ {% endif %} +
+ +
+
+
+
+ + \ No newline at end of file