Admin website

This commit is contained in:
2025-09-25 16:54:50 +02:00
parent 8dbf6caa6f
commit 24f15b6e28
36 changed files with 3451 additions and 561 deletions

View File

@@ -1,38 +1,46 @@
import React from 'react'
import React, { useMemo } from 'react'
import { useParams, Link } from 'react-router-dom'
import { Helmet } from 'react-helmet-async'
import ministries from '../data/ministries.json'
import events from '../data/events.json'
import { useEvents } from '../hooks/useEvents'
import LazyImage from '../components/LazyImage'
export default function MinistryDetail(){
export default function MinistryDetail() {
const { slug } = useParams()
const m = ministries.find(x => x.slug === slug)
if(!m) return (
<section className="section">
<div className="container">
<div className="text-center py-12">
<h1 className="font-heading text-h1 mb-4">Ministry Not Found</h1>
<p className="text-body mb-6">The ministry you're looking for doesn't exist.</p>
<Link to="/ministries" className="btn">Back to Ministries</Link>
</div>
</div>
</section>
)
const { events: eventItems } = useEvents()
const ministry = ministries.find(x => x.slug === slug)
// Filter events that might be related to this ministry
const relatedEvents = events.filter(e =>
e.title.toLowerCase().includes(m.category.toLowerCase()) ||
e.description.toLowerCase().includes(m.category.toLowerCase())
).slice(0, 3)
const relatedEvents = useMemo(() => {
if (!ministry) return []
const category = `${ministry.category || ''}`.toLowerCase()
return eventItems
.filter(event => {
const title = `${event.title || ''}`.toLowerCase()
const description = `${event.description || ''}`.toLowerCase()
return title.includes(category) || description.includes(category)
})
.slice(0, 3)
}, [eventItems, ministry])
if (!ministry) {
return (
<section className="section">
<div className="container">
<div className="text-center py-12">
<h1 className="font-heading text-h1 mb-4">Ministry Not Found</h1>
<p className="text-body mb-6">The ministry you're looking for doesn't exist.</p>
<Link to="/ministries" className="btn">Back to Ministries</Link>
</div>
</div>
</section>
)
}
return (
<>
<Helmet>
<title>{m.name} - Annaville Seventh-day Adventist Church</title>
<meta name="description" content={m.description} />
<title>{ministry.name} - Annaville Seventh-day Adventist Church</title>
<meta name="description" content={ministry.description} />
</Helmet>
{/* Hero Section */}
@@ -41,29 +49,29 @@ export default function MinistryDetail(){
<div className="grid lg:grid-cols-2 gap-12 items-center">
<div>
<div className="inline-block bg-primary/10 text-primary px-4 py-2 rounded-full text-sm font-medium mb-4">
{m.category}
{ministry.category}
</div>
<h1 className="font-heading text-h1 mb-6">{m.name}</h1>
<p className="text-body text-lg mb-6">{m.description}</p>
<h1 className="font-heading text-h1 mb-6">{ministry.name}</h1>
<p className="text-body text-lg mb-6">{ministry.description}</p>
<div className="flex flex-wrap gap-4 text-muted">
<div className="flex items-center gap-2">
<span className="text-2xl">🕒</span>
<span>{m.meeting}</span>
<span className="text-2xl"><EFBFBD>Y'</span>
<span>{ministry.meeting}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-2xl">📍</span>
<span>{m.where}</span>
<span className="text-2xl"><3E>Y"?</span>
<span>{ministry.where}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-2xl">👥</span>
<span>{m.ages}</span>
<span className="text-2xl"><EFBFBD>Y'<EFBFBD></span>
<span>{ministry.ages}</span>
</div>
</div>
</div>
<div className="relative">
<LazyImage
src={m.image}
alt={`${m.name} at Annaville SDA Church`}
src={ministry.image}
alt={`${ministry.name} at Annaville SDA Church`}
className="w-full h-80 rounded-2xl shadow-lg"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent rounded-2xl"></div>
@@ -83,9 +91,9 @@ export default function MinistryDetail(){
<div>
<h2 className="font-heading text-h2 mb-6">What We Do</h2>
<div className="grid md:grid-cols-2 gap-4">
{m.activities.map((activity, index) => (
{ministry.activities.map((activity, index) => (
<div key={index} className="flex items-start gap-3 p-4 bg-sand rounded-lg">
<span className="text-primary text-xl"></span>
<span className="text-primary text-xl"><EFBFBD>o"</span>
<span className="text-body">{activity}</span>
</div>
))}
@@ -97,15 +105,15 @@ export default function MinistryDetail(){
<div>
<h2 className="font-heading text-h2 mb-6">Upcoming Events</h2>
<div className="grid gap-4">
{relatedEvents.map(e => (
{relatedEvents.map(event => (
<Link
key={e.slug}
to={`/events/${e.slug}`}
key={event.slug}
to={`/events/${event.slug}`}
className="block p-6 bg-white border border-subtle rounded-lg hover:shadow-md transition-shadow"
>
<h3 className="font-heading text-h3 mb-2">{e.title}</h3>
<p className="text-muted mb-2">{e.date} {e.time}</p>
<p className="text-body">{e.description}</p>
<h3 className="font-heading text-h3 mb-2">{event.title}</h3>
<p className="text-muted mb-2">{event.date} - {event.time}</p>
<p className="text-body">{event.description}</p>
</Link>
))}
</div>
@@ -116,12 +124,12 @@ export default function MinistryDetail(){
<div>
<h2 className="font-heading text-h2 mb-6">Frequently Asked Questions</h2>
<div className="space-y-4">
{m.faq.map((item, index) => (
{ministry.faq.map((item, index) => (
<details key={index} className="group">
<summary className="cursor-pointer p-6 bg-white border border-subtle rounded-lg hover:bg-sand/50 transition-colors list-none">
<div className="flex items-center justify-between">
<h3 className="font-heading text-h3 text-ink">{item.question}</h3>
<span className="text-primary text-xl group-open:rotate-180 transition-transform"></span>
<span className="text-primary text-xl group-open:rotate-180 transition-transform"><3E>-<2D></span>
</div>
</summary>
<div className="p-6 bg-sand/30 rounded-b-lg border-t-0 border border-subtle">
@@ -142,29 +150,29 @@ export default function MinistryDetail(){
<div className="space-y-4">
<div>
<h4 className="font-medium text-ink mb-2">Ministry Leader</h4>
<p className="text-body">{m.leader}</p>
<p className="text-body">{ministry.leader}</p>
</div>
<div>
<h4 className="font-medium text-ink mb-2">Contact</h4>
<div className="space-y-2">
<a
href={`mailto:${m.contact.email}`}
href={`mailto:${ministry.contact.email}`}
className="block text-primary hover:text-primaryHover transition-colors"
>
📧 {m.contact.email}
<EFBFBD>Y"<EFBFBD> {ministry.contact.email}
</a>
<a
href={`tel:${m.contact.phone.replace(/\D/g, '')}`}
href={`tel:${ministry.contact.phone.replace(/\D/g, '')}`}
className="block text-primary hover:text-primaryHover transition-colors"
>
📞 {m.contact.phone}
<EFBFBD>Y"z {ministry.contact.phone}
</a>
</div>
</div>
<div>
<h4 className="font-medium text-ink mb-2">Meeting Details</h4>
<p className="text-body">{m.meeting}</p>
<p className="text-muted text-sm">{m.where}</p>
<p className="text-body">{ministry.meeting}</p>
<p className="text-muted text-sm">{ministry.where}</p>
</div>
</div>
<div className="mt-6">
@@ -182,7 +190,7 @@ export default function MinistryDetail(){
to="/ministries"
className="block text-primary hover:text-primaryHover transition-colors"
>
Back to All Ministries
<EFBFBD><EFBFBD>? Back to All Ministries
</Link>
<Link
to="/events"
@@ -204,16 +212,16 @@ export default function MinistryDetail(){
<h3 className="font-heading text-h3 mb-4">Other Ministries</h3>
<div className="space-y-3">
{ministries
.filter(ministry => ministry.slug !== m.slug)
.filter(other => other.slug !== ministry.slug)
.slice(0, 3)
.map(ministry => (
.map(other => (
<Link
key={ministry.slug}
to={`/ministries/${ministry.slug}`}
key={other.slug}
to={`/ministries/${other.slug}`}
className="block p-3 bg-sand rounded-lg hover:bg-sand/80 transition-colors"
>
<h4 className="font-medium text-ink">{ministry.name}</h4>
<p className="text-muted text-sm">{ministry.meeting}</p>
<h4 className="font-medium text-ink">{other.name}</h4>
<p className="text-muted text-sm">{other.meeting}</p>
</Link>
))}
</div>