Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16,336 changes: 16,298 additions & 38 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@reduxjs/toolkit": "^1.7.1",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.24.0",
"env-cmd": "^10.1.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-loader-spinner": "^5.1.0",
"react-redux": "^7.2.6",
"react-router-dom": "^6.2.1",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.3"
},
Expand Down
42 changes: 36 additions & 6 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,40 @@
.app-container {
display: flex;
padding: 3em;
padding: 3em;}
.myNav {
display: flex;
background-color: rgba(0, 0,0, .8);
padding: 10px;
height: 60px;
align-self: stretch;
align-items: center;
flex-wrap: nowrap;
}
/* Remove bullets, margin and padding */
.myNav ul {
list-style: none;
padding: 5px;
margin: 0;
font-weight: bold;
font-size: larger;
}
.myNav li {
float: left;
/* Or you can use display: inline; */
}
/* Define the block styling for the links */
.myNav li a {
display: inline-block;
text-align: center;
padding: 10px;
color: azure;
}
.myNav li a :hover {
opacity: 1;
}
/* This is optional, however if you want to display the active link differently apply a background to it */
.myNav li a.active {
background-color: white;
}

.profile-container {
Expand All @@ -9,11 +43,7 @@

/* NAVBAR */

.navbar {
background-color: rgba(0, 0,0, .8);
padding: 10px;
height: 60px;
}


.navbar-logo-container {
padding: 5px;
Expand Down
25 changes: 14 additions & 11 deletions src/components/layouts/Navbar.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import React from "react";

import { Link } from "react-router-dom";
import logo from "../../assets/img/logo.svg";
function Navbar () {

export default class Navbar extends React.Component {

render() {

return (
<div className="navbar">
<div className="navbar-logo-container">
<img src={logo} className="navbar-logo-img" alt="logo"/>
</div>
</div>
<nav class="myNav">
<img src={logo} className="navbar-logo-img" alt="logo"/>
<ul>
<li><a href="/List.js">Organisations</a></li>
<li><a href="/RepositoriesList.js">Repositories</a></li>
</ul>
</nav>
)
}


}

}
export default Navbar;
70 changes: 34 additions & 36 deletions src/components/profile/Profile.js
Original file line number Diff line number Diff line change
@@ -1,90 +1,86 @@
import React from "react";
import React, {useEffect, useState} from "react";
import axios from "axios";

import email from "../../assets/img/email.png";
import anonymous_avatar from "../../assets/img/anonymous.png"
import anonymous_avatar from "../../assets/img/anonymous.png";
import { useSelector,useDispatch } from "react-redux";
import fetchUserProfile from "../../redux/actions/profile.actions";
function Profile (){
//const [profile, setProfile] = useState({})
const dispatch = useDispatch()
const profile = useSelector((state) => state.profile.profile);

export default class Profile extends React.Component {
constructor() {
super()
this.state = {
profile: {}
}
}

componentDidMount() {
axios.get(`https://api.github.com/user`)
.then((response) => {
this.setState({profile: response.data})
})
}
useEffect ( () => {
dispatch(fetchUserProfile())
}, [])

handleNavigateToProfile = () => {
window.location = this.state.profile.html_url
const handleNavigateToProfile = () => {
window.location = profile.html_url
}

render() {

return (
<div className="profile-content-container">
<img
src={this.state.profile.avatar_url ? this.state.profile.avatar_url : anonymous_avatar}
src={profile.avatar_url ? profile.avatar_url : anonymous_avatar}
alt="avatar"
className="profile-avatar"
/>
<h3 onClick={this.handleNavigateToProfile} className="profile-name">
{this.state.profile.name} <br/>
{ this.state.profile.login &&
<h3 onClick={handleNavigateToProfile} className="profile-name">
{profile.name} <br/>
{ profile.login &&
<span className="profile-login">
@{this.state.profile.login}
@{profile.login}
</span>
}
</h3>
<div className="profile-info">
<span>{this.state.profile.bio}</span>
<span>{profile.bio}</span>
<div className="profile-social-items">
{ this.state.profile.followers &&
{ profile.followers &&
<span className="profile-social-item">
<svg text="muted" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" className="octicon octicon-people">
<path fill-rule="evenodd" d="M5.5 3.5a2 2 0 100 4 2 2 0 000-4zM2 5.5a3.5 3.5 0 115.898 2.549 5.507 5.507 0 013.034 4.084.75.75 0 11-1.482.235 4.001 4.001 0 00-7.9 0 .75.75 0 01-1.482-.236A5.507 5.507 0 013.102 8.05 3.49 3.49 0 012 5.5zM11 4a.75.75 0 100 1.5 1.5 1.5 0 01.666 2.844.75.75 0 00-.416.672v.352a.75.75 0 00.574.73c1.2.289 2.162 1.2 2.522 2.372a.75.75 0 101.434-.44 5.01 5.01 0 00-2.56-3.012A3 3 0 0011 4z"></path>
</svg>
<span><b>{this.state.profile.followers}</b> followers</span>
<span><b>{profile.followers}</b> followers</span>
</span>
}
{ this.state.profile.following &&
{ profile.following &&
<span className="profile-social-item">
<span>.</span>
<span><b>{this.state.profile.following}</b> following</span>
<span><b>{profile.following}</b> following</span>
</span>
}

</div>
<div className="profile-info-items">

{this.state.profile.email &&
{profile.email &&
(
<span className="profile-info-item">
<img src={email} className="profile-info-icon" alt="email"/>
<span>{this.state.profile.email}</span>
<span>{profile.email}</span>
</span>
)
}
{this.state.profile.location &&
{profile.location &&
(
<span className="profile-info-item">
<svg className="octicon octicon-location" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">
<path fill-rule="evenodd" d="M11.536 3.464a5 5 0 010 7.072L8 14.07l-3.536-3.535a5 5 0 117.072-7.072v.001zm1.06 8.132a6.5 6.5 0 10-9.192 0l3.535 3.536a1.5 1.5 0 002.122 0l3.535-3.536zM8 9a2 2 0 100-4 2 2 0 000 4z"></path>
</svg>
<span>{this.state.profile.location}</span>
<span>{profile.location}</span>
</span>
)
}
{this.state.profile.company &&
{profile.company &&
(
<span className="profile-info-item">
<svg className="octicon octicon-organization" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">
<path fill-rule="evenodd" d="M1.5 14.25c0 .138.112.25.25.25H4v-1.25a.75.75 0 01.75-.75h2.5a.75.75 0 01.75.75v1.25h2.25a.25.25 0 00.25-.25V1.75a.25.25 0 00-.25-.25h-8.5a.25.25 0 00-.25.25v12.5zM1.75 16A1.75 1.75 0 010 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 00.25-.25V8.285a.25.25 0 00-.111-.208l-1.055-.703a.75.75 0 11.832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0114.25 16h-3.5a.75.75 0 01-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 01-.75-.75V14h-1v1.25a.75.75 0 01-.75.75h-3zM3 3.75A.75.75 0 013.75 3h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 3.75zM3.75 6a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM3 9.75A.75.75 0 013.75 9h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 9.75zM7.75 9a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM7 6.75A.75.75 0 017.75 6h.5a.75.75 0 010 1.5h-.5A.75.75 0 017 6.75zM7.75 3a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5z"></path>
</svg>
<span>{this.state.profile.company}</span>
<span>{profile.company}</span>
</span>
)
}
Expand All @@ -93,6 +89,8 @@ export default class Profile extends React.Component {
</div>
</div>
)
}


}

}
export default Profile;
80 changes: 31 additions & 49 deletions src/components/repositories/RepositoriesList.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,40 @@
import React from "react";
import axios from "axios";
import React, { useEffect, useState } from "react";
import SingleRepository from "./SingleRepository";
import { useSelector, useDispatch } from "react-redux";
import fetchRepos from "../../redux/actions/repos.actions";

export default class RepositoriesList extends React.Component {
constructor() {
super()
this.state = {
filters: {
page: 1,
per_page: 10,
visibility: "public"
},
repos: []
}
}
function RepositoriesList () {
const [filters, setFilters] = useState({page:1,per_page:10,visibility:"public"})
const dispatch = useDispatch()
const repos = useSelector((state) => state.repos.reposList )


componentDidMount() {
this.fetchRepos();
}
useEffect ( () => {
dispatch(fetchRepos())
}, [])

fetchRepos = () => {
this.setState({ repos: "loading" })
axios.get("https://api.github.com/user/repos", {
params: this.state.filters
})
.then((response) => {
this.setState({ repos: response.data })
})
.catch((error) => {
console.log(error)
this.setState({ repos: [] })
})
}

handleNextPage = () => {
this.setState({
filters: { ...this.state.filters, page: this.state.filters.page + 1}
const handleNextPage = () => {
setFilters({
filters: { ...filters, page: filters.page + 1}
}, () => {
this.fetchRepos();
fetchRepos();
})
}

handlePrevPage = () => {
const handlePrevPage = () => {
this.setState({
filters: { ...this.state.filters, page: this.state.filters.page - 1}
filters: { ...filters, page: filters.page - 1}
}, () => {
this.fetchRepos();
fetchRepos();
})
}

render() {

return (
<div className="repositories-container">
<h2 className="repositories-header">Popular Repositories:</h2>

{this.state.repos === "loading" ?
{repos === "loading" ?

(
<div className="repositories-list-container">
Expand All @@ -65,7 +45,7 @@ export default class RepositoriesList extends React.Component {
:

(
this.state.repos.length === 0 ?
repos.length === 0 ?
(
<div className="repositories-list-container">
<span>No repositories ...</span>
Expand All @@ -75,33 +55,35 @@ export default class RepositoriesList extends React.Component {
(
<div className="repositories-list-container">
{
this.state.repos.map((repo, index) => (
repos.map((repo, index) => (
<div className="single-repository-container" key={index}>
<SingleRepository repo={repo} />
</div>
))
}

<div className="repositoies-list-navigation-buttons-container">
<div className="repositoies-list-navigation-buttons-container">
<button
onClick={this.handlePrevPage}
onClick={handlePrevPage}
className="repositoies-list-navigation-button"
disabled={this.state.filters.page === 1}
disabled={filters.page === 1}
>
{"<"}
</button>
<button
onClick={this.handleNextPage}
onClick={handleNextPage}
className="repositoies-list-navigation-button"
>
{">"}
</button>
</div>
</div>
</div>
)
)
}
</div>
)
}
}

}

export default RepositoriesList;
Loading