Skip to content

Commit

Permalink
implements github challenges list
Browse files Browse the repository at this point in the history
  • Loading branch information
jongomez committed Nov 10, 2023
1 parent 3cc8393 commit 6d258f3
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 170 deletions.
4 changes: 4 additions & 0 deletions packages/docusaurus-playground/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ const config = {
routeBasePath: '/',
path: 'docs',
},

// Uncomment to fetch new generated data.
/*
generated: {
challenges: {
repoArray: [
Expand All @@ -57,6 +60,7 @@ const config = {
jobBoard: 'waku',
},
},
*/
}),
],
],
Expand Down
12 changes: 10 additions & 2 deletions packages/docusaurus-playground/src/pages/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
GithubChallenges,
} from '../components/mdx'
import * as jobData from '/generated/jobs.json'
import * as challengesData from '/generated/challenges.json'

<Hero size="large">
<HeroInfo>
Expand Down Expand Up @@ -355,5 +356,12 @@ import * as jobData from '/generated/jobs.json'
Build on Waku
</CallToActionButton>
</Box>
<JobsPerDepartment jobData={jobData} />
<GithubChallenges org="codex" useDummyData />
<JobsPerDepartment jobData={jobData} useDummyData />
<GithubChallenges
challengesData={challengesData}
subheaderText="Lorem ipsum dolor sit amet consectetur. Enim magna urna fames mattis
tincidunt nibh mi ornare. Sed amet morbi mauris pellentesque fusce ut.
Bibendum vestibulum Lorem ipsum dolor sit amet consectetur. Enim magna
urna fames mattis tincidunt nibh mi ornare. Sed amet morbi mauris
pellentesque fusce ut. Bibendum vestibulum"
/>
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ const fetchChallenges = async ({
}: {
out: string
} & ChallengeConfig) => {
if (!githubAccessToken) {
console.log(
'No github access token provided, creating empty challenges file',
)
await fsp.writeFile(out, '{}')
return
}

const issues = await fetchGithubIssues(repoArray, githubAccessToken)

await fsp.writeFile(out, JSON.stringify(issues))
Expand Down
1 change: 1 addition & 0 deletions packages/logos-docusaurus-preset/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export type SiteConfig = Partial<Config>
export * from './preset'
export * from './status'
export * from './themes'
export * from './github'
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
}

.mdx-ghc__participant-photo {
width: 24px;
border-radius: 100%;
margin-left: -4px;
border: 1px solid rgb(var(--lsd-border-secondary));
Expand Down Expand Up @@ -85,9 +86,3 @@
grid-template-columns: 82px 1fr;
}
}

.mdx-ghc__achievement {
display: flex;
align-items: center;
padding-left: 4px;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Typography } from '@acid-info/lsd-react'
import { SingleGithubChallenge } from './SingleGithubChallenge'
import React from 'react'
import useFetchGithubIssues, { GithubIssue } from './useFetchGithubIssues'
import { dummyGithubIssue } from './githubChallengesDummyData'
import { SingleGithubChallenge } from './SingleGithubChallenge'
import { GithubIssue } from '@acid-info/logos-docusaurus-preset/src/types/github'

