Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test #1

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
3 changes: 2 additions & 1 deletion src/App.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.App-header{
background-color: #8ABEB1
background-color: #8ABEB1;
text-align: center;
}
.App-logo{
margin: 5px 0px 5px 10px;
Expand Down
77 changes: 44 additions & 33 deletions src/features/route-map.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,55 @@
import React, {useState, useEffect} from "react"
import { Port } from '../services/ports-reducer'
import { Loader } from "@googlemaps/js-api-loader"
import React, { useState, useEffect } from "react";
import { Port } from "../services/ports-reducer";
import { Loader } from "@googlemaps/js-api-loader";

declare global {
interface Window {
initMap: () => void;
}
interface Window {
initMap: () => void;
}
}

interface RouteMapParams{
ports: Port[]
interface RouteMapParams {
ports: Port[];
}
function RouteMap({ports}: RouteMapParams){
const [theMap, setTheMap] = useState<google.maps.Map>()
function RouteMap({ ports }: RouteMapParams) {
const [theMap, setTheMap] = useState<google.maps.Map>();

const loader = new Loader({
apiKey: "AIzaSyDckokR5ozbjFB7hC0yip1S5mbPYcgoQv8",
version: "weekly"
})
const loader = new Loader({
apiKey: "AIzaSyDckokR5ozbjFB7hC0yip1S5mbPYcgoQv8",
version: "weekly",
});

useEffect(() => {
loader
.load()
.then((google) => {
const mapOptions = {
center: {
lat: 0,
lng: 0
},
zoom: 3
}
const map = new google.maps.Map(document.getElementById("route-map") as HTMLElement, mapOptions)
setTheMap(map);
})
}, []);
return (
<div id="map-container">
<div id="route-map"></div>
useEffect(() => {
loader.load().then((google) => {
const mapOptions = {
center: {
lat: 0,
lng: 0,
},
zoom: 3,
};
const map = new google.maps.Map(
document.getElementById("route-map") as HTMLElement,
mapOptions
);
const infowindow = new google.maps.InfoWindow();
for (let i = 0; i < ports.length; i++) {
const singlePort = ports[i];
const myLatLng = { lat: singlePort["lat"], lng: singlePort["lng"] };
new google.maps.Marker({
position: myLatLng,
map,
title: singlePort["name"],
});
}
setTheMap(map);
});
}, [ports]);
return (
<div id="map-container">
<div id="route-map"></div>
</div>
)
);
}

export default RouteMap;
8 changes: 5 additions & 3 deletions src/features/voyage-planner.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.voyage-planner-container{
display: flex;
flex-direction: row;
margin: 10px;
}

.voyage-route-container{
Expand All @@ -9,21 +10,22 @@
border-left: 2px solid grey;
display: flex;
flex-direction: column;
text-align: center;
}
#port-select{
width: 90%;
}
.port-locator{

line-height: 2;
}

.voyage-listing{

line-height: 1.5;
}

.voyage-map-container{
width: 80%;
height: 100vh;
text-align: center;
}

#route-map{
Expand Down
89 changes: 66 additions & 23 deletions src/features/voyage-planner.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,73 @@
import React from 'react'
import RouteMap from "./route-map"
import "./voyage-planner.css"
import React, { useEffect, useState } from "react";
import RouteMap from "./route-map";
import "./voyage-planner.css";
import { fetchPorts, setPorts, Port } from "../services/ports-reducer";
import { addPorts } from "../services/voyage-reducer";
import { useAppDispatch, useAppSelector } from "../services/hooks";
import store, { RootState } from "../services/store";

interface VoyagePlannerParams{
interface VoyagePlannerParams {}

}
function VoyagePlanner(params: VoyagePlannerParams) {
const [selectedPort, setSelectedPort] = useState("");
const [addedPorts, setAddedPorts] = useState<Port[]>([]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added ports are in the redux store. Where are you duplicating here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also removed here. Please check the latest changes.

const [offset, setOffset] = useState(0);
const [fetchData, setFetchData] = useState([]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data is stored in the Redux store. Why are you duplicating it here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your feedback John. I removed the duplicates from here. Please check the latest changes.


const dispatch = useAppDispatch();

function VoyagePlanner(params: VoyagePlannerParams){
useEffect(() => {
fetchPorts(offset).then((resp: any) => {
setFetchData(fetchData.concat(resp));
dispatch(setPorts(fetchData));
setOffset(offset + resp.length);
setSelectedPort(store.getState().ports.ports[0].name);
});
}, [offset]);

return (
<div className="voyage-planner-container">
<div className="voyage-route-container">
<h2>Route Planner</h2>
<div className="port-locator">
<select id="port-select"/> <button>+</button>
</div>
<div className="voyage-listing">
<h2>Voyage</h2>
</div>
</div>
<div className="voyage-map-container">
<h2>Route Map</h2>
<RouteMap ports={[]}/>
</div>
const handleChange = (e: any) => {
setSelectedPort(e.target.value);
};

const addVoyage = () => {
const portTobeAdded =
store.getState().ports.ports &&
store
.getState()
.ports.ports.filter((item: Port) => item.name === selectedPort);
dispatch(addPorts(portTobeAdded[0]));
setAddedPorts(store.getState().voyage.ports);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed requirement to calculate estimated time of arrival, distance travelled.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also added the functionality for distance and estimated time of arrival here. Please check the latest code.

};
return (
<div className="voyage-planner-container">
<div className="voyage-route-container">
<h2>Route Planner</h2>
<div className="port-locator">
<select id="port-select" value={selectedPort} onChange={handleChange}>
{store.getState().ports.ports &&
store.getState().ports.ports.map((item: Port, key: number) => {
return (
<option id={key.toString()} key={key} value={item.name}>
{item.name}
</option>
);
})}
</select>
<button onClick={addVoyage}>Add</button>
</div>
<div className="voyage-listing">
<h2>Voyage</h2>
{addedPorts &&
addedPorts.map((item, key) => {
return <div key={key}>{item.name}</div>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low effort here. Remove port functionality? Re-arrange? No styling

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this part as well.

})}
</div>
)
</div>
<div className="voyage-map-container">
<h2>Route Map</h2>
<RouteMap ports={addedPorts} />
</div>
</div>
);
}
export default VoyagePlanner
export default VoyagePlanner;
18 changes: 11 additions & 7 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { Provider } from "react-redux";
import store from "../src/services/store";

const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<App />
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);

Expand Down
34 changes: 29 additions & 5 deletions src/services/ports-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface Port {
uncode: string,
name: string,
lat: number,
lon: number
lng: number
}

interface PortsState {
Expand All @@ -23,6 +23,16 @@ const initialState: PortsState = {
offset: 0,
ports: []
}
export interface SetPortAction {
type: 'SETPORTACTION'
portList: Port[]
}

export const setPorts = (portList: Port[]): SetPortAction => {
return { type: 'SETPORTACTION', portList }
}



/**
* TODO: implement the reducer function to manage the list of ports
Expand All @@ -31,9 +41,13 @@ const initialState: PortsState = {
* @param action
* @returns PortsState
*/
export function portsReducer(state = initialState, action: AnyAction): PortsState{

return state
export function portsReducer(state = initialState, action: AnyAction): PortsState {
switch (action.type) {
case 'SETPORTACTION':
return { ...state, ports: action.portList }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are doing a paginated fetch - the ports should be appended, not replaced

Copy link
Author

@shruthidasarapu shruthidasarapu Jun 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I solved the issue here. Please check the latest changes which I made and let me know any further improvements

default:
return { ...state }
}
}

/**
Expand All @@ -42,7 +56,17 @@ export function portsReducer(state = initialState, action: AnyAction): PortsStat
* so you may need multiple calls to fetch all the data
* @param offset: where to start pulling from
*/
export function fetchPorts(offset: number){}
export async function fetchPorts(offset: number) {
return new Promise((resolve) => {
fetch(
`https://8u9tblsay0.execute-api.us-east-1.amazonaws.com/default/zn-frontend-challenge-port-service?offset=${offset}`
)
.then((response) => response.json())
.then((json) => {
resolve(json.data);
});
});
}



3 changes: 2 additions & 1 deletion src/services/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ const store = configureStore({
})

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
export type AppDispatch = typeof store.dispatch
export default store;
19 changes: 17 additions & 2 deletions src/services/voyage-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,27 @@ const initialState: VoyageState = {
ports: []
}

export interface AddPortAction {
type: 'ADDPORTACTION'
port: Port
}

export const addPorts = (port: Port): AddPortAction => {
return { type: 'ADDPORTACTION', port }
}


export function voyageReducer(state = initialState, action: AnyAction){

return state
switch (action.type) {
case 'ADDPORTACTION':
const currentPorts = state.ports;
return { ...state, ports: [...currentPorts,action.port] }
default:
return {...state}
}
}


export function addPort(port: Port){}
export function removePort(port: Port){}
export function movePort(port: Port, newPosition: number){}
Expand Down