add contact page

This commit is contained in:
Yisroel Baum 2026-06-13 23:19:30 +03:00
parent 6e98825767
commit 4e03b0cacb
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
2 changed files with 557 additions and 0 deletions

View file

@ -1,6 +1,7 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import HomePage from '@/views/HomePage.vue' import HomePage from '@/views/HomePage.vue'
import AboutPage from '@/views/AboutPage.vue' import AboutPage from '@/views/AboutPage.vue'
import ContactPage from '@/views/ContactPage.vue'
import LoginPage from '@/views/LoginPage.vue' import LoginPage from '@/views/LoginPage.vue'
import MediaPage from '@/views/MediaPage.vue' import MediaPage from '@/views/MediaPage.vue'
import ElementPage from '@/views/ElementPage.vue' import ElementPage from '@/views/ElementPage.vue'
@ -25,6 +26,11 @@ const router = createRouter({
name: 'about', name: 'about',
component: AboutPage, component: AboutPage,
}, },
{
path: '/contact',
name: 'contact',
component: ContactPage,
},
{ {
path: '/media', path: '/media',
name: 'media', name: 'media',

View file

@ -0,0 +1,551 @@
<script setup lang="ts">
import { ref } from 'vue'
import SiteHeader from '@/components/SiteHeader.vue'
interface SocialLink {
label: string
href: string
}
const contactFirstName = ref('')
const contactLastName = ref('')
const contactCity = ref('')
const contactCountry = ref('')
const contactEmail = ref('')
const contactMessage = ref('')
const newsletterFullName = ref('')
const newsletterEmail = ref('')
const socialLinks: SocialLink[] = [
{
label: 'YouTube',
href: 'https://www.youtube.com/@rabbigerzi',
},
{
label: 'Spotify',
href: 'https://open.spotify.com/show/49H1X9A7KZWAnnIbcoQXQR?si=6253691f23be44ad',
},
]
function submitContact(submitEvent: Event): void {
submitEvent.preventDefault()
contactFirstName.value = ''
contactLastName.value = ''
contactCity.value = ''
contactCountry.value = ''
contactEmail.value = ''
contactMessage.value = ''
}
function submitNewsletter(submitEvent: Event): void {
submitEvent.preventDefault()
newsletterFullName.value = ''
newsletterEmail.value = ''
}
</script>
<template>
<div class="contact-page">
<SiteHeader />
<main>
<section class="contact-hero" data-cy="contact-hero">
<div class="contact-hero__inner">
<p class="contact-hero__eyebrow">Contact</p>
<h1 class="contact-hero__heading">Contact</h1>
<p class="contact-hero__body">
Rabbi Gerzi receives numerous messages each week. It may take some time to get back to
you, but we will do our best to respond in a timely manner.
</p>
</div>
</section>
<section class="contact-main">
<div class="contact-main__inner">
<form class="contact-form" data-cy="contact-form" @submit="submitContact">
<h2 class="contact-form__heading">Send Rabbi Gerzi a Message</h2>
<div class="contact-form__grid">
<label class="contact-form__field">
<span class="contact-form__label">First Name</span>
<input
v-model="contactFirstName"
name="firstName"
type="text"
class="contact-form__input"
autocomplete="given-name"
required
/>
</label>
<label class="contact-form__field">
<span class="contact-form__label">Last Name</span>
<input
v-model="contactLastName"
name="lastName"
type="text"
class="contact-form__input"
autocomplete="family-name"
required
/>
</label>
<label class="contact-form__field">
<span class="contact-form__label">City</span>
<input
v-model="contactCity"
name="city"
type="text"
class="contact-form__input"
autocomplete="address-level2"
required
/>
</label>
<label class="contact-form__field">
<span class="contact-form__label">Country</span>
<input
v-model="contactCountry"
name="country"
type="text"
class="contact-form__input"
autocomplete="country-name"
required
/>
</label>
<label class="contact-form__field contact-form__field--wide">
<span class="contact-form__label">Email</span>
<input
v-model="contactEmail"
name="email"
type="email"
class="contact-form__input"
autocomplete="email"
required
/>
</label>
<label class="contact-form__field contact-form__field--wide">
<span class="contact-form__label">Message</span>
<textarea
v-model="contactMessage"
name="message"
class="contact-form__textarea"
rows="6"
required
></textarea>
</label>
</div>
<button type="submit" class="contact-form__submit">Submit</button>
</form>
<aside class="contact-social" data-cy="contact-social">
<h2 class="contact-social__heading">Follow Rabbi Gerzi on Social Media</h2>
<div class="contact-social__links">
<a
v-for="socialLink in socialLinks"
:key="socialLink.href"
:href="socialLink.href"
class="contact-social__link"
target="_blank"
rel="noopener"
>
{{ socialLink.label }}
</a>
</div>
</aside>
</div>
</section>
<section class="get-involved" data-cy="get-involved">
<div class="get-involved__card">
<div class="get-involved__copy">
<h2 class="get-involved__heading">Get Involved</h2>
<p class="get-involved__subtext">
Subscribe for updates as we release new content, chaburot and events.
</p>
</div>
<form class="get-involved__form" @submit="submitNewsletter">
<label class="get-involved__field">
<span class="get-involved__label">Full Name</span>
<input
v-model="newsletterFullName"
name="fullName"
type="text"
class="get-involved__input"
autocomplete="name"
/>
</label>
<label class="get-involved__field">
<span class="get-involved__label">Email Address</span>
<input
v-model="newsletterEmail"
name="newsletterEmail"
type="email"
class="get-involved__input"
autocomplete="email"
/>
</label>
<button type="submit" class="get-involved__submit">Submit</button>
</form>
</div>
</section>
</main>
<footer class="site-footer" data-cy="footer">
<div class="site-footer__inner">
<div class="site-footer__brand">
<img src="/assets/signature.png" alt="R' Yehoshua Gerzi" class="site-footer__signature" />
<div class="site-footer__social">
<a href="#" class="site-footer__social-link" aria-label="YouTube"> &#9654; </a>
<a href="#" class="site-footer__social-link" aria-label="Spotify"> &#9835; </a>
</div>
</div>
<nav class="site-footer__links">
<ul class="site-footer__link-column">
<li><a href="/media">Torah Media</a></li>
<li><a href="/about">About</a></li>
</ul>
<ul class="site-footer__link-column">
<li><a href="/donate">Donate</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</div>
<p class="site-footer__copyright">&copy; Rabbi Gerzi 2025</p>
</footer>
</div>
</template>
<style scoped>
.contact-page {
min-height: 100vh;
background: var(--color-white);
}
.contact-hero {
background: var(--color-cream);
padding: 4rem 2rem;
}
.contact-hero__inner {
max-width: 760px;
margin: 0 auto;
text-align: center;
}
.contact-hero__eyebrow {
margin: 0 0 0.75rem;
color: var(--color-olive);
font-family: var(--font-sans);
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0;
text-transform: uppercase;
}
.contact-hero__heading,
.contact-form__heading,
.contact-social__heading,
.get-involved__heading {
margin: 0;
color: var(--color-slate);
font-family: var(--font-serif);
font-weight: 400;
line-height: 1.15;
}
.contact-hero__heading {
font-size: clamp(2.3rem, 4vw, 3.35rem);
}
.contact-hero__body {
max-width: 42rem;
margin: 1.35rem auto 0;
color: var(--color-text-muted);
font-family: var(--font-serif);
font-size: clamp(1.05rem, 2vw, 1.25rem);
line-height: 1.65;
}
.contact-main {
background: var(--color-white);
padding: 5rem 2rem;
}
.contact-main__inner {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(260px, 0.42fr);
max-width: 1100px;
margin: 0 auto;
gap: 2rem;
align-items: start;
}
.contact-form,
.contact-social {
background: var(--color-white);
border: 1px solid var(--color-border);
border-radius: 8px;
}
.contact-form {
padding: clamp(1.5rem, 4vw, 2.5rem);
}
.contact-form__heading {
font-size: clamp(1.5rem, 2.4vw, 2rem);
}
.contact-form__grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
margin-top: 2rem;
gap: 1rem;
}
.contact-form__field {
display: flex;
flex-direction: column;
gap: 0.45rem;
}
.contact-form__field--wide {
grid-column: 1 / -1;
}
.contact-form__label,
.get-involved__label {
color: var(--color-text-muted);
font-family: var(--font-sans);
font-size: 0.85rem;
}
.contact-form__input,
.contact-form__textarea,
.get-involved__input {
width: 100%;
padding: 0.78rem 1rem;
color: var(--color-text);
background: var(--color-cream);
border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 8px;
font-family: var(--font-sans);
font-size: 1rem;
}
.contact-form__textarea {
resize: vertical;
min-height: 150px;
}
.contact-form__input:focus,
.contact-form__textarea:focus,
.get-involved__input:focus {
outline: 2px solid var(--color-slate);
outline-offset: 2px;
}
.contact-form__submit,
.get-involved__submit {
margin-top: 1.25rem;
padding: 0.85rem 1rem;
color: var(--color-white);
background: var(--color-text);
border: none;
border-radius: 8px;
font-family: var(--font-sans);
font-size: 1rem;
font-weight: 500;
}
.contact-form__submit:hover,
.get-involved__submit:hover {
background: var(--color-slate);
}
.contact-social {
padding: 2rem;
background: var(--color-cream);
}
.contact-social__heading {
font-size: clamp(1.3rem, 2vw, 1.7rem);
}
.contact-social__links {
display: grid;
margin-top: 1.5rem;
gap: 0.85rem;
}
.contact-social__link {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.95rem 1rem;
color: var(--color-text);
background: var(--color-white);
border: 1px solid var(--color-border);
border-radius: 8px;
font-family: var(--font-sans);
font-weight: 600;
}
.contact-social__link:hover {
border-color: var(--color-slate);
}
.get-involved {
background: var(--color-cream);
padding: 5rem 2rem;
}
.get-involved__card {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center;
max-width: 1100px;
margin: 0 auto;
padding: 3rem;
gap: 3rem;
background: rgba(255, 255, 255, 0.48);
border: 1px solid rgb(230 225 210 / 70%);
border-radius: 8px;
}
.get-involved__heading {
margin-bottom: 1.25rem;
color: var(--color-text);
font-size: clamp(1.6rem, 2.6vw, 2.4rem);
}
.get-involved__subtext {
max-width: 36ch;
margin: 0;
color: var(--color-text-muted);
font-family: var(--font-serif);
font-size: 1rem;
line-height: 1.55;
}
.get-involved__form {
display: flex;
flex-direction: column;
gap: 1rem;
}
.get-involved__field {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.get-involved__submit {
margin-top: 0.5rem;
}
.site-footer {
padding: 4rem 2rem 2rem;
background: var(--color-white);
border-top: 1px solid var(--color-border);
}
.site-footer__inner {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: start;
max-width: 1100px;
margin: 0 auto 2rem;
gap: 2rem;
}
.site-footer__brand {
display: flex;
flex-direction: column;
gap: 1rem;
}
.site-footer__signature {
width: auto;
height: 40px;
}
.site-footer__social {
display: flex;
gap: 0.75rem;
}
.site-footer__social-link {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
color: var(--color-text-muted);
border: 1px solid var(--color-border);
border-radius: 6px;
}
.site-footer__social-link:hover {
background: var(--color-cream);
}
.site-footer__links {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.site-footer__link-column {
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
gap: 0.6rem;
list-style: none;
}
.site-footer__link-column a {
color: var(--color-text);
font-family: var(--font-sans);
font-size: 0.95rem;
}
.site-footer__link-column a:hover {
color: var(--color-slate);
}
.site-footer__copyright {
margin: 0;
color: var(--color-text-muted);
font-family: var(--font-sans);
font-size: 0.85rem;
text-align: center;
}
@media (max-width: 860px) {
.contact-hero {
padding: 3rem 1rem;
}
.contact-main {
padding: 4rem 1rem;
}
.contact-main__inner,
.contact-form__grid,
.get-involved__card,
.site-footer__inner {
grid-template-columns: 1fr;
}
.get-involved {
padding: 4rem 1rem;
}
.get-involved__card {
padding: 2rem;
gap: 2rem;
}
.site-footer__links {
grid-template-columns: 1fr;
}
}
</style>