feat: fetch data for charts

This commit is contained in:
Ephraim Atta-Duncan
2024-10-24 10:32:18 +00:00
parent d80634e0d0
commit 364f9894b0
8 changed files with 220 additions and 2 deletions

View File

@@ -0,0 +1,36 @@
import type { NextRequest } from 'next/server';
import cors from '@/lib/cors';
const paths = [
{ path: '/total-prs', description: 'Total GitHub Forks' },
{ path: '/total-stars', description: 'Total GitHub Stars' },
{ path: '/total-forks', description: 'Total GitHub Forks' },
{ path: '/total-issues', description: 'Total GitHub Issues' },
];
export function GET(request: NextRequest) {
const url = request.nextUrl.toString();
const apis = paths.map(({ path, description }) => {
return { path: url + path, description };
});
return cors(
request,
new Response(JSON.stringify(apis), {
status: 200,
headers: {
'content-type': 'application/json',
},
}),
);
}
export function OPTIONS(request: Request) {
return cors(
request,
new Response(null, {
status: 204,
}),
);
}

View File

@@ -0,0 +1,27 @@
import cors from '@/lib/cors';
import { transformRepoStats } from '@/lib/transform-repo-stats';
export async function GET(request: Request) {
const res = await fetch('https://stargrazer-live.onrender.com/api/stats');
const data = await res.json();
const transformedData = transformRepoStats(data, 'forks');
return cors(
request,
new Response(JSON.stringify({ 'total-forks': transformedData }), {
status: 200,
headers: {
'content-type': 'application/json',
},
}),
);
}
export function OPTIONS(request: Request) {
return cors(
request,
new Response(null, {
status: 204,
}),
);
}

View File

@@ -0,0 +1,27 @@
import cors from '@/lib/cors';
import { transformRepoStats } from '@/lib/transform-repo-stats';
export async function GET(request: Request) {
const res = await fetch('https://stargrazer-live.onrender.com/api/stats');
const data = await res.json();
const transformedData = transformRepoStats(data, 'openIssues');
return cors(
request,
new Response(JSON.stringify({ 'total-issues': transformedData }), {
status: 200,
headers: {
'content-type': 'application/json',
},
}),
);
}
export function OPTIONS(request: Request) {
return cors(
request,
new Response(null, {
status: 204,
}),
);
}

View File

@@ -0,0 +1,27 @@
import cors from '@/lib/cors';
import { transformRepoStats } from '@/lib/transform-repo-stats';
export async function GET(request: Request) {
const res = await fetch('https://stargrazer-live.onrender.com/api/stats');
const data = await res.json();
const transformedData = transformRepoStats(data, 'stars');
return cors(
request,
new Response(JSON.stringify({ 'total-stars': transformedData }), {
status: 200,
headers: {
'content-type': 'application/json',
},
}),
);
}
export function OPTIONS(request: Request) {
return cors(
request,
new Response(null, {
status: 204,
}),
);
}

View File

@@ -0,0 +1,27 @@
import cors from '@/lib/cors';
import { transformRepoStats } from '@/lib/transform-repo-stats';
export async function GET(request: Request) {
const res = await fetch('https://stargrazer-live.onrender.com/api/stats');
const data = await res.json();
const transformedData = transformRepoStats(data, 'stars');
return cors(
request,
new Response(JSON.stringify({ 'total-stars': transformedData }), {
status: 200,
headers: {
'content-type': 'application/json',
},
}),
);
}
export function OPTIONS(request: Request) {
return cors(
request,
new Response(null, {
status: 204,
}),
);
}

View File

@@ -2,7 +2,10 @@ import type { NextRequest } from 'next/server';
import cors from '@/lib/cors';
const paths = [{ path: 'github', description: 'GitHub Data' }];
const paths = [
{ path: 'github', description: 'GitHub Data' },
{ path: 'community', description: 'Community Data' },
];
export function GET(request: NextRequest) {
const url = request.nextUrl.toString();

View File

@@ -0,0 +1,71 @@
// Define interfaces for the data structure
type RepoStats = {
stars: number;
forks: number;
mergedPRs: number;
openIssues: number;
};
type DataEntry = {
[key: string]: RepoStats;
};
type TransformedData = {
labels: string[];
datasets: {
label: string;
data: number[];
}[];
};
type MonthNames = {
[key: string]: string;
};
type MetricKey = keyof RepoStats;
const FRIENDLY_METRIC_NAMES: { [key in MetricKey]: string } = {
stars: 'Stars',
forks: 'Forks',
mergedPRs: 'Merged PRs',
openIssues: 'Open Issues',
};
export function transformRepoStats(data: DataEntry, metric: MetricKey): TransformedData {
const sortedEntries = Object.entries(data).sort(([dateA], [dateB]) => {
const [yearA, monthA] = dateA.split('-').map(Number);
const [yearB, monthB] = dateB.split('-').map(Number);
return new Date(yearA, monthA - 1).getTime() - new Date(yearB, monthB - 1).getTime();
});
const monthNames: MonthNames = {
'1': 'Jan',
'2': 'Feb',
'3': 'Mar',
'4': 'Apr',
'5': 'May',
'6': 'Jun',
'7': 'Jul',
'8': 'Aug',
'9': 'Sep',
'10': 'Oct',
'11': 'Nov',
'12': 'Dec',
};
const labels = sortedEntries.map(([date]) => {
const [year, month] = date.split('-');
const monthIndex = parseInt(month);
return `${monthNames[monthIndex.toString()]} ${year}`;
});
return {
labels,
datasets: [
{
label: `Total ${FRIENDLY_METRIC_NAMES[metric]}`,
data: sortedEntries.map(([_, stats]) => stats[metric]),
},
],
};
}

View File

@@ -9,7 +9,7 @@
"dev:marketing": "turbo run dev --filter=@documenso/marketing",
"dev:docs": "turbo run dev --filter=@documenso/documentation",
"dev:openpage-api": "turbo run dev --filter=@documenso/openpage-api",
"start": "turbo run start --filter=@documenso/web --filter=@documenso/marketing --filter=@documenso/documentation",
"start": "turbo run start --filter=@documenso/web --filter=@documenso/marketing --filter=@documenso/documentation --filter=@documenso/openpage-api",
"lint": "turbo run lint",
"lint:fix": "turbo run lint:fix",
"format": "prettier --write \"**/*.{js,jsx,cjs,mjs,ts,tsx,cts,mts,mdx}\"",