.
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<title>{% block title %}Proc Rota{% endblock %}</title>
|
<title>{% block title %}Proc Rota{% endblock %}</title>
|
||||||
<link rel="stylesheet" href="{% static 'output/timetable.css' %}">
|
<link rel="stylesheet" href="{% static 'output/timetable.css' %}">
|
||||||
|
<link rel="stylesheet" href="{% static 'css/forms.css' %}">
|
||||||
<!-- Inline fallback for critical layout in case static file serving is unavailable -->
|
<!-- Inline fallback for critical layout in case static file serving is unavailable -->
|
||||||
<style>
|
<style>
|
||||||
/* minimal critical styles from timetable.css to avoid broken layout when static not found */
|
/* minimal critical styles from timetable.css to avoid broken layout when static not found */
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
{% if token %}
|
||||||
|
<input type="hidden" name="token" value="{{ token }}">
|
||||||
|
{% endif %}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
@@ -49,7 +52,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
];
|
];
|
||||||
window.initCalendar('calendar', { workerId: container.dataset.workerId, leaves: leaves, requestUrl: '{% url "rota:request_leave" %}', leavesUrl: '{% if worker %}{% url "rota:worker_leaves_json" worker.id %}{% endif %}', mode: container.dataset.mode || 'inline' });
|
window.initCalendar('calendar', { workerId: container.dataset.workerId, leaves: leaves, requestUrl: '{% if token %}{% url "rota:request_leave_token" token %}{% else %}{% url "rota:request_leave" %}{% endif %}', leavesUrl: '{% if worker %}{% url "rota:worker_leaves_json" worker.id %}{% endif %}', mode: container.dataset.mode || 'inline' });
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -301,6 +301,9 @@ def worker_detail(request, worker_id):
|
|||||||
leave = form.save(commit=False)
|
leave = form.save(commit=False)
|
||||||
leave.worker = worker
|
leave.worker = worker
|
||||||
leave.save()
|
leave.save()
|
||||||
|
# For non-HTMX (full-page) submissions just redirect back to the
|
||||||
|
# worker detail page. Token-aware redirects are handled by the
|
||||||
|
# tokenized `request_leave` view (the public token page).
|
||||||
return redirect("rota:worker_detail", worker_id=worker.id)
|
return redirect("rota:worker_detail", worker_id=worker.id)
|
||||||
else:
|
else:
|
||||||
# Pre-fill dates when `date` query param is provided (ISO YYYY-MM-DD)
|
# Pre-fill dates when `date` query param is provided (ISO YYYY-MM-DD)
|
||||||
@@ -512,6 +515,16 @@ def request_leave(request, token=None):
|
|||||||
# Trigger modal close and a leaveUpdated event so client can refresh calendar highlights
|
# Trigger modal close and a leaveUpdated event so client can refresh calendar highlights
|
||||||
response["HX-Trigger"] = "closeModal,leaveUpdated"
|
response["HX-Trigger"] = "closeModal,leaveUpdated"
|
||||||
return response
|
return response
|
||||||
|
# For full-page submissions: if this request was made using a tokenized
|
||||||
|
# URL (public leave request page), keep the user on that token page so
|
||||||
|
# they can see confirmation and existing requests. Otherwise go to the
|
||||||
|
# worker detail page.
|
||||||
|
if token:
|
||||||
|
try:
|
||||||
|
return redirect(reverse('rota:request_leave_token', args=[token]))
|
||||||
|
except Exception:
|
||||||
|
# fallback to worker detail
|
||||||
|
pass
|
||||||
return redirect("rota:worker_detail", worker_id=worker.id)
|
return redirect("rota:worker_detail", worker_id=worker.id)
|
||||||
else:
|
else:
|
||||||
# Prefill dates when provided via query params for both full page and HTMX modal
|
# Prefill dates when provided via query params for both full page and HTMX modal
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/* Nice, light styling for forms and modals used in request flows */
|
||||||
|
:root{
|
||||||
|
--primary:#2b8fd6;
|
||||||
|
--primary-dark:#226a9e;
|
||||||
|
--muted:#6b7280;
|
||||||
|
--bg:#ffffff;
|
||||||
|
--glass: rgba(255,255,255,0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make modal card a pleasant width and add gentle shadow */
|
||||||
|
#modal .modal-card, #modal .modal-content {
|
||||||
|
width: min(820px, 96%);
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal .modal-card-head .modal-card-title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1.15rem;
|
||||||
|
color: #0b2540;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal .modal-card-body {
|
||||||
|
padding-top: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form layout improvements */
|
||||||
|
form .field {
|
||||||
|
margin-bottom: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
form label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--muted);
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make inputs stretch and more modern */
|
||||||
|
input[type="text"], input[type="date"], input[type="email"], input[type="number"], textarea, select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.55rem 0.6rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid #dfe6ee;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.6);
|
||||||
|
background: linear-gradient(180deg,#fff,#fcfdff);
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea { min-height: 100px; }
|
||||||
|
|
||||||
|
.form-errors, .help.is-danger { color: #9b1c1c; background: #fff2f2; padding:0.5rem; border-radius:6px; border:1px solid #f1c0c0 }
|
||||||
|
|
||||||
|
/* Primary button styling */
|
||||||
|
.button.is-primary {
|
||||||
|
background: linear-gradient(180deg,var(--primary),var(--primary-dark));
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
box-shadow: 0 4px 12px rgba(43,143,214,0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.is-primary:hover{ background: linear-gradient(180deg,var(--primary-dark),#1b5a82); }
|
||||||
|
|
||||||
|
.button + .button { margin-left: 0.5rem; }
|
||||||
|
|
||||||
|
/* Small helpers for inline legend */
|
||||||
|
.legend-swatch { display:inline-block; width:12px; height:12px; border-radius:3px; margin-right:0.5rem; vertical-align:middle; border:1px solid #ddd }
|
||||||
|
|
||||||
|
/* Responsive tweaks */
|
||||||
|
@media (max-width: 640px){
|
||||||
|
#modal .modal-card, #modal .modal-content { width: 96%; }
|
||||||
|
.button.is-primary { width: 100%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leave list styling */
|
||||||
|
#leave-list ul { list-style:none; padding:0; margin:0; }
|
||||||
|
#leave-list li { padding:0.6rem 0; border-bottom:1px solid #f3f6f9; display:flex; align-items:center; justify-content:space-between }
|
||||||
|
#leave-list li .leave-range { font-weight:600; color:#0b2540 }
|
||||||
|
#leave-list li em { color:var(--muted); margin-left:0.5rem }
|
||||||
|
#leave-list li form { margin-left:1rem }
|
||||||
Reference in New Issue
Block a user