Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend
This commit is contained in:
commit
91db23e063
@ -279,6 +279,11 @@ urlpatterns = [
|
|||||||
views.CarFinanceUpdateView.as_view(),
|
views.CarFinanceUpdateView.as_view(),
|
||||||
name="car_finance_update",
|
name="car_finance_update",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"htmx/cars/bulk_update_car_price/",
|
||||||
|
views.bulk_update_car_price,
|
||||||
|
name="bulk_update_car_price",
|
||||||
|
),
|
||||||
path("ajax/", views.AjaxHandlerView.as_view(), name="ajax_handler"),
|
path("ajax/", views.AjaxHandlerView.as_view(), name="ajax_handler"),
|
||||||
path(
|
path(
|
||||||
"cars/<slug:slug>/add-color/", views.CarColorCreate.as_view(), name="add_color"
|
"cars/<slug:slug>/add-color/", views.CarColorCreate.as_view(), name="add_color"
|
||||||
|
|||||||
@ -23,6 +23,7 @@ from inventory.models import Status as LeadStatus
|
|||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from background_task.models import Task
|
from background_task.models import Task
|
||||||
from django.views.generic import FormView
|
from django.views.generic import FormView
|
||||||
|
from django.views.decorators.http import require_http_methods
|
||||||
from django.db.models.deletion import RestrictedError
|
from django.db.models.deletion import RestrictedError
|
||||||
from django.http.response import StreamingHttpResponse
|
from django.http.response import StreamingHttpResponse
|
||||||
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
||||||
@ -9288,3 +9289,26 @@ def upload_cars(request,pk=None):
|
|||||||
return render(request, 'csv_upload.html',{"make_data":models.CarMake.objects.all(),"form":form,"item":item})
|
return render(request, 'csv_upload.html',{"make_data":models.CarMake.objects.all(),"form":form,"item":item})
|
||||||
###############################################################
|
###############################################################
|
||||||
###############################################################
|
###############################################################
|
||||||
|
|
||||||
|
@require_http_methods(["POST"])
|
||||||
|
def bulk_update_car_price(request):
|
||||||
|
if request.method == "POST":
|
||||||
|
cars = request.POST.getlist('car')
|
||||||
|
price = request.POST.get('price')
|
||||||
|
|
||||||
|
if not price or int(price) <= 0:
|
||||||
|
messages.error(request, "Please enter a valid price")
|
||||||
|
elif not cars:
|
||||||
|
messages.error(request, "No cars selected for price update")
|
||||||
|
else:
|
||||||
|
for car_pk in cars:
|
||||||
|
car_finance , created = models.CarFinance.objects.get_or_create(car__pk=car_pk, cost_price=Decimal(price),selling_price=0)
|
||||||
|
if not created:
|
||||||
|
car_finance.cost_price = Decimal(price)
|
||||||
|
car_finance.selling_price = 0
|
||||||
|
car_finance.save()
|
||||||
|
messages.success(request, "Price updated successfully")
|
||||||
|
|
||||||
|
response = HttpResponse()
|
||||||
|
response['HX-Redirect'] = reverse('car_list')
|
||||||
|
return response
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
@ -109,7 +109,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="d-flex justify-content-end mt-3">
|
<div class="d-flex justify-content-end mt-3">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
@ -117,9 +117,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>{% trans "No model change audit events found." %}</p>
|
<p>{% trans "No model change audit events found." %}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -102,7 +102,7 @@
|
|||||||
<!-- Tour Manager -->
|
<!-- Tour Manager -->
|
||||||
<script src="{% static 'js/tours/tour-manager.js' %}"></script>
|
<script src="{% static 'js/tours/tour-manager.js' %}"></script>
|
||||||
|
|
||||||
<script src="{% static 'js/tours/help-button.js' %}"></script>
|
<script src="{% static 'js/tours/help-button.js' %}"></script>
|
||||||
<script src="{% static 'vendors/lodash/lodash.min.js' %}"></script>
|
<script src="{% static 'vendors/lodash/lodash.min.js' %}"></script>
|
||||||
<script src="{% static 'vendors/list.js/list.min.js' %}"></script>
|
<script src="{% static 'vendors/list.js/list.min.js' %}"></script>
|
||||||
<script src="{% static 'vendors/feather-icons/feather.min.js' %}"></script>
|
<script src="{% static 'vendors/feather-icons/feather.min.js' %}"></script>
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
{% block title %}Bill Details - {{ block.super }}{% endblock %}
|
{% block title %}Bill Details - {{ block.super }}{% endblock %}
|
||||||
|
|
||||||
{% block customCSS %}
|
{% block customCSS %}
|
||||||
<style>
|
<style>
|
||||||
/* Optional custom overrides for Bootstrap 5 */
|
/* Optional custom overrides for Bootstrap 5 */
|
||||||
.table th,
|
.table th,
|
||||||
.table td {
|
.table td {
|
||||||
@ -26,17 +26,17 @@
|
|||||||
font-size: 0.6rem;
|
font-size: 0.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#djl-vendor-card-widget{
|
#djl-vendor-card-widget{
|
||||||
|
|
||||||
max-height:30rem;
|
max-height:30rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container-fluid py-4">
|
<div class="container-fluid py-4">
|
||||||
<div class="row g-4" >
|
<div class="row g-4" >
|
||||||
<!-- Left Sidebar -->
|
<!-- Left Sidebar -->
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
@ -237,6 +237,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% include "bill/includes/mark_as.html" %}
|
{% include "bill/includes/mark_as.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -6,7 +6,7 @@
|
|||||||
{% load widget_tweaks crispy_forms_filters %}
|
{% load widget_tweaks crispy_forms_filters %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container py-4">
|
<div class="container py-4">
|
||||||
<div class="row g-4">
|
<div class="row g-4">
|
||||||
<!-- Vendor Card -->
|
<!-- Vendor Card -->
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
@ -52,6 +52,6 @@
|
|||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% include "bill/includes/mark_as.html" %}
|
{% include "bill/includes/mark_as.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -267,18 +267,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.card-footer .btn-link {
|
.card-footer .btn-link {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
.card-footer .btn-link:hover {
|
.card-footer .btn-link:hover {
|
||||||
background-color: rgba(0,0,0,0.03);
|
background-color: rgba(0,0,0,0.03);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
window.showPOModal = function(title, actionUrl, buttonText) {
|
window.showPOModal = function(title, actionUrl, buttonText) {
|
||||||
const modalEl = document.getElementById('POModal');
|
const modalEl = document.getElementById('POModal');
|
||||||
if (!modalEl) {
|
if (!modalEl) {
|
||||||
@ -302,5 +302,5 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
modal.show();
|
modal.show();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -19,5 +19,5 @@
|
|||||||
<p class="card-text">{% trans 'No available notes to display...' %}</p>
|
<p class="card-text">{% trans 'No available notes to display...' %}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
polygon(15px 0, 100% 0, 100% 100%, 15px 100%, 0 50%)
|
polygon(15px 0, 100% 0, 100% 100%, 15px 100%, 0 50%)
|
||||||
{% endif %};
|
{% endif %};
|
||||||
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.kanban-header::after {
|
.kanban-header::after {
|
||||||
|
|||||||
@ -50,4 +50,4 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load i18n static widget_tweaks custom_filters %}
|
{% load i18n static widget_tweaks custom_filters %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{# Check if an 'object' exists in the context #}
|
{# Check if an 'object' exists in the context #}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
{% trans 'Update Opportunity'%}
|
{% trans 'Update Opportunity'%}
|
||||||
|
|||||||
@ -90,7 +90,7 @@
|
|||||||
<div id="opportunities-grid" class="row g-4 px-2 px-lg-4 mt-1">
|
<div id="opportunities-grid" class="row g-4 px-2 px-lg-4 mt-1">
|
||||||
{% include 'crm/opportunities/partials/opportunity_grid.html' %}
|
{% include 'crm/opportunities/partials/opportunity_grid.html' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-end mt-3">
|
<div class="d-flex justify-content-end mt-3">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
{% if is_paginated %}
|
{% if is_paginated %}
|
||||||
{% include 'partials/pagination.html' %}
|
{% include 'partials/pagination.html' %}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
{% load static i18n %}
|
{% load static i18n %}
|
||||||
|
|
||||||
{% block customCSS %}
|
{% block customCSS %}
|
||||||
<style>
|
<style>
|
||||||
.color-card {
|
.color-card {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
@ -68,11 +68,11 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock customCSS %}
|
{% endblock customCSS %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<h2>Upload Cars CSV</h2>
|
<h2>Upload Cars CSV</h2>
|
||||||
<div class="d-flex justify-content-end">
|
<div class="d-flex justify-content-end">
|
||||||
<a href="{% static 'sample/cars_sample.csv' %}" class="btn btn-outline-success mt-4">
|
<a href="{% static 'sample/cars_sample.csv' %}" class="btn btn-outline-success mt-4">
|
||||||
@ -153,8 +153,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if item %}
|
{% if item %}
|
||||||
<h3 class="mt-4">List of Items</h3>
|
<h3 class="mt-4">List of Items</h3>
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
@ -173,5 +173,5 @@
|
|||||||
<button type="submit" class="btn btn-primary">Upload</button>
|
<button type="submit" class="btn btn-primary">Upload</button>
|
||||||
<a href="{{ request.META.HTTP_REFERER }}" class="btn btn-secondary">Cancel</a>
|
<a href="{{ request.META.HTTP_REFERER }}" class="btn btn-secondary">Cancel</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -4,10 +4,10 @@
|
|||||||
{% block title %}Haikal Bot{% endblock %}
|
{% block title %}Haikal Bot{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.2/papaparse.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.2/papaparse.min.js"></script>
|
||||||
|
|
||||||
<div class="container mt-5">
|
<div class="container mt-5">
|
||||||
<div class="card shadow-sm">
|
<div class="card shadow-sm">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<h5 class="mb-0"><i class="fas fa-robot me-2"></i>{% trans "HaikalBot" %}</h5>
|
<h5 class="mb-0"><i class="fas fa-robot me-2"></i>{% trans "HaikalBot" %}</h5>
|
||||||
@ -29,17 +29,17 @@
|
|||||||
<canvas id="chart-canvas" height="200px"></canvas>
|
<canvas id="chart-canvas" height="200px"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const chatHistory = document.getElementById('chat-history');
|
const chatHistory = document.getElementById('chat-history');
|
||||||
const chartContainer = document.getElementById('chart-container');
|
const chartContainer = document.getElementById('chart-container');
|
||||||
const chartCanvas = document.getElementById('chart-canvas');
|
const chartCanvas = document.getElementById('chart-canvas');
|
||||||
const exportBtn = document.getElementById('export-btn');
|
const exportBtn = document.getElementById('export-btn');
|
||||||
let chartInstance = null;
|
let chartInstance = null;
|
||||||
let latestDataTable = null;
|
let latestDataTable = null;
|
||||||
|
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
let cookieValue = null;
|
let cookieValue = null;
|
||||||
if (document.cookie && document.cookie !== "") {
|
if (document.cookie && document.cookie !== "") {
|
||||||
const cookies = document.cookie.split(";");
|
const cookies = document.cookie.split(";");
|
||||||
@ -54,13 +54,13 @@ function getCookie(name) {
|
|||||||
return cookieValue;
|
return cookieValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
function speak(text) {
|
function speak(text) {
|
||||||
const utterance = new SpeechSynthesisUtterance(text);
|
const utterance = new SpeechSynthesisUtterance(text);
|
||||||
utterance.lang = document.documentElement.lang || "en";
|
utterance.lang = document.documentElement.lang || "en";
|
||||||
window.speechSynthesis.speak(utterance);
|
window.speechSynthesis.speak(utterance);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderTable(data) {
|
function renderTable(data) {
|
||||||
latestDataTable = data;
|
latestDataTable = data;
|
||||||
exportBtn.style.display = 'inline-block';
|
exportBtn.style.display = 'inline-block';
|
||||||
const headers = Object.keys(data[0]);
|
const headers = Object.keys(data[0]);
|
||||||
@ -72,9 +72,9 @@ function renderTable(data) {
|
|||||||
});
|
});
|
||||||
html += '</tbody></table></div>';
|
html += '</tbody></table></div>';
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendMessage(role, htmlContent) {
|
function appendMessage(role, htmlContent) {
|
||||||
const align = role === 'AI' ? 'bg-secondary-light' : 'bg-primary-light';
|
const align = role === 'AI' ? 'bg-secondary-light' : 'bg-primary-light';
|
||||||
chatHistory.innerHTML += `
|
chatHistory.innerHTML += `
|
||||||
<div class="mb-3 p-3 rounded ${align}">
|
<div class="mb-3 p-3 rounded ${align}">
|
||||||
@ -82,9 +82,9 @@ function appendMessage(role, htmlContent) {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
chatHistory.scrollTop = chatHistory.scrollHeight;
|
chatHistory.scrollTop = chatHistory.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('chat-form').addEventListener('submit', async function(e) {
|
document.getElementById('chat-form').addEventListener('submit', async function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const input = document.getElementById('chat-input');
|
const input = document.getElementById('chat-input');
|
||||||
const prompt = input.value.trim();
|
const prompt = input.value.trim();
|
||||||
@ -151,9 +151,9 @@ document.getElementById('chat-form').addEventListener('submit', async function(e
|
|||||||
: `<p>${result.data}</p>`;
|
: `<p>${result.data}</p>`;
|
||||||
appendMessage('AI', content);
|
appendMessage('AI', content);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('export-btn').addEventListener('click', () => {
|
document.getElementById('export-btn').addEventListener('click', () => {
|
||||||
if (!latestDataTable) return;
|
if (!latestDataTable) return;
|
||||||
const csv = Papa.unparse(latestDataTable);
|
const csv = Papa.unparse(latestDataTable);
|
||||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
||||||
@ -164,10 +164,10 @@ document.getElementById('export-btn').addEventListener('click', () => {
|
|||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Voice input (speech-to-text)
|
// Voice input (speech-to-text)
|
||||||
document.getElementById('mic-btn').addEventListener('click', () => {
|
document.getElementById('mic-btn').addEventListener('click', () => {
|
||||||
const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
|
const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
|
||||||
recognition.lang = document.documentElement.lang || "en";
|
recognition.lang = document.documentElement.lang || "en";
|
||||||
recognition.interimResults = false;
|
recognition.interimResults = false;
|
||||||
@ -183,6 +183,6 @@ document.getElementById('mic-btn').addEventListener('click', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
recognition.start();
|
recognition.start();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -6,11 +6,11 @@
|
|||||||
{% endblock title %}
|
{% endblock title %}
|
||||||
|
|
||||||
{% block description %}
|
{% block description %}
|
||||||
AI assistant
|
AI assistant
|
||||||
{% endblock description %}
|
{% endblock description %}
|
||||||
|
|
||||||
{% block customCSS %}
|
{% block customCSS %}
|
||||||
<style>
|
<style>
|
||||||
.chart-container {
|
.chart-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
@ -54,13 +54,13 @@ AI assistant
|
|||||||
color: #dc3545;
|
color: #dc3545;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock customCSS %}
|
{% endblock customCSS %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||||
<div class="card shadow-none mb-3">
|
<div class="card shadow-none mb-3">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<div class="d-flex align-items-center fw-bolder fs-3 d-inline-block">
|
<div class="d-flex align-items-center fw-bolder fs-3 d-inline-block">
|
||||||
<img class="d-dark-none" src="{% static 'images/favicons/haikalbot_v1.png' %}" alt="{% trans 'home' %}" width="32" />
|
<img class="d-dark-none" src="{% static 'images/favicons/haikalbot_v1.png' %}" alt="{% trans 'home' %}" width="32" />
|
||||||
@ -99,16 +99,16 @@ AI assistant
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Global configuration
|
// Global configuration
|
||||||
const MAX_MESSAGE_LENGTH = 400;
|
const MAX_MESSAGE_LENGTH = 400;
|
||||||
const WARNING_THRESHOLD = 350;
|
const WARNING_THRESHOLD = 350;
|
||||||
const isArabic = '{{ LANGUAGE_CODE }}' === 'ar';
|
const isArabic = '{{ LANGUAGE_CODE }}' === 'ar';
|
||||||
|
|
||||||
// Chart rendering function
|
// Chart rendering function
|
||||||
function renderInsightChart(labels, data, chartType = 'bar', title = 'Insight Chart') {
|
function renderInsightChart(labels, data, chartType = 'bar', title = 'Insight Chart') {
|
||||||
const canvasId = 'chart_' + Date.now();
|
const canvasId = 'chart_' + Date.now();
|
||||||
const chartHtml = `<div class="chart-container"><canvas id="${canvasId}"></canvas></div>`;
|
const chartHtml = `<div class="chart-container"><canvas id="${canvasId}"></canvas></div>`;
|
||||||
$('#chatMessages').append(chartHtml);
|
$('#chatMessages').append(chartHtml);
|
||||||
@ -136,9 +136,9 @@ function renderInsightChart(labels, data, chartType = 'bar', title = 'Insight Ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// DOM elements
|
// DOM elements
|
||||||
const messageInput = $('#messageInput');
|
const messageInput = $('#messageInput');
|
||||||
const charCount = $('#charCount');
|
const charCount = $('#charCount');
|
||||||
@ -516,6 +516,6 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
@ -145,8 +145,14 @@
|
|||||||
hx-on::after-request="filter_after_request()">{{ _("Search") }}</button>
|
hx-on::after-request="filter_after_request()">{{ _("Search") }}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<form class="update-price-form d-flex flex-row align-items-center ms-auto w-25 d-none" action="" method="post" style="float:right;">
|
<form hx-boost='true' action="{% url 'bulk_update_car_price' %}" method="post"
|
||||||
<input class="form-control me-2" type="number" placeholder='{{ _("Search") }}' name="price" aria-label="Price">
|
hx-include=".car-checkbox"
|
||||||
|
class="update-price-form d-flex flex-row align-items-center ms-auto w-25 d-none" style="float:right;">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="form-floating me-2">
|
||||||
|
<input class="form-control" type="number" placeholder='{{ _("Search") }}' name="price" aria-label="Price" id="price">
|
||||||
|
<label for="price">{{ _("Price") }}</label>
|
||||||
|
</div>
|
||||||
<button class="btn btn-outline-primary" type="submit">{{ _("Search") }}</button>
|
<button class="btn btn-outline-primary" type="submit">{{ _("Search") }}</button>
|
||||||
</form>
|
</form>
|
||||||
<div class="table-responsive scrollbar transition">
|
<div class="table-responsive scrollbar transition">
|
||||||
@ -186,7 +192,7 @@
|
|||||||
<tr class="position-static">
|
<tr class="position-static">
|
||||||
<td class="align-middle white-space-nowrap">
|
<td class="align-middle white-space-nowrap">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input car-checkbox" type="checkbox" name="car" id="car-{{car.pk}}">
|
<input class="form-check-input car-checkbox" type="checkbox" name="car" value="{{ car.pk }}" id="car-{{car.pk}}">
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="align-middle white-space-nowrap ps-1">
|
<td class="align-middle white-space-nowrap ps-1">
|
||||||
@ -275,8 +281,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
links = document.querySelectorAll('.nav-link')
|
links = document.querySelectorAll('.nav-link')
|
||||||
links.forEach(link => {
|
links.forEach(link => {
|
||||||
@ -313,18 +319,31 @@
|
|||||||
|
|
||||||
document.getElementById('select-all').addEventListener('change', function() {
|
document.getElementById('select-all').addEventListener('change', function() {
|
||||||
const checkboxes = document.querySelectorAll('#project-list-table-body input[type="checkbox"]');
|
const checkboxes = document.querySelectorAll('#project-list-table-body input[type="checkbox"]');
|
||||||
checkboxes.forEach(checkbox => {
|
|
||||||
checkbox.checked = this.checked;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
document.getElementById('car-checkbox').addEventListener('change', function() {
|
|
||||||
const form = document.querySelector('.update-price-form');
|
|
||||||
if (this.checked) {
|
if (this.checked) {
|
||||||
|
checkboxes.forEach(checkbox => checkbox.checked = true);
|
||||||
|
} else {
|
||||||
|
checkboxes.forEach(checkbox => checkbox.checked = false);
|
||||||
|
}
|
||||||
|
updateFormVisibility();
|
||||||
|
});
|
||||||
|
|
||||||
|
const cbox = document.querySelectorAll('.car-checkbox');
|
||||||
|
cbox.forEach(checkbox => {
|
||||||
|
checkbox.addEventListener('change', function() {
|
||||||
|
updateFormVisibility();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateFormVisibility() {
|
||||||
|
const form = document.querySelector('.update-price-form');
|
||||||
|
const checkedCount = document.querySelectorAll('.car-checkbox:checked').length;
|
||||||
|
const submitButton = form.querySelector('button[type="submit"]');
|
||||||
|
if (checkedCount > 0) {
|
||||||
form.classList.remove('d-none');
|
form.classList.remove('d-none');
|
||||||
|
submitButton.textContent = `Update Cost Price (${checkedCount})`;
|
||||||
} else {
|
} else {
|
||||||
form.classList.add('d-none');
|
form.classList.add('d-none');
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock customJS %}
|
{% endblock customJS %}
|
||||||
|
|||||||
@ -45,7 +45,7 @@
|
|||||||
#065535
|
#065535
|
||||||
#000000
|
#000000
|
||||||
#133337
|
#133337
|
||||||
#ffc0cb</a>
|
#ffc0cb</a>
|
||||||
<br>
|
<br>
|
||||||
<span class="glyphicon glyphicon-star"></span>707
|
<span class="glyphicon glyphicon-star"></span>707
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -351,4 +351,4 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -130,7 +130,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block customerJS %}
|
{% block customerJS %}
|
||||||
<script>
|
<script>
|
||||||
// Handle delete modal for all tables
|
// Handle delete modal for all tables
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
var deleteModal = document.getElementById('deleteModal');
|
var deleteModal = document.getElementById('deleteModal');
|
||||||
@ -140,5 +140,5 @@
|
|||||||
document.getElementById('deleteAccountBtn').href = `/accounts/delete/${accountId}/`;
|
document.getElementById('deleteAccountBtn').href = `/accounts/delete/${accountId}/`;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% if accounts %}
|
{% if accounts %}
|
||||||
<div class="table-responsive px-1 scrollbar mt-3">
|
<div class="table-responsive px-1 scrollbar mt-3">
|
||||||
<table class="table align-items-center table-flush">
|
<table class="table align-items-center table-flush">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-body-highlight">
|
<tr class="bg-body-highlight">
|
||||||
@ -54,16 +54,16 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-end mt-3">
|
<div class="d-flex justify-content-end mt-3">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
{% if is_paginated %}
|
{% if is_paginated %}
|
||||||
{% include 'partials/pagination.html' %}
|
{% include 'partials/pagination.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="alert ">
|
<div class="alert ">
|
||||||
{% trans "No accounts found in this category." %}
|
{% trans "No accounts found in this category." %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<h2>{{ title }}</h2>
|
<h2>{{ title }}</h2>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
@ -59,10 +59,10 @@
|
|||||||
<a href="{% url 'purchase_order_list' %}" class="btn btn-phoenix-secondary">Cancel</a>
|
<a href="{% url 'purchase_order_list' %}" class="btn btn-phoenix-secondary">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
const container = document.getElementById('formset-container');
|
const container = document.getElementById('formset-container');
|
||||||
const addBtn = document.getElementById('add-item');
|
const addBtn = document.getElementById('add-item');
|
||||||
const totalForms = document.querySelector('#id_form-TOTAL_FORMS');
|
const totalForms = document.querySelector('#id_form-TOTAL_FORMS');
|
||||||
@ -99,11 +99,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
totalForms.value = parseInt(totalForms.value) - 1;
|
totalForms.value = parseInt(totalForms.value) - 1;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Empty form template -->
|
<!-- Empty form template -->
|
||||||
<div class="empty-form d-none">
|
<div class="empty-form d-none">
|
||||||
<div class="item-form row g-3 mb-3 align-items-end">
|
<div class="item-form row g-3 mb-3 align-items-end">
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<select name="form-__prefix__-make" class="form-select make-select"></select>
|
<select name="form-__prefix__-make" class="form-select make-select"></select>
|
||||||
@ -130,6 +130,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
<button type="button" class="btn btn-phoenix-danger btn-sm remove-row">Remove</button>
|
<button type="button" class="btn btn-phoenix-danger btn-sm remove-row">Remove</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load static i18n crispy_forms_tags %}
|
{% load static i18n crispy_forms_tags %}
|
||||||
{% block customCSS %}
|
{% block customCSS %}
|
||||||
<style>
|
<style>
|
||||||
.color-card {
|
.color-card {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
@ -67,10 +67,10 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="row g-4">
|
<div class="row g-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@ -140,5 +140,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary mt-5">Add New Item To Inventory</button>
|
<button type="submit" class="btn btn-primary mt-5">Add New Item To Inventory</button>
|
||||||
</form>
|
</form>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
{% load django_ledger %}
|
{% load django_ledger %}
|
||||||
{% load widget_tweaks %}
|
{% load widget_tweaks %}
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
window.showPOModal = function(title, actionUrl, buttonText) {
|
window.showPOModal = function(title, actionUrl, buttonText) {
|
||||||
const modalEl = document.getElementById('POModal');
|
const modalEl = document.getElementById('POModal');
|
||||||
if (!modalEl) {
|
if (!modalEl) {
|
||||||
@ -26,7 +26,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
modal.show();
|
modal.show();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% if not create_po %}
|
{% if not create_po %}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<form action="{% url 'inventory_item_create' po_model.pk %}" method="post">
|
<form action="{% url 'inventory_item_create' po_model.pk %}" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% include "purchase_orders/partials/po-select.html" with name="make" target="model" data=make_data pk=po_model.pk %}
|
{% include "purchase_orders/partials/po-select.html" with name="make" target="model" data=make_data pk=po_model.pk %}
|
||||||
{% include "purchase_orders/partials/po-select.html" with name="model" target="serie" data=model_data pk=po_model.pk %}
|
{% include "purchase_orders/partials/po-select.html" with name="model" target="serie" data=model_data pk=po_model.pk %}
|
||||||
@ -22,6 +22,6 @@
|
|||||||
<input type="number" class="form-control" id="quantity" name="quantity" required>
|
<input type="number" class="form-control" id="quantity" name="quantity" required>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-phoenix-primary">Add New Item To Inventory</button>
|
<button type="submit" class="btn btn-phoenix-primary">Add New Item To Inventory</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container-fluid mt-4">
|
<div class="container-fluid mt-4">
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="account">Name</label>
|
<label for="account">Name</label>
|
||||||
@ -18,6 +18,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-phoenix-primary mt-2">Add New Item To Inventory</button>
|
<button type="submit" class="btn btn-phoenix-primary mt-2">Add New Item To Inventory</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
@ -6,7 +6,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<h2>Confirm Deletion</h2>
|
<h2>Confirm Deletion</h2>
|
||||||
<p>Are you sure you want to delete the Purchase Order <strong>"{{ po.po_number }}"</strong>?</p>
|
<p>Are you sure you want to delete the Purchase Order <strong>"{{ po.po_number }}"</strong>?</p>
|
||||||
|
|
||||||
@ -15,5 +15,5 @@
|
|||||||
<button type="submit" class="btn btn-phoenix-danger">Yes, Delete</button>
|
<button type="submit" class="btn btn-phoenix-danger">Yes, Delete</button>
|
||||||
<a href="{% url 'purchase_order_detail' po.id %}" class="btn btn-phoenix-secondary">Cancel</a>
|
<a href="{% url 'purchase_order_detail' po.id %}" class="btn btn-phoenix-secondary">Cancel</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -5,7 +5,7 @@
|
|||||||
{% load django_ledger %}
|
{% load django_ledger %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container-fluid mt-4">
|
<div class="container-fluid mt-4">
|
||||||
<div class="row g-4">
|
<div class="row g-4">
|
||||||
<!-- Left Sidebar -->
|
<!-- Left Sidebar -->
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
@ -64,14 +64,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include "purchase_orders/includes/mark_as.html" %}
|
{% include "purchase_orders/includes/mark_as.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
window.showPOModal = function(title, actionUrl, buttonText) {
|
window.showPOModal = function(title, actionUrl, buttonText) {
|
||||||
const modalEl = document.getElementById('POModal');
|
const modalEl = document.getElementById('POModal');
|
||||||
if (!modalEl) {
|
if (!modalEl) {
|
||||||
@ -95,6 +95,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
modal.show();
|
modal.show();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock customJS %}
|
{% endblock customJS %}
|
||||||
@ -6,7 +6,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<h2>Purchase Order: {{ po.po_number }}</h2>
|
<h2>Purchase Order: {{ po.po_number }}</h2>
|
||||||
<p><strong>Status:</strong>
|
<p><strong>Status:</strong>
|
||||||
<span class="">
|
<span class="">
|
||||||
@ -60,8 +60,8 @@
|
|||||||
<a href="{% url 'purchase_order_list' %}" class="btn btn-phoenix-secondary">Back to List</a>
|
<a href="{% url 'purchase_order_list' %}" class="btn btn-phoenix-secondary">Back to List</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal fade" id="POModal" data-bs-keyboard="true" tabindex="-1" aria-labelledby="POModalLabel" aria-hidden="true">
|
<div class="modal fade" id="POModal" data-bs-keyboard="true" tabindex="-1" aria-labelledby="POModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-lg">
|
<div class="modal-dialog modal-lg">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header justify-content-between align-items-start gap-5 px-4 pt-4 pb-3 border-0">
|
<div class="modal-header justify-content-between align-items-start gap-5 px-4 pt-4 pb-3 border-0">
|
||||||
|
|||||||
@ -93,8 +93,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
function showPOModal(title, actionUrl, buttonText) {
|
function showPOModal(title, actionUrl, buttonText) {
|
||||||
const modal = new bootstrap.Modal(document.getElementById('POModal'));
|
const modal = new bootstrap.Modal(document.getElementById('POModal'));
|
||||||
document.getElementById('POModalTitle').innerText = title;
|
document.getElementById('POModalTitle').innerText = title;
|
||||||
|
|
||||||
@ -105,6 +105,6 @@ function showPOModal(title, actionUrl, buttonText) {
|
|||||||
</a>
|
</a>
|
||||||
`;
|
`;
|
||||||
modal.show();
|
modal.show();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock customJS %}
|
{% endblock customJS %}
|
||||||
@ -1,10 +1,10 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<h1><i class="fa-solid fa-cart-shopping me-1"></i>{{po.po_number}}</h1>
|
<h1><i class="fa-solid fa-cart-shopping me-1"></i>{{po.po_number}}</h1>
|
||||||
|
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<h4>Status:</h4>
|
<h4>Status:</h4>
|
||||||
{% comment %} Apply appropriate text color based on po.po_status {% endcomment %}
|
{% comment %} Apply appropriate text color based on po.po_status {% endcomment %}
|
||||||
{% if po.po_status == 'draft' %}
|
{% if po.po_status == 'draft' %}
|
||||||
@ -20,7 +20,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<h4 class="ms-2 text-muted mb-0">{{ po.po_status|capfirst }}</h4> {# Use muted for unknown/default status #}
|
<h4 class="ms-2 text-muted mb-0">{{ po.po_status|capfirst }}</h4> {# Use muted for unknown/default status #}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -68,7 +68,7 @@
|
|||||||
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock customCSS %}
|
{% endblock customCSS %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
{% load static i18n humanize %}
|
{% load static i18n humanize %}
|
||||||
|
|
||||||
{% block customCSS %}
|
{% block customCSS %}
|
||||||
<style>
|
<style>
|
||||||
/* Custom CSS for additional styling */
|
/* Custom CSS for additional styling */
|
||||||
.status-badge {
|
.status-badge {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
@ -67,11 +67,11 @@
|
|||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
border-radius: 0.375rem;
|
border-radius: 0.375rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock customCSS %}
|
{% endblock customCSS %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container-fluid px-0">
|
<div class="container-fluid px-0">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<header class="bg-primary py-3">
|
<header class="bg-primary py-3">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -81,10 +81,10 @@
|
|||||||
{{ _("Sale Order")}} #{{ saleorder.formatted_order_id }}
|
{{ _("Sale Order")}} #{{ saleorder.formatted_order_id }}
|
||||||
</h1>
|
</h1>
|
||||||
<div>
|
<div>
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
=======
|
=======
|
||||||
|
|
||||||
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
||||||
<button class="btn btn-sm btn-outline-light me-2">
|
<button class="btn btn-sm btn-outline-light me-2">
|
||||||
<i class="fas fa-print me-1"></i> {{ _("Print") }}
|
<i class="fas fa-print me-1"></i> {{ _("Print") }}
|
||||||
</button>
|
</button>
|
||||||
@ -275,17 +275,17 @@
|
|||||||
<!-- Documents Card -->
|
<!-- Documents Card -->
|
||||||
<div class="card mb-4 shadow-sm">
|
<div class="card mb-4 shadow-sm">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
<h5 class="mb-0">{{ _("Documents") }}</h5>
|
<h5 class="mb-0">{{ _("Documents") }}</h5>
|
||||||
<button class="btn btn-sm btn-primary">
|
<button class="btn btn-sm btn-primary">
|
||||||
<i class="fas fa-plus me-1"></i> {{ _("Add Document")}}
|
<i class="fas fa-plus me-1"></i> {{ _("Add Document")}}
|
||||||
=======
|
=======
|
||||||
|
|
||||||
<h5 class="mb-0">{{ _("Documents") }}</h5>
|
<h5 class="mb-0">{{ _("Documents") }}</h5>
|
||||||
<button class="btn btn-sm btn-primary">
|
<button class="btn btn-sm btn-primary">
|
||||||
<i class="fas fa-plus me-1"></i> {{ _("Add Document")}}
|
<i class="fas fa-plus me-1"></i> {{ _("Add Document")}}
|
||||||
|
|
||||||
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -330,13 +330,13 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<textarea class="form-control" name="comment" rows="3" placeholder="Add a comment or note..." required></textarea>
|
<textarea class="form-control" name="comment" rows="3" placeholder="Add a comment or note..." required></textarea>
|
||||||
<div class="d-flex justify-content-end mt-2">
|
<div class="d-flex justify-content-end mt-2">
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
<button type="submit" class="btn btn-primary btn-sm">{{ _("Post Comment")}}</button>
|
<button type="submit" class="btn btn-primary btn-sm">{{ _("Post Comment")}}</button>
|
||||||
=======
|
=======
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary btn-sm">{{ _("Post Comment")}}</button>
|
<button type="submit" class="btn btn-primary btn-sm">{{ _("Post Comment")}}</button>
|
||||||
|
|
||||||
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -379,51 +379,51 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% comment %} <a href="{% url 'edit_sale_order' saleorder.pk %}" class="btn btn-primary"> {% endcomment %}
|
{% comment %} <a href="{% url 'edit_sale_order' saleorder.pk %}" class="btn btn-primary"> {% endcomment %}
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
=======
|
=======
|
||||||
|
|
||||||
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
||||||
<a href="" class="btn btn-primary">
|
<a href="" class="btn btn-primary">
|
||||||
<i class="fas fa-edit me-2"></i> {{ _("Edit Order")}}
|
<i class="fas fa-edit me-2"></i> {{ _("Edit Order")}}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if not saleorder.invoice %}
|
{% if not saleorder.invoice %}
|
||||||
{% comment %} <a href="{% url 'create_invoice_from_order' saleorder.pk %}" class="btn btn-info"> {% endcomment %}
|
{% comment %} <a href="{% url 'create_invoice_from_order' saleorder.pk %}" class="btn btn-info"> {% endcomment %}
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
<a href="" class="btn btn-info">
|
<a href="" class="btn btn-info">
|
||||||
<i class="fas fa-file-invoice-dollar me-2"></i> {{ _("Create Invoice")}}
|
<i class="fas fa-file-invoice-dollar me-2"></i> {{ _("Create Invoice")}}
|
||||||
=======
|
=======
|
||||||
|
|
||||||
<a href="" class="btn btn-info">
|
<a href="" class="btn btn-info">
|
||||||
<i class="fas fa-file-invoice-dollar me-2"></i> {{ _("Create Invoice")}}
|
<i class="fas fa-file-invoice-dollar me-2"></i> {{ _("Create Invoice")}}
|
||||||
|
|
||||||
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if saleorder.status == 'approved' and not saleorder.actual_delivery_date %}
|
{% if saleorder.status == 'approved' and not saleorder.actual_delivery_date %}
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
<button class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#deliveryModal">
|
<button class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#deliveryModal">
|
||||||
<i class="fas fa-truck me-2"></i> {{ _("Schedule Delivery")}}
|
<i class="fas fa-truck me-2"></i> {{ _("Schedule Delivery")}}
|
||||||
=======
|
=======
|
||||||
|
|
||||||
<button class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#deliveryModal">
|
<button class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#deliveryModal">
|
||||||
<i class="fas fa-truck me-2"></i> {{ _("Schedule Delivery")}}
|
<i class="fas fa-truck me-2"></i> {{ _("Schedule Delivery")}}
|
||||||
|
|
||||||
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if saleorder.status != 'cancelled' %}
|
{% if saleorder.status != 'cancelled' %}
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
<button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#cancelModal">
|
<button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#cancelModal">
|
||||||
<i class="fas fa-times-circle me-2"></i> {{ _("Cancel Order")}}
|
<i class="fas fa-times-circle me-2"></i> {{ _("Cancel Order")}}
|
||||||
=======
|
=======
|
||||||
|
|
||||||
<button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#cancelModal">
|
<button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#cancelModal">
|
||||||
<i class="fas fa-times-circle me-2"></i> {{ _("Cancel Order")}}
|
<i class="fas fa-times-circle me-2"></i> {{ _("Cancel Order")}}
|
||||||
|
|
||||||
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
@ -555,10 +555,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Cancel Order Modal -->
|
<!-- Cancel Order Modal -->
|
||||||
<div class="modal fade" id="cancelModal" tabindex="-1" aria-labelledby="cancelModalLabel" aria-hidden="true">
|
<div class="modal fade" id="cancelModal" tabindex="-1" aria-labelledby="cancelModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
@ -575,23 +575,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ _("Close") }}</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ _("Close") }}</button>
|
||||||
<button type="submit" class="btn btn-danger">{{ _("Confirm Cancellation")}}</button>
|
<button type="submit" class="btn btn-danger">{{ _("Confirm Cancellation")}}</button>
|
||||||
=======
|
=======
|
||||||
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ _("Close") }}</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ _("Close") }}</button>
|
||||||
<button type="submit" class="btn btn-danger">{{ _("Confirm Cancellation")}}</button>
|
<button type="submit" class="btn btn-danger">{{ _("Confirm Cancellation")}}</button>
|
||||||
|
|
||||||
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Schedule Delivery Modal -->
|
<!-- Schedule Delivery Modal -->
|
||||||
<div class="modal fade" id="deliveryModal" tabindex="-1" aria-labelledby="deliveryModalLabel" aria-hidden="true">
|
<div class="modal fade" id="deliveryModal" tabindex="-1" aria-labelledby="deliveryModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
@ -612,24 +612,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ _("Close") }}</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ _("Close") }}</button>
|
||||||
<button type="submit" class="btn btn-primary">{{ _("Schedule Delivery")}}</button>
|
<button type="submit" class="btn btn-primary">{{ _("Schedule Delivery")}}</button>
|
||||||
=======
|
=======
|
||||||
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ _("Close") }}</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ _("Close") }}</button>
|
||||||
<button type="submit" class="btn btn-primary">{{ _("Schedule Delivery")}}</button>
|
<button type="submit" class="btn btn-primary">{{ _("Schedule Delivery")}}</button>
|
||||||
|
|
||||||
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
>>>>>>> e9e2fd3 (add bulk insert + po item insert)
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
<script>
|
<script>
|
||||||
// Status update function
|
// Status update function
|
||||||
function updateStatus(newStatus) {
|
function updateStatus(newStatus) {
|
||||||
fetch("", {
|
fetch("", {
|
||||||
@ -669,5 +669,5 @@
|
|||||||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock customJS %}
|
{% endblock customJS %}
|
||||||
@ -12,12 +12,12 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="content fs-9">
|
<div class="content fs-9">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<!-- English Section -->
|
<!-- English Section -->
|
||||||
<h2>Date: 1/1/2025</h2>
|
<h2>Date: 1/1/2025</h2>
|
||||||
<section id="terms">
|
<section id="terms">
|
||||||
<h2>Terms of Service</h2>
|
<h2>Terms of Service</h2>
|
||||||
<p>Welcome to <strong>Haikal</strong>, an advanced car inventory management platform owned and operated by <strong>Tenhal Information Technology Company</strong> ("we", "our", "us"). By accessing or using the Haikal system ("the Service"), you agree to be legally bound by the terms outlined below.</p>
|
<p>Welcome to <strong>Haikal</strong>, an advanced car inventory management platform owned and operated by <strong>Tenhal Information Technology Company</strong> ("we", "our", "us"). By accessing or using the Haikal system ("the Service"), you agree to be legally bound by the terms outlined below.</p>
|
||||||
<h3>1. Acceptance of Terms</h3>
|
<h3>1. Acceptance of Terms</h3>
|
||||||
@ -66,11 +66,11 @@
|
|||||||
|
|
||||||
<h3>11. Governing Law</h3>
|
<h3>11. Governing Law</h3>
|
||||||
<p>These terms are governed by the laws of the Kingdom of Saudi Arabia. Any disputes will be resolved exclusively in courts located in Riyadh.</p>
|
<p>These terms are governed by the laws of the Kingdom of Saudi Arabia. Any disputes will be resolved exclusively in courts located in Riyadh.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<section id="privacy">
|
<section id="privacy">
|
||||||
<h2>Privacy Policy</h2>
|
<h2>Privacy Policy</h2>
|
||||||
|
|
||||||
<p>We value your privacy and are committed to protecting your personal and business data. This Privacy Policy explains how we collect, use, and protect your information when you use Haikal.</p>
|
<p>We value your privacy and are committed to protecting your personal and business data. This Privacy Policy explains how we collect, use, and protect your information when you use Haikal.</p>
|
||||||
@ -120,7 +120,7 @@
|
|||||||
|
|
||||||
<h3>9. Changes to this Policy</h3>
|
<h3>9. Changes to this Policy</h3>
|
||||||
<p>We may revise this Privacy Policy from time to time. Updates will be posted here with a revised effective date.</p>
|
<p>We may revise this Privacy Policy from time to time. Updates will be posted here with a revised effective date.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -128,7 +128,7 @@
|
|||||||
<div class="col-6" dir="rtl">
|
<div class="col-6" dir="rtl">
|
||||||
<h2>التاريخ: ١/١/٢٠٢٥</h2>
|
<h2>التاريخ: ١/١/٢٠٢٥</h2>
|
||||||
<!-- Arabic Section -->
|
<!-- Arabic Section -->
|
||||||
<section class="arabic">
|
<section class="arabic">
|
||||||
<h2>شروط الخدمة</h2>
|
<h2>شروط الخدمة</h2>
|
||||||
<p>مرحبًا بك في <strong>هيكل</strong>، منصة متقدمة لإدارة مخزون السيارات، مملوكة وتديرها <strong>شركة تنحل لتقنية المعلومات</strong> ("نحن"، "خاصتنا"). باستخدامك لنظام هيكل، فإنك توافق على الالتزام القانوني بالشروط التالية:</p>
|
<p>مرحبًا بك في <strong>هيكل</strong>، منصة متقدمة لإدارة مخزون السيارات، مملوكة وتديرها <strong>شركة تنحل لتقنية المعلومات</strong> ("نحن"، "خاصتنا"). باستخدامك لنظام هيكل، فإنك توافق على الالتزام القانوني بالشروط التالية:</p>
|
||||||
|
|
||||||
@ -178,11 +178,11 @@
|
|||||||
|
|
||||||
<h3>١١. القانون الحاكم</h3>
|
<h3>١١. القانون الحاكم</h3>
|
||||||
<p>تخضع هذه الشروط لقوانين المملكة العربية السعودية، ويكون الاختصاص القضائي لمحاكم الرياض فقط.</p>
|
<p>تخضع هذه الشروط لقوانين المملكة العربية السعودية، ويكون الاختصاص القضائي لمحاكم الرياض فقط.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<section class="arabic">
|
<section class="arabic">
|
||||||
<h2>سياسة الخصوصية</h2>
|
<h2>سياسة الخصوصية</h2>
|
||||||
|
|
||||||
<p>نحن نهتم بخصوصيتك وملتزمون بحماية بياناتك الشخصية والتجارية. توضح هذه السياسة كيفية جمع واستخدام وحماية بياناتك عند استخدام نظام هيكل.</p>
|
<p>نحن نهتم بخصوصيتك وملتزمون بحماية بياناتك الشخصية والتجارية. توضح هذه السياسة كيفية جمع واستخدام وحماية بياناتك عند استخدام نظام هيكل.</p>
|
||||||
@ -232,10 +232,10 @@
|
|||||||
|
|
||||||
<h3>٩. التحديثات</h3>
|
<h3>٩. التحديثات</h3>
|
||||||
<p>قد نُجري تغييرات على هذه السياسة، وسيتم نشر التعديلات مع تاريخ سريان جديد.</p>
|
<p>قد نُجري تغييرات على هذه السياسة، وسيتم نشر التعديلات مع تاريخ سريان جديد.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row border-top">
|
<div class="row border-top">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<section id="contact">
|
<section id="contact">
|
||||||
@ -247,7 +247,7 @@
|
|||||||
📧 <a href="mailto:info@tenhal.sa">info@tenhal.sa</a><br>
|
📧 <a href="mailto:info@tenhal.sa">info@tenhal.sa</a><br>
|
||||||
🌐 <a href="https://www.tenhal.sa" target="_blank">www.tenhal.sa</a>
|
🌐 <a href="https://www.tenhal.sa" target="_blank">www.tenhal.sa</a>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6" dir="rtl">
|
<div class="col-6" dir="rtl">
|
||||||
<section class="arabic">
|
<section class="arabic">
|
||||||
@ -259,7 +259,7 @@
|
|||||||
📧 <a href="mailto:info@tenhal.sa">info@tenhal.sa</a><br>
|
📧 <a href="mailto:info@tenhal.sa">info@tenhal.sa</a><br>
|
||||||
🌐 <a href="https://www.tenhal.sa" target="_blank">tenhal.sa</a>
|
🌐 <a href="https://www.tenhal.sa" target="_blank">tenhal.sa</a>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
{% block title %}{{ tour.name }} - Interactive Guide{% endblock %}
|
{% block title %}{{ tour.name }} - Interactive Guide{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container my-4">
|
<div class="container my-4">
|
||||||
<h1>{{ tour.name }}</h1>
|
<h1>{{ tour.name }}</h1>
|
||||||
<p class="lead">{{ tour.description }}</p>
|
<p class="lead">{{ tour.description }}</p>
|
||||||
|
|
||||||
@ -16,16 +16,16 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_js %}
|
{% block extra_js %}
|
||||||
<script>
|
<script>
|
||||||
// Auto-start the tour after a short delay
|
// Auto-start the tour after a short delay
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.tourManager.loadTour('{{ tour.slug }}');
|
window.tourManager.loadTour('{{ tour.slug }}');
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -3,7 +3,7 @@
|
|||||||
{% block title %}Interactive Guides{% endblock %}
|
{% block title %}Interactive Guides{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container my-4">
|
<div class="container my-4">
|
||||||
<h1>Interactive Guides</h1>
|
<h1>Interactive Guides</h1>
|
||||||
<p class="lead">Learn how to use the car inventory system with these interactive step-by-step guides.</p>
|
<p class="lead">Learn how to use the car inventory system with these interactive step-by-step guides.</p>
|
||||||
|
|
||||||
@ -28,5 +28,5 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user