Skip to content

Commit f1a3a6b

Browse files
Country dropdown & misc cchanges
1 parent abf76e7 commit f1a3a6b

File tree

7 files changed

+103
-4
lines changed

7 files changed

+103
-4
lines changed

frontend/src/__tests__/App.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,37 @@ describe('App', () => {
207207
expect(browser.store.getState().router.location.pathname).toBe('/');
208208
expect(browser.getByText('Jane Doe')).toBeInTheDocument();
209209
});
210+
211+
it('should filter users by country', async () => {
212+
let countrySelected = false;
213+
// mock the api
214+
server.use(
215+
rest.get('/api/users', (req, res, ctx) => {
216+
countrySelected = req.url.searchParams.get('country');
217+
if (countrySelected === 'Not USA') {
218+
return res(ctx.json({ users: [], totalPages: 1 }));
219+
}
220+
return res(ctx.json({
221+
users: [{
222+
id: 1, last_name: 'Doe', date_of_birth: '2000-01-02', country_name: 'USA', country_id: 1, first_name: 'John',
223+
}],
224+
totalPages: 1,
225+
}));
226+
}),
227+
rest.get('/api/countries', (req, res, ctx) => {
228+
return res(ctx.json([
229+
{ id: 1, name: 'USA', users_count: 1 },
230+
{ id: 2, name: 'Not USA', users_count: 0 },
231+
]));
232+
})
233+
);
234+
///////////////////////////////
235+
const browser = renderWithProvider(<App />);
236+
// wait for the / page to load
237+
await browser.findByText('John Doe');
238+
// select the country
239+
fireEvent.change(browser.getByTestId('country-filter-select'), { target: { value: 'Not USA' } });
240+
await browser.findByText('No users found');
241+
expect(countrySelected).toBe('Not USA');
242+
});
210243
});

frontend/src/__tests__/components/UsersChart.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ describe('getPieChartOption', () => {
4242
expect(selectedMap).toEqual({ Canada: true });
4343
});
4444

45+
it('should return the correct option for no selected country', () => {
46+
const countries = [
47+
{ id: 1, name: 'United States', users_count: 10 },
48+
];
49+
const { series: [{ selectedMap, selectedMode }] } = getPieChartOption(countries);
50+
expect(selectedMode).toEqual('single');
51+
expect(selectedMap).toEqual(null);
52+
});
53+
4554
// disabled because it's not working at all, due to the way echarts-for-react is implemented
4655
false && it('should call setCountry when a country is clicked', async () => {
4756
const setCountry = jest.fn();
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// CountryFilter is a component that is used in the Home view. It is a dropdown menu that allows the user to filter the data by country. The component is connected to the redux store and dispatches an action when the user selects a country. The action is handled by the reducer and updates the state of the application. This component very similar to DateFilter.
2+
import React, { Component } from 'react';
3+
import { connect } from 'react-redux';
4+
import { setCountry } from 'store/UISlice';
5+
import { countriesUpdates } from 'store/events';
6+
import uuid from 'react-uuid';
7+
8+
class CountryFilter extends Component {
9+
_emptyFilter = uuid();
10+
11+
componentDidMount() {
12+
this.props.countriesUpdates(true);
13+
}
14+
15+
componentWillUnmount() {
16+
this.props.countriesUpdates(false);
17+
}
18+
19+
onChange = e => {
20+
const value = e.target.value;
21+
this.props.setCountry((value === this._emptyFilter) ? null : value);
22+
};
23+
24+
render() {
25+
const { countries, activeCountry } = this.props;
26+
if (!countries.loaded) return null;
27+
return (
28+
<div className="row pt-3">
29+
<select
30+
className="form-control"
31+
onChange={this.onChange}
32+
value={activeCountry || this._emptyFilter}
33+
data-testid="country-filter-select"
34+
>
35+
<option value={this._emptyFilter}>All countries</option>
36+
{countries.data.map(({ id, name }) => (
37+
<option key={id} value={name}>
38+
{name}
39+
</option>
40+
))}
41+
</select>
42+
</div>
43+
);
44+
}
45+
}
46+
47+
export default connect(
48+
state => ({
49+
countries: state.countries,
50+
activeCountry: state.UI.country,
51+
}),
52+
{ setCountry, countriesUpdates }
53+
)(CountryFilter);

frontend/src/components/CustomDatePicker.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class CustomDatePicker extends Component {
2929
return (
3030
<DatePicker
3131
customInput={<CustomInput onReset={() => onChange(null)} id={id} />}
32+
showMonthDropdown
33+
showYearDropdown
3234
{...this.props}
3335
/>
3436
);

frontend/src/components/DateFilter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class DateFilter extends Component {
1313

1414
return (
1515
<div className="row date-filter">
16-
<div className="col-md-5 col-12">
16+
<div className="col-md-6 col-12 px-0">
1717
<CustomDatePicker
1818
dateFormat="dd-MM-yyyy"
1919
selected={dateFrom}
@@ -26,7 +26,7 @@ class DateFilter extends Component {
2626
/>
2727
</div>
2828

29-
<div className="col-md-5 col-12">
29+
<div className="col-md-6 col-12 px-0">
3030
<CustomDatePicker
3131
dateFormat="dd-MM-yyyy"
3232
selected={dateTo}

frontend/src/components/UsersChart.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { setCountry } from 'store/UISlice';
55
import ReactEcharts from 'echarts-for-react';
66

77
function getPieChartOption(countries, activeCountry) {
8-
const selectedMap = activeCountry ? { [activeCountry]: true } : {};
8+
const selectedMap = activeCountry ? { [activeCountry]: true } : null;
99
return {
1010
title: {
1111
text: 'Number of Users by Country',

frontend/src/views/Home.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// Home view - This view displays the main content of the application which includes the Pie Chart, Date Filter Inputs, and User Data Grid.
22
// The pie chart is built using the echarts library and shows the number of users in each country. The date filter inputs allow the user to filter the data by selecting a date range. The user data grid shows the filtered data and allows the user to interact with the data. The grid also shows a pagination if the data is large.
33
import React, { Component } from 'react';
4+
import { Outlet } from 'react-router-dom';
45
import UsersChart from 'components/UsersChart';
56
import DateFilter from 'components/DateFilter';
67
import UsersDataGrid from 'components/UsersDataGrid';
7-
import { Outlet } from 'react-router-dom';
8+
import CountryFilter from 'components/CountryFilter';
89

910
class Home extends Component {
1011
render() {
@@ -17,6 +18,7 @@ class Home extends Component {
1718
</div>
1819
<div className="col-6">
1920
<DateFilter />
21+
<CountryFilter />
2022
</div>
2123
</div>
2224
<div className="row">

0 commit comments

Comments
 (0)