parent
2e7efa5c49
commit
0eca8e5f5f
|
@ -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}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
|
@ -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>
|
||||||
|
)
|
||||||
|
}
|
|
@ -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>
|
||||||
|
)
|
||||||
|
}
|
|
@ -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>
|
||||||
|
)
|
||||||
|
}
|
|
@ -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>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
|
@ -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>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
|
@ -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: (
|
||||||
|
|
Loading…
Reference in New Issue