gatsby#PageProps TypeScript Examples
The following examples show how to use
gatsby#PageProps.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: using-typescript.tsx From vhealth-gatsby with MIT License | 6 votes |
UsingTypescript: React.FC<PageProps<DataProps>> = ({ data, path }) => (
<Layout>
<SEO title="Using TypeScript" />
<h1>Gatsby supports TypeScript by default!</h1>
<p>This means that you can create and write <em>.ts/.tsx</em> files for your pages, components etc. Please note that the <em>gatsby-*.js</em> files (like gatsby-node.js) currently don't support TypeScript yet.</p>
<p>For type checking you'll want to install <em>typescript</em> via npm and run <em>tsc --init</em> to create a <em>.tsconfig</em> file.</p>
<p>You're currently on the page "{path}" which was built on {data.site.buildTime}.</p>
<p>To learn more, head over to our <a href="https://www.gatsbyjs.org/docs/typescript/">documentation about TypeScript</a>.</p>
<Link to="/">Go back to the homepage</Link>
</Layout>
)
Example #2
Source File: Letter.tsx From defund12.org with MIT License | 6 votes |
/**
* Initialize the component and its state.
* @param {PageProps<EmailProps>} props
*/
constructor(props: PageProps<LetterProps>) {
super(props);
console.log(this.props);
this.siteConfig = this.props.data.siteConfig;
this.letterData = this.props.data.markdownRemark.frontmatter;
this.layoutProps = {
pageTitle: `Defund12 in ${this.letterData.city}, ${this.letterData.state}`,
meta: `Send a pre-written letter directly to ${this.letterData.city}, ${this.letterData.state} officials`,
metaQueryString: queryString.stringify({
state: this.letterData.state,
city: this.letterData.city,
}),
layout: "letter",
};
}
Example #3
Source File: tags-template.tsx From blog.ojisan.io with MIT License | 6 votes |
UsingTypescript: React.FC<PageProps<GatsbyTypes.TagTemplateQuery>> = (
props
) => {
const nodes = props.data.allMarkdownRemark.nodes;
const frontmatters = nodes.map((node) => node.frontmatter);
if (frontmatters.some((f) => f === undefined)) {
throw new Error();
}
return (
<Layout>
<Seo title="blog.ojisan.io" />
<div className={cards}>
{frontmatters.map((f) => {
return <Card data={f} key={f?.path} />;
})}
</div>
</Layout>
);
}
Example #4
Source File: 404.tsx From defund12.org with MIT License | 6 votes |
/**
* The site's 404 page.
*/
export default class NotFound extends React.Component<PageProps<SiteProps>> {
/**
* React render method.
* @return {React.ReactNode} the rendered component
*/
render(): React.ReactNode {
return (
<Layout {...this.props.data.siteConfig}>
<main className="content">
<div>
<h1 className="pagetitle">Page not found</h1>
<br />
<h3>
<i>We're sorry, we couldn't find the page you requested</i>
</h3>
</div>
</main>
</Layout>
);
}
}
Example #5
Source File: index.tsx From defund12.org with MIT License | 6 votes |
/**
* The landing/home/root page. Defund 12!
*/
export default class Index extends React.Component<PageProps<SiteProps>> {
/**
* Initialize the component.
* @param {PageProps<SiteProps>} props
*/
constructor(props: PageProps<SiteProps>) {
super(props);
}
/**
* React render method.
* @return {React.ReactNode} the rendered component
*/
render(): React.ReactNode {
return (
<Layout>
<EmailList />
</Layout>
);
}
}
Example #6
Source File: letterSuccess.tsx From defund12.org with MIT License | 6 votes |
/** The page for when a letter is successfully sent */
export default class LetterSuccess extends React.Component<
PageProps<SiteProps>
> {
/**
* React render method.
* @return {React.ReactNode} the rendered component
*/
render(): React.ReactNode {
return (
<Layout {...this.props.data.siteConfig}>
<article className="letterContentSection">
<div className="container">
<div className="letterContent">
<div>
<h1 className="pagetitle">Letters Sent!</h1>
<br />
<p>
Thanks, you should get an email in a bit confirming your
postcards have been sent
</p>
<p className="italic">
If you don't in like ... 15 minutes or so, email us at{" "}
<a href="mailto:[email protected]">
[email protected]
</a>
</p>
<br />
<br />
</div>
</div>
</div>
</article>
</Layout>
);
}
}
Example #7
Source File: tags.tsx From blog.ojisan.io with MIT License | 6 votes |
TagsPage: React.FC<PageProps<GatsbyTypes.TagsQuery>> = (props) => {
const tags = props.data.allMarkdownRemark.group;
if (tags.some((tag) => tag === undefined)) throw new Error("invalid tag");
const kebabTags = tags.map((tag) => ({
...tag,
fieldValue: toLower(tag.fieldValue || ""),
}));
return (
<Layout>
<Seo title="blog.ojisan.io" />
<div className={cards}>
{kebabTags.map((node) => (
<Link key={node.fieldValue} to={`/tags/${node.fieldValue}`}>
{node.fieldValue}({node.totalCount})
</Link>
))}
</div>
</Layout>
);
}
Example #8
Source File: index.tsx From blog.ojisan.io with MIT License | 6 votes |
UsingTypescript: React.FC<PageProps<GatsbyTypes.BlogPostsQuery>> = (
props
) => {
const nodes = props.data.blogs.nodes;
const frontmatters = nodes.map((node) => node.frontmatter);
if (frontmatters.some((f) => f === undefined)) {
throw new Error();
}
return (
<Layout>
<Seo title="blog.ojisan.io" />
<div className={cards}>
{frontmatters.map((f) => {
return <Card data={f} key={f?.path} />;
})}
</div>
</Layout>
);
}
Example #9
Source File: categoryPage.tsx From mswjs.io with MIT License | 6 votes |
CategoryPage: React.FC<PageProps<never, PageContext>> = ({
pageContext,
}) => {
const {
categoryTitle,
categoryDescription,
childNavTree,
navTree,
breadcrumbs,
} = pageContext
return (
<DocsLayout navTree={navTree} breadcrumbs={breadcrumbs}>
<Seo title={categoryTitle} description={categoryDescription} />
<Heading level={1}>{categoryTitle}</Heading>
{categoryDescription && (
<TextLead dangerouslySetInnerHTML={{ __html: categoryDescription }} />
)}
{childNavTree[0]?.items && (
<>
<hr />
<CategoryChildPages items={childNavTree[0].items} />
</>
)}
</DocsLayout>
)
}
Example #10
Source File: terms.tsx From nyxo-website with MIT License | 6 votes |
TermsPage: FC<PageProps<Props>> = ({ location: { pathname }, data: { markdownRemark: { html }, termsMeta, dataJson: { terms: { description, title }, }, }, }) => ( <Layout> <SEO title={title} pathName={pathname} description={description} staticImage={true} image={termsMeta.childImageSharp.fixed.src} /> <PageHeader title={title} text="" /> <Container> <Content dangerouslySetInnerHTML={{ __html: html }} /> </Container> </Layout> )
Example #11
Source File: index.tsx From nyxo-website with MIT License | 6 votes |
CoachingPage = (props: PageProps<AuthorsPageQueryQuery>) => {
const {
data: {
allDataJson: { nodes },
coachingMeta,
},
location: { pathname },
} = props
const {
title = "Authors Page",
description = "Nyxo Authors",
} = nodes[0].authors
return (
<Layout>
<SEO
title={title}
description={description}
pathName={pathname}
image={coachingMeta?.childImageSharp?.fixed?.src}
staticImage={true}
/>
<PageHeader
title="Nyxo Authors"
text="Explore the people behind Nyxo Sleep Coaching"
/>
<Container>
<Authors>
<AuthorList />
</Authors>
</Container>
</Layout>
)
}
Example #12
Source File: privacy.tsx From nyxo-website with MIT License | 6 votes |
PrivacyPage: FC<PageProps<Props>> = ({
location: { pathname },
data: {
markdownRemark: { html },
privacyMeta,
dataJson: {
privacy: { description, title },
},
},
}) => {
return (
<Layout>
<SEO
title={title}
pathName={pathname}
description={description}
staticImage={true}
image={privacyMeta.childImageSharp.fixed.src}
/>
<PageHeader title={title} text="" />
<Container>
<Content dangerouslySetInnerHTML={{ __html: html }} />
</Container>
</Layout>
)
}
Example #13
Source File: Email.tsx From defund12.org with MIT License | 6 votes |
/**
* Initialize the component and its state.
* @param {PageProps<EmailProps>} props
*/
constructor(props: PageProps<EmailProps>) {
super(props);
this.siteConfig = this.props.data.siteConfig;
this.emailData = this.props.data.markdownRemark.frontmatter;
this.layoutProps = {
pageTitle: `Defund12 in ${this.emailData.city}, ${this.emailData.state}`,
meta: `Send a pre-written email directly to ${this.emailData.city}, ${this.emailData.state} officials`,
metaQueryString: queryString.stringify({
state: this.emailData.state,
city: this.emailData.city,
}),
layout: "email",
};
this.state = new EmailState();
}
Example #14
Source File: coaching.tsx From nyxo-website with MIT License | 5 votes |
CoachingPage: FC<PageProps<Props, { language: string }>> = (props) => {
const {
data: {
weeks: { nodes: weeks },
allContentfulLesson: { nodes: lessons },
habits: { nodes: habits },
recentlyUpdated: { nodes: recentlyUpdated },
coachingMeta,
coachingCover,
},
pageContext: { language },
location: { pathname },
} = props
const { t } = useTranslation()
return (
<Layout>
<SEO
title={t("COACHING.TITLE")}
description={t("COACHING.DESCRIPTION")}
pathName={pathname}
image={coachingMeta?.childImageSharp?.fixed?.src}
staticImage={true}
/>
<Container>
<Title>{t("COACHING.TITLE")}</Title>
<Subtitle>{t("COACHING.SUBTITLE")}</Subtitle>
<CoverPhotoContainer>
<Cover fluid={coachingCover.childImageSharp.fluid} />
</CoverPhotoContainer>
<SuggestedContent lessons={lessons} habits={habits} />
<P>{t("COACHING.INTRODUCTION")}</P>
<H3>{t("COACHING.HOW_IT_WORKS")}</H3>
<P>{t("COACHING.HOW_IT_WORKS_TEXT")}</P>
<LessonHighlights language={language} />
<H2>{t("COACHING.WEEKS")}</H2>
<P>{t("COACHING.WEEKS_TEXT")}</P>
<Weeks>
{weeks.map((week: ContentfulWeek) => {
return (
<WeekCard
bookmarked={false}
key={`${week?.slug}`}
path={`/week/${week?.slug}`}
intro={week?.intro}
name={week?.weekName}
duration={week?.duration}
lessons={week?.lessons}
coverPhoto={week?.coverPhoto?.fluid as FluidObject}
slug={week.slug}
/>
)
})}
</Weeks>
<HabitHighlights locale={language} />
<H2>{t("COACHING.AUTHORS")}</H2>
<P>{t("COACHING.AUTHORS_TEXT")}</P>
<AuthorList locale={language} />
</Container>
<GetAppBanner />
</Layout>
)
}
Example #15
Source File: {MarkdownRemark.frontmatter__path}.tsx From blog.ojisan.io with MIT License | 5 votes |
Template: VFC<PageProps<GatsbyTypes.BlogPostQuery>> = (props) => {
const { markdownRemark } = props.data; // data.markdownRemark holds your po
if (markdownRemark === undefined) {
throw new Error("");
}
const { frontmatter, html, excerpt, tableOfContents } = markdownRemark;
if (frontmatter === undefined || tableOfContents === undefined) {
throw new Error("");
}
const { title, visual, isProtect, created, tags, path } = frontmatter;
if (
title === undefined ||
visual === undefined ||
html === undefined ||
created === undefined ||
tags === undefined ||
path === undefined
)
throw new Error("should be");
// HACK: absolutePath があると型変換できないので。
const image = getImage({ ...visual.childImageSharp } as ImageDataLike);
if (image === undefined) {
throw new Error("aa");
}
// TODO: throw して narrowing するコードにする
const tagss = tags.filter((tag) => {
return typeof tag === "string";
}) as string[];
return (
<Layout>
<Seo
title={title}
description={excerpt}
image={visual.publicURL}
hatebuHeader={isProtect}
jsonLD={JSON.stringify({
"@context": "http://schema.org",
"@type": "Article",
name: title,
headline: excerpt,
datePublished: created,
dateModified: created,
url: `https://blog.ojisan.io/${path}`,
mainEntityOfPage: `https://blog.ojisan.io/${path}`,
image: [`https://blog.ojisan.io/${visual.publicURL}`],
description: excerpt,
author: {
"@type": "Person",
url: "https://twitter.com/sadnessOjisan",
name: "sadnessOjisan",
},
publisher: {
"@type": "Organization",
name: "sadnessOjisan",
logo: {
"@type": "ImageObject",
url: "https://pbs.twimg.com/profile_images/1106559155874074625/doWoL3em_400x400.png",
},
},
})}
/>
<div>
<MetaInfo image={image} tags={tagss} title={title} created={created} />
<div className={toc}>
<Toc toc={tableOfContents} />
</div>
<ArticleBody html={html} />
</div>
</Layout>
);
}
Example #16
Source File: for-you.tsx From nyxo-website with MIT License | 5 votes |
ForYouPage: FC<PageProps<Props>> = (props) => {
const {
location: { pathname },
data: { forYouMeta, forYouCover },
} = props
const { t } = useTranslation()
return (
<Layout>
<SEO
title={t("FOR_YOU.TITLE")}
pathName={pathname}
description={t("FOR_YOU.DESCRIPTION")}
staticImage={true}
image={forYouMeta.childImageSharp.fixed.src}
/>
<Container>
<PageHeader
title={t("FOR_YOU.TITLE")}
subtitle={t("FOR_YOU.DESCRIPTION")}
coverPhoto={forYouCover?.childImageSharp?.fluid}
/>
<div className={"targets"}>
<H2>{t("FOR_YOU.NYXO_OFFERING")}</H2>
<div className={"row"}>
<div className={"col-6"}>
<div className={"item"}>
<H3>{t("FOR_YOU.TITLE_1")}</H3>
<P>{t("FOR_YOU.TEXT_1")}</P>
</div>
</div>
<div className={"col-6"}>
<div className={"item"}>
<H3>{t("FOR_YOU.TITLE_2")}</H3>
<P>{t("FOR_YOU.TEXT_2")}</P>
</div>
</div>
</div>
<div className={"row"}>
<div className={"col-6"}>
<div className={"item"}>
<H3>{t("FOR_YOU.TITLE_3")}</H3>
<P>{t("FOR_YOU.TEXT_3")}</P>
</div>
</div>
<div className={"col-6"}>
<div className={"item"}>
<H3>{t("FOR_YOU.TITLE_4")}</H3>
<P>{t("FOR_YOU.TEXT_4")}</P>
</div>
</div>
</div>
<PricingRow>
<PricingCard
name={pricing.free.title}
price={pricing.free.price}
perks={pricing.free.perks}
/>
<PricingCard
name={pricing.premium.title}
price={pricing.premium.price}
perks={pricing.premium.perks}
/>
</PricingRow>
</div>
</Container>
<GetAppBanner />
<NewsLetterForm />
</Layout>
)
}
Example #17
Source File: for-organizations.tsx From nyxo-website with MIT License | 5 votes |
ForOrganizations: FC<PageProps<Props>> = ({
location: { pathname },
data: { forOrganizationsMeta, organizationsCover },
}) => {
const { t } = useTranslation()
return (
<Layout>
<SEO
title={t("FOR_ORGANIZATIONS.TITLE")}
pathName={pathname}
description={t("FOR_ORGANIZATIONS.DESCRIPTION")}
staticImage={true}
image={forOrganizationsMeta.childImageSharp.fixed.src}
/>
<Container>
<PageHeader
title={t("FOR_ORGANIZATIONS.TITLE")}
subtitle={t("FOR_ORGANIZATIONS.DESCRIPTION")}
coverPhoto={organizationsCover.childImageSharp.fluid}
/>
<div className={"targets"}>
<div className={"title"}>
<H2>{t("FOR_ORGANIZATIONS.SUBTITLE")}</H2>
</div>
<div className={"row"}>
<div className={"col-6"}>
<div className={"item"}>
<H3>{t("FOR_ORGANIZATIONS.TITLE_1")}</H3>
<P>{t("FOR_ORGANIZATIONS.TEXT_1")}</P>
</div>
</div>
<div className={"col-6"}>
<div className={"item"}>
<H3>{t("FOR_ORGANIZATIONS.TITLE_2")}</H3>
<P>{t("FOR_ORGANIZATIONS.TEXT_2")}</P>
</div>
</div>
</div>
<div className={"row"}>
<div className={"col-6"}>
<div className={"item"}>
<H3>{t("FOR_ORGANIZATIONS.TITLE_3")}</H3>
<P>{t("FOR_ORGANIZATIONS.TEXT_3")}</P>
</div>
</div>
<div className={"col-6"}>
<div className={"item"}>
<H3>{t("FOR_ORGANIZATIONS.TITLE_4")}</H3>
<P>{t("FOR_ORGANIZATIONS.TEXT_4")}</P>
</div>
</div>
</div>
<PricingTable />
<InfoText>{t("FOR_ORGANIZATIONS.CONTACT")}</InfoText>
<BookDemo
rel="noopener"
href="https://calendly.com/nyxo"
target="_blank">
{t("FOR_ORGANIZATIONS.DEMO_BUTTON")}
</BookDemo>
</div>
</Container>
<GetAppBanner />
<NewsLetterForm />
</Layout>
)
}
Example #18
Source File: contact.tsx From nyxo-website with MIT License | 5 votes |
ContactPage: FC<PageProps<Props>> = (props) => {
const {
location: { pathname },
data: { contactMeta },
} = props
const { t } = useTranslation()
return (
<Layout>
<SEO
title={t("CONTACT.TITLE")}
description={t("CONTACT.TEXT")}
pathName={pathname}
staticImage={true}
image={contactMeta.childImageSharp.fixed.src}
/>
<Container>
<div className={"content"}>
<div className={"row"}>
<div className={"col-7"}>
<H1>{t("CONTACT.TITLE")}</H1>
<P>{t("CONTACT.TEXT")}</P>
</div>
<div className={"col-5"}>
<div className={"contact-items"}>
<Form
name="contact"
action-xhr=""
method="post"
data-netlify="true"
data-netlify-honeypot="bot-field">
<input type="hidden" name="form-name" value="contact" />
<TextBox
type="text"
name="name"
id="name"
placeholder={t("CONTACT.NAME")}
/>
<TextBox
type="email"
name="email"
id="email"
placeholder={t("CONTACT.EMAIL")}
/>
<TextBox
type="text"
name="subject"
id="subject"
placeholder={t("CONTACT.SUBJECT")}
/>
<TextArea
name="message"
id="message"
rows={5}
placeholder={t("CONTACT.MESSAGE")}
/>
<ContactButton type="submit">
{t("CONTACT.SEND")}
</ContactButton>
</Form>
</div>
</div>
</div>
</div>
</Container>
</Layout>
)
}
Example #19
Source File: blog.tsx From nyxo-website with MIT License | 5 votes |
BlogPage: FC<PageProps<Props>> = ({
location: { pathname },
data: {
allMarkdownRemark: { nodes: blogPosts },
blogMeta,
blogCover,
},
}) => {
const { t } = useTranslation()
return (
<Layout>
<SEO
title={t("BLOG.TITLE")}
description={t("BLOG.DESCRIPTION")}
pathName={pathname}
image={blogMeta.childImageSharp.fixed.src}
staticImage={true}
/>
<Container>
<PageHeader
title={t("BLOG.TITLE")}
subtitle={t("BLOG.DESCRIPTION")}
coverPhoto={blogCover.childImageSharp.fluid}
/>
<TagWrap>
<TagFilter />
</TagWrap>
<Posts>
{blogPosts.map(
({
frontmatter: {
slug,
author,
title,
description,
thumbnailBlog,
tags,
},
}: BlogPostNode) => {
return (
<BlogPost
key={slug}
author={author}
title={title}
slug={`/${slug}`}
description={description}
thumbnailBlog={thumbnailBlog}
tags={tags}
/>
)
}
)}
</Posts>
</Container>
<NewsLetterForm />
</Layout>
)
}
Example #20
Source File: letters.tsx From defund12.org with MIT License | 5 votes |
/**
* Contains a list just like the homepage, but with letters.
*/
export default class Letters extends React.Component<PageProps<SiteProps>> {
/**
* Initialize the component.
* @param {PageProps<SiteProps>} props
*/
constructor(props: PageProps<SiteProps>) {
super(props);
}
/**
* React render method.
* @return {React.ReactNode} the rendered component
*/
render(): React.ReactNode {
return (
<StaticQuery
query={graphql`
query LetterPageQuery {
siteConfig {
letterPageHeader
}
}
`}
render={(data: { siteConfig: LettersPageConfig }) => {
const header = (
<span
dangerouslySetInnerHTML={{
__html: DefundUtils.markdownToHTML(
data.siteConfig.letterPageHeader
),
}}
></span>
);
return (
<Layout>
<TemplateList layout="letter" header={header} />
</Layout>
);
}}
/>
);
}
}
Example #21
Source File: letters.tsx From defund12.org with MIT License | 5 votes |
/**
* Initialize the component.
* @param {PageProps<SiteProps>} props
*/
constructor(props: PageProps<SiteProps>) {
super(props);
}
Example #22
Source File: index.tsx From defund12.org with MIT License | 5 votes |
/**
* Initialize the component.
* @param {PageProps<SiteProps>} props
*/
constructor(props: PageProps<SiteProps>) {
super(props);
}
Example #23
Source File: about.tsx From nyxo-website with MIT License | 4 votes |
AboutPage: FC<PageProps<Props>> = ({
location: { pathname },
data: {
dataJson: {
about: { perks, title, description },
},
perttu,
eeva,
kayla,
pietari,
miska,
chinh,
anu,
liisa,
contactMeta,
},
}) => {
const { t } = useTranslation()
const team = [
{
name: "Perttu Lähteenlahti",
position: "CEO",
image: perttu.childImageSharp.fluid,
slug: "perttu-lahteenlahti",
},
{
name: "Eeva Siika-aho",
position: "COO",
image: eeva.childImageSharp.fluid,
slug: "eeva-siika-aho",
},
{
name: "Pietari Nurmi",
position: "Head of Coaching",
image: pietari.childImageSharp.fluid,
slug: "pietari-nurmi",
},
{
name: "Kayla Gordon",
position: "Software Engineer",
image: kayla.childImageSharp.fluid,
slug: "kayla-gordon",
},
{
name: "Miska Nurmi",
position: "Data Analyst",
image: miska.childImageSharp.fluid,
slug: "miska-nurmi",
},
{
name: "Duong Minh Chinh",
position: "Software Engineer",
image: chinh.childImageSharp.fluid,
slug: "chinh-duong",
},
]
const scientists = [
{
name: "Anu-Katriina Pesonen",
position: "Professor of clinical and developmental psychology",
image: anu.childImageSharp.fluid,
slug: "anu-katriina-pesonen",
},
{
name: "Liisa Kuula",
position: "Postdoctoral Researcher",
image: liisa.childImageSharp.fluid,
slug: "liisa-kuula",
},
]
return (
<Layout>
<SEO
title={t("ABOUT.NYXO")}
description={t("ABOUT.INTRODUCTION_1")}
pathName={pathname}
image={contactMeta.childImageSharp.fixed.src}
/>
<Container>
<H1>{t("ABOUT.TITLE")}</H1>
<Row>
<Column>
<H2>{t("ABOUT.NYXO")}</H2>
<P>{t("ABOUT.INTRODUCTION_1")}</P>
<P>{t("ABOUT.INTRODUCTION_2")}</P>
<P>{t("ABOUT.INTRODUCTION_3")}</P>
</Column>
</Row>
<Row>
<Team>
{team.map((person) => (
<PersonCard
key={person.slug}
name={person.name}
image={person.image}
slug={person.slug}
position={person.position}
/>
))}
</Team>
</Row>
<Row>
<Column>
<H2>{t("ABOUT.SCIENTISTS")}</H2>
<P>{t("ABOUT.SCIENTISTS_TEXT")}</P>
</Column>
</Row>
<Row>
<Team>
{scientists.map((person) => (
<PersonCard
key={person.slug}
name={person.name}
image={person.image}
position={person.position}
slug={person.slug}
/>
))}
</Team>
</Row>
<JoinUs>
<H2>{t("ABOUT.WORK_FOR_US")}</H2>
<P>{t("ABOUT.WORK_FOR_US_TEXT")}</P>
</JoinUs>
{/* <InstagramFeaturette /> */}
</Container>
</Layout>
)
}
Example #24
Source File: blog-post.tsx From nyxo-website with MIT License | 4 votes |
BlogPostTemplate: FC<PageProps<Props>> = ({
data: {
markdownRemark: {
excerpt,
html,
frontmatter: {
slug = "",
tags,
thumbnailBlog,
canonical,
description,
title,
date,
},
},
contentfulAuthor: author,
allMarkdownRemark,
},
location: { pathname },
}) => {
const blogPosts = allMarkdownRemark.edges.map(
({ node }: { node: BlogPostNode }) => node
)
const relatedBlogPosts = new RelatedContentFactory(blogPosts, slug)
.setMaxArticles(3)
.setTags(tags)
.getArticles()
const { t } = useTranslation()
return (
<Layout>
<>
<SEO
title={title as string}
pathName={pathname}
image={thumbnailBlog?.childImageSharp?.fixed?.src}
description={(description || excerpt) as string}
staticImage={true}
canonical={canonical}
/>
<Header>
<TextContainer>
<Title>{title}</Title>
<Date>{date}</Date>
<Image
alt="Blog post cover"
fluid={thumbnailBlog?.childImageSharp?.fluid}
/>
</TextContainer>
</Header>
<TextContainer>
<Content dangerouslySetInnerHTML={{ __html: html }} />
{!!author && <AuthorCard author={author} />}
<Tags>
<H3>{t("TAGS")}</H3>
<TagSection largeTags tags={tags} />
</Tags>
<ShareArea></ShareArea>
</TextContainer>
<Container>
<H3>{t("RELATED")}</H3>
<RelatedContentSection>
{relatedBlogPosts.map(
({ article: blogPost }: { article: BlogPostNode }) => (
<BlogPost
key={blogPost.frontmatter.slug}
tags={blogPost.frontmatter.tags}
slug={`/${blogPost.frontmatter.slug}`}
title={blogPost.frontmatter.title}
author={blogPost.frontmatter.author}
thumbnailBlog={blogPost.frontmatter.thumbnailBlog}
description={blogPost.frontmatter.description}
/>
)
)}
</RelatedContentSection>
</Container>
</>
</Layout>
)
}
Example #25
Source File: index.tsx From nyxo-website with MIT License | 4 votes |
IndexPage: FC<PageProps<Props>> = ({
location: { pathname },
data: {
indexMeta,
datasources,
lessons,
cover,
data,
recentlyUpdated: { nodes: recentlyUpdated },
},
}) => {
const { t } = useTranslation()
return (
<Layout>
<SEO
title={t("INDEX.TITLE")}
pathName={pathname}
description={t("INDEX.INTRODUCTION")}
staticImage={true}
image={indexMeta.childImageSharp.fixed.src}
canonical={pathname}
/>
<div className={"page-header home"}>
<HeroMessage>{t("INDEX.TITLE")}</HeroMessage>
<Container>
<HeroContentWrap>
<P>{t("INDEX.INTRODUCTION")}</P>
</HeroContentWrap>
</Container>
<HeroImg>
<NewImage
alt={"Nyxo Dashboard and phone"}
path={cover.childImageSharp.fluid}
/>
</HeroImg>
</div>
<Featured />
<IndexContainer>
<div className={"features"}>
<div className={"feature__item"}>
<div className={"row"}>
<div className="col-6 first">
<div className={"thumbnail"}>
<Image
alt="Nyxo data sources"
path={datasources.childImageSharp.fluid}
/>
</div>
</div>
<div className={"col-6"}>
<div className={"feature__content"}>
<FeaturesHeroText>{t("INDEX.IMPORTING")}</FeaturesHeroText>
<P>{t("INDEX.IMPORTING_TEXT")}</P>
</div>
</div>
</div>
</div>
<div className={"feature__item"}>
<div className={"row"}>
<div className={"col-6"}>
<div className={"feature__content"}>
<FeaturesHeroText>{t("INDEX.AUTHORS")}</FeaturesHeroText>
<P>{t("INDEX.AUTHORS_TEXT")}</P>
</div>
</div>
<div className="col-6 first">
<AuthorFeaturette />
</div>
</div>
</div>
<div className={"feature__item"}>
<div className={"row"}>
<div className="col-6 first">
<div className={"thumbnail"}>
<Image
alt="Nyxo data sources"
path={data.childImageSharp.fluid}
/>
</div>
</div>
<div className={"col-6"}>
<div className={"feature__content"}>
<FeaturesHeroText>{t("INDEX.EASE_OF_USE")}</FeaturesHeroText>
<P>{t("INDEX.EASE_OF_USE_TEXT")}</P>
</div>
</div>
</div>
</div>
<div className={"feature__item"}>
<div className={"row"}>
<div className={"col-6"}>
<div className={"feature__content"}>
<FeaturesHeroText>{t("INDEX.DATA")}</FeaturesHeroText>
<P>{t("INDEX.DATA_TEXT")}</P>
</div>
</div>
<div className="col-6 first">
<div className={"thumbnail"}>
<Image
alt="Nyxo data sources"
path={lessons.childImageSharp.fluid}
/>
</div>
</div>
</div>
</div>
<div className={"feature__item"}>
<div className={"row"}>
<div className="col-6 first">
<div className={"thumbnail"}>
<Image
alt="Nyxo data sources"
path={datasources.childImageSharp.fluid}
/>
</div>
</div>
<div className={"col-6"}>
<div className={"feature__content"}>
<FeaturesHeroText>
{t("INDEX.ORGANIZATIONS")}
</FeaturesHeroText>
<P>{t("INDEX.ORGANIZATIONS_TEXT")}</P>
<Demo
rel="noopener"
href="https://calendly.com/nyxo"
target="_blank">
{t("FOR_ORGANIZATIONS.DEMO_BUTTON")}
</Demo>
</div>
</div>
</div>
</div>
</div>
<RecentlyUpdated lessons={recentlyUpdated} />
</IndexContainer>
<BlogPreview />
<NewsLetterForm />
</Layout>
)
}
Example #26
Source File: blog-tag.tsx From web with Apache License 2.0 | 4 votes |
BlogTagPage = ({
pageContext: { tagSlug, tagName, posts, seo: tagSeo = {} }
}: PageProps<
any,
{
tagSlug: string
tagName: string
posts: BlogPostNode[]
seo?: any
}
>) => {
const seo = {
...jsonWithTagSlugs.seo,
...tagSeo
}
const content = { ...jsonWithTagSlugs, tags: [...jsonWithTagSlugs.tags] }
const blogTagPosts = useStaticQuery(graphql`
query blogTagListing {
allMdx(
filter: {
fileAbsolutePath: { regex: "/markdown/blog/" }
frontmatter: { published: { ne: false } }
}
) {
edges {
node {
id
frontmatter {
featuredimage {
id
publicURL
childImageSharp {
gatsbyImageData
}
}
path
seo {
title
description
keywords
}
tags
category
publishedAt(formatString: "MMMM DD, YYYY")
author
path
title
teaser
overline
}
}
}
}
}
`)
blogTagPosts.allMdx.edges.forEach(({ node }: { node: BlogPostNode }) => {
const postTags = node.frontmatter.tags || []
content.tags.forEach((tag) => {
if (postTags.includes(tag.name) && !tag.ids.includes(node.id)) {
tag.posts.push(node)
tag.ids.push(node.id)
}
})
})
return (
<Layout>
<SEO {...seo} />
<FeaturedBlogPosts
{...getFeaturedProps(blogTagPosts.allMdx.edges, rawJson)}
/>
<Newsletter
{...(rawJson.newsletter as React.ComponentProps<typeof Newsletter>)}
/>
<BlogHeading title={tagName} />
<BlogTags currentSlug={tagSlug} tags={content.tags} />
<BlogList id={`blog.${tagSlug}.list`} posts={posts} />
</Layout>
)
}
Example #27
Source File: Letter.tsx From defund12.org with MIT License | 4 votes |
/**
* A rendered email, containing links to send or copy.
*/
export default class Letter extends React.Component<PageProps<LetterProps>> {
letterData: LetterData;
siteConfig: LetterConfig;
layoutProps: OptionalLayoutProps;
/**
* Initialize the component and its state.
* @param {PageProps<EmailProps>} props
*/
constructor(props: PageProps<LetterProps>) {
super(props);
console.log(this.props);
this.siteConfig = this.props.data.siteConfig;
this.letterData = this.props.data.markdownRemark.frontmatter;
this.layoutProps = {
pageTitle: `Defund12 in ${this.letterData.city}, ${this.letterData.state}`,
meta: `Send a pre-written letter directly to ${this.letterData.city}, ${this.letterData.state} officials`,
metaQueryString: queryString.stringify({
state: this.letterData.state,
city: this.letterData.city,
}),
layout: "letter",
};
}
/**
* React render method.
* @return {React.ReactNode} the rendered component
*/
render(): React.ReactNode {
// parse the offical restricts from the template markdown that look like
// locality:legislatorUpperBody into structured restricts for our APIs
const officialRestricts = this.letterData.officials?.map(
(officialString) => {
const parts = officialString.split(":");
return {
level: parts[0],
role: parts[1],
} as OfficialRestrict;
}
);
const template = {
template: this.letterData.body,
officialRestricts,
};
return (
<Layout {...this.layoutProps}>
<section className="emailPageHeader">
<h2>{this.letterData.name}</h2>
<b>
{this.letterData.city}, {this.letterData.state}
</b>
<div className="buttons">
<a
onClick={() =>
DefundUtils.copyToClipboard(this.letterData.permalink, true)
}
>
Copy link
</a>
</div>
<p
dangerouslySetInnerHTML={{
__html: DefundUtils.markdownToHTML(
this.siteConfig.letterPageHeader
),
}}
></p>
</section>
<article className="letterContentSection">
<div className="container">
<div className="letterContent">
<LetterForm
template={template}
googleApiKey={this.siteConfig.googleApiKey}
></LetterForm>
</div>
</div>
</article>
<LetterList />
</Layout>
);
}
}
Example #28
Source File: Email.tsx From defund12.org with MIT License | 4 votes |
/**
* A rendered email, containing links to send or copy.
*/
export default class Email extends React.Component<
PageProps<EmailProps>,
EmailState
> {
siteConfig: EmailConfig;
emailData: EmailData;
layoutProps: OptionalLayoutProps;
autoOpen = false;
/**
* Initialize the component and its state.
* @param {PageProps<EmailProps>} props
*/
constructor(props: PageProps<EmailProps>) {
super(props);
this.siteConfig = this.props.data.siteConfig;
this.emailData = this.props.data.markdownRemark.frontmatter;
this.layoutProps = {
pageTitle: `Defund12 in ${this.emailData.city}, ${this.emailData.state}`,
meta: `Send a pre-written email directly to ${this.emailData.city}, ${this.emailData.state} officials`,
metaQueryString: queryString.stringify({
state: this.emailData.state,
city: this.emailData.city,
}),
layout: "email",
};
this.state = new EmailState();
}
/**
* React client-side mount method.
*/
componentDidMount(): void {
const isAndroid = /(android)/i.test(navigator.userAgent);
if (isAndroid) {
this.emailData.body = this.emailData.body.replace("\n", "<br/>");
}
const queryParams = queryString.parse(this.props.location.search);
if ("browse" in queryParams) {
// Automatically updates the URL so
// if folks try to share, it will auto-open
const pathWithoutQuery = `${this.props.location.origin}${this.props.location.pathname}`;
window.history.replaceState({}, document.title, pathWithoutQuery);
} else {
this.autoOpen = true;
this.openEmail();
}
}
/**
* Redirects the browser to a mailto: link containing the email information
*/
openEmail(): void {
const subject = encodeURIComponent(
this.siteConfig.defaultSubjectLine.trim()
);
const body = encodeURIComponent(this.emailData.body.trim());
const recipients = this.emailData.recipients;
const cc = this.emailData.cc || [];
const bcc = recipients.concat(cc);
window.location.href = `mailto:?bcc=${bcc.join(
","
)}&subject=${subject}&body=${body}`;
}
/**
* Updates the component state to reflect which element was clicked.
* @param {Pick<EmailState, K>} statePatch an object containing
* the state update to apply
* @param {string} copy the text to copy to the user's clipboard.
*/
handleClipboardCopy<K extends keyof EmailState>(
statePatch: Pick<EmailState, K>,
copy: string
): void {
this.setState(statePatch);
DefundUtils.copyToClipboard(copy);
}
/**
* React render method.
* @return {React.ReactNode} the rendered component
*/
render(): React.ReactNode {
return (
<Layout {...this.layoutProps}>
<section className="emailPageHeader">
<h2>{this.emailData.name}</h2>
<b>
{this.emailData.city}, {this.emailData.state}
</b>
<p hidden={!this.autoOpen}>{this.siteConfig.autoOpenMessage}</p>
<div className="buttons">
<a onClick={this.openEmail.bind(this)}>Send email</a>
<a
onClick={() =>
DefundUtils.copyToClipboard(this.emailData.permalink, true)
}
>
Copy link
</a>
</div>
<p>{this.siteConfig.badMailtoMessage}</p>
</section>
<article className="emailContentSection">
<div className="container">
<div className="emailContent">
<div className="recipients">
<b>To:</b>
<span
className="copyToClipboard"
onClick={() =>
this.handleClipboardCopy(
{ recipientsCopied: true },
this.emailData.recipients.join(", ")
)
}
>
{this.state.recipientsCopied ? "✅(copied)" : "?"}
</span>
{this.emailData.recipients.join(", ")}
</div>
{this.emailData.cc ? (
<div className="recipients">
<b>CC:</b>
<span
className="copyToClipboard"
onClick={() =>
this.handleClipboardCopy(
{ ccCopied: true },
this.emailData.cc.join(", ")
)
}
>
{this.state.ccCopied ? "✅(copied)" : "?"}
</span>
{this.emailData.cc.join(", ")}
</div>
) : undefined}
<div className="recipients">
<b>Subject:</b> {this.siteConfig.defaultSubjectLine}
</div>
<div>
<b>Message:</b>
<i>
(Don't forget to replace the [x]'s with your information!)
</i>
<span
className="copyToClipboard"
onClick={() =>
this.handleClipboardCopy(
{ bodyCopied: true },
this.emailData.body
)
}
>
{this.state.bodyCopied ? "✅(copied)" : "?"}
</span>
<span
dangerouslySetInnerHTML={{
__html: DefundUtils.markdownToHTML(this.emailData.body),
}}
></span>
</div>
</div>
</div>
</article>
<br></br>
<EmailList />
</Layout>
);
}
}