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
18 changes: 18 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"env": {
"node": true,
"browser": true,
"es6": true
},
"parser": "babel-eslint",
"extends": "airbnb",
"rules": {
"react/prefer-stateless-function": "off",
"import/extensions": "off",
"jsx-a11y/anchor-is-valid": ["error", {
"components": ["Link"],
"specialLink": ["to"]
}],
"jsx-a11y/label-has-for": "off",
}
}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/node_modules
/dist
/.vscode
/npm-debug.log
36 changes: 10 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,15 @@
# Frontend Challenge
# Uso del front
El proyecto se encuentra utilizando _React_ y _Redux_, junto con _axios_ para realizar los request al backend.

This is our challenge for Frontend Developers at @get_crowder
## Requerimientos
* Nodejs 8
* npm | yarn

#### About the challenge
## Correr en desarrollo
Se esta utilizando una variable de entrono que define en donde se encuentra la ruta del backend.
El env es __BACKEND_URL__

We'll give you some requirements that must be done and for which you'll be evaluated, but you're free to choose a solution method.
Para correr el proyecto:

#### What we expect to learn from you with this challenge:
> yarn install && yarn run start

* Your work style.
* How you think and solve problems.
* How you communicate.

#### Next steps

* Fork this repository to your personal account.
* Follow the instructions in the challenge-description file.
* Solve the challenge in the best way you can.
* Send us a PR with your solution.

#### How to face the challenge

* You can use any resource you like, we do too.
* There are no rules in terms of libraries you can add to the project, but keep in mind we will evaluate coherence
* Think, then code. We will evaluate not only the code, but how you faced the problem and the solution you came up with.
* Write code that is clean and easy to read. Code that "just works" doesn't work for us.

#### Doubts?

Do you have in doubt related to the process? Open an issue and we'll be happy to help.
File renamed without changes.
31 changes: 31 additions & 0 deletions challengeDescription/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Frontend Challenge

This is our challenge for Frontend Developers at @get_crowder

#### About the challenge

We'll give you some requirements that must be done and for which you'll be evaluated, but you're free to choose a solution method.

#### What we expect to learn from you with this challenge:

* Your work style.
* How you think and solve problems.
* How you communicate.

#### Next steps

* Fork this repository to your personal account.
* Follow the instructions in the challenge-description file.
* Solve the challenge in the best way you can.
* Send us a PR with your solution.

#### How to face the challenge

* You can use any resource you like, we do too.
* There are no rules in terms of libraries you can add to the project, but keep in mind we will evaluate coherence
* Think, then code. We will evaluate not only the code, but how you faced the problem and the solution you came up with.
* Write code that is clean and easy to read. Code that "just works" doesn't work for us.

#### Doubts?

Do you have in doubt related to the process? Open an issue and we'll be happy to help.
File renamed without changes.
50 changes: 50 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "frontend-challenge",
"version": "1.0.0",
"description": "This is our challenge for Frontend Developers at @get_crowder",
"main": "index.js",
"scripts": {
"start": "npm run build",
"build": "webpack --env BACKEND_URL=http://api-challenge.getcrowder.com -d && webpack-dev-server --content-base src/ --inline --hot",
"build:prod": "webpack -p && cp src/index.html dist/index.html && mkdir -p dist/static && cp -R src/static/* dist/static",
"lint": "eslint src/app/*"
},
"repository": {
"type": "git",
"url": "git+https://github.com/juanmottesi/frontend-challenge.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/juanmottesi/frontend-challenge/issues"
},
"homepage": "https://github.com/juanmottesi/frontend-challenge#readme",
"dependencies": {
"axios": "^0.18.0",
"prop-types": "^15.6.1",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-infinite-scroll-component": "^4.1.0",
"react-redux": "^5.0.7",
"react-router": "^4.0.0",
"react-router-dom": "^4.0.0",
"redux": "^4.0.0",
"redux-logger": "^3.0.6",
"redux-promise-middleware": "^5.1.1"
},
"devDependencies": {
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.4",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"eslint": "^4.19.1",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-import": "^2.11.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.7.0",
"webpack": "^4.8.1",
"webpack-cli": "^2.1.3",
"webpack-dev-server": "^3.1.4"
}
}
Binary file added src/.DS_Store
Binary file not shown.
16 changes: 16 additions & 0 deletions src/app/actions/eventActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import BackendService from '../services/backendService';

export default {
lookingEvents(page) {
return {
type: 'LOOKING_EVENTS',
payload: BackendService.getEvents(16, page * 16),
};
},
getEvent(eventId) {
return {
type: 'GET_EVENT',
payload: BackendService.getEvent(eventId),
};
},
};
64 changes: 64 additions & 0 deletions src/app/actions/orderActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import BackendService from '../services/backendService.js';

