649 lines
31 KiB
HTML
649 lines
31 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if object %}Edit {{ object.name }}{% else %}Add Supplier{% endif %} - {{ block.super }}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<!-- Page Header -->
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h1 class="h3 mb-1">
|
|
<i class="fas fa-truck me-2"></i>{% if object %}Edit Supplier{% else %}Add New Supplier{% endif %}
|
|
</h1>
|
|
<nav aria-label="breadcrumb">
|
|
<ol class="breadcrumb mb-0">
|
|
<li class="breadcrumb-item"><a href="{% url 'inventory:dashboard' %}">Inventory</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'inventory:supplier_list' %}">Suppliers</a></li>
|
|
{% if object %}
|
|
<li class="breadcrumb-item"><a href="{% url 'inventory:supplier_detail' object.pk %}">{{ object.name }}</a></li>
|
|
<li class="breadcrumb-item active">Edit</li>
|
|
{% else %}
|
|
<li class="breadcrumb-item active">Add New</li>
|
|
{% endif %}
|
|
</ol>
|
|
</nav>
|
|
</div>
|
|
<div class="btn-group">
|
|
<a href="{% if object %}{% url 'inventory:supplier_detail' object.pk %}{% else %}{% url 'inventory:supplier_list' %}{% endif %}"
|
|
class="btn btn-outline-secondary">
|
|
<i class="fas fa-arrow-left me-2"></i>Back
|
|
</a>
|
|
{% if object %}
|
|
<a href="{% url 'inventory:supplier_detail' object.pk %}" class="btn btn-outline-info">
|
|
<i class="fas fa-eye me-2"></i>View Details
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Main Form -->
|
|
<div class="col-lg-8">
|
|
<form method="post" id="supplierForm" novalidate>
|
|
{% csrf_token %}
|
|
|
|
<!-- Basic Information -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-info-circle me-2"></i>Basic Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.supplier_code.id_for_label }}" class="form-label">
|
|
Supplier Code <span class="text-danger">*</span>
|
|
</label>
|
|
{{ form.supplier_code }}
|
|
{% if form.supplier_code.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.supplier_code.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Unique identifier for the supplier</div>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.name.id_for_label }}" class="form-label">
|
|
Supplier Name <span class="text-danger">*</span>
|
|
</label>
|
|
{{ form.name }}
|
|
{% if form.name.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.name.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.supplier_type.id_for_label }}" class="form-label">
|
|
Supplier Type <span class="text-danger">*</span>
|
|
</label>
|
|
{{ form.supplier_type }}
|
|
{% if form.supplier_type.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.supplier_type.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.is_active.id_for_label }}" class="form-label">Status</label>
|
|
<div class="form-check form-switch">
|
|
{{ form.is_active }}
|
|
<label class="form-check-label" for="{{ form.is_active.id_for_label }}">
|
|
Active Supplier
|
|
</label>
|
|
</div>
|
|
{% if form.is_active.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.is_active.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="{{ form.description.id_for_label }}" class="form-label">Description</label>
|
|
{{ form.description }}
|
|
{% if form.description.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.description.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Brief description of the supplier and their services</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Contact Information -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-address-book me-2"></i>Contact Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.contact_person.id_for_label }}" class="form-label">Contact Person</label>
|
|
{{ form.contact_person }}
|
|
{% if form.contact_person.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.contact_person.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.contact_title.id_for_label }}" class="form-label">Title</label>
|
|
{{ form.contact_title }}
|
|
{% if form.contact_title.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.contact_title.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.phone.id_for_label }}" class="form-label">Phone</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text"><i class="fas fa-phone"></i></span>
|
|
{{ form.phone }}
|
|
</div>
|
|
{% if form.phone.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.phone.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.email.id_for_label }}" class="form-label">Email</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text"><i class="fas fa-envelope"></i></span>
|
|
{{ form.email }}
|
|
</div>
|
|
{% if form.email.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.email.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="{{ form.website.id_for_label }}" class="form-label">Website</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text"><i class="fas fa-globe"></i></span>
|
|
{{ form.website }}
|
|
</div>
|
|
{% if form.website.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.website.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Address Information -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-map-marker-alt me-2"></i>Address Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label for="{{ form.address.id_for_label }}" class="form-label">Street Address</label>
|
|
{{ form.address }}
|
|
{% if form.address.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.address.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-4 mb-3">
|
|
<label for="{{ form.city.id_for_label }}" class="form-label">City</label>
|
|
{{ form.city }}
|
|
{% if form.city.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.city.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-4 mb-3">
|
|
<label for="{{ form.state.id_for_label }}" class="form-label">State/Province</label>
|
|
{{ form.state }}
|
|
{% if form.state.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.state.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-4 mb-3">
|
|
<label for="{{ form.zip_code.id_for_label }}" class="form-label">ZIP/Postal Code</label>
|
|
{{ form.zip_code }}
|
|
{% if form.zip_code.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.zip_code.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="{{ form.country.id_for_label }}" class="form-label">Country</label>
|
|
{{ form.country }}
|
|
{% if form.country.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.country.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Business Information -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-building me-2"></i>Business Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.tax_id.id_for_label }}" class="form-label">Tax ID</label>
|
|
{{ form.tax_id }}
|
|
{% if form.tax_id.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.tax_id.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Tax identification number</div>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.license_number.id_for_label }}" class="form-label">License Number</label>
|
|
{{ form.license_number }}
|
|
{% if form.license_number.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.license_number.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Business license or registration number</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.payment_terms.id_for_label }}" class="form-label">Payment Terms</label>
|
|
{{ form.payment_terms }}
|
|
{% if form.payment_terms.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.payment_terms.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="{{ form.credit_limit.id_for_label }}" class="form-label">Credit Limit</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">$</span>
|
|
{{ form.credit_limit }}
|
|
</div>
|
|
{% if form.credit_limit.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.credit_limit.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Maximum credit amount allowed</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="{{ form.rating.id_for_label }}" class="form-label">Rating</label>
|
|
{{ form.rating }}
|
|
{% if form.rating.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.rating.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Supplier performance rating (1-5 stars)</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notes -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-sticky-note me-2"></i>Additional Notes
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label for="{{ form.notes.id_for_label }}" class="form-label">Notes</label>
|
|
{{ form.notes }}
|
|
{% if form.notes.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.notes.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Additional information about the supplier</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="resetForm()">
|
|
<i class="fas fa-undo me-2"></i>Reset
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="previewSupplier()">
|
|
<i class="fas fa-eye me-2"></i>Preview
|
|
</button>
|
|
</div>
|
|
<div>
|
|
<a href="{% if object %}{% url 'inventory:supplier_detail' object.pk %}{% else %}{% url 'inventory:supplier_list' %}{% endif %}"
|
|
class="btn btn-outline-secondary me-2">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
<button type="submit" class="btn btn-primary" id="saveButton">
|
|
<i class="fas fa-save me-2"></i>{% if object %}Update Supplier{% else %}Create Supplier{% endif %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-4">
|
|
<!-- Form Help -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-question-circle me-2"></i>Form Help
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="accordion" id="helpAccordion">
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#basicInfo">
|
|
Basic Information
|
|
</button>
|
|
</h2>
|
|
<div id="basicInfo" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<ul class="list-unstyled mb-0">
|
|
<li><strong>Supplier Code:</strong> Unique identifier for internal use</li>
|
|
<li><strong>Name:</strong> Official business name</li>
|
|
<li><strong>Type:</strong> Category of products/services provided</li>
|
|
<li><strong>Status:</strong> Whether the supplier is currently active</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#contactInfo">
|
|
Contact Information
|
|
</button>
|
|
</h2>
|
|
<div id="contactInfo" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<ul class="list-unstyled mb-0">
|
|
<li><strong>Contact Person:</strong> Primary contact at the supplier</li>
|
|
<li><strong>Phone:</strong> Primary phone number</li>
|
|
<li><strong>Email:</strong> Primary email address</li>
|
|
<li><strong>Website:</strong> Company website URL</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#businessInfo">
|
|
Business Information
|
|
</button>
|
|
</h2>
|
|
<div id="businessInfo" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<ul class="list-unstyled mb-0">
|
|
<li><strong>Tax ID:</strong> Federal tax identification number</li>
|
|
<li><strong>License:</strong> Business license or registration</li>
|
|
<li><strong>Payment Terms:</strong> Standard payment terms</li>
|
|
<li><strong>Credit Limit:</strong> Maximum outstanding balance</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Validation Status -->
|
|
<div class="card mb-4" id="validationCard" style="display: none;">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-check-circle me-2"></i>Validation Status
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id="validationResults"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions -->
|
|
{% if object %}
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-bolt me-2"></i>Quick Actions
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<a href="{% url 'inventory:supplier_detail' object.pk %}" class="btn btn-outline-primary">
|
|
<i class="fas fa-eye me-2"></i>View Details
|
|
</a>
|
|
<a href="{% url 'inventory:purchase_order_create' %}?supplier={{ object.id }}" class="btn btn-outline-success">
|
|
<i class="fas fa-shopping-cart me-2"></i>Create Order
|
|
</a>
|
|
<button type="button" class="btn btn-outline-info" onclick="duplicateSupplier()">
|
|
<i class="fas fa-copy me-2"></i>Duplicate
|
|
</button>
|
|
<a href="{% url 'inventory:supplier_delete' object.pk %}" class="btn btn-outline-danger">
|
|
<i class="fas fa-trash me-2"></i>Delete
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Supplier form functionality
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const form = document.getElementById('supplierForm');
|
|
const saveButton = document.getElementById('saveButton');
|
|
|
|
// Form validation
|
|
form.addEventListener('submit', function(e) {
|
|
if (!form.checkValidity()) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
} else {
|
|
// Show loading state
|
|
saveButton.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Saving...';
|
|
saveButton.disabled = true;
|
|
}
|
|
form.classList.add('was-validated');
|
|
});
|
|
|
|
// Real-time validation
|
|
const requiredFields = form.querySelectorAll('[required]');
|
|
requiredFields.forEach(field => {
|
|
field.addEventListener('blur', validateField);
|
|
field.addEventListener('input', validateField);
|
|
});
|
|
|
|
function validateField(e) {
|
|
const field = e.target;
|
|
const isValid = field.checkValidity();
|
|
|
|
if (isValid) {
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
} else {
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
}
|
|
|
|
updateValidationStatus();
|
|
}
|
|
|
|
function updateValidationStatus() {
|
|
const validationCard = document.getElementById('validationCard');
|
|
const validationResults = document.getElementById('validationResults');
|
|
const validFields = form.querySelectorAll('.is-valid').length;
|
|
const invalidFields = form.querySelectorAll('.is-invalid').length;
|
|
const totalRequired = requiredFields.length;
|
|
|
|
if (validFields > 0 || invalidFields > 0) {
|
|
validationCard.style.display = 'block';
|
|
validationResults.innerHTML = `
|
|
<div class="d-flex justify-content-between mb-2">
|
|
<span>Valid Fields:</span>
|
|
<span class="text-success">${validFields}</span>
|
|
</div>
|
|
<div class="d-flex justify-content-between mb-2">
|
|
<span>Invalid Fields:</span>
|
|
<span class="text-danger">${invalidFields}</span>
|
|
</div>
|
|
<div class="progress" style="height: 6px;">
|
|
<div class="progress-bar bg-success" role="progressbar"
|
|
style="width: ${(validFields / totalRequired) * 100}%"></div>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
|
|
// Auto-generate supplier code
|
|
const nameField = document.getElementById('{{ form.name.id_for_label }}');
|
|
const codeField = document.getElementById('{{ form.supplier_code.id_for_label }}');
|
|
|
|
if (nameField && codeField && !codeField.value) {
|
|
nameField.addEventListener('input', function() {
|
|
if (!codeField.value) {
|
|
const code = this.value.toUpperCase()
|
|
.replace(/[^A-Z0-9]/g, '')
|
|
.substring(0, 10);
|
|
codeField.value = code;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Phone number formatting
|
|
const phoneField = document.getElementById('{{ form.phone.id_for_label }}');
|
|
if (phoneField) {
|
|
phoneField.addEventListener('input', function() {
|
|
let value = this.value.replace(/\D/g, '');
|
|
if (value.length >= 6) {
|
|
value = value.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
|
|
} else if (value.length >= 3) {
|
|
value = value.replace(/(\d{3})(\d{0,3})/, '($1) $2');
|
|
}
|
|
this.value = value;
|
|
});
|
|
}
|
|
});
|
|
|
|
function resetForm() {
|
|
if (confirm('Are you sure you want to reset the form? All unsaved changes will be lost.')) {
|
|
document.getElementById('supplierForm').reset();
|
|
document.querySelectorAll('.is-valid, .is-invalid').forEach(field => {
|
|
field.classList.remove('is-valid', 'is-invalid');
|
|
});
|
|
document.getElementById('validationCard').style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function previewSupplier() {
|
|
// Implement supplier preview functionality
|
|
alert('Preview functionality coming soon!');
|
|
}
|
|
|
|
function duplicateSupplier() {
|
|
if (confirm('Create a copy of this supplier?')) {
|
|
window.location.href = '{% url "inventory:supplier_create" %}?duplicate={{ object.pk }}';
|
|
}
|
|
}
|
|
|
|
// Auto-save functionality
|
|
let autoSaveTimeout;
|
|
document.getElementById('supplierForm').addEventListener('input', function() {
|
|
clearTimeout(autoSaveTimeout);
|
|
autoSaveTimeout = setTimeout(() => {
|
|
// Auto-save draft
|
|
console.log('Auto-saving draft...');
|
|
}, 30000); // Save after 30 seconds of inactivity
|
|
});
|
|
</script>
|
|
|
|
<style>
|
|
.form-control.is-valid,
|
|
.form-select.is-valid {
|
|
border-color: #198754;
|
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='m2.3 6.73.94-.94 1.38 1.38 3.22-3.22.94.94-4.16 4.16z'/%3e%3c/svg%3e");
|
|
}
|
|
|
|
.form-control.is-invalid,
|
|
.form-select.is-invalid {
|
|
border-color: #dc3545;
|
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath d='m5.8 4.6 1.4 1.4 1.4-1.4'/%3e%3c/svg%3e");
|
|
}
|
|
|
|
.accordion-button:not(.collapsed) {
|
|
background-color: #f8f9fa;
|
|
color: #0d6efd;
|
|
}
|
|
|
|
.progress {
|
|
background-color: #e9ecef;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.d-flex.justify-content-between {
|
|
flex-direction: column;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.btn-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.col-md-6, .col-md-4 {
|
|
margin-bottom: 1rem;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|