diff --git a/OneCprogsite/media/scan/2025/11/14/Отзыв_о_работе_РОВЕН_Сердюк_Н..jpg b/OneCprogsite/media/scan/2025/11/14/Отзыв_о_работе_РОВЕН_Сердюк_Н..jpg new file mode 100644 index 0000000..b19cde8 Binary files /dev/null and b/OneCprogsite/media/scan/2025/11/14/Отзыв_о_работе_РОВЕН_Сердюк_Н..jpg differ diff --git a/OneCprogsite/programmer/static/programmer/css/competence.css b/OneCprogsite/programmer/static/programmer/css/competence.css new file mode 100644 index 0000000..c94820d --- /dev/null +++ b/OneCprogsite/programmer/static/programmer/css/competence.css @@ -0,0 +1,299 @@ +/* competence.css - Стили для страницы компетенций */ + +/* Основные стили для страницы компетенций */ +.competence-item { + display: flex; + gap: 2rem; + align-items: flex-start; + padding: 2rem; + background: var(--bg-card); + border-radius: var(--radius-xl); + box-shadow: var(--shadow-lg); + border-left: 4px solid var(--secondary); + transition: var(--transition); + border: 1px solid var(--border-light); +} + +.competence-item:hover { + transform: translateX(8px); + box-shadow: var(--shadow-xl); + border-color: var(--primary-light); +} + +.competence-scan-wrapper { + flex-shrink: 0; +} + +.competence-scan-container { + width: 280px; + cursor: pointer; + border-radius: var(--radius-lg); + overflow: hidden; + border: 2px solid var(--border-light); + transition: var(--transition); + position: relative; + box-shadow: var(--shadow-md); +} + +.competence-scan-container:hover { + transform: translateY(-4px) scale(1.02); + box-shadow: var(--shadow-xl); + border-color: var(--primary); +} + +.competence-scan { + width: 100%; + height: auto; + display: block; + transition: var(--transition); +} + +.competence-content { + flex: 1; + min-width: 0; +} + +.competence-title { + font-size: 1.5rem; + font-weight: 700; + color: var(--text-primary); + margin-bottom: 1rem; + background: var(--gradient-primary); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.competence-description { + line-height: 1.7; + font-size: 1.05rem; + color: var(--text-primary); +} + +.competence-description p { + margin-bottom: 1rem; +} + +.competence-description p:last-child { + margin-bottom: 0; +} + +.scan-hint { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(transparent, rgba(0,0,0,0.8)); + color: white; + padding: 1rem; + text-align: center; + opacity: 0; + transition: var(--transition); + transform: translateY(10px); +} + +.competence-scan-container:hover .scan-hint { + opacity: 1; + transform: translateY(0); +} + +/* Стили для модального окна с изображением компетенций */ +.modal.competence-modal { + background-color: rgba(15, 19, 31, 0.95); + backdrop-filter: blur(10px); +} + +.modal.competence-modal .modal-content { + background: transparent; + border: none; + box-shadow: none; + max-width: 95vw; + max-height: 95vh; + margin: 2% auto; +} + +.modal.competence-modal .modal-header { + background: var(--bg-card); + border-bottom: 2px solid var(--border-light); + padding: 1.5rem 2rem; +} + +.modal.competence-modal .modal-header h3 { + margin: 0; + color: var(--text-primary); + font-size: 1.25rem; + font-weight: 600; + background: var(--gradient-primary); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.modal.competence-modal .modal-body { + padding: 1rem; + display: flex; + align-items: center; + justify-content: center; + background: transparent; +} + +.modal-image { + max-width: 90vw; + max-height: 80vh; + width: auto; + height: auto; + display: block; + margin: 0 auto; + border-radius: var(--radius-md); + box-shadow: var(--shadow-xl); + transition: all 0.3s ease; +} + +/* Анимации для модального окна */ +.modal.competence-modal { + transition: opacity 0.3s ease; + opacity: 0; +} + +.modal.competence-modal.active { + opacity: 1; +} + +.modal.competence-modal .modal-content { + transform: scale(0.7); + transition: transform 0.3s ease; +} + +.modal.competence-modal.active .modal-content { + transform: scale(1); +} + +/* Улучшенные тени и границы */ +.competence-scan-container { + border: 2px solid var(--border-light); + box-shadow: var(--shadow-lg); +} + +.competence-scan-container:hover { + border-color: var(--primary-light); + box-shadow: var(--shadow-xl); +} + +/* Адаптивность для мобильных устройств */ +@media (max-width: 768px) { + .competence-item { + flex-direction: column; + padding: 1.5rem; + gap: 1.5rem; + } + + .competence-scan-container { + width: 100%; + max-width: 300px; + margin: 0 auto; + } + + .competence-title { + font-size: 1.375rem; + text-align: center; + } + + .modal-image { + max-width: 95vw; + max-height: 70vh; + } + + .modal.competence-modal .modal-content { + margin: 10% auto; + } + + .modal.competence-modal .modal-header { + padding: 1rem 1.5rem; + } +} + +@media (max-width: 480px) { + .competence-item { + padding: 1.25rem; + } + + .competence-scan-container { + max-width: 100%; + } + + .competence-title { + font-size: 1.25rem; + } + + .modal.competence-modal .modal-content { + margin: 5% auto; + max-width: 98vw; + } + + .modal.competence-modal .modal-body { + padding: 0.5rem; + } + + .modal.competence-modal .modal-header { + padding: 1rem; + } + + .modal.competence-modal .modal-header h3 { + font-size: 1.1rem; + } +} + +/* Стили для светлой темы */ +@media (prefers-color-scheme: light) { + .modal.competence-modal { + background-color: rgba(0, 0, 0, 0.8); + } + + .modal.competence-modal .modal-header { + background: var(--bg-primary); + } + + .scan-hint { + background: linear-gradient(transparent, rgba(0,0,0,0.7)); + } + + .competence-item { + background: var(--bg-primary); + } + + .competence-description { + color: var(--text-primary); + } +} + +/* Улучшенные стили для сетки компетенций */ +.competence-grid { + display: grid; + gap: 2rem; +} + +.competence-grid .modern-card { + padding: 0; + overflow: hidden; +} + +.competence-grid .modern-card::before { + height: 4px; + background: var(--gradient-secondary); +} + +/* Анимации появления */ +.fade-in { + animation: fadeInUp 0.8s ease-out; +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(40px); + } + to { + opacity: 1; + transform: translateY(0); + } +} \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/css/recall.css b/OneCprogsite/programmer/static/programmer/css/recall.css new file mode 100644 index 0000000..b6154a8 --- /dev/null +++ b/OneCprogsite/programmer/static/programmer/css/recall.css @@ -0,0 +1,228 @@ +/* recall.css - Стили для страницы отзывов */ + +/* Основные стили для страницы отзывов */ +.recall-item { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.recall-content { + display: flex; + gap: 2rem; + align-items: flex-start; +} + +.recall-scan-wrapper { + flex-shrink: 0; +} + +.recall-scan-container { + width: 280px; + cursor: pointer; + border-radius: var(--radius-lg); + overflow: hidden; + border: 2px solid var(--border-light); + transition: var(--transition); + position: relative; + box-shadow: var(--shadow-md); +} + +.recall-scan-container:hover { + transform: translateY(-4px) scale(1.02); + box-shadow: var(--shadow-xl); + border-color: var(--primary); +} + +.recall-scan { + width: 100%; + height: auto; + display: block; + transition: var(--transition); +} + +.recall-text { + flex: 1; + min-width: 0; + line-height: 1.7; + font-size: 1.05rem; + color: var(--text-primary); +} + +.recall-text p { + margin-bottom: 1rem; +} + +.recall-text p:last-child { + margin-bottom: 0; +} + +.scan-hint { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(transparent, rgba(0,0,0,0.8)); + color: white; + padding: 1rem; + text-align: center; + opacity: 0; + transition: var(--transition); + transform: translateY(10px); +} + +.recall-scan-container:hover .scan-hint { + opacity: 1; + transform: translateY(0); +} + +/* Стили для модального окна с изображением */ +.modal.image-modal { + background-color: rgba(15, 19, 31, 0.95); + backdrop-filter: blur(10px); +} + +.modal.image-modal .modal-content { + background: transparent; + border: none; + box-shadow: none; + max-width: 95vw; + max-height: 95vh; + margin: 2% auto; +} + +.modal.image-modal .modal-header { + background: var(--bg-card); + border-bottom: 2px solid var(--border-light); + padding: 1.5rem 2rem; +} + +.modal.image-modal .modal-header h3 { + margin: 0; + color: var(--text-primary); + font-size: 1.25rem; + font-weight: 600; + background: var(--gradient-primary); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.modal.image-modal .modal-body { + padding: 1rem; + display: flex; + align-items: center; + justify-content: center; + background: transparent; +} + +.modal-image { + max-width: 90vw; + max-height: 80vh; + width: auto; + height: auto; + display: block; + margin: 0 auto; + border-radius: var(--radius-md); + box-shadow: var(--shadow-xl); + transition: all 0.3s ease; +} + +/* Анимации для модального окна */ +.modal.image-modal { + transition: opacity 0.3s ease; + opacity: 0; +} + +.modal.image-modal.active { + opacity: 1; +} + +.modal.image-modal .modal-content { + transform: scale(0.7); + transition: transform 0.3s ease; +} + +.modal.image-modal.active .modal-content { + transform: scale(1); +} + +/* Улучшенные тени и границы */ +.recall-scan-container { + border: 2px solid var(--border-light); + box-shadow: var(--shadow-lg); +} + +.recall-scan-container:hover { + border-color: var(--primary-light); + box-shadow: var(--shadow-xl); +} + +/* Адаптивность для мобильных устройств */ +@media (max-width: 768px) { + .recall-content { + flex-direction: column; + gap: 1.5rem; + } + + .recall-scan-container { + width: 100%; + max-width: 300px; + margin: 0 auto; + } + + .recall-scan-wrapper { + order: -1; + } + + .modal-image { + max-width: 95vw; + max-height: 70vh; + } + + .modal.image-modal .modal-content { + margin: 10% auto; + } + + .modal.image-modal .modal-header { + padding: 1rem 1.5rem; + } +} + +@media (max-width: 480px) { + .recall-scan-container { + max-width: 100%; + } + + .modal.image-modal .modal-content { + margin: 5% auto; + max-width: 98vw; + } + + .modal.image-modal .modal-body { + padding: 0.5rem; + } + + .modal.image-modal .modal-header { + padding: 1rem; + } + + .modal.image-modal .modal-header h3 { + font-size: 1.1rem; + } +} + +/* Стили для светлой темы */ +@media (prefers-color-scheme: light) { + .modal.image-modal { + background-color: rgba(0, 0, 0, 0.8); + } + + .modal.image-modal .modal-header { + background: var(--bg-primary); + } + + .scan-hint { + background: linear-gradient(transparent, rgba(0,0,0,0.7)); + } +} \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/css/styles_dark.css b/OneCprogsite/programmer/static/programmer/css/styles_dark.css index 0b5f12d..b4b07c3 100644 --- a/OneCprogsite/programmer/static/programmer/css/styles_dark.css +++ b/OneCprogsite/programmer/static/programmer/css/styles_dark.css @@ -1332,4 +1332,142 @@ body { .competence-scan-container { max-width: 100%; } +} + +/* Стили для страницы отзывов */ +.recall-item { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.recall-content { + display: flex; + gap: 2rem; + align-items: flex-start; +} + +.recall-scan-wrapper { + flex-shrink: 0; +} + +.recall-scan-container { + width: 280px; + cursor: pointer; + border-radius: var(--radius-lg); + overflow: hidden; + border: 2px solid var(--border-light); + transition: var(--transition); + position: relative; + box-shadow: var(--shadow-md); +} + +.recall-scan-container:hover { + transform: translateY(-4px) scale(1.02); + box-shadow: var(--shadow-xl); + border-color: var(--primary); +} + +.recall-scan { + width: 100%; + height: auto; + display: block; + transition: var(--transition); +} + +.recall-text { + flex: 1; + min-width: 0; + line-height: 1.7; + font-size: 1.05rem; +} + +.scan-hint { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(transparent, rgba(0,0,0,0.8)); + color: white; + padding: 1rem; + text-align: center; + opacity: 0; + transition: var(--transition); + transform: translateY(10px); +} + +.recall-scan-container:hover .scan-hint { + opacity: 1; + transform: translateY(0); +} + +/* Стили для модального окна с изображением */ +.modal-image { + max-width: 90vw; + max-height: 80vh; + width: auto; + height: auto; + display: block; + margin: 0 auto; + border-radius: var(--radius-md); + box-shadow: var(--shadow-xl); + transition: all 0.3s ease; +} + +.modal-content.image-modal { + max-width: 95vw; + max-height: 95vh; + background: transparent; + border: none; + box-shadow: none; +} + +.modal-body.image-modal-body { + padding: 1rem; + display: flex; + align-items: center; + justify-content: center; + background: transparent; +} + +/* Адаптивность для мобильных устройств */ +@media (max-width: 768px) { + .recall-content { + flex-direction: column; + gap: 1.5rem; + } + + .recall-scan-container { + width: 100%; + max-width: 300px; + margin: 0 auto; + } + + .recall-scan-wrapper { + order: -1; + } + + .modal-image { + max-width: 95vw; + max-height: 70vh; + } + + .modal-content.image-modal { + margin: 10% auto; + } +} + +@media (max-width: 480px) { + .recall-scan-container { + max-width: 100%; + } + + .modal-content.image-modal { + margin: 5% auto; + max-width: 98vw; + } + + .modal-body.image-modal-body { + padding: 0.5rem; + } } \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/css/styles_w.css b/OneCprogsite/programmer/static/programmer/css/styles_w.css index 4c1eb3e..baa7f16 100644 --- a/OneCprogsite/programmer/static/programmer/css/styles_w.css +++ b/OneCprogsite/programmer/static/programmer/css/styles_w.css @@ -1265,4 +1265,142 @@ body { .mobile-menu .theme-icon.moon { color: #1A1F36 !important; +} + +/* Стили для страницы отзывов */ +.recall-item { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.recall-content { + display: flex; + gap: 2rem; + align-items: flex-start; +} + +.recall-scan-wrapper { + flex-shrink: 0; +} + +.recall-scan-container { + width: 280px; + cursor: pointer; + border-radius: var(--radius-lg); + overflow: hidden; + border: 2px solid var(--border-light); + transition: var(--transition); + position: relative; + box-shadow: var(--shadow-md); +} + +.recall-scan-container:hover { + transform: translateY(-4px) scale(1.02); + box-shadow: var(--shadow-xl); + border-color: var(--primary); +} + +.recall-scan { + width: 100%; + height: auto; + display: block; + transition: var(--transition); +} + +.recall-text { + flex: 1; + min-width: 0; + line-height: 1.7; + font-size: 1.05rem; +} + +.scan-hint { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(transparent, rgba(0,0,0,0.8)); + color: white; + padding: 1rem; + text-align: center; + opacity: 0; + transition: var(--transition); + transform: translateY(10px); +} + +.recall-scan-container:hover .scan-hint { + opacity: 1; + transform: translateY(0); +} + +/* Стили для модального окна с изображением */ +.modal-image { + max-width: 90vw; + max-height: 80vh; + width: auto; + height: auto; + display: block; + margin: 0 auto; + border-radius: var(--radius-md); + box-shadow: var(--shadow-xl); + transition: all 0.3s ease; +} + +.modal-content.image-modal { + max-width: 95vw; + max-height: 95vh; + background: transparent; + border: none; + box-shadow: none; +} + +.modal-body.image-modal-body { + padding: 1rem; + display: flex; + align-items: center; + justify-content: center; + background: transparent; +} + +/* Адаптивность для мобильных устройств */ +@media (max-width: 768px) { + .recall-content { + flex-direction: column; + gap: 1.5rem; + } + + .recall-scan-container { + width: 100%; + max-width: 300px; + margin: 0 auto; + } + + .recall-scan-wrapper { + order: -1; + } + + .modal-image { + max-width: 95vw; + max-height: 70vh; + } + + .modal-content.image-modal { + margin: 10% auto; + } +} + +@media (max-width: 480px) { + .recall-scan-container { + max-width: 100%; + } + + .modal-content.image-modal { + margin: 5% auto; + max-width: 98vw; + } + + .modal-body.image-modal-body { + padding: 0.5rem; + } } \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/js/competence.js b/OneCprogsite/programmer/static/programmer/js/competence.js new file mode 100644 index 0000000..48e126b --- /dev/null +++ b/OneCprogsite/programmer/static/programmer/js/competence.js @@ -0,0 +1,73 @@ +// competence.js - Скрипты для страницы компетенций +function openCompetenceModal(imageUrl, title) { + console.log('Opening competence modal with:', imageUrl); + const modal = document.getElementById('competenceModal'); + const modalImg = document.getElementById('competenceModalImage'); + const modalTitle = document.getElementById('competenceModalTitle'); + + if (modal && modalImg) { + modal.style.display = "block"; + modalImg.src = imageUrl; + if (title && modalTitle) { + modalTitle.textContent = title; + } + + // Добавляем класс для анимации + setTimeout(() => { + modal.classList.add('active'); + }, 10); + + // Подстраиваем размер изображения + adjustCompetenceModalImageSize(); + } +} + +function closeCompetenceModal() { + const modal = document.getElementById('competenceModal'); + if (modal) { + modal.classList.remove('active'); + setTimeout(() => { + modal.style.display = "none"; + }, 300); + } +} + +function adjustCompetenceModalImageSize() { + const modalImg = document.getElementById('competenceModalImage'); + + if (modalImg) { + const maxWidth = window.innerWidth * 0.9; + const maxHeight = window.innerHeight * 0.8; + + modalImg.style.maxWidth = `${maxWidth}px`; + modalImg.style.maxHeight = `${maxHeight}px`; + } +} + +// Инициализация после загрузки DOM +document.addEventListener('DOMContentLoaded', function() { + // Закрытие модального окна при клике вне изображения + document.addEventListener('click', function(event) { + const modal = document.getElementById('competenceModal'); + if (event.target === modal) { + closeCompetenceModal(); + } + }); + + // Закрытие по ESC + document.addEventListener('keydown', function(event) { + if (event.key === 'Escape') { + closeCompetenceModal(); + } + }); + + // Адаптация размера изображения при изменении размера окна + window.addEventListener('resize', function() { + const modalImg = document.getElementById('competenceModalImage'); + if (modalImg && modalImg.src) { + adjustCompetenceModalImageSize(); + } + }); + + console.log('Competence page scripts initialized'); +}); \ No newline at end of file diff --git a/OneCprogsite/programmer/static/programmer/js/recall.js b/OneCprogsite/programmer/static/programmer/js/recall.js new file mode 100644 index 0000000..b8f2c6e --- /dev/null +++ b/OneCprogsite/programmer/static/programmer/js/recall.js @@ -0,0 +1,74 @@ +// recall.js - Скрипты для страницы отзывов +function openModal(imageUrl, title) { + console.log('Opening modal with:', imageUrl); + const modal = document.getElementById('imageModal'); + const modalImg = document.getElementById('modalImage'); + const modalTitle = document.getElementById('modalTitle'); + + if (modal && modalImg) { + modal.style.display = "block"; + modalImg.src = imageUrl; + if (title && modalTitle) { + modalTitle.textContent = title; + } + + // Добавляем класс для анимации + setTimeout(() => { + modal.classList.add('active'); + }, 10); + + // Подстраиваем размер изображения + adjustModalImageSize(); + } +} + +function closeModal() { + const modal = document.getElementById('imageModal'); + if (modal) { + modal.classList.remove('active'); + setTimeout(() => { + modal.style.display = "none"; + }, 300); + } +} + +function adjustModalImageSize() { + const modalImg = document.getElementById('modalImage'); + const modalContent = document.querySelector('.modal-content'); + + if (modalImg && modalContent) { + const maxWidth = window.innerWidth * 0.9; + const maxHeight = window.innerHeight * 0.8; + + modalImg.style.maxWidth = `${maxWidth}px`; + modalImg.style.maxHeight = `${maxHeight}px`; + } +} + +// Инициализация после загрузки DOM +document.addEventListener('DOMContentLoaded', function() { + // Закрытие модального окна при клике вне изображения + document.addEventListener('click', function(event) { + const modal = document.getElementById('imageModal'); + if (event.target === modal) { + closeModal(); + } + }); + + // Закрытие по ESC + document.addEventListener('keydown', function(event) { + if (event.key === 'Escape') { + closeModal(); + } + }); + + // Адаптация размера изображения при изменении размера окна + window.addEventListener('resize', function() { + const modalImg = document.getElementById('modalImage'); + if (modalImg && modalImg.src) { + adjustModalImageSize(); + } + }); + + console.log('Recall page scripts initialized'); +}); \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/base.html b/OneCprogsite/programmer/templates/programmer/base.html index 6477bc2..681a68a 100644 --- a/OneCprogsite/programmer/templates/programmer/base.html +++ b/OneCprogsite/programmer/templates/programmer/base.html @@ -547,5 +547,9 @@ {% bootstrap_javascript %} + + {% block extra_js %} + + {% endblock %} \ No newline at end of file diff --git a/OneCprogsite/programmer/templates/programmer/competence.html b/OneCprogsite/programmer/templates/programmer/competence.html index a8fa6c5..707324d 100644 --- a/OneCprogsite/programmer/templates/programmer/competence.html +++ b/OneCprogsite/programmer/templates/programmer/competence.html @@ -1,5 +1,10 @@ {% extends 'programmer/base.html' %} {% load django_bootstrap5 %} +{% load static %} + +{% block extra_css %} + +{% endblock %} {% block content %}