up Filter, docs, base temletes
This commit is contained in:
parent
c83938bddc
commit
13f065d4fc
25198
logs/app.log
25198
logs/app.log
File diff suppressed because it is too large
Load Diff
26674
logs/app.log.1
26674
logs/app.log.1
File diff suppressed because it is too large
Load Diff
63072
logs/app.log.2
63072
logs/app.log.2
File diff suppressed because it is too large
Load Diff
|
@ -114,7 +114,8 @@ async def process_client_data(
|
||||||
get_jobs = await get_applied_jobs(db, user_id)
|
get_jobs = await get_applied_jobs(db, user_id)
|
||||||
|
|
||||||
# [ ]: NOTE Рабоиа в фоне BackgroundTasks process_client_data()
|
# [ ]: NOTE Рабоиа в фоне BackgroundTasks process_client_data()
|
||||||
@router.post("/client/")
|
@router.post("/client/", summary="Обновления json_data и переобновление вакансий",
|
||||||
|
description="Этот эндпоинт обновляет json_data, удаляет все вакансии со статусом Scheduled и создаёт по полученным данным новые вакансии")
|
||||||
async def client(
|
async def client(
|
||||||
data: JsonData,
|
data: JsonData,
|
||||||
x_api_key: str = Header(...),
|
x_api_key: str = Header(...),
|
||||||
|
@ -236,7 +237,8 @@ async def client(
|
||||||
# return {"status": "ok", "message": "JSON получен"}
|
# return {"status": "ok", "message": "JSON получен"}
|
||||||
|
|
||||||
|
|
||||||
@router.post("/client_update")
|
@router.post("/client_update", summary="Обновления клиента",
|
||||||
|
description="Этот эндпоинт получает ID пользователя, переходит по ссылки что бы получить json_data")
|
||||||
async def client_update(data: update, x_api_key: str = Header(...), db: Session = Depends(get_async_session)):
|
async def client_update(data: update, x_api_key: str = Header(...), db: Session = Depends(get_async_session)):
|
||||||
|
|
||||||
if x_api_key != "4545454":
|
if x_api_key != "4545454":
|
||||||
|
@ -256,7 +258,8 @@ async def client_update(data: update, x_api_key: str = Header(...), db: Session
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/client_jobs/")
|
@router.post("/client_jobs/", summary="Получить список работ по клиенту",
|
||||||
|
description="Этот эндпоинт получает ID пользователя, в ответ отдаёт список вакансий")
|
||||||
async def client_jobs(data: update, x_api_key: str = Header(...), db: Session = Depends(get_async_session)):
|
async def client_jobs(data: update, x_api_key: str = Header(...), db: Session = Depends(get_async_session)):
|
||||||
if x_api_key != "4545454":
|
if x_api_key != "4545454":
|
||||||
raise HTTPException(status_code=403, detail="Invalid API Key")
|
raise HTTPException(status_code=403, detail="Invalid API Key")
|
||||||
|
@ -274,7 +277,8 @@ async def client_jobs(data: update, x_api_key: str = Header(...), db: Session =
|
||||||
# return {"message": "JSON получен", "data": get_jobs}
|
# return {"message": "JSON получен", "data": get_jobs}
|
||||||
|
|
||||||
|
|
||||||
@router.post("/avtopilot")
|
@router.post("/avtopilot", summary="Автопилот вкл, выкл",
|
||||||
|
description="Этот эндпоинт получает ID пользователя, включает или отключает автопилот. При false все вакансии со статусом Scheduled становятся Paused при true наоборот!")
|
||||||
async def avtopilot(data: avtopilots, x_api_key: str = Header(...), db: Session = Depends(get_async_session)):
|
async def avtopilot(data: avtopilots, x_api_key: str = Header(...), db: Session = Depends(get_async_session)):
|
||||||
|
|
||||||
if x_api_key != "4545454":
|
if x_api_key != "4545454":
|
||||||
|
@ -295,7 +299,8 @@ async def avtopilot(data: avtopilots, x_api_key: str = Header(...), db: Session
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/jobs_delete")
|
@router.post("/jobs_delete", summary="Удаление вакансии",
|
||||||
|
description="Этот эндпоинт получает ID пользователя и ID вакансии, Удаляет у пользователя вакансию")
|
||||||
async def jobs_delete(data: jobs_delete, x_api_key: str = Header(...), db: Session = Depends(get_async_session)):
|
async def jobs_delete(data: jobs_delete, x_api_key: str = Header(...), db: Session = Depends(get_async_session)):
|
||||||
if x_api_key != "4545454":
|
if x_api_key != "4545454":
|
||||||
raise HTTPException(status_code=403, detail="Invalid API Key")
|
raise HTTPException(status_code=403, detail="Invalid API Key")
|
||||||
|
|
|
@ -318,6 +318,10 @@ async def product_filtered(
|
||||||
if conditions:
|
if conditions:
|
||||||
stmt = stmt.join(Job).where(and_(*conditions))
|
stmt = stmt.join(Job).where(and_(*conditions))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("client_id:", client)
|
||||||
|
print("status:", status)
|
||||||
# Выполняем запрос
|
# Выполняем запрос
|
||||||
try:
|
try:
|
||||||
result = await session.execute(stmt)
|
result = await session.execute(stmt)
|
||||||
|
@ -359,6 +363,8 @@ async def product_filtered(
|
||||||
"jobs": applied_jobs, "role": username["role"],
|
"jobs": applied_jobs, "role": username["role"],
|
||||||
"username": username['username'], "users": users,
|
"username": username['username'], "users": users,
|
||||||
"role": username["role"],
|
"role": username["role"],
|
||||||
|
"status": status, "assigned_users_ids": assignees,
|
||||||
|
"client_id": client,
|
||||||
|
|
||||||
"current_path": request.url.path
|
"current_path": request.url.path
|
||||||
}
|
}
|
||||||
|
|
7592
search_jobes2.json
7592
search_jobes2.json
File diff suppressed because it is too large
Load Diff
|
@ -56,8 +56,38 @@
|
||||||
<div class="-intro-x breadcrumb mr-auto hidden sm:flex"> </div>
|
<div class="-intro-x breadcrumb mr-auto hidden sm:flex"> </div>
|
||||||
<!-- END: Breadcrumb -->
|
<!-- END: Breadcrumb -->
|
||||||
|
|
||||||
|
<h2 class="text-lg font-medium mr-auto">
|
||||||
|
{{size}}
|
||||||
|
</h2>
|
||||||
|
|
||||||
<!-- BEGIN: Account Menu -->
|
{% set current_path = request.url.path %}
|
||||||
|
|
||||||
|
{% if size == "Work" %}
|
||||||
|
<a href="/productuj">
|
||||||
|
<button class="button text-white shadow-md mr-2 {% if current_path == '/productuj' %}bg-red-700{% else %}bg-theme-1{% endif %}">
|
||||||
|
Unassigned Jobs
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/productmj">
|
||||||
|
<button class="button text-white shadow-md mr-2 {% if current_path == '/productmj' %}bg-red-700{% else %}bg-theme-1{% endif %}">
|
||||||
|
My Jobs
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/product">
|
||||||
|
<button class="button text-white shadow-md mr-2 {% if current_path == '/product' %}bg-red-700{% else %}bg-theme-1{% endif %}">
|
||||||
|
All Jobs
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/productoj">
|
||||||
|
<button class="button text-white shadow-md mr-2 {% if current_path == '/productoj' %}bg-red-700{% else %}bg-theme-1{% endif %}">
|
||||||
|
Outstanding Jobs
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
<!-- BEGIN: Account Menu -->
|
||||||
<div class="intro-x dropdown w-8 h-8 relative">
|
<div class="intro-x dropdown w-8 h-8 relative">
|
||||||
<div class="dropdown-toggle w-8 h-8 rounded-full overflow-hidden shadow-lg image-fit zoom-in">
|
<div class="dropdown-toggle w-8 h-8 rounded-full overflow-hidden shadow-lg image-fit zoom-in">
|
||||||
<img alt="Midone Tailwind HTML Admin Template" src="/static/dist/images/333.png">
|
<img alt="Midone Tailwind HTML Admin Template" src="/static/dist/images/333.png">
|
||||||
|
|
|
@ -26,23 +26,10 @@
|
||||||
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="intro-y flex flex-col sm:flex-row items-center mt-8">
|
|
||||||
<h2 class="text-lg font-medium mr-auto">
|
|
||||||
Tasks
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productuj'">Unasigned Jobs</button>
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productmj'">My Jobs</button>
|
|
||||||
|
|
||||||
<button class="button text-white bg-red-500 hover:bg-red-700 shadow-md mr-2" onclick="window.location.href='/product'">All Jobs</button>
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productoj'">Outstanding Jobs</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="p-5" id="boxed-accordion">
|
<div class="p-5" id="boxed-accordion">
|
||||||
<div class="preview">
|
<div class="preview">
|
||||||
|
@ -98,10 +85,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Applied on -->
|
<!-- Applied on -->
|
||||||
<div class="col-span-6 mt-4">
|
<div class="w-1/2">
|
||||||
<div class="text-xs">Applied on</div>
|
<div class="text-xs">Applied on</div>
|
||||||
<select id="date_applied" class="input w-full border mt-2 flex-1" name="date_applied">
|
<select id="date_applied" class="input w-full border mt-2 flex-1" name="date_applied">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
|
@ -121,8 +108,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-nowrap gap-4 mt-4"> <!-- flex-nowrap запрещает перенос на новую строку -->
|
<div class="flex flex-nowrap gap-4 mt-4"> <!-- flex-nowrap запрещает перенос на новую строку -->
|
||||||
<!-- Clients (50% ширины) -->
|
<!-- Clients (50% ширины) -->
|
||||||
<div class="flex-1 min-w-0"> <!-- flex-1 + min-w-0 предотвращает "расползание" -->
|
<div class="flex-1 min-w-0"> <!-- flex-1 + min-w-0 предотвращает "расползание" -->
|
||||||
<label class="block mb-1 text-sm">Clients</label>
|
<label class="block mb-1 text-sm">Clients</label>
|
||||||
|
@ -147,16 +135,17 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Status и кнопка Apply Filters -->
|
<!-- Status и кнопка Apply Filters -->
|
||||||
<div class="col-span-6 mt-4">
|
<div class="flex-1 min-w-0">
|
||||||
<label>Status</label>
|
<label>Status</label>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<select data-placeholder="Select Status" class="select2 w-full" multiple name="status">
|
<select data-placeholder="Select Status" class="select2 w-full" multiple name="status">
|
||||||
<option value="Scheduled">Scheduled</option>
|
<option value="Scheduled">Scheduled</option>
|
||||||
<option value="Requested">Requested</option>
|
<option value="Requested">Requested</option>
|
||||||
<option value="In-Progress">In-Progress</option>
|
<option value="In-Progress">In-Progress</option>
|
||||||
|
<option value="Paused">Paused</option>
|
||||||
<option value="Applied">Applied</option>
|
<option value="Applied">Applied</option>
|
||||||
<option value="Issues Applying">Issues Applying</option>
|
<option value="Issues Applying">Issues Applying</option>
|
||||||
<option value="Cancelled">Cancelled</option>
|
<option value="Cancelled">Cancelled</option>
|
||||||
|
@ -164,6 +153,7 @@
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="button bg-theme-1 text-white mt-5">Apply Filters</button>
|
<button type="submit" class="button bg-theme-1 text-white mt-5">Apply Filters</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -241,6 +231,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
<option value="Scheduled" {% if job.status == "Scheduled" %}selected{% endif %}>Scheduled</option>
|
<option value="Scheduled" {% if job.status == "Scheduled" %}selected{% endif %}>Scheduled</option>
|
||||||
<option value="Requested" {% if job.status == "Requested" %}selected{% endif %}>Requested</option>
|
<option value="Requested" {% if job.status == "Requested" %}selected{% endif %}>Requested</option>
|
||||||
<option value="In-Progress" {% if job.status == "In-Progress" %}selected{% endif %}>In-Progress</option>
|
<option value="In-Progress" {% if job.status == "In-Progress" %}selected{% endif %}>In-Progress</option>
|
||||||
|
<option value="Paused" {% if job.status == "Paused" %}selected{% endif %}>Paused</option>
|
||||||
<option value="Applied" {% if job.status == "Applied" %}selected{% endif %}>Applied</option>
|
<option value="Applied" {% if job.status == "Applied" %}selected{% endif %}>Applied</option>
|
||||||
<option value="Issues Applying" {% if job.status == "Issues Applying" %}selected{% endif %}>Issues Applying</option>
|
<option value="Issues Applying" {% if job.status == "Issues Applying" %}selected{% endif %}>Issues Applying</option>
|
||||||
<option value="Cancelled" {% if job.status == "Cancelled" %}selected{% endif %}>Cancelled</option>
|
<option value="Cancelled" {% if job.status == "Cancelled" %}selected{% endif %}>Cancelled</option>
|
||||||
|
|
|
@ -4,17 +4,192 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="intro-y flex flex-col sm:flex-row items-center mt-8">
|
|
||||||
<h2 class="text-lg font-medium mr-auto">
|
|
||||||
Tasks
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productuj'">Unasigned Jobs</button>
|
<style>
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productmj'">My Jobs</button>
|
.select2-container {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style>
|
||||||
|
.filter-link {
|
||||||
|
font-size: 18px; /* Увеличиваем размер шрифта */
|
||||||
|
font-weight: bold; /* Делаем текст жирным */
|
||||||
|
padding: 10px 20px; /* Добавляем отступы для лучшего кликабельности */
|
||||||
|
background-color: #7a61fe; /* Добавляем зелёный фон */
|
||||||
|
color: white; /* Текст белый */
|
||||||
|
border-radius: 5px; /* Слегка скругляем углы */
|
||||||
|
text-align: center; /* Выравнивание по центру */
|
||||||
|
cursor: pointer; /* Курсор в виде указателя при наведении */
|
||||||
|
transition: background-color 0.3s ease, transform 0.2s ease; /* Плавные анимации */
|
||||||
|
}
|
||||||
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/product'">All Jobs</button>
|
.filter-link:hover {
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productoj'">Outstanding Jobs</button>
|
background-color: #7a61fe; /* Темнее при наведении */
|
||||||
|
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="p-5" id="boxed-accordion">
|
||||||
|
<div class="preview">
|
||||||
|
<div class="accordion">
|
||||||
|
<div class="accordion__pane__content mt-3 text-gray-700 leading-relaxed">
|
||||||
|
<a href="javascript:;" class="accordion__pane__toggle filter-link font-medium block">Filter</a>
|
||||||
|
|
||||||
|
<div class="accordion__pane__content mt-3 text-gray-800 leading-relaxed">
|
||||||
|
<div class="dropdown-box__content box p-5">
|
||||||
|
<form method="POST" action="/productf">
|
||||||
|
<!-- Дата-фильтры (Requested, Posted, Applied) -->
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<!-- Requested on -->
|
||||||
|
<div class="w-1/2">
|
||||||
|
<div class="text-xs">Requested on</div>
|
||||||
|
<select id="date_requested" class="input w-full border mt-2 flex-1" name="date_requested">
|
||||||
|
<option value=""></option>
|
||||||
|
<option value="Today">Today</option>
|
||||||
|
<option value="Last 7 days">Last 7 days</option>
|
||||||
|
<option value="For all time">For all time</option>
|
||||||
|
<option value="custom_date_requested">from date to date</option>
|
||||||
|
</select>
|
||||||
|
<div id="date-requested-range-wrapper" class="p-5 grid grid-cols-12 gap-4 row-gap-3 mt-4" style="display: none;">
|
||||||
|
<div class="col-span-12 sm:col-span-6">
|
||||||
|
<label>From</label>
|
||||||
|
<input type="date" id="date-requested-from" class="input w-full border mt-2" name="date_requested_from">
|
||||||
|
</div>
|
||||||
|
<div class="col-span-12 sm:col-span-6">
|
||||||
|
<label>To</label>
|
||||||
|
<input type="date" id="date-requested-to" class="input w-full border mt-2" name="date_requested_to">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Posted on -->
|
||||||
|
<div class="w-1/2">
|
||||||
|
<div class="text-xs">Posted on</div>
|
||||||
|
<select id="date_posted" class="input w-full border mt-2 flex-1" name="date_posted">
|
||||||
|
<option value=""></option>
|
||||||
|
<option value="Today">Today</option>
|
||||||
|
<option value="Last 7 days">Last 7 days</option>
|
||||||
|
<option value="For all time">For all time</option>
|
||||||
|
<option value="custom_date_posted">from date to date</option>
|
||||||
|
</select>
|
||||||
|
<div id="date-posted-range-wrapper" class="p-5 grid grid-cols-12 gap-4 row-gap-3 mt-4" style="display: none;">
|
||||||
|
<div class="col-span-12 sm:col-span-6">
|
||||||
|
<label>From</label>
|
||||||
|
<input type="date" id="date-posted-from" class="input w-full border mt-2" name="date_posted_from">
|
||||||
|
</div>
|
||||||
|
<div class="col-span-12 sm:col-span-6">
|
||||||
|
<label>To</label>
|
||||||
|
<input type="date" id="date-posted-to" class="input w-full border mt-2" name="date_posted_to">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Applied on -->
|
||||||
|
<div class="w-1/2">
|
||||||
|
<div class="text-xs">Applied on</div>
|
||||||
|
<select id="date_applied" class="input w-full border mt-2 flex-1" name="date_applied">
|
||||||
|
<option value=""></option>
|
||||||
|
<option value="Today">Today</option>
|
||||||
|
<option value="Last 7 days">Last 7 days</option>
|
||||||
|
<option value="For all time">For all time</option>
|
||||||
|
<option value="custom_date_applied">from date to date</option>
|
||||||
|
</select>
|
||||||
|
<div id="date-applied-range-wrapper" class="p-5 grid grid-cols-12 gap-4 row-gap-3 mt-4" style="display: none;">
|
||||||
|
<div class="col-span-12 sm:col-span-6">
|
||||||
|
<label>From</label>
|
||||||
|
<input type="date" id="date-applied-from" class="input w-full border mt-2" name="date_applied_from">
|
||||||
|
</div>
|
||||||
|
<div class="col-span-12 sm:col-span-6">
|
||||||
|
<label>To</label>
|
||||||
|
<input type="date" id="date-applied-to" class="input w-full border mt-2" name="date_applied_to">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-nowrap gap-4 mt-4"> <!-- flex-nowrap запрещает перенос на новую строку -->
|
||||||
|
<!-- Clients (50% ширины) -->
|
||||||
|
<div class="flex-1 min-w-0"> <!-- flex-1 + min-w-0 предотвращает "расползание" -->
|
||||||
|
<label class="block mb-1 text-sm">Clients</label>
|
||||||
|
<select id="clients-multiselect1" class="select2 w-full" multiple="multiple" data-placeholder="Select Clients" name="client">
|
||||||
|
{% set seen_ids = [] %}
|
||||||
|
{% for job in jobs %}
|
||||||
|
{% if job.client.id not in seen_ids %}
|
||||||
|
|
||||||
|
<option value="{{ job.client.id }}" {% if job.client.id|string in client_id %}selected{% endif %}>
|
||||||
|
{{ job.client.user_nicename }}
|
||||||
|
</option>
|
||||||
|
{% set _ = seen_ids.append(job.client.id) %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Assignee (50% ширины) -->
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<label class="block mb-1 text-sm">Assignee</label>
|
||||||
|
<select id="assignee-multiselect" class="select2 w-full" multiple="multiple" data-placeholder="Select Assignee" name="assignee">
|
||||||
|
{% for user in users %}
|
||||||
|
<option value="{{ user.id }}" {% if user.id|string in assigned_users_ids %}selected{% endif %}>{{ user.username }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Status и кнопка Apply Filters -->
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<label>Status</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<select data-placeholder="Select Status" class="select2 w-full" multiple name="status">
|
||||||
|
{% for option in ["Scheduled", "Requested", "In-Progress", "Paused", "Applied", "Issues Applying", "Cancelled"] %}
|
||||||
|
<option value="{{ option }}" {% if option in status %}selected{% endif %}>{{ option }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="button bg-theme-1 text-white mt-5">Apply Filters</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Функция для настройки обработчиков событий для каждого селекта
|
||||||
|
function setupDateSelect(selectId, wrapperId, customValue) {
|
||||||
|
const select = document.getElementById(selectId);
|
||||||
|
const dateRangeWrapper = document.getElementById(wrapperId);
|
||||||
|
|
||||||
|
select.addEventListener('change', function() {
|
||||||
|
if (this.value === customValue) {
|
||||||
|
dateRangeWrapper.style.display = 'grid';
|
||||||
|
} else {
|
||||||
|
dateRangeWrapper.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Инициализация при загрузке страницы
|
||||||
|
if (select.value === customValue) {
|
||||||
|
dateRangeWrapper.style.display = 'grid';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Настройка всех трех селектов
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
setupDateSelect('date_requested', 'date-requested-range-wrapper', 'custom_date_requested');
|
||||||
|
setupDateSelect('date_posted', 'date-posted-range-wrapper', 'custom_date_posted');
|
||||||
|
setupDateSelect('date_applied', 'date-applied-range-wrapper', 'custom_date_applied');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- BEGIN: Datatable -->
|
<!-- BEGIN: Datatable -->
|
||||||
<div class="intro-y datatable-wrapper box p-5 mt-5">
|
<div class="intro-y datatable-wrapper box p-5 mt-5">
|
||||||
<table class="table table-report table-report--bordered display datatable w-full">
|
<table class="table table-report table-report--bordered display datatable w-full">
|
||||||
|
@ -54,6 +229,7 @@
|
||||||
<option value="Scheduled" {% if job.status == "Scheduled" %}selected{% endif %}>Scheduled</option>
|
<option value="Scheduled" {% if job.status == "Scheduled" %}selected{% endif %}>Scheduled</option>
|
||||||
<option value="Requested" {% if job.status == "Requested" %}selected{% endif %}>Requested</option>
|
<option value="Requested" {% if job.status == "Requested" %}selected{% endif %}>Requested</option>
|
||||||
<option value="In-Progress" {% if job.status == "In-Progress" %}selected{% endif %}>In-Progress</option>
|
<option value="In-Progress" {% if job.status == "In-Progress" %}selected{% endif %}>In-Progress</option>
|
||||||
|
<option value="Paused" {% if job.status == "Paused" %}selected{% endif %}>Paused</option>
|
||||||
<option value="Applied" {% if job.status == "Applied" %}selected{% endif %}>Applied</option>
|
<option value="Applied" {% if job.status == "Applied" %}selected{% endif %}>Applied</option>
|
||||||
<option value="Issues Applying" {% if job.status == "Issues Applying" %}selected{% endif %}>Issues Applying</option>
|
<option value="Issues Applying" {% if job.status == "Issues Applying" %}selected{% endif %}>Issues Applying</option>
|
||||||
<option value="Cancelled" {% if job.status == "Cancelled" %}selected{% endif %}>Cancelled</option>
|
<option value="Cancelled" {% if job.status == "Cancelled" %}selected{% endif %}>Cancelled</option>
|
||||||
|
|
|
@ -26,23 +26,6 @@
|
||||||
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="intro-y flex flex-col sm:flex-row items-center mt-8">
|
|
||||||
<h2 class="text-lg font-medium mr-auto">
|
|
||||||
Tasks
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productuj'">Unasigned Jobs</button>
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productmj'">My Jobs</button>
|
|
||||||
|
|
||||||
<button class="button text-white bg-red-500 hover:bg-red-700 shadow-md mr-2" onclick="window.location.href='/product'">All Jobs</button>
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productoj'">Outstanding Jobs</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="p-5" id="boxed-accordion">
|
<div class="p-5" id="boxed-accordion">
|
||||||
<div class="preview">
|
<div class="preview">
|
||||||
|
|
|
@ -26,21 +26,6 @@
|
||||||
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="intro-y flex flex-col sm:flex-row items-center mt-8">
|
|
||||||
<h2 class="text-lg font-medium mr-auto">
|
|
||||||
Tasks
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productuj'">Unasigned Jobs</button>
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productmj'">My Jobs</button>
|
|
||||||
|
|
||||||
<button class="button text-white bg-red-500 hover:bg-red-700 shadow-md mr-2" onclick="window.location.href='/product'">All Jobs</button>
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productoj'">Outstanding Jobs</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,202 +4,104 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<style>
|
|
||||||
.select2-container {
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style>
|
|
||||||
.filter-link {
|
|
||||||
font-size: 18px; /* Увеличиваем размер шрифта */
|
|
||||||
font-weight: bold; /* Делаем текст жирным */
|
|
||||||
padding: 10px 20px; /* Добавляем отступы для лучшего кликабельности */
|
|
||||||
background-color: #7a61fe; /* Добавляем зелёный фон */
|
|
||||||
color: white; /* Текст белый */
|
|
||||||
border-radius: 5px; /* Слегка скругляем углы */
|
|
||||||
text-align: center; /* Выравнивание по центру */
|
|
||||||
cursor: pointer; /* Курсор в виде указателя при наведении */
|
|
||||||
transition: background-color 0.3s ease, transform 0.2s ease; /* Плавные анимации */
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-link:hover {
|
|
||||||
background-color: #7a61fe; /* Темнее при наведении */
|
|
||||||
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div class="intro-y flex flex-col sm:flex-row items-center mt-8">
|
<div class="intro-y flex flex-col sm:flex-row items-center mt-8">
|
||||||
<h2 class="text-lg font-medium mr-auto">
|
<h2 class="text-lg font-medium mr-auto">
|
||||||
Tasks
|
Tasks
|
||||||
</h2>
|
</h2>
|
||||||
|
<!-- BEGIN: Inbox Filter
|
||||||
|
<div class="intro-y flex flex-col-reverse sm:flex-row items-center">
|
||||||
|
<div class="w-full sm:w-auto relative mr-auto mt-3 sm:mt-0">
|
||||||
|
<i class="w-4 h-4 absolute my-auto inset-y-0 ml-3 left-0 z-10 text-gray-700" data-feather="search"></i>
|
||||||
|
<input type="text" class="input w-full sm:w-64 box px-10 text-gray-700 placeholder-theme-13" placeholder="Filter">
|
||||||
|
<div class="inbox-filter dropdown absolute inset-y-0 mr-3 right-0 flex items-center">
|
||||||
|
<i class="dropdown-toggle w-4 h-4 cursor-pointer text-gray-700" data-feather="chevron-down"></i>
|
||||||
|
<div class="inbox-filter__dropdown-box dropdown-box mt-10 absolute top-0 left-0 z-20">
|
||||||
|
<div class="dropdown-box__content box p-5">
|
||||||
|
<div class="grid grid-cols-12 gap-4 row-gap-3">
|
||||||
|
<div class="col-span-6">
|
||||||
|
<div class="text-xs">Requested o</div>
|
||||||
|
<select class="input w-full border mt-2 flex-1">
|
||||||
|
<option value="" selected disabled>Выберите</option>
|
||||||
|
<option>Сегодня</option>
|
||||||
|
<option>Последние 7 дней</option>
|
||||||
|
<option>За все время</option>
|
||||||
|
<option>От даты - до даты.</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<div class="text-xs">Posted on</div>
|
||||||
|
<select class="input w-full border mt-2 flex-1">
|
||||||
|
<option value="" selected disabled>Выберите</option>
|
||||||
|
<option>Сегодня</option>
|
||||||
|
<option>Последние 7 дней</option>
|
||||||
|
<option>За все время</option>
|
||||||
|
<option>От даты - до даты.</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<div class="text-xs">Applied on</div>
|
||||||
|
<select class="input w-full border mt-2 flex-1">
|
||||||
|
<option value="" selected disabled>Выберите</option>
|
||||||
|
<option>Сегодня</option>
|
||||||
|
<option>Последние 7 дней</option>
|
||||||
|
<option>За все время</option>
|
||||||
|
<option>От даты - до даты.</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<div class="text-xs">Client</div>
|
||||||
|
<select class="input w-full border mt-2 flex-1">
|
||||||
|
<option value="" selected disabled>Выберите</option>
|
||||||
|
<option>-</option>
|
||||||
|
<option>-</option>
|
||||||
|
<option>-</option>
|
||||||
|
<option>-</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<div class="text-xs">Assignee</div>
|
||||||
|
<select class="select2 w-full" multiple>
|
||||||
|
<option value="" selected disabled>Выберите</option>
|
||||||
|
<option>-</option>
|
||||||
|
<option>-</option>
|
||||||
|
<option>-</option>
|
||||||
|
<option>-</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<div class="text-xs">Status</div>
|
||||||
|
<select class="select2 w-full" multiple>
|
||||||
|
|
||||||
|
<option>Scheduled</option>
|
||||||
|
<option>Requested</option>
|
||||||
|
<option>Applying</option>
|
||||||
|
<option>Applied</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-12 flex items-center mt-3">
|
||||||
|
|
||||||
|
<button class="button w-32 justify-center block bg-theme-1 text-white ml-2">Search</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-full sm:w-auto flex">
|
||||||
|
|
||||||
|
<div class="dropdown relative">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
END: Inbox Filter -->
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productuj'">Unasigned Jobs</button>
|
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productuj'">Unasigned Jobs</button>
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productmj'">My Jobs</button>
|
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productmj'">My Jobs</button>
|
||||||
|
|
||||||
<button class="button text-white bg-red-500 hover:bg-red-700 shadow-md mr-2" onclick="window.location.href='/product'">All Jobs</button>
|
<button class="button text-white bg-red-500 hover:bg-red-700 shadow-md mr-2" onclick="window.location.href='/product'">All Jobs</button>
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productoj'">Outstanding Jobs</button>
|
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productoj'">Outstanding Jobs</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="p-5" id="boxed-accordion">
|
|
||||||
<div class="preview">
|
|
||||||
<div class="accordion">
|
|
||||||
<div class="accordion__pane border border-gray-200 p-4 mt-3">
|
|
||||||
<a href="javascript:;" class="accordion__pane__toggle filter-link font-medium block">Filter</a>
|
|
||||||
|
|
||||||
<div class="accordion__pane__content mt-3 text-gray-800 leading-relaxed">
|
|
||||||
<div class="dropdown-box__content box p-5">
|
|
||||||
<form method="POST" action="/productf">
|
|
||||||
<!-- Дата-фильтры (Requested, Posted, Applied) -->
|
|
||||||
<div class="flex gap-4">
|
|
||||||
<!-- Requested on -->
|
|
||||||
<div class="w-1/2">
|
|
||||||
<div class="text-xs">Requested on</div>
|
|
||||||
<select id="date_requested" class="input w-full border mt-2 flex-1" name="date_requested">
|
|
||||||
<option value=""></option>
|
|
||||||
<option value="Today">Today</option>
|
|
||||||
<option value="Last 7 days">Last 7 days</option>
|
|
||||||
<option value="For all time">For all time</option>
|
|
||||||
<option value="custom_date_requested">from date to date</option>
|
|
||||||
</select>
|
|
||||||
<div id="date-requested-range-wrapper" class="p-5 grid grid-cols-12 gap-4 row-gap-3 mt-4" style="display: none;">
|
|
||||||
<div class="col-span-12 sm:col-span-6">
|
|
||||||
<label>From</label>
|
|
||||||
<input type="date" id="date-requested-from" class="input w-full border mt-2" name="date_requested_from">
|
|
||||||
</div>
|
|
||||||
<div class="col-span-12 sm:col-span-6">
|
|
||||||
<label>To</label>
|
|
||||||
<input type="date" id="date-requested-to" class="input w-full border mt-2" name="date_requested_to">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Posted on -->
|
|
||||||
<div class="w-1/2">
|
|
||||||
<div class="text-xs">Posted on</div>
|
|
||||||
<select id="date_posted" class="input w-full border mt-2 flex-1" name="date_posted">
|
|
||||||
<option value=""></option>
|
|
||||||
<option value="Today">Today</option>
|
|
||||||
<option value="Last 7 days">Last 7 days</option>
|
|
||||||
<option value="For all time">For all time</option>
|
|
||||||
<option value="custom_date_posted">from date to date</option>
|
|
||||||
</select>
|
|
||||||
<div id="date-posted-range-wrapper" class="p-5 grid grid-cols-12 gap-4 row-gap-3 mt-4" style="display: none;">
|
|
||||||
<div class="col-span-12 sm:col-span-6">
|
|
||||||
<label>From</label>
|
|
||||||
<input type="date" id="date-posted-from" class="input w-full border mt-2" name="date_posted_from">
|
|
||||||
</div>
|
|
||||||
<div class="col-span-12 sm:col-span-6">
|
|
||||||
<label>To</label>
|
|
||||||
<input type="date" id="date-posted-to" class="input w-full border mt-2" name="date_posted_to">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Applied on -->
|
|
||||||
<div class="col-span-6 mt-4">
|
|
||||||
<div class="text-xs">Applied on</div>
|
|
||||||
<select id="date_applied" class="input w-full border mt-2 flex-1" name="date_applied">
|
|
||||||
<option value=""></option>
|
|
||||||
<option value="Today">Today</option>
|
|
||||||
<option value="Last 7 days">Last 7 days</option>
|
|
||||||
<option value="For all time">For all time</option>
|
|
||||||
<option value="custom_date_applied">from date to date</option>
|
|
||||||
</select>
|
|
||||||
<div id="date-applied-range-wrapper" class="p-5 grid grid-cols-12 gap-4 row-gap-3 mt-4" style="display: none;">
|
|
||||||
<div class="col-span-12 sm:col-span-6">
|
|
||||||
<label>From</label>
|
|
||||||
<input type="date" id="date-applied-from" class="input w-full border mt-2" name="date_applied_from">
|
|
||||||
</div>
|
|
||||||
<div class="col-span-12 sm:col-span-6">
|
|
||||||
<label>To</label>
|
|
||||||
<input type="date" id="date-applied-to" class="input w-full border mt-2" name="date_applied_to">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex flex-nowrap gap-4 mt-4"> <!-- flex-nowrap запрещает перенос на новую строку -->
|
|
||||||
<!-- Clients (50% ширины) -->
|
|
||||||
<div class="flex-1 min-w-0"> <!-- flex-1 + min-w-0 предотвращает "расползание" -->
|
|
||||||
<label class="block mb-1 text-sm">Clients</label>
|
|
||||||
<select id="clients-multiselect1" class="select2 w-full" multiple="multiple" data-placeholder="Select Clients" name="client">
|
|
||||||
{% set seen_ids = [] %}
|
|
||||||
{% for job in jobs %}
|
|
||||||
{% if job.client.id not in seen_ids %}
|
|
||||||
<option value="{{ job.client.id }}">{{ job.client.user_nicename }}</option>
|
|
||||||
{% set _ = seen_ids.append(job.client.id) %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Assignee (50% ширины) -->
|
|
||||||
<div class="flex-1 min-w-0"> <!-- flex-1 дает равную ширину -->
|
|
||||||
<label class="block mb-1 text-sm">Assignee</label>
|
|
||||||
<select id="assignee-multiselect" class="select2 w-full" multiple="multiple" data-placeholder="Select Assignee" name="assignee">
|
|
||||||
<option value="">— Not selected —</option>
|
|
||||||
{% for user in users %}
|
|
||||||
<option value="{{ user.id }}" {% if user.id in assigned_users_ids %}selected{% endif %}>{{ user.username }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Status и кнопка Apply Filters -->
|
|
||||||
<div class="col-span-6 mt-4">
|
|
||||||
<label>Status</label>
|
|
||||||
<div class="mt-2">
|
|
||||||
<select data-placeholder="Select Status" class="select2 w-full" multiple name="status">
|
|
||||||
<option value="Scheduled">Scheduled</option>
|
|
||||||
<option value="Requested">Requested</option>
|
|
||||||
<option value="In-Progress">In-Progress</option>
|
|
||||||
<option value="Applied">Applied</option>
|
|
||||||
<option value="Issues Applying">Issues Applying</option>
|
|
||||||
<option value="Cancelled">Cancelled</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="button bg-theme-1 text-white mt-5">Apply Filters</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Функция для настройки обработчиков событий для каждого селекта
|
|
||||||
function setupDateSelect(selectId, wrapperId, customValue) {
|
|
||||||
const select = document.getElementById(selectId);
|
|
||||||
const dateRangeWrapper = document.getElementById(wrapperId);
|
|
||||||
|
|
||||||
select.addEventListener('change', function() {
|
|
||||||
if (this.value === customValue) {
|
|
||||||
dateRangeWrapper.style.display = 'grid';
|
|
||||||
} else {
|
|
||||||
dateRangeWrapper.style.display = 'none';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Инициализация при загрузке страницы
|
|
||||||
if (select.value === customValue) {
|
|
||||||
dateRangeWrapper.style.display = 'grid';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Настройка всех трех селектов
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
setupDateSelect('date_requested', 'date-requested-range-wrapper', 'custom_date_requested');
|
|
||||||
setupDateSelect('date_posted', 'date-posted-range-wrapper', 'custom_date_posted');
|
|
||||||
setupDateSelect('date_applied', 'date-applied-range-wrapper', 'custom_date_applied');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<!-- BEGIN: Datatable -->
|
<!-- BEGIN: Datatable -->
|
||||||
<div class="intro-y datatable-wrapper box p-5 mt-5">
|
<div class="intro-y datatable-wrapper box p-5 mt-5">
|
||||||
<table class="table table-report table-report--bordered display datatable w-full">
|
<table class="table table-report table-report--bordered display datatable w-full">
|
||||||
|
|
|
@ -27,22 +27,6 @@
|
||||||
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
transform: scale(1.002); /* Немного увеличиваем размер при наведении */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="intro-y flex flex-col sm:flex-row items-center mt-8">
|
|
||||||
<h2 class="text-lg font-medium mr-auto">
|
|
||||||
Tasks
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productuj'">Unasigned Jobs</button>
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productmj'">My Jobs</button>
|
|
||||||
|
|
||||||
<button class="button text-white bg-red-500 hover:bg-red-700 shadow-md mr-2" onclick="window.location.href='/product'">All Jobs</button>
|
|
||||||
<button class="button text-white bg-theme-1 shadow-md mr-2" onclick="window.location.href='/productoj'">Outstanding Jobs</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="p-5" id="boxed-accordion">
|
<div class="p-5" id="boxed-accordion">
|
||||||
|
|
Loading…
Reference in New Issue