type GithubChallengesHeaderProps = {
message?: string
Expand All @@ -22,50 +23,73 @@ const GithubChallengesHeader: React.FC<GithubChallengesHeaderProps> = ({
}

const hasChallenges = (githubChallenges: GithubIssue[]): boolean => {
return githubChallenges.length > 0
return Array.isArray(githubChallenges) && !!githubChallenges.length
}

const getIssuesFromRawData = (rawData: any): GithubIssue[] => {
let issues: GithubIssue[] = []

Object.keys(rawData).forEach((key) => {
if (!isNaN(Number(key))) {
// Extract the array of issues for each repository
const repoIssues = Object.values(rawData[key])[0] // each object should have only one key-value pair
if (Array.isArray(repoIssues)) {
issues = issues.concat(repoIssues)
}
}
})

return issues
}

type GithubChallengesProps = React.HTMLAttributes<HTMLDivElement> & {
org: string
challengesData: any
useDummyData?: boolean
subheaderText?: string
filterByName?: string // A string that represents a regex pattern
}

export const GithubChallenges: React.FC<GithubChallengesProps> = ({
org,
challengesData,
useDummyData,
subheaderText,
filterByName,
...props
}) => {
const [data, error, loading] = useFetchGithubIssues(org, useDummyData)
let challengesArray: GithubIssue[] | undefined | null = useDummyData
? [dummyGithubIssue]
: getIssuesFromRawData(challengesData)

if (loading) {
return <GithubChallengesHeader />
if (!challengesArray || !hasChallenges(challengesArray)) {
return <GithubChallengesHeader message="No challenges to show" />
}

if (error) {
return <GithubChallengesHeader message="Error fetching data" />
}

if (!data || !hasChallenges(data)) {
return <GithubChallengesHeader message="No challenges to show" />
if (filterByName) {
try {
const regex = new RegExp(filterByName, 'i') // 'i' for case-insensitive
challengesArray = challengesArray?.filter((issue) =>
regex.test(issue.title),
)
} catch (error) {
console.error('Invalid regex pattern:', error)
}
}

return (
<div {...props}>
<GithubChallengesHeader />
<Typography
variant="body1"
className="mdx-ghc-subheader-text"
component="div"
>
Lorem ipsum dolor sit amet consectetur. Enim magna urna fames mattis
tincidunt nibh mi ornare. Sed amet morbi mauris pellentesque fusce ut.
Bibendum vestibulum Lorem ipsum dolor sit amet consectetur. Enim magna
urna fames mattis tincidunt nibh mi ornare. Sed amet morbi mauris
pellentesque fusce ut. Bibendum vestibulum
</Typography>
{data.map((issue) => {
return <SingleGithubChallenge key={issue.id} issue={issue} />
})}
{!!subheaderText && (
<Typography
variant="body1"
className="mdx-ghc-subheader-text"
component="div"
>
{subheaderText}
</Typography>
)}
{challengesArray.map((issue) => (
<SingleGithubChallenge key={issue.id} issue={issue} />
))}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,54 @@ import React from 'react'
import { IconExternalLink } from '@logos-theme/components/Icon'
import './GithubChallenges.scss'
import Link from '@docusaurus/Link'
import { GithubIssue } from './useFetchGithubIssues'
import { GithubIssue } from '@acid-info/logos-docusaurus-preset/src/types/github'

const getProjectNames = (issue: GithubIssue): string => {
const projectNames = issue.projects.map((project) => project.name)

if (projectNames.length === 0) {
return ''
}

return Array.from(new Set(projectNames)).join(', ')
}

type Participant = {
name: string
avatarUrl: string
}

const extractUniqueParticipants = (issue: GithubIssue): Participant[] => {
const participants = new Map<string, Participant>()

// Add the user who created the issue
participants.set(issue.user.login, {
name: issue.user.login,
avatarUrl: issue.user.avatarUrl,
})

// Add all assignees
issue.assignees.forEach((assignee) => {
participants.set(assignee.login, {
name: assignee.login,
avatarUrl: assignee.avatarUrl,
})
})

// Skipping comment authors for now, because they don't have avatarUrl.
/*
// Add all comment authors
issue.comments.forEach((comment) => {
// Assuming comment.author is the login name of the commenter
participants.set(comment.author, {
name: comment.author,
avatarUrl: '', // Placeholder, as avatarUrl is not available directly in GithubComment type
})
})
*/

return Array.from(participants.values())
}

function addSizeToAvatarUrl(avatarUrl: string, size: number = 24): string {
const url = new URL(avatarUrl)
Expand All @@ -25,6 +72,39 @@ type SingleGithubChallengeProps = {
export const SingleGithubChallenge: React.FC<SingleGithubChallengeProps> = ({
issue,
}) => {
const participants = extractUniqueParticipants(issue)
const projectsConst = getProjectNames(issue)
const hasProjects = projectsConst !== ''
const hasMilestone = !!issue.milestone

const elementsToRender: React.ReactNode[] = []

if (hasProjects) {
elementsToRender.push(
<>
<Typography variant="body3" className="mdx-ghc__label">
{projectsConst.includes(', ') ? 'Projects' : 'Project'}
</Typography>
<Typography variant="body3" className="mdx-ghc__project-name">
{projectsConst}
</Typography>
</>,
)
}

if (hasMilestone) {
elementsToRender.push(
<>
<Typography variant="body3" className="mdx-ghc__label">
Milestone
</Typography>
<Typography variant="body3" className="mdx-ghc__milestone-text">
{issue.milestone}
</Typography>
</>,
)
}

return (
<div className="mdx-ghc__container">
<Link href={issue.url} className="mdx-ghc__issue-title-link">
Expand All @@ -40,7 +120,7 @@ export const SingleGithubChallenge: React.FC<SingleGithubChallengeProps> = ({
key={index}
className="mdx-ghc__challenge-label"
>
{label.name}
{label}
</Typography>
))}
</div>
Expand All @@ -60,50 +140,20 @@ export const SingleGithubChallenge: React.FC<SingleGithubChallengeProps> = ({
>
{issue.comments.length}
</Typography>
{issue.participants.map((participant, index) => (
{participants.map((participant, index) => (
<img
key={index}
className="mdx-ghc__participant-photo"
src={addSizeToAvatarUrl(participant.avatarUrl)}
alt={participant.login}
alt={participant.name}
/>
))}
</div>

{/* 1st row 3rd item */}
<Typography variant="body3" className="mdx-ghc__label">
Project
</Typography>

{/* 1st row 4th item */}
<Typography variant="body3" className="mdx-ghc__project-name">
{issue.project ? issue.project.name : ''}
</Typography>

{/* 2nd row 1st item */}
<Typography variant="body3" className="mdx-ghc__label">
Achievement
</Typography>

{/* 2nd row 2nd item */}
<div className="mdx-ghc__achievement">
<img
className="mdx-ghc__participant-photo"
src={addSizeToAvatarUrl(
'https://avatars.githubusercontent.com/u/8811422?u=b4aec0f11a78abe3b71c42e4adfba3ebd61f34aa&v=4',
)}
/>
</div>

{/* 2nd row 3rd item */}
<Typography variant="body3" className="mdx-ghc__label">
Milestone
</Typography>

{/* 2nd row 4th item */}
<Typography variant="body3" className="mdx-ghc__milestone-text">
{issue.milestone || ''}
</Typography>
{/* Render Projects and/or Milestone */}
{elementsToRender.map((element, index) => (
<React.Fragment key={index}>{element}</React.Fragment>
))}
</div>

<Link href={issue.url} className="mdx-ghc__view-on-github-link">
Expand Down
Loading

0 comments on commit 6d258f3

Please sign in to comment.