avtopost.kultmost.ru/templates/profile/invitation.html
2026-07-22 03:07:21 -04:00

414 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% import "/components/header.html" as header %}
{% import "/components/footer.html" as footer %}
{% import "components/profile_card.html" as profile_card %}
{% import "components/profile_nav.html" as profile_nav %}
{% block title %}Приглашения{% endblock %}
{% macro render_post(doc) %}
<figure class="c_4b1hy b_uu2ub">
<img class="b_1fvkt" src="/b/posts/{{doc.medias[0]}}">
<figcaption class="c_3g8gh b_pvw5a">
<div class="b_thlt1_2">
<span class="b_5dr47_2">Выберите картину</span>
</div>
<div class="b_thlt1" style="display:none;">
<span class="b_5dr47">Картина выбрана</span>
</div>
<h2 class="c_9hvtd b_f5fb2">{{doc.title}}</h2>
<label class="offer-label">
<input
type="checkbox"
class="offer-checkbox"
data-post-id="{{ doc._id }}"
onchange="selectPost(this)"
>
<span class="offer-text">Выбрать</span>
</label>
<p class="b_6spaf">...</p>
</figcaption>
</figure>
{% endmacro %}
{% block content %}
{{ header.section(user) }}
<section class="c_dg3k4">
<div class="c_gtoe9">
{{ profile_card.profile_card(user) }}
<div class="c_ru432">
{{ profile_nav.profile_nav(user, 'invitation') }}
<div class="c_tihtk" id="main">
<article class="c_9fgdh b_ax8vz" id="l{{doc._id}}">
<div class="c_z3dpx b_73p10">
<div class="b_vabj9_2">
<span class="b_0jst1_2">{{doc.type}}</span>
</div>
<header class="c_m876y b_9xtz9">
<h3 class="c_hysjg b_8f3uh">{{ doc.title }}</h3>
</header>
<p class="c_2fr39 b_tfnz2">{{doc.get('exhibition').title }}</p>
<p>Место проведения: {{ doc.get('exhibition').get('place') }}</p>
<div class="b_otttb">
<span class="c_2fr39 b_tfnz2">С {{ ( doc.get('exhibition').datetime_start.strftime('%d.%m.%Y')) if
doc.get('exhibition').datetime_start
else ''}}</span>
<span class="c_2fr39 b_tfnz2">По {{ ( doc.get('exhibition').date_finish.strftime('%d.%m.%Y')) if
doc.get('exhibition').date_finish else
''}}</span>
</div>
{{render_links(doc)}}
<p>Выбрано: <span id="lenSelected">0</span></p>
<button
onclick="accept_inv('{{doc._id}}')"
class="btn"
style="width: 100%; box-sizing: border-box;"
>
Принять условия
</button>
{% set user_contact = doc.get('user') %}
{{render_user_contacts(user_contact)}}
<p class="c_drpqj b_mp1wb">{{ (doc._id.generation_time.strftime('%d.%m.%Y')) if doc._id else ''}}</p>
</div>
</article>
{% for post in doc.get('posts')%}
{{render_post(post)}}
{% endfor %}
</div>
</div>
</div>
</section>
<script>
const LS_KEY = 'selected_posts_ids_{{doc._id}}';
function safeParseArray(raw) {
try {
const v = JSON.parse(raw);
if (!Array.isArray(v)) return [];
return v.map(String);
} catch {
return [];
}
}
function loadSelectedIds() {
const raw = localStorage.getItem(LS_KEY);
if (!raw) return [];
return safeParseArray(raw);
}
function saveSelectedIds(ids) {
localStorage.setItem(LS_KEY, JSON.stringify(ids.map(String)));
}
function updateSelectedCount() {
const el = document.getElementById('lenSelected');
if (!el) return;
el.textContent = String(loadSelectedIds().length);
}
function setStateUI(checkbox) {
const figure = checkbox && checkbox.closest ? checkbox.closest('figure') : null;
if (!figure) return;
const chooseBlock = figure.querySelector('.b_thlt1_2');
const selectedBlock = figure.querySelector('.b_thlt1');
const checked = !!checkbox.checked;
if (chooseBlock) chooseBlock.style.display = checked ? 'none' : '';
if (selectedBlock) selectedBlock.style.display = checked ? '' : 'none';
}
function setAllCheckboxesFromStorage() {
const selectedSet = new Set(loadSelectedIds());
const boxes = document.querySelectorAll('.offer-checkbox');
boxes.forEach(cb => {
const postId = String(cb.dataset.postId || '');
const isSelected = postId && selectedSet.has(postId);
cb.checked = isSelected;
setStateUI(cb);
});
updateSelectedCount();
}
function selectPost(checkbox) {
if (!checkbox || !checkbox.dataset) return;
const postId = String(checkbox.dataset.postId || '');
if (!postId) return;
// делаем из текущего состояния множества (устойчиво к дублям и т.п.)
const ids = loadSelectedIds();
const set = new Set(ids);
if (checkbox.checked) set.add(postId);
else set.delete(postId);
const next = Array.from(set);
saveSelectedIds(next);
setStateUI(checkbox);
updateSelectedCount();
}
async function accept_inv(inv_id) {
const ids = loadSelectedIds();
if (!Array.isArray(ids) || ids.length === 0) {
showToast({ message: 'Выберите хотя бы одну картину', status: 'error' });
return;
}
try {
const res = await fetch(`/api/invitation/accept/${inv_id}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ posts: ids })
});
if (!res.ok) {
showToast({ message: 'Не удалось принять приглашение', status: 'error' });
return;
}
showToast({ message: 'Приглашение принято. Перенаправляем на страницу доставки' });
setTimeout(() => {
localStorage.removeItem(LS_KEY);
window.location.href = '/profile/delivery#main';
}, 5000);
} catch (e) {
showToast({ message: 'Ошибка сети/сервера', status: 'error' });
}
}
// загрузка состояния при открытии страницы
document.addEventListener('DOMContentLoaded', () => {
setAllCheckboxesFromStorage();
});
</script>
{{ footer.section(user) }}
{% endblock %}
{% macro render_user_contacts(user) %}
<div class="c_dbbe4 b_otttb">
{% if user %}
<img class="c_pm80w b_a68fq" src="/a/{{user._id}}" alt="{{ user.username | e }}" crossorigin="anonymous"
fetchpriority="high" loading="eager">
<div class="c_4402p b_ntazj">
<p class="c_kvah4 b_ghosy">{{ user.username | e }}</p>
</div>
{% endif %}
</div>
<div class="menua">
<a class="icona" href="tel:{{user.phone.split(',')[-1].strip()}}"><svg xmlns="http://www.w3.org/2000/svg"
height="24px" viewBox="0 -960 960 960" width="24px" fill="#5F1798">
<path
d="M162-120q-18 0-30-12t-12-30v-162q0-13 9-23.5t23-14.5l138-28q14-2 28.5 2.5T342-374l94 94q38-22 72-48.5t65-57.5q33-32 60.5-66.5T681-524l-97-98q-8-8-11-19t-1-27l26-140q2-13 13-22.5t25-9.5h162q18 0 30 12t12 30q0 125-54.5 247T631-329Q531-229 409-174.5T162-120Zm556-480q17-39 26-79t14-81h-88l-18 94 66 66ZM360-244l-66-66-94 20v88q41-3 81-14t79-28Zm358-356ZM360-244Z" />
</svg>
<span>{{ user.phone.split(',')[-1].strip() }}</span>
</a>
<a class="icona" href="mailto:{{user.email}}"> <svg xmlns="http://www.w3.org/2000/svg" height="24px"
viewBox="0 -960 960 960" width="24px" fill="#5F1798">
<path
d="M480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480v58q0 59-40.5 100.5T740-280q-35 0-66-15t-52-43q-29 29-65.5 43.5T480-280q-83 0-141.5-58.5T280-480q0-83 58.5-141.5T480-680q83 0 141.5 58.5T680-480v58q0 26 17 44t43 18q26 0 43-18t17-44v-58q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93h200v80H480Zm85-315q35-35 35-85t-35-85q-35-35-85-35t-85 35q-35 35-35 85t35 85q35 35 85 35t85-35Z" />
</svg>
<span>{{user.email}}</span>
</a>
<div class="icona"><span>Написать</span></div>
<div class="icona">
<a class="icona" href="{% if user.social_vk %}https://vk.ru/im?sel={{user.social_vk.id}}{%else%}#{%endif%}">
<img src="/static/icons/vk.svg" height="40">
</a>
<a class="icona" href="https://telegram.me/{{user.phone.split(',')[-1].strip()}}">
<img src="/static/icons/tg.svg" height="40">
<!-- <span>Написать в ТГ</span> -->
</a>
<a class="icona" href="https://max.ru/{{user.phone.split(',')[-1].strip()}}">
<img src="/static/icons/max.svg" height="40" style="border-radius: 50% 50% 50% 30%;">
<!-- <span>Написать в MAX</span> -->
</a>
<a class="icona" href="https://wa.me/{{user.phone.split(',')[-1].strip()}}">
<img src="/static/icons/wapp.svg" height="40">
<!-- <span>Написать в WA</span> -->
</a>
</div>
</div>
{% endmacro %}
{% macro render_links(doc) %}
{% if doc.get('exhibition').get('tizer_file_id') or doc.get('exhibition').get('tizer_link') %}
<a class="btn" href="{% if doc.get('exhibition') and doc.get('exhibition').get('tizer_link') %}{{doc.get('exhibition').tizer_link}}{% else %}/b/exhibition/{{ doc.get('exhibition').tizer_file_id }}{% endif %}" style="width: 100%;">Релиз выставки</a>
{%endif%}
<a class="btn" href="{% if doc.get('exhibition') and doc.get('exhibition').get('rules_link') %}{{doc.get('exhibition').rules_link}}{% else %}/b/exhibition/{{ doc.get('exhibition').rules_file_id }}{% endif %}" style="width: 100%;">Условия выставки</a>
{% endmacro %}
{% block head %}
{{ header.style() }}
{{ profile_nav.style() }}
<style type="text/css">/* Base (common) styles */
.c_aq9et {
cursor: pointer;
transition: transform 0.1s linear, box‑shadow 0.1s linear;
box-shadow: 0 0 0 rgba(0, 0, 0, 0);
}
.c_aq9et:active {
transform: scale(0.9);
box-shadow: 5px 5px 5px rgba(95, 23, 152, 0.32);
}
article>a{width: 100%;}
picture>img{ width: 100%; object-fit: scale-down; }
.fl{display: flex;justify-content: space-between;width: 100%;}
.c_som9s { color: #FFF; font-family: Inter; font-size: 14px; font-style: normal; font-weight: 400; line-height: normal; }
.c_aq9et { display: flex; padding: 19px 33px; justify-content: center; align-items: center; align-self: stretch; border-radius: 5px; background: #5F1798; }
.b_ornr9 { align-self: stretch; height: 400px; overflow: hidden;}
.b_0jst1 { color: #0ED646; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 700; line-height: normal; }
.b_vabj9 { align-items: center; background: rgba(14, 214, 70, 0.20); border-radius: 30px; display: flex; justify-content: center; padding: 1.5px 10px; }
.b_0jst1_2 { color: #5F1798; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 700; line-height: normal; }
.b_vabj9_2 { align-items: center; background: #5e17982f; border-radius: 30px; display: flex; justify-content: center; padding: 1.5px 10px; }
.b_8f3uh { -webkit-box-orient: vertical; -webkit-line-clamp: 1; color: #000; display: -webkit-box; flex: 1 0 0; font-family: Inter; font-size: 24px; font-style: normal; font-weight: 700; line-height: normal; overflow: hidden; text-overflow: ellipsis; }
.b_9xtz9 { align-items: center; align-self: stretch; display: flex; justify-content: center; }
.b_tfnz2 { align-self: stretch; color: #5F1798; font-family: Inter; font-size: 14px; font-style: normal; font-weight: 400; line-height: normal; cursor: pointer; }
.b_a68fq { aspect-ratio: 1/1; border-radius: 50px; height: 50px; width: 50px; object-fit: cover; }
.b_ghosy { align-self: stretch; color: #000; font-family: Inter; font-size: 16px; font-style: normal; font-weight: 400; line-height: normal; }
.b_ntazj { align-items: flex-start; display: flex; flex-direction: column; flex: 1 0 0; justify-content: center; }
.b_otttb { align-items: center; align-self: stretch; display: flex; gap: 13px; }
.b_s6ool { white-space: pre-line; -webkit-box-orient: vertical; -webkit-line-clamp: 3; align-self: stretch; color: rgba(58, 58, 58, 0.75); display: -webkit-box; font-family: Inter; font-size: 14px; font-style: normal; font-weight: 400; line-height: normal; overflow: hidden; text-overflow: ellipsis; }
.b_mp1wb { align-self: stretch; color: rgba(58, 58, 58, 0.75); font-family: Inter; font-size: 14px; font-style: normal; font-weight: 400; line-height: normal; text-align: right; }
.b_73p10 { align-items: flex-start; align-self: stretch; background: #FFF; display: flex; flex-direction: column; gap: 10px; justify-content: center; }
.c_z3dpx{ padding: 10px 20px;}
.b_ax8vz { align-items: flex-start; border-radius: 10px; border: 1px solid #5F1798; box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.30), 0 4px 20px 0 rgba(0, 0, 0, 0.20); display: flex; flex-direction: column; width: 335px; overflow: hidden;}
@media (min-width: 901px) {
.c_9fgdh { align-items: flex-start; border-radius: 10px; border: 1px solid #5F1798; box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.30), 0 4px 20px 0 rgba(0, 0, 0, 0.20); display: flex; flex-direction: column; flex-shrink: 0; width: 335px; }
}
@media (max-width: 699px) {
.b_ornr9{height: auto;}
}
</style>
<style type="text/css">
.menua{width: 100%;
display: flex;
flex-direction: column;
gap: 7px;
margin: 10px 20px;}
.icona{display: flex;
gap: 10px;
align-items: center;}
.icona>span{color: #5F1798;}
.c_hysjg {
color: #0ED646;
font-family: Inter;
/* font-size: 12px; */
font-style: normal;
font-weight: 700;
line-height: normal;
}
/* .c_m876y{align-items: center;
background: rgba(14, 214, 70, 0.20);
border-radius: 30px;
display: flex;
justify-content: center;
padding: 1.5px 10px;} */
/* Mobile */
@media (max-width: 699px) {
.c_mrl59 { align-items: center; background: #5F1798; border-radius: 25px; bottom: -15px; display: flex; height: 50px; justify-content: center; position: absolute; right: -15px; width: 50px; }
}
/* Tablet */
@media (min-width: 700px) and (max-width: 900px) {
.c_iiehk { align-items: center; border-radius: 5px; display: flex; flex-direction: column; gap: 20px; width: 335px; }
.c_nnsh6>a>img{display: none;}
}
/* Desktop */
@media (min-width: 901px) {
.c_iiehk { align-items: flex-end; border-radius: 5px; display: flex; flex-direction: column; gap: 20px; width: 310px; }
.c_nnsh6>a>img{display: none;}
}</style>
<style type="text/css">
.b_thlt1 { align-items: center; background: rgba(14, 214, 70, 0.20); border-radius: 30px; display: flex; justify-content: center; padding: 1.5px 10px; }
.b_5dr47 { color: #0ED646; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 700; line-height: normal; }
.b_thlt1_2 { align-items: center; background: rgba(95, 23, 152, 0.20); border-radius: 30px; display: flex; justify-content: center; padding: 1.5px 10px; }
.b_5dr47_2 { color: #5F1798; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 700; line-height: normal; }
.b_6spaf {
color: #5F1798;
font-family: Inter;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
.b_qla2q {
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
color: #000;
display: -webkit-box;
font-family: Inter;
font-size: 13px;
font-style: normal;
font-weight: 400;
line-height: normal;
overflow: hidden;
text-overflow: ellipsis;
}
.b_uu2ub { align-items: flex-start; background: #FDFAFF; border-radius: 5px; border: 1px solid #5F1798; box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.25), 0 4px 20px 0 rgba(0, 0, 0, 0.20); display: flex; flex-direction: column; width: 335px; }
.b_1fvkt { align-self: stretch; border-radius: 5px; flex-shrink: 0; }
.b_pvw5a { gap: 7px;align-items: flex-start; align-self: stretch; display: flex; flex-direction: column; flex: 1 0 0; justify-content: space-between; padding: 10px 20px 37px 20px; }
.b_xz6em { align-items: center; align-self: stretch; display: flex; gap: 13px; }
.b_ob59y { border-radius: 1em; height: 70px; min-width: 70px; max-width: 150px; vertical-align: top; object-fit: cover;}
.b_ffruz { align-items: flex-start; display: flex; flex-direction: column; flex: 1 0 0; justify-content: center; }
.b_09est { color: #000; font-family: Inter; font-size: 15px; font-style: normal; font-weight: 700; line-height: normal; }
.b_wy3rt {
align-items: center;
background: #5F1798;
border-radius: 5px;
display: flex;
justify-content: center;
padding: 15px 0;
width: 100%;
}
.b_bvl0d {
color: #FFF;
font-family: Inter;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
/* Mobile */
@media (max-width: 699px) {
.c_3g8gh { align-items: flex-start; align-self: stretch; display: flex; flex-direction: column; flex-shrink: 0; justify-content: space-between; padding: 10px 20px 37px 20px; }
.c_4b1hy { align-items: flex-start; background: #FDFAFF; border-radius: 5px; border: 1px solid #5F1798; box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.25), 0 4px 20px 0 rgba(0, 0, 0, 0.20); display: flex; flex-direction: column; width: 335px; }
.c_mrl59 { align-items: center; background: #5F1798; border-radius: 25px; bottom: -15px; display: flex; height: 50px; justify-content: center; position: absolute; right: -15px; width: 50px; }
}
/* Tablet */
@media (min-width: 700px) and (max-width: 900px) {
.c_iiehk { align-items: center; border-radius: 5px; display: flex; flex-direction: column; gap: 20px; width: 335px; }
.c_nnsh6>a>img{display: none;}
}
/* Desktop */
@media (min-width: 901px) {
.c_iiehk { align-items: flex-end; border-radius: 5px; display: flex; flex-direction: column; gap: 20px; width: 310px; }
.c_nnsh6>a>img{display: none;}
}</style>
{{ footer.style() }}
{% endblock %}