extract public pages layout
This commit is contained in:
parent
47aa722697
commit
1e681ca693
29
app/public-area/components/base-layout.tsx
Normal file
29
app/public-area/components/base-layout.tsx
Normal 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;
|
@ -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;
|
||||||
|
23
app/public-area/components/layout.tsx
Normal file
23
app/public-area/components/layout.tsx
Normal 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;
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user