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 vote down vote up
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 vote down vote up
/**
   * 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 vote down vote up
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 vote down vote up
/**
 * 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 vote down vote up
/**
 * 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 vote down vote up
/** 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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
/**
   * 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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
/**
 * 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 vote down vote up
/**
   * 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 vote down vote up
/**
   * 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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
/**
 * 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 vote down vote up
/**
 * 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>&nbsp;
            <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>
                &nbsp;
                {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>
                  &nbsp;
                  {this.emailData.cc.join(", ")}
                </div>
              ) : undefined}

              <div className="recipients">
                <b>Subject:</b> {this.siteConfig.defaultSubjectLine}
              </div>
              <div>
                <b>Message:</b>&nbsp;
                <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>
    );
  }
}