portfolio/src/components/subcomponents/GithubRepos.jsx

210 lines
5.8 KiB
JavaScript

import React from 'react';
import { connect } from 'react-redux';
import { getRepos, getUser, getRepoLanguages, nextPage, setSortValue } from '../../actions';
import { ToggleButton, Button } from './Buttons';
class GithubRepos extends React.Component {
perPage = 5;
sortOptions = [
// text: displayed text, value: value used for sorting
{text: "Created Date", value: "created_at"},
{text: "Last Pushed", value: "pushed_at"},
{text: "Name", value: "name"},
{text: "Number of Forks", value: "forks"},
{text: "Size", value: "size"},
{text: "Last Updated", value: "updated_at"},
];
componentDidMount() {
document.title = "Github Repos";
if (!this.props.repos) {
this.props.getUser(this.props.username); // Receive the repos at start
this.props.getRepos(this.props.username); // Receive the repos at start
}
}
renderLanguages(name) {
this.props.getRepoLanguages(this.props.username, name);
// Given that we've already received the repo's languages
if (this.props.repoLanguages && this.props.repoLanguages[name]) {
// Create a bubble for each language
return Object.keys(this.props.repoLanguages[name]).map(language=>{
return <div className="language" key={language}>{language}</div>; // Language bubble JSX
});
}
}
roundUp(num) {
return num%1 === 0? num : num-(num%1)+1
}
objArrayBubbleSort(arr, value) {
/**
* arrayBubbleSort
*/
let unsorted;
let tmp;
do {
unsorted = false;
for (let i = 0; i < arr.length-1; i++) {
if (
(value.asc && arr[i][value.value] > arr[i+1][value.value]) // Ascending
|| (!value.asc && arr[i][value.value] < arr[i+1][value.value]) // Descending
) {
tmp = arr[i+1];
arr[i+1] = arr[i];
arr[i] = tmp;
unsorted = true;
}
}
} while (unsorted);
return arr;
}
renderRepos() {
if (this.props.repos) { // If the repos have been received
if (this.props.repos.length > 0) {
// Render each repo
let repos = this.props.single ? [this.props.repos[0]] : this.props.repos
let pages = this.roundUp(repos.length/this.perPage);
let sortedRepos = this.objArrayBubbleSort([...repos], this.props.sortedValue);
const render = sortedRepos.slice(0, this.props.page*this.perPage).map((repo) =>{
let updated = (new Date (repo.updated_at)).toLocaleString();
let created = (new Date (repo.created_at)).toLocaleString();
return (
<div className="repo" key={repo.id}>
<a href={repo.html_url} target="_blank" rel="noreferrer" className="title">{repo.name}</a>
<div className="content">
<p className="description">{repo.description ? repo.description : "No Description"}</p>
{
repo.homepage ? // If the repo has a homepage, render a button
<a href={repo.homepage} target="_blank" rel="noreferrer" className="website"> Project Website </a>:
""
}
</div>
<div className="languages">
Languages:
{
this.renderLanguages(repo.name) // Render each language for the repo
}
</div>
<div className="time">
Last Updated: {updated}
</div>
<div className="time">
Created: {created}
</div>
</div>
);
});
return (
<div className="repo-list">
<div className="sort-menu">
<div className="select-menu">
<p>Sort By:&ensp;</p>
<select className="dropdown-list" onChange={v=>{
this.props.setSortValue({
...this.props.sortedValue,
value: v.target.value
});
}}>
{
this.sortOptions.map(option=>{
return (
<option
value={option.value}
key={option.value}
selected={option.value === this.props.sortedValue.value}
>
{option.text}
</option>);
})
}
</select>
</div>
&ensp;
<ToggleButton defVal={false} clickAction={(val)=>{
console.warn(val);
this.props.setSortValue({
...this.props.sortedValue,
asc: val
});
}} />
</div>
{render}
{this.props.page < pages ?
<Button className="mar-la mar-ra" onClick={()=>this.props.nextPage()}>Load More ({this.props.page}/{pages})</Button>
: ""
}
</div>
); // display the repo list with the rendered repos
} else {
return <div className="loading">User doesn't have any repositories</div>
}
}
// Return nothing if repos haven't been received
return <div className="loading"> Loading Repositories... </div>; // Return nothing if repos haven't been collected
}
render = () => {
return (<div>{this.renderRepos()}</div>);
}
}
const mapStateToProps = (state) => {
return {
repos: state.github.repos,
repoLanguages: state.github.repoLanguages,
page: state.github.page,
sortedValue: state.github.sortedValue
};
}
export default connect(mapStateToProps, {
getRepos,
getRepoLanguages,
getUser,
nextPage,
setSortValue
})(GithubRepos);