Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into samuel-issue-219-copy
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel-Aktar-Laskar committed Mar 31, 2024
2 parents 3606186 + a1bd913 commit e612027
Show file tree
Hide file tree
Showing 23 changed files with 216 additions and 118 deletions.
5 changes: 4 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ NEXT_PUBLIC_META_URL=https://leaderboard.ohc.network
## -- Page Details -- ##
NEXT_PUBLIC_PAGE_TITLE=OHC Network Contributors
NEXT_PUBLIC_CONTRIBUTORS_INFO=""
NEXT_PUBLIC_LEADERBOARD_DEFAULT_ROLES=core,intern,contributor
NEXT_PUBLIC_LEADERBOARD_DEFAULT_ROLES=core,intern,contributor

## -- Data Source -- ##
DATA_SOURCE=https://github.com/coronasafe/leaderboard-data.git
10 changes: 8 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@
"tailwindcss/classnames-order": "error",
"tailwindcss/enforces-shorthand": "off",
"tailwindcss/no-contradicting-classname": "error",
"tailwindcss/enforces-negative-arbitrary-values": "off"
"tailwindcss/enforces-negative-arbitrary-values": "off",
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
]
},
"ignorePatterns": ["data"]
"ignorePatterns": ["data"]
}
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ data-repo

#IDE
.idea
.vscode
.vscode

# Package Lock
package-lock.json
yarn.lock
2 changes: 0 additions & 2 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
# Ignore data
./data
./contributors
./data-repo
80 changes: 42 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
A simple leaderboard app built with Next.js and Tailwind CSS to list top contributors of a GitHub organization.
A simple leaderboard app built with Next.js and Tailwind CSS to list the top contributors of a GitHub organization.

<img width="1822" alt="image" src="https://github.com/coronasafe/leaderboard/assets/25143503/6352a4cf-4b8b-4f80-b45c-6af323ee502e">

## Getting Started

### Starting the deployment server
### Prerequisites

