fix
This commit is contained in:
parent
abacc5e152
commit
fe8a036f06
@ -4601,13 +4601,14 @@
|
|||||||
"\n",
|
"\n",
|
||||||
" data = [doc async for doc in cursor]\n",
|
" data = [doc async for doc in cursor]\n",
|
||||||
" exhibitions = await exhibition_collection.find({'_id': {'$in': [ObjectId(i.get('exhibition_id')) for i in data if i.get('exhibition_id')]}}).to_list()\n",
|
" exhibitions = await exhibition_collection.find({'_id': {'$in': [ObjectId(i.get('exhibition_id')) for i in data if i.get('exhibition_id')]}}).to_list()\n",
|
||||||
"\n",
|
" competitions = await competitions_col.find({'_id': {'$in': [i.get('competitions') for i in data if i.get('competitions')]}}).to_list()\n",
|
||||||
" return templates.TemplateResponse(\n",
|
" return templates.TemplateResponse(\n",
|
||||||
" request=request,\n",
|
" request=request,\n",
|
||||||
" name=\"profile/delivery.html\",\n",
|
" name=\"profile/delivery.html\",\n",
|
||||||
" context={\n",
|
" context={\n",
|
||||||
" \"user\": user,\n",
|
" \"user\": user,\n",
|
||||||
" \"exhibitions\": exhibitions,\n",
|
" \"exhibitions\": exhibitions,\n",
|
||||||
|
" \"competitions\": competitions,\n",
|
||||||
" \"data\": data,\n",
|
" \"data\": data,\n",
|
||||||
" \"page_title\": \"Доставка\",\n",
|
" \"page_title\": \"Доставка\",\n",
|
||||||
" \"active_section\": \"delivery\"\n",
|
" \"active_section\": \"delivery\"\n",
|
||||||
|
|||||||
3
main.py
3
main.py
@ -3505,13 +3505,14 @@ async def profile_delivery(
|
|||||||
|
|
||||||
data = [doc async for doc in cursor]
|
data = [doc async for doc in cursor]
|
||||||
exhibitions = await exhibition_collection.find({'_id': {'$in': [ObjectId(i.get('exhibition_id')) for i in data if i.get('exhibition_id')]}}).to_list()
|
exhibitions = await exhibition_collection.find({'_id': {'$in': [ObjectId(i.get('exhibition_id')) for i in data if i.get('exhibition_id')]}}).to_list()
|
||||||
|
competitions = await competitions_col.find({'_id': {'$in': [i.get('competitions') for i in data if i.get('competitions')]}}).to_list()
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
request=request,
|
request=request,
|
||||||
name="profile/delivery.html",
|
name="profile/delivery.html",
|
||||||
context={
|
context={
|
||||||
"user": user,
|
"user": user,
|
||||||
"exhibitions": exhibitions,
|
"exhibitions": exhibitions,
|
||||||
|
"competitions": competitions,
|
||||||
"data": data,
|
"data": data,
|
||||||
"page_title": "Доставка",
|
"page_title": "Доставка",
|
||||||
"active_section": "delivery"
|
"active_section": "delivery"
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
{% import "components/profile_card.html" as profile_card %}
|
{% import "components/profile_card.html" as profile_card %}
|
||||||
{% import "components/profile_nav.html" as profile_nav %}
|
{% import "components/profile_nav.html" as profile_nav %}
|
||||||
{% import "competition/list.html" as competition %}
|
{% import "competition/list.html" as competition %}
|
||||||
|
{% import "competition/card.html" as card %}
|
||||||
|
|
||||||
{% block title %}Где картины{% endblock %}
|
{% block title %}Где картины{% endblock %}
|
||||||
|
|
||||||
@ -100,223 +101,48 @@
|
|||||||
<div class="c_ru432">
|
<div class="c_ru432">
|
||||||
{{ profile_nav.profile_nav(user, 'delivery') }}
|
{{ profile_nav.profile_nav(user, 'delivery') }}
|
||||||
<div class="c_tihtk" id="main">
|
<div class="c_tihtk" id="main">
|
||||||
{% set statuses = ['Ожидает отправки', 'Возврат художнику'] %}
|
{% for competition in competitions %}
|
||||||
|
{{card.section(competition, False, "/competition/{}".format(competition._id))}}
|
||||||
<article class="c_9fgdh b_ax8vz">
|
|
||||||
<div class="c_z3dpx b_73p10">
|
|
||||||
<header class="c_m876y b_9xtz9">
|
|
||||||
<h3 class="b_8f3uh">Фильтры</h3>
|
|
||||||
</header>
|
|
||||||
<div class="c_aihm6 floating-group">
|
|
||||||
<select class="c_xhd5k" id="exhibition_id" name="exhibition_id" required
|
|
||||||
onchange="filterFigure(this.value)">
|
|
||||||
<option value="">Выбрать выставку</option>
|
|
||||||
{% for doc in exhibitions %}
|
|
||||||
<option value="{{doc._id}}">{{doc.title}}</option>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
{% for i in exhibitions %}
|
||||||
<label for="exhibition_id" class="c_z3ybu floating-label">Выставка</label>
|
<article class="c_9fgdh b_ax8vz">
|
||||||
|
<a href="/profile/partner/exhibition/{{i._id}}{% if i.status == 0 %}/catalog{%endif%}#main">
|
||||||
|
<div class="b_ornr9">
|
||||||
|
<picture>
|
||||||
|
<img src="/b/exhibition/{{i.poster_file_id}}" data-src="/b/exhibition/{{i.poster_orig_id}}" id="preview_poster" crossorigin="anonymous" fetchpriority="high" loading="eager" alt="Загрузите афишу" class="b_ornr9">
|
||||||
|
</picture>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="c_z3dpx b_73p10">
|
||||||
|
<a class="b_73p10" href="/profile/partner/exhibition/{{i._id}}{% if i.status == 0 %}/catalog{%endif%}#main">
|
||||||
|
<div class="c_c4wam b_vabj9">
|
||||||
|
{% if now > i.date_finish %}
|
||||||
|
<span class="c_95csi b_0jst1">Закончилась</span>
|
||||||
|
{% elif now > i.datetime_start %}
|
||||||
|
<span class="c_95csi b_0jst1">Началась</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="c_95csi b_0jst1">Формируется</span>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if data | selectattr('status', 'in', statuses) | list | length > 0 %}
|
|
||||||
<header class="c_m876y b_9xtz9">
|
<header class="c_m876y b_9xtz9">
|
||||||
<h3 class="b_8f3uh">Настройки отправки</h3>
|
<h3 class="c_hysjg b_8f3uh" id="preview_title">{{i.title}}</h3>
|
||||||
</header>
|
</header>
|
||||||
<p class="b_tfnz2">Можно менять перед каждой отправкой картины</p>
|
<p class="c_2fr39 b_tfnz2" id="preview_topic">{{i.topic}}</p>
|
||||||
<div class="b_73p10">
|
<div class="c_dbbe4 b_otttb">
|
||||||
<div class="c_aihm6 floating-group">
|
{% if user %}
|
||||||
<select class="c_xhd5k" type="text" id="delivery_type" name="delivery_type" required>
|
<img crossorigin="anonymous" fetchpriority="high" loading="eager" class="c_pm80w b_a68fq" src="/a/{{i.user._id}}" alt="{{ i.user.username | e }}">
|
||||||
<option>СДЭК</option>
|
<div class="c_4402p b_ntazj">
|
||||||
<option>Самостоятельно</option>
|
<p class="c_kvah4 b_ghosy">{{ i.user.username }}</p>
|
||||||
</select>
|
|
||||||
<label for="delivery_type" class="c_z3ybu floating-label">Способ доставки</label>
|
|
||||||
</div>
|
|
||||||
<div class="c_aihm6 floating-group">
|
|
||||||
<input placeholder="..." type="text" id="track" name="track" class="c_xhd5k" required
|
|
||||||
data-toast="Поле Трэк-номер должно быть заполнено">
|
|
||||||
<label for="track" class="c_z3ybu floating-label">Трэк-номер</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
<p class="c_2fr39 b_tfnz2">Подробнее</p>
|
||||||
|
</a>
|
||||||
|
<div class="b_otttb"><a class="c_2fr39 b_tfnz2" href="/form/exhibition/{{i._id}}">Редактировать</a><span onclick="deleteExhibition(this, '{{i._id}}')" class="c_2fr39 b_tfnz2">Удалить</span></div>
|
||||||
|
<p class="c_drpqj b_mp1wb">{{ ( i._id.generation_time.strftime('%d.%m.%Y')) if i._id else ''}}</p>
|
||||||
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
|
||||||
{% for doc in data if doc.status in statuses %}
|
|
||||||
{{ render_doc(doc) }}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for doc in data if doc.status not in statuses %}
|
|
||||||
{{ render_doc(doc) }}
|
|
||||||
{% endfor %}
|
|
||||||
<script defer>
|
|
||||||
const query = window.location.href.split('?')[1] || '';
|
|
||||||
let exhibition_id = null;
|
|
||||||
if (query) {
|
|
||||||
const parts = query.split('=');
|
|
||||||
if (parts[0] === 'exhibition_id' && parts[1] !== 'None') {
|
|
||||||
exhibition_id = parts[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function filterFigure(exhibition_id) {
|
|
||||||
document.getElementById('main').querySelectorAll('figure').forEach(figure => {
|
|
||||||
|
|
||||||
if (!exhibition_id || figure.dataset.exhibition_id === exhibition_id) {
|
|
||||||
figure.style.display = 'flex';
|
|
||||||
console.log(figure.dataset.exhibition_id, exhibition_id, 'flex')
|
|
||||||
} else {
|
|
||||||
console.log(figure.dataset.exhibition_id, exhibition_id)
|
|
||||||
figure.style.display = 'none';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exhibition_id) {
|
|
||||||
document.getElementById('exhibition_id').value = exhibition_id;
|
|
||||||
}
|
|
||||||
filterFigure(exhibition_id);
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
const deliveryType = document.getElementById('delivery_type');
|
|
||||||
const track = document.getElementById('track');
|
|
||||||
|
|
||||||
function toggleTrack() {
|
|
||||||
const isSelf = deliveryType.value === 'Самостоятельно';
|
|
||||||
if (isSelf) {
|
|
||||||
track.required = false;
|
|
||||||
track.value = '';
|
|
||||||
} else {
|
|
||||||
track.required = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deliveryType.addEventListener('change', toggleTrack);
|
|
||||||
toggleTrack();
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
async function btnAccept(btn, itemId){
|
|
||||||
const figcaption = btn.parentElement;
|
|
||||||
const statusDiv = figcaption.querySelectorAll('div')[0];
|
|
||||||
const statusSpan = statusDiv.querySelector('span')
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await fetch('/api/delivery/accept', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
item: itemId,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
let errorMessage = 'Ошибка сохранения';
|
|
||||||
try {
|
|
||||||
const errorData = await res.json();
|
|
||||||
errorMessage = errorData.detail || errorMessage;
|
|
||||||
} catch (e) {
|
|
||||||
try {
|
|
||||||
const errorText = await res.text();
|
|
||||||
errorMessage = errorText || errorMessage;
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
showToast({ message: errorMessage, duration: 2500 });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
statusDiv.className = 'b_thlt1';
|
|
||||||
statusSpan.className = 'b_5dr47';
|
|
||||||
statusSpan.textContent = 'Получено';
|
|
||||||
btn.style.display = 'none'
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Network error:', error);
|
|
||||||
showToast({ message: 'Не удалось подключиться к серверу', duration: 2500 });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
async function btnSend(btn, itemId, sender, too){
|
|
||||||
const figcaption = btn.parentElement;
|
|
||||||
const statusDiv = figcaption.querySelectorAll('div')[0];
|
|
||||||
const statusSpan = statusDiv.querySelector('span')
|
|
||||||
|
|
||||||
|
|
||||||
const delivery_type = document.getElementById('delivery_type').value;
|
|
||||||
const trackValue = document.getElementById('track');
|
|
||||||
|
|
||||||
let track = ''
|
|
||||||
if (delivery_type === 'СДЭК' && trackValue) {
|
|
||||||
track = trackValue.value
|
|
||||||
}
|
|
||||||
const requiredInputs = document.querySelectorAll('input[required]');
|
|
||||||
const requiredTextareas = document.querySelectorAll('textarea[required]');
|
|
||||||
const requiredFields = [...requiredInputs, ...requiredTextareas];
|
|
||||||
|
|
||||||
let firstErrorField = null;
|
|
||||||
let hasError = false;
|
|
||||||
|
|
||||||
requiredFields.forEach(field => {
|
|
||||||
const group = field.closest('.floating-group');
|
|
||||||
if (!group) return; // skip if no group wrapper
|
|
||||||
|
|
||||||
let isEmpty = false;
|
|
||||||
if (field.type === 'file') {
|
|
||||||
isEmpty = !field.files || field.files.length === 0;
|
|
||||||
} else {
|
|
||||||
isEmpty = !field.value || !field.value.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEmpty) {
|
|
||||||
group.classList.add('error');
|
|
||||||
hasError = true;
|
|
||||||
showToast({message: field.dataset.toast, duration:2500});
|
|
||||||
if (!firstErrorField) firstErrorField = field;
|
|
||||||
} else {
|
|
||||||
group.classList.remove('error');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hasError && firstErrorField) {
|
|
||||||
firstErrorField.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
||||||
setTimeout(() => firstErrorField.focus(), 600);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await fetch('/api/delivery/send', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
sender,
|
|
||||||
too,
|
|
||||||
item: itemId,
|
|
||||||
delivery_type,
|
|
||||||
track: track
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
let errorMessage = 'Ошибка сохранения';
|
|
||||||
try {
|
|
||||||
const errorData = await res.json();
|
|
||||||
errorMessage = errorData.detail || errorMessage;
|
|
||||||
} catch (e) {
|
|
||||||
// If response isn't JSON, try to get text
|
|
||||||
try {
|
|
||||||
const errorText = await res.text();
|
|
||||||
errorMessage = errorText || errorMessage;
|
|
||||||
} catch (e) {
|
|
||||||
// Fallback to generic error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
showToast({ message: errorMessage, duration: 2500 });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
statusDiv.className = 'b_thlt1_2';
|
|
||||||
statusSpan.className = 'b_5dr47_2';
|
|
||||||
statusSpan.textContent = 'Ожидает получения';
|
|
||||||
btn.style.display = 'none'
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Network error:', error);
|
|
||||||
showToast({ message: 'Не удалось подключиться к серверу', duration: 2500 });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -329,6 +155,7 @@ async function btnSend(btn, itemId, sender, too){
|
|||||||
{{ header.style() }}
|
{{ header.style() }}
|
||||||
{{ competition.style() }}
|
{{ competition.style() }}
|
||||||
{{ profile_nav.style() }}
|
{{ profile_nav.style() }}
|
||||||
|
{{card.style()}}
|
||||||
<style>/* Base (common) styles */
|
<style>/* Base (common) styles */
|
||||||
.c_aihm6{width: 100%;}
|
.c_aihm6{width: 100%;}
|
||||||
.mw{margin: 0 20px;
|
.mw{margin: 0 20px;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user