Files
yarmarka/templates/application_detail.html
2026-03-13 19:58:52 +03:00

358 lines
11 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.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Отклик | Rabota.Today</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
/* Стили аналогичные предыдущим страницам */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
body {
background: linear-gradient(145deg, #eef5fa 0%, #e0eaf5 100%);
min-height: 100vh;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
}
.header {
background: #0b1c34;
color: white;
padding: 20px 40px;
border-radius: 40px;
margin-bottom: 40px;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 28px;
font-weight: 700;
display: flex;
align-items: center;
gap: 15px;
}
.logo i {
color: #3b82f6;
background: rgba(255,255,255,0.1);
padding: 12px;
border-radius: 20px;
}
.nav {
display: flex;
gap: 15px;
align-items: center;
}
.nav a {
color: white;
text-decoration: none;
padding: 10px 20px;
border-radius: 30px;
}
.nav .active {
background: #3b82f6;
}
.back-link {
display: inline-block;
margin-bottom: 20px;
color: #4f7092;
text-decoration: none;
}
.application-detail {
background: white;
border-radius: 40px;
padding: 40px;
box-shadow: 0 20px 40px rgba(0,20,40,0.1);
}
.status-bar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 2px solid #dee9f5;
}
.status-badge {
padding: 8px 20px;
border-radius: 40px;
font-weight: 600;
}
.status-badge.pending { background: #fef3c7; color: #92400e; }
.status-badge.viewed { background: #dbeafe; color: #1e40af; }
.status-badge.accepted { background: #d1fae5; color: #065f46; }
.status-badge.rejected { background: #fee2e2; color: #b91c1c; }
.date {
color: #4f7092;
font-size: 14px;
}
.section {
margin: 30px 0;
padding: 20px;
background: #f9fcff;
border-radius: 20px;
}
.section h3 {
color: #0b1c34;
margin-bottom: 15px;
}
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
}
.info-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
background: white;
border-radius: 15px;
}
.info-item i {
color: #3b82f6;
width: 20px;
}
.message-box {
background: white;
padding: 20px;
border-radius: 20px;
margin: 20px 0;
font-style: italic;
border-left: 4px solid #3b82f6;
}
.response-box {
background: #e6f7e6;
padding: 20px;
border-radius: 20px;
margin: 20px 0;
border-left: 4px solid #10b981;
}
.action-buttons {
display: flex;
gap: 15px;
margin-top: 30px;
}
.btn {
padding: 14px 28px;
border-radius: 40px;
border: none;
font-weight: 600;
cursor: pointer;
}
.btn-primary {
background: #0b1c34;
color: white;
}
.btn-success {
background: #10b981;
color: white;
}
.btn-danger {
background: #ef4444;
color: white;
}
.btn-outline {
background: transparent;
border: 2px solid #dee9f5;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<div class="logo">
<i class="fas fa-briefcase"></i>
Rabota.Today
</div>
<div class="nav" id="nav">
<!-- Навигация -->
</div>
</div>
<a href="/applications" class="back-link"><i class="fas fa-arrow-left"></i> Назад к откликам</a>
<div id="applicationDetail" class="application-detail">
<div class="loading">Загрузка...</div>
</div>
</div>
<script>
const API_BASE_URL = 'http://localhost:8000/api';
const token = localStorage.getItem('accessToken');
const pathParts = window.location.pathname.split('/');
const applicationId = pathParts[pathParts.length - 1];
if (!token) window.location.href = '/login';
async function loadApplication() {
try {
const response = await fetch(`${API_BASE_URL}/applications/${applicationId}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (!response.ok) throw new Error('Ошибка загрузки');
const app = await response.json();
renderApplication(app);
} catch (error) {
console.error('Error:', error);
}
}
function renderApplication(app) {
const container = document.getElementById('applicationDetail');
const isEmployer = app.employer_id === currentUser?.id;
const statusText = {
'pending': 'Ожидает',
'viewed': 'Просмотрено',
'accepted': 'Принято',
'rejected': 'Отклонено'
}[app.status] || app.status;
container.innerHTML = `
<div class="status-bar">
<span class="status-badge ${app.status}">${statusText}</span>
<span class="date">Создано: ${new Date(app.created_at).toLocaleString()}</span>
</div>
<h2>${escapeHtml(app.vacancy_title)}</h2>
<div class="section">
<h3>Информация о вакансии</h3>
<div class="info-grid">
<div class="info-item">
<i class="fas fa-building"></i>
<span>${escapeHtml(app.company_name || app.employer_name)}</span>
</div>
<div class="info-item">
<i class="fas fa-money-bill"></i>
<span>${escapeHtml(app.vacancy_salary || 'з/п не указана')}</span>
</div>
<div class="info-item">
<i class="fas fa-envelope"></i>
<span>${escapeHtml(app.employer_email)}</span>
</div>
</div>
</div>
<div class="section">
<h3>Информация о соискателе</h3>
<div class="info-grid">
<div class="info-item">
<i class="fas fa-user"></i>
<span>${escapeHtml(app.applicant_name)}</span>
</div>
<div class="info-item">
<i class="fas fa-envelope"></i>
<span>${escapeHtml(app.applicant_email)}</span>
</div>
<div class="info-item">
<i class="fas fa-phone"></i>
<span>${escapeHtml(app.applicant_phone || '—')}</span>
</div>
<div class="info-item">
<i class="fab fa-telegram"></i>
<span>${escapeHtml(app.applicant_telegram || '—')}</span>
</div>
</div>
</div>
${app.message ? `
<div class="message-box">
<strong>Сопроводительное письмо:</strong>
<p>${escapeHtml(app.message)}</p>
</div>
` : ''}
${app.response_message ? `
<div class="response-box">
<strong>Ответ работодателя:</strong>
<p>${escapeHtml(app.response_message)}</p>
<small>${new Date(app.response_at).toLocaleString()}</small>
</div>
` : ''}
${isEmployer && app.status === 'pending' ? `
<div class="action-buttons">
<button class="btn btn-success" onclick="updateStatus('accepted')">Принять</button>
<button class="btn btn-danger" onclick="updateStatus('rejected')">Отклонить</button>
</div>
` : ''}
`;
}
async function updateStatus(status) {
const message = prompt('Введите сообщение (необязательно):');
try {
const response = await fetch(`${API_BASE_URL}/applications/${applicationId}/status`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
status: status,
response_message: message || null
})
});
if (response.ok) {
alert('Статус обновлен');
loadApplication();
}
} catch (error) {
alert('Ошибка');
}
}
function escapeHtml(unsafe) {
if (!unsafe) return '';
return unsafe.toString()
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
loadApplication();
</script>
</body>
</html>