AT map frontend added

This commit is contained in:
Anh-Thy04
2025-04-21 12:32:38 +02:00
parent e4f439ff22
commit 856c32dc6b
8 changed files with 349 additions and 0 deletions

2
AT_frontend/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.venv/
__pychache__/

152
AT_frontend/app.py Normal file
View File

@@ -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)

33
AT_frontend/forms.py Normal file
View File

@@ -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)

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Admin Dashboard</title>
<script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-3 col-lg-2 d-md-block bg-dark sidebar collapse">
<div class="position-sticky pt-3">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active text-white" href="#">
Dashboard
</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="#">
Users
</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="#">
Reports
</a>
</li>
</ul>
</div>
</div>
<div class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Admin Dashboard</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group me-2">
<button type="button" class="btn btn-sm btn-outline-secondary">Share</button>
<button type="button" class="btn btn-sm btn-outline-secondary">Export</button>
</div>
<a href="/logout" class="btn btn-sm btn-danger">Logout</a>
</div>
</div>
{%block content%}
{% endblock %}

View File

@@ -0,0 +1,68 @@
{%extends 'base.html' %}
{% block content %}
<div class="row">
<div class="col-md-4">
<div class="card mb-4">
<div class="card-body">
<h5>Gate Control Dashboard</h5>
<form method="POST">
{{ form.hidden_tag() }}
<div class="d-grid gap-2 mb-3">
{{ form.open_gate(class="btn btn-dark") }}
</div>
<div class="d-grid gap-2 mb-3">
{{ form.close_gate(class="btn btn-dark") }}
</div>
<div class="d-grid gap-2 mb-3">
{{ form.check_camera(class="btn btn-dark") }}
</div>
<div class="mb-3">
{{ form.debug_mode() }}
<label for="{{ form.debug_mode.id }}">Enable Debug Mode</label>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark">Submit</button>
</div>
</form>
<h6>Gate Status: {{ gate_status }}</h6>
<h6>Camera Status: {{ camera_status }}</h6>
{% if debug_mode %}
<h7>Debug Mode is Enabled</h7>
{% endif %}
</div>
</div>
</div>
<div class="col-md-4">
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">System Logs</h5>
<div class="log-container" style="max-height: 250px; overflow-y: auto;">
<table class="table table-sm table-hover">
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Action</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
{% for log in recent_logs %}
<tr>
<td><small>{{ log.timestamp.strftime('%H:%M:%S') }}</small></td>
<td><small>{{ log.action }}</small></td>
<td>
<span class="badge {% if log.status == 'success' %}bg-success{% elif log.status == 'warning' %}bg-warning{% elif log.status == 'error' %}bg-danger{% else %}bg-secondary{% endif %}">
{{ log.status }}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</html>
{% endblock %}

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://getbootstrap.com/docs/5.3/assets/css/docs.css" rel="stylesheet">
<title>Inlog</title>
<script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body class="bg-dark">
<div class="container d-flex justify-content-center align-items-center" style="min-height: 100vh;">
<div class="card p-4 shadow">
<h3 class="text-center mb-4">Admin Login</h3>
<form action="{{ url_for('login') }}" method="post">
{{ form.csrf_token }}
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" id="password" class="form-control" name="password" required>
<div id="passwordHelpInline" class="form-text">
Must be 8-20 characters long.
</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="remember" name="remember">
<label class="form-check-label" for="remember">Remember me</label>
</div>
{% if error %}
<div class="alert alert-danger">
{{ error }}
</div>
{% endif %}
<div class="d-grid">
<button type="submit" class="btn btn-dark">Login</button>
</div>
</form>
</div>
</div>
</body>
</html>