Skip to content

Commit 4d5585a

Browse files
Merge pull request #24 from GabrielDeveloper/develop
* Create component to show details of visites
2 parents c4dffb1 + b52ed75 commit 4d5585a

File tree

6 files changed

+321
-1
lines changed

6 files changed

+321
-1
lines changed

app/App.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import ListClientComponent from 'components/Client/List/Client'
1212
import ProfileClientComponent from 'components/Client/Profile/Client'
1313
import SaveClientComponent from 'components/Client/Save/Client'
1414
import CreateVisitComponent from 'components/Visit/Create/Visit'
15+
import ShowVisitComponent from 'components/Visit/Show/Visit'
1516
import CreateAreaComponent from 'components/Area/Create/Area'
1617

1718
ReactDOM.render(
@@ -25,7 +26,7 @@ ReactDOM.render(
2526
<Route path="areas" component={AreaComponent} />
2627
<Route path="area" component={CreateAreaComponent} />
2728
<Route path="visit/:clientId/" component={CreateVisitComponent} />
28-
<Route path="visit/:id" component={AreaComponent} />
29+
<Route path="visit/:id" component={ShowVisitComponent} />
2930
<Route path="lastVisits" component={LastVisitsComponent} />
3031
</Route>
3132
</Router>,

app/components/Visit/Show/Visit.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import React from 'react';
2+
import { Link } from 'react-router'
3+
4+
import VisitService from 'services/Visit'
5+
import Error from 'components/Error/Error'
6+
import styles from 'components/Visit/Show/styles.css'
7+
import DateHelper from 'helpers/DateHelper'
8+
9+
class Visit extends React.Component
10+
{
11+
constructor(props) {
12+
super(props);
13+
this.state = {
14+
visit : null,
15+
error: ''
16+
};
17+
this.getVisit(this.props.params.id);
18+
}
19+
20+
getVisit(id) {
21+
VisitService.find(id).then((response) => {
22+
this.setState({visit: response.data.visit.shift()});
23+
}).catch((error) => {
24+
this.setState({error: 'Error Found: Trying get visit'});
25+
let isValidResponse = typeof error.response.data !== 'undefined'
26+
if (typeof error.response.data.error !== 'undefined') {
27+
this.setState({error: error.response.data.error});
28+
}
29+
});
30+
}
31+
32+
render() {
33+
if (this.state.error) {
34+
return (<Error error={this.state.error} />);
35+
}
36+
if (!this.state.visit) {
37+
return <div>Loading...</div>;
38+
}
39+
40+
return (
41+
<div className="container column is-12">
42+
<div className="section profile-heading profile-heading-color profile-visit">
43+
<div className="columns">
44+
<div className="column is-4">
45+
<div className="image is-2by1">
46+
<img src="https://placehold.it/256x256" />
47+
</div>
48+
</div>
49+
<div className="column is-4 name">
50+
<h3 className="title is-3 color-black">
51+
<strong>{this.state.visit.client.name}</strong>
52+
</h3>
53+
<p className="tagline">
54+
<strong>Visit Date: </strong>{DateHelper.formateDate(this.state.visit.visit_date)}
55+
</p>
56+
<p className="tagline">
57+
<strong>Address: </strong>{this.state.visit.client.address}
58+
</p>
59+
<p className="tagline">
60+
<strong>Area: </strong>{this.state.visit.client.area._id}
61+
</p>
62+
</div>
63+
<div className="column is-2 followers has-text-centered">
64+
<p className="stat-val"><strong>R$ {this.state.visit.value_received}</strong></p>
65+
<p className="stat-key">Value Received</p>
66+
</div>
67+
<div className="column is-2 likes has-text-centered">
68+
<p className="stat-val"><strong>{this.state.visit.sales_quantity}</strong></p>
69+
<p className="stat-key">Sales Quantity</p>
70+
</div>
71+
</div>
72+
</div>
73+
</div>
74+
);
75+
}
76+
}
77+
78+
export default Visit;
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
body {
2+
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
3+
}
4+
.container.profile {
5+
margin-top:50px;
6+
}
7+
.section.profile-visit {
8+
padding-bottom: 50px!important;
9+
}
10+
.section.profile-visit .stat-key{
11+
font-weight: normal!important;
12+
font-size: 14px!important;
13+
}
14+
.section.profile-visit .tagline {
15+
padding: 20px 0;
16+
line-height: 0.1;
17+
font-size: 14px!important;
18+
}
19+
20+
.profile-heading .followers, .profile-heading .following {
21+
border-right: 1px solid #f1f1f1;
22+
margin: -30px 0;
23+
padding: 70px 30px;
24+
}
25+
.profile-heading .likes {
26+
margin: -30px 0;
27+
padding: 70px 30px;
28+
border-right:none!important;
29+
}
30+
.profile-heading .name {
31+
border-right: 1px solid #f1f1f1;
32+
margin:-30px 0;
33+
padding: 40px 30px 0 30px;
34+
}
35+
.profile-heading .followers, .profile-heading .following {
36+
border-right: 1px solid #f1f1f1;
37+
margin:-30px 0;
38+
padding: 70px 30px;
39+
}
40+
.profile-heading .likes {
41+
margin:-30px 0;
42+
padding: 70px 30px;
43+
}
44+
.profile-heading .stat-key {
45+
font-size: 20px;
46+
font-weight: 200;
47+
}
48+
.profile-heading .stat-val {
49+
font-size: 35px;
50+
font-weight: bold;
51+
}
52+
.profile-options {
53+
background-color: #f1f1f1;
54+
margin:-20px 0 20px 0;
55+
}
56+
.profile-options .link a {
57+
padding:18px;
58+
font-size: 18px;
59+
}
60+
.profile-options .link .icon {
61+
font-size: 16px;
62+
padding-top:2px;
63+
}
64+
.tagline {
65+
padding:20px 0;
66+
font-size: 16px;
67+
line-height: 1.4;
68+
}
69+
.avatar {
70+
float: right;
71+
}
72+
.follow {
73+
float: right;
74+
}
75+
.avatar img {
76+
border-radius: 200px;
77+
}
78+
p.title.is-bold {
79+
font-weight: bold;
80+
}
81+
.card .timestamp {
82+
float:right;
83+
color:#bbb;
84+
}
85+
.profile-heading-color {
86+
color: #333;
87+
}
88+
.color-black {
89+
color: black !important;
90+
}

app/helpers/DateHelper.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const DateHelper = {
2+
formateDate(date) {
3+
let dateObj = new Date(date);
4+
let options = {
5+
day: '2-digit',
6+
month: '2-digit',
7+
year: 'numeric'
8+
}
9+
return dateObj.toLocaleDateString("en-US", options);
10+
}
11+
}
12+
13+
export default DateHelper;

app/services/Visit.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ const Visit = {
2222

2323
save(data) {
2424
return axios.post(this.getEntryPoint().join('/'), data, this.getConfig());
25+
},
26+
27+
find(id) {
28+
let url = this.getEntryPoint();
29+
url.push(id);
30+
31+
return axios.get(url.join('/'), this.getConfig());
2532
}
2633
};
2734

tests/Show.Visit.test.js

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
jest.enableAutomock();
2+
jest.dontMock('components/Visit/Show/Visit');
3+
jest.dontMock('components/Error/Error');
4+
jest.dontMock('react');
5+
jest.dontMock('react-router');
6+
jest.dontMock('axios');
7+
jest.dontMock('axios-mock-adapter');
8+
jest.dontMock('enzyme');
9+
jest.dontMock('services/Visit');
10+
jest.dontMock('helpers/DateHelper');
11+
12+
describe('Test Visit', () => {
13+
require('../tests/__mocks__/LocalStorageMock');
14+
15+
const React = require('react');
16+
const Enzyme = require('enzyme');
17+
const shallow = Enzyme.shallow;
18+
const mount = Enzyme.mount;
19+
20+
let axios = require('axios');
21+
let MockAdapter = require('axios-mock-adapter');
22+
23+
it('Visit should show mocked data', (done) => {
24+
25+
let id = '123abc';
26+
let response = {
27+
visit: [{
28+
visit_date: "2017-10-01",
29+
value_received: 300,
30+
sales_quantity: 150,
31+
client: {
32+
id: id,
33+
name: 'Jon Snow',
34+
address: '7 Street',
35+
city: 'Winterfell',
36+
ability: 200,
37+
frequency: 10,
38+
area: {
39+
_id: 'Center',
40+
parents: 'Center'
41+
}
42+
},
43+
}]
44+
};
45+
let Visit;
46+
let component;
47+
let mockAdapter = new MockAdapter(axios);
48+
49+
mockAdapter.onGet(HOST + '/api/v1/visit/' + id).reply(200, response);
50+
51+
Visit = require('components/Visit/Show/Visit').default;
52+
53+
component = mount(
54+
<Visit params={ { id: id} }/>
55+
);
56+
57+
setTimeout(() => {
58+
59+
try {
60+
expect(component.find('.name p').at(0).text()).toEqual('Visit Date: 10/01/2017');
61+
expect(component.find('.name p').at(1).text()).toEqual('Address: 7 Street');
62+
expect(component.find('.name p').at(2).text()).toEqual('Area: Center');
63+
expect(component.find('.followers p').at(0).text()).toEqual('R$ 300');
64+
expect(component.find('.followers p').at(1).text()).toEqual('Value Received');
65+
expect(component.find('.likes p').at(0).text()).toEqual('150');
66+
expect(component.find('.likes p').at(1).text()).toEqual('Sales Quantity');
67+
done();
68+
} catch(e) {
69+
console.log(e);
70+
}
71+
}, 0);
72+
});
73+
74+
it('Visit should show error message', (done) => {
75+
76+
let id = '123abc';
77+
let response = { error:"Visit Not Found" };
78+
let Visit;
79+
let component;
80+
let mockAdapter = new MockAdapter(axios);
81+
82+
mockAdapter.onGet(HOST + '/api/v1/visit/' + id).reply(404, response);
83+
84+
Visit = require('components/Visit/Show/Visit').default;
85+
86+
component = shallow(
87+
<Visit params={ { id: id} }/>
88+
);
89+
90+
setTimeout(() => {
91+
92+
try {
93+
component.update();
94+
expect(component.render().text()).toEqual('Visit Not Found');
95+
done();
96+
} catch(e) {
97+
console.log(e);
98+
}
99+
}, 0);
100+
});
101+
102+
it('Visit should show default error message', (done) => {
103+
104+
let id = '123abc';
105+
let response = {};
106+
let Visit;
107+
let component;
108+
let mockAdapter = new MockAdapter(axios);
109+
110+
mockAdapter.onGet(HOST + '/api/v1/visit/' + id).reply(503, response);
111+
112+
Visit = require('components/Visit/Show/Visit').default;
113+
114+
component = shallow(
115+
<Visit params={ { id: id} }/>
116+
);
117+
118+
setTimeout(() => {
119+
try {
120+
component.update();
121+
expect(component.render().text()).toEqual('Error Found: Trying get visit');
122+
done();
123+
} catch(e) {
124+
console.log(e);
125+
}
126+
}, 0);
127+
});
128+
129+
});
130+
131+

0 commit comments

Comments
 (0)