add shared buttons in post
This commit is contained in:
@@ -3,45 +3,57 @@ import { getLatestColonPost } from '@lib/api/colon-posts';
|
|||||||
import Author from '@components/AuthorDisplay.astro';
|
import Author from '@components/AuthorDisplay.astro';
|
||||||
|
|
||||||
const colonPost = await getLatestColonPost();
|
const colonPost = await getLatestColonPost();
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
{colonPost && (
|
{colonPost && (
|
||||||
<div class="colon-post-card">
|
<div class="colon-post-card">
|
||||||
<div class="colon-post-content">
|
<div class="split-flex">
|
||||||
<div class="colon-post-left">
|
<!-- ЛЕВЫЙ БЛОК: 30% ширины, фото впритык -->
|
||||||
{colonPost.featuredImage?.node?.sourceUrl && (
|
<div class="left-photo">
|
||||||
<a href={colonPost.uri}>
|
{colonPost.featuredImage?.node?.sourceUrl ? (
|
||||||
|
<a href={colonPost.uri} class="photo-link">
|
||||||
<img
|
<img
|
||||||
src={colonPost.featuredImage.node.sourceUrl}
|
src={colonPost.featuredImage.node.sourceUrl}
|
||||||
alt={colonPost.featuredImage.node.altText || colonPost.secondaryTitle || colonPost.title}
|
alt={colonPost.featuredImage.node.altText || colonPost.secondaryTitle || colonPost.title}
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="colon-post-image"
|
class="photo-img"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
) : (
|
||||||
|
<div class="photo-placeholder"></div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="colon-post-meta">
|
|
||||||
<span>{new Date(colonPost.date).toLocaleDateString('ru-RU')}</span>
|
|
||||||
<div><Author post={colonPost} separator=", " /></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="colon-post-right">
|
<!-- ПРАВЫЙ БЛОК: 70% ширины, заголовок сверху, дата|автор снизу -->
|
||||||
<a href={colonPost.uri}>
|
<div class="right-content">
|
||||||
<h3>{colonPost.secondaryTitle || colonPost.title}</h3>
|
<div class="content-wrapper">
|
||||||
</a>
|
<!-- Заголовок жирным сверху -->
|
||||||
|
<a href={colonPost.uri} class="title-link">
|
||||||
|
<h3 class="bold-title">{colonPost.secondaryTitle || colonPost.title}</h3>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Мета-информация внизу: дата | автор -->
|
||||||
|
<div class="meta-line">
|
||||||
|
<span class="date">{new Date(colonPost.date).toLocaleDateString('ru-RU')}</span>
|
||||||
|
<span class="separator">|</span>
|
||||||
|
<span class="author"><Author post={colonPost} separator=", " /></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
/* Основная карточка */
|
||||||
.colon-post-card {
|
.colon-post-card {
|
||||||
background: white;
|
background: #ececec;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
||||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 800px; /* опционально, для демо */
|
||||||
|
height: 200px; /* фиксированная высота карточки */
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-card:hover {
|
.colon-post-card:hover {
|
||||||
@@ -49,137 +61,131 @@ const colonPost = await getLatestColonPost();
|
|||||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-content {
|
/* Flex-контейнер: две части */
|
||||||
|
.split-flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
height: 100%;
|
||||||
padding: 20px;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colon-post-left {
|
|
||||||
flex: 0 0 200px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colon-post-image-link {
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 6px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colon-post-image {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 150px;
|
|
||||||
object-fit: cover;
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-image:hover {
|
/* ЛЕВЫЙ БЛОК: ровно 30% */
|
||||||
transform: scale(1.05);
|
.left-photo {
|
||||||
}
|
flex: 0 0 34%; /* ширина 30%, не растягивается */
|
||||||
|
height: 100%;
|
||||||
.colon-post-image-placeholder {
|
background: #d4d4d4; /* фон, если нет фото */
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-link {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 150px;
|
height: 100%;
|
||||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|
||||||
border-radius: 6px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.placeholder-text {
|
.photo-img {
|
||||||
color: #666;
|
width: 100%;
|
||||||
font-size: 14px;
|
height: 100%;
|
||||||
|
object-fit: cover; /* заполняет контейнер, сохраняя пропорции и обрезаясь */
|
||||||
|
display: block;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-meta {
|
.photo-img:hover {
|
||||||
|
transform: scale(1.05); /* легкий эффект при наведении */
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ПРАВЫЙ БЛОК: 70% */
|
||||||
|
.right-content {
|
||||||
|
flex: 1; /* занимает оставшееся место (70%) */
|
||||||
|
height: 100%;
|
||||||
|
padding: 16px 20px; /* внутренние отступы */
|
||||||
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
font-size: 12px;
|
}
|
||||||
color: #666;
|
|
||||||
|
/* Обёртка для контента, чтобы занять всю высоту и распределить пространство */
|
||||||
|
.content-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Заголовок жирным */
|
||||||
|
.bold-title {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
font-weight: 700;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
transition: color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-date {
|
.title-link {
|
||||||
white-space: nowrap;
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-separator {
|
.title-link:hover .bold-title {
|
||||||
margin: 0 5px;
|
color: #3498db;
|
||||||
color: #ccc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-author {
|
/* Мета-строка: прижимаем к низу */
|
||||||
white-space: nowrap;
|
.meta-line {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #666;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-top: auto; /* это прижимает мету к низу */
|
||||||
}
|
}
|
||||||
|
|
||||||
.author-link {
|
.separator {
|
||||||
|
color: #aaa;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author :global(a) {
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.author-link:hover {
|
.author :global(a:hover) {
|
||||||
color: #3498db;
|
color: #3498db;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-right {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colon-post-title-link {
|
|
||||||
text-decoration: none;
|
|
||||||
color: inherit;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colon-post-title {
|
|
||||||
margin: 0 0 10px 0;
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: 1.4;
|
|
||||||
color: #2c3e50;
|
|
||||||
transition: color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colon-post-title:hover {
|
|
||||||
color: #3498db;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colon-post-secondary-title {
|
|
||||||
font-size: 16px;
|
|
||||||
color: #666;
|
|
||||||
line-height: 1.5;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Адаптивность */
|
/* Адаптивность */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 600px) {
|
||||||
.colon-post-content {
|
.colon-post-card {
|
||||||
flex-direction: column;
|
height: auto;
|
||||||
gap: 15px;
|
min-height: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-left {
|
.left-photo {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 30%;
|
||||||
width: 100%;
|
aspect-ratio: 1 / 1; /* сохраняем квадрат на мобильных */
|
||||||
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-image,
|
.right-content {
|
||||||
.colon-post-image-placeholder {
|
padding: 12px 16px;
|
||||||
height: 200px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.colon-post-title {
|
.bold-title {
|
||||||
font-size: 18px;
|
font-size: 1.1rem;
|
||||||
}
|
|
||||||
|
|
||||||
.colon-post-secondary-title {
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Если нужно точное соответствие макету, можно добавить медиа-запросы под свои нужды */
|
||||||
</style>
|
</style>
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
import { getLatestAnews } from '../lib/api/posts.js';
|
import { getLatestAnews } from '../lib/api/posts.js';
|
||||||
import { fetchWPRestGet } from "@/lib/api/wp-rest-get-client";
|
import { fetchWPRestGet } from "@/lib/api/wp-rest-get-client";
|
||||||
|
|
||||||
|
|
||||||
// Даты/время
|
// Даты/время
|
||||||
function formatDate(dateString: string): string {
|
function formatDate(dateString: string): string {
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
@@ -51,118 +50,129 @@ const hasNews = newsPosts.length > 0;
|
|||||||
const hasTop = topPosts.length > 0;
|
const hasTop = topPosts.length > 0;
|
||||||
|
|
||||||
// По умолчанию открываем вкладку, где есть данные
|
// По умолчанию открываем вкладку, где есть данные
|
||||||
const defaultTab: "news" | "top" = hasTop ? "top" : "news";
|
const defaultTab: "news" | "top" = hasNews ? "news" : "top";
|
||||||
---
|
---
|
||||||
|
|
||||||
{(hasNews || hasTop) && (
|
{(hasNews || hasTop) && (
|
||||||
<div class="endnews-container">
|
<div class="endnews-container" id="endnews-container">
|
||||||
<div class="endnews-header">
|
{/* Табы на всю ширину, каждый по 50% - теперь div'ы */}
|
||||||
<h4 class="endnews-title">Новости</h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Radio-кнопки ВНЕ .endnews-tabs для работы CSS-селекторов */}
|
|
||||||
<input
|
|
||||||
class="endnews-tab-input"
|
|
||||||
type="radio"
|
|
||||||
name="endnews-tab"
|
|
||||||
id="endnews-tab-news"
|
|
||||||
checked={defaultTab === "news"}
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
class="endnews-tab-input"
|
|
||||||
type="radio"
|
|
||||||
name="endnews-tab"
|
|
||||||
id="endnews-tab-top"
|
|
||||||
checked={defaultTab === "top"}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Только labels в блоке табов */}
|
|
||||||
<div class="endnews-tabs">
|
<div class="endnews-tabs">
|
||||||
<label class="endnews-tab-label" for="endnews-tab-news">Новости</label>
|
<div class={`endnews-tab-label ${defaultTab === 'news' ? 'active' : ''}`} data-tab="news">Новости</div>
|
||||||
<label class="endnews-tab-label" for="endnews-tab-top">Топ‑10</label>
|
<div class={`endnews-tab-label ${defaultTab === 'top' ? 'active' : ''}`} data-tab="top">Топ‑10</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Контент: две панели, показываем нужную через :checked */}
|
{/* Контент: две панели */}
|
||||||
<div class="latestnews-list">
|
<div class="latestnews-list">
|
||||||
<section class="endnews-panel endnews-panel--news" aria-label="Новости">
|
<section class={`endnews-panel endnews-panel--news ${defaultTab === 'news' ? 'active' : ''}`} aria-label="Новости">
|
||||||
{Object.entries(groupedNews).map(([dateKey, datePosts]) => (
|
{Object.entries(groupedNews).map(([dateKey, datePosts]) => (
|
||||||
<div class="latestnews-date-group" key={dateKey}>
|
<div class="latestnews-date-group" key={dateKey}>
|
||||||
<div class="latestnews-date">{formatDate(dateKey + 'T00:00:00')}</div>
|
<div class="latestnews-date">{formatDate(dateKey + 'T00:00:00')}</div>
|
||||||
|
|
||||||
{datePosts.map((post) => (
|
{/* Переделано в ul > li */}
|
||||||
<article class="lastnews-item" key={post.uri}>
|
<ul class="latestnews-items">
|
||||||
<div class="lastnews-time">{formatTime(post.date)}</div>
|
{datePosts.map((post) => (
|
||||||
<div class="lastnews-content">
|
<li class="lastnews-item" key={post.uri}>
|
||||||
<a href={post.uri || '#'} class="endnews-link">
|
<div class="lastnews-time">{formatTime(post.date)}</div>
|
||||||
{post.title}
|
<div class="lastnews-content">
|
||||||
</a>
|
<a href={post.uri || '#'} class="endnews-link">
|
||||||
</div>
|
{post.title}
|
||||||
</article>
|
</a>
|
||||||
))}
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="endnews-panel endnews-panel--top" aria-label="Топ-10">
|
<section class={`endnews-panel endnews-panel--top ${defaultTab === 'top' ? 'active' : ''}`} aria-label="Топ-10">
|
||||||
{topPosts.map((post, i) => (
|
{topPosts.length > 0 ? (
|
||||||
<article class="lastnews-item" key={(post.uri ?? post.link ?? post.title) + i}>
|
<ul class="latestnews-items top-items">
|
||||||
<div class="ltopnews-content">
|
{topPosts.map((post, i) => (
|
||||||
<a href={post.uri ?? post.link ?? '#'} class="endnews-link">
|
<li class="lastnews-item top-item" key={(post.uri ?? post.link ?? post.title) + i}>
|
||||||
{post.title}
|
<div class="lastnews-content">
|
||||||
</a>
|
<a href={post.uri ?? post.link ?? '#'} class="endnews-link">
|
||||||
</div>
|
{post.title}
|
||||||
</article>
|
</a>
|
||||||
))}
|
</div>
|
||||||
|
</li>
|
||||||
{!hasTop && <div class="endnews-empty">Топ пока пуст</div>}
|
))}
|
||||||
|
</ul>
|
||||||
|
) : (
|
||||||
|
<div class="endnews-empty">Топ пока пуст</div>
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const container = document.getElementById('endnews-container');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const tabs = container.querySelectorAll('.endnews-tab-label');
|
||||||
|
const panels = {
|
||||||
|
news: container.querySelector('.endnews-panel--news'),
|
||||||
|
top: container.querySelector('.endnews-panel--top')
|
||||||
|
};
|
||||||
|
|
||||||
|
tabs.forEach(tab => {
|
||||||
|
tab.addEventListener('click', () => {
|
||||||
|
const tabName = tab.dataset.tab;
|
||||||
|
|
||||||
|
// Обновляем классы на табах
|
||||||
|
tabs.forEach(t => t.classList.remove('active'));
|
||||||
|
tab.classList.add('active');
|
||||||
|
|
||||||
|
// Обновляем классы на панелях
|
||||||
|
Object.values(panels).forEach(panel => {
|
||||||
|
if (panel) panel.classList.remove('active');
|
||||||
|
});
|
||||||
|
if (panels[tabName]) panels[tabName].classList.add('active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.endnews-container { width:100%; }
|
.endnews-container { width:100%; }
|
||||||
|
|
||||||
.endnews-header{
|
/* Tabs на всю ширину */
|
||||||
padding:12px 16px;
|
|
||||||
background:#B61D1D;
|
|
||||||
border-radius:6px 6px 0 0;
|
|
||||||
}
|
|
||||||
.endnews-title{ color:#fff; margin:0; font-size:1.1rem; font-weight:600; }
|
|
||||||
|
|
||||||
/* Скрываем radio-кнопки */
|
|
||||||
.endnews-tab-input{
|
|
||||||
position:absolute;
|
|
||||||
opacity:0;
|
|
||||||
pointer-events:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tabs */
|
|
||||||
.endnews-tabs{
|
.endnews-tabs{
|
||||||
display:flex;
|
display:flex;
|
||||||
gap:8px;
|
width:100%;
|
||||||
padding:10px 12px;
|
background: #ECECEC;
|
||||||
border:1px solid #ECECEC;
|
border-radius: 6px 6px 0 0;
|
||||||
border-top:none;
|
overflow: hidden;
|
||||||
background:#fff;
|
|
||||||
}
|
|
||||||
.endnews-tab-label{
|
|
||||||
cursor:pointer;
|
|
||||||
user-select:none;
|
|
||||||
font-size:0.85rem;
|
|
||||||
font-weight:700;
|
|
||||||
padding:8px 10px;
|
|
||||||
border-radius:6px;
|
|
||||||
background:#f5f5f5;
|
|
||||||
color:#505258;
|
|
||||||
transition: background 0.2s, color 0.2s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Активный таб - используем общий сиблинг-селектор */
|
.endnews-tab-label{
|
||||||
#endnews-tab-news:checked ~ .endnews-tabs label[for="endnews-tab-news"],
|
flex: 1 1 0;
|
||||||
#endnews-tab-top:checked ~ .endnews-tabs label[for="endnews-tab-top"]{
|
width: 50%;
|
||||||
background:#B61D1D;
|
min-width: 50%;
|
||||||
color:#fff;
|
max-width: 50%;
|
||||||
|
cursor:pointer;
|
||||||
|
user-select:none;
|
||||||
|
font-size:0.95rem;
|
||||||
|
font-weight:400;
|
||||||
|
padding:12px 10px;
|
||||||
|
text-align: center;
|
||||||
|
background: #ECECEC;
|
||||||
|
color: #BFBFBF;
|
||||||
|
transition: background 0.2s, color 0.2s, font-weight 0.2s, border 0.2s;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Активный таб - черный жирный на белом фоне */
|
||||||
|
.endnews-tab-label.active{
|
||||||
|
background: #FFFFFF;
|
||||||
|
color: #000000;
|
||||||
|
font-weight: 700;
|
||||||
|
border: 1px solid #ECECEC;
|
||||||
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* list container */
|
/* list container */
|
||||||
@@ -171,17 +181,40 @@ const defaultTab: "news" | "top" = hasTop ? "top" : "news";
|
|||||||
border-top:none;
|
border-top:none;
|
||||||
border-radius:0 0 6px 6px;
|
border-radius:0 0 6px 6px;
|
||||||
background:#fff;
|
background:#fff;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
scrollbar-width: none;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Скрываем скроллбар */
|
||||||
|
.latestnews-list::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Панели скрыты по умолчанию */
|
/* Панели скрыты по умолчанию */
|
||||||
.endnews-panel{ display:none; }
|
.endnews-panel{ display:none; }
|
||||||
|
|
||||||
/* Показываем нужную панель по выбранному radio */
|
/* Показываем активную панель */
|
||||||
#endnews-tab-news:checked ~ .latestnews-list .endnews-panel--news{ display:block; }
|
.endnews-panel.active{ display:block; }
|
||||||
#endnews-tab-top:checked ~ .latestnews-list .endnews-panel--top { display:block; }
|
|
||||||
|
|
||||||
/* Существующий стиль списка */
|
/* Стили для списка */
|
||||||
.latestnews-date-group{ padding:12px 16px; border-bottom:1px solid #f0f0f0; }
|
.latestnews-items {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.latestnews-items li{
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
line-height: 1.2;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.latestnews-date-group{
|
||||||
|
padding:12px 16px;
|
||||||
|
border-bottom:1px solid #f0f0f0;
|
||||||
|
}
|
||||||
.latestnews-date-group:last-child{ border-bottom:none; }
|
.latestnews-date-group:last-child{ border-bottom:none; }
|
||||||
|
|
||||||
.latestnews-date{
|
.latestnews-date{
|
||||||
@@ -212,6 +245,46 @@ const defaultTab: "news" | "top" = hasTop ? "top" : "news";
|
|||||||
margin-top:1px;
|
margin-top:1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Стили для топ-новостей */
|
||||||
|
.top-items {
|
||||||
|
padding: 8px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-item {
|
||||||
|
position: relative;
|
||||||
|
padding: 10px 0 10px 16px;
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-item::before {
|
||||||
|
content: '';
|
||||||
|
background: #b51d1d;
|
||||||
|
width: 3px;
|
||||||
|
height: 20px;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
-webkit-transform: translate(0, -50%);
|
||||||
|
-ms-transform: translate(0,-50%);
|
||||||
|
transform: translate(0, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-item .lastnews-content {
|
||||||
|
margin-left: 0;
|
||||||
|
padding-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lastnews-time-top{
|
||||||
|
min-width:2.5rem;
|
||||||
|
flex-shrink:0;
|
||||||
|
}
|
||||||
|
|
||||||
.lastnews-content{
|
.lastnews-content{
|
||||||
line-height:1.3;
|
line-height:1.3;
|
||||||
font-weight:500;
|
font-weight:500;
|
||||||
@@ -221,18 +294,6 @@ const defaultTab: "news" | "top" = hasTop ? "top" : "news";
|
|||||||
flex:1;
|
flex:1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topnews-content{
|
|
||||||
|
|
||||||
line-height:1.3;
|
|
||||||
font-weight:500;
|
|
||||||
font-size:0.9em;
|
|
||||||
color:#000;
|
|
||||||
transition:color 0.2s;
|
|
||||||
margin-left: 4px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.endnews-link{ color:inherit; text-decoration:none; display:block; }
|
.endnews-link{ color:inherit; text-decoration:none; display:block; }
|
||||||
.endnews-link:hover{ color:#B61D1D; }
|
.endnews-link:hover{ color:#B61D1D; }
|
||||||
|
|
||||||
@@ -244,14 +305,36 @@ const defaultTab: "news" | "top" = hasTop ? "top" : "news";
|
|||||||
}
|
}
|
||||||
.endnews-empty{ padding:12px 16px; color:#6b6d72; font-size:0.85rem; }
|
.endnews-empty{ padding:12px 16px; color:#6b6d72; font-size:0.85rem; }
|
||||||
|
|
||||||
/* Десктоп скролл */
|
/* Десктоп версия */
|
||||||
@media (min-width:1024px){
|
@media (min-width:1024px){
|
||||||
.endnews-container{ height:500px; display:flex; flex-direction:column; }
|
.endnews-container{ height:500px; display:flex; flex-direction:column; }
|
||||||
.latestnews-list{ flex:1; overflow-y:auto; overflow-x:hidden; }
|
.latestnews-list{ flex:1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Мобильная версия */
|
||||||
@media (max-width:1023px){
|
@media (max-width:1023px){
|
||||||
.endnews-container{ height:auto; }
|
.endnews-container{ height:auto; }
|
||||||
.latestnews-list{ overflow:visible; }
|
.latestnews-list{ overflow:visible; }
|
||||||
|
|
||||||
|
/* Скрываем вкладку Топ-10 на мобильных */
|
||||||
|
.endnews-tab-label[data-tab="top"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Оставляем только вкладку Новости на всю ширину */
|
||||||
|
.endnews-tab-label[data-tab="news"] {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* На мобильных всегда показываем панель новостей */
|
||||||
|
.endnews-panel--top {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.endnews-panel--news {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -17,24 +17,41 @@ if (!menu) {
|
|||||||
---
|
---
|
||||||
|
|
||||||
<nav class="primary-nav" aria-label="Main navigation">
|
<nav class="primary-nav" aria-label="Main navigation">
|
||||||
<div class="primary-nav__content">
|
<div class="primary-nav__wrapper">
|
||||||
<button class="primary-nav__burger" aria-label="Toggle menu"></button>
|
<div class="primary-nav__content">
|
||||||
<ul class="primary-nav__list">
|
|
||||||
{menu.menuItems.nodes.map(item => {
|
<button class="primary-nav__burger" aria-label="Toggle menu"></button>
|
||||||
const colorClass = item.menuItemColor ? `color-${item.menuItemColor}` : 'color-black';
|
|
||||||
return (
|
<!-- Логотип для фиксированного меню -->
|
||||||
<li class="primary-nav__item" key={item.id}>
|
<div class="primary-nav__logo-scroll">
|
||||||
<a
|
<a href="/" aria-label="На главную">
|
||||||
href={item.url}
|
<img
|
||||||
class={`primary-nav__link ${colorClass}`}
|
alt="Профиль"
|
||||||
target={item.target || '_self'}
|
width="120"
|
||||||
>
|
height="27"
|
||||||
{item.label}
|
src="https://cdn.profile.ru/wp-content/themes/profile/assets/img/profile-logo-delovoy.svg"
|
||||||
</a>
|
class="primary-nav__logo-image"
|
||||||
</li>
|
/>
|
||||||
);
|
</a>
|
||||||
})}
|
</div>
|
||||||
</ul>
|
|
||||||
|
<ul class="primary-nav__list">
|
||||||
|
{menu.menuItems.nodes.map(item => {
|
||||||
|
const colorClass = item.menuItemColor ? `color-${item.menuItemColor}` : 'color-black';
|
||||||
|
return (
|
||||||
|
<li class="primary-nav__item" key={item.id}>
|
||||||
|
<a
|
||||||
|
href={item.url}
|
||||||
|
class={`primary-nav__link ${colorClass}`}
|
||||||
|
target={item.target || '_self'}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@@ -43,16 +60,88 @@ if (!menu) {
|
|||||||
<style>
|
<style>
|
||||||
.primary-nav {
|
.primary-nav {
|
||||||
margin: 12px 0;
|
margin: 12px 0;
|
||||||
position: relative;
|
|
||||||
border-top: 1px solid black;
|
border-top: 1px solid black;
|
||||||
border-bottom: 1px solid black;
|
border-bottom: 1px solid black;
|
||||||
|
background-color: white;
|
||||||
|
width: 100%;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Стили только для десктопа */
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.primary-nav.fixed {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Добавляем отступ для контента, когда меню фиксированное */
|
||||||
|
.primary-nav.fixed + * {
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Обертка для центрирования контента */
|
||||||
|
.primary-nav__wrapper {
|
||||||
|
width: 100%;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* При фиксированном меню обертка тоже фиксируется */
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.primary-nav.fixed .primary-nav__wrapper {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 20px; /* Добавляем отступы по бокам */
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-nav__content {
|
.primary-nav__content {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: stretch;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 48px;
|
min-height: 48px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Для десктопа добавляем ограничение ширины */
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.primary-nav__content {
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Стили для логотипа, появляющегося при скролле */
|
||||||
|
.primary-nav__logo-scroll {
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
margin-right: 20px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Показываем логотип только когда меню фиксированное и на десктопе */
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.primary-nav.fixed .primary-nav__logo-scroll {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 1;
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary-nav__logo-image {
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
height: 27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-nav__burger {
|
.primary-nav__burger {
|
||||||
@@ -112,3 +201,89 @@ if (!menu) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const primaryNav = document.querySelector('.primary-nav');
|
||||||
|
const header = document.querySelector('.header');
|
||||||
|
|
||||||
|
if (!primaryNav || !header) return;
|
||||||
|
|
||||||
|
// Проверяем, что это десктоп
|
||||||
|
let isDesktop = window.innerWidth >= 768;
|
||||||
|
|
||||||
|
// Убираем ранний return, чтобы эффект мог включаться/выключаться при ресайзе
|
||||||
|
|
||||||
|
// Создаем плейсхолдер для сохранения места при фиксированном меню
|
||||||
|
const placeholder = document.createElement('div');
|
||||||
|
placeholder.className = 'primary-nav-placeholder';
|
||||||
|
placeholder.style.display = 'none';
|
||||||
|
placeholder.style.height = primaryNav.offsetHeight + 'px';
|
||||||
|
placeholder.style.width = '100%';
|
||||||
|
placeholder.style.backgroundColor = 'transparent';
|
||||||
|
|
||||||
|
// Вставляем плейсхолдер после меню
|
||||||
|
if (primaryNav.parentNode) {
|
||||||
|
primaryNav.parentNode.insertBefore(placeholder, primaryNav.nextSibling);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleScroll() {
|
||||||
|
// Применяем эффект только на десктопе
|
||||||
|
if (!isDesktop) return;
|
||||||
|
|
||||||
|
const topBar = document.querySelector('.top-bar');
|
||||||
|
if (!topBar) return;
|
||||||
|
|
||||||
|
const topBarHeight = topBar.offsetHeight;
|
||||||
|
const scrollPosition = window.scrollY;
|
||||||
|
|
||||||
|
if (scrollPosition > topBarHeight) {
|
||||||
|
if (!primaryNav.classList.contains('fixed')) {
|
||||||
|
primaryNav.classList.add('fixed');
|
||||||
|
if (placeholder.parentNode) {
|
||||||
|
placeholder.style.display = 'block';
|
||||||
|
// Обновляем высоту плейсхолдера
|
||||||
|
placeholder.style.height = primaryNav.offsetHeight + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (primaryNav.classList.contains('fixed')) {
|
||||||
|
primaryNav.classList.remove('fixed');
|
||||||
|
if (placeholder.parentNode) {
|
||||||
|
placeholder.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', handleScroll);
|
||||||
|
|
||||||
|
// Вызываем сразу для правильного начального состояния
|
||||||
|
handleScroll();
|
||||||
|
|
||||||
|
// Обновляем при изменении размера окна
|
||||||
|
window.addEventListener('resize', function() {
|
||||||
|
const newIsDesktop = window.innerWidth >= 768;
|
||||||
|
|
||||||
|
if (newIsDesktop !== isDesktop) {
|
||||||
|
isDesktop = newIsDesktop;
|
||||||
|
if (!isDesktop) {
|
||||||
|
// Стали мобильным - убираем эффект
|
||||||
|
primaryNav.classList.remove('fixed');
|
||||||
|
if (placeholder.parentNode) {
|
||||||
|
placeholder.style.display = 'none';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Стали десктопом - проверяем скролл
|
||||||
|
handleScroll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (primaryNav.classList.contains('fixed')) {
|
||||||
|
placeholder.style.height = primaryNav.offsetHeight + 'px';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
@@ -136,7 +136,7 @@ const formattedDate = postDate.toLocaleDateString('ru-RU', {
|
|||||||
left: 16px;
|
left: 16px;
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 0.75rem;
|
font-size: 0.625rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
@@ -164,7 +164,7 @@ const formattedDate = postDate.toLocaleDateString('ru-RU', {
|
|||||||
|
|
||||||
.title-overlay {
|
.title-overlay {
|
||||||
margin: 0 0 12px 0;
|
margin: 0 0 12px 0;
|
||||||
font-size: 1.5rem;
|
font-size: 1.4rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,6 @@ const formattedDate = postDate.toLocaleDateString('ru-RU', {
|
|||||||
.author-overlay {
|
.author-overlay {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
font-style: italic;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Адаптивность */
|
/* Адаптивность */
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
---
|
---
|
||||||
|
import { stripHtml } from '@/utils/htmlhelpers';
|
||||||
|
import Author from '@components/AuthorDisplay.astro';
|
||||||
|
import Subscribe from '@components/SubscribePost.astro';
|
||||||
|
import ShareButtons from '@components/ShareButtons.astro';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
post: any;
|
post: any;
|
||||||
@@ -6,18 +10,114 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { post, pageInfo } = Astro.props;
|
const { post, pageInfo } = Astro.props;
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
{post ? (
|
{post ? (
|
||||||
<article class="news-single">
|
<div class="article-wrapper">
|
||||||
<h1>{post.title}</h1>
|
<article class="news-single">
|
||||||
<div class="meta">
|
<div class="article_info">
|
||||||
{post.date && <time>{new Date(post.date).toLocaleDateString('ru-RU')}</time>}
|
<div class="publication__data">{post.date && <time>{new Date(post.date).toLocaleDateString('ru-RU')}</time>}</div>
|
||||||
</div>
|
<span class="author"><Author post={post} separator=", " /></span>
|
||||||
{post.content && <div set:html={post.content} />}
|
</div>
|
||||||
</article>
|
<h1>{post.title}</h1>
|
||||||
|
{post.secondaryTitle && <p class="secondary-title">{post.secondaryTitle}</p>}
|
||||||
|
|
||||||
|
{post.featuredImage?.node?.sourceUrl && (
|
||||||
|
<figure class="featured-image">
|
||||||
|
<img
|
||||||
|
src={post.featuredImage.node.sourceUrl}
|
||||||
|
alt={post.featuredImage.node.altText || post.title}
|
||||||
|
width={post.featuredImage.node.mediaDetails?.width || 1200}
|
||||||
|
height={post.featuredImage.node.mediaDetails?.height || 675}
|
||||||
|
loading="eager"
|
||||||
|
class="post-image"
|
||||||
|
/>
|
||||||
|
{(post.featuredImage.node.description || post.featuredImage.node.caption) && (
|
||||||
|
<figcaption class="image-caption">
|
||||||
|
{post.featuredImage.node.description && (
|
||||||
|
<p>{stripHtml(post.featuredImage.node.description)}</p>
|
||||||
|
)}
|
||||||
|
{post.featuredImage.node.caption && (
|
||||||
|
<span>©{stripHtml(post.featuredImage.node.caption)}</span>
|
||||||
|
)}
|
||||||
|
</figcaption>
|
||||||
|
)}
|
||||||
|
</figure>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{post.content && <div set:html={post.content} />}
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<ShareButtons url={post.uri} title={post.title} />
|
||||||
|
|
||||||
|
<Subscribe />
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>Новость не найдена</div>
|
<div>Новость не найдена</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.article-wrapper {
|
||||||
|
position: relative;
|
||||||
|
max-width: 75%;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-single h1{
|
||||||
|
font-size: 2.375rem;
|
||||||
|
line-height: 1.2;
|
||||||
|
margin: 0 0 0.625rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondary-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
color: #666;
|
||||||
|
margin: 0.5rem 0 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article_info{
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publication__data::after{
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
height: 12px;
|
||||||
|
margin-top: -6px;
|
||||||
|
border-left: 1px solid grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featured-image {
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-image {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
border-radius: 8px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-caption {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #666;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-caption p {
|
||||||
|
margin: 0 0 0.25rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-caption span {
|
||||||
|
font-style: italic;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
10
src/components/SubscribePost.astro
Normal file
10
src/components/SubscribePost.astro
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
<div class="clearfix">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Читайте на смартфоне наши Telegram-каналы: <a href="https://t.me/profile_newzzz/" target="_blank">Профиль-News</a>, и <a href="https://t.me/profilejournal" target="_blank">журнал Профиль</a>. Скачивайте полностью <a href="https://profile.ru/mobilnye-prilozheniya/" target="_blank">бесплатное мобильное</a> приложение журнала "Профиль".
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
const { title, description } = Astro.props;
|
const { title, description } = Astro.props;
|
||||||
|
|
||||||
import Header from '../components/Header/Header.astro';
|
import Header from '../components/Header/Header.astro';
|
||||||
|
import Header_lite from '../components/Header/Header_lite.astro';
|
||||||
import CurrentDate from '../components/Header/CurrentDate.astro';
|
import CurrentDate from '../components/Header/CurrentDate.astro';
|
||||||
import Footer from '../components/Footer.astro';
|
import Footer from '../components/Footer.astro';
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ import '../styles/global.css';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Footer
|
<Footer
|
||||||
publicationName="ТехноВестник"
|
publicationName="Профиль"
|
||||||
organization="Учредитель: ИДР. Все права защищены."
|
organization="Учредитель: ИДР. Все права защищены."
|
||||||
menuItems={[
|
menuItems={[
|
||||||
{ text: "О нас", url: "/about" },
|
{ text: "О нас", url: "/about" },
|
||||||
@@ -47,11 +48,3 @@ import '../styles/global.css';
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
main {
|
|
||||||
width:100%;
|
|
||||||
max-width: 1024px;
|
|
||||||
margin:auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -137,6 +137,7 @@ export async function getProfileArticleById(databaseId) {
|
|||||||
id
|
id
|
||||||
databaseId
|
databaseId
|
||||||
title
|
title
|
||||||
|
secondaryTitle
|
||||||
content
|
content
|
||||||
excerpt
|
excerpt
|
||||||
uri
|
uri
|
||||||
@@ -150,6 +151,7 @@ export async function getProfileArticleById(databaseId) {
|
|||||||
sourceUrl
|
sourceUrl
|
||||||
altText
|
altText
|
||||||
caption
|
caption
|
||||||
|
description
|
||||||
mediaDetails {
|
mediaDetails {
|
||||||
width
|
width
|
||||||
height
|
height
|
||||||
@@ -169,6 +171,15 @@ export async function getProfileArticleById(databaseId) {
|
|||||||
uri
|
uri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# Соавторы как массив
|
||||||
|
coauthors {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
url
|
||||||
|
description
|
||||||
|
}
|
||||||
categories {
|
categories {
|
||||||
nodes {
|
nodes {
|
||||||
id
|
id
|
||||||
@@ -195,7 +206,6 @@ export async function getProfileArticleById(databaseId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Получить Anews пост по databaseId
|
* Получить Anews пост по databaseId
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ if (pageInfo.type === 'single') { //одиночная статья
|
|||||||
description="Информационное агентство Деловой журнал Профиль"
|
description="Информационное агентство Деловой журнал Профиль"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|
||||||
{pageInfo.type === 'single' && article ? (
|
{pageInfo.type === 'single' && article ? (
|
||||||
<NewsSingle post={article} pageInfo={pageInfo} />
|
<NewsSingle post={article} pageInfo={pageInfo} />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ a {
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
|
|||||||
30
src/utils/htmlhelpers.ts
Normal file
30
src/utils/htmlhelpers.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Удаляет HTML-теги и декодирует HTML-сущности
|
||||||
|
*/
|
||||||
|
export function stripHtml(html: string): string {
|
||||||
|
if (!html) return '';
|
||||||
|
return html
|
||||||
|
.replace(/<[^>]*>/g, '')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, "'")
|
||||||
|
.replace(/'/g, "'")
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/ /g, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Только декодирует HTML-сущности, не удаляет теги
|
||||||
|
*/
|
||||||
|
export function decodeHtmlEntities(text: string): string {
|
||||||
|
if (!text) return '';
|
||||||
|
return text
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, "'")
|
||||||
|
.replace(/'/g, "'")
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/ /g, ' ');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user