Compare commits

..

1 Commits

Author SHA1 Message Date
DeCentN2Madness abd2aab752 feat(library): restore live-site intro copy above post listings
- add the two missing Library introduction paragraphs between the hero and article grid
- match the live `/library` page structure without changing the shared library layout
- keep the existing sidebar and card listing behavior intact
2026-06-11 14:28:24 -07:00
4 changed files with 34 additions and 76 deletions
+1 -21
View File
@@ -1,5 +1,4 @@
--- ---
import LikeViewCounter from './LikeViewCounter.astro';
const { post, prefix = '' } = Astro.props; const { post, prefix = '' } = Astro.props;
const href = `${prefix}/library/${post.data.slug}`.replace('//', '/'); const href = `${prefix}/library/${post.data.slug}`.replace('//', '/');
const readMore = { en: 'Read More', es: 'Leer Más', ar: 'اقرأ المزيد' }[post.data.lang] || 'Read More'; const readMore = { en: 'Read More', es: 'Leer Más', ar: 'اقرأ المزيد' }[post.data.lang] || 'Read More';
@@ -10,31 +9,12 @@ const readMore = { en: 'Read More', es: 'Leer Más', ar: 'اقرأ المزيد'
<div class="blog-card-meta"><img src="/assets/images/rula-diab-avatar.jpg" alt="" /><p>Rula Diab, Clinical Director, M.Ed, BCBA, LBA<br /><time datetime={post.data.date.toISOString()}>{post.data.date.toLocaleDateString(post.data.lang, { day: 'numeric', month: 'long', year: 'numeric' })}</time></p></div> <div class="blog-card-meta"><img src="/assets/images/rula-diab-avatar.jpg" alt="" /><p>Rula Diab, Clinical Director, M.Ed, BCBA, LBA<br /><time datetime={post.data.date.toISOString()}>{post.data.date.toLocaleDateString(post.data.lang, { day: 'numeric', month: 'long', year: 'numeric' })}</time></p></div>
<h3><a href={href}>{post.data.title}</a></h3> <h3><a href={href}>{post.data.title}</a></h3>
<p>{post.data.description}</p> <p>{post.data.description}</p>
<div class="blog-card-footer" style="align-items:center;display:flex;justify-content:space-between;gap:var(--space-lg);margin-top:auto;">
<a class="text-link" href={href}>{readMore}</a> <a class="text-link" href={href}>{readMore}</a>
<LikeViewCounter slug={post.data.slug} />
</div>
</div> </div>
</article> </article>
<style> <style>
.blog-card-meta { align-items: center; display: flex; font-size: .78rem; gap: .75rem; } .blog-card-meta { align-items: center; display: flex; font-size: .78rem; gap: .75rem; }
.blog-card-meta img { aspect-ratio: 1; border-radius: 50%; height: 42px; width: 42px; } .blog-card-meta img { aspect-ratio: 1; border-radius: 50%; height: 42px; width: 42px; }
.blog-card { background: white; border: 0; border-radius: 4px; box-shadow: rgba(54, 48, 48, 0.28) 0 0 12px 0; display: flex; margin-bottom: 40px; overflow: hidden; } .blog-card h3 { font-size: 1.35rem; }
.blog-card > a { flex: 0 0 232px; display: block; margin: .75rem; }
.blog-card > a img { aspect-ratio: auto; display: block; height: 100%; object-fit: cover; width: 100%; }
.blog-card .card-body { display: flex; flex: 1; flex-direction: column; gap: 0; padding: 20px; }
.blog-card .card-body h3 { font-family: var(--font-body); }
.blog-card-footer { align-items: center; display: flex; justify-content: space-between; gap: var(--space-lg); margin-top: auto; }
:global(.blog-card .like-view-counter) { border-top: 0; justify-content: space-between; margin-block: 0; padding-top: 0; width: auto; }
.blog-card h3 { font-size: 1.35rem; margin-bottom: 1rem; }
.blog-card p { margin-bottom: 1rem; }
.blog-card .text-link { margin: 0; }
@media (max-width: 760px) {
.blog-card { flex-direction: column; }
.blog-card > a { flex-basis: auto; }
.blog-card > a img { height: auto; aspect-ratio: 4 / 3; }
.blog-card-footer { align-items: flex-start; flex-direction: column; }
}
</style> </style>
+7 -24
View File
@@ -1,16 +1,11 @@
--- ---
const { slug } = Astro.props; const { slug } = Astro.props;
--- ---
<div class="like-view-counter" data-counter> <div class="like-view-counter likes-views" data-counter>
<span aria-label="Article views"><span class="view-count" data-views>0</span> views</span>
<span class="like-group">
<span class="like-count" data-likes>—</span>
<button class="like-button" type="button" data-like data-slug={slug} aria-label="Like this article" aria-pressed="false"> <button class="like-button" type="button" data-like data-slug={slug} aria-label="Like this article" aria-pressed="false">
<svg aria-hidden="true" viewBox="0 0 12 10" width="20" height="20" focusable="false" class="like-icon"> <span aria-hidden="true">♡</span> <span class="like-count" data-likes>—</span>
<path d="m1 4.4c-1-4 2.5-5 4.5-2.5l.5 .6l.5-.6c2-2.5 6-1.5 4.5 2.5q-1 3-5 5q-4-2-5-5z"></path>
</svg>
</button> </button>
</span> <span aria-label="Article views">Views: <span class="view-count" data-views>—</span></span>
</div> </div>
<script> <script>
const apiBase = import.meta.env.PUBLIC_AIA_API_BASE || 'https://api.azinstitute4autism.com'; const apiBase = import.meta.env.PUBLIC_AIA_API_BASE || 'https://api.azinstitute4autism.com';
@@ -49,14 +44,6 @@ const { slug } = Astro.props;
const views = counter.querySelector<HTMLElement>('[data-views]'); const views = counter.querySelector<HTMLElement>('[data-views]');
if (!button || !slug) return; if (!button || !slug) return;
const isLocalhost = ['localhost', '127.0.0.1', '::1'].includes(window.location.hostname);
if (isLocalhost) {
counter.dataset.unavailable = 'true';
if (likes) likes.textContent = '0';
if (views) views.textContent = '0';
return;
}
const cookieName = `liked_${slug}`; const cookieName = `liked_${slug}`;
const renderLiked = (liked: boolean) => { const renderLiked = (liked: boolean) => {
button.classList.toggle('liked', liked); button.classList.toggle('liked', liked);
@@ -79,7 +66,7 @@ const { slug } = Astro.props;
} catch { } catch {
counter.dataset.unavailable = 'true'; counter.dataset.unavailable = 'true';
if (likes) likes.textContent = '0'; if (likes) likes.textContent = '0';
if (views) views.textContent = '0'; if (views) views.textContent = '';
} }
button.addEventListener('click', async () => { button.addEventListener('click', async () => {
@@ -111,12 +98,8 @@ const { slug } = Astro.props;
</script> </script>
<style> <style>
.like-view-counter { align-items: center; border-top: 1px solid var(--color-border); display: flex; gap: var(--space-lg); font-size: .75rem; margin-block: var(--space-xl); padding-top: var(--space-md); } .like-view-counter { align-items: center; border-top: 1px solid var(--color-border); display: flex; gap: var(--space-lg); margin-block: var(--space-xl); padding-top: var(--space-md); }
.like-view-counter { font-size: .8rem; } .like-view-counter button { background: white; border: 1px solid var(--color-border); border-radius: 999px; padding: .6rem 1rem; }
.like-group { align-items: center; display: inline-flex; gap: .35rem; } .like-view-counter button.liked { background: var(--color-primary-dark); border-color: var(--color-primary-dark); color: white; }
.like-view-counter button { align-items: center; background: white; border: none; color: inherit; display: inline-flex; gap: 0; padding: 0; }
.like-view-counter .like-count { color: var(--color-text); min-width: 1ch; }
.like-view-counter .like-icon { fill: none; flex: 0 0 auto; stroke: #d92d20; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.6; }
.like-view-counter button.liked .like-icon { fill: #d92d20; stroke: #d92d20; }
.like-view-counter button:disabled { cursor: wait; opacity: .65; } .like-view-counter button:disabled { cursor: wait; opacity: .65; }
</style> </style>
+18 -20
View File
@@ -1,35 +1,33 @@
--- ---
import BaseLayout from './BaseLayout.astro'; import BaseLayout from './BaseLayout.astro';
import PageHero from '../components/PageHero.astro'; import PageHero from '../components/PageHero.astro';
const { title, description, intro = [], lang = 'en' } = Astro.props; const { title, description, lang = 'en' } = Astro.props;
const languagePrefix = lang === 'en' ? '' : `/${lang}`; const languagePrefix = lang === 'en' ? '' : `/${lang}`;
const canonical = `https://www.azinstitute4autism.com${languagePrefix}/library`; const canonical = `https://www.azinstitute4autism.com${languagePrefix}/library`;
--- ---
<BaseLayout title={title} description={description} canonical={canonical} lang={lang}> <BaseLayout title={title} description={description} canonical={canonical} lang={lang}>
<PageHero title={title} image="/assets/images/hero-library-index.webp" eyebrow="Welcome to" constrain /> <PageHero title={title} image="/assets/images/hero-library-index.webp" eyebrow="Welcome to" constrain />
<section class="library-intro"> <section class="library-intro"><div class="container"><h2>Library</h2><p>{description}</p></div></section>
<div class="container">
<h2>Library</h2>
{intro.length ? intro.map((paragraph) => <p>{paragraph}</p>) : <p>{description}</p>}
</div>
</section>
<div class="container section library-layout"><slot /></div> <div class="container section library-layout"><slot /></div>
</BaseLayout> </BaseLayout>
<style> <style>
:global(.library-intro) { background: var(--color-primary); color: white; padding-block: 3rem; } .library-intro { background: var(--color-primary); color: white; padding-block: 3rem; }
:global(.library-intro h2) { color: white; } .library-intro h2 { color: white; }
:global(.library-layout) { align-items: start; display: grid; gap: 3rem; grid-template-columns: 1fr 240px; } .library-layout { align-items: start; display: grid; gap: 3rem; grid-template-columns: 1fr 240px; }
:global(.library-sidebar) { position: sticky; top: 1rem; } .library-sidebar { position: sticky; top: 1rem; }
:global(.library-sidebar label) { display: block; font-weight: 700; margin-bottom: .4rem; } .library-sidebar label { display: block; font-weight: 700; margin-bottom: .4rem; }
:global(.library-sidebar input) { border: 1px solid var(--color-border); border-radius: 4px; font: inherit; padding: .7rem; width: 100%; } .library-sidebar input { border: 1px solid var(--color-border); border-radius: 4px; font: inherit; padding: .7rem; width: 100%; }
:global(.library-sidebar h2) { font-size: 1.1rem; margin-top: 2rem; } .library-sidebar h2 { font-size: 1.1rem; margin-top: 2rem; }
:global(.library-sidebar ul) { list-style: none; padding: 0; } .library-sidebar ul { list-style: none; padding: 0; }
:global(.library-sidebar li) { border-bottom: 1px solid var(--color-border); padding-block: .65rem; } .library-sidebar li { border-bottom: 1px solid var(--color-border); padding-block: .65rem; }
:global(.library-sidebar a) { color: var(--color-primary); font-size: .9rem; } .library-sidebar a { color: var(--color-primary); font-size: .9rem; }
:global(.blog-list) { display: block; } .blog-list { display: grid; gap: 2rem; }
.blog-list .blog-card { box-shadow: none; display: grid; grid-template-columns: 240px 1fr; }
.blog-list .blog-card > a img { aspect-ratio: 4 / 3; height: 100%; }
@media (max-width: 760px) { @media (max-width: 760px) {
:global(.library-layout) { grid-template-columns: 1fr; } .library-layout { grid-template-columns: 1fr; }
:global(.library-sidebar) { position: static; } .library-sidebar { position: static; }
.blog-list .blog-card { grid-template-columns: 1fr; }
} }
</style> </style>
+5 -8
View File
@@ -5,14 +5,11 @@ import BlogCard from '../../components/BlogCard.astro';
const posts = (await getCollection('blog', ({ data }) => data.lang === 'en' && !data.draft)).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf()); const posts = (await getCollection('blog', ({ data }) => data.lang === 'en' && !data.draft)).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
const popular = posts.slice(0, 5); const popular = posts.slice(0, 5);
--- ---
<BlogIndexLayout <BlogIndexLayout title="The Library at AZ Institute for Autism" description="Welcome to the Library at AIA, where we share valuable insights, strategies, and resources to support individuals with autism, their families, and professionals in the field. Our articles explore key topics in Applied Behavior Analysis (ABA) therapy, community events, success stories, and expert guidance.">
title="The Library at AZ Institute for Autism" <div class="container library-copy">
description="Welcome to the Library at AIA, where we share valuable insights, strategies, and resources to support individuals with autism, their families, and professionals in the field. Our articles explore key topics in Applied Behavior Analysis (ABA) therapy, community events, success stories, and expert guidance." <p>Welcome to the Library at AIA, where we share valuable insights, strategies, and resources to support individuals with autism, their families, and professionals in the field. Our articles explore key topics in Applied Behavior Analysis (ABA) therapy, including teaching self-advocacy, proactive and reactive strategies, and innovative intervention techniques.</p>
intro={[ <p>We also highlight community events, success stories, and expert guidance to foster understanding and empowerment. Whether you're a parent, caregiver, educator, or advocate, our goal is to provide meaningful content that helps children with autism reach their highest potential in a compassionate and supportive environment. Stay connected with us as we continue to share knowledge and celebrate progress!</p>
"Welcome to the Library at AIA, where we share valuable insights, strategies, and resources to support individuals with autism, their families, and professionals in the field. Our articles explore key topics in Applied Behavior Analysis (ABA) therapy, including teaching self-advocacy, proactive and reactive strategies, and innovative intervention techniques.", </div>
"We also highlight community events, success stories, and expert guidance to foster understanding and empowerment. Whether you're a parent, caregiver, educator, or advocate, our goal is to provide meaningful content that helps children with autism reach their highest potential in a compassionate and supportive environment. Stay connected with us as we continue to share knowledge and celebrate progress!",
]}
>
<div class="blog-list">{posts.map((post) => <BlogCard post={post} />)}</div> <div class="blog-list">{posts.map((post) => <BlogCard post={post} />)}</div>
<aside class="library-sidebar"> <aside class="library-sidebar">
<label for="library-search">Search</label> <label for="library-search">Search</label>