export default {
changeName(name) {
return {
type: 'CHANGE_NAME',
payload: name,
};
},
changeEmail(email) {
return {
type: 'CHANGE_EMAIL',
payload: email,
};
},
changePhone(phone) {
return {
type: 'CHANGE_PHONE',
payload: phone,
};
},
changeAddress(address) {
return {
type: 'CHANGE_ADDRESS',
payload: address,
};
},
changeCardholder(cardholder) {
return {
type: 'CHANGE_CARDHOLDER',
payload: cardholder,
};
},
changeCardNumber(cardNumber) {
return {
type: 'CHANGE_CARD_NUMBER',
payload: cardNumber,
};
},
changeCardExpiration(cardExpiration) {
return {
type: 'CHANGE_CARD_EXPIRATION',
payload: cardExpiration,
};
},
changeCVV(cvv) {
return {
type: 'CHANGE_CVV',
payload: cvv,
};
},
cleanUp() {
return {
type: 'CLEAN_UP',
payload: null,
};
},
executePay(information) {
return {
type: 'EXECUTE_PAY',
payload: BackendService.executePay(information),
};
},
};
46 changes: 46 additions & 0 deletions src/app/actions/purchaseActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import BackendService from '../services/backendService';

export default {
getSectors(dateId) {
return {
type: 'GET_SECTORS',
payload: BackendService.getSectors(dateId),
};
},
getRates(eventId) {
return {
type: 'GET_RATES',
payload: BackendService.getRates(eventId),
};
},
setDate(date) {
return {
type: 'SET_DATE',
payload: date,
};
},
setSector(sector) {
return {
type: 'SET_SECTOR',
payload: sector,
};
},
setRate(rate) {
return {
type: 'SET_RATE',
payload: rate,
};
},
setQuantity(quantity) {
return {
type: 'SET_QUANTITY',
payload: quantity,
};
},
clearPurchase() {
return {
type: 'CLEAR_PURCHASE',
payload: null,
};
},
};
60 changes: 60 additions & 0 deletions src/app/components/ErrorPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';
import PropTypes from 'prop-types';

import { Link } from 'react-router-dom';

const styles = { color: '#f60' };

const ErrorPage = props => (
<div className="jumbotron text-center">
<h3><strong style={styles}>Error on your order</strong></h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Donec et imperdiet turpis. Quisque at arcu at mi porta dictum.
Duis venenatis mollis erat sed vehicula.
</p>
<p>
<Link
className="btn btn-primary btn-lg"
to={{
pathname: '/order',
state: {
event: props.location.state.event,
date: props.location.state.date,
rate: props.location.state.rate,
sector: props.location.state.sector,
quantity: props.location.state.quantity,
},
}}
role="button"
>Try Again
</Link>
</p>
</div>
);

ErrorPage.propTypes = {
location: PropTypes.objectOf({
state: PropTypes.objectOf({
date: PropTypes.objectOf({
date: PropTypes.string,
}).isRequired,
event: PropTypes.objectOf({
name: PropTypes.string,
thubm: PropTypes.string,
venue: PropTypes.objectOf({
name: PropTypes.string,
address: PropTypes.string,
}).isRequired,
}).isRequired,
rate: PropTypes.objectOf({
id: PropTypes.string,
max: PropTypes.number,
name: PropTypes.string,
}).isRequired,
sector: PropTypes.objectOf({ name: PropTypes.string }).isRequired,
}),
}).isRequired,
};

export default ErrorPage;
26 changes: 26 additions & 0 deletions src/app/components/EventDescription.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';

const EventDescription = props => (
<div className="row">
<div className="col-sm-7">
<h4><strong>Event Description</strong></h4>
<p>
{ props.event.description }
</p>
</div>
<div className="col-sm-offset-1 col-sm-4">
<h4><strong>Where</strong></h4>
{ props.event.venue.address }
</div>
</div>
);

EventDescription.propTypes = {
event: PropTypes.objectOf({
description: PropTypes.string,
venue: PropTypes.objectOf({ address: PropTypes.string }),
}).isRequired,
};

export default EventDescription;
22 changes: 22 additions & 0 deletions src/app/components/EventImage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import PropTypes from 'prop-types';

import { Link } from 'react-router-dom';

const EventImage = props => (
<div className="col-sm-3 event-list">
<Link to={`/event/${props.event.id}`}>
<img src={props.event.thumb} alt={props.event.name} width="100%" />
</Link>
</div>
);

EventImage.propTypes = {
event: PropTypes.objectOf({
id: PropTypes.number,
name: PropTypes.string,
thumb: PropTypes.string,
}).isRequired,
};

export default EventImage;
Loading