Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Anton Horn committed Feb 13, 2019
0 parents commit b4a229b
Show file tree
Hide file tree
Showing 42 changed files with 1,571 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Numerous always-ignore extensions
*.diff
*.err
*.orig
*.log
*.rej
*.swo
*.swp
*.vi
*~
*.sass-cache
node_modules/
bower_components/
app/gen-assets/
build/
dist/
temp/
dest/

# OS or Editor folders
.DS_Store
Thumbs.db
.cache
.project
.settings
.tmproj
*.esproj
nbproject
*.sublime-project
*.sublime-workspace
*.komodoproject
.komodotools
_notes
dwsync.xml
.vscode
160 changes: 160 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
### How to build the project

```shell
# install dependencies
npm install gulp-cli -g
npm install

# build the project in the "development" mode
gulp

# build the project in the "production" mode
gulp build.production

# run the built-in server to preview the website
# or open the "./build/index.html" in your browser
gulp watch
```

### Important folders

- source folder: **./app**
- build folder: **./build**


### Model

```javascript
{
userData: {
isFetching: false,
errorMessage: null,
data: {
username: "friend",
name: "Michael Popesko",
description: "Developer"
}
},
repositories: {
isFetching: false,
errorMessage: null,
data: [
{
id: "kh123k",
name: "html5-template",
description: "html5 template",
website: "https://friend.github.com/html5-template",
languages: {
isFetching: false,
errorMessage: null,
data: [ "CSS", "Html", "Javascript" ]
}
},
{
id: "sdfr3sy",
name: "wordpress-template",
description: "wordpress template",
website: "https://friend.github.com/wordpress-template",
languages: {
isFetching: false,
errorMessage: null,
data: [ "CSS", "Javascript", "PHP" ]
}
}
]
}
}
```

### Form

```html
<section>
<header>
<h1>
Javascript Challenge “Github Resumé” 1.1
</h1>
</header>

<section>
<form>
<fieldset>

<label>
Enter your GitHub username and click "generate".
</label>

<label class="error-message"></label>

<p>
<input type="text" placeholder="Enter your GitHub username" />

<input type="submit" value="generate"/>
</p>

</fieldset>
</form>
</section>

<footer>
<p>
This app shows <b>maximum 5 repositories</b> in order to reduce
number of requests to the GitHub API. <a href="https://developer.github.com/v3/#rate-limiting" target="_blank">Here</a> you can read
more about limitations of the API.
</p>
</footer>
</section>
```

### Resume

```html
<section>
<header class="user">
<h1 class="user__name">
Michael Popesko
</h1>

<h2 class="user__description">
Developer
</h2>
</header>

<section>
<div>
<h3>Repositories</h3>
<ul>
<li class="repository">
<span class="error-message"></span>
<h4 class="repository__name">
<a href="https://friend.github.com/html5-template" target="_blank">html5-template</a>
</h4>
<h5 class="repository__description">html5 template</h5>
<div class="repository__languages">
CSS, Html, Javascript
</div>
</li>
<li class="repository">
<span class="error-message"></span>
<h4 class="repository__name">
<a href="https://friend.github.com/wordpress-template" target="_blank">wordpress-template</a>
</h4>
<h5 class="repository__description">wordpress template</h5>
<div class="repository__languages">
CSS, Javascript, PHP
</div>
</li>
</ul>
<a href="#">back</a>
</div>
</section>

<footer>
<p>
This app shows <b>maximum 5 repositories</b> in order to reduce
number of requests to the GitHub API. <a href="https://developer.github.com/v3/#rate-limiting" target="_blank">Here</a> you can read
more about limitations of the API.
</p>
</footer>
</section>
```
28 changes: 28 additions & 0 deletions app/assets/scripts/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import ReactDOM from "react-dom";

import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import thunkMiddleware from "redux-thunk";
import { createLogger } from "redux-logger";

import ReactApp from "./modules/components/ReactApp";
import rootReducer from "./modules/reducers";


let middleware = [ thunkMiddleware ];
if(process.env.NODE_ENV == "development"){
middleware.push(createLogger());
}

let store = createStore(
rootReducer,
applyMiddleware(...middleware)
);

ReactDOM.render(
<Provider store={store}>
<ReactApp />
</Provider>,
document.getElementById("react")
);
5 changes: 5 additions & 0 deletions app/assets/scripts/modules/Globals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Globals = {
githubApiUrl: "https://api.github.com"
}

