Styles updated for responsiveness, added EmailButton and CopyButton components, added photo of pastor and Pam

main
Jeremy Hayes 2023-10-23 18:42:13 -05:00
parent e8e1915830
commit 66c935dfa5
17 changed files with 496 additions and 183 deletions

View File

@ -4,6 +4,6 @@ echo "building app..."
npm run build npm run build
echo "Deploying files to server" echo "Deploying files to server"
scp -r dist/* jeremy@154.56.60.138:/var/www/trailblazer.shop/ scp -r dist/* jeremy@154.56.60.138:/var/www/northshrevebaptist.org/
echo "DONE!" echo "DONE!"

60
package-lock.json generated
View File

@ -12,6 +12,7 @@
"localforage": "^1.10.0", "localforage": "^1.10.0",
"match-sorter": "^6.3.1", "match-sorter": "^6.3.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-copy-to-clipboard": "^5.1.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "^4.11.0", "react-icons": "^4.11.0",
"react-router-dom": "^6.16.0", "react-router-dom": "^6.16.0",
@ -1515,6 +1516,14 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true "dev": true
}, },
"node_modules/copy-to-clipboard": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
"integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
"dependencies": {
"toggle-selection": "^1.0.6"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -3219,7 +3228,6 @@
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@ -3636,7 +3644,6 @@
"version": "15.8.1", "version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"dependencies": { "dependencies": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@ -3683,6 +3690,18 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-copy-to-clipboard": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz",
"integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==",
"dependencies": {
"copy-to-clipboard": "^3.3.1",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"react": "^15.3.0 || 16 || 17 || 18"
}
},
"node_modules/react-dom": { "node_modules/react-dom": {
"version": "18.2.0", "version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
@ -3706,8 +3725,7 @@
"node_modules/react-is": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
"dev": true
}, },
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.14.0", "version": "0.14.0",
@ -4278,6 +4296,11 @@
"node": ">=8.0" "node": ">=8.0"
} }
}, },
"node_modules/toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
},
"node_modules/ts-interface-checker": { "node_modules/ts-interface-checker": {
"version": "0.1.13", "version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
@ -5599,6 +5622,14 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true "dev": true
}, },
"copy-to-clipboard": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
"integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
"requires": {
"toggle-selection": "^1.0.6"
}
},
"cross-spawn": { "cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -6850,8 +6881,7 @@
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
"dev": true
}, },
"object-hash": { "object-hash": {
"version": "3.0.0", "version": "3.0.0",
@ -7118,7 +7148,6 @@
"version": "15.8.1", "version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"requires": { "requires": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@ -7145,6 +7174,15 @@
"loose-envify": "^1.1.0" "loose-envify": "^1.1.0"
} }
}, },
"react-copy-to-clipboard": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz",
"integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==",
"requires": {
"copy-to-clipboard": "^3.3.1",
"prop-types": "^15.8.1"
}
},
"react-dom": { "react-dom": {
"version": "18.2.0", "version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
@ -7163,8 +7201,7 @@
"react-is": { "react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
"dev": true
}, },
"react-refresh": { "react-refresh": {
"version": "0.14.0", "version": "0.14.0",
@ -7573,6 +7610,11 @@
"is-number": "^7.0.0" "is-number": "^7.0.0"
} }
}, },
"toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
},
"ts-interface-checker": { "ts-interface-checker": {
"version": "0.1.13", "version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",

View File

@ -14,6 +14,7 @@
"localforage": "^1.10.0", "localforage": "^1.10.0",
"match-sorter": "^6.3.1", "match-sorter": "^6.3.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-copy-to-clipboard": "^5.1.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "^4.11.0", "react-icons": "^4.11.0",
"react-router-dom": "^6.16.0", "react-router-dom": "^6.16.0",

View File

@ -4,7 +4,7 @@ import { Link } from "react-router-dom";
const Footer = () => { const Footer = () => {
return ( return (
<div className="h-fit py-6 px-5 grid grid-cols-4 gap-2 w-full items-center text-white border-b-2 border-gray-50 inset-0 bg-blue-900/70 backdrop-blur-sm dark:bg-slate-900/80"> <div className="h-fit py-6 px-5 grid grid-cols-2 sm:grid-cols-4 gap-2 w-full items-center text-white border-b-2 border-gray-50 inset-0 bg-blue-900/70 backdrop-blur-sm dark:bg-slate-900/80">
<div className="text-4xl">NSBC</div> <div className="text-4xl">NSBC</div>
<div> <div>
<ul className="text-sm"> <ul className="text-sm">

View File

@ -1,17 +1,15 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { FaSearch } from "react-icons/fa"; import { FaSearch } from "react-icons/fa";
import { Link } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import About from "../pages/About";
import Contact from "../pages/Contact";
import HelpfulLinks from "../pages/HelpfulLinks";
import Home from "../pages/Home";
import HowToBecomeAChristian from "../pages/HowToBecomeAChristian";
import OnlineGiving from "../pages/OnlineGiving";
import Services from "../pages/Services";
import UpcomingEvents from "../pages/UpcomingEvents";
const Sidebar = () => { const Sidebar = ( props) => {
const [menu, setMenu] = useState([ const navigate = useNavigate();
const handleClick = (e, {to}) => {
e.preventDefault();
props.onClose(false);
navigate(to);
}
const menu = [
{ {
name: "Home", name: "Home",
path: "/", path: "/",
@ -23,67 +21,78 @@ const Sidebar = () => {
{ {
name: "Services", name: "Services",
path: "/services", path: "/services",
},{
name: "About",
path: "/about",
}, },
{ {
name: "Church Staff", name: "About",
path: "/church-staff", path: "/about",
}, { },
name: "Contact", {
path: "/contact", name: "Church Staff",
}, { path: "/church-staff",
name: "How to Become a Christian", },
path: "/become-a-christian", {
}, { name: "Contact",
name: "Online Giving", path: "/contact",
path: "/tithing", },
}, { {
name: "Helpful Links", name: "How to Become a Christian",
path: "/links", path: "/become-a-christian",
}, },
{
name: "Online Giving",
path: "/tithing",
},
{
name: "Helpful Links",
path: "/links",
},
// { // {
// name: "Rocks Cry Out Youth Ministry", // name: "Rocks Cry Out Youth Ministry",
// path: "/rocks-cry-out-youth-ministry", // path: "/rocks-cry-out-youth-ministry",
// }, // },
]); ];
return ( return (
<div className=""> <div className="">
<div <div
id="sidebar" id="sidebar"
className="absolute px-3 py-5 z-40 bg-blue-900/95 w-full sm:w-fit min-h-screen h-[100vh] overflow-y-auto" className="px-3 py-5 min-h-screen z-40 bg-blue-900/95 "
> >
<div> <div>
<div className="flex w-full"> <div className="flex w-full">
<form id="search-form" role="search"> <div className="flex border bg-blue-200/20 text-white border-slate-200 rounded-md">
<input <form id="search-form" role="search">
className="border bg-blue-200/20 text-white border-slate-200 py-1 px-2 rounded-l-md border-r-0" <input
id="q" className="w-fit py-1 px-2 bg-transparent outline-none"
aria-label="Search contacts" id="q"
placeholder="Search" aria-label="Search contacts"
type="search" placeholder="Search"
name="q" type="search"
/> name="q"
<div id="search-spinner" aria-hidden hidden={true} /> />
<div className="sr-only" aria-live="polite"></div> <div id="search-spinner" aria-hidden hidden={true} />
</form> <div className="sr-only" aria-live="polite"></div>
<form method="post"> </form>
<button <form method="post">
className="border border-slate-200 rounded-r-md bg-blue-200/20 text-white border-l-0 py-2 px-2" <button
type="submit" className=" bg-transparent text-white border-l-0 py-2 px-2"
> type="submit"
<FaSearch /> >
</button> <FaSearch />
</form> </button>
</form>
</div>
</div> </div>
</div> </div>
<nav> <nav>
<ul className="text-white mt-3"> <ul className="text-white mt-3">
{menu.map((item) => ( {menu.map((item) => (
<li className="py-1 hover:border-b border-b-gray-200 " key={item.name}> <li
<Link className="w-full" to={item.path}>{item.name}</Link> className="py-1 hover:border-b border-b-gray-200 "
key={item.name}
>
<Link onClick={(e) => handleClick(e,{to: item.path})} className="w-full flex h-fit" >
{item.name}
</Link>
</li> </li>
))} ))}
</ul> </ul>

View File

@ -0,0 +1,26 @@
import React, { useState } from 'react'
import { FaRegCopy } from 'react-icons/fa'
import { copyTextToClipboard } from '../../helpers/copyTextToClipboard'
const CopyButton = ({ text, title } ) => {
const [isCopied, setIsCopied] = useState(false)
const handleCopyClick = () => {
copyTextToClipboard(text)
setIsCopied(true)
setTimeout(() => {
setIsCopied(false)
}, 3000)
}
return (
<button className='flex items-start gap-1' onClick={handleCopyClick} title={title}>
<div className='flex items-center'>
<FaRegCopy />
</div>
<div className='text-xs -mt-1'>
{isCopied ? 'Copied' : 'Copy'}
</div>
</button>
)
}
export default CopyButton

View File

@ -0,0 +1,19 @@
import React from "react";
import { FaEnvelope } from "react-icons/fa";
const EmailButton = ({email, label}) => {
return (
<div className="flex items-center">
<a
title={label}
className="px-2 flex items-center justify-center"
href={"mailto:" + email}
>
<FaEnvelope />
&nbsp;{label} &nbsp;
</a>
</div>
);
};
export default EmailButton;

View File

@ -0,0 +1,17 @@
import React from 'react'
import { FaTimes } from 'react-icons/fa'
const ImageModal = ({image, title, descripton, onClose}) => {
const closeModal = (e) => {
onClose(e)
}
return (
<div className='fixed top-0 left-0 z-80 w-screen h-screen bg-black/70 flex justify-center items-center'>
<button className="fixed z-90 top-24 right-8 text-white text-5xl font-bold"
onClick={() => closeModal()}><FaTimes /></button>
<img src={image} className="max-h-[600px] max-w-[800px] object-cover object-center"/>
</div>
)
}
export default ImageModal

View File

@ -1,31 +1,74 @@
import React, { useState } from "react"; import React, { useEffect, useRef, useState } from "react";
import { AnimatePresence, motion } from "framer-motion"; import { AnimatePresence, motion, useCycle } from "framer-motion";
import { Outlet } from "react-router-dom"; import { Outlet } from "react-router-dom";
import Navbar from "./Components/Navbar"; import Navbar from "./Components/Navbar";
import Sidebar from "./Components/Sidebar"; import Sidebar from "./Components/Sidebar";
import Footer from "./Components/Footer"; import Footer from "./Components/Footer";
const itemVariants = {
closed: {
opacity: 0,
},
open: { opacity: 1 },
};
const sideVariants = {
closed: {
transition: {
staggerChildren: 0.2,
staggerDirection: -1,
},
},
open: {
transition: {
staggerChildren: 0.2,
staggerDirection: 1,
},
},
};
const Root = () => { const Root = () => {
const [sideBarOpen, setSideBarOpen] = useState(false); const [sideBarOpen, setSideBarOpen] = useCycle(false, true);
const sideNav = useRef();
useEffect(() => {
function handleClickOutside(event) {
if (sideNav.current && !sideNav.current.contains(event.target)) {
setSideBarOpen(false);
}
}
// Bind the event listener
document.addEventListener("mousedown", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener("mousedown", handleClickOutside);
};
}, [sideNav]);
return ( return (
<div className="xl:container mx-auto"> <div className="xl:max-w-6xl mx-auto">
<Navbar sideBarOpen={sideBarOpen} openSideBar={setSideBarOpen} /> <Navbar sideBarOpen={sideBarOpen} openSideBar={setSideBarOpen} />
<div className="flex"> <div className="flex">
<AnimatePresence> <AnimatePresence>
{sideBarOpen && ( {sideBarOpen && (
<div id="backdrop" className="w-full h-screen absolute top-0 left-0 bg-black/20" onClick={() => setSideBarOpen(false)}> <motion.aside
className="fixed w-full sm:w-fit min-h-screen h-[100vh] overflow-y-auto z-40"
<motion.div ref={sideNav}
initial={{ opacity: 0 }} initial={{ width: 0 }}
style={{ originX: 0.5 }} animate={{
animate={{ opacity: 1 }} width: 300,
exit={{ opacity: 0 }} }}
transition={{}} exit={{
duration="1.5s" width: 0,
transition: { delay: 0.7, duration: 0.3 },
}}
>
<motion.div
className="container"
initial="closed"
animate="open"
exit="closed"
variants={sideVariants}
> >
<Sidebar /> <Sidebar onClose={() => setSideBarOpen(false)} />
</motion.div> </motion.div>
</div> </motion.aside>
)} )}
</AnimatePresence> </AnimatePresence>
<div id="detail" className="py-3 mt-24 px-2 w-full"> <div id="detail" className="py-3 mt-24 px-2 w-full">

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

View File

@ -0,0 +1,7 @@
export async function copyTextToClipboard(text) {
if ('clipboard' in navigator) {
return await navigator.clipboard.writeText(text);
} else {
return document.execCommand('copy', true, text);
}
}

View File

@ -0,0 +1,27 @@
import { useEffect } from 'react';
const useClickOutside = (ref, handleClickOutside) => {
useEffect(() => {
const handleClick = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
handleClickOutside();
}
};
const handleEscape = (event) => {
if (event.key === 'Escape') {
handleClickOutside();
}
};
document.addEventListener('click', handleClick);
document.addEventListener('keydown', handleEscape);
return () => {
document.removeEventListener('click', handleClick);
document.removeEventListener('keydown', handleEscape);
};
}, [ref, handleClickOutside]);
};
export default useClickOutside;

View File

@ -1,65 +1,166 @@
import React from "react"; import React, { useState } from "react";
import SteveMiller from "../assets/SteveMiller.jpg"; import SteveMillerImage from "../assets/SteveMiller.jpg";
import PastorImage from "../assets/PastorAndWifeSmall.png";
import useDocumentTitle from "../hooks/useDocumentTitle"; import useDocumentTitle from "../hooks/useDocumentTitle";
import CopyButton from "../Components/ui/CopyButton";
import ImageModal from "../Components/ui/ImageModal";
import EmailButton from "../Components/ui/EmailButton";
const ChurchStaff = () => { const ChurchStaff = () => {
useDocumentTitle('NSBC | Church Staff'); useDocumentTitle("NSBC | Church Staff");
const jenniferCarter = {
name: "Jennifer Carter",
title: "Youth Director",
phone: null,
email: "jennifer@jubileezoo.com",
imageSmall: "https://placehold.co/600x400",
imageLarge: "https://placehold.co/600x400",
person2: {
name: "Don",
title: "Husband",
},
};
const SteveMiller = {
name: "Steve Miller",
title: "Worship Leader",
phone: null,
email: null,
imageSmall: SteveMillerImage,
imageLarge: SteveMillerImage,
person2: null,
};
const PastorAndWifeSmall = {
name: "Rev. Cecil Marr",
title: "Pastor and Wife",
phone: null,
email: null,
imageLarge: PastorImage,
imageSmall: PastorImage,
person2: {
name: "Pam Marr",
title: "Pianist",
},
};
const lindaConnor = {
name: "Linda Connor",
title: "Ministry Assistant - Office Secretary",
phone: null,
email: "linda@northshrevebaptist.org",
imageSmall: "https://placehold.co/600x400",
imageLarge: "https://placehold.co/600x400",
person2: {
name: "David",
title: "Husband",
},
};
const staffArr = [
PastorAndWifeSmall,
SteveMiller,
jenniferCarter,
lindaConnor,
];
const [activeModalImage, setActiveModalImage] = useState(false);
const [activeModalTitle, setActiveModalTitle] = useState(false);
const handleModalOpen = (title, image) => {
setActiveModalImage(image);
setActiveModalTitle(title);
setModalOpen(true);
};
const [modalOpen, setModalOpen] = useState(false);
return ( return (
<div className="max-w-2xl mx-auto"> <div className="max-w-2xl mx-auto">
<h1 className="text-4xl flex justify-center">Church Staff</h1> <h1 className="text-4xl flex justify-center">Church Staff</h1>
<div className="flex flex-col items-start "> <div className="flex flex-col items-start ">
<section className="grid grid-cols-2 gap-3 items-center p-4 bg-slate-100 w-full h-fit"> {staffArr.map((person, index) => (
<span> <div key={index} className="flex flex-col items-start">
<h2 className="text-2xl">Pastor</h2> {index % 2 === 0 ? (
<p>Rev. Cecil Marr</p> <section className="grid grid-cols-2 gap-3 items-center p-4 bg-slate-100 w-full h-fit">
</span> <span>
<div> <h2 className="text-2xl">{person.title}</h2>
<img src="https://placehold.co/600x400" /> <p>
{person.name}
{person.person2 && (
<span>
- {person.person2.name} - {person.person2.title}
</span>
)}
</p>
<div className="flex items-center">
{person.email && (
<>
<EmailButton
email={jenniferCarter.email}
label="Email Jennifer"
/>
<CopyButton
text={jenniferCarter.email}
title="Copy Jennifer Carter Email"
/>
</>
)}
</div>
</span>
<div>
<span>
<button
onClick={() =>
handleModalOpen(person.title, person.imageLarge)
}
className="w-full"
>
<img src={person.imageSmall} />
</button>
</span>
</div>
</section>
) : (
<section className="grid grid-cols-2 gap-3 bg-neutral-50 items-center w-full h-fit p-4">
<span>
<button
onClick={() =>
handleModalOpen(person.title, person.imageLarge)
}
className="w-full"
>
<img src={person.imageSmall} />
</button>
</span>
<div className="flex w-full justify-end">
<span className="flex flex-col">
<h2 className="text-2xl">{person.title}</h2>
<p>
{person.name}{" "}
{person.person2 && (
<span>
- {person.person2.name} - {person.person2.title}
</span>
)}
</p>
{person.email && (
<div className="flex items-center">
<EmailButton
email={jenniferCarter.email}
label={"Email " + person.name}
/>
<CopyButton
title={"Copy " + person.name + " Email"}
text={person.email}
/>
</div>
)}
</span>
</div>
</section>
)}
</div> </div>
</section> ))}
<section className="grid grid-cols-2 gap-3 bg-neutral-50 items-center w-full h-fit p-4">
<span> {modalOpen && (
<img src={SteveMiller} /> <ImageModal
</span> image={activeModalImage}
<div className="flex w-full justify-end"> title={activeModalTitle}
<span className="flex flex-col"> onClose={() => setModalOpen(false)}
<h2 className="text-2xl">Worship Leader</h2> />
<p>Steve Miller</p> )}
</span>
</div>
</section>
<section className="grid grid-cols-2 gap-3 bg-slate-100 items-center w-full h-fit p-4">
<div className="flex w-full justify-start">
<span className="flex flex-col">
<h2 className="text-2xl">Youth Director</h2>
<p>Jennifer Carter - husband - Don </p>
<p>
<a href="mailto:jennifer@jubileezoo.com">
Email: jennifer@jubileezoo.com
</a>
</p>
</span>
</div>
<span>
<img src="https://placehold.co/600x400" />
</span>
</section>
<section className="grid grid-cols-2 gap-3 bg-neutral-50 items-center w-full h-fit p-4">
<span>
<img src="https://placehold.co/600x400" />
</span>
<div className="flex w-full justify-end">
<span className="flex flex-col">
<h2 className="text-2xl">Ministry Assistant - Office Secretary</h2>
<p>Linda Conner - husband - David</p>
<p>
<a href="mailto:linda@northshrevebaptist.org">
Email: linda@northshrevebaptist.org
</a>
</p>
</span>
</div>
</section>
<div className="block w-full h-40"></div> <div className="block w-full h-40"></div>
</div> </div>
</div> </div>

View File

@ -5,6 +5,7 @@ import ChurchBG from "../assets/NSBC2.png";
const Home = () => { const Home = () => {
return ( return (
<div className=" -mt-28">
<div className=" -mx-2 -mt-3 relative"> <div className=" -mx-2 -mt-3 relative">
<ScrollRestoration /> <ScrollRestoration />
<div className="w-full"> <div className="w-full">
@ -13,36 +14,46 @@ const Home = () => {
className="w-full h-full object-cover object-center" className="w-full h-full object-cover object-center"
/> />
</div> </div>
<div className="w-full flex bg-cover h-full absolute md:object-cover object-center object-contain -top-0 text-gray-50 justify-center items-center"> <div className=" md:absolute lg:absolute xl:absolute top-0 w-full h-fit">
<div className="p-[4px] rounded-xl w-full sm:w-fit md:p-5 inset-0 bg-black/70 dark:bg-slate-900/80"> <div className="w-full h-full flex text-gray-50 justify-center items-center">
<div className="p-3 md:my-32 md:rounded-xl lg:rounded-xl lg:my-48 w-full lg:w-fit md:w-fit md:p-5 inset-0 bg-black/70 dark:bg-slate-900/80">
<h1 className="w-full flex justify-center text-xl sm:text-2xl md:text-2xl lg:text-4xl">
"Welcome to the House of Praise!"
</h1>
<p className="w-full text-sm sm:text-lg md:text-2xl lg:text-3xl flex justify-center my-3">
North Shreve Baptist Church
</p>
<p className="w-full text-xs sm:text-sm md:text-2xl lg:text-2xl flex justify-center my-3">
4930 Old Mooringsport Road Shreveport, LA 71107
</p>
<h1 className="w-full flex justify-center text-xl sm:text-2xl md:text-4xl"> <div className="w-full px-14 md:px-1 text-xs sm:text-sm md:text-xl lg:text-2xl flex justify-between my-3">
"Welcome to the House of Praise!" <a href="tel:318-425-2350" className="flex items-center">
</h1> <FaPhone /> &nbsp; (318) 425-2350
<p className="w-full text-sm sm:text-lg md:text-2xl flex justify-center my-3"> </a>
North Shreve Baptist Church <a
</p> href="mailto:office@northshrevebaptist.org"
<p className="w-full text-xs sm:text-sm md:text-2xl flex justify-center my-3"> className="flex items-center"
4930 Old Mooringsport Road Shreveport, LA 71107 >
</p> <FaEnvelope /> &nbsp; Email
</a>
<div className="w-full text-xs sm:text-sm md:text-xl flex justify-between my-3"> </div>
<a href="tel:318-425-2350" className="flex items-center"><FaPhone /> &nbsp; (318) 425-2350</a> <p className="w-full text-xs sm:text-sm md:text-xl lg:text-2xl flex justify-center my-3">
<a href="mailto:office@northshrevebaptist.org" className="flex items-center"><FaEnvelope /> &nbsp; Email</a> Rev. Cecil Marr, Pastor
</div> </p>
<p className="w-full text-xs sm:text-sm md:text-xl flex justify-center my-3"> <p className=" w-full text-xs sm:text-sm md:text-xl lg:text-2xl flex justify-center ">
Rev. Cecil Marr, Pastor Steve Miller, Worship Leader
</p> </p>
<p className=" w-full text-xs sm:text-sm md:text-xl flex justify-center "> <div className="w-full flex justify-center my-3 pt-2">
Steve Miller, Worship Leader <button className="flex text-xs items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 md:py-2 md:text-lg md:px-10">
</p> Watch Past Services &nbsp; <FaPlay />
<div className="w-full flex justify-center my-3 pt-2"> </button>
<button className="flex items-center justify-center px-4 py-2 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 md:py-2 md:text-lg md:px-10"> </div>
Watch Past Services &nbsp; <FaPlay />
</button>
</div> </div>
</div> </div>
</div> </div>
</div>
<div>
<div> <div>
<div className="p-2 max-w-lg mx-auto"> <div className="p-2 max-w-lg mx-auto">
<p className="pt-4 flex justify-between"> <p className="pt-4 flex justify-between">
@ -54,21 +65,21 @@ const Home = () => {
<span>11:00 am.</span> <span>11:00 am.</span>
</p> </p>
<p className="pb-4 flex justify-between"> <p className="pb-4 flex justify-between">
<span> <span>Wednesday Evening Worship</span>
Wednesday Evening Worship <span>6:30 p.m.</span>
</span>
<span>
6:30 p.m.
</span>
</p> </p>
<p className="pb-4 flex justify-center"> <p className="pb-4 flex justify-center">
<Link className="px-4 py-2 border border-transparent text-center text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 md:py-2 md:text-lg cursor-pointer md:px-10" to="/services">Click here to view the 2023 Worship Schedule for more details</Link> <Link
className="px-4 py-2 border border-transparent text-center text-base font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 md:py-2 md:text-lg cursor-pointer md:px-10"
to="/services"
>
Click here to view the 2023 Worship Schedule for more details
</Link>
</p> </p>
</div> </div>
</div> </div>
</div> </div>
</div>
); );
}; };

View File

@ -11,12 +11,12 @@ const HowToBecomeAChristian = () => {
<div className=""> <div className="">
<ScrollRestoration /> <ScrollRestoration />
<section className="mx-24 flex flex-col gap-6"> <section className="mx-4 md:mx-24 flex flex-col md:gap-6">
<h1 className="text-3xl my-12 font-bold flex justify-center"> <h1 className="text-3xl my-12 font-bold flex justify-center">
How do I become a Christian? How do I become a Christian?
</h1> </h1>
<div className="text-gray-700 my-3 grid grid-cols-2 gap-5"> <div className="text-gray-700 my-3 grid grid-cols-1 md:grid-cols-2 md:gap-5">
<section className="flex flex-col gap-5"> <section className="grid flex-col sm:gap-5">
<p> <p>
You're not here by accident. God loves you. He wants you to have a You're not here by accident. God loves you. He wants you to have a
personal relationship with Him through Jesus, His Son. There is personal relationship with Him through Jesus, His Son. There is
@ -43,12 +43,12 @@ const HowToBecomeAChristian = () => {
3:23 3:23
</p> </p>
</section> </section>
<img src={Gap} alt="" /> <img src={Gap} alt="Separated from God" />
</div> </div>
</section> </section>
<section className="mx-24 flex my-7 flex-col gap-6 "> <section className="mx-4 md:mx-24 flex my-7 flex-col md:gap-6 ">
<div className="grid grid-cols-2 gap-5"> <div className="grid grid-cols-1 md:grid-cols-2 gap-5">
<div> <div className="flex justify-center">
<img src={Scales} alt="" /> <img src={Scales} alt="" />
</div> </div>
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">

View File

@ -5,7 +5,17 @@ export default {
"./src/**/*.{js,ts,jsx,tsx}", "./src/**/*.{js,ts,jsx,tsx}",
], ],
theme: { theme: {
extend: {}, extend: {
screens: {
'2xs': { min: '300px' },
xs: { max: '575px' }, // Mobile (iPhone 3 - iPhone XS Max).
sm: { min: '576px', max: '897px' }, // Mobile (matches max: iPhone 11 Pro Max landscape @ 896px).
md: { min: '898px', max: '1199px' }, // Tablet (matches max: iPad Pro @ 1112px).
lg: { min: '1200px' }, // Desktop smallest.
xl: { min: '1259px' }, // Desktop wide.
'2xl': { min: '1359px' } // Desktop widescreen.
},
},
}, },
plugins: [], plugins: [],
} }