.ts
TypeScript
(application/typescript)
// 1st-party
import type { ReactView } from "@ethicdevs/react-monolith";
// 3rd-party
import React from "react";
// generated via script[generate:prisma]
import type { Organization, PullRequest } from "@prisma/client";
// app
import type { CommonProps, RepositoryWithForkedFromRepo } from "../../types";
import { AppRoute } from "../../routes.defs";
import { Card } from "../../components/Card.styled";
import { Chip } from "../../components/Chip";
import { Grid } from "../../components/Grid";
import { Layout } from "../../components/Layout";
import { PageWrapper } from "../../components/PageWrapper";
import { buildRouteLink } from "../../utils/shared";
import { Colors, NamedColors } from "../../utils/style";
// app islands
import { IslandWrapper } from "../../components/IslandWrapper.styled";
import RepositoryHero from "../../islands/RepositoryHero";

type PullRequestsFilter = "all" | "open" | "closed" | "merged" | "search";

export interface RepositoryPullRequestsViewProps extends CommonProps {
  parentOrg: Organization;
  pullRequests: PullRequest[];
  repo: RepositoryWithForkedFromRepo;
  pullRequestsFilter?: PullRequestsFilter;
}

const RepositoryPullRequestsView: ReactView<
  RepositoryPullRequestsViewProps