export default Globals;
18 changes: 18 additions & 0 deletions app/assets/scripts/modules/actions/ActionType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const ActionType = {
FETCH_USER_DATA: "FETCH_USER_DATA",
FETCH_REPOSITORIES: "FETCH_REPOSITORIES",
FETCH_REPOSITORY_LANGUAGES: "FETCH_REPOSITORY_LANGUAGES",

RECEIVE_USER_DATA: "RECEIVE_USER_DATA",
RECEIVE_REPOSITORIES: "RECEIVE_REPOSITORIES",
RECEIVE_REPOSITORY_LANGUAGES: "RECEIVE_REPOSITORY_LANGUAGES",

FETCH_USER_DATA_FAILED: "FETCH_USER_DATA_FAILED",
FETCH_REPOSITORIES_FAILED: "FETCH_REPOSITORIES_FAILED",
FETCH_REPOSITORY_LANGUAGES_FAILED: "FETCH_REPOSITORY_LANGUAGES_FAILED",

RESET_USER_DATA: "RESET_USER_DATA",
RESET_REPOSITORIES: "RESET_REPOSITORIES"
};

export default ActionType;
3 changes: 3 additions & 0 deletions app/assets/scripts/modules/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { fetchUserData, resetUserData } from "./userData";
export { fetchRepositories, resetRepositories } from "./repositories";
export { fetchLanguages } from "./languages";
31 changes: 31 additions & 0 deletions app/assets/scripts/modules/actions/languages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Globals from "../Globals";
import ActionType from "./ActionType";
import ajaxRequest from "../ajaxRequest";

const receiveLanguages = (repositoryId, data) => ({
type: ActionType.RECEIVE_REPOSITORY_LANGUAGES,
repositoryId,
data
})

const fetchLanguagesFailed = (repositoryId, errorMessage) => ({
type: ActionType.FETCH_REPOSITORY_LANGUAGES_FAILED,
repositoryId,
errorMessage
})

export const fetchLanguages = repositoryId => {
return dispatch => {
dispatch({
type: ActionType.FETCH_REPOSITORY_LANGUAGES,
repositoryId
});

return new Promise((resolve, reject) => {
let url = `${Globals.githubApiUrl}/repositories/${repositoryId}/languages`;
ajaxRequest(url, resolve, reject);
})
.then(response => dispatch(receiveLanguages(repositoryId, response)))
.catch(errorMsg => dispatch(fetchLanguagesFailed(repositoryId, errorMsg)));
}
}
32 changes: 32 additions & 0 deletions app/assets/scripts/modules/actions/repositories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import ActionType from "./ActionType";
import Globals from "../Globals";
import ajaxRequest from "../ajaxRequest";

const receiveRepositories = data => ({
type: ActionType.RECEIVE_REPOSITORIES,
data
});

const fetchRepositoriesFailed = errorMessage => ({
type: ActionType.FETCH_REPOSITORIES_FAILED,
errorMessage
});

export const fetchRepositories = (username, maxReposCount = 5) => {
return dispatch => {
dispatch({ type: ActionType.FETCH_REPOSITORIES });

return new Promise((resolve, reject) => {
let url = `${Globals.githubApiUrl}/users/${username}/repos?per_page=${maxReposCount}&page=1`
ajaxRequest(url, resolve, reject);
})
.then(response => dispatch(receiveRepositories(
response.slice(0, maxReposCount),
maxReposCount)))
.catch(errMsg => dispatch(fetchRepositoriesFailed(errMsg)));
};
}

export const resetRepositories = () => ({
type: ActionType.RESET_REPOSITORIES
});
30 changes: 30 additions & 0 deletions app/assets/scripts/modules/actions/userData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Globals from "../Globals";
import ActionType from "./ActionType";
import ajaxRequest from "../ajaxRequest";

const receiveUserData = data => ({
type: ActionType.RECEIVE_USER_DATA,
data
});

const fetchUserDataFailed = errorMessage => ({
type: ActionType.FETCH_USER_DATA_FAILED,
errorMessage
});

export const fetchUserData = username => {
return dispatch => {
dispatch({ type: ActionType.FETCH_USER_DATA });

return new Promise((resolve, reject) => {
let url = `${Globals.githubApiUrl}/users/${username}`
ajaxRequest(url, resolve, reject);
})
.then(response => dispatch(receiveUserData(response)))
.catch(errorMsg => dispatch(fetchUserDataFailed(errorMsg)));
}
}

export const resetUserData = () => ({
type: ActionType.RESET_USER_DATA
});
35 changes: 35 additions & 0 deletions app/assets/scripts/modules/ajaxRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import $ from "jquery";

const errorMsg = {
badResponse: "Fetching data failed"
};

const defaultErrorFunc = errorMsg => {
console.warn(errorMsg);
}

const ajaxRequest = (inUrl, doneCb, errorCb = defaultErrorFunc) => {
$.ajax({
type: "GET",
url: inUrl,
dataType: "jsonp",
data: '',
success: function(response, status){
if(status !== "success"){
errorCb(errorMsg.badResponse);
return;
}

if(response.data && !response.data.message){
doneCb(response.data);
}else{
errorCb(response.data.message);
}
},
error: function(){
errorCb(errorMsg.badResponse);
}
});
}

export default ajaxRequest;
Loading

0 comments on commit b4a229b

Please sign in to comment.