Модалка отправки отклика: кнопка в колонке действий, генерация с прелоадером, отправка по готовности текста
This commit is contained in:
1 parent
e4cd06a23d
commit
2d781737f2
1 file changed
+106
@@ -86,6 +86,12 @@
|
||||
max-height: 92vh; overflow: auto; }
|
||||
.modal-box img { max-width: 100%; border: 1px solid var(--border);
|
||||
border-radius: 8px; display: block; }
|
||||
.spinner { width: 18px; height: 18px; border: 2px solid var(--border);
|
||||
border-top-color: var(--accent); border-radius: 50%;
|
||||
animation: spin .8s linear infinite; flex-shrink: 0; }
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
.loading { display: flex; align-items: center; gap: 10px;
|
||||
color: var(--muted); margin-bottom: 8px; }
|
||||
::-webkit-scrollbar { width: 10px; height: 10px; }
|
||||
::-webkit-scrollbar-track { background: var(--bg); }
|
||||
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 5px; }
|
||||
@@ -240,6 +246,28 @@
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<!-- ============ МОДАЛКА: ОТПРАВКА ОТКЛИКА ============ -->
|
||||
<div id="send-modal" class="modal hidden" onclick="if(event.target===this) closeSendModal()">
|
||||
<div class="modal-box">
|
||||
<div class="toolbar">
|
||||
<h2 style="margin:0">Отправить отклик</h2>
|
||||
<div class="spacer"></div>
|
||||
<button class="secondary" onclick="closeSendModal()">Закрыть</button>
|
||||
</div>
|
||||
<div id="send-vacancy-title" class="muted" style="margin-bottom:8px"></div>
|
||||
<div id="send-loading" class="loading">
|
||||
<div class="spinner"></div>
|
||||
<span>Текст генерируется...</span>
|
||||
</div>
|
||||
<textarea id="send-letter" style="min-height:140px" disabled
|
||||
placeholder="Сопроводительное письмо появится здесь..."></textarea>
|
||||
<div class="toolbar" style="margin-top:12px">
|
||||
<button id="btn-send-letter" onclick="sendFromModal()" disabled>Отправить отклик</button>
|
||||
<span id="send-modal-note" class="muted"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============ МОДАЛКА: ПРОВЕРКА ОТКЛИКА ============ -->
|
||||
<div id="shot-modal" class="modal hidden" onclick="if(event.target===this) closeShot()">
|
||||
<div class="modal-box">
|
||||
@@ -264,6 +292,7 @@ let vacancies = [];
|
||||
let generatedTexts = {};
|
||||
let currentShotId = null;
|
||||
let sentTexts = new Set();
|
||||
let sendModalId = null;
|
||||
|
||||
// ---------- Вкладки ----------
|
||||
function showTab(name) {
|
||||
@@ -511,6 +540,7 @@ function renderVacancies() {
|
||||
<td>${exp}</td>
|
||||
<td>${status}</td>
|
||||
<td class="actions-cell">
|
||||
<button class="secondary" onclick="openSendModal('${v.id}')">Отправить отклик</button>
|
||||
<button class="secondary" onclick="openVacancy('${v.id}')">Открыть</button>
|
||||
<button class="secondary" onclick="markDone('${v.id}')">Отправил</button>
|
||||
</td>
|
||||
@@ -589,6 +619,82 @@ function escapeHtml(s) {
|
||||
}
|
||||
|
||||
// ---------- Открытие, проверка и отправка ----------
|
||||
async function openSendModal(id) {
|
||||
if (!currentAccount) { alert('Сначала выберите аккаунт'); return; }
|
||||
const v = vacancies.find(x => x.id === id);
|
||||
if (!v) return;
|
||||
sendModalId = id;
|
||||
document.getElementById('send-vacancy-title').textContent = `${v.title} — ${v.company || ''}`;
|
||||
document.getElementById('send-letter').value = '';
|
||||
document.getElementById('send-letter').disabled = true;
|
||||
document.getElementById('btn-send-letter').disabled = true;
|
||||
document.getElementById('send-modal-note').textContent = '';
|
||||
document.getElementById('send-modal').classList.remove('hidden');
|
||||
|
||||
const cached = generatedTexts[id];
|
||||
if (cached) {
|
||||
// Текст уже сгенерирован ранее — показываем сразу
|
||||
document.getElementById('send-letter').value = cached;
|
||||
document.getElementById('send-letter').disabled = false;
|
||||
document.getElementById('btn-send-letter').disabled = false;
|
||||
document.getElementById('send-loading').classList.add('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
// Генерируем текст (прелоадер виден)
|
||||
document.getElementById('send-loading').classList.remove('hidden');
|
||||
try {
|
||||
const data = await api(`/api/accounts/${currentAccount}/generate`, {
|
||||
method: 'POST', body: JSON.stringify({ ids: [id] }),
|
||||
});
|
||||
document.getElementById('send-loading').classList.add('hidden');
|
||||
if (data.texts && data.texts[id]) {
|
||||
generatedTexts[id] = data.texts[id];
|
||||
document.getElementById('send-letter').value = data.texts[id];
|
||||
document.getElementById('send-letter').disabled = false;
|
||||
document.getElementById('btn-send-letter').disabled = false;
|
||||
renderTexts();
|
||||
} else if (data.errors && data.errors[id]) {
|
||||
document.getElementById('send-modal-note').textContent = 'Ошибка: ' + data.errors[id];
|
||||
}
|
||||
} catch (e) {
|
||||
document.getElementById('send-loading').classList.add('hidden');
|
||||
document.getElementById('send-modal-note').textContent = 'Ошибка: ' + e.message;
|
||||
}
|
||||
}
|
||||
|
||||
function closeSendModal() {
|
||||
document.getElementById('send-modal').classList.add('hidden');
|
||||
}
|
||||
|
||||
async function sendFromModal() {
|
||||
if (!currentAccount || !sendModalId) return;
|
||||
const message = document.getElementById('send-letter').value;
|
||||
const btn = document.getElementById('btn-send-letter');
|
||||
const note = document.getElementById('send-modal-note');
|
||||
btn.disabled = true; note.textContent = 'Отправляю...';
|
||||
try {
|
||||
const data = await api(`/api/accounts/${currentAccount}/send-now`, {
|
||||
method: 'POST', body: JSON.stringify({ id: sendModalId, message }),
|
||||
});
|
||||
if (data.screenshot) {
|
||||
showShotModal(sendModalId, data.screenshot, data.note || 'Отклик отправлен', true);
|
||||
sentTexts.add(sendModalId);
|
||||
const v = vacancies.find(x => x.id === sendModalId);
|
||||
if (v) v.responded = true;
|
||||
renderVacancies();
|
||||
renderTexts();
|
||||
closeSendModal();
|
||||
} else {
|
||||
note.textContent = data.note || 'Не удалось отправить отклик';
|
||||
btn.disabled = false;
|
||||
}
|
||||
} catch (e) {
|
||||
note.textContent = 'Ошибка: ' + e.message;
|
||||
btn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function showShotModal(id, screenshot, note, sent) {
|
||||
currentShotId = id;
|
||||
document.getElementById('shot-img').src = screenshot + '?t=' + Date.now();
|
||||
|
||||
Reference in new issue
Block a user