> = ({
  commonProps,
  parentOrg,
  pullRequests,
  repo,
  pullRequestsFilter = "open",
}) => {
  return (
    <Layout
      {...commonProps}
      showDrawerPrimary
      orgSlug={parentOrg.slug}
      repoSlug={repo.slug}
    >
      <PageWrapper>
        <IslandWrapper data-islandid={`${RepositoryHero.name}$$0`}>
          <RepositoryHero
            themeScheme={commonProps.themeScheme}
            forkedFromRepo={repo.forkedFromRepo}
            forksCount={repo.forks.length}
            parentOrg={parentOrg}
            path={`Pull Requests`}
            repo={repo}
            showForkButton={false}
            showNewButton
            newButtonText={"New Pull Request"}
            // newButtonText={
            //   <>
            //     <span>New Pull Request</span>
            //     <GitPullIcon
            //       color={Colors.WHITE_01}
            //       size={24}
            //     />
            //   </>
            // }
            newButtonUrl={buildRouteLink(
              AppRoute.REPOSITORY_PULL_REQUEST_CREATE,
              {
                orgSlug: parentOrg.slug,
                repoSlug: repo.slug,
              },
            )}
          />
        </IslandWrapper>
        <Grid.Col
          fluid
          style={{
            padding: "12px 0",
            borderBottom: `1px solid ${NamedColors.BORDER_DEFAULT[commonProps.themeScheme]}`,
          }}
        >
          <Grid.Row
            fluid
            alignItems={"center"}
            gap={12}
            style={{ padding: "0 8px" }}
          >
            <a
              style={{
                fontWeight: pullRequestsFilter === "all" ? "bold" : "normal",
                textDecoration:
                  pullRequestsFilter === "all" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pulls?filter=${
                "all" as PullRequestsFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>All</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsTotal}
                </Chip>
              </Grid.Row>
            </a>
            <a
              style={{
                fontWeight: pullRequestsFilter === "open" ? "bold" : "normal",
                textDecoration:
                  pullRequestsFilter === "open" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pulls?filter=${
                "open" as PullRequestsFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>Open</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsOpen}
                </Chip>
              </Grid.Row>
            </a>
            <a
              style={{
                fontWeight: pullRequestsFilter === "merged" ? "bold" : "normal",
                textDecoration:
                  pullRequestsFilter === "merged" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pulls?filter=${
                "merged" as PullRequestsFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>Merged</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsMerged}
                </Chip>
              </Grid.Row>
            </a>
            <a
              style={{
                fontWeight: pullRequestsFilter === "closed" ? "bold" : "normal",
                textDecoration:
                  pullRequestsFilter === "closed" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pulls?filter=${
                "closed" as PullRequestsFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>Closed</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsClosed}
                </Chip>
              </Grid.Row>
            </a>
          </Grid.Row>
        </Grid.Col>
        <Grid.Col fluid gap={4} style={{ marginTop: 12 }}>
          {pullRequests != null && pullRequests.length >= 1 ? (
            pullRequests.map((pr) => (
              <Card
                key={pr.id}
                themeScheme={commonProps.themeScheme}
                style={{ width: "100%", padding: 8 }}
              >
                <Grid.Col fluid>
                  <a
                    style={{ width: "100%" }}
                    href={buildRouteLink(
                      AppRoute.REPOSITORY_PULL_REQUEST_DETAILS,
                      {
                        orgSlug: parentOrg.slug,
                        repoSlug: repo.slug,
                        pullUid: pr.uid,
                      },
                    )}
                  >
                    <Grid.Row fluid alignItems={"center"} gap={4}>
                      <span>#{pr.uid}</span>
                      <span>&bull;</span>
                      <span style={{ flex: 1 }}>{pr.summary}</span>
                      <Chip
                        themeScheme={commonProps.themeScheme}
                        color={
                          {
                            OPEN: Colors.PRIMARY_01,
                            CLOSE_MERGED: Colors.GREEN_01,
                            CLOSE_DENIED: Colors.RED_01,
                          }[pr.state]
                        }
                      >
                        {
                          {
                            OPEN: "Open",
                            CLOSE_MERGED: "Merged",
                            CLOSE_DENIED: "Closed",
                          }[pr.state]
                        }
                      </Chip>
                    </Grid.Row>
                  </a>
                  <Grid.Row
                    fluid
                    nowrap
                    gap={8}
                    alignItems={"center"}
                    style={{ opacity: 0.67 }}
                  >
                    wants to merge{" "}
                    <Chip
                      themeScheme={commonProps.themeScheme}
                      style={{ textTransform: "none" }}
                    >
                      <code>{pr.sourceBranch}</code>
                    </Chip>
                    into{" "}
                    <Chip
                      themeScheme={commonProps.themeScheme}
                      style={{ textTransform: "none" }}
                    >
                      <code>{pr.targetBranch}</code>
                    </Chip>
                  </Grid.Row>
                  <Grid.Col
                    fluid
                    gap={4}
                    style={{ opacity: 0.67, marginTop: 4 }}
                  >
                    {new Date(pr.createdAt).getTime() <=
                      new Date(pr.updatedAt).getTime() && (
                      <span>
                        {`opened on ${new Date(pr.createdAt).toLocaleString()}`}
                      </span>
                    )}
                    {((pr.closedAt == null &&
                      new Date(pr.updatedAt).getTime() >
                        new Date(pr.createdAt).getTime()) ||
                      (pr.closedAt != null &&
                        new Date(pr.updatedAt).getTime() <
                          new Date(pr.closedAt).getTime())) && (
                      <span>
                        {`updated on ${new Date(pr.updatedAt).toLocaleString()}`}
                      </span>
                    )}
                    {pr.closedAt != null && (
                      <span>
                        {`closed on ${new Date(pr.closedAt).toLocaleString()}`}
                      </span>
                    )}
                  </Grid.Col>
                </Grid.Col>
              </Card>
            ))
          ) : (
            <Grid.Col
              fluid
              nowrap
              justifyContent={"center"}
              alignItems={"center"}
              style={{ minHeight: "70vh" }}
            >
              <h1 style={{ margin: 0 }}>No Pull Request Yet</h1>
              <p style={{ maxWidth: "62%", textAlign: "center" }}>
                <span>Be the change you want to see, </span>
                <a
                  href={buildRouteLink(
                    AppRoute.REPOSITORY_PULL_REQUEST_CREATE,
                    {
                      orgSlug: parentOrg.slug,
                      repoSlug: repo.slug,
                    },
                  )}
                >
                  open the first Pull Request
                </a>
                <span> to this repository 🚀.</span>
              </p>
            </Grid.Col>
          )}
        </Grid.Col>
      </PageWrapper>
    </Layout>
  );
};

RepositoryPullRequestsView.displayName = "RepositoryPullRequestsView";
export default RepositoryPullRequestsView;