Added OG Image (#5251)
- Added dynamic OG Image to share and download in contributors page <img width="1176" alt="Screenshot 2024-05-02 at 16 24 00" src="https://github.com/twentyhq/twenty/assets/102751374/0579454b-ccc7-46ba-9875-52458f06ee82"> - Added dynamic metadata - Added design to contributor page - Added a NEXT_PUBLIC_HOST_URL in the .env file Co-authored-by: Ady Beraud <a.beraud96@gmail.com>
This commit is contained in:
@ -7,11 +7,11 @@ import { Breadcrumb } from '@/app/_components/contributors/Breadcrumb';
|
||||
import { ContentContainer } from '@/app/_components/contributors/ContentContainer';
|
||||
import { ProfileCard } from '@/app/_components/contributors/ProfileCard';
|
||||
import { ProfileInfo } from '@/app/_components/contributors/ProfileInfo';
|
||||
import { ProfileSharing } from '@/app/_components/contributors/ProfileSharing';
|
||||
import { PullRequests } from '@/app/_components/contributors/PullRequests';
|
||||
import { ThankYou } from '@/app/_components/contributors/ThankYou';
|
||||
import { Background } from '@/app/_components/oss-friends/Background';
|
||||
import { findAll } from '@/database/database';
|
||||
import { pullRequestModel, userModel } from '@/database/model';
|
||||
import { getContributorActivity } from '@/app/contributors/utils/get-contributor-activity';
|
||||
|
||||
export function generateMetadata({
|
||||
params,
|
||||
@ -24,114 +24,63 @@ export function generateMetadata({
|
||||
'Explore the impactful contributions of ' +
|
||||
params.slug +
|
||||
' on the Twenty Github Repo. Discover their merged pull requests, ongoing work, and top ranking. Join and contribute to the #1 Open-Source CRM thriving community!',
|
||||
openGraph: {
|
||||
images: [`/api/contributors/og-image/${params.slug}`],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function ({ params }: { params: { slug: string } }) {
|
||||
const contributors = await findAll(userModel);
|
||||
try {
|
||||
const contributorActivity = await getContributorActivity(params.slug);
|
||||
if (contributorActivity) {
|
||||
const {
|
||||
firstContributionAt,
|
||||
mergedPRsCount,
|
||||
rank,
|
||||
activeDays,
|
||||
pullRequestActivityArray,
|
||||
contributorPullRequests,
|
||||
contributor,
|
||||
} = contributorActivity;
|
||||
|
||||
const contributor = contributors.find(
|
||||
(contributor) => contributor.id === params.slug,
|
||||
);
|
||||
|
||||
if (!contributor) {
|
||||
return;
|
||||
return (
|
||||
<Background>
|
||||
<ContentContainer>
|
||||
<Breadcrumb active={contributor.id} />
|
||||
<ProfileCard
|
||||
username={contributor.id}
|
||||
avatarUrl={contributor.avatarUrl}
|
||||
firstContributionAt={firstContributionAt}
|
||||
/>
|
||||
<ProfileInfo
|
||||
mergedPRsCount={mergedPRsCount}
|
||||
rank={rank}
|
||||
activeDays={activeDays}
|
||||
/>
|
||||
<ProfileSharing
|
||||
userUrl={contributor.url}
|
||||
username={contributor.id}
|
||||
/>
|
||||
<ActivityLog data={pullRequestActivityArray} />
|
||||
<PullRequests
|
||||
list={
|
||||
contributorPullRequests.slice(0, 9) as {
|
||||
id: string;
|
||||
title: string;
|
||||
url: string;
|
||||
createdAt: string;
|
||||
mergedAt: string | null;
|
||||
authorId: string;
|
||||
}[]
|
||||
}
|
||||
/>
|
||||
<ThankYou username={contributor.id} />
|
||||
</ContentContainer>
|
||||
</Background>
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('error: ', error);
|
||||
}
|
||||
|
||||
const pullRequests = await findAll(pullRequestModel);
|
||||
const mergedPullRequests = pullRequests
|
||||
.filter((pr) => pr.mergedAt !== null)
|
||||
.filter(
|
||||
(pr) =>
|
||||
![
|
||||
'dependabot',
|
||||
'cyborch',
|
||||
'emilienchvt',
|
||||
'Samox',
|
||||
'charlesBochet',
|
||||
'gitstart-app',
|
||||
'thaisguigon',
|
||||
'lucasbordeau',
|
||||
'magrinj',
|
||||
'Weiko',
|
||||
'gitstart-twenty',
|
||||
'bosiraphael',
|
||||
'martmull',
|
||||
'FelixMalfait',
|
||||
'thomtrp',
|
||||
'Bonapara',
|
||||
'nimraahmed',
|
||||
].includes(pr.authorId),
|
||||
);
|
||||
|
||||
const contributorPullRequests = pullRequests.filter(
|
||||
(pr) => pr.authorId === contributor.id,
|
||||
);
|
||||
const mergedContributorPullRequests = contributorPullRequests.filter(
|
||||
(pr) => pr.mergedAt !== null,
|
||||
);
|
||||
|
||||
const mergedContributorPullRequestsByContributor = mergedPullRequests.reduce(
|
||||
(acc, pr) => {
|
||||
acc[pr.authorId] = (acc[pr.authorId] || 0) + 1;
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
const mergedContributorPullRequestsByContributorArray = Object.entries(
|
||||
mergedContributorPullRequestsByContributor,
|
||||
)
|
||||
.map(([authorId, value]) => ({ authorId, value }))
|
||||
.sort((a, b) => b.value - a.value);
|
||||
|
||||
const contributorRank =
|
||||
((mergedContributorPullRequestsByContributorArray.findIndex(
|
||||
(contributor) => contributor.authorId === params.slug,
|
||||
) +
|
||||
1) /
|
||||
contributors.length) *
|
||||
100;
|
||||
|
||||
const pullRequestActivity = contributorPullRequests.reduce((acc, pr) => {
|
||||
const date = new Date(pr.createdAt).toISOString().split('T')[0];
|
||||
acc[date] = (acc[date] || 0) + 1;
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
const pullRequestActivityArray = Object.entries(pullRequestActivity)
|
||||
.map(([day, value]) => ({ day, value }))
|
||||
.sort((a, b) => new Date(a.day).getTime() - new Date(b.day).getTime());
|
||||
|
||||
return (
|
||||
<Background>
|
||||
<ContentContainer>
|
||||
<Breadcrumb active={contributor.id} />
|
||||
<ProfileCard
|
||||
username={contributor.id}
|
||||
avatarUrl={contributor.avatarUrl}
|
||||
firstContributionAt={pullRequestActivityArray[0]?.day}
|
||||
/>
|
||||
<ProfileInfo
|
||||
mergedPRsCount={mergedContributorPullRequests.length}
|
||||
rank={Math.ceil(Number(contributorRank)).toFixed(0)}
|
||||
activeDays={pullRequestActivityArray.length}
|
||||
/>
|
||||
<ActivityLog data={pullRequestActivityArray} />
|
||||
<PullRequests
|
||||
list={
|
||||
contributorPullRequests.slice(0, 9) as {
|
||||
id: string;
|
||||
title: string;
|
||||
url: string;
|
||||
createdAt: string;
|
||||
mergedAt: string | null;
|
||||
authorId: string;
|
||||
}[]
|
||||
}
|
||||
/>
|
||||
<ThankYou username={contributor.id} />
|
||||
</ContentContainer>
|
||||
</Background>
|
||||
);
|
||||
}
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
import { findAll } from '@/database/database';
|
||||
import { pullRequestModel, userModel } from '@/database/model';
|
||||
|
||||
export const getContributorActivity = async (username: string) => {
|
||||
const contributors = await findAll(userModel);
|
||||
|
||||
const contributor = contributors.find((contributor) => {
|
||||
return contributor.id === username;
|
||||
});
|
||||
|
||||
if (!contributor) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pullRequests = await findAll(pullRequestModel);
|
||||
const mergedPullRequests = pullRequests
|
||||
.filter((pr) => pr.mergedAt !== null)
|
||||
.filter(
|
||||
(pr) =>
|
||||
![
|
||||
'dependabot',
|
||||
'cyborch',
|
||||
'emilienchvt',
|
||||
'Samox',
|
||||
'charlesBochet',
|
||||
'gitstart-app',
|
||||
'thaisguigon',
|
||||
'lucasbordeau',
|
||||
'magrinj',
|
||||
'Weiko',
|
||||
'gitstart-twenty',
|
||||
'bosiraphael',
|
||||
'martmull',
|
||||
'FelixMalfait',
|
||||
'thomtrp',
|
||||
'Bonapara',
|
||||
'nimraahmed',
|
||||
].includes(pr.authorId),
|
||||
);
|
||||
|
||||
const contributorPullRequests = pullRequests.filter(
|
||||
(pr) => pr.authorId === contributor.id,
|
||||
);
|
||||
const mergedContributorPullRequests = contributorPullRequests.filter(
|
||||
(pr) => pr.mergedAt !== null,
|
||||
);
|
||||
|
||||
const mergedContributorPullRequestsByContributor = mergedPullRequests.reduce(
|
||||
(acc, pr) => {
|
||||
acc[pr.authorId] = (acc[pr.authorId] || 0) + 1;
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
const mergedContributorPullRequestsByContributorArray = Object.entries(
|
||||
mergedContributorPullRequestsByContributor,
|
||||
)
|
||||
.map(([authorId, value]) => ({ authorId, value }))
|
||||
.sort((a, b) => b.value - a.value);
|
||||
|
||||
const contributorRank =
|
||||
((mergedContributorPullRequestsByContributorArray.findIndex(
|
||||
(contributor) => contributor.authorId === username,
|
||||
) +
|
||||
1) /
|
||||
contributors.length) *
|
||||
100;
|
||||
|
||||
const pullRequestActivity = contributorPullRequests.reduce((acc, pr) => {
|
||||
const date = new Date(pr.createdAt).toISOString().split('T')[0];
|
||||
acc[date] = (acc[date] || 0) + 1;
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
const pullRequestActivityArray = Object.entries(pullRequestActivity)
|
||||
.map(([day, value]) => ({ day, value }))
|
||||
.sort((a, b) => new Date(a.day).getTime() - new Date(b.day).getTime());
|
||||
|
||||
const firstContributionAt = pullRequestActivityArray[0]?.day;
|
||||
const mergedPRsCount = mergedContributorPullRequests.length;
|
||||
const rank = Math.ceil(Number(contributorRank)).toFixed(0);
|
||||
const activeDays = pullRequestActivityArray.length;
|
||||
const contributorAvatar = contributor.avatarUrl;
|
||||
|
||||
return {
|
||||
firstContributionAt,
|
||||
mergedPRsCount,
|
||||
rank,
|
||||
activeDays,
|
||||
pullRequestActivityArray,
|
||||
contributorPullRequests,
|
||||
contributorAvatar,
|
||||
contributor,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user