fix: enforce write phase completion gate and wire done endpoint
- GET /write now checks all groups are written/skipped before showing
the completion screen; incomplete sessions are redirected to the first
draft group
- POST /write/done now accepts form data (not JSON) and redirects to
/export; wired up from the completion screen via a <form> POST button
- phase5.html extra_scripts block wrapped in {% if group %} to prevent
Jinja errors when group is None on the completion screen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,11 @@ def write():
|
|||||||
total = len(active_groups)
|
total = len(active_groups)
|
||||||
group = active_groups[group_idx] if group_idx < total else None
|
group = active_groups[group_idx] if group_idx < total else None
|
||||||
done_count = sum(1 for g in active_groups if g.status in ("written", "skipped"))
|
done_count = sum(1 for g in active_groups if g.status in ("written", "skipped"))
|
||||||
|
if group is None:
|
||||||
|
all_done = all(g.status in ("written", "skipped", "exported") for g in active_groups)
|
||||||
|
if not all_done:
|
||||||
|
first_incomplete = next(i for i, g in enumerate(active_groups) if g.status == "draft")
|
||||||
|
return redirect(url_for("write.write", album_id=album_id, group_idx=first_incomplete))
|
||||||
photos = []
|
photos = []
|
||||||
if group:
|
if group:
|
||||||
by_id = {p.id: p for p in state.photos}
|
by_id = {p.id: p for p in state.photos}
|
||||||
@@ -86,12 +91,13 @@ def skip():
|
|||||||
|
|
||||||
|
|
||||||
@bp.post("/write/done")
|
@bp.post("/write/done")
|
||||||
def done():
|
def write_done():
|
||||||
body = request.get_json()
|
album_id = request.form["album_id"]
|
||||||
album_id = body["album_id"]
|
|
||||||
state = load_state(album_id, current_app)
|
state = load_state(album_id, current_app)
|
||||||
|
if state is None:
|
||||||
|
return jsonify({"ok": False, "error": "not found"}), 404
|
||||||
if "write" not in state.phases_completed:
|
if "write" not in state.phases_completed:
|
||||||
state.phases_completed.append("write")
|
state.phases_completed.append("write")
|
||||||
state.phase = "export"
|
state.phase = "export"
|
||||||
save_state(state, current_app)
|
save_state(state, current_app)
|
||||||
return jsonify({"ok": True, "redirect": f"/export?album_id={album_id}"})
|
return redirect(f"/export?album_id={album_id}")
|
||||||
|
|||||||
@@ -7,7 +7,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if not group %}
|
{% if not group %}
|
||||||
<div class="alert alert-success">All groups written or skipped. <a href="/export?album_id={{ album_id }}" class="link">Continue to export →</a></div>
|
<div class="alert alert-success mb-4">All groups written or skipped.</div>
|
||||||
|
<form method="post" action="/write/done">
|
||||||
|
<input type="hidden" name="album_id" value="{{ album_id }}">
|
||||||
|
<button type="submit" class="btn btn-primary">Export →</button>
|
||||||
|
</form>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="flex gap-4">
|
<div class="flex gap-4">
|
||||||
|
|
||||||
@@ -101,6 +105,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_scripts %}
|
{% block extra_scripts %}
|
||||||
|
{% if group %}
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
var albumId = {{ album_id | tojson }};
|
var albumId = {{ album_id | tojson }};
|
||||||
@@ -193,4 +198,5 @@
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user