Skip to content

Commit

Permalink
feat: new contributor highlight card (#1443)
Browse files Browse the repository at this point in the history
Co-authored-by: ( Nechiforel David-Samuel ) NsdHSO <37635083+NsdHSO@users.noreply.github.com>
Co-authored-by: Brandon Roberts <robertsbt@gmail.com>
  • Loading branch information
3 people committed Jul 31, 2023
1 parent 49dff5b commit c88000b
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React, { useState, useEffect } from "react";
import { HiOutlineEmojiHappy } from "react-icons/hi";
import { TfiMoreAlt } from "react-icons/tfi";
import { FiEdit, FiLinkedin, FiTwitter } from "react-icons/fi";
import { BsCalendar2Event, BsLink45Deg } from "react-icons/bs";
import { FiEdit, FiLinkedin } from "react-icons/fi";
import { BsCalendar2Event, BsLink45Deg, BsTwitter } from "react-icons/bs";
import { GrFlag } from "react-icons/gr";
import Emoji from "react-emoji-render";
import { usePostHog } from "posthog-js/react";
import { MdError } from "react-icons/md";
import { format } from "date-fns";
import { FaUserPlus } from "react-icons/fa";
import { BiGitPullRequest } from "react-icons/bi";
import { VscIssues } from "react-icons/vsc";
import clsx from "clsx";
import Title from "components/atoms/Typography/title";

import { Textarea } from "components/atoms/Textarea/text-area";
Expand All @@ -21,7 +24,7 @@ import {
} from "components/atoms/Dropdown/dropdown";

import useSupabaseAuth from "lib/hooks/useSupabaseAuth";
import { generateApiPrUrl } from "lib/utils/github";
import { generateApiPrUrl, getAvatarByUsername, getOwnerAndRepoNameFromUrl } from "lib/utils/github";
import { fetchGithubPRInfo } from "lib/hooks/fetchGithubPRInfo";
import { updateHighlights } from "lib/hooks/updateHighlight";
import { deleteHighlight } from "lib/hooks/deleteHighlight";
Expand Down Expand Up @@ -51,6 +54,7 @@ import {
} from "../AlertDialog/alert-dialog";
import { Popover, PopoverContent, PopoverTrigger } from "../Popover/popover";
import { Calendar } from "../Calendar/calendar";
import CardRepoList, { RepoList } from "../CardRepoList/card-repo-list";

interface ContributorHighlightCardProps {
title?: string;
Expand All @@ -61,7 +65,9 @@ interface ContributorHighlightCardProps {
shipped_date: string;
refreshCallBack?: () => void;
emojis: DbEmojis[];
type?: HighlightType;
}
type HighlightType = "pull_request" | "issue" | "blog";

const ContributorHighlightCard = ({
title,
Expand All @@ -71,6 +77,7 @@ const ContributorHighlightCard = ({
id,
refreshCallBack,
emojis,
type = "pull_request",
shipped_date,
}: ContributorHighlightCardProps) => {
const { toast } = useToast();
Expand Down Expand Up @@ -151,6 +158,50 @@ const ContributorHighlightCard = ({
}
};

const { owner: repoOwner, repoName } = getOwnerAndRepoNameFromUrl(prLink);
const repoIcon = getAvatarByUsername(repoOwner, 60);

const repo: RepoList = {
repoIcon,
repoName,
repoOwner,
};

const getHighlightTypePreset = (type: HighlightType): { text: string; icon?: React.ReactElement } => {
switch (type) {
case "pull_request":
return { text: "Pull request", icon: <BiGitPullRequest className="text-lg md:text-xl" /> };
case "blog":
return {
text: "Blog post",
icon: (
// Used svg as i could not find the exact icon in react-icons
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
className="w-6 h-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"
/>
</svg>
),
};
case "issue":
return { text: "Issue", icon: <VscIssues className="text-lg md:text-xl" /> };

default:
return { text: "Pull request", icon: <BiGitPullRequest className="text-lg md:text-xl" /> };
}
};

const { icon, text } = getHighlightTypePreset(type);

const handleUpdateHighlight = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

Expand Down Expand Up @@ -221,6 +272,10 @@ const ContributorHighlightCard = ({
return (
<article className="flex flex-col md:max-w-[40rem] flex-1 gap-3 lg:gap-6">
<div>
<div className={clsx("flex items-center gap-1 text-light-slate-12", title && "mb-2")}>
{icon}
<span className="text-sm md:text-base text-light-slate-10">{getHighlightTypePreset(type).text}</span>
</div>
<div className="flex items-center justify-between w-full">
<div className="flex items-center justify-between gap-1 pr-2">
{title && (
Expand All @@ -231,24 +286,26 @@ const ContributorHighlightCard = ({
</div>
<div className="flex items-center gap-3 ml-auto lg:gap-3">
<DropdownMenu>
<DropdownMenuTrigger className=" py-2 px-2 rounded-full data-[state=open]:bg-light-slate-7">
<TfiMoreAlt size={24} />
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="flex flex-col gap-1 py-2 rounded-lg">
<DropdownMenuItem className="rounded-md">
<div className="flex items-center gap-3 w-max">
<Tooltip direction="top" content="share on twitter">
<a
onClick={() => {
handleCaptureClickDetailsForAnalytics("twitter");
}}
target="_blank"
rel="noreferrer"
href={`https://twitter.com/intent/tweet?text=${twitterTweet}&url=${host}/feed/${id}`}
className="flex gap-2.5 py-1 items-center pl-3 pr-7"
className="flex items-center p-3 transition rounded-full hover:bg-light-orange-5"
>
<FiTwitter size={22} />
<span>Share to Twitter</span>
<BsTwitter className="text-lg text-light-orange-9 md:text-xl" />
</a>
</DropdownMenuItem>
</Tooltip>
<DropdownMenuTrigger className="py-2 px-2 rounded-full data-[state=open]:bg-light-slate-7">
<TfiMoreAlt size={24} />
</DropdownMenuTrigger>
</div>

<DropdownMenuContent align="end" className="flex flex-col gap-1 py-2 rounded-lg">
<DropdownMenuItem className="rounded-md">
<a
onClick={() => {
Expand Down Expand Up @@ -379,6 +436,11 @@ const ContributorHighlightCard = ({
/>
</div>
))}
{type === "pull_request" && (
<div className="ml-auto">
<CardRepoList repoList={[repo]} />
</div>
)}
</div>

<Dialog open={openEdit} onOpenChange={setOpenEdit}>
Expand Down
7 changes: 7 additions & 0 deletions lib/utils/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,15 @@ const isValidPullRequestUrl = (url: string): boolean => {
return url.match(/((https?:\/\/)?(www\.)?github\.com\/[^\/]+\/[^\/]+\/pull\/[0-9]+)/) ? true : false;
};

const getOwnerAndRepoNameFromUrl = (url: string): { owner: string; repoName: string } => {
const [, , , owner, repoName] = url.split("/");

return { owner, repoName };
};

export {
getAvatarById,
getOwnerAndRepoNameFromUrl,
getAvatarByUsername,
getProfileLink,
getRepoIssuesLink,
Expand Down
93 changes: 93 additions & 0 deletions stories/molecules/contributor-highlight-card.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { TooltipProvider } from "@radix-ui/react-tooltip";
import { Meta, StoryFn } from "@storybook/react";
import ContributorHighlightCard from "components/molecules/ContributorHighlight/contributor-highlight-card";

export default {
title: "Design System/Molecules/ContributorHighlightCard",
} as Meta<typeof ContributorHighlightCard>;

const Template: StoryFn<typeof ContributorHighlightCard> = (args) => (
<TooltipProvider>
<ContributorHighlightCard {...args} />
</TooltipProvider>
);

export const Default = Template.bind({});
export const PullRequest = Template.bind({});
export const Issue = Template.bind({});
export const BlogPost = Template.bind({});

Default.args = {
title: "Contributor Highlight",
desc: "This is a description",
user: "bdougie",
prLink: "https://github.com/open-sauced/insights/pull/1",
shipped_date: "2023-01-19 13:24:51.000000",
emojis: [
{
name: "100",
url: "https://github.githubassets.com/images/icons/emoji/unicode/1f4af.png?v8",
display_order: 1,
id: "2",
created_at: "",
updated_at: "",
},
],
};

PullRequest.args = {
title: "Contributor Highlight",
desc: "This is a description",
user: "bdougie",
prLink: "https://github.com/open-sauced/insights/pull/1",
shipped_date: "2023-01-19 13:24:51.000000",
emojis: [
{
name: "100",
url: "https://github.githubassets.com/images/icons/emoji/unicode/1f4af.png?v8",
display_order: 3,
id: "4",
created_at: "",
updated_at: "",
},
],
type: "pull_request",
};

Issue.args = {
title: "Contributor Highlight",
desc: "This is a description",
user: "bdougie",
prLink: "https://github.com/open-sauced/insights/pull/1",
shipped_date: "2023-01-19 13:24:51.000000",
emojis: [
{
name: "100",
url: "https://github.githubassets.com/images/icons/emoji/unicode/1f4af.png?v8",
display_order: 3,
id: "4",
created_at: "",
updated_at: "",
},
],
type: "issue",
};

BlogPost.args = {
title: "Contributor Highlight",
desc: "This is a description",
user: "bdougie",
prLink: "https://github.com/open-sauced/insights/pull/1",
shipped_date: "2023-01-19 13:24:51.000000",
emojis: [
{
name: "100",
url: "https://github.githubassets.com/images/icons/emoji/unicode/1f4af.png?v8",
display_order: 3,
id: "4",
created_at: "",
updated_at: "",
},
],
type: "blog",
};

0 comments on commit c88000b

Please sign in to comment.