mirror of
				https://github.com/StefBuwalda/ProjectIOT.git
				synced 2025-10-30 19:29:57 +00:00 
			
		
		
		
	changed files on the frontend
This commit is contained in:
		
							
								
								
									
										3
									
								
								AT_frontend/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								AT_frontend/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +1 @@ | ||||
| .venv/ | ||||
| __pychache__/ | ||||
| .venvs/ | ||||
| @@ -1,152 +1,35 @@ | ||||
| from flask import Flask, render_template, request, redirect, url_for, flash, session | ||||
| from flask import Flask, render_template, session, redirect, url_for, session | ||||
| from flask_wtf import FlaskForm | ||||
| from wtforms import StringField, PasswordField, BooleanField, SubmitField | ||||
| from wtforms import (StringField, BooleanField, | ||||
|                                   RadioField, SelectField, | ||||
|                                   TextAreaField, 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) | ||||
| app.config['SECRET_KEY'] = 'mijngeheimesleutel' | ||||
|  | ||||
| # 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}')" | ||||
| class InfoForm(FlaskForm): | ||||
|  | ||||
| # Keep your existing user dictionary for authentication | ||||
| users = { | ||||
|     "admin": {"password": "admin123", "role": "admin"}, | ||||
|     "user": {"password": "user123", "role": "user"} | ||||
| } | ||||
|     naam = StringField('Wat is je naam?',validators=[DataRequired()]) | ||||
|     vrouw  = BooleanField("Ben je een vrouw?") | ||||
|     instrument = RadioField('Welk instrument wil je leren bespelen?',   choices=[('ins_een','Gitaar'),('ins_twee','Drums')]) | ||||
|     plaats = SelectField(u'Welke locatie heeft de voorkeur?', | ||||
|              choices=[('as', 'Assen'), ('dr', 'Drachten'), ('gr', 'Groningen')]) | ||||
|     feedback = TextAreaField() | ||||
|     submit = SubmitField('Verzend') | ||||
|  | ||||
| # 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('/') | ||||
| @app.route('/', methods=['GET', 'POST']) | ||||
| 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() | ||||
|      | ||||
|     form = InfoForm() | ||||
|     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" | ||||
|         session['naam'] = form.username.data | ||||
|         session['password'] = form.password.data | ||||
|  | ||||
| @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() | ||||
|         return render_template('dashboard.html') | ||||
|     return render_template('login.html', form=form) | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     app.run(debug=True) | ||||
							
								
								
									
										
											BIN
										
									
								
								AT_frontend/static/images/car.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								AT_frontend/static/images/car.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 4.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								AT_frontend/static/images/logo-light.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								AT_frontend/static/images/logo-light.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 8.6 KiB | 
| @@ -1,68 +1,18 @@ | ||||
| {%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 %} | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <title>Document</title> | ||||
| </head> | ||||
| <body> | ||||
|     <h1>Bedankt voor de moeite. <br>Dit zijn de ingevulde gegevens:</h1> | ||||
| <ul> | ||||
|     <li>Naam: {{ session['naam'] }}</li> | ||||
|     <li>Geslacht: {{ session['geslacht'] }}</li> | ||||
|     <li>Instrument: {{ session['instrument'] }}</li> | ||||
|     <li>Plaats: {{ session['plaats'] }}</li> | ||||
|     <li>Feedback: {{ session['feedback'] }}</li> | ||||
| </ul> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										75
									
								
								AT_frontend/templates/login.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								AT_frontend/templates/login.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| <!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" integrity="sha384-SgOJa3DmI69IUzQ2PVdRZhwQ+dy64/BUtbMJw1MZ8t5HZApcHrRKUc4W0kG879m7" crossorigin="anonymous"> | ||||
|     <title>Login</title> | ||||
|     <style> | ||||
|         .rounded-input { | ||||
|             border-radius: 20px;  | ||||
|         } | ||||
|  | ||||
|         .split-background { | ||||
|             position: fixed; | ||||
|             top: 0; | ||||
|             left: 0; | ||||
|             width: 100%; | ||||
|             height: 50vh; | ||||
|             background-color: #424D66; | ||||
|             z-index: -1; | ||||
|         } | ||||
|         @keyframes moveLeftRight { | ||||
|             0% { | ||||
|                 transform: translateX(0);  | ||||
|             } | ||||
|             100% { | ||||
|                 transform: translateX(1366px);  | ||||
|             } | ||||
|         } | ||||
|         .logo { | ||||
|             margin-top: 70px; | ||||
|             width: 770px;  | ||||
|             height: auto; | ||||
|         } | ||||
|         .car-image-container { | ||||
|             position: fixed; | ||||
|             bottom: 33px; | ||||
|         } | ||||
|         .animate { | ||||
|             animation: moveLeftRight 15s infinite alternate; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
| <body> | ||||
|     <div class="split-background"> | ||||
|     <div class="container-fluid text-center"> | ||||
|         <img src="../static/images/logo-light.png" alt="Logo" class="logo" class="img-fluid mt-5"> | ||||
|             </div> | ||||
|                 </div> | ||||
|                     <div class="container d-flex justify-content-center align-items-center" style="min-height: 100vh;"> | ||||
|                         <div class="col-md-6 col-lg-4"> | ||||
|                             <form method="POST" class="p-5 border rounded-input shadow-sm bg-white bg-opacity-75"> | ||||
|                                 <div class=" p-4 border rounded-input shadow-sm bg-white"> | ||||
|                                     <label for="username" class="form-label text-center w-100">Username</label> | ||||
|                                             <input type="text" class="form-control rounded-input" id="username" name="username" required> | ||||
|                                                 <label for="password" class="form-label text-center w-100">Password</label> | ||||
|                                                     <input type="password" class="form-control rounded-input" id="password" name="password" required> | ||||
|                                                 <br> | ||||
|                                             <div class="d-grid"> | ||||
|                                         <button type="submit" class="btn btn-dark rounded-input px-4 mx-auto w-50">Sign in</button> | ||||
|                                         </div> | ||||
|                                     </div> | ||||
|                                 </form> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div class="car-image-container"> | ||||
|                         <img src="../static/images/car.png" alt="Moving Image" class="animate"> | ||||
|                         </div> | ||||
|                     <footer class="py-3 bg-dark text-white fixed-bottom""> | ||||
|                 <div class="container text-center"> | ||||
|             <span class="text-muted"> </span> | ||||
|         </div> | ||||
|     </footer> | ||||
| </body> | ||||
| </html> | ||||
		Reference in New Issue
	
	Block a user
	 Anh-Thy04
					Anh-Thy04