feat(i18n): reconcile multilingual pages and shared forms
This commit is contained in:
22 files changed
+2866
-88
No files matched your search
@@ -2,11 +2,16 @@
|
||||
import Button from './Button.astro';
|
||||
import ContactObfuscation from './ContactObfuscation.astro';
|
||||
|
||||
import { formMessages } from '../utils/form-messages';
|
||||
|
||||
interface Props {
|
||||
lang?: string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
const { title = 'Contact AIA' } = Astro.props;
|
||||
const { lang = 'en' } = Astro.props;
|
||||
const text = formMessages(lang);
|
||||
const title = Astro.props.title ?? text.contactHeading;
|
||||
---
|
||||
|
||||
<form class="contact-form-card" method="post" action="">
|
||||
@@ -14,13 +19,13 @@ const { title = 'Contact AIA' } = Astro.props;
|
||||
<!-- TODO: Add spam protection before production launch. -->
|
||||
<h3 class="contact-form-card__title">{title}</h3>
|
||||
<div class="contact-form-card__fields">
|
||||
<label>Parent or guardian name<input name="name" autocomplete="name" /></label>
|
||||
<label>Email<input type="email" name="email" autocomplete="email" /></label>
|
||||
<label>Phone<input type="tel" name="phone" autocomplete="tel" /></label>
|
||||
<label>Service of interest<select name="service"><option>ABA Therapy</option><option>Autism Evaluation</option><option>Learner Social Club</option><option>Other</option></select></label>
|
||||
<label>How can we help?<textarea name="message" rows="5"></textarea></label>
|
||||
<Button type="submit" disabled aria-describedby="contact-form-note" class="contact-form-card__submit">Submit</Button>
|
||||
<p id="contact-form-note" class="contact-form-card__note">Online submission is not yet connected. Please call <ContactObfuscation phone="(480) 687-7099" hrefValue="+14806877099" obfuscatedText="9907-786 (084)" />.</p>
|
||||
<label>{text.name}<input name="name" autocomplete="name" /></label>
|
||||
<label>{text.email}<input type="email" name="email" autocomplete="email" /></label>
|
||||
<label>{text.phone}<input type="tel" name="phone" autocomplete="tel" /></label>
|
||||
<label>{text.service}<select name="service">{text.options.map((label) => <option>{label}</option>)}</select></label>
|
||||
<label>{text.message}<textarea name="message" rows="5"></textarea></label>
|
||||
<Button type="submit" disabled aria-describedby="contact-form-note" class="contact-form-card__submit">{text.submit}</Button>
|
||||
<p id="contact-form-note" class="contact-form-card__note">{text.disabled} <ContactObfuscation phone="(480) 687-7099" hrefValue="+14806877099" obfuscatedText="9907-786 (084)" />.</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
---
|
||||
import Button from './Button.astro';
|
||||
import ContactObfuscation from './ContactObfuscation.astro';
|
||||
const { title = 'Schedule Your Free Consultation', showBackground = false } = Astro.props;
|
||||
import { formMessages } from '../utils/form-messages';
|
||||
const { lang = 'en', showBackground = false } = Astro.props;
|
||||
const text = formMessages(lang);
|
||||
const title = Astro.props.title ?? text.heading;
|
||||
---
|
||||
<section class:list={['form-section', { 'form-section-background': showBackground }]} aria-labelledby="form-title">
|
||||
<div class="container form-grid">
|
||||
<div><p class="eyebrow">Get started</p><h2 id="form-title">{title}</h2><p>Tell our client advocates how we can help. Submission is disabled until a production form backend is selected.</p></div>
|
||||
<div><p class="eyebrow">{text.eyebrow}</p><h2 id="form-title">{title}</h2><p>{text.intro}</p></div>
|
||||
<form class="form" method="post" action="">
|
||||
<!-- TODO: Wire this form to Netlify Forms, a custom API endpoint, or another backend service. -->
|
||||
<!-- TODO: Add spam protection before production launch. -->
|
||||
<label>Parent or guardian name<input name="name" autocomplete="name" /></label>
|
||||
<label>Email<input type="email" name="email" autocomplete="email" /></label>
|
||||
<label>Phone<input type="tel" name="phone" autocomplete="tel" /></label>
|
||||
<label>Service of interest<select name="service"><option>ABA Therapy</option><option>Autism Evaluation</option><option>Learner Social Club</option><option>Other</option></select></label>
|
||||
<label>How can we help?<textarea name="message" rows="5"></textarea></label>
|
||||
<Button type="submit" disabled aria-describedby="form-note">Submit</Button>
|
||||
<p id="form-note" class="form-note">Online submission is not yet connected. Please call <ContactObfuscation phone="(480) 687-7099" hrefValue="+14806877099" obfuscatedText="9907-786 (084)" />.</p>
|
||||
<label>{text.name}<input name="name" autocomplete="name" /></label>
|
||||
<label>{text.email}<input type="email" name="email" autocomplete="email" /></label>
|
||||
<label>{text.phone}<input type="tel" name="phone" autocomplete="tel" /></label>
|
||||
<label>{text.service}<select name="service">{text.options.map((label) => <option>{label}</option>)}</select></label>
|
||||
<label>{text.message}<textarea name="message" rows="5"></textarea></label>
|
||||
<Button type="submit" disabled aria-describedby="form-note">{text.submit}</Button>
|
||||
<p id="form-note" class="form-note">{text.disabled} <ContactObfuscation phone="(480) 687-7099" hrefValue="+14806877099" obfuscatedText="9907-786 (084)" />.</p>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
@@ -17,31 +17,31 @@ if (!slice?.items.length) throw new Error(`Empty author archive: ${author.archiv
|
||||
const { Content } = await render(author.entry);
|
||||
const prefix = locale === 'en' ? '' : `/${locale}`;
|
||||
const text = {
|
||||
en: { heading: 'The Library at AZ Institute for Autism', title: 'Library & News Room | Arizona Institute for Autism', page: 'Page' },
|
||||
es: { heading: 'La Biblioteca en AZ Institute for Autism', title: 'Biblioteca y Noticias | Instituto de Autismo de Arizona', page: 'Página' },
|
||||
ar: { heading: 'مكتبة معهد أريزونا للتوحد', title: 'المكتبة وغرفة الأخبار | معهد أريزونا للتوحد', page: 'الصفحة' }
|
||||
en: { heading: 'The Library at AZ Institute for Autism', title: 'Library & News Room | Arizona Institute for Autism', page: 'Page', welcome: 'Welcome to', posts: 'All Post', popular: 'Popular Posts' },
|
||||
es: { heading: 'La Biblioteca en AZ Institute for Autism', title: 'Biblioteca y Noticias | Instituto de Autismo de Arizona', page: 'Página', welcome: 'Bienvenido a', posts: 'Todas las publicaciones', popular: 'Publicaciones populares' },
|
||||
ar: { heading: 'مكتبة معهد أريزونا للتوحد', title: 'المكتبة وغرفة الأخبار | معهد أريزونا للتوحد', page: 'الصفحة', welcome: 'مرحبًا بكم في', posts: 'جميع المقالات', popular: 'المقالات الشائعة' }
|
||||
}[locale];
|
||||
const title = `${text.title} | ${author.displayName}${currentPage > 1 ? ` | ${text.page} ${currentPage}` : ''}`;
|
||||
// Use the existing catalog's latest-post treatment; no second article list.
|
||||
const popular = catalog.slice(0, 5);
|
||||
---
|
||||
<BaseLayout title={title} description={author.description} image={author.avatar} lang={locale}>
|
||||
<PageHero title={text.heading} image="/assets/images/hero-library-index.webp" eyebrow="Welcome to" constrain />
|
||||
<PageHero title={text.heading} image="/assets/images/hero-library-index.webp" eyebrow={text.welcome} constrain />
|
||||
<section class="author-profile" aria-labelledby="author-heading">
|
||||
{author.avatar && <img class="author-profile__avatar" src={author.avatar} alt={author.displayName} width="176" height="176" />}
|
||||
<div class="author-profile__content">
|
||||
<h2 id="author-heading"><bdi>{author.displayName}</bdi></h2>
|
||||
<h2 id="author-heading"><bdi>{locale === 'ar' ? author.displayName.split(/(BCBA|LBA)/).map((part) => /^(BCBA|LBA)$/.test(part) ? <bdi dir="ltr" lang="en">{part}</bdi> : part) : author.displayName}</bdi></h2>
|
||||
<div class="author-biography"><Content /></div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="author-listing container">
|
||||
<section aria-labelledby="author-posts-heading">
|
||||
<h2 id="author-posts-heading" class="author-posts-heading"><a href={libraryRootRoute(locale)}>All Post</a></h2>
|
||||
<h2 id="author-posts-heading" class="author-posts-heading"><a href={libraryRootRoute(locale)}>{text.posts}</a></h2>
|
||||
<div class="blog-list">{slice.items.map(({ entry }) => <BlogCard post={entry} prefix={prefix} />)}</div>
|
||||
<LibraryPagination locale={locale} page={slice} authorRoot={author.archiveRoute} />
|
||||
</section>
|
||||
<aside class="author-sidebar" aria-labelledby="author-popular-heading">
|
||||
<h2 id="author-popular-heading">Popular Posts</h2>
|
||||
<h2 id="author-popular-heading">{text.popular}</h2>
|
||||
<ul>{popular.map(({ entry, route }) => <li><a href={route}>{entry.data.title}</a></li>)}</ul>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
---
|
||||
import ContactForm from '../ContactForm.astro';
|
||||
import { formMessages } from '../../utils/form-messages';
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
lang: string;
|
||||
}
|
||||
|
||||
const { title } = Astro.props;
|
||||
const { title, lang } = Astro.props;
|
||||
const text = formMessages(lang);
|
||||
---
|
||||
|
||||
<section class="contact-page">
|
||||
@@ -13,12 +16,12 @@ const { title } = Astro.props;
|
||||
<div class="contact-page__copy">
|
||||
<slot />
|
||||
</div>
|
||||
<ContactForm title={title} />
|
||||
<ContactForm title={title} lang={lang} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="contact-map-section" aria-label="Map showing Arizona Institute for Autism in Scottsdale">
|
||||
<div id="aia-contact-map" class="contact-map"></div>
|
||||
<section class="contact-map-section" aria-label={text.map}>
|
||||
<div id="aia-contact-map" class="contact-map" data-tile-alt={text.tile} data-zoom-in={text.zoomIn} data-zoom-out={text.zoomOut} data-marker-label={text.marker}></div>
|
||||
</section>
|
||||
|
||||
<script is:inline src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
|
||||
@@ -28,7 +31,8 @@ const { title } = Astro.props;
|
||||
|
||||
if (!mapElement || !window.L) return;
|
||||
|
||||
const map = window.L.map(mapElement).setView([33.63, -111.88756], 12);
|
||||
const map = window.L.map(mapElement, { zoomControl: false }).setView([33.63, -111.88756], 12);
|
||||
window.L.control.zoom({ zoomInTitle: mapElement.dataset.zoomIn, zoomOutTitle: mapElement.dataset.zoomOut }).addTo(map);
|
||||
const tiles = window.L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
||||
maxZoom: 19
|
||||
@@ -36,13 +40,13 @@ const { title } = Astro.props;
|
||||
|
||||
tiles.on('tileload', (event) => {
|
||||
if (event.tile && !event.tile.alt) {
|
||||
event.tile.alt = 'OpenStreetMap tile showing area around Arizona Institute for Autism in Scottsdale, AZ';
|
||||
event.tile.alt = mapElement.dataset.tileAlt;
|
||||
}
|
||||
});
|
||||
|
||||
tiles.addTo(map);
|
||||
|
||||
window.L.marker([33.617746, -111.88756]).addTo(map).bindPopup(`
|
||||
window.L.marker([33.617746, -111.88756], { alt: mapElement.dataset.markerLabel, title: mapElement.dataset.markerLabel }).addTo(map).bindPopup(`
|
||||
<span style="display:block;text-align:center">
|
||||
<b>Arizona Institute for Autism</b><br>
|
||||
<img class="contact-map__logo" alt="Arizona Institute for Autism" src="/assets/images/aia-logo.svg" width="94">
|
||||
|
||||
Reference in new issue
Block a user