Skip to content

Commit

Permalink
#3: Implement a second page, Restaurants List
Browse files Browse the repository at this point in the history
 - added lists of sample restaurants in a fake API call
 - added UI for the restaurants list page
  • Loading branch information
dartandrevinsky committed Apr 29, 2021
1 parent be904d7 commit b93eef8
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 78 deletions.
37 changes: 37 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"connected-react-router": "^6.9.1",
"history": "^4.10.1",
"react": "^17.0.2",
"react-bootstrap-table-next": "^4.0.3",
"react-dom": "^17.0.2",
"react-hook-form": "^7.2.1",
"react-icons": "^4.2.0",
Expand Down
81 changes: 41 additions & 40 deletions src/features/address/addressAPI.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,61 @@
export function fetchRestaurants(address, time, origin) {
debugger;
return new Promise((resolve, reject) =>
setTimeout(() =>
/[02468]$/.test(time) ?
resolve({ data: { address, time, origin, restaurants:
resolve({
data: {
address,
time,
origin,
restaurants: (/[0]$/.test(time) ?
[] :
[
// two entries
{
id: '',
title: '',
address: '',
category: '',
distance: '',
deliveryTime: 0
},{
id: '',
title: '',
address: '',
category: '',
distance: '',
deliveryTime: 0
},
...(/[79]$/.test(time) ? [
'id': '121721',
'name': 'Nandos Banani',
'address': 'Road-11, Banani, Dhaka',
'delivery-fee': 75.00,
avgDeliveryTime: 60
}, {
'id': '6317637',
'name': 'Le Petit Souffle',
'address': 'Third Floor, Century City Mall, Kalayaan Avenue, Poblacion, Makati City',
'delivery-fee': 75.00,
avgDeliveryTime: 60
},
...(/[68]$/.test(time) ? [
// 3 more entries
{
id: '',
title: '',
address: '',
category: '',
distance: '',
deliveryTime: 0
},{
id: '',
title: '',
address: '',
category: '',
distance: '',
deliveryTime: 0
},{
id: '',
title: '',
address: '',
category: '',
distance: '',
deliveryTime: 0
'id': '6304287',
'name': 'Izakaya Kikufuji',
'address': 'Little Tokyo, 2277 Chino Roces Avenue, Legaspi Village, Makati City',
'delivery-fee': 75.00,
avgDeliveryTime: 60
}, {
'id': '6300002',
'name': 'Heat - Edsa Shangri-La',
'address': 'Edsa Shangri-La, 1 Garden Way, Ortigas, Mandaluyong City\n',
'delivery-fee': 75.00,
avgDeliveryTime: 60
}, {
'id': '6318506',
'name': 'Ooma',
'address': 'Third Floor, Mega Fashion Hall, SM Megamall, Ortigas, Mandaluyong City',
'delivery-fee': 75.00,
avgDeliveryTime: 60
},
] : [])
]
} }) :
])
}
}) :
reject(({
message: 'Form submission error',
code: 500,
errors: {
time: 'Wrong time',
address: 'Return to sender, address unknown'
}
})), 5000)
})), 3000)
);
}
9 changes: 5 additions & 4 deletions src/features/address/addressSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const initialState = {
status: 'idle',
value: null,
error: null,
restaurantsArr: null,
restaurants: restaurantsAdapter.getInitialState()
};

