Skip to content

Commit

Permalink
feat: fork
Browse files Browse the repository at this point in the history
  • Loading branch information
Nevo David committed Oct 17, 2023
1 parent 3df456d commit 04120aa
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 47 deletions.
8 changes: 7 additions & 1 deletion helpers/twitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ export default async function twitter(req, res, query) {
},
});

const findForks = await prisma.forkGiven.findMany({
where: {
userId: user.id,
},
});

if (!user?.id || !query.code) {
return { props: { twitter, devto, findStars } };
return { props: { twitter, devto, findStars, findForks } };
}

return {
Expand Down
9 changes: 9 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ model User {
userActionLogs ActionLogs[] @relation("affectedUser")
adminActionLogs ActionLogs[] @relation("admin")
starsGiven StarsGiven[]
forksGiven ForkGiven[]
winners Winners[]
votes ArticlesVotes[]
}
Expand All @@ -169,6 +170,14 @@ model StarsGiven {
@@unique([userId, library])
}

model ForkGiven {
id String @id @default(cuid())
userId String
library String
user User @relation(fields: [userId], references: [id])
@@unique([userId, library])
}

model Winners {
id String @id @default(cuid())
month Int
Expand Down
89 changes: 89 additions & 0 deletions src/components/pages/bonuses/hero/fork.the.library.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { usePlausible } from 'next-plausible';
import PropTypes from 'prop-types';
import { useCallback, useState } from 'react';
import { toast } from 'react-toastify';

import GitHubIcon from '../../../../icons/github.inline.svg';

const ForkTheLibrary = ({ bonus, number, name, library, accepted }) => {
const plausible = usePlausible();
const [starred, setStarred] = useState(accepted);
const test = useCallback(async () => {
const data = await (
await fetch('/api/github-fork', {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
method: 'POST',
body: JSON.stringify({ library }),
})
).json();

if (data.finish) {
plausible('star-the-library', { props: { library } });
setStarred(true);
} else {
toast.error('No fork found, please try to remove the fork and fork again');
}
}, []);

return (
<li className="grid grid-cols-[20px_485px_230px_1fr] gap-x-5 border-b border-gray-2 py-4 lg:grid-cols-[20px_390px_1fr_1fr] md:grid-cols-[20px_485px_230px_1fr] sm:grid-cols-[100px_100px_120px]">
<span className="sm:hidden">{number + 2}</span>
<span>
<a
href={`https://github.com/${library}`}
className="cursor-pointer"
target="_blank"
rel="external noopener"
>
<div className="flex">
<div>
Fork <strong>{name}</strong>
</div>
<div>
<GitHubIcon className="ml-[10px] h-[20px] leading-[0]" />
</div>
</div>
</a>
</span>
<span>{bonus || 1} points</span>
<span>
{starred ? (
<span>Accepted!</span>
) : (
<a
className="cta-btn-animation relative flex max-w-full cursor-pointer items-center justify-center leading-none"
rel="noreferrer"
onClick={test}
>
<svg
className="cta-btn-animation-border xs:w-full"
width="200"
height="59"
viewBox="0 0 268 59"
fill="none"
>
<path d="M1 58V1H251.586L267 16.4142V58H1Z" stroke="white" strokeWidth="2" />
</svg>

<div className="absolute inset-0 flex items-center justify-center space-x-2.5">
<span className="text-lg sm:text-[18px]">Check</span>
</div>
</a>
)}
</span>
</li>
);
};

ForkTheLibrary.propTypes = {
bonus: PropTypes.number,
number: PropTypes.number,
name: PropTypes.string,
library: PropTypes.string,
accepted: PropTypes.bool,
};

export default ForkTheLibrary;
41 changes: 40 additions & 1 deletion src/components/pages/bonuses/hero/hero.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import React from 'react';

import InviteButton from '../../../shared/invite/invite.button';

import ForkTheLibrary from './fork.the.library';
import StarTheLibrary from './star.the.library';

const title = 'Bonuses';

const Hero = ({ findStars }) => (
const Hero = ({ findStars, findForks }) => (
<section className="safe-paddings relative">
<div className="container relative z-10 flex h-full flex-col items-center justify-center py-16">
<h1 className="font-titles text-60 font-semibold leading-none md:text-42">{title}</h1>
Expand Down Expand Up @@ -74,6 +75,43 @@ const Hero = ({ findStars }) => (
bonus={1}
accepted={findStars.find((item) => item.library === 'clickvote/clickvote')}
/>
<ForkTheLibrary
number={2}
name="Novu"
library="novuhq/novu"
accepted={findForks.find((item) => item.library === 'novuhq/novu')}
/>
<ForkTheLibrary
number={3}
name="ToolJet"
library="tooljet/tooljet"
accepted={findForks.find((item) => item.library === 'tooljet/tooljet')}
/>
<ForkTheLibrary
number={4}
name="Wasp"
library="wasp-lang/wasp"
accepted={findForks.find((item) => item.library === 'wasp-lang/wasp')}
/>
<ForkTheLibrary
number={5}
name="Hanko"
library="teamhanko/hanko"
accepted={findForks.find((item) => item.library === 'teamhanko/hanko')}
/>
<ForkTheLibrary
number={6}
name="CrowdDev"
library="CrowdDotDev/crowd.dev"
accepted={findForks.find((item) => item.library === 'CrowdDotDev/crowd.dev')}
/>
<ForkTheLibrary
number={7}
name="ClickVote"
library="clickvote/clickvote"
bonus={1}
accepted={findForks.find((item) => item.library === 'clickvote/clickvote')}
/>
<li className="grid grid-cols-[20px_485px_230px_1fr] gap-x-5 border-b border-gray-2 py-4 lg:grid-cols-[20px_390px_1fr_1fr] md:grid-cols-[20px_485px_230px_1fr] sm:grid-cols-[100px_100px_120px]">
<span className="sm:hidden">8</span>
<span>
Expand Down Expand Up @@ -139,6 +177,7 @@ Hero.propTypes = {
twitter: PropTypes.bool,
devto: PropTypes.bool,
findStars: PropTypes.array,
findForks: PropTypes.array,
};

export default Hero;
86 changes: 43 additions & 43 deletions src/components/pages/bonuses/hero/star.the.library.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,53 +30,53 @@ const StarTheLibrary = ({ bonus, number, name, library, accepted }) => {

return (
<li className="grid grid-cols-[20px_485px_230px_1fr] gap-x-5 border-b border-gray-2 py-4 lg:grid-cols-[20px_390px_1fr_1fr] md:grid-cols-[20px_485px_230px_1fr] sm:grid-cols-[100px_100px_120px]">
<span className="sm:hidden">{number}</span>
<span>
<a
href={`https://github.com/${library}`}
className="cursor-pointer"
target="_blank"
rel="external noopener"
>
<div className="flex">
<div>
Give <strong>{name}</strong> a star{' '}
</div>
<div>
<GitHubIcon className="ml-[10px] h-[20px] leading-[0]" />
</div>
</div>
<br />
(if you already gave a star, remove the star and star again)
</a>
</span>
<span>{bonus || 1} points</span>
<span>
{starred ? (
<span>Accepted!</span>
) : (
<span className="sm:hidden">{number}</span>
<span>
<a
className="cta-btn-animation relative flex max-w-full cursor-pointer items-center justify-center leading-none"
rel="noreferrer"
onClick={test}
href={`https://github.com/${library}`}
className="cursor-pointer"
target="_blank"
rel="external noopener"
>
<svg
className="cta-btn-animation-border xs:w-full"
width="200"
height="59"
viewBox="0 0 268 59"
fill="none"
>
<path d="M1 58V1H251.586L267 16.4142V58H1Z" stroke="white" strokeWidth="2" />
</svg>

<div className="absolute inset-0 flex items-center justify-center space-x-2.5">
<span className="text-lg sm:text-[18px]">Check</span>
<div className="flex">
<div>
Give <strong>{name}</strong> a star{' '}
</div>
<div>
<GitHubIcon className="ml-[10px] h-[20px] leading-[0]" />
</div>
</div>
<br />
(if you already gave a star, remove the star and star again)
</a>
)}
</span>
</li>
</span>
<span>{bonus || 1} points</span>
<span>
{starred ? (
<span>Accepted!</span>
) : (
<a
className="cta-btn-animation relative flex max-w-full cursor-pointer items-center justify-center leading-none"
rel="noreferrer"
onClick={test}
>
<svg
className="cta-btn-animation-border xs:w-full"
width="200"
height="59"
viewBox="0 0 268 59"
fill="none"
>
<path d="M1 58V1H251.586L267 16.4142V58H1Z" stroke="white" strokeWidth="2" />
</svg>

<div className="absolute inset-0 flex items-center justify-center space-x-2.5">
<span className="text-lg sm:text-[18px]">Check</span>
</div>
</a>
)}
</span>
</li>
);
};

Expand Down
56 changes: 56 additions & 0 deletions src/pages/api/github-fork.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import findGitHubToken from '~/helpers/find.github.token';
import findUserAndTeam from '~/helpers/find.user.and.team';
import prisma from '~/prisma/client';

const list = [
'novuhq/novu',
'tooljet/tooljet',
'wasp-lang/wasp',
'teamhanko/hanko',
'CrowdDotDev/crowd.dev',
'clickvote/clickvote',
];
export default async function handler(req, res) {
const { user } = await findUserAndTeam(req, res);
if (!req?.body?.library || !list.includes(req?.body?.library) || !user) {
res.json({ finish: false });
return;
}

const exists = await prisma.forkGiven.findFirst({
where: {
userId: user.id,
library: req.body.library,
},
});

if (exists) {
res.json({ finish: false });
return;
}

const accessToken = await findGitHubToken(user.id);
const load = await (
await fetch(`https://api.github.com/repos/${req?.body?.library}/forks`, {
method: 'GET',
headers: {
Authorization: `token ${accessToken}`,
Accept: 'application/vnd.github.v3+json',
},
})
).json();

if (!load.find((p) => p.full_name.indexOf(user.handle) > -1)) {
res.json({ finish: false });
return;
}

await prisma.forkGiven.create({
data: {
userId: user.id,
library: req.body.library,
},
});

res.json({ finish: true });
}
5 changes: 3 additions & 2 deletions src/pages/bonuses.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import LayoutMain from 'layouts/layouts/layout-main';

import twitter from '~/helpers/twitter';

const Home = ({ twitter, devto, findStars }) => (
const Home = ({ twitter, devto, findStars, findForks }) => (
<LayoutMain
seo={{
isRobotsNoindexPage: true,
}}
absolute={false}
withoutFooter
>
<Hero twitter={twitter} devto={devto} findStars={findStars} />
<Hero twitter={twitter} devto={devto} findStars={findStars} findForks={findForks} />
<JoinUs />
</LayoutMain>
);
Expand All @@ -23,6 +23,7 @@ Home.propTypes = {
twitter: PropTypes.bool,
devto: PropTypes.bool,
findStars: PropTypes.array,
findForks: PropTypes.array,
};

export async function getServerSideProps(context) {
Expand Down

1 comment on commit 04120aa

@vercel
Copy link

@vercel vercel bot commented on 04120aa Oct 17, 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.