Skip to content

Commit

Permalink
Add "Whats Happening" section (#145)
Browse files Browse the repository at this point in the history
* Add events and GitHub Markdown rendering

* Improvements

* list commits in push event

* added prettier extensions and fixed related eslint errors (#154)

* added prettier extensions and fixed related eslint errors

* updated lock file

---------

Co-authored-by: Khavin Shankar <khavinshankar@gmail.com>
  • Loading branch information
rithviknishad and khavinshankar committed Dec 11, 2023
1 parent ce57c80 commit 3b6cb50
Show file tree
Hide file tree
Showing 13 changed files with 835 additions and 30 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
NEXT_PUBLIC_ORG_NAME=ohc.network
NEXT_PUBLIC_ORG_INFO=Open Healthcare Network is a free and open-source disaster management system that is used by National Health Mission, Government of India and various state governments for reimaging digital war rooms. The solution that students got an opportunity to intern with has supported 3.34Lac patient management and 1.29 Lac ambulance shiftings and is approved by the United Nations as a Digital Public Good.
NEXT_PUBLIC_ORG_LOGO=/logo.webp
NEXT_PUBLIC_GITHUB_ORG=coronasafe

## -- SEO details -- ##
NEXT_PUBLIC_META_TITLE=Open Healthcare Network
Expand Down
15 changes: 15 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import InfoCard from "../components/contributors/InfoCard";
import Link from "next/link";
import { getContributors } from "../lib/api";
import { getLastWeekDateRangeString } from "../lib/utils";
import GitHubEvents from "@/components/gh_events/GitHubEvents";

export default function Home() {
const contributors: any = getContributors();
Expand Down Expand Up @@ -31,6 +32,20 @@ export default function Home() {
) : (
<div className="pt-0" />
)}

<div>
<div className="mx-auto">
<div className="space-y-12">
<div className="space-y-5 sm:space-y-4 md:max-w-xl lg:max-w-3xl xl:max-w-none">
<h2 className="text-3xl font-bold tracking-tight sm:text-5xl">
What&apos;s happening?
</h2>
</div>
<GitHubEvents minimal />
</div>
</div>
</div>

<div>
<div className="mx-auto">
<div className="space-y-12">
Expand Down
14 changes: 2 additions & 12 deletions components/contributors/GithubActivity.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Activity, ActivityData } from "@/lib/types";
import OpenGraphImage from "../gh_events/OpenGraphImage";

let commentTypes = (activityEvent: string[]) => {
switch (activityEvent[0]) {
Expand Down Expand Up @@ -89,18 +90,7 @@ let renderText = (activity: Activity) => {
</div>
{activity["type"] == "pr_merged" && (
<div className="pt-4">
<a href={activity["link"]}>
<img
alt={activity["link"]}
className="rounded-xl"
src={`https://opengraph.githubassets.com/${generateId()}/${activity[
"link"
]
.split("/")
.slice(3, 7)
.join("/")}/`}
/>
</a>
<OpenGraphImage url={activity["link"]} className="rounded-xl" />
</div>
)}
{activity["type"] != "pr_merged" && (
Expand Down
5 changes: 3 additions & 2 deletions components/contributors/InfoCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { Contributor } from "@/lib/types";
import clsx from "clsx";
import Link from "next/link";

export default function InfoCard({
contributor,
minimal = true,
Expand All @@ -26,12 +27,12 @@ export default function InfoCard({
className=""
>
<div
className={`flex flex-shrink-0 items-center bg-opacity-50 rounded-full md:p-1 relative z-10 ${
className={`flex flex-shrink-0 items-center bg-opacity-50 rounded-full md:p-1 z-10 h-28 w-28 md:h-32 md:w-32 ${
isClickable && `cursor-pointer`
}`}
>
<img
className=" h-28 w-28 md:h-32 md:w-32 rounded-full border-2 border-indigo-500"
className="rounded-full border-2 border-indigo-500"
src={`https://avatars.githubusercontent.com/${contributor.github}`}
alt={contributor.github}
/>
Expand Down
194 changes: 194 additions & 0 deletions components/gh_events/GitHubEvent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import { IGitHubEvent } from "@/lib/gh_events";
import GitHubReleaseEventBody from "./ReleaseEventBody";
import OpenGraphImage from "./OpenGraphImage";
import timeSince from "@/lib/timeSince";

export default function GitHubEvent({ event }: { event?: IGitHubEvent }) {
if (!event) {
return (
<div className="w-full h-10 bg-gray-200 dark:bg-gray-700 animate-pulse rounded" />
);
}

let title, body;

switch (event.type) {
case "MemberEvent":
title = (
<>
{event.payload.action} member{" "}
<a
className="cursor-pointer text-gray-300 font-bold"
href={"https://github.com/" + event.payload.member.login}
>
{event.payload.member.login}
</a>
</>
);
body = "";
break;

case "IssuesEvent":
title = (
<>
{event.payload.action} an issue in{" "}
<a
className="cursor-pointer text-gray-300 font-bold"
href={"https://github.com/" + event.repo.name}
>
{event.repo.name}
</a>
</>
);
body = <OpenGraphImage url={event.payload.issue.html_url} />;
break;

case "PullRequestEvent":
title = (
<>
{event.payload.action} a pull request in{" "}
<a
className="cursor-pointer text-gray-300 font-bold"
href={"https://github.com/" + event.repo.name}
>
{event.repo.name}
</a>
</>
);
body = event.payload.action === "opened" && (
<OpenGraphImage url={event.payload.pull_request.html_url} />
);
break;

case "PushEvent":
title = (
<>
pushed {event.payload.size} commits to{" "}
<span className="text-gray-300 font-bold">
{event.payload.ref.replace("refs/heads/", "")}
</span>{" "}
in{" "}
<a
className="cursor-pointer text-gray-300 font-bold"
href={event.repo.url}
>
{event.repo.name}
</a>
</>
);
body = (
<ul className="text-xs">
{event.payload.commits.map((commit) => (
<a
key={commit.sha}
className="hover:underline group"
href={`https://github.com/${event.repo.name}/commit/${commit.sha}`}
>
<li>
<span className="text-gray-500 font-mono px-2 group-hover:text-gray-700 dark:group-hover:text-gray-300">
{commit.sha.slice(-7)}
</span>
<span className="text-gray-700 dark:text-gray-300">
{commit.message.split("\n")[0]}
</span>
</li>
</a>
))}
</ul>
);
break;

case "ForkEvent":
title = (
<>
forked{" "}
<a
className="cursor-pointer text-gray-300 font-bold"
href={event.repo.url}
>
{event.repo.name}
</a>
</>
);
body = <OpenGraphImage url={event.payload.forkee.html_url} />;
break;

case "ReleaseEvent":
title = (
<>
released{" "}
<a
className="cursor-pointer text-gray-300 font-bold"
href={event.payload.release.html_url}
>
{event.repo.name}#{event.payload.release.tag_name}
</a>
</>
);
body = <GitHubReleaseEventBody event={event} />;
break;

default:
title = (event as IGitHubEvent).type;
// body = JSON.stringify(event.payload);
break;
}

return (
<li>
<div className="relative pb-4">
<span
className="absolute left-5 top-5 -ml-px h-full w-0.5 bg-gray-200 dark:bg-gray-700"
aria-hidden
/>
<div className="relative flex items-start space-x-5">
<div className="relative">
<img
className="flex h-10 w-10 items-center justify-center rounded-full bg-gray-400 ring-8 ring-gray-200 dark:ring-gray-700"
src={event.actor.avatar_url + "&s=40"}
alt=""
/>
{event.type.includes("Comment") && (
<span className="absolute -bottom-1.5 -right-1.5 rounded bg-gray-200 dark:bg-gray-700 px-0.5 py-px">
<svg
className="h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden
>
<path
fillRule="evenodd"
d="M10 2c-2.236 0-4.43.18-6.57.524C1.993 2.755 1 4.014 1 5.426v5.148c0 1.413.993 2.67 2.43 2.902.848.137 1.705.248 2.57.331v3.443a.75.75 0 001.28.53l3.58-3.579a.78.78 0 01.527-.224 41.202 41.202 0 005.183-.5c1.437-.232 2.43-1.49 2.43-2.903V5.426c0-1.413-.993-2.67-2.43-2.902A41.289 41.289 0 0010 2zm0 7a1 1 0 100-2 1 1 0 000 2zM8 8a1 1 0 11-2 0 1 1 0 012 0zm5 1a1 1 0 100-2 1 1 0 000 2z"
clipRule="evenodd"
/>
</svg>
</span>
)}
</div>

<div className="min-w-0 flex-1">
<div>
<span className="text-sm text-gray-700 dark:text-gray-300">
<a
href={`https://github.com/${event.actor.login}`}
className="font-bold text-gray-700 dark:text-gray-300 cursor-pointer"
>
{event.actor.login}
</a>{" "}
<span className="mt-0.5 text-sm text-gray-400">
{title} {timeSince(event.created_at)}
</span>
</span>

{!!body && (
<div className="mt-4 ml-2 max-w-lg rounded-xl overflow-hidden">
<p>{body}</p>
</div>
)}
</div>
</div>
</div>
</div>
</li>
);
}
60 changes: 60 additions & 0 deletions components/gh_events/GitHubEvents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"use client";

import { IGitHubEvent } from "@/lib/gh_events";
import { useEffect, useState } from "react";
import GitHubEvent from "./GitHubEvent";

const exludeBotEvents = (event: IGitHubEvent) => {
return !event.actor.login.includes("bot");
};

const excludeBlacklistedEvents = (event: IGitHubEvent) => {
const blacklist = [
"CreateEvent",
"WatchEvent",
"PullRequestReviewEvent",
"PullRequestReviewCommentEvent",
"DeleteEvent",
"IssueCommentEvent",
] as IGitHubEvent["type"][];

return !blacklist.includes(event.type);
};

export default function GitHubEvents({ minimal }: { minimal?: boolean }) {
const [page, setPage] = useState(1);
const [events, setEvents] = useState<IGitHubEvent[]>();

useEffect(() => {
fetch(
`https://api.github.com/orgs/${process.env.NEXT_PUBLIC_GITHUB_ORG}/events?per_page=20&page=${page}`,
)
.then((res) => res.json())
.then((data) =>
setEvents(
data
.filter(exludeBotEvents)
.filter(excludeBlacklistedEvents)
.slice(0, 5),
),
);
}, [page]);

return (
<div className="flow-root">
<ul role="list" className="space-y-4 flex flex-col gap-4 mt-4 -mb-8">
{events ? (
events.map((e) => <GitHubEvent key={e.id} event={e} />)
) : (
<>
<GitHubEvent />
<GitHubEvent />
<GitHubEvent />
<GitHubEvent />
<GitHubEvent />
</>
)}
</ul>
</div>
);
}
18 changes: 18 additions & 0 deletions components/gh_events/OpenGraphImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const hashed = (url: string) => {
return Buffer.from(url + new Date().toDateString()).toString("base64");
};

const OpenGraphImage = (props: { url: string; className?: string }) => {
const src = props.url.replace(
"https://github.com/",
`https://opengraph.githubassets.com/${hashed(props.url)}/`,
);

return (
<a href={props.url}>
<img alt={props.url} className={props.className} src={src} />
</a>
);
};

export default OpenGraphImage;
30 changes: 30 additions & 0 deletions components/gh_events/ReleaseEventBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ReleaseEvent } from "@/lib/gh_events";

export default function GitHubReleaseEventBody({
event,
}: {
event: ReleaseEvent;
}) {
return (
<div className="flex flex-col gap-2">
<a
className="underline text-white font-medium"
href={event.payload.release.html_url}
>
See release notes
</a>
<span className="text-white font-medium">Contributors</span>
<ul className="flex flex-wrap gap-2">
{event.payload.release.mentions.map((contributor) => (
<li key={contributor.login}>
<img
src={contributor.avatar_url + "&s=64"}
alt={contributor.login}
className="w-8 h-8 rounded-full"
/>
</li>
))}
</ul>
</div>
);
}
Loading

1 comment on commit 3b6cb50

@vercel
Copy link

@vercel vercel bot commented on 3b6cb50 Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.