- Split monolithic app.py (400+ lines) into organized modules - Extract models, forms, and commands into separate files - Implement Flask blueprints for route organization - Maintain full functionality with cleaner architecture - Update all templates to use new blueprint URLs - Enhance README with technical documentation Structure: ├── app.py (50 lines) - Flask app factory ├── models.py (62 lines) - SQLAlchemy models ├── forms.py (43 lines) - WTForms definitions ├── commands.py (74 lines) - CLI commands └── routes/ - Blueprint modules for each feature 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
74 lines
3.5 KiB
HTML
74 lines
3.5 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}{{ title }} - Gestion Scolaire{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="max-w-2xl mx-auto">
|
|
<div class="mb-6">
|
|
<a href="{{ url_for('assessments.detail', id=assessment.id) }}" class="text-blue-600 hover:text-blue-800 text-sm font-medium">
|
|
← Retour à l'évaluation "{{ assessment.title }}"
|
|
</a>
|
|
</div>
|
|
|
|
<div class="bg-white shadow rounded-lg">
|
|
<div class="px-6 py-4 border-b border-gray-200">
|
|
<h1 class="text-xl font-semibold text-gray-900">{{ title }}</h1>
|
|
<p class="text-sm text-gray-600 mt-1">Évaluation : {{ assessment.title }} ({{ assessment.class_group.name }})</p>
|
|
</div>
|
|
|
|
<form method="POST" class="px-6 py-4 space-y-6">
|
|
{{ form.hidden_tag() }}
|
|
|
|
<div>
|
|
<label for="{{ form.title.id }}" class="block text-sm font-medium text-gray-700 mb-1">
|
|
{{ form.title.label.text }}
|
|
</label>
|
|
{{ form.title(class="block w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-blue-500 focus:border-blue-500") }}
|
|
{% if form.title.errors %}
|
|
<div class="mt-1 text-sm text-red-600">
|
|
{% for error in form.title.errors %}
|
|
<p>{{ error }}</p>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div>
|
|
<label for="{{ form.description.id }}" class="block text-sm font-medium text-gray-700 mb-1">
|
|
{{ form.description.label.text }}
|
|
</label>
|
|
{{ form.description(class="block w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-blue-500 focus:border-blue-500", rows="3") }}
|
|
{% if form.description.errors %}
|
|
<div class="mt-1 text-sm text-red-600">
|
|
{% for error in form.description.errors %}
|
|
<p>{{ error }}</p>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div>
|
|
<label for="{{ form.order.id }}" class="block text-sm font-medium text-gray-700 mb-1">
|
|
{{ form.order.label.text }}
|
|
</label>
|
|
{{ form.order(class="block w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-blue-500 focus:border-blue-500") }}
|
|
{% if form.order.errors %}
|
|
<div class="mt-1 text-sm text-red-600">
|
|
{% for error in form.order.errors %}
|
|
<p>{{ error }}</p>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
<p class="mt-1 text-xs text-gray-500">L'ordre détermine l'affichage des exercices dans l'évaluation</p>
|
|
</div>
|
|
|
|
<div class="flex justify-end space-x-3 pt-4 border-t border-gray-200">
|
|
<a href="{{ url_for('assessments.detail', id=assessment.id) }}" class="px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors">
|
|
Annuler
|
|
</a>
|
|
{{ form.submit(class="px-4 py-2 bg-blue-600 text-white rounded-md text-sm font-medium hover:bg-blue-700 transition-colors") }}
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endblock %} |