Files
yarmarka/templates/company_detail.html
2026-03-16 18:57:22 +03:00

748 lines
24 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: 1200px;
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;
flex-wrap: wrap;
gap: 20px;
}
.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;
flex-wrap: wrap;
}
.nav a {
color: white;
text-decoration: none;
padding: 10px 20px;
border-radius: 30px;
transition: 0.2s;
}
.nav a:hover {
background: rgba(255,255,255,0.1);
}
.nav .active {
background: #3b82f6;
}
.profile-link {
display: flex;
align-items: center;
gap: 8px;
background: #3b82f6;
padding: 8px 20px !important;
}
.admin-badge {
background: #f59e0b;
color: white;
padding: 2px 8px;
border-radius: 20px;
font-size: 12px;
margin-left: 5px;
}
.back-link {
display: inline-block;
margin-bottom: 20px;
color: #4f7092;
text-decoration: none;
font-size: 16px;
}
.back-link i {
margin-right: 8px;
}
.back-link:hover {
color: #0b1c34;
}
/* Шапка компании */
.company-header {
background: white;
border-radius: 40px;
padding: 40px;
margin-bottom: 30px;
box-shadow: 0 20px 40px rgba(0,20,40,0.1);
display: flex;
gap: 40px;
flex-wrap: wrap;
align-items: center;
}
.company-logo {
width: 120px;
height: 120px;
background: #eef4fa;
border-radius: 30px;
display: flex;
align-items: center;
justify-content: center;
font-size: 48px;
color: #3b82f6;
flex-shrink: 0;
}
.company-logo img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 30px;
}
.company-info {
flex: 1;
}
.company-name {
font-size: 36px;
font-weight: 700;
color: #0b1c34;
margin-bottom: 10px;
}
.company-meta {
display: flex;
gap: 20px;
color: #4f7092;
font-size: 16px;
flex-wrap: wrap;
}
.company-meta i {
color: #3b82f6;
margin-right: 5px;
}
.company-website {
display: inline-block;
margin-top: 15px;
color: #3b82f6;
text-decoration: none;
font-weight: 600;
}
.company-website:hover {
text-decoration: underline;
}
/* Статистика компании */
.company-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.stat-card {
background: white;
border-radius: 30px;
padding: 25px;
text-align: center;
box-shadow: 0 10px 20px rgba(0,20,40,0.05);
}
.stat-card i {
font-size: 32px;
color: #3b82f6;
margin-bottom: 10px;
}
.stat-value {
font-size: 28px;
font-weight: 700;
color: #0b1c34;
}
.stat-label {
color: #4f7092;
font-size: 14px;
}
/* Описание компании */
.company-description {
background: white;
border-radius: 40px;
padding: 40px;
margin-bottom: 30px;
box-shadow: 0 20px 40px rgba(0,20,40,0.1);
}
.section-title {
font-size: 24px;
color: #0b1c34;
margin-bottom: 20px;
font-weight: 600;
display: flex;
align-items: center;
gap: 10px;
}
.section-title i {
color: #3b82f6;
}
.description-text {
line-height: 1.8;
color: #1f3f60;
font-size: 16px;
white-space: pre-line;
}
/* Контакты */
.company-contacts {
background: white;
border-radius: 40px;
padding: 40px;
margin-bottom: 30px;
box-shadow: 0 20px 40px rgba(0,20,40,0.1);
}
.contacts-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.contact-item {
display: flex;
align-items: center;
gap: 15px;
padding: 15px;
background: #f9fcff;
border-radius: 20px;
}
.contact-item i {
width: 40px;
height: 40px;
background: #eef4fa;
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
color: #3b82f6;
font-size: 18px;
}
.contact-info {
flex: 1;
}
.contact-label {
font-size: 12px;
color: #4f7092;
margin-bottom: 4px;
}
.contact-value {
font-weight: 600;
color: #0b1c34;
}
/* Вакансии компании */
.company-vacancies {
background: white;
border-radius: 40px;
padding: 40px;
margin-bottom: 30px;
box-shadow: 0 20px 40px rgba(0,20,40,0.1);
}
.vacancies-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
flex-wrap: wrap;
gap: 20px;
}
.vacancies-header h2 {
font-size: 24px;
color: #0b1c34;
display: flex;
align-items: center;
gap: 10px;
}
.vacancies-header h2 i {
color: #3b82f6;
}
.vacancies-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
.vacancy-card {
background: #f9fcff;
border: 1px solid #dee9f5;
border-radius: 30px;
padding: 25px;
transition: 0.2s;
cursor: pointer;
position: relative;
}
.vacancy-card:hover {
background: white;
box-shadow: 0 10px 30px rgba(0,20,40,0.1);
transform: translateY(-3px);
}
.vacancy-card h3 {
color: #0b1c34;
margin-bottom: 10px;
font-size: 18px;
}
.vacancy-salary {
color: #3b82f6;
font-weight: 700;
font-size: 18px;
margin: 10px 0;
}
.vacancy-tags {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin: 10px 0;
}
.tag {
background: #eef4fa;
padding: 4px 10px;
border-radius: 20px;
font-size: 12px;
color: #1f3f60;
}
.vacancy-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 15px;
font-size: 14px;
color: #4f7092;
}
/* Социальные сети */
.company-social {
background: white;
border-radius: 40px;
padding: 40px;
box-shadow: 0 20px 40px rgba(0,20,40,0.1);
}
.social-links {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.social-link {
width: 50px;
height: 50px;
background: #eef4fa;
border-radius: 25px;
display: flex;
align-items: center;
justify-content: center;
color: #3b82f6;
font-size: 24px;
transition: 0.2s;
}
.social-link:hover {
background: #3b82f6;
color: white;
transform: translateY(-3px);
}
/* Загрузка */
.loading {
text-align: center;
padding: 60px;
color: #4f7092;
font-size: 18px;
}
/* Ошибка */
.error-message {
background: #fee2e2;
color: #b91c1c;
padding: 20px;
border-radius: 30px;
text-align: center;
margin: 40px 0;
}
/* Адаптивность */
@media (max-width: 768px) {
.company-header {
flex-direction: column;
text-align: center;
}
.company-meta {
justify-content: center;
}
.contacts-grid {
grid-template-columns: 1fr;
}
}
</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="javascript:history.back()" class="back-link"><i class="fas fa-arrow-left"></i> Назад</a>
<!-- Контент компании -->
<div id="companyContent">
<div class="loading">Загрузка информации о компании...</div>
</div>
</div>
<script>
const API_BASE_URL = window.location.protocol + '//' + window.location.host + '/api';
let currentUser = null;
// Получаем ID компании из URL
const pathParts = window.location.pathname.split('/');
const companyId = pathParts[pathParts.length - 1];
// Проверка авторизации
async function checkAuth() {
const token = localStorage.getItem('accessToken');
if (token) {
try {
const response = await fetch(`${API_BASE_URL}/user`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (response.ok) {
currentUser = await response.json();
} else {
localStorage.removeItem('accessToken');
}
} catch (error) {
console.error('Error checking auth:', error);
}
}
updateNavigation();
}
// Обновление навигации
function updateNavigation() {
const nav = document.getElementById('nav');
if (currentUser) {
const firstName = currentUser.full_name.split(' ')[0];
const adminBadge = currentUser.is_admin ? '<span class="admin-badge">Admin</span>' : '';
nav.innerHTML = `
<a href="/">Главная</a>
<a href="/vacancies">Вакансии</a>
<a href="/resumes">Резюме</a>
<a href="/favorites">Избранное</a>
<a href="/applications">Отклики</a>
<a href="/profile" class="profile-link">
<i class="fas fa-user-circle"></i> ${firstName} ${adminBadge}
</a>
`;
} else {
nav.innerHTML = `
<a href="/">Главная</a>
<a href="/vacancies">Вакансии</a>
<a href="/resumes">Резюме</a>
<a href="/login">Войти</a>
<a href="/register">Регистрация</a>
`;
}
}
// Загрузка информации о компании
async function loadCompany() {
try {
console.log('📥 Загрузка компании ID:', companyId);
const response = await fetch(`${API_BASE_URL}/companies/${companyId}`);
if (!response.ok) {
throw new Error('Компания не найдена');
}
const company = await response.json();
console.log('✅ Компания загружена:', company);
// Загружаем вакансии компании
const vacanciesResponse = await fetch(`${API_BASE_URL}/vacancies/all?company_id=${companyId}`);
const vacancies = vacanciesResponse.ok ? await vacanciesResponse.json() : { vacancies: [] };
renderCompany(company, vacancies.vacancies || []);
} catch (error) {
console.error('❌ Ошибка загрузки компании:', error);
document.getElementById('companyContent').innerHTML = `
<div class="error-message">
<i class="fas fa-exclamation-circle"></i>
Компания не найдена или была удалена
</div>
<div style="text-align: center; margin-top: 20px;">
<a href="/" class="btn btn-primary">На главную</a>
</div>
`;
}
}
// Отображение компании
function renderCompany(company, vacancies) {
const container = document.getElementById('companyContent');
// Форматирование даты регистрации
const createdDate = new Date(company.created_at).toLocaleDateString('ru-RU', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
// Активные вакансии
const activeVacancies = vacancies.filter(v => v.is_active).length;
container.innerHTML = `
<!-- Шапка компании -->
<div class="company-header">
<div class="company-logo">
${company.logo ?
`<img src="${escapeHtml(company.logo)}" alt="${escapeHtml(company.name)}">` :
`<i class="fas fa-building"></i>`
}
</div>
<div class="company-info">
<h1 class="company-name">${escapeHtml(company.name)}</h1>
<div class="company-meta">
<span><i class="fas fa-calendar"></i> На рынке с ${createdDate}</span>
${company.website ?
`<span><i class="fas fa-globe"></i> <a href="${escapeHtml(company.website)}" target="_blank">${escapeHtml(company.website)}</a></span>` :
''
}
</div>
</div>
</div>
<!-- Статистика компании -->
<div class="company-stats">
<div class="stat-card">
<i class="fas fa-briefcase"></i>
<div class="stat-value">${vacancies.length}</div>
<div class="stat-label">Всего вакансий</div>
</div>
<div class="stat-card">
<i class="fas fa-check-circle"></i>
<div class="stat-value">${activeVacancies}</div>
<div class="stat-label">Активных</div>
</div>
<div class="stat-card">
<i class="fas fa-eye"></i>
<div class="stat-value">${vacancies.reduce((sum, v) => sum + (v.views || 0), 0)}</div>
<div class="stat-label">Просмотров</div>
</div>
</div>
<!-- Описание компании -->
${company.description ? `
<div class="company-description">
<h2 class="section-title">
<i class="fas fa-info-circle"></i> О компании
</h2>
<div class="description-text">${escapeHtml(company.description).replace(/\n/g, '<br>')}</div>
</div>
` : ''}
<!-- Контактная информация -->
<div class="company-contacts">
<h2 class="section-title">
<i class="fas fa-address-card"></i> Контактная информация
</h2>
<div class="contacts-grid">
${company.email ? `
<div class="contact-item">
<i class="fas fa-envelope"></i>
<div class="contact-info">
<div class="contact-label">Email</div>
<div class="contact-value">
<a href="mailto:${escapeHtml(company.email)}">${escapeHtml(company.email)}</a>
</div>
</div>
</div>
` : ''}
${company.phone ? `
<div class="contact-item">
<i class="fas fa-phone"></i>
<div class="contact-info">
<div class="contact-label">Телефон</div>
<div class="contact-value">
<a href="tel:${escapeHtml(company.phone)}">${escapeHtml(company.phone)}</a>
</div>
</div>
</div>
` : ''}
${company.address ? `
<div class="contact-item">
<i class="fas fa-map-marker-alt"></i>
<div class="contact-info">
<div class="contact-label">Адрес</div>
<div class="contact-value">${escapeHtml(company.address)}</div>
</div>
</div>
` : ''}
${company.website ? `
<div class="contact-item">
<i class="fas fa-globe"></i>
<div class="contact-info">
<div class="contact-label">Сайт</div>
<div class="contact-value">
<a href="${escapeHtml(company.website)}" target="_blank">${escapeHtml(company.website)}</a>
</div>
</div>
</div>
` : ''}
</div>
</div>
<!-- Вакансии компании -->
<div class="company-vacancies">
<div class="vacancies-header">
<h2>
<i class="fas fa-briefcase"></i> Вакансии компании
</h2>
<span style="color: #4f7092;">${vacancies.length} вакансий</span>
</div>
${vacancies.length > 0 ? `
<div class="vacancies-grid">
${vacancies.map(v => `
<div class="vacancy-card" onclick="window.location.href='/vacancy/${v.id}'">
<h3>${escapeHtml(v.title)}</h3>
<div class="vacancy-salary">${escapeHtml(v.salary || 'з/п не указана')}</div>
<div class="vacancy-tags">
${(v.tags || []).map(t => `<span class="tag">${escapeHtml(t.name)}</span>`).join('')}
</div>
<div class="vacancy-footer">
<span><i class="fas fa-eye"></i> ${v.views || 0}</span>
<span><i class="fas fa-calendar"></i> ${new Date(v.created_at).toLocaleDateString()}</span>
</div>
</div>
`).join('')}
</div>
` : `
<p style="text-align: center; color: #4f7092; padding: 40px;">
У компании пока нет активных вакансий
</p>
`}
</div>
<!-- Социальные сети (заглушка, можно добавить позже) -->
<div class="company-social" style="display: none;">
<h2 class="section-title">
<i class="fas fa-share-alt"></i> Мы в соцсетях
</h2>
<div class="social-links">
<a href="#" class="social-link"><i class="fab fa-telegram"></i></a>
<a href="#" class="social-link"><i class="fab fa-vk"></i></a>
<a href="#" class="social-link"><i class="fab fa-linkedin"></i></a>
</div>
</div>
`;
}
// Экранирование HTML
function escapeHtml(unsafe) {
if (!unsafe) return '';
return unsafe.toString()
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
// Инициализация
checkAuth().then(() => {
loadCompany();
});
</script>
</body>
</html>