Expand All @@ -39,8 +40,7 @@ export const retrieveRestaurantsForAddress = createAsyncThunk(

dispatch(keepAddressAndTime({ address, time, now }));
// TODO: convert it into correct reducer
dispatch(keepRestaurants(response?.data));
debugger;
dispatch(keepRestaurants(response?.data?.restaurants));
dispatch(navigateToPickRestaurants());
return response?.data;
}
Expand All @@ -63,7 +63,7 @@ export const addressSlice = createSlice({
state.origin = action.payload.now;
},
keepRestaurants(state, action) {
state.restaurants = action.payload;
state.restaurantsArr = action.payload;
}
},
extraReducers: (builder) => builder
Expand All @@ -72,6 +72,7 @@ export const addressSlice = createSlice({
})
.addCase(retrieveRestaurantsForAddress.fulfilled, (state, { payload }) => {
state.status = 'idle';
debugger;
restaurantsAdapter.setAll(state.restaurants, payload.restaurants);
})
.addCase(retrieveRestaurantsForAddress.rejected, (state, action) => {
Expand All @@ -86,6 +87,6 @@ export const accessAddressStatus = () => ({ [ ns ]: state }) => state.status;
export const accessDeliveryAddress = () => ({ [ ns ]: state }) => state.address;
export const accessDeliveryTime = () => ({ [ ns ]: state }) => state.time;
export const accessDeliveryTimeBlock = () => ({ [ ns ]: state }) => (state.time && state.origin) ? ({ time: state.time, origin: state.origin }) : null;
export const accessRestaurantsList = () => ({ [ ns ]: state }) => state.restaurants;
export const accessRestaurantsList = () => ({ [ ns ]: state }) => state.restaurantsArr;

export default addressSlice.reducer;
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ ReactDOM.render(rootAppNode,
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
export { LessLargeTextDiv } from './ui/elements/textElements';
export { LargeTextDiv } from './ui/elements/textElements';
5 changes: 3 additions & 2 deletions src/ui/elements/errorBoundary.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { connect } from 'react-redux';
import { Snippet } from './Snippet';
import { Container } from 'reactstrap';

export class ErrorBoundary extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -38,7 +39,7 @@ export class ErrorBoundary extends React.Component {

const errorText = String(this.state.error);

return <>
return <Container>
<h3>Something went wrong</h3>
<p>Please try to reload the page. If the problem persists please seek support <br />
using the copy-pasted information below to describe what went wrong <br /> and by clicking the <button
Expand All @@ -54,7 +55,7 @@ export class ErrorBoundary extends React.Component {
<button className="btn btn-sm btn-primary" onClick={ this.handleDismissError }>Dismiss</button>
</p>

</>;
</Container>;
}
}

Expand Down
10 changes: 10 additions & 0 deletions src/ui/elements/textElements.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@ export const Span = styled.span`
${ props => props.vaMiddle ? `vertical-align: middle;` : '' }
${ props => props.centerEditIcon ? `transform: translate(2px, -2px); display: inline-block;` : '' }
`;
export const LargeTextDiv = styled.div`
font-size: 4rem;
font-weight: 800;
color: rgba(0, 0, 0, .75);
`;
export const LessLargeTextDiv = styled.div`
font-size: ${ props => props.size || 3}rem;
font-weight: 800;
color: rgba(0, 0, 0, .8);
`;
10 changes: 5 additions & 5 deletions src/ui/pages/AppLayout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ export const AppLayout = () => {
</header>

<div className="p-2" />
<Container>
<ErrorBoundary>
<RootRoutes />
</ErrorBoundary>
</Container>

<ErrorBoundary>
<RootRoutes />
</ErrorBoundary>

</div>;
};

Expand Down
19 changes: 4 additions & 15 deletions src/ui/pages/LandingPage/index.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
import React from 'react';
import styled from 'styled-components';
import { LandingPageForm } from './landingPageForm';
import { Container } from 'reactstrap';
import { LargeTextDiv, LessLargeTextDiv } from '../../elements/textElements';


const LargeTextDiv = styled.div`
font-size: 4rem;
font-weight: 800;
color: rgba(0, 0, 0, .75);
`;

const LessLargeTextDiv = styled.div`
font-size: 3rem;
font-weight: 800;
color: rgba(0, 0, 0, .8);
`;

const LandingPage = () => {

return <div>
return <Container>
<div className="mb-5 mx-auto pt-3">
<LargeTextDiv className="text-center">FTGO Application</LargeTextDiv>
<LessLargeTextDiv className="text-center">Pick delivery address and time:</LessLargeTextDiv>
</div>
<div className="mx-auto">
<LandingPageForm />
</div>
</div>;
</Container>;
};

export default LandingPage;
Expand Down
70 changes: 58 additions & 12 deletions src/ui/pages/RestaurantListPage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { useDispatch, useSelector } from 'react-redux';
import { useCallback, useEffect } from 'react';
import { navigateToEditDeliveryAddress } from '../../../features/actions/navigation';
import { IconEdit } from '../../elements/icons';
import { Col, Row } from 'reactstrap';
import { Span } from '../../elements/textElements';
import { Col, Container, Row } from 'reactstrap';
import { LessLargeTextDiv, Span } from '../../elements/textElements';
import { RoundedButton } from '../../elements/formElements';
import BootstrapTable from 'react-bootstrap-table-next';
import 'react-bootstrap-table-next/dist/react-bootstrap-table2.min.css';

export const RestaurantListPage = () => {

Expand Down Expand Up @@ -41,18 +43,62 @@ export const RestaurantListPage = () => {
dispatch(navigateToEditDeliveryAddress());
}, [ dispatch ]);

return <div>
<Row><Col sm={ 6 }>
<label className="font-weight-bold small">Deliver To:</label>
<address>{ deliveryAddress }</address>
</Col><Col sm={ 4 }>
<label className="font-weight-bold small">Deliver At:</label>
<div>
<time dateTime={ deliveryTime }>{ deliveryTime }</time>
</div>
</Col><Col sm={ 2 } className="text-right"><RoundedButton title="Edit delivery address and time" color="secondary" outline onClick={ handleEditAddress }><Span centerEditIcon><IconEdit /></Span></RoundedButton></Col></Row>
const columns = [ {
dataField: 'id',
text: 'Ref ID',
sort: true
}, {
dataField: 'name',
text: 'Restaurant',
sort: true
}, {
dataField: 'address',
text: 'Address',
sort: true
} ];

const defaultSorted = [ {
dataField: 'name',
order: 'desc'
} ];

return <div style={ { marginTop: '-1rem' } }>
<div className="navbar-shadow navbar">
<Container>
<Col sm={ 6 }>
<label className="font-weight-bold small">Deliver To:</label>
<address style={ { marginBottom: '0' } }>{ deliveryAddress }</address>
</Col><Col sm={ 4 }>
<label className="font-weight-bold small">Deliver At:</label>
<div>
<time dateTime={ deliveryTime }>{ deliveryTime }</time>
</div>
</Col><Col sm={ 2 } className="text-right">
<RoundedButton title="Edit delivery address and time" color="secondary" outline onClick={ handleEditAddress }><Span centerEditIcon><IconEdit /></Span></RoundedButton></Col>
</Container>
</div>
<Container>
<Row>
<Col sm={ 3 }>
<LessLargeTextDiv size={ 2.5 } className="mb-2">Restaurants:</LessLargeTextDiv>
<LessLargeTextDiv size={ 1.25 }>Listing: <strong>{ String(restaurants?.length ?? 0) }</strong></LessLargeTextDiv>
</Col>
<Col sm={ 9 } className="py-2">
<BootstrapTable
bootstrap4
keyField="id"
data={ restaurants || [] }
noDataIndication={ <>No restaurants</> }
columns={ columns }
defaultSorted={ defaultSorted }
bordered={ false }
/>
</Col>
</Row>
</Container>

</div>;
};

export default RestaurantListPage;

0 comments on commit b93eef8

Please sign in to comment.