Run the following command in the terminal:
Ensure that `pnpm` is installed on your device. You can check the steps for installation here. [Docs Link](https://pnpm.io/installation)

```bash
./load-org-data.sh
```
### Starting the development server

Install dependencies:

```bash
pnpm install
```

Now run the deployment server:
Now run the development server:

```bash
pnpm dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

### Troubleshooting
If you encounter any issues during setup, refer to the following troubleshooting tips:

- **Error: GITHUB_PAT is not configured in the environment. Request quota exhausted for request POST /graphql**
- If you're facing this error for new contributors, follow these steps:
1. Instead of running `pnpm dev`, create your own GitHub access token. [Read Steps here](https://docs.github.com/en/[email protected]/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens).
2. Run the following command instead:

```bash
GITHUB_PAT=<YOUR_KEY> pnpm dev
```
- Alternatively, if you have the `gh cli` installed and configured on your device, you can run the following command without creating an access token:

```bash
GITHUB_PAT=$(gh auth token) pnpm dev
```

### Installing packages

To install new packages, run the following command:
Expand All @@ -38,8 +53,8 @@ pnpm add <package_name>

## How to add a new member?

Create a new markdown file with the github user name in the `contributors` folder. For example, if you want to
add `john-doe` as a contributor, create a file named `john-doe.md` in the `contributors` folder.
Create a new markdown file with the GitHub user name in the `contributors` folder. For example, if you want to
add `john-doe` as a contributor, and create a file named `john-doe.md` in the `contributors` folder.

The file should contain the following content:

Expand All @@ -60,41 +75,30 @@ _Passionate about creating scalable and distributed systems for the power grid a
source digital public goods._ (supports markdown)
```
All members marked with `role: core` and `role: operations` will be will be hidden from the leaderboard section by default.You can toggle their visibility by changing filters.
All members marked with `role: core` and `role: operations` will be hidden from the leaderboard section by default. You can toggle their visibility by changing filters.
You will be able to see the users profile page at `http://localhost:3000/contributors/john-doe`.
You will be able to see the user's profile page at `http://localhost:3000/contributors/john-doe`.
## Customizing the app
# Customizing the app
1. To add or remove a badge, edit the `config/GraduateAttributes.ts` file.
2. To Setup the repo for a new org, update
the [scraper config](https://github.com/coronasafe/leaderboard/blob/d42c7b7ba608c4911d932e92679ab1914371c8a0/.github/workflows/main.yml#L32)
the [scraper config](https://github.com/coronasafe/leaderboard/blob/060d88f1caf2190792beffaa464a2a48bfa6f2db/.github/workflows/scraper.yaml#L40) and update the `DATA_SOURCE` variable in the `.env` file to match the repo containing your organization data.
3. To change the colors, fonts, or plugins edit the `tailwind.config.js` file.
### Environment Variables

#### **Organization Details**

- **NEXT_PUBLIC_ORG_NAME**
- Will be displayed in the navbar.
- **NEXT_PUBLIC_ORG_INFO**
- (Optional) Will be displayed in the "What do we do?" section.
- **NEXT_PUBLIC_ORG_LOGO**
- Will be displayed in the footer.

#### **SEO details**

- **NEXT_PUBLIC_META_TITLE**
- **NEXT_PUBLIC_META_IMG**
- **NEXT_PUBLIC_META_DESCRIPTION**
- **NEXT_PUBLIC_META_URL**

#### **Page Details**

- **NEXT_PUBLIC_PAGE_TITLE**
- Will be displayed in page title.
- **NEXT_PUBLIC_CONTRIBUTORS_INFO**
- (Optional) Will be displayed next to "Our Contributors" section. You can use it to display a note about your
contributors.
## Environment Variables
| Variable | Description | Default | Optional? |
|---|---|---|---|
| **NEXT_PUBLIC_ORG_NAME** | Will be displayed in the navbar | ohc.network | No |
| **NEXT_PUBLIC_ORG_INFO** | Will be displayed in the "What do we do?" section. | 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. | Yes |
| **NEXT_PUBLIC_ORG_LOGO** | Will be displayed in the footer. | /logo.webp | No |
| **NEXT_PUBLIC_META_TITLE** | Metadata title | Open Healthcare Network | No |
| **NEXT_PUBLIC_META_IMG** | Metadata img | /logo.webp | No |
| **NEXT_PUBLIC_META_DESCRIPTION** | Metadata description | OHC Network Leaderboard tracks the weekly progress of all coronasafe contributors. | No |
| **NEXT_PUBLIC_META_URL** | Metadata url | https://leaderboard.ohc.network | No |
| **NEXT_PUBLIC_PAGE_TITLE** | Will be displayed in page title. | OHC Network Contributors | No |
| **NEXT_PUBLIC_CONTRIBUTORS_INFO** | Will be displayed next to "Our Contributors" section. You can use it to display a note about your contributors. | | Yes |
| **DATA_SOURCE** | Url for data repository | https://github.com/coronasafe/leaderboard-data.git | Yes |
9 changes: 2 additions & 7 deletions app/contributors/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,8 @@ export default async function Page({ params }: Params) {
) + 1 || null;

return (
<div className="min-h-screen overflow-x-hidden bg-background">
<div className="min-h-screen overflow-hidden bg-background">
{/* <Header /> */}
<div className="bg-secondary-200/50 dark:bg-secondary-700/50 border-b border-secondary-300 pb-3 pt-2 shadow-md dark:border-secondary-700">
<h1 className="mx-auto max-w-6xl text-center text-sm text-secondary-600 dark:text-secondary-400 md:text-xl">
Personal Learning Dashboard (Beta)
</h1>
</div>
<section className="bg-secondary-200 px-4 py-6 dark:bg-secondary-800">
<div className=" mx-auto flex max-w-6xl flex-col gap-2 md:flex-row lg:gap-16">
<div className="mx-auto my-auto min-w-max md:w-2/3">
Expand Down Expand Up @@ -360,7 +355,7 @@ export default async function Page({ params }: Params) {

{contributor["activityData"] &&
contributor["activityData"]["activity"] && (
<div className="mt-6 px-4 md:p-0">
<div className="mt-6 px-4 md:w-[64rem] md:p-0">
<div className="flex flex-col gap-1">
<h3 className="font-bold text-foreground">Contributions</h3>
<span className="text-sm text-secondary-500 dark:text-secondary-400">
Expand Down
4 changes: 2 additions & 2 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "../theme.css";
@import "../data-repo/config/theme.css";
@tailwind base;
@tailwind components;
@tailwind utilities;
Expand Down Expand Up @@ -129,4 +129,4 @@ html.dark {
opacity: 100;
transform: translateX(0px);
transform: translateY(0px);
}
}
15 changes: 9 additions & 6 deletions components/DateRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ const DateRangePicker = (props: Props) => {
>
{`${formatDate(startDate)}${formatDate(endDate)}`}
</Popover.Button>
<Popover.Panel className="absolute z-10 mt-2 rounded-lg border border-primary-400 bg-background shadow-lg shadow-primary-500">
<Popover.Panel className="absolute z-10 mt-2 w-full rounded-lg border border-primary-400 bg-background shadow-lg shadow-primary-500 sm:min-w-[23rem]">
<div className="flex flex-col p-4">
<div className="flex items-center justify-between gap-2 text-sm font-bold">
<div className="flex flex-col items-center justify-between gap-0 text-sm font-bold sm:flex-row sm:gap-2">
<input
type="date"
name="start"
Expand All @@ -52,9 +52,12 @@ const DateRangePicker = (props: Props) => {
end: endDate,
})
}
className="block w-48 rounded-md border border-secondary-600 bg-transparent p-2 text-center text-foreground dark:border-secondary-300"
className="block w-full rounded-md border border-secondary-600 bg-transparent p-2 text-center text-foreground dark:border-secondary-300"
/>
<span className="text-base font-bold"></span>
<span className="hidden text-base font-bold sm:block">
</span>
<span className="text-base font-bold sm:hidden"></span>
<input
type="date"
name="end"
Expand All @@ -65,10 +68,10 @@ const DateRangePicker = (props: Props) => {
end: e.target.valueAsDate ?? new Date(),
})
}
className="block w-48 rounded-md border border-secondary-600 bg-transparent p-2 text-center text-foreground dark:border-secondary-300"
className="block w-full rounded-md border border-secondary-600 bg-transparent p-2 text-center text-foreground dark:border-secondary-300"
/>
</div>
<div className="mt-6 grid grid-cols-2 gap-2">
<div className="mt-6 grid grid-cols-1 gap-2 sm:grid-cols-2">
{rangePresets.map((range, index) => (
<button
key={index}
Expand Down
53 changes: 40 additions & 13 deletions components/contributors/GithubActivity.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"use client";

import { ACTIVITY_TYPES, Activity, ActivityData } from "@/lib/types";
import { formatDuration } from "@/lib/utils";
import { formatDuration, parseDateRangeSearchParam } from "@/lib/utils";
import OpenGraphImage from "../gh_events/OpenGraphImage";
import { useMemo, useState } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import RelativeTime from "../RelativeTime";
import DateRangePicker from "../DateRangePicker";
import { format } from "date-fns";

let commentTypes = (activityEvent: string[]) => {
switch (activityEvent[0]) {
Expand Down Expand Up @@ -290,7 +292,7 @@ const activitiesOfType = (types: Activity["type"][]) => {
};
};

const getRangeFilterPresets = (activities: Activity[]) => {
/*const getRangeFilterPresets = (activities: Activity[]) => {
if (!activities.length) return [];
const latest = new Date(activities[0].time);
Expand All @@ -312,7 +314,7 @@ const getRangeFilterPresets = (activities: Activity[]) => {
current.setMonth(current.getMonth() + 1);
}
return results.reverse();
};
};*/

interface Props {
activityData: ActivityData;
Expand All @@ -322,11 +324,24 @@ export default function GithubActivity({ activityData }: Props) {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const rangeQuery = searchParams.get("range") ?? "last-month";
// const rangeQuery = searchParams.get("range") ?? "last-month";
const [start, end] = parseDateRangeSearchParam(searchParams.get("between"));

const updateSearchParam = (key: string, value?: string) => {
const current = new URLSearchParams(searchParams);
if (!value) {
current.delete(key);
} else {
current.set(key, value);
}
const search = current.toString();
const query = search ? `?${search}` : "";
router.replace(`${pathname}${query}`, { scroll: false });
};

const [activityTypes, setActivityTypes] = useState([...ACTIVITY_TYPES]);

const range = useMemo(() => {
/*const range = useMemo(() => {
const to = new Date();
to.setDate(to.getDate() + 1);
Expand All @@ -344,15 +359,15 @@ export default function GithubActivity({ activityData }: Props) {
to.setMonth(to.getMonth() + 1);
return { from, to };
}
}, [rangeQuery]);
}, [rangeQuery]);*/

const rangePresets = useMemo(
/*const rangePresets = useMemo(
() => getRangeFilterPresets(activityData["activity"]),
[activityData],
);
);*/

const activitiesInRange = activityData.activity.filter(
activitiesBetween(range),
activitiesBetween({ from: start, to: end }),
);

const activities = activitiesInRange
Expand All @@ -361,9 +376,21 @@ export default function GithubActivity({ activityData }: Props) {

return (
<div className="flex flex-row-reverse flex-wrap items-start justify-between gap-6 md:flex-nowrap">
<div className="top-6 my-4 flex w-full flex-col gap-2 rounded-lg border border-primary-500 p-4 md:sticky md:w-64">
<div className="top-24 my-4 flex w-full flex-col gap-2 rounded-lg border border-primary-500 p-4 md:sticky md:w-[42rem]">
<h3>Filter Activity</h3>
<select
<DateRangePicker
value={{ start, end }}
onChange={(value) => {
updateSearchParam(
"between",
`${format(value.start, "yyyy-MM-dd")}...${format(
value.end,
"yyyy-MM-dd",
)}`,
);
}}
/>
{/* <select
className="my-4 block rounded border border-secondary-600 px-2 py-1 text-sm font-medium text-foreground focus:z-10 focus:outline-none dark:border-secondary-300"
disabled={!rangePresets}
value={rangeQuery}
Expand Down Expand Up @@ -392,7 +419,7 @@ export default function GithubActivity({ activityData }: Props) {
})}
</option>
))}
</select>
</select> */}
{ACTIVITY_TYPES.map((type) => (
<ActivityCheckbox
key={type}
Expand All @@ -403,7 +430,7 @@ export default function GithubActivity({ activityData }: Props) {
/>
))}
</div>
<div className="mt-4 w-full px-1 text-foreground sm:px-2">
<div className="mt-4 w-full grow px-1 text-foreground sm:px-2">
<ul role="list" className="my-4 w-full max-w-xl">
{activities.map((activity, i) => {
return <li key={i}>{showContribution(activity)}</li>;
Expand Down
4 changes: 3 additions & 1 deletion config/GraduateAttributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,9 @@ export type GraduateAttribute = {
let resolveLevel = (attribute: GraduateAttribute, value: number) => {
return {
...attribute,
currentLevel: attribute.levels.reduce((p, v) => (value >= v.value ? v : p)),
currentLevel: value
? attribute.levels.reduce((p, v) => (value >= v.value ? v : p))
: undefined,
};
};

Expand Down
1 change: 0 additions & 1 deletion contributors

This file was deleted.

1 change: 0 additions & 1 deletion data

This file was deleted.

6 changes: 3 additions & 3 deletions lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { Activity, ActivityData, Contributor, Highlights } from "./types";
import { padZero } from "./utils";
import { readFile, readdir } from "fs/promises";

const root = join(process.cwd(), "contributors");
const slackRoot = join(process.cwd(), "data/slack");
const githubRoot = join(process.cwd(), "data/github");
const root = join(process.cwd(), "data-repo/contributors");
const slackRoot = join(process.cwd(), "data-repo/data/slack");
const githubRoot = join(process.cwd(), "data-repo/data/github");

const points = {
comment_created: 1,
Expand Down
Loading

0 comments on commit e612027

Please sign in to comment.