Template MVC básico com Jinja
This commit is contained in:
parent
27a71ae761
commit
9e9d8958c1
@ -3,6 +3,8 @@ from flasgger import Swagger
|
|||||||
from app.database import db
|
from app.database import db
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
from app.routes.user_routes import user_bp
|
from app.routes.user_routes import user_bp
|
||||||
|
from app.routes.login_form import login_bp
|
||||||
|
from app.routes.dashboard import dashboard_bp
|
||||||
from app.routes.invoice_routes import invoice_bp
|
from app.routes.invoice_routes import invoice_bp
|
||||||
from werkzeug.security import generate_password_hash
|
from werkzeug.security import generate_password_hash
|
||||||
|
|
||||||
@ -54,5 +56,7 @@ def create_app():
|
|||||||
# Registrar Blueprints
|
# Registrar Blueprints
|
||||||
app.register_blueprint(user_bp, url_prefix="/users")
|
app.register_blueprint(user_bp, url_prefix="/users")
|
||||||
app.register_blueprint(invoice_bp, url_prefix="/invoices")
|
app.register_blueprint(invoice_bp, url_prefix="/invoices")
|
||||||
|
app.register_blueprint(login_bp, url_prefix="/login_bp")
|
||||||
|
app.register_blueprint(dashboard_bp, url_prefix="/dashboard")
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
0
app/controllers/__init__.py
Normal file
0
app/controllers/__init__.py
Normal file
13
app/controllers/auth_controller.py
Normal file
13
app/controllers/auth_controller.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from app.auth import generate_token
|
||||||
|
from app.models.user import User
|
||||||
|
from werkzeug.security import check_password_hash
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
def authenticate_user(email, password):
|
||||||
|
user = User.query.filter_by(email=email).first()
|
||||||
|
|
||||||
|
if not user or not check_password_hash(user.password, password):
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
token = generate_token(user)
|
||||||
|
return user, token
|
||||||
12
app/routes/dashboard.py
Normal file
12
app/routes/dashboard.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from flask import Blueprint, render_template, session, redirect, url_for, flash
|
||||||
|
|
||||||
|
dashboard_bp = Blueprint("dashboard", __name__, template_folder="templates")
|
||||||
|
|
||||||
|
@dashboard_bp.route("/")
|
||||||
|
def dashboard():
|
||||||
|
"""Protege a rota do dashboard"""
|
||||||
|
if "user_id" not in session:
|
||||||
|
flash("Faça login para acessar o dashboard.", "warning")
|
||||||
|
return redirect(url_for("login_form.login"))
|
||||||
|
|
||||||
|
return render_template("dashboard.html", user_email=session.get("user_email"))
|
||||||
30
app/routes/login_form.py
Normal file
30
app/routes/login_form.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
from flask import Blueprint, render_template, request, redirect, url_for, flash, session
|
||||||
|
from app.controllers.auth_controller import authenticate_user
|
||||||
|
|
||||||
|
login_bp = Blueprint("login_form", __name__, template_folder="templates")
|
||||||
|
|
||||||
|
@login_bp.route("/", methods=["GET", "POST"])
|
||||||
|
def login():
|
||||||
|
"""Rota de login"""
|
||||||
|
if request.method == "POST":
|
||||||
|
email = request.form.get("email")
|
||||||
|
password = request.form.get("password")
|
||||||
|
|
||||||
|
user, token = authenticate_user(email, password)
|
||||||
|
|
||||||
|
if user:
|
||||||
|
session["user_id"] = user.id
|
||||||
|
session["user_email"] = user.email
|
||||||
|
flash("Login bem-sucedido!", "success")
|
||||||
|
return redirect(url_for("dashboard.dashboard"))
|
||||||
|
|
||||||
|
flash("Credenciais inválidas!", "danger")
|
||||||
|
|
||||||
|
return render_template("login.html")
|
||||||
|
|
||||||
|
@login_bp.route("/logout")
|
||||||
|
def logout():
|
||||||
|
"""Rota de logout"""
|
||||||
|
session.clear()
|
||||||
|
flash("Você saiu da conta.", "info")
|
||||||
|
return redirect(url_for("login_form.login"))
|
||||||
13
app/templates/dashboard.html
Normal file
13
app/templates/dashboard.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pt">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Dashboard</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Bem-vindo ao Dashboard!</h1>
|
||||||
|
<p>Usuário logado: {{ user_email }}</p>
|
||||||
|
<a href="{{ url_for('login_form.login') }}">Sair</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
32
app/templates/login.html
Normal file
32
app/templates/login.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pt">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Login</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="login-container">
|
||||||
|
<h2>Login</h2>
|
||||||
|
|
||||||
|
{% with messages = get_flashed_messages(with_categories=True) %}
|
||||||
|
{% if messages %}
|
||||||
|
{% for category, message in messages %}
|
||||||
|
<div class="alert alert-{{ category }}">{{ message }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
<label for="email">E-mail:</label>
|
||||||
|
<input type="email" name="email" required>
|
||||||
|
|
||||||
|
<label for="password">Senha:</label>
|
||||||
|
<input type="password" name="password" required>
|
||||||
|
|
||||||
|
<button type="submit">Entrar</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -1,13 +1,16 @@
|
|||||||
attrs==25.1.0
|
attrs==25.1.0
|
||||||
blinker==1.9.0
|
blinker==1.9.0
|
||||||
click==8.1.8
|
click==8.1.8
|
||||||
|
exceptiongroup==1.2.2
|
||||||
factory_boy==3.3.3
|
factory_boy==3.3.3
|
||||||
Faker==36.2.2
|
Faker==36.2.2
|
||||||
flasgger==0.9.7.1
|
flasgger==0.9.7.1
|
||||||
Flask==3.1.0
|
Flask==3.1.0
|
||||||
|
Flask-JWT-Extended==4.7.1
|
||||||
Flask-SQLAlchemy==3.1.1
|
Flask-SQLAlchemy==3.1.1
|
||||||
Flask-Testing==0.8.1
|
Flask-Testing==0.8.1
|
||||||
greenlet==3.1.1
|
greenlet==3.1.1
|
||||||
|
importlib_metadata==8.6.1
|
||||||
iniconfig==2.0.0
|
iniconfig==2.0.0
|
||||||
itsdangerous==2.2.0
|
itsdangerous==2.2.0
|
||||||
Jinja2==3.1.6
|
Jinja2==3.1.6
|
||||||
@ -17,12 +20,15 @@ MarkupSafe==3.0.2
|
|||||||
mistune==3.1.2
|
mistune==3.1.2
|
||||||
packaging==24.2
|
packaging==24.2
|
||||||
pluggy==1.5.0
|
pluggy==1.5.0
|
||||||
|
PyJWT==2.10.1
|
||||||
pytest==8.3.5
|
pytest==8.3.5
|
||||||
PyYAML==6.0.2
|
PyYAML==6.0.2
|
||||||
referencing==0.36.2
|
referencing==0.36.2
|
||||||
rpds-py==0.23.1
|
rpds-py==0.23.1
|
||||||
six==1.17.0
|
six==1.17.0
|
||||||
SQLAlchemy==2.0.38
|
SQLAlchemy==2.0.38
|
||||||
|
tomli==2.2.1
|
||||||
typing_extensions==4.12.2
|
typing_extensions==4.12.2
|
||||||
tzdata==2025.1
|
tzdata==2025.1
|
||||||
Werkzeug==3.1.3
|
Werkzeug==3.1.3
|
||||||
|
zipp==3.21.0
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user