feat: integrate github api to fetch contributors (#139)

* feat: integrate github api to fetch contributors

* fix: link credits page on mobile
This commit is contained in:
Olaleye Blessing 2022-04-19 11:48:59 +01:00 committed by GitHub
parent 430c6f08ad
commit acd29e95cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1888 additions and 1790 deletions

View File

@ -1,115 +1,116 @@
import React, { useState } from 'react' import React, { useState, useEffect } from 'react'
import axios from 'axios'
import ContributorsStyle from './Contributors.style' import ContributorsStyle from './Contributors.style'
import styles from '../../styles/Contributors.module.css' import styles from '../../styles/Contributors.module.css'
import Image from 'next/image' import Image from 'next/image'
import profilepic from 'assets/ContributorsImages/sampleImage.jpg' import profilepic from 'assets/ContributorsImages/sampleImage.jpg'
import { GitHub } from '@mui/icons-material' import { GitHub } from '@mui/icons-material'
import Head from "next/head"; import Head from 'next/head'
import Script from "next/script"; import Script from 'next/script'
const contributorsURL =
'https://api.github.com/repos/bravo68web/url-minify/contributors'
export default function Contributors() { export default function Contributors() {
const [contributors, setContributors] = useState([ const [contributors, setContributors] = useState({
{ loading: true,
id: 1, error: null,
profilepic, data: [],
name: 'Jacob Myers', })
gitHubUsername: '@jacob',
}, useEffect(() => {
{ const fetchContributors = async () => {
id: 2, try {
profilepic, setContributors((prev) => ({ ...prev, loading: true }))
name: 'John Doe', const { data } = await axios.get(contributorsURL)
gitHubUsername: '@john', setContributors((prev) => ({ ...prev, data }))
}, } catch (error) {
{ console.log(error)
id: 3, setContributors((prev) => ({ ...prev, error: 'There is an error' }))
profilepic, } finally {
name: 'Sara Williams', setContributors((prev) => ({ ...prev, loading: false }))
gitHubUsername: '@sara', }
}, }
{ fetchContributors()
id: 4, }, [])
profilepic,
name: 'Sara Williams', if (contributors.data) {
gitHubUsername: '@sara', // remove bots from contributors list
}, contributors.data = [...contributors.data].filter(
{ ({ type }) => type === 'User'
id: 5, )
profilepic, }
name: 'Sara Williams',
gitHubUsername: '@sara',
},
{
id: 6,
profilepic,
name: 'Sara Williams',
gitHubUsername: '@sara',
},
{
id: 7,
profilepic,
name: 'Sara Williams',
gitHubUsername: '@sara',
},
{
id: 8,
profilepic,
name: 'Sara Williams',
gitHubUsername: '@sara',
},
{
id: 9,
profilepic,
name: 'Sara Williams',
gitHubUsername: '@sara',
},
])
return ( return (
<> <>
<Head> <Head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" <link
crossOrigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossOrigin="anonymous"
/> />
</Head> </Head>
<Script <Script
id="bootstrap-cdn" id="bootstrap-cdn"
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" /> src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
/>
<ContributorsStyle>
<> <ContributorsStyle className="conttt">
<div className={styles.head}>CONTRIBUTORS</div> <>
<div class="conatiner contributor-cards"> <header>
<div className="contributor-cards row"> <h1 className={styles.head}>CONTRIBUTORS</h1>
{contributors.map((contributor) => { </header>
return ( {contributors.loading ? (
<div className="contributor-card col-3" key={contributor.id}> <p className="contributors__loading">Loading...</p>
<div className="contributor-cardPointerStart"> ) : contributors.error ? (
<div id="circle"></div> <p className="contributors__loading">{contributors.error}</p>
</div> ) : (
<div id="ImageContainer"> <ul className="contributor-cards row">
<Image {contributors.data.map((contributor) => {
src={contributor.profilepic} return (
alt="Contributors Profile Picture" <li
width={'100px'} className="contributor-card col-3 flex"
height={'100px'} key={contributor.id}
className="contributor-Pic" >
/> <span className="contributor__indicator"></span>
</div> <figure className="contributor__avatar flex">
<div id="contributorDetailsWrapper"> <Image
<div className="contributor-Name">{contributor.name}</div> src={contributor.avatar_url}
<div className="contributor-GithubUsername"> width={100}
<GitHub /> height={100}
<span id="username">{contributor.gitHubUsername}</span> alt={`${contributor.login}'s profile picture`}
</div> />
</div> </figure>
</div> <p
className="contributor__name ellipsis"
) title={contributor.login}
})} >
</div> {contributor.login}
</div> </p>
<p className="contributor__github flex">
<a
href={contributor.url}
target="_blank"
rel="noopener"
className="contributor__github--link flex"
>
<GitHub className="contributor__github--icon" />
<span
id="username"
className="contributor__github--username ellipsis"
>
@{contributor.login}
</span>
</a>
</p>
</li>
)
})}
</ul>
)}
</> </>
</ContributorsStyle> </ContributorsStyle>
</> </>
) )
} }

View File

@ -1,67 +1,124 @@
import styled from 'styled-components' import styled from 'styled-components'
export default styled.section` export default styled.section`
display: flex; padding-top: 6rem;
flex-direction: column;
justify-content: center; .contributors {
.contributor-cards{ &__loading {
display: flex; text-align: center;
width: 85%; font-size: clamp(1.5rem, 2vw, 2.5rem);
align-item: center; }
justify-content: center;
margin:20px;
margin-left: 6%
} }
.contributor-card {
width: 240px; .flex {
height: 250px;
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
justify-content: space-around; justify-content: center;
background-color: #ffffff;
border-radius: 10px;
margin: 15px;
padding: 5px;
} }
.contributor-cardPointerStart {
width: 180px; .ellipsis {
display: flex;
justify-content: flex-start;
}
#circle {
height: 10px;
width: 10px;
border-radius: 50%;
background-color: green;
}
.contributor-Pic {
width: 100px;
height: 100px;
}
#ImageContainer {
border-radius: 50%;
border: 3px solid #35cdf0;
overflow: hidden; overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
} }
.contributor-Name {
color: #1d92e0; .contributor {
font-size: 25px; &-cards {
font-weight: bold; list-style: none;
display: flex;
padding-left: 1.6rem;
padding-right: 1.6rem;
gap: 2rem 1.6rem;
max-width: 80rem;
margin: 1rem auto 2rem;
}
&-card {
margin-left: auto;
margin-right: auto;
background-color: rgb(255, 255, 255);
border-radius: 1rem;
flex: 1 1 auto;
max-width: 18rem;
width: 100%;
flex-direction: column;
text-align: center;
padding: 2.4rem 0.8rem;
position: relative;
transition: all 0.2s linear;
transform: scale(0.97);
&:hover {
transform: scale(1);
box-shadow: 1px 1px 9px rgba(0, 0, 0, 0.2);
}
&:nth-child(3n-2) {
.contributor__indicator {
left: 1rem;
}
}
&:nth-child(3n-1) {
.contributor__indicator {
left: 48.5%;
}
}
&:nth-child(3n) {
.contributor__indicator {
right: 1rem;
}
}
}
&__indicator {
position: absolute;
top: 1rem;
width: 0.6rem;
height: 0.6rem;
background: green;
border-radius: 50%;
}
&__avatar {
border-radius: 50%;
border: 3px solid rgb(53, 205, 240);
overflow: hidden;
img {
max-width: 100%;
border-radius: 50%;
}
}
&__name {
color: rgb(29, 146, 224);
font-size: clamp(1.5rem, calc(4vw + 0.5em), 2.5rem);
font-weight: bold;
}
&__github {
width: 100%;
&--link {
width: 100%;
transition: all 0.2s linear;
transform: scale(0.95);
max-width: max-content;
&:hover {
transform: scale(1);
text-shadow: 1px 1px black;
}
}
&--username {
display: inline-block;
margin-left: 0.2rem;
width: auto;
}
}
} }
#contributorDetailsWrapper {
display: flex;
flex-direction: column;
justfiy-content: flex-start;
}
.contributor-GithubUsername {
display: flex;
justify-content: baseline;
font-size: 20px;
}
#username {
color: grey;
font-weight: bold;
padding-left: 4px;
}
` `

View File

@ -116,15 +116,17 @@ function Index(props) {
</a> </a>
</MenuItem> </MenuItem>
<MenuItem onClick={handleCloseNavMenu}> <MenuItem onClick={handleCloseNavMenu}>
<a href={NotFound}> <Link href="/contributors">
<Typography <a>
textAlign="center" <Typography
variant="h6" textAlign="center"
sx={{ display: 'flex' }} variant="h6"
> sx={{ display: 'flex' }}
CREDITS >
</Typography> CREDITS
</a> </Typography>
</a>
</Link>
</MenuItem> </MenuItem>
</Menu> </Menu>
</Box> </Box>

View File

@ -1,3 +1,6 @@
module.exports = { module.exports = {
reactStrictMode: true, reactStrictMode: true,
images: {
domains: ['avatars.githubusercontent.com'],
},
} }

View File

@ -2,16 +2,21 @@
font-family: 'Montserrat Alternates', sans-serif; font-family: 'Montserrat Alternates', sans-serif;
color: #fff; color: #fff;
/* text-shadow: 3px 2px 1px black; */ /* text-shadow: 3px 2px 1px black; */
margin-top: 100px; /* margin-top: 100px; */
line-height: 1.15; line-height: 1.15;
font-size: 5.5rem; /* font-size: 5.5rem; */
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
font-size: clamp(1.8rem, calc(5vw + 1rem), 5.5rem);
padding-left: 1.6rem;
padding-right: 1.6rem;
margin-bottom: 4rem;
} }
@media (max-width: 600px) { @media (max-width: 600px) {
.head { .head {
font-size: 2.5rem; /* font-size: 2.5rem; */
margin-top: 2em; /* margin-top: 2em; */
margin-bottom: 100px; margin-bottom: 2rem;
} }
} }

File diff suppressed because it is too large Load Diff