Merge branch 'master' of https://github.com/lucasPDY/oxen-website into add-faq
This commit is contained in:
commit
4fc0d4c30e
|
@ -13,7 +13,7 @@ interface Props {
|
|||
}
|
||||
|
||||
export function CardGrid({ rows, children }: Props) {
|
||||
const { isMobile, isDesktop, isHuge } = useContext(ScreenContext);
|
||||
const { isDesktop, isHuge } = useContext(ScreenContext);
|
||||
|
||||
const [ref, { width }] = useMeasure();
|
||||
const widthOfCardPx = 200;
|
||||
|
@ -37,25 +37,7 @@ export function CardGrid({ rows, children }: Props) {
|
|||
|
||||
return (
|
||||
<>
|
||||
{isMobile ? (
|
||||
<div className="">
|
||||
<HorizontalScrollable>
|
||||
{children.map(child => (
|
||||
<div
|
||||
key={uuid()}
|
||||
style={{
|
||||
width: '80vw',
|
||||
minWidth: '275px',
|
||||
maxWidth: '330px',
|
||||
}}
|
||||
className="py-4"
|
||||
>
|
||||
{child}
|
||||
</div>
|
||||
))}
|
||||
</HorizontalScrollable>
|
||||
</div>
|
||||
) : (
|
||||
{
|
||||
<Contained>
|
||||
<div ref={ref} className={classNames('flex flex-col', spacingY)}>
|
||||
{_.chunk(cards, grouping).map(group => (
|
||||
|
@ -69,7 +51,7 @@ export function CardGrid({ rows, children }: Props) {
|
|||
))}
|
||||
</div>
|
||||
</Contained>
|
||||
)}
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -60,8 +60,8 @@ export function MobileHeader() {
|
|||
<TriangleSVG
|
||||
onClick={() => toggleSideMenu()}
|
||||
className={classNames(
|
||||
'h-3 fill-current text-primary transform outline-none duration-300 cursor-pointer',
|
||||
sideMenuExpanded ? 'rotate-180' : '-rotate-60',
|
||||
'h-4 fill-current text-primary transform outline-none duration-300 cursor-pointer',
|
||||
sideMenuExpanded ? 'rotate-90' : '',
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
@ -71,8 +71,8 @@ export function MobileHeader() {
|
|||
<TriangleSVG
|
||||
onClick={() => toggleMobileMenu()}
|
||||
className={classNames(
|
||||
'h-4 transform outline-none duration-300 cursor-pointer',
|
||||
headerMobileMenuExpanded ? '-rotate-90' : 'rotate-90',
|
||||
'h-4 fill-current text-primary transform outline-none duration-300 cursor-pointer',
|
||||
headerMobileMenuExpanded ? 'rotate-90' : '',
|
||||
)}
|
||||
/>
|
||||
<MobileMenu />
|
||||
|
|
|
@ -59,7 +59,7 @@ export function SideMenuInner() {
|
|||
{!isDesktop && (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex flex-col pt-8 font-medium uppercase font-prompt text-lg',
|
||||
'flex flex-col pt-8 pl-6 font-medium uppercase font-prompt text-lg',
|
||||
)}
|
||||
>
|
||||
{_.chunk(NAVIGATION.MENU_ITEMS, 2).map(group => (
|
||||
|
@ -80,28 +80,32 @@ export function SideMenuInner() {
|
|||
<div className="px-6 pb-3">
|
||||
<SocialsRow />
|
||||
|
||||
<div className="flex items-center justify-between font-medium text-secondary whitespace-nowrap">
|
||||
View Oxen on{' '}
|
||||
<div className="flex items-center">
|
||||
<a
|
||||
href="https://www.coingecko.com/en/coins/oxen"
|
||||
target="_blank"
|
||||
rel="dofollow"
|
||||
className="flex items-center mx-2 space-x-1 font-bold hover:underline"
|
||||
>
|
||||
<img className="h-5" src="/img/coingecko.png" />
|
||||
<span>CoinGecko</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://coinmarketcap.com/currencies/oxen/"
|
||||
target="_blank"
|
||||
rel="dofollow"
|
||||
className="flex items-center mx-2 space-x-1 font-bold hover:underline"
|
||||
>
|
||||
<img className="h-5" src="/img/coinmarketcap.png" />
|
||||
<span>CMC</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="flex items-center justify-between font-medium whitespace-nowrap">
|
||||
<a
|
||||
href="/downloads/oxen-media-kit.zip"
|
||||
target="_blank"
|
||||
className="flex items-center space-x-1 hover:underline hover:text-secondary"
|
||||
>
|
||||
<span>Media Kit</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://coinmarketcap.com/currencies/oxen/"
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
className="flex items-center space-x-1 hover:underline hover:text-secondary"
|
||||
>
|
||||
<img className="h-5" src="/img/coinmarketcap.png" />
|
||||
<span>CMC</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.coingecko.com/en/coins/oxen"
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
className="flex items-center space-x-1 hover:underline hover:text-secondary"
|
||||
>
|
||||
<img className="h-5" src="/img/coingecko.png" />
|
||||
<span>CoinGecko</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
@ -114,13 +118,13 @@ export function SideMenuInner() {
|
|||
}
|
||||
|
||||
const SocialsRow = () => {
|
||||
const { isDesktop } = useContext(ScreenContext);
|
||||
const { isTablet } = useContext(ScreenContext);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex pt-3 pb-3 space-x-3 justify-between',
|
||||
isDesktop && 'justify-between',
|
||||
'flex pt-3 pb-3',
|
||||
isTablet ? 'justify-start space-x-5 px-6' : 'justify-between',
|
||||
)}
|
||||
>
|
||||
<a href="https://t.me/Oxen_Community" target="_blank" rel="noreferrer">
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
const METADATA = {
|
||||
OXEN_HOST_URL: 'https://oxen.io',
|
||||
TITLE_SUFFIX: 'Oxen | Privacy made simple.',
|
||||
SITE_META_DESCRIPTION:
|
||||
'Oxen is built by the OPTF, a passionate team of advocates, creatives, and engineers building a world where the internet is open, software is free and accessible, and your privacy is protected. The OPTF also builds other platforms using Oxen technology, and supports other developers in building on Oxen.',
|
||||
ROADMAP: {
|
||||
DESCRIPTION: "View Oxen's plan for the future here.",
|
||||
},
|
||||
404: {
|
||||
DESCRIPTION: "Oopsy, here's our 404 page.",
|
||||
},
|
||||
BLOG: {
|
||||
DESCRIPTION: "View Oxen's Blog Updates Here",
|
||||
URL: 'https://oxen.io/blog',
|
||||
},
|
||||
};
|
||||
|
||||
export default METADATA;
|
||||
|
|
|
@ -127,8 +127,6 @@ const NAVIGATION = {
|
|||
SIDE_MENU_ITEMS,
|
||||
BLOG_REGEX: /^\/(blog)([?tag=[\w-]*)?([?&]page=[0-9]{1,3})?/,
|
||||
POST_REGEX: /^\/(blog\/)(([\w-]{1,100})|(\[slug\]))$/,
|
||||
SITE_META_DESCRIPTION:
|
||||
'Oxen is built by the Loki Foundation, a passionate team of advocates, creatives, and engineers building a world where the internet is open, software is free and accessible, and your privacy is protected. The Loki Foundation also builds other platforms using Oxen technology, and supports other developers in building on Oxen.',
|
||||
};
|
||||
|
||||
export default NAVIGATION;
|
||||
|
|
|
@ -2,9 +2,9 @@ import classNames from 'classnames';
|
|||
import Head from 'next/head';
|
||||
import React, { useContext } from 'react';
|
||||
// import _404 from '../assets/svgs/404.svg';
|
||||
import { UI } from '../constants';
|
||||
import { UI, METADATA } from '../constants';
|
||||
import { ScreenContext } from '../contexts/screen';
|
||||
import { generateTitle } from '../utils/metadata';
|
||||
import { generateTitle, generateURL } from '../utils/metadata';
|
||||
|
||||
function oxen404() {
|
||||
const { isMobile, isTablet, isDesktop, isHuge } = useContext(ScreenContext);
|
||||
|
@ -47,10 +47,24 @@ function oxen404() {
|
|||
width: '9rem',
|
||||
};
|
||||
|
||||
const pageTitle = generateTitle('404');
|
||||
const pageURL = generateURL('/404');
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center flex-grow h-full">
|
||||
<Head>
|
||||
<title>{generateTitle('404')}</title>
|
||||
<title>{pageTitle}</title>
|
||||
<meta name="description" content={METADATA['404'].DESCRIPTION}></meta>
|
||||
<meta property="og:title" content={pageTitle} key="ogtitle" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content={METADATA['404'].DESCRIPTION}
|
||||
key="ogdesc"
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={pageURL} />
|
||||
|
||||
<link rel="canonical" href={pageURL}></link>
|
||||
</Head>
|
||||
|
||||
<div style={wrapperStyles} className="flex items-center flex-grow">
|
||||
|
@ -65,13 +79,13 @@ function oxen404() {
|
|||
<div style={_404SectionStyles} className="absolute left-0 z-50">
|
||||
<h1
|
||||
style={_404TitleStyles}
|
||||
className="-mb-4 text-opacity-25 font-sans text-primary text-8xl"
|
||||
className="-mb-4 font-sans text-opacity-25 text-primary text-8xl"
|
||||
>
|
||||
404
|
||||
</h1>
|
||||
<p
|
||||
style={_404TextStyles}
|
||||
className="text-4xl tracking-tight font-sans text-primary"
|
||||
className="font-sans text-4xl tracking-tight text-primary"
|
||||
>
|
||||
Nothing found here.
|
||||
</p>
|
||||
|
|
|
@ -4,11 +4,11 @@ import React, { useEffect } from 'react';
|
|||
import { useDispatch } from 'react-redux';
|
||||
import { Contained } from '../components/Contained';
|
||||
import { RichBody } from '../components/RichBody';
|
||||
import { NAVIGATION } from '../constants';
|
||||
import { NAVIGATION, METADATA } from '../constants';
|
||||
import { CmsApi, unslugify } from '../services/cms';
|
||||
import { PageType, setPageType, SideMenuItem } from '../state/navigation';
|
||||
import { ISplitPage } from '../types/cms';
|
||||
import { generateTitle } from '../utils/metadata';
|
||||
import { generateTitle, generateURL } from '../utils/metadata';
|
||||
|
||||
interface IPath {
|
||||
params: { page: string; isRoadmap?: boolean };
|
||||
|
@ -19,7 +19,6 @@ export async function getStaticPaths() {
|
|||
// Hardcoded in navigation constants.
|
||||
// Contentful can edit entries but cannot add/remove
|
||||
// without touching code.
|
||||
|
||||
const paths: IPath[] = Object.values(NAVIGATION.SIDE_MENU_ITEMS).map(
|
||||
item => ({
|
||||
params: { page: item.href },
|
||||
|
@ -30,8 +29,8 @@ export async function getStaticPaths() {
|
|||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
const id = unslugify(String(params?.page) ?? '');
|
||||
|
||||
const href = params?.page ?? '';
|
||||
const id = unslugify(String(href));
|
||||
// Roadmap page is special 👁️👄👁️
|
||||
if (SideMenuItem[id] == [SideMenuItem.ROADMAP]) {
|
||||
// query all FAQ items from contentful
|
||||
|
@ -39,6 +38,7 @@ export async function getStaticProps({ params }) {
|
|||
props: {
|
||||
page: null,
|
||||
isRoadmap: true,
|
||||
href: `/${href}`, // the '/' is removed from the href from getStaticPaths(), so let's add it back here
|
||||
},
|
||||
revalidate: 60,
|
||||
};
|
||||
|
@ -57,7 +57,6 @@ export async function getStaticProps({ params }) {
|
|||
|
||||
const cms = new CmsApi();
|
||||
const page = await cms.fetchPageById(SideMenuItem[id]);
|
||||
|
||||
if (!page) {
|
||||
return { notFound: true };
|
||||
}
|
||||
|
@ -66,6 +65,7 @@ export async function getStaticProps({ params }) {
|
|||
props: {
|
||||
page,
|
||||
isRoadmap: false,
|
||||
href: `/${href}`,
|
||||
},
|
||||
revalidate: 60,
|
||||
};
|
||||
|
@ -74,25 +74,54 @@ export async function getStaticProps({ params }) {
|
|||
function Page({
|
||||
page,
|
||||
isRoadmap,
|
||||
href,
|
||||
}: {
|
||||
page: ISplitPage | null;
|
||||
isRoadmap?: boolean;
|
||||
href: string;
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
dispatch(setPageType(PageType.NORMAL));
|
||||
}, []);
|
||||
const pageTitle = generateTitle(
|
||||
isRoadmap
|
||||
? NAVIGATION.SIDE_MENU_ITEMS[SideMenuItem.ROADMAP].label
|
||||
: page?.label,
|
||||
);
|
||||
|
||||
const pageDescription = isRoadmap
|
||||
? METADATA.ROADMAP.DESCRIPTION
|
||||
: page?.title;
|
||||
|
||||
const pageURL = generateURL(
|
||||
isRoadmap ? NAVIGATION.SIDE_MENU_ITEMS[SideMenuItem.ROADMAP].href : href,
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
{generateTitle(
|
||||
isRoadmap
|
||||
? NAVIGATION.SIDE_MENU_ITEMS[SideMenuItem.ROADMAP].label
|
||||
: page?.label,
|
||||
)}
|
||||
</title>
|
||||
<title>{pageTitle}</title>
|
||||
<meta name="description" content={pageDescription}></meta>
|
||||
<meta property="og:title" content={pageTitle} key="ogtitle" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content={pageDescription}
|
||||
key="ogdesc"
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta
|
||||
property="og:image"
|
||||
content={page?.hero?.imageUrl}
|
||||
key="ogimage"
|
||||
/>
|
||||
<meta property="og:url" content={pageURL} />
|
||||
|
||||
<link rel="canonical" href={pageURL}></link>
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={pageTitle} />
|
||||
<meta name="twitter:description" content={pageDescription} />
|
||||
<meta name="twitter:image" content={page?.hero?.imageUrl} />
|
||||
</Head>
|
||||
|
||||
<div className="bg-alt">
|
||||
|
|
|
@ -63,6 +63,9 @@ function App({ Component, pageProps }: AppProps) {
|
|||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1"
|
||||
></meta>
|
||||
<meta property="og:site_name" content="Oxen" key="ogsitename" />
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta name="apple-itunes-app" content="app-id=1547745078" />
|
||||
</Head>
|
||||
|
||||
<Layout>
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Article } from '../../components/article/Article';
|
|||
import { CmsApi } from '../../services/cms';
|
||||
import { PageType, setPageType, setPostTitle } from '../../state/navigation';
|
||||
import { IPost } from '../../types/cms';
|
||||
import { generateTitle } from '../../utils/metadata';
|
||||
import { generateTitle, generateURL } from '../../utils/metadata';
|
||||
|
||||
interface IPath {
|
||||
params: { slug: string };
|
||||
|
@ -43,7 +43,7 @@ export async function getStaticProps({ params }) {
|
|||
|
||||
const cms = new CmsApi();
|
||||
const post = await cms.fetchBlogBySlug(String(params?.slug) ?? '');
|
||||
|
||||
const url = generateURL(params?.slug ? `/blog/${params?.slug}` : '/blog');
|
||||
if (!post) {
|
||||
return { notFound: true };
|
||||
}
|
||||
|
@ -51,13 +51,14 @@ export async function getStaticProps({ params }) {
|
|||
return {
|
||||
props: {
|
||||
post,
|
||||
url,
|
||||
},
|
||||
revalidate: 60,
|
||||
};
|
||||
}
|
||||
|
||||
// Parallax on bg as mouse moves
|
||||
function Post({ post }: { post: IPost }) {
|
||||
function Post({ post, url }: { post: IPost; url: string }) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -66,28 +67,30 @@ function Post({ post }: { post: IPost }) {
|
|||
}, []);
|
||||
|
||||
const pageTitle = generateTitle(post?.title);
|
||||
const imageURL = post?.featureImage?.imageUrl;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{pageTitle}</title>
|
||||
|
||||
<meta name="image_src" content={post?.featureImage?.imageUrl} />
|
||||
<meta name="image_url" content={post?.featureImage?.imageUrl} />
|
||||
<meta name="keywords" content={post?.tags?.join(' ')} />
|
||||
<meta
|
||||
property="og:image"
|
||||
content={post?.featureImage?.imageUrl}
|
||||
key="ogimage"
|
||||
/>
|
||||
|
||||
<meta property="og:site_name" content="oxen.io" key="ogsitename" />
|
||||
<meta name="description" content={post?.description}></meta>
|
||||
<meta property="og:title" content={pageTitle} key="ogtitle" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content={post?.description}
|
||||
key="ogdesc"
|
||||
/>
|
||||
<meta property="og:type" content="article" />
|
||||
<meta name="image_src" content={imageURL} />
|
||||
<meta name="image_url" content={imageURL} />
|
||||
<meta name="keywords" content={post?.tags?.join(' ')} />
|
||||
<meta property="og:image" content={imageURL} key="ogimage" />
|
||||
<meta property="og:url" content={url} />
|
||||
<link rel="canonical" href={url}></link>{' '}
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={pageTitle} />
|
||||
<meta name="twitter:description" content={post?.description} />
|
||||
<meta name="twitter:image" content={imageURL} />
|
||||
</Head>
|
||||
|
||||
<div className="bg-alt">
|
||||
|
|
|
@ -9,7 +9,7 @@ import { ArticleCardFeature } from '../../components/cards/ArticleCardFeature';
|
|||
import { CardGrid } from '../../components/cards/CardGrid';
|
||||
import { Contained } from '../../components/Contained';
|
||||
import { TagBlock } from '../../components/TagBlock';
|
||||
import { CMS } from '../../constants';
|
||||
import { CMS, METADATA } from '../../constants';
|
||||
import { CmsApi } from '../../services/cms';
|
||||
import { PageType, setPageType } from '../../state/navigation';
|
||||
import { IPost } from '../../types/cms';
|
||||
|
@ -131,10 +131,28 @@ const Blog = (props: Props) => {
|
|||
</Contained>
|
||||
);
|
||||
|
||||
const pageTitle = generateTitle('Blog');
|
||||
const featuredImageURL = featuredPost?.featureImage?.imageUrl;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Head>
|
||||
<title>{generateTitle('Blog')}</title>
|
||||
<title>{pageTitle}</title>
|
||||
<meta name="description" content={METADATA.BLOG.DESCRIPTION}></meta>
|
||||
<meta property="og:title" content={pageTitle} key="ogtitle" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content={METADATA.BLOG.DESCRIPTION}
|
||||
key="ogdesc"
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content={featuredImageURL} key="ogimage" />
|
||||
<meta property="og:url" content={METADATA.BLOG.URL} />
|
||||
<link rel="canonical" href={METADATA.BLOG.URL}></link>
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={pageTitle} />
|
||||
<meta name="twitter:description" content={METADATA.BLOG.DESCRIPTION} />
|
||||
<meta name="twitter:image" content={featuredImageURL} />
|
||||
</Head>
|
||||
|
||||
<div className="flex flex-col w-full mt-12 mb-6 space-y-6 bg-alt">
|
||||
|
|
|
@ -2,26 +2,40 @@ import Head from 'next/head';
|
|||
import React from 'react';
|
||||
import { HomeHero } from '../components/HomeHero';
|
||||
import { HomeHeroBubble } from '../components/HomeHeroBubble';
|
||||
import { METADATA, NAVIGATION } from '../constants';
|
||||
import { METADATA } from '../constants';
|
||||
|
||||
const Index = () => {
|
||||
const imageURL = `${METADATA.OXEN_HOST_URL}/site-banner.png`;
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{METADATA.TITLE_SUFFIX}</title>
|
||||
<meta
|
||||
name="description"
|
||||
content={METADATA.SITE_META_DESCRIPTION}
|
||||
></meta>
|
||||
<meta
|
||||
property="og:title"
|
||||
content="Oxen - Privacy should be simple."
|
||||
key="title"
|
||||
content={METADATA.TITLE_SUFFIX}
|
||||
key="ogtitle"
|
||||
/>
|
||||
<meta property="og:image" content={'site-banner.png'} key="ogimage" />
|
||||
<meta property="og:site_name" content="oxen.io" key="ogsitename" />
|
||||
<meta property="og:title" content={'Oxen'} key="ogtitle" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content={NAVIGATION.SITE_META_DESCRIPTION}
|
||||
content={METADATA.SITE_META_DESCRIPTION}
|
||||
key="ogdesc"
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content={imageURL} key="ogimage" />
|
||||
<meta property="og:url" content={METADATA.OXEN_HOST_URL} />
|
||||
|
||||
<link rel="canonical" href={METADATA.OXEN_HOST_URL}></link>
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={METADATA.TITLE_SUFFIX} />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content={METADATA.SITE_META_DESCRIPTION}
|
||||
/>
|
||||
<meta name="twitter:image" content={imageURL} />
|
||||
</Head>
|
||||
|
||||
{/* Only visible when no pages are open */}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import Head from 'next/head';
|
||||
import React from 'react';
|
||||
import { useMeasure } from 'react-use';
|
||||
import { NAVIGATION } from '../constants';
|
||||
import { NAVIGATION, METADATA } from '../constants';
|
||||
import { SideMenuItem } from '../state/navigation';
|
||||
import { generateTitle } from '../utils/metadata';
|
||||
import { generateTitle, generateURL } from '../utils/metadata';
|
||||
|
||||
function Roadmap() {
|
||||
const [ref, { width, height }] = useMeasure();
|
||||
|
@ -18,14 +18,36 @@ function Roadmap() {
|
|||
console.log('roadmap ➡️ width:', width);
|
||||
console.log('roadmap ➡️ ratio:', aspectRatio);
|
||||
|
||||
const pageTitle = generateTitle(
|
||||
NAVIGATION.SIDE_MENU_ITEMS[SideMenuItem.ROADMAP].label,
|
||||
);
|
||||
const pageURL = generateURL(
|
||||
NAVIGATION.SIDE_MENU_ITEMS[SideMenuItem.ROADMAP].href,
|
||||
);
|
||||
const imageURL = `${METADATA.OXEN_HOST_URL}/site-banner.png`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
{generateTitle(
|
||||
NAVIGATION.SIDE_MENU_ITEMS[SideMenuItem.ROADMAP].label,
|
||||
)}
|
||||
</title>
|
||||
<title>{pageTitle}</title>
|
||||
<meta name="description" content={METADATA.ROADMAP.DESCRIPTION}></meta>
|
||||
<meta property="og:title" content={pageTitle} key="ogtitle" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content={METADATA.ROADMAP.DESCRIPTION}
|
||||
key="ogdesc"
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={pageURL} />
|
||||
|
||||
<link rel="canonical" href={pageURL}></link>
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={pageTitle} />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content={METADATA.ROADMAP.DESCRIPTION}
|
||||
/>
|
||||
<meta name="twitter:image" content={imageURL} />
|
||||
</Head>
|
||||
|
||||
<div className="mx-4">
|
||||
|
@ -46,7 +68,7 @@ function Roadmap() {
|
|||
</h2>
|
||||
<img
|
||||
style={{ maxHeight: horizontal ? '90%' : 'auto' }}
|
||||
src={`img/session-${horizontal ? 'x' : 'y'}.jpg`}
|
||||
src={`img/session-${horizontal ? 'x' : 'y'}.png`}
|
||||
className="w-full rounded-md"
|
||||
/>
|
||||
</div>
|
||||
|
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 472 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.7 MiB |
Binary file not shown.
Before Width: | Height: | Size: 267 KiB |
Binary file not shown.
After Width: | Height: | Size: 873 KiB |
|
@ -6,3 +6,7 @@ export function generateTitle(prefix: string) {
|
|||
? `${titleCase(prefix)} - ${METADATA.TITLE_SUFFIX}`
|
||||
: METADATA.TITLE_SUFFIX;
|
||||
}
|
||||
|
||||
export function generateURL(prefix: string) {
|
||||
return prefix ? `${METADATA.OXEN_HOST_URL}${prefix}` : METADATA.OXEN_HOST_URL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue