extract public pages layout

This commit is contained in:
m5r 2021-08-30 05:28:42 +08:00
parent 47aa722697
commit 1e681ca693
6 changed files with 119 additions and 165 deletions

View File

@ -0,0 +1,29 @@
import type { FunctionComponent } from "react";
import { Head } from "blitz";
import Header from "./header";
const BaseLayout: FunctionComponent = ({ children }) => (
<>
<Head>
<title>Shellphone: Your Personal Cloud Phone</title>
<link
rel="preload"
href="/fonts/P22MackinacPro-ExtraBold.woff2"
as="font"
type="font/woff2"
crossOrigin="anonymous"
/>
</Head>
<section className="font-inter antialiased bg-white text-gray-900 tracking-tight">
<section className="flex flex-col min-h-screen overflow-hidden">
<Header />
<main className="flex-grow">{children}</main>
</section>
</section>
</>
);
export default BaseLayout;

View File

@ -50,14 +50,6 @@ function DesktopNavLink({ href, label }: NavLinkProps) {
); );
} }
function MobileNavLink({ href, label }: NavLinkProps) {
return (
<Link href={href}>
<a className="flex text-gray-600 hover:text-gray-900 py-2">{label}</a>
</Link>
);
}
function MobileNav() { function MobileNav() {
const [mobileNavOpen, setMobileNavOpen] = useState(false); const [mobileNavOpen, setMobileNavOpen] = useState(false);
@ -183,6 +175,16 @@ function MobileNav() {
</Transition.Root> </Transition.Root>
</div> </div>
); );
function MobileNavLink({ href, label }: NavLinkProps) {
return (
<Link href={href}>
<a onClick={() => setMobileNavOpen(false)} className="flex text-gray-600 hover:text-gray-900 py-2">
{label}
</a>
</Link>
);
}
} }
export default Header; export default Header;

View File

@ -0,0 +1,23 @@
import type { FunctionComponent } from "react";
import BaseLayout from "./base-layout";
type Props = {
title: string;
};
const Layout: FunctionComponent<Props> = ({ children, title }) => (
<BaseLayout>
<section className="max-w-6xl mx-auto px-4 sm:px-6">
<div className="pt-32 pb-10 md:pt-34 md:pb-16">
<div className="max-w-5xl mx-auto">
<h1 className="h1 mb-16 font-extrabold font-mackinac">{title}</h1>
</div>
<div className="max-w-3xl mx-auto text-lg xl:text-xl flow-root">{children}</div>
</div>
</section>
</BaseLayout>
);
export default Layout;

View File

@ -1,42 +1,21 @@
import type { BlitzPage } from "blitz"; import type { BlitzPage } from "blitz";
import { Head } from "blitz";
import Header from "../components/header"; import BaseLayout from "../components/base-layout";
import ReferralBanner from "../components/referral-banner"; import ReferralBanner from "../components/referral-banner";
import Hero from "../components/hero"; import Hero from "../components/hero";
import FAQs from "../components/faqs"; import FAQs from "../components/faqs";
import Footer from "../components/footer";
const LandingPage: BlitzPage = () => { const LandingPage: BlitzPage = () => {
return ( return (
<> <>
<Head>
<title>Shellphone: Your Personal Cloud Phone</title>
<link
rel="preload"
href="/fonts/P22MackinacPro-ExtraBold.woff2"
as="font"
type="font/woff2"
crossOrigin="anonymous"
/>
</Head>
<ReferralBanner /> <ReferralBanner />
<section className="font-inter antialiased bg-white text-gray-900 tracking-tight"> <Hero />
<section className="flex flex-col min-h-screen overflow-hidden"> <FAQs />
<Header />
<main className="flex-grow">
<Hero />
<FAQs />
</main>
<Footer />
</section>
</section>
</> </>
); );
}; };
LandingPage.getLayout = (page) => <BaseLayout>{page}</BaseLayout>;
LandingPage.suppressFirstRenderFlicker = true; LandingPage.suppressFirstRenderFlicker = true;
export default LandingPage; export default LandingPage;

View File

@ -1,10 +1,9 @@
import type { BlitzPage } from "blitz"; import type { BlitzPage } from "blitz";
import { Head, useQuery } from "blitz"; import { useQuery } from "blitz";
import getMetrics from "../queries/get-metrics"; import getMetrics from "../queries/get-metrics";
import Header from "../components/header"; import Layout from "../components/layout";
import Footer from "../components/footer";
const initialData = { const initialData = {
phoneNumbers: 0, phoneNumbers: 0,
@ -17,43 +16,11 @@ const OpenMetrics: BlitzPage = () => {
const { phoneNumbers, smsExchanged, minutesCalled } = metrics ?? initialData; const { phoneNumbers, smsExchanged, minutesCalled } = metrics ?? initialData;
return ( return (
<> <dl className="mt-5 grid grid-cols-1 gap-5 sm:grid-cols-3">
<Head> <Card title="Phone Numbers Registered" value={phoneNumbers} />
<title>Shellphone: Your Personal Cloud Phone</title> <Card title="SMS Exchanged" value={smsExchanged} />
<link <Card title="Minutes on Call" value={minutesCalled} />
rel="preload" </dl>
href="/fonts/P22MackinacPro-ExtraBold.woff2"
as="font"
type="font/woff2"
crossOrigin="anonymous"
/>
</Head>
<section className="font-inter antialiased bg-white text-gray-900 tracking-tight">
<section className="flex flex-col min-h-screen overflow-hidden">
<Header />
<main className="flex-grow">
<section className="max-w-6xl mx-auto px-4 sm:px-6">
<div className="pt-32 pb-10 md:pt-34 md:pb-16">
<div className="max-w-5xl mx-auto">
<h1 className="h1 mb-16 font-extrabold font-mackinac">Open Metrics</h1>
</div>
<div className="max-w-3xl mx-auto text-lg xl:text-xl flow-root">
<dl className="mt-5 grid grid-cols-1 gap-5 sm:grid-cols-3">
<Card title="Phone Numbers Registered" value={phoneNumbers} />
<Card title="SMS Exchanged" value={smsExchanged} />
<Card title="Minutes on Call" value={minutesCalled} />
</dl>
</div>
</div>
</section>
</main>
<Footer />
</section>
</section>
</>
); );
}; };
@ -66,6 +33,7 @@ function Card({ title, value }: any) {
); );
} }
OpenMetrics.getLayout = (page) => <Layout title="Open Metrics">{page}</Layout>;
OpenMetrics.suppressFirstRenderFlicker = true; OpenMetrics.suppressFirstRenderFlicker = true;
export default OpenMetrics; export default OpenMetrics;

View File

@ -5,104 +5,56 @@ import { CheckIcon, XIcon, TerminalIcon } from "@heroicons/react/solid";
import Header from "../components/header"; import Header from "../components/header";
import Footer from "../components/footer"; import Footer from "../components/footer";
import Layout from "../components/layout";
const Roadmap: BlitzPage = () => { const Roadmap: BlitzPage = () => {
return ( return (
<> <ul role="list" className="-mb-8">
<Head> {roadmap.map((feature, index) => {
<title>Shellphone: Your Personal Cloud Phone</title> const isDone = feature.status === "done";
<link const isInProgress = feature.status === "in-progress";
rel="preload" return (
href="/fonts/P22MackinacPro-ExtraBold.woff2" <li key={feature.name}>
as="font" <div className="relative pb-8">
type="font/woff2" {index !== roadmap.length - 1 ? (
crossOrigin="anonymous" <span
/> className="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
</Head> aria-hidden="true"
<section className="font-inter antialiased bg-white text-gray-900 tracking-tight"> />
<section className="flex flex-col min-h-screen overflow-hidden"> ) : null}
<Header /> <div className="relative flex space-x-3">
<div>
<main className="flex-grow"> <span
<section className="max-w-6xl mx-auto px-4 sm:px-6"> className={clsx(
<div className="pt-32 pb-10 md:pt-34 md:pb-16"> isDone ? "bg-green-500" : isInProgress ? "bg-yellow-500" : "bg-gray-400",
<div className="max-w-5xl mx-auto"> "h-8 w-8 rounded-full flex items-center justify-center ring-8 ring-white",
<h1 className="h1 mb-16 font-extrabold font-mackinac">(Rough) Roadmap</h1> )}
>
{isDone ? (
<CheckIcon className="h-5 w-5 text-white" aria-hidden="true" />
) : isInProgress ? (
<TerminalIcon className="h-5 w-5 text-white" aria-hidden="true" />
) : (
<XIcon className="h-5 w-5 text-white" aria-hidden="true" />
)}
</span>
</div> </div>
<div className="min-w-0 flex-1 items-center flex justify-between space-x-4">
<div className="max-w-3xl mx-auto text-lg xl:text-xl flow-root"> <div>
<ul role="list" className="-mb-8"> <p className="text-md xl:text-lg text-gray-900">{feature.name}</p>
{roadmap.map((feature, index) => { </div>
const isDone = feature.status === "done"; {isDone ? (
const isInProgress = feature.status === "in-progress"; <div className="text-right self-start text-md xl:text-lg whitespace-nowrap text-gray-500">
return ( <time>{formatter.format(feature.doneDate)}</time>
<li key={feature.name}> </div>
<div className="relative pb-8"> ) : null}
{index !== roadmap.length - 1 ? (
<span
className="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
aria-hidden="true"
/>
) : null}
<div className="relative flex space-x-3">
<div>
<span
className={clsx(
isDone
? "bg-green-500"
: isInProgress
? "bg-yellow-500"
: "bg-gray-400",
"h-8 w-8 rounded-full flex items-center justify-center ring-8 ring-white",
)}
>
{isDone ? (
<CheckIcon
className="h-5 w-5 text-white"
aria-hidden="true"
/>
) : isInProgress ? (
<TerminalIcon
className="h-5 w-5 text-white"
aria-hidden="true"
/>
) : (
<XIcon
className="h-5 w-5 text-white"
aria-hidden="true"
/>
)}
</span>
</div>
<div className="min-w-0 flex-1 items-center flex justify-between space-x-4">
<div>
<p className="text-md xl:text-lg text-gray-900">
{feature.name}
</p>
</div>
{isDone ? (
<div className="text-right self-start text-md xl:text-lg whitespace-nowrap text-gray-500">
<time>
{formatter.format(feature.doneDate)}
</time>
</div>
) : null}
</div>
</div>
</div>
</li>
);
})}
</ul>
</div> </div>
</div> </div>
</section> </div>
</main> </li>
);
<Footer /> })}
</section> </ul>
</section>
</>
); );
}; };
@ -185,6 +137,7 @@ const formatter = Intl.DateTimeFormat("en-US", {
year: "numeric", year: "numeric",
}); });
Roadmap.getLayout = (page) => <Layout title="(Rough) Roadmap">{page}</Layout>;
Roadmap.suppressFirstRenderFlicker = true; Roadmap.suppressFirstRenderFlicker = true;
export default Roadmap; export default Roadmap;