Merge pull request 'ui chnages' (#4) from frontend into main
Reviewed-on: #4
This commit is contained in:
commit
7f23cc18fb
Binary file not shown.
@ -157,7 +157,7 @@ LOCALE_PATHS = [
|
|||||||
BASE_DIR / 'locale',
|
BASE_DIR / 'locale',
|
||||||
]
|
]
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = 'Asia/Riyadh'
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
|
|||||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
@ -298,20 +298,32 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link {% if request.resolver_match.url_name == 'training_list' %}active{% endif %}" href="{% url 'training_list' %}">
|
<a class="nav-link {% if request.resolver_match.url_name == 'training_list' %}active{% endif %}" href="{% url 'training_list' %}">
|
||||||
<span class="d-flex align-items-center gap-2">
|
<span class="d-flex align-items-center gap-2">
|
||||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" stroke="currentColor" stroke-width="2"></path>
|
<path stroke-linecap="round" stroke-linejoin="round" d="M4.26 10.147a60.438 60.438 0 0 0-.491 6.347A48.62 48.62 0 0 1 12 20.904a48.62 48.62 0 0 1 8.232-4.41 60.46 60.46 0 0 0-.491-6.347m-15.482 0a50.636 50.636 0 0 0-2.658-.813A59.906 59.906 0 0 1 12 3.493a59.903 59.903 0 0 1 10.399 5.84c-.896.248-1.783.52-2.658.814m-15.482 0A50.717 50.717 0 0 1 12 13.489a50.702 50.702 0 0 1 7.74-3.342M6.75 15a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm0 0v-3.675A55.378 55.378 0 0 1 12 8.443m-7.007 11.55A5.981 5.981 0 0 0 6.75 15.75v-1.5" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
{% trans "Training" %}
|
{% trans "Training" %}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link {% if request.resolver_match.url_name == 'list_meetings' %}active{% endif %}" href="{% url 'list_meetings' %}">
|
<a class="nav-link {% if request.resolver_match.url_name == 'list_meetings' %}active{% endif %}" href="{% url 'list_meetings' %}">
|
||||||
|
<span class="d-flex align-items-center gap-2">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
{% trans "Meetings" %}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link {% if request.resolver_match.url_name == 'form_templates_list' %}active{% endif %}" href="{% url 'form_templates_list' %}">
|
||||||
<span class="d-flex align-items-center gap-2">
|
<span class="d-flex align-items-center gap-2">
|
||||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" stroke="currentColor" stroke-width="2"></path>
|
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" stroke="currentColor" stroke-width="2"></path>
|
||||||
</svg>
|
</svg>
|
||||||
{% trans "Meetings" %}
|
{% trans "Form Templates" %}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -9,10 +9,10 @@
|
|||||||
/* Updated CSS styles with a new Teal/Aqua theme */
|
/* Updated CSS styles with a new Teal/Aqua theme */
|
||||||
:root {
|
:root {
|
||||||
/* New Color Palette (Teal/Aqua/Deep Blue) */
|
/* New Color Palette (Teal/Aqua/Deep Blue) */
|
||||||
--primary: #0081a7; /* Deep Teal/Cyan for main actions */
|
--primary: #004a53; /* Deep Teal/Cyan for main actions */
|
||||||
--primary-light: #00b4d8; /* Brighter Aqua/Cyan */
|
--primary-light: #00b4d8; /* Brighter Aqua/Cyan */
|
||||||
--secondary: #005a78; /* Darker Teal for hover/accent */
|
--secondary: #005a78; /* Darker Teal for hover/accent */
|
||||||
--success: #00cc99; /* Bright Greenish-Teal for success */
|
--success: #005a78; /* Bright Greenish-Teal for success */
|
||||||
|
|
||||||
/* Neutral Colors (Kept for consistency) */
|
/* Neutral Colors (Kept for consistency) */
|
||||||
--light: #f4fcfc; /* Very light off-white (slightly blue tinted) */
|
--light: #f4fcfc; /* Very light off-white (slightly blue tinted) */
|
||||||
@ -160,7 +160,7 @@
|
|||||||
}
|
}
|
||||||
/* Stage Navigation - Fixed Height with Scroll */
|
/* Stage Navigation - Fixed Height with Scroll */
|
||||||
.stage-nav-container {
|
.stage-nav-container {
|
||||||
height: 60px;
|
height: 100px;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@ -175,6 +175,7 @@
|
|||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
height:70px;
|
||||||
}
|
}
|
||||||
.stage-tab {
|
.stage-tab {
|
||||||
padding: 12px 20px;
|
padding: 12px 20px;
|
||||||
|
|||||||
@ -6,117 +6,140 @@
|
|||||||
{% block customCSS %}
|
{% block customCSS %}
|
||||||
<style>
|
<style>
|
||||||
/* ================================================= */
|
/* ================================================= */
|
||||||
/* THEME VARIABLES AND GLOBAL STYLES */
|
/* UI Variables (Matching Job List) */
|
||||||
/* ================================================= */
|
/* ================================================= */
|
||||||
:root {
|
:root {
|
||||||
--kaauh-teal: #00636e;
|
--kaauh-teal: #00636e;
|
||||||
--kaauh-teal-dark: #004a53;
|
--kaauh-teal-dark: #004a53;
|
||||||
--kaauh-border: #eaeff3;
|
--kaauh-border: #eaeff3;
|
||||||
--kaauh-primary-text: #343a40;
|
--kaauh-primary-text: #343a40;
|
||||||
|
--kaauh-gray-light: #f8f9fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Primary Color Overrides */
|
/* --- Typography and Color Overrides --- */
|
||||||
.text-primary { color: var(--kaauh-teal) !important; }
|
.text-primary { color: var(--kaauh-teal) !important; }
|
||||||
|
|
||||||
/* Main Action Button Style */
|
/* --- Button Base Styles (Matching Job List) --- */
|
||||||
.btn-main-action, .btn-primary {
|
.btn-main-action {
|
||||||
background-color: var(--kaauh-teal);
|
background-color: var(--kaauh-teal);
|
||||||
border-color: var(--kaauh-teal);
|
border-color: var(--kaauh-teal);
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
padding: 0.6rem 1.2rem;
|
padding: 0.375rem 0.75rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
.btn-main-action:hover, .btn-primary:hover {
|
.btn-main-action:hover {
|
||||||
background-color: var(--kaauh-teal-dark);
|
background-color: var(--kaauh-teal-dark);
|
||||||
border-color: var(--kaauh-teal-dark);
|
border-color: var(--kaauh-teal-dark);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Card enhancements */
|
/* Secondary Button Style (for Edit/Preview) */
|
||||||
|
.btn-outline-secondary {
|
||||||
|
color: var(--kaauh-teal-dark);
|
||||||
|
border-color: var(--kaauh-teal);
|
||||||
|
}
|
||||||
|
.btn-outline-secondary:hover {
|
||||||
|
background-color: var(--kaauh-teal-dark);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--kaauh-teal-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Size Utilities (matching Bootstrap convention) */
|
||||||
|
.btn-lg {
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
.btn-sm {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
padding: 0.3rem 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Card and Layout Styles (Matching Job List) --- */
|
||||||
.card {
|
.card {
|
||||||
border: 1px solid var(--kaauh-border);
|
border: 1px solid var(--kaauh-border);
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
|
||||||
|
|
||||||
/* Template Card hover effect (re-themed) */
|
|
||||||
.template-card {
|
|
||||||
transition: transform 0.2s, box-shadow 0.2s;
|
transition: transform 0.2s, box-shadow 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Template Card Hover Effect (Consistent with job list card hover) */
|
||||||
|
.template-card {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.05) !important;
|
|
||||||
}
|
}
|
||||||
.template-card:hover {
|
.template-card:hover {
|
||||||
transform: translateY(-5px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
|
box-shadow: 0 6px 16px rgba(0,0,0,0.1) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Card Header Theming */
|
/* Card Header Theming */
|
||||||
.card-header {
|
.card-header {
|
||||||
background-color: #f0f8ff !important; /* Light blue tint for header */
|
/* FIX: Use !important to override default white/light backgrounds from Bootstrap */
|
||||||
|
background-color: var(--kaauh-teal-dark) !important;
|
||||||
border-bottom: 1px solid var(--kaauh-border);
|
border-bottom: 1px solid var(--kaauh-border);
|
||||||
color: var(--kaauh-teal-dark);
|
color: white !important; /* Base color for header text */
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
border-radius: 0.75rem 0.75rem 0 0;
|
border-radius: 0.75rem 0.75rem 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure all elements within the header are visible */
|
||||||
.card-header h3 {
|
.card-header h3 {
|
||||||
color: var(--kaauh-teal-dark);
|
color: white !important;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.card-header .fas {
|
.card-header .fas {
|
||||||
color: var(--kaauh-teal);
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
.card-header .small {
|
||||||
/* Stats Theming */
|
color: rgba(255, 255, 255, 0.7) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Content Styles (Stats, Description) --- */
|
||||||
.stat-value {
|
.stat-value {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: var(--kaauh-teal-dark); /* Using dark teal for stats */
|
color: var(--kaauh-teal-dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-label {
|
.stat-label {
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
color: var(--kaauh-primary-text);
|
color: var(--kaauh-primary-text);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-description {
|
.card-description {
|
||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
color: var(--kaauh-primary-text);
|
color: var(--kaauh-primary-text);
|
||||||
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search Input Theming */
|
/* --- Form/Search Input Theming (Matching Job List) --- */
|
||||||
.form-control {
|
.form-control-search {
|
||||||
|
box-shadow: none;
|
||||||
|
border-color: var(--kaauh-border);
|
||||||
|
border-radius: 0 0.5rem 0.5rem 0;
|
||||||
|
}
|
||||||
|
.form-control-search:focus {
|
||||||
|
border-color: var(--kaauh-teal);
|
||||||
|
box-shadow: 0 0 0 0.1rem rgba(0, 99, 110, 0.25);
|
||||||
|
}
|
||||||
|
.input-group-search .input-group-text {
|
||||||
|
background-color: white;
|
||||||
|
border-right: none;
|
||||||
|
border-color: var(--kaauh-border);
|
||||||
border-radius: 0.5rem 0 0 0.5rem;
|
border-radius: 0.5rem 0 0 0.5rem;
|
||||||
border-color: var(--kaauh-border);
|
|
||||||
}
|
}
|
||||||
.input-group .btn-outline-secondary {
|
.input-group-search .form-control {
|
||||||
border-radius: 0 0.5rem 0.5rem 0;
|
|
||||||
border-left: none;
|
border-left: none;
|
||||||
color: var(--kaauh-teal);
|
|
||||||
border-color: var(--kaauh-border);
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
}
|
|
||||||
.input-group .btn-outline-secondary:hover {
|
|
||||||
background-color: #e9ecef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Action Buttons (Re-theming outline colors) */
|
/* --- Danger Outline (Delete) --- */
|
||||||
.btn-outline-primary {
|
|
||||||
--bs-btn-color: var(--kaauh-teal-dark);
|
|
||||||
--bs-btn-border-color: var(--kaauh-teal);
|
|
||||||
--bs-btn-hover-bg: var(--kaauh-teal);
|
|
||||||
--bs-btn-hover-border-color: var(--kaauh-teal);
|
|
||||||
--bs-btn-hover-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete Button - keep bold red */
|
|
||||||
.btn-outline-danger {
|
.btn-outline-danger {
|
||||||
--bs-btn-color: #dc3545;
|
--bs-btn-color: #dc3545;
|
||||||
--bs-btn-border-color: #dc3545;
|
--bs-btn-border-color: #dc3545;
|
||||||
@ -124,97 +147,138 @@
|
|||||||
--bs-btn-hover-color: white;
|
--bs-btn-hover-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Empty State Theming */
|
/* --- Empty State Theming --- */
|
||||||
.empty-state {
|
.empty-state {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 3rem 1rem;
|
padding: 3rem 1rem;
|
||||||
color: var(--kaauh-primary-text);
|
color: var(--kaauh-primary-text);
|
||||||
border: 2px dashed var(--kaauh-border);
|
border: 2px dashed var(--kaauh-border);
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
background-color: #f8f9fa;
|
background-color: var(--kaauh-gray-light);
|
||||||
}
|
}
|
||||||
.empty-state i {
|
.empty-state i {
|
||||||
font-size: 3.5rem;
|
font-size: 3.5rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
color: var(--kaauh-teal);
|
color: var(--kaauh-teal-dark);
|
||||||
|
}
|
||||||
|
.empty-state .btn-main-action .fas {
|
||||||
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pagination Styling */
|
/* --- Pagination Styling (Matching Job List) --- */
|
||||||
.pagination .page-link {
|
.pagination .page-item .page-link {
|
||||||
color: var(--kaauh-teal-dark);
|
color: var(--kaauh-teal-dark);
|
||||||
|
border-color: var(--kaauh-border);
|
||||||
}
|
}
|
||||||
.pagination .page-item.active .page-link {
|
.pagination .page-item.active .page-link {
|
||||||
background-color: var(--kaauh-teal);
|
background-color: var(--kaauh-teal);
|
||||||
border-color: var(--kaauh-teal);
|
border-color: var(--kaauh-teal);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
.pagination .page-item:not(.active) .page-link:hover {
|
.pagination .page-item:hover .page-link:not(.active) {
|
||||||
background-color: #e9ecef;
|
background-color: #e9ecef;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container py-4">
|
<div class="container py-4">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4 pb-2 border-bottom border-primary">
|
<div class="d-flex justify-content-between align-items-center mb-4 pb-2 border-bottom border-primary">
|
||||||
<h1 class="h3 mb-0 fw-bold text-primary">
|
<h1 class="h3 mb-0 fw-bold" style="color: var(--kaauh-teal-dark); font-weight: 700;">
|
||||||
<i class="fas fa-file-alt me-2"></i>Form Templates
|
<i class="fas fa-file-alt me-2"></i>{% trans "Form Templates" %}
|
||||||
</h1>
|
</h1>
|
||||||
<a href="{% url 'form_builder' %}" class="btn btn-main-action">
|
<a href="{% url 'form_builder' %}" class="btn btn-main-action">
|
||||||
<i class="fas fa-plus me-1"></i> Create New Template
|
<i class="fas fa-plus me-1"></i> {% trans "Create New Template" %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-4">
|
{# Search/Filter Area - Matching Job List Structure #}
|
||||||
<div class="col-md-6">
|
<div class="card mb-4 shadow-sm no-hover">
|
||||||
<div class="input-group">
|
<div class="card-body">
|
||||||
<input type="text" class="form-control" id="searchInput" placeholder="Search templates..." value="{{ query }}">
|
<h5 class="card-title text-muted mb-3" style="font-weight: 500;">Search Templates</h5>
|
||||||
<button class="btn btn-outline-secondary" type="button" id="searchBtn">
|
<form method="get" class="row g-3 align-items-end">
|
||||||
<i class="fas fa-search"></i>
|
|
||||||
</button>
|
<div class="col-md-6">
|
||||||
</div>
|
<label for="search" class="form-label small text-muted">Search by Template Name</label>
|
||||||
|
<div class="input-group input-group-lg input-group-search">
|
||||||
|
<span class="input-group-text"><i class="fas fa-search text-muted"></i></span>
|
||||||
|
<input type="text" name="q" id="searchInput" class="form-control form-control-search"
|
||||||
|
placeholder="{% trans 'Search templates by name...' %}"
|
||||||
|
value="{{ query|default_if_none:'' }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="filter-buttons">
|
||||||
|
<button type="submit" class="btn btn-main-action btn-lg">
|
||||||
|
<i class="fas fa-filter me-1"></i> Search
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{# Show Clear button if search is active #}
|
||||||
|
{% if query %}
|
||||||
|
<a href="{% url 'form_templates_list' %}" class="btn btn-outline-danger btn-sm">
|
||||||
|
<i class="fas fa-times me-1"></i> Clear Search
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% if templates %}
|
{% if templates %}
|
||||||
<div class="row g-4">
|
<div class="row g-4">
|
||||||
{% for template in templates %}
|
{% for template in templates %}
|
||||||
<div class="col-lg-4 col-md-6">
|
<div class="col-lg-4 col-md-6">
|
||||||
<div class="card template-card h-100 shadow-sm">
|
<div class="card template-card h-100">
|
||||||
<div class="card-header">
|
<div class="card-header ">
|
||||||
<h3 class="h5 mb-2">{{ template.name }}</h3>
|
<h3 class="h5 mb-2">{{ template.name }}</h3>
|
||||||
<div class="d-flex justify-content-between text-muted small">
|
<div class="d-flex justify-content-between small">
|
||||||
<span><i class="fas fa-calendar me-1"></i> {{ template.created_at|date:"M d, Y" }}</span>
|
<span><i class="fas fa-calendar me-1"></i> {{ template.created_at|date:"M d, Y" }}</span>
|
||||||
<span><i class="fas fa-sync-alt me-1"></i> {{ template.updated_at|timesince }} ago</span>
|
<span><i class="fas fa-sync-alt me-1"></i> {{ template.updated_at|timesince }} {% trans "ago" %}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body d-flex flex-column">
|
<div class="card-body d-flex flex-column">
|
||||||
<div class="row text-center mb-3">
|
|
||||||
<div class="col-6">
|
{# Content area - includes stats and description #}
|
||||||
<div class="stat-value">{{ template.get_stage_count }}</div>
|
<div class="flex-grow-1">
|
||||||
<div class="stat-label">Stages</div>
|
<div class="row text-center mb-3">
|
||||||
</div>
|
<div class="col-6">
|
||||||
<div class="col-6">
|
<div class="stat-value">{{ template.get_stage_count }}</div>
|
||||||
<div class="stat-value">{{ template.get_field_count }}</div>
|
<div class="stat-label">{% trans "Stages" %}</div>
|
||||||
<div class="stat-label">Fields</div>
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="stat-value">{{ template.get_field_count }}</div>
|
||||||
|
<div class="stat-label">{% trans "Fields" %}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="card-text card-description small">
|
||||||
|
{% if template.description %}
|
||||||
|
{{ template.description|truncatewords:20 }}
|
||||||
|
{% else %}
|
||||||
|
<em class="text-muted">{% trans "No description provided" %}</em>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p class="card-text card-description flex-grow-1 small">
|
|
||||||
{% if template.description %}
|
{# Action area - visually separated with pt-2 border-top #}
|
||||||
{{ template.description|truncatewords:20 }}
|
<div class="mt-auto pt-2 border-top">
|
||||||
{% else %}
|
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||||
<em class="text-muted">No description provided</em>
|
<a href="{% url 'form_wizard' template.id %}" class="btn btn-outline-secondary btn-sm action-btn">
|
||||||
{% endif %}
|
<i class="fas fa-eye me-1"></i> {% trans "Preview" %}
|
||||||
</p>
|
</a>
|
||||||
<div class="card-actions d-grid gap-2 d-md-flex justify-content-md-end pt-3 border-top border-light-subtle">
|
<a href="{% url 'form_builder' template.id %}" class="btn btn-outline-secondary btn-sm action-btn">
|
||||||
<a href="{% url 'form_builder' template.id %}" class="btn btn-outline-primary btn-sm action-btn">
|
<i class="fas fa-edit me-1"></i> {% trans "Edit" %}
|
||||||
<i class="fas fa-edit me-1"></i> Edit
|
</a>
|
||||||
</a>
|
<button class="btn btn-outline-danger btn-sm action-btn delete"
|
||||||
<button class="btn btn-outline-danger btn-sm action-btn delete"
|
data-template-id="{{ template.id }}"
|
||||||
data-template-id="{{ template.id }}"
|
data-template-name="{{ template.name }}">
|
||||||
data-template-name="{{ template.name }}">
|
<i class="fas fa-trash me-1"></i> {% trans "Delete" %}
|
||||||
<i class="fas fa-trash me-1"></i> Delete
|
</button>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -223,71 +287,70 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if templates.has_other_pages %}
|
{% if templates.has_other_pages %}
|
||||||
<div class="d-flex justify-content-center mt-4">
|
<nav aria-label="Page navigation" class="mt-4">
|
||||||
<nav aria-label="Page navigation">
|
<ul class="pagination justify-content-center">
|
||||||
<ul class="pagination mb-0">
|
{# Previous page logic #}
|
||||||
{% if templates.has_previous %}
|
{% if templates.has_previous %}
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a class="page-link" href="?page={{ templates.previous_page_number }}{% if query %}&q={{ query }}{% endif %}" aria-label="Previous">
|
<a class="page-link" href="?page=1{% if query %}&q={{ query }}{% endif %}">First</a>
|
||||||
<span aria-hidden="true">«</span>
|
</li>
|
||||||
</a>
|
<li class="page-item">
|
||||||
</li>
|
<a class="page-link" href="?page={{ templates.previous_page_number }}{% if query %}&q={{ query }}{% endif %}">Previous</a>
|
||||||
{% endif %}
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% for num in templates.paginator.page_range %}
|
{# Current Page #}
|
||||||
{% if templates.number == num %}
|
<li class="page-item active">
|
||||||
<li class="page-item active"><span class="page-link">{{ num }}</span></li>
|
<span class="page-link">{{ templates.number }} of {{ templates.paginator.num_pages }}</span>
|
||||||
{% elif num > templates.number|add:'-3' and num < templates.number|add:'3' %}
|
</li>
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" href="?page={{ num }}{% if query %}&q={{ query }}{% endif %}">{{ num }}</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if templates.has_next %}
|
{# Next page logic #}
|
||||||
<li class="page-item">
|
{% if templates.has_next %}
|
||||||
<a class="page-link" href="?page={{ templates.next_page_number }}{% if query %}&q={{ query }}{% endif %}" aria-label="Next">
|
<li class="page-item">
|
||||||
<span aria-hidden="true">»</span>
|
<a class="page-link" href="?page={{ templates.next_page_number }}{% if query %}&q={{ query }}{% endif %}">Next</a>
|
||||||
</a>
|
</li>
|
||||||
</li>
|
<li class="page-item">
|
||||||
{% endif %}
|
<a class="page-link" href="?page={{ templates.paginator.num_pages }}{% if query %}&q={{ query }}{% endif %}">Last</a>
|
||||||
</ul>
|
</li>
|
||||||
</nav>
|
{% endif %}
|
||||||
</div>
|
</ul>
|
||||||
|
</nav>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="empty-state">
|
<div class="text-center py-5 card shadow-sm">
|
||||||
<i class="fas fa-file-contract"></i>
|
<div class="card-body">
|
||||||
<h3 class="h4 mb-3">No Form Templates Found</h3>
|
<i class="fas fa-file-contract fa-3x mb-3" style="color: var(--kaauh-teal-dark);"></i>
|
||||||
<p class="mb-4 text-muted">
|
<h3 class="h4 mb-3">{% trans "No Form Templates Found" %}</h3>
|
||||||
{% if query %}No templates match your search "{{ query }}".{% else %}You haven't created any form templates yet.{% endif %}
|
<p class="text-muted">
|
||||||
</p>
|
{% if query %}
|
||||||
<a href="{% url 'form_builder' %}" class="btn btn-main-action">
|
{% blocktrans with query=query %}No templates match your search "{{ query }}".{% endblocktrans %}
|
||||||
<i class="fas fa-plus me-1"></i> Create Your First Template
|
{% else %}
|
||||||
</a>
|
{% trans "You haven't created any form templates yet." %}
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
<a href="{% url 'form_builder' %}" class="btn btn-main-action mt-3">
|
||||||
|
<i class="fas fa-plus me-1 text-white"></i> {% trans "Create Your First Template" %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include 'includes/delete_modal.html' %}
|
{% include 'includes/delete_modal.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_js %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
// Note: JS logic remains the same, assuming 'csrfToken' is available in 'base.html' or elsewhere.
|
// JS logic remains the same as previous versions but ensures Django variables are handled
|
||||||
|
|
||||||
// Initialize Bootstrap modal
|
|
||||||
const deleteModal = new bootstrap.Modal(document.getElementById('deleteModal'));
|
const deleteModal = new bootstrap.Modal(document.getElementById('deleteModal'));
|
||||||
|
|
||||||
// Create toast container if it doesn't exist (using theme styles)
|
|
||||||
let toastContainer = document.querySelector('.toast-container');
|
let toastContainer = document.querySelector('.toast-container');
|
||||||
if (!toastContainer) {
|
if (!toastContainer) {
|
||||||
toastContainer = document.createElement('div');
|
toastContainer = document.createElement('div');
|
||||||
toastContainer.className = 'toast-container';
|
toastContainer.className = 'toast-container position-fixed bottom-0 end-0 p-3';
|
||||||
document.body.appendChild(toastContainer);
|
document.body.appendChild(toastContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to create toast notification
|
|
||||||
function createToast(message, type = 'success') {
|
function createToast(message, type = 'success') {
|
||||||
const toastId = 'toast-' + Date.now();
|
const toastId = 'toast-' + Date.now();
|
||||||
const iconClass = type === 'success' ? 'check-circle text-success' : 'exclamation-circle text-danger';
|
const iconClass = type === 'success' ? 'check-circle text-success' : 'exclamation-circle text-danger';
|
||||||
@ -310,24 +373,29 @@
|
|||||||
const toast = new bootstrap.Toast(toastElement);
|
const toast = new bootstrap.Toast(toastElement);
|
||||||
toast.show();
|
toast.show();
|
||||||
|
|
||||||
// Remove toast element after it's hidden
|
|
||||||
toastElement.addEventListener('hidden.bs.toast', () => {
|
toastElement.addEventListener('hidden.bs.toast', () => {
|
||||||
toastElement.remove();
|
toastElement.remove();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search functionality
|
// Search functionality - handles submission on Enter key
|
||||||
document.getElementById('searchBtn').addEventListener('click', function() {
|
|
||||||
const query = document.getElementById('searchInput').value;
|
|
||||||
// Assuming the query parameter for search is 'q' based on pagination logic
|
|
||||||
window.location.href = query ? `?q=${encodeURIComponent(query)}` : '?';
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('searchInput').addEventListener('keypress', function(e) {
|
document.getElementById('searchInput').addEventListener('keypress', function(e) {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
document.getElementById('searchBtn').click();
|
e.preventDefault();
|
||||||
|
const query = this.value;
|
||||||
|
// Assumes 'form_templates_list' is the view name for this page
|
||||||
|
window.location.href = query ? `?q=${encodeURIComponent(query)}` : '{% url "form_templates_list" %}';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Bind search form submit to the main button click event for consistency
|
||||||
|
document.querySelector('.filter-buttons button[type="submit"]').addEventListener('click', function(e) {
|
||||||
|
// Prevent default submission to handle URL construction correctly
|
||||||
|
e.preventDefault();
|
||||||
|
const query = document.getElementById('searchInput').value;
|
||||||
|
window.location.href = query ? `?q=${encodeURIComponent(query)}` : '{% url "form_templates_list" %}';
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Delete modal functionality
|
// Delete modal functionality
|
||||||
let templateToDelete = null;
|
let templateToDelete = null;
|
||||||
@ -348,12 +416,12 @@
|
|||||||
|
|
||||||
if (!templateToDelete) return;
|
if (!templateToDelete) return;
|
||||||
|
|
||||||
// This relies on 'csrfToken' being defined somewhere, which is typical for Django templates.
|
// This CSRF token selector assumes it's present in your base template or form
|
||||||
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
|
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Note: Update this API path if necessary based on your actual URL configuration
|
// NOTE: Update this URL to match your actual Django API endpoint for deletion
|
||||||
const response = await fetch(`/api/templates/${templateToDelete}/delete/`, {
|
const response = await fetch(`/api/templates/${templateToDelete}/delete/`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: {
|
headers: {
|
||||||
'X-CSRFToken': csrfToken,
|
'X-CSRFToken': csrfToken,
|
||||||
@ -365,15 +433,11 @@
|
|||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
// Show success toast
|
|
||||||
createToast(result.message);
|
createToast(result.message);
|
||||||
|
|
||||||
// Hide the modal
|
|
||||||
deleteModal.hide();
|
deleteModal.hide();
|
||||||
|
|
||||||
// Remove the template card from the DOM after a short delay
|
// Smoothly remove the card
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Find the button that was clicked and its parent card column
|
|
||||||
const buttonClicked = document.querySelector(`button[data-template-id="${templateToDelete}"]`);
|
const buttonClicked = document.querySelector(`button[data-template-id="${templateToDelete}"]`);
|
||||||
if(buttonClicked) {
|
if(buttonClicked) {
|
||||||
const cardToRemove = buttonClicked.closest('.col-lg-4');
|
const cardToRemove = buttonClicked.closest('.col-lg-4');
|
||||||
@ -385,10 +449,9 @@
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
cardToRemove.remove();
|
cardToRemove.remove();
|
||||||
|
|
||||||
// Check if any templates remain
|
// Reload if the last card is removed to show the empty state
|
||||||
const remainingCards = document.querySelectorAll('.col-lg-4');
|
const remainingCards = document.querySelectorAll('.col-lg-4');
|
||||||
if (remainingCards.length === 0) {
|
if (remainingCards.length === 0) {
|
||||||
// Reload to show the empty state
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
@ -396,7 +459,6 @@
|
|||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
} else {
|
} else {
|
||||||
// Show error toast
|
|
||||||
createToast('Error: ' + (result.error || 'Could not delete template.'), 'error');
|
createToast('Error: ' + (result.error || 'Could not delete template.'), 'error');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -8,34 +8,42 @@
|
|||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
<style>
|
<style>
|
||||||
|
/* KAAT-S Theme Variables */
|
||||||
:root {
|
:root {
|
||||||
--primary: #4361ee;
|
--kaauh-teal: #00636e; /* Main Primary Color */
|
||||||
--primary-light: #4895ef;
|
--kaauh-teal-dark: #004a53; /* Dark Primary Color */
|
||||||
--secondary: #3f37c9;
|
|
||||||
--success: #4cc9f0;
|
/* Mapping wizard defaults to theme colors */
|
||||||
|
--primary: var(--kaauh-teal);
|
||||||
|
--primary-light: #007c89; /* Slightly lighter shade for subtle hover/border */
|
||||||
|
--secondary: var(--kaauh-teal-dark);
|
||||||
|
--success: #198754; /* Keeping a standard success green for Submit */
|
||||||
|
--error: #dc3545; /* Standard danger red */
|
||||||
|
|
||||||
--light: #f8f9fa;
|
--light: #f8f9fa;
|
||||||
--dark: #212529;
|
--dark: #212529;
|
||||||
--gray: #6c757d;
|
--gray: #6c757d;
|
||||||
--light-gray: #e9ecef;
|
--light-gray: #e9ecef;
|
||||||
--border: #dee2e6;
|
--border: #dee2e6;
|
||||||
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
--radius: 8px;
|
--radius: 16px; /* Increased radius for a softer look */
|
||||||
--transition: all 0.3s ease;
|
--transition: all 0.3s ease;
|
||||||
--error: #e53935;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
/* Dark gradient background to match the theme */
|
||||||
|
background: linear-gradient(135deg, var(--kaauh-teal-dark) 0%, #1e3a47 100%);
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wizard-container {
|
.wizard-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 700px;
|
max-width: 800px; /* Increased max-width slightly for content */
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -47,7 +55,7 @@
|
|||||||
|
|
||||||
/* Progress Bar */
|
/* Progress Bar */
|
||||||
.progress-container {
|
.progress-container {
|
||||||
height: 6px;
|
height: 8px; /* Slightly thicker bar */
|
||||||
background: var(--light-gray);
|
background: var(--light-gray);
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -55,7 +63,7 @@
|
|||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: var(--primary);
|
background: var(--primary); /* Teal color */
|
||||||
transition: width 0.4s ease;
|
transition: width 0.4s ease;
|
||||||
width: 0%;
|
width: 0%;
|
||||||
}
|
}
|
||||||
@ -71,7 +79,7 @@
|
|||||||
.logo {
|
.logo {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--primary);
|
color: var(--secondary); /* Dark teal for logo */
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
@ -97,7 +105,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding-right: 10px;
|
padding-right: 15px; /* Space for scrollbar */
|
||||||
}
|
}
|
||||||
|
|
||||||
.stage-title {
|
.stage-title {
|
||||||
@ -119,6 +127,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
.required-indicator {
|
.required-indicator {
|
||||||
@ -138,13 +147,13 @@
|
|||||||
|
|
||||||
.form-input:focus {
|
.form-input:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: var(--primary);
|
border-color: var(--primary); /* Teal focus border */
|
||||||
box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2);
|
box-shadow: 0 0 0 4px rgba(0, 99, 110, 0.2); /* Teal shadow */
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-input.error {
|
.form-input.error {
|
||||||
border-color: var(--error);
|
border-color: var(--error);
|
||||||
box-shadow: 0 0 0 3px rgba(229, 57, 53, 0.2);
|
box-shadow: 0 0 0 4px rgba(220, 53, 69, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-message {
|
.error-message {
|
||||||
@ -175,18 +184,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.file-upload-area:hover {
|
.file-upload-area:hover {
|
||||||
border-color: var(--primary);
|
border-color: var(--primary); /* Teal hover border */
|
||||||
background: rgba(67, 97, 238, 0.05);
|
background: rgba(0, 99, 110, 0.05); /* Light teal background */
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-upload-area.error {
|
.file-upload-area.error {
|
||||||
border-color: var(--error);
|
border-color: var(--error);
|
||||||
background: rgba(229, 57, 53, 0.05);
|
background: rgba(220, 53, 69, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-upload-icon {
|
.file-upload-icon {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
color: var(--primary);
|
color: var(--primary); /* Teal icon */
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +205,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.file-upload-text strong {
|
.file-upload-text strong {
|
||||||
color: var(--primary);
|
color: var(--primary); /* Teal text */
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-upload-info {
|
.file-upload-info {
|
||||||
@ -222,7 +231,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.file-icon {
|
.file-icon {
|
||||||
color: var(--primary);
|
color: var(--primary); /* Teal icon */
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +247,7 @@
|
|||||||
.remove-file-btn {
|
.remove-file-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
color: #e53935;
|
color: var(--error);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
@ -251,7 +260,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.remove-file-btn:hover {
|
.remove-file-btn:hover {
|
||||||
background: #ffebee;
|
background: rgba(220, 53, 69, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Radio/Checkbox Styles */
|
/* Radio/Checkbox Styles */
|
||||||
@ -271,13 +280,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.option-item.selected {
|
.option-item.selected {
|
||||||
border-color: var(--primary);
|
border-color: var(--primary); /* Teal border */
|
||||||
background: rgba(67, 97, 238, 0.05);
|
background: rgba(0, 99, 110, 0.05); /* Light teal background */
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-item.error {
|
.option-item.error {
|
||||||
border-color: var(--error);
|
border-color: var(--error);
|
||||||
background: rgba(229, 57, 53, 0.05);
|
background: rgba(220, 53, 69, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensures radio/checkbox controls themselves use the primary color */
|
||||||
|
.option-item input[type="radio"]:checked,
|
||||||
|
.option-item input[type="checkbox"]:checked {
|
||||||
|
accent-color: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-item input {
|
.option-item input {
|
||||||
@ -338,33 +353,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn-back {
|
.btn-back {
|
||||||
background: var(--light);
|
background: var(--light-gray); /* Match theme's light gray */
|
||||||
color: var(--gray);
|
color: var(--gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-back:hover {
|
.btn-back:hover {
|
||||||
background: var(--light-gray);
|
background: #d8dadc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-next {
|
.btn-next {
|
||||||
background: var(--primary);
|
background: var(--primary); /* Teal color */
|
||||||
color: white;
|
color: white;
|
||||||
box-shadow: 0 4px 12px rgba(67, 97, 238, 0.3);
|
box-shadow: 0 4px 12px rgba(0, 99, 110, 0.3); /* Teal shadow */
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-next:hover {
|
.btn-next:hover {
|
||||||
background: var(--secondary);
|
background: var(--secondary); /* Darker teal on hover */
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-submit {
|
.btn-submit {
|
||||||
background: var(--success);
|
background: var(--success); /* Green for submit */
|
||||||
color: white;
|
color: white;
|
||||||
box-shadow: 0 4px 12px rgba(76, 201, 240, 0.3);
|
box-shadow: 0 4px 12px rgba(25, 135, 84, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-submit:hover {
|
.btn-submit:hover {
|
||||||
background: #3ab0d9;
|
background: #157347;
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,6 +388,7 @@
|
|||||||
.wizard-container {
|
.wizard-container {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stage-title {
|
.stage-title {
|
||||||
@ -395,7 +411,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="wizard-container">
|
<div class="wizard-container">
|
||||||
<!-- Progress Bar -->
|
|
||||||
<div class="progress-container">
|
<div class="progress-container">
|
||||||
<div class="progress-bar" id="progressBar"></div>
|
<div class="progress-bar" id="progressBar"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -410,8 +425,7 @@
|
|||||||
|
|
||||||
<div class="wizard-content">
|
<div class="wizard-content">
|
||||||
<div class="stage-container" id="stageContainer">
|
<div class="stage-container" id="stageContainer">
|
||||||
<!-- Stages will be rendered here -->
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="preview-container" id="previewContainer" style="display: none;">
|
<div class="preview-container" id="previewContainer" style="display: none;">
|
||||||
<h3 class="mb-4">Review Your Application</h3>
|
<h3 class="mb-4">Review Your Application</h3>
|
||||||
@ -770,8 +784,8 @@
|
|||||||
elements.submitBtn.style.display = 'none';
|
elements.submitBtn.style.display = 'none';
|
||||||
elements.nextBtn.style.display = 'flex';
|
elements.nextBtn.style.display = 'flex';
|
||||||
elements.nextBtn.textContent = state.currentStage === state.stages.length - 1 ?
|
elements.nextBtn.textContent = state.currentStage === state.stages.length - 1 ?
|
||||||
'Preview <i class="fas fa-arrow-right"></i>' :
|
'Preview' :
|
||||||
'Next <i class="fas fa-arrow-right"></i>';
|
'Next'
|
||||||
}
|
}
|
||||||
|
|
||||||
function createFieldElement(field) {
|
function createFieldElement(field) {
|
||||||
|
|||||||
@ -3,6 +3,144 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Create Zoom Meeting" %} - {{ block.super }}{% endblock %}
|
{% block title %}{% trans "Create Zoom Meeting" %} - {{ block.super }}{% endblock %}
|
||||||
|
|
||||||
|
{% block customCSS %}
|
||||||
|
<style>
|
||||||
|
/* UI Variables for the KAAT-S Theme */
|
||||||
|
:root {
|
||||||
|
--kaauh-teal: #00636e;
|
||||||
|
--kaauh-teal-dark: #004a53;
|
||||||
|
--kaauh-border: #eaeff3;
|
||||||
|
--kaauh-primary-text: #343a40;
|
||||||
|
--kaauh-gray: #6c757d;
|
||||||
|
|
||||||
|
/* Status Colors are mostly for list views, but included for completeness */
|
||||||
|
--kaauh-success: var(--kaauh-teal);
|
||||||
|
--kaauh-warning: #ffc107;
|
||||||
|
--kaauh-danger: #dc3545;
|
||||||
|
--kaauh-secondary: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CARD STYLING */
|
||||||
|
.card {
|
||||||
|
border: 1px solid var(--kaauh-border);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
||||||
|
max-width: 600px; /* Constrain width for a better form layout */
|
||||||
|
margin: 2rem auto; /* Center the form card */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HEADER STYLING */
|
||||||
|
.card-header {
|
||||||
|
background-color: white; /* Ensure header background is white */
|
||||||
|
border-bottom: 1px solid var(--kaauh-border);
|
||||||
|
padding: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-top-left-radius: 0.75rem;
|
||||||
|
border-top-right-radius: 0.75rem;
|
||||||
|
}
|
||||||
|
.card-header h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: var(--kaauh-teal-dark);
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
.card-header h1 svg {
|
||||||
|
width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FORM STYLING */
|
||||||
|
form {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
.form-row {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
.form-label {
|
||||||
|
display: block;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--kaauh-gray);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
/* Style for Django form fields (assuming they render as input/select) */
|
||||||
|
.form-row input,
|
||||||
|
.form-row select {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--kaauh-primary-text);
|
||||||
|
background-color: #fff;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: 1px solid var(--kaauh-border);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||||
|
}
|
||||||
|
.form-row input:focus,
|
||||||
|
.form-row select:focus {
|
||||||
|
border-color: var(--kaauh-teal);
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: 0 0 0 0.1rem rgba(0, 99, 110, 0.25);
|
||||||
|
}
|
||||||
|
/* Ensure the datetime picker input is styled correctly */
|
||||||
|
input[type="datetime-local"] {
|
||||||
|
font-family: inherit; /* Fixes font for datetime-local */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BUTTON STYLING */
|
||||||
|
/* Base style for all buttons */
|
||||||
|
.btn-base {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
text-decoration: none; /* Remove underline from anchor buttons */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary Action Button (Create/Submit) */
|
||||||
|
.btn-main-action {
|
||||||
|
background-color: var(--kaauh-teal);
|
||||||
|
border-color: var(--kaauh-teal);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.btn-main-action:hover {
|
||||||
|
background-color: var(--kaauh-teal-dark);
|
||||||
|
border-color: var(--kaauh-teal-dark);
|
||||||
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Outline Secondary (Cancel/Back) */
|
||||||
|
.btn-kaats-outline-secondary {
|
||||||
|
color: var(--kaauh-secondary);
|
||||||
|
border-color: var(--kaauh-secondary);
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.btn-kaats-outline-secondary:hover {
|
||||||
|
background-color: var(--kaauh-secondary);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--kaauh-secondary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
@ -12,33 +150,40 @@
|
|||||||
</svg>
|
</svg>
|
||||||
{% trans "Create New Zoom Meeting" %}
|
{% trans "Create New Zoom Meeting" %}
|
||||||
</h1>
|
</h1>
|
||||||
<a href="{% url 'list_meetings' %}" class="btn btn-secondary">{% trans "Back to Meetings" %}</a>
|
{# Using custom secondary button for 'Back to Meetings' link #}
|
||||||
|
<a href="{% url 'list_meetings' %}" class="btn-base btn-kaats-outline-secondary">
|
||||||
|
{% trans "Back to Meetings" %}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label class="form-label">{% trans "Topic" %}</label>
|
<label class="form-label" for="{{ form.topic.id_for_label }}">{% trans "Topic" %}</label>
|
||||||
{{ form.topic }}
|
{{ form.topic }}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label class="form-label">{% trans "Start Time" %}</label>
|
<label class="form-label" for="{{ form.start_time.id_for_label }}">{% trans "Start Time" %}</label>
|
||||||
{{ form.start_time }}
|
{{ form.start_time }}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label class="form-label">{% trans "Duration (minutes)" %}</label>
|
<label class="form-label" for="{{ form.duration.id_for_label }}">{% trans "Duration (minutes)" %}</label>
|
||||||
{{ form.duration }}
|
{{ form.duration }}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
|
||||||
<button type="submit" class="btn btn-primary">
|
{# Action Buttons at the bottom #}
|
||||||
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<div class="form-row d-flex gap-3">
|
||||||
|
<button type="submit" class="btn-base btn-main-action">
|
||||||
|
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width: 1.25rem;">
|
||||||
<path d="M5 13l4 4L19 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
<path d="M5 13l4 4L19 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
</svg>
|
</svg>
|
||||||
{% trans "Create Meeting" %}
|
{% trans "Create Meeting" %}
|
||||||
</button>
|
</button>
|
||||||
<a href="{% url 'list_meetings' %}" class="btn btn-secondary">{% trans "Cancel" %}</a>
|
{# Using custom secondary button for 'Cancel' link #}
|
||||||
|
<a href="{% url 'list_meetings' %}" class="btn-base btn-kaats-outline-secondary">
|
||||||
|
{% trans "Cancel" %}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -2,52 +2,130 @@
|
|||||||
{% load static i18n %}
|
{% load static i18n %}
|
||||||
|
|
||||||
{% block title %}{% trans "Zoom Meetings" %} - {{ block.super }}{% endblock %}
|
{% block title %}{% trans "Zoom Meetings" %} - {{ block.super }}{% endblock %}
|
||||||
{% block extra_css %}
|
{% block customCSS %}
|
||||||
<style>
|
<style>
|
||||||
/* New Teal/Aqua Theme Variables */
|
/* UI Variables for the KAAT-S Theme */
|
||||||
:root {
|
:root {
|
||||||
--primary: #0081a7; /* Deep Teal/Cyan */
|
--kaauh-teal: #00636e;
|
||||||
--primary-light: #00b4d8; /* Brighter Aqua/Cyan */
|
--kaauh-teal-dark: #004a53;
|
||||||
--secondary: #005a78; /* Darker Teal for hover/accent */
|
--kaauh-border: #eaeff3;
|
||||||
--success: #00cc99; /* Bright Greenish-Teal for success */
|
--kaauh-primary-text: #343a40;
|
||||||
--light: #f4fcfc; /* Very light off-white (slightly blue tinted) */
|
--kaauh-gray: #6c757d;
|
||||||
--dark: #212529; /* Near black text */
|
|
||||||
--gray: #6c757d; /* Standard gray text */
|
/* Status Colors based on KAAT-S example */
|
||||||
--light-gray: #e0f0f4; /* Lighter background for hover/disabled */
|
--kaauh-success: var(--kaauh-teal);
|
||||||
--border: #c4d7e0; /* Lighter, softer border color */
|
--kaauh-warning: #ffc107;
|
||||||
--danger: #e53935; /* Kept red for danger/delete actions */
|
--kaauh-danger: #dc3545;
|
||||||
--warning: #ff8f00; /* Kept orange for waiting status */
|
--kaauh-secondary: #6c757d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GENERAL GRID AND CARD STYLES */
|
/* Base style for all buttons to inherit Bootstrap's basic structure/reset */
|
||||||
|
.btn-base {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
padding: 0.375rem 0.75rem; /* Standard default padding */
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||||
|
/* FIX: Remove link underline for anchor tags used as buttons */
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Small Button Size */
|
||||||
|
.btn-sm {
|
||||||
|
padding: 0.3rem 0.6rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main Action Button (Create Meeting) */
|
||||||
|
.btn-main-action {
|
||||||
|
background-color: var(--kaauh-teal);
|
||||||
|
border-color: var(--kaauh-teal);
|
||||||
|
color: white;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.btn-main-action:hover {
|
||||||
|
background-color: var(--kaauh-teal-dark);
|
||||||
|
border-color: var(--kaauh-teal-dark);
|
||||||
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
||||||
|
text-decoration: none; /* Ensure no hover underline if base fails */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Outline Primary (View/Join buttons) */
|
||||||
|
.btn-kaats-outline-primary {
|
||||||
|
color: var(--kaauh-teal);
|
||||||
|
border-color: var(--kaauh-teal);
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.btn-kaats-outline-primary:hover {
|
||||||
|
background-color: var(--kaauh-teal);
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Outline Secondary (Update button) */
|
||||||
|
.btn-kaats-outline-secondary {
|
||||||
|
color: var(--kaauh-secondary);
|
||||||
|
border-color: var(--kaauh-secondary);
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.btn-kaats-outline-secondary:hover {
|
||||||
|
background-color: var(--kaauh-secondary);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--kaauh-secondary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Outline Danger (Delete button) */
|
||||||
|
.btn-kaats-outline-danger {
|
||||||
|
color: var(--kaauh-danger);
|
||||||
|
border-color: var(--kaauh-danger);
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.btn-kaats-outline-danger:hover {
|
||||||
|
background-color: var(--kaauh-danger);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--kaauh-danger);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- General UI Styles (Unchanged) --- */
|
||||||
|
|
||||||
|
/* CARD GRID STYLES */
|
||||||
.meetings-grid {
|
.meetings-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
padding: 1.5rem; /* Added padding to the grid container */
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
.meeting-card {
|
.meeting-card {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 8px;
|
border-radius: 0.75rem;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--kaauh-border);
|
||||||
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.meeting-card:hover {
|
.meeting-card:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 6px 16px rgba(0,0,0,0.1);
|
||||||
border-color: var(--primary-light); /* Highlight border on hover */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TOPIC AND DETAILS STYLES */
|
/* TOPIC AND DETAILS STYLES */
|
||||||
.meeting-topic {
|
.meeting-topic {
|
||||||
font-size: 1.1rem;
|
font-size: 1.15rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--primary); /* Uses the new primary color */
|
color: var(--kaauh-teal-dark);
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--kaauh-border);
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
.meeting-detail {
|
.meeting-detail {
|
||||||
@ -58,7 +136,7 @@
|
|||||||
.detail-label {
|
.detail-label {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
color: var(--gray); /* Uses gray variable */
|
color: var(--kaauh-gray);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@ -66,31 +144,30 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
color: var(--dark);
|
color: var(--kaauh-primary-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* STATUS BADGE STYLES (Updated to use theme-based colors) */
|
/* STATUS BADGE STYLES */
|
||||||
.status-badge {
|
.status-badge {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
border-radius: 9999px;
|
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
font-weight: 600;
|
font-weight: 700;
|
||||||
|
padding: 0.4em 0.8em;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
/* Waiting (Warning) */
|
.bg-warning {
|
||||||
.status-waiting {
|
background: var(--kaauh-warning) !important;
|
||||||
background: rgba(255, 143, 0, 0.15); /* Light orange tint */
|
color: var(--kaauh-primary-text) !important;
|
||||||
color: var(--warning);
|
|
||||||
}
|
}
|
||||||
/* Started (Success) */
|
.bg-success {
|
||||||
.status-started {
|
background: var(--kaauh-success) !important;
|
||||||
background: rgba(0, 204, 153, 0.15); /* Light greenish-teal tint */
|
color: white !important;
|
||||||
color: var(--success);
|
|
||||||
}
|
}
|
||||||
/* Ended (Danger) */
|
.bg-danger {
|
||||||
.status-ended {
|
background: var(--kaauh-danger) !important;
|
||||||
background: rgba(229, 57, 53, 0.15); /* Light red tint */
|
color: white !important;
|
||||||
color: var(--danger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ACTION AREA STYLES */
|
/* ACTION AREA STYLES */
|
||||||
@ -100,39 +177,41 @@
|
|||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.btn-sm { /* Re-styled the small button to inherit from main theme structure */
|
|
||||||
padding: 0.3rem 0.6rem;
|
/* Header Styling */
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
||||||
/* Ensure the primary/outline buttons are defined (assuming a global class) */
|
|
||||||
.btn-primary {
|
|
||||||
background: var(--primary);
|
|
||||||
color: white;
|
|
||||||
border: 1px solid var(--primary);
|
|
||||||
}
|
|
||||||
.btn-primary:hover {
|
|
||||||
background: var(--secondary);
|
|
||||||
border-color: var(--secondary);
|
|
||||||
}
|
|
||||||
.btn-outline-primary {
|
|
||||||
background: transparent;
|
|
||||||
border: 1px solid var(--primary);
|
|
||||||
color: var(--primary);
|
|
||||||
}
|
|
||||||
.btn-outline-primary:hover {
|
|
||||||
background: var(--primary);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
/* Card header style for H1 to match theme */
|
|
||||||
.card-header h1 {
|
.card-header h1 {
|
||||||
color: var(--primary);
|
color: var(--kaauh-teal-dark);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
border: 1px solid var(--kaauh-border);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empty State Icon Color */
|
||||||
|
.text-muted.mb-3 {
|
||||||
|
color: var(--kaauh-teal-dark) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pagination Link Styling */
|
||||||
|
.pagination .page-item .page-link {
|
||||||
|
color: var(--kaauh-teal-dark);
|
||||||
|
border-color: var(--kaauh-border);
|
||||||
|
}
|
||||||
|
.pagination .page-item.active .page-link {
|
||||||
|
background-color: var(--kaauh-teal);
|
||||||
|
border-color: var(--kaauh-teal);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.pagination .page-item:hover .page-link:not(.active) {
|
||||||
|
background-color: #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
/* RESPONSIVE STYLES */
|
/* RESPONSIVE STYLES */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.meetings-grid {
|
.meetings-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
padding: 1rem;
|
|
||||||
}
|
}
|
||||||
.meeting-detail {
|
.meeting-detail {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -156,7 +235,7 @@
|
|||||||
<div class="d-flex gap-2 align-items-center">
|
<div class="d-flex gap-2 align-items-center">
|
||||||
{% include "includes/search_form.html" with search_query=search_query %}
|
{% include "includes/search_form.html" with search_query=search_query %}
|
||||||
|
|
||||||
<a href="{% url 'create_meeting' %}" class="btn btn-primary">
|
<a href="{% url 'create_meeting' %}" class="btn-base btn-main-action">
|
||||||
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M12 4v16m8-8H4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
<path d="M12 4v16m8-8H4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
</svg>
|
</svg>
|
||||||
@ -190,11 +269,7 @@
|
|||||||
<div class="meeting-detail">
|
<div class="meeting-detail">
|
||||||
<div class="detail-label">{% trans "Status" %}:</div>
|
<div class="detail-label">{% trans "Status" %}:</div>
|
||||||
<div class="detail-value">
|
<div class="detail-value">
|
||||||
<span class="status-badge
|
<span class="status-badge {% if meeting.status == 'waiting' %}bg-warning{% elif meeting.status == 'started' %}bg-success{% elif meeting.status == 'ended' %}bg-danger{% endif %}">
|
||||||
{% if meeting.status == 'waiting' %}status-waiting
|
|
||||||
{% elif meeting.status == 'started' %}status-started
|
|
||||||
{% elif meeting.status == 'ended' %}status-ended
|
|
||||||
{% endif %}">
|
|
||||||
{% if meeting.status == 'waiting' %}
|
{% if meeting.status == 'waiting' %}
|
||||||
{% trans "Waiting" %}
|
{% trans "Waiting" %}
|
||||||
{% elif meeting.status == 'started' %}
|
{% elif meeting.status == 'started' %}
|
||||||
@ -210,7 +285,7 @@
|
|||||||
<div class="meeting-detail">
|
<div class="meeting-detail">
|
||||||
<div class="detail-label">{% trans "Join URL" %}:</div>
|
<div class="detail-label">{% trans "Join URL" %}:</div>
|
||||||
<div class="detail-value">
|
<div class="detail-value">
|
||||||
<a href="{{ meeting.join_url }}" target="_blank" class="btn btn-outline-primary btn-sm">
|
<a href="{{ meeting.join_url }}" target="_blank" class="btn-base btn-kaats-outline-primary btn-sm">
|
||||||
{% trans "Join Meeting" %}
|
{% trans "Join Meeting" %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -218,18 +293,18 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a href="{% url 'meeting_details' meeting.pk %}" class="btn btn-outline-primary btn-sm" title="{% trans 'View' %}">
|
<a href="{% url 'meeting_details' meeting.pk %}" class="btn-base btn-kaats-outline-primary btn-sm" title="{% trans 'View' %}">
|
||||||
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
<path d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
<path d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0 8.268-2.943-9.542-7z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
<path d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0 8.268-2.943-9.542-7z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a href="{% url 'update_meeting' meeting.pk %}" class="btn btn-outline-secondary btn-sm" title="{% trans 'Update' %}">
|
<a href="{% url 'update_meeting' meeting.pk %}" class="btn-base btn-kaats-outline-secondary btn-sm" title="{% trans 'Update' %}">
|
||||||
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
<path d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<button type="button" class="btn btn-outline-danger btn-sm" title="{% trans 'Delete' %}"
|
<button type="button" class="btn-base btn-kaats-outline-danger btn-sm" title="{% trans 'Delete' %}"
|
||||||
data-bs-toggle="deleteModal"
|
data-bs-toggle="deleteModal"
|
||||||
data-delete-url="{% url 'delete_meeting' meeting.pk %}"
|
data-delete-url="{% url 'delete_meeting' meeting.pk %}"
|
||||||
data-item-name="{{ meeting.topic }}">
|
data-item-name="{{ meeting.topic }}">
|
||||||
@ -280,7 +355,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<p class="text-muted">{% trans "No meetings found." %}</p>
|
<p class="text-muted">{% trans "No meetings found." %}</p>
|
||||||
{% if user.is_staff %}
|
{% if user.is_staff %}
|
||||||
<a href="{% url 'create_meeting' %}" class="btn btn-primary mt-3">
|
<a href="{% url 'create_meeting' %}" class="btn-base btn-main-action mt-3">
|
||||||
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M12 4v16m8-8H4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
<path d="M12 4v16m8-8H4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
@ -2,6 +2,172 @@
|
|||||||
{% load static i18n %}
|
{% load static i18n %}
|
||||||
{% block title %}{% trans "Update Zoom Meeting" %} - {{ block.super }}{% endblock %}
|
{% block title %}{% trans "Update Zoom Meeting" %} - {{ block.super }}{% endblock %}
|
||||||
|
|
||||||
|
{% block customCSS %}
|
||||||
|
<style>
|
||||||
|
/* UI Variables for the KAAT-S Theme */
|
||||||
|
:root {
|
||||||
|
--kaauh-teal: #00636e;
|
||||||
|
--kaauh-teal-dark: #004a53;
|
||||||
|
--kaauh-border: #eaeff3;
|
||||||
|
--kaauh-primary-text: #343a40;
|
||||||
|
--kaauh-gray: #6c757d;
|
||||||
|
|
||||||
|
/* Status Colors for alerts/messages */
|
||||||
|
--kaauh-success: var(--kaauh-teal);
|
||||||
|
--kaauh-danger: #dc3545;
|
||||||
|
--kaauh-info: #17a2b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CONTAINER AND CARD STYLING */
|
||||||
|
.container {
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
border: 1px solid var(--kaauh-border);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto; /* Center the card */
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HEADER STYLING (The section outside the card) */
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.header h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
color: var(--kaauh-teal-dark);
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
.header p {
|
||||||
|
color: var(--kaauh-gray);
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CARD TITLE STYLING */
|
||||||
|
.card-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: var(--kaauh-teal-dark);
|
||||||
|
font-weight: 600;
|
||||||
|
border-bottom: 1px solid var(--kaauh-border);
|
||||||
|
padding-bottom: 0.75rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FORM STYLING */
|
||||||
|
.form-row {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
.form-label {
|
||||||
|
display: block;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--kaauh-gray);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.form-input {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--kaauh-primary-text);
|
||||||
|
background-color: #fff;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: 1px solid var(--kaauh-border);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||||
|
}
|
||||||
|
.form-input:focus {
|
||||||
|
border-color: var(--kaauh-teal);
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: 0 0 0 0.1rem rgba(0, 99, 110, 0.25);
|
||||||
|
}
|
||||||
|
input[type="datetime-local"] {
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MESSAGES/ALERTS STYLING */
|
||||||
|
.messages {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto 1.5rem auto;
|
||||||
|
}
|
||||||
|
.alert {
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.alert-success {
|
||||||
|
color: white;
|
||||||
|
background-color: var(--kaauh-success);
|
||||||
|
border-color: var(--kaauh-success);
|
||||||
|
}
|
||||||
|
.alert-danger {
|
||||||
|
color: white;
|
||||||
|
background-color: var(--kaauh-danger);
|
||||||
|
border-color: var(--kaauh-danger);
|
||||||
|
}
|
||||||
|
.alert-info {
|
||||||
|
color: white;
|
||||||
|
background-color: var(--kaauh-info);
|
||||||
|
border-color: var(--kaauh-info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BUTTON STYLING */
|
||||||
|
.actions {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
.btn-base {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary Action Button (Update) */
|
||||||
|
.btn-main-action {
|
||||||
|
background-color: var(--kaauh-teal);
|
||||||
|
border-color: var(--kaauh-teal);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.btn-main-action:hover {
|
||||||
|
background-color: var(--kaauh-teal-dark);
|
||||||
|
border-color: var(--kaauh-teal-dark);
|
||||||
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Secondary Button (Cancel) */
|
||||||
|
.btn-kaats-outline-secondary {
|
||||||
|
color: var(--kaauh-secondary);
|
||||||
|
border-color: var(--kaauh-secondary);
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.btn-kaats-outline-secondary:hover {
|
||||||
|
background-color: var(--kaauh-secondary);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--kaauh-secondary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
@ -9,11 +175,12 @@
|
|||||||
<p>{% trans "Modify the details of your scheduled meeting" %}</p>
|
<p>{% trans "Modify the details of your scheduled meeting" %}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Messages -->
|
{# Apply KAAT-S theme styles to Django messages #}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
<div class="messages">
|
<div class="messages">
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
<div class="alert alert-{{ message.tags }}">
|
{# Use message tags to map to alert classes: success, danger, info #}
|
||||||
|
<div class="alert alert-{{ message.tags|default:'info' }}">
|
||||||
{{ message }}
|
{{ message }}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -33,8 +200,9 @@
|
|||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="start_time" class="form-label">{% trans "Start Time (ISO 8601):" %}</label>
|
<label for="start_time" class="form-label">{% trans "Start Time (ISO 8601):" %}</label>
|
||||||
|
{# Note: Django template filter for datetime-local needs to be precise Y-m-d\TH:i #}
|
||||||
<input type="datetime-local" id="start_time" name="start_time" class="form-input"
|
<input type="datetime-local" id="start_time" name="start_time" class="form-input"
|
||||||
value="{{ meeting.start_time|slice:'0:16'|date:'Y-m-d\TH:i' }}" required>
|
value="{{ meeting.start_time|slice:'0:16' }}" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -43,10 +211,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button type="submit" class="btn btn-primary">{% trans "Update Meeting" %}</button>
|
<button type="submit" class="btn-base btn-main-action">
|
||||||
<a href="{% url 'meeting_details' meeting.pk %}" class="btn btn-secondary">{% trans "Cancel" %}</a>
|
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width: 1.25rem;">
|
||||||
|
<path d="M5 13l4 4L19 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
</svg>
|
||||||
|
{% trans "Update Meeting" %}
|
||||||
|
</button>
|
||||||
|
{# Using custom secondary button for 'Cancel' link #}
|
||||||
|
<a href="{% url 'meeting_details' meeting.pk %}" class="btn-base btn-kaats-outline-secondary">
|
||||||
|
{% trans "Cancel" %}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
Loading…
x
Reference in New Issue
Block a user