- Remove routes/exercises.py blueprint (only consultation routes) - Delete templates/exercise_detail.html (intermediate page removed) - Update app.py to remove exercises blueprint registration - Modernize templates/assessment_detail.html with: * Hero section with gradient background * Action cards with hover effects and animations * Centered progress indicator with visual circles * Compact exercise structure display * Improved responsive design and UX Part of Phase 2 UX improvements - eliminating intermediate pages for direct navigation. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
96 lines
3.5 KiB
Python
96 lines
3.5 KiB
Python
import os
|
|
import logging
|
|
from flask import Flask, render_template
|
|
from models import db, Assessment, Student, ClassGroup
|
|
from commands import init_db
|
|
from app_config_classes import config
|
|
from app_config import config_manager
|
|
from exceptions.handlers import register_error_handlers
|
|
from core.logging import setup_logging
|
|
|
|
# Import blueprints
|
|
from routes.assessments import bp as assessments_bp
|
|
from routes.grading import bp as grading_bp
|
|
from routes.config import bp as config_bp
|
|
|
|
def create_app(config_name=None):
|
|
if config_name is None:
|
|
config_name = os.environ.get('FLASK_ENV', 'development')
|
|
|
|
app = Flask(__name__)
|
|
app.config.from_object(config[config_name])
|
|
|
|
# Initialiser la configuration de l'application
|
|
app.app_config = config_manager
|
|
|
|
# Configuration du logging structuré
|
|
setup_logging(app)
|
|
|
|
# Initialize extensions
|
|
db.init_app(app)
|
|
|
|
# Register error handlers
|
|
register_error_handlers(app)
|
|
|
|
# Initialiser la configuration par défaut après l'initialisation de la DB
|
|
with app.app_context():
|
|
db.create_all()
|
|
config_manager.initialize_default_config()
|
|
|
|
# Register blueprints
|
|
app.register_blueprint(assessments_bp)
|
|
app.register_blueprint(grading_bp)
|
|
app.register_blueprint(config_bp)
|
|
|
|
# Register CLI commands
|
|
app.cli.add_command(init_db)
|
|
|
|
# Main routes
|
|
@app.route('/')
|
|
def index():
|
|
try:
|
|
recent_assessments = Assessment.query.order_by(Assessment.date.desc()).limit(5).all()
|
|
total_students = Student.query.count()
|
|
total_assessments = Assessment.query.count()
|
|
total_classes = ClassGroup.query.count()
|
|
return render_template('index.html',
|
|
recent_assessments=recent_assessments,
|
|
total_students=total_students,
|
|
total_assessments=total_assessments,
|
|
total_classes=total_classes)
|
|
except Exception as e:
|
|
app.logger.error(f'Erreur lors du chargement de la page d\'accueil: {e}')
|
|
return render_template('error.html', error="Erreur lors du chargement de la page"), 500
|
|
|
|
@app.route('/classes')
|
|
def classes():
|
|
try:
|
|
classes = ClassGroup.query.order_by(ClassGroup.year, ClassGroup.name).all()
|
|
return render_template('classes.html', classes=classes)
|
|
except Exception as e:
|
|
app.logger.error(f'Erreur lors du chargement des classes: {e}')
|
|
return render_template('error.html', error="Erreur lors du chargement des classes"), 500
|
|
|
|
@app.route('/students')
|
|
def students():
|
|
try:
|
|
# Optimisation: utiliser joinedload pour éviter les requêtes N+1
|
|
from sqlalchemy.orm import joinedload
|
|
students = Student.query.options(joinedload(Student.class_group)).order_by(
|
|
ClassGroup.name, Student.last_name, Student.first_name
|
|
).join(ClassGroup).all()
|
|
return render_template('students.html', students=students)
|
|
except Exception as e:
|
|
app.logger.error(f'Erreur lors du chargement des étudiants: {e}')
|
|
return render_template('error.html', error="Erreur lors du chargement des étudiants"), 500
|
|
|
|
return app
|
|
|
|
if __name__ == '__main__':
|
|
app = create_app()
|
|
with app.app_context():
|
|
db.create_all()
|
|
|
|
# Le mode debug est géré par la configuration
|
|
port = int(os.environ.get('PORT', 5000))
|
|
app.run(host='0.0.0.0', port=port) |