Add first pass of about and contact pages.

main v0.1.0
Joshua Potter 2023-12-07 08:35:45 -07:00
parent 2e7efa5c49
commit 0eca8e5f5f
7 changed files with 262 additions and 0 deletions

View File

@ -0,0 +1,37 @@
import * as React from "react"
import clsx from "clsx"
type BorderProps<T extends React.ElementType> = {
as?: T
className?: string
position?: "top" | "left"
invert?: boolean
}
export function Border<T extends React.ElementType = "div">({
as,
className,
position = "top",
invert = false,
...props
}: Omit<React.ComponentPropsWithoutRef<T>, keyof BorderProps<T>> &
BorderProps<T>) {
let Component = as ?? "div"
return (
<Component
className={clsx(
"relative before:absolute after:absolute",
invert
? "before:bg-white after:bg-white/10"
: "before:bg-neutral-950 after:bg-neutral-950/10",
position === "top" &&
"before:left-0 before:top-0 before:h-px before:w-6 after:left-8 after:right-0 after:top-0 after:h-px",
position === "left" &&
"before:left-0 before:top-0 before:h-6 before:w-px after:bottom-0 after:left-0 after:top-8 after:w-px",
className
)}
{...props}
/>
)
}

View File

@ -0,0 +1,60 @@
import * as React from "react"
import clsx from "clsx"
import { Border } from "./Border"
export function GridList({
children,
className,
}: {
children: React.ReactNode
className?: string
}) {
return (
<ul
role="list"
className={clsx(
"grid grid-cols-1 gap-10 sm:grid-cols-2 lg:grid-cols-3",
className
)}
>
{children}
</ul>
)
}
export function GridListItem({
title,
children,
className,
invert = false,
}: {
title: string
children: React.ReactNode
className?: string
invert?: boolean
}) {
return (
<li
className={clsx(
"text-base",
invert
? "text-neutral-300 before:bg-white after:bg-white/10"
: "text-neutral-600 before:bg-neutral-950 after:bg-neutral-100",
className
)}
>
<Border position="left" className="pl-8" invert={invert}>
<strong
className={clsx(
"font-semibold",
invert ? "text-white" : "text-neutral-950"
)}
>
{title}.
</strong>{" "}
{children}
</Border>
</li>
)
}

View File

@ -0,0 +1,48 @@
import * as React from "react"
import clsx from "clsx"
import { Container } from "./Container"
import { FadeIn } from "./FadeIn"
export function PageIntro({
eyebrow,
title,
children,
centered = false,
}: {
eyebrow: string
title: string | React.ReactNode
children: React.ReactNode
centered?: boolean
}) {
return (
<Container
className={clsx("mt-24 sm:mt-32 lg:mt-40", centered && "text-center")}
>
<FadeIn>
<h1>
<span className="block font-display text-base font-semibold text-neutral-950">
{eyebrow}
</span>
<span className="sr-only"> - </span>
<span
className={clsx(
"mt-6 block max-w-5xl font-display text-5xl font-medium tracking-tight text-neutral-950 [text-wrap:balance] sm:text-6xl",
centered && "mx-auto"
)}
>
{title}
</span>
</h1>
<div
className={clsx(
"mt-6 max-w-3xl text-xl text-neutral-600",
centered && "mx-auto"
)}
>
{children}
</div>
</FadeIn>
</Container>
)
}

View File

@ -0,0 +1,65 @@
import * as React from "react"
import clsx from "clsx"
import { Container } from "./Container"
export function SectionIntro({
title,
eyebrow,
children,
smaller = false,
invert = false,
...props
}: Omit<
React.ComponentPropsWithoutRef<typeof Container>,
"title" | "children"
> & {
title: string
eyebrow?: string
children?: React.ReactNode
smaller?: boolean
invert?: boolean
}) {
return (
<Container {...props}>
<div className="max-w-2xl">
<h2>
{eyebrow && (
<>
<span
className={clsx(
"mb-6 block font-display text-base font-semibold",
invert ? "text-white" : "text-neutral-950"
)}
>
{eyebrow}
</span>
<span className="sr-only"> - </span>
</>
)}
<span
className={clsx(
"block font-display tracking-tight [text-wrap:balance]",
smaller
? "text-2xl font-semibold"
: "text-4xl font-medium sm:text-5xl",
invert ? "text-white" : "text-neutral-950"
)}
>
{title}
</span>
</h2>
{children && (
<div
className={clsx(
"mt-6 text-xl",
invert ? "text-neutral-300" : "text-neutral-600"
)}
>
{children}
</div>
)}
</div>
</Container>
)
}

View File

@ -0,0 +1,29 @@
import * as React from "react"
import { PageIntro } from "../components/PageIntro"
const Title = (
<span>
The{" "}
<span className="bg-gradient-to-r from-amber-500 via-orange-500 to-amber-500 bg-clip-text text-transparent">
BoardWise
</span>{" "}
Mission
</span>
)
export function About() {
return (
<>
<PageIntro eyebrow="About Us" title={Title}>
<p>A better approach to finding the right coach for you.</p>
<p className="mt-4 text-base">
We are a small group of chess enthusiasts dedicated to helping other
players improve their game as efficiently as they can. We{"'"}re
starting this initiative the best way we know how - with experts in
the field.
</p>
</PageIntro>
</>
)
}

View File

@ -0,0 +1,13 @@
import * as React from "react"
import { PageIntro } from "../components/PageIntro"
export function Contact() {
return (
<>
<PageIntro eyebrow="Contact Us" title="Questions or Comments?">
<p>Tell us how we can improve our site.</p>
</PageIntro>
</>
)
}

View File

@ -2,6 +2,8 @@ import * as React from "react"
import { createBrowserRouter } from "react-router-dom" import { createBrowserRouter } from "react-router-dom"
import { FallbackMessage } from "./components/FallbackMessage" import { FallbackMessage } from "./components/FallbackMessage"
import { About } from "./pages/About"
import { Contact } from "./pages/Contact"
import { Search } from "./pages/Search" import { Search } from "./pages/Search"
export const router = createBrowserRouter([ export const router = createBrowserRouter([
@ -9,6 +11,14 @@ export const router = createBrowserRouter([
path: "/", path: "/",
element: <Search />, element: <Search />,
}, },
{
path: "/about/",
element: <About />,
},
{
path: "/contact/",
element: <Contact />,
},
{ {
path: "*", path: "*",
element: ( element: (