From 9fe43828e2b5e5213fbd5bc0ad23a56d6def8a66 Mon Sep 17 00:00:00 2001
From: Nisha <nishachaube1@gmail.com>
Date: Fri, 9 Oct 2020 14:02:49 -0400
Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=93=96=20DOC:=20Update=20Readme?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/README.md b/README.md
index ef2666f..a78aaef 100644
--- a/README.md
+++ b/README.md
@@ -66,13 +66,10 @@ sudo apt-get install libpq-dev python-dev
 sudo apt-get install postgresql postgresql-contrib
 ```
 
-### Install Postgresql **_Windows_**
 
-[Tutorial PostgreSQL windows](https://www.postgresqltutorial.com/install-postgresql/)
 
 ### Setup Database and User in PostgreSQL
 
-Based on these settings in [settings.py](/src/project/project/settings.py)
 
 ```python
 DATABASES = {

From 734f02dfccfcec275459aa624fbdb3526f469155 Mon Sep 17 00:00:00 2001
From: Nisha <nishachaube1@gmail.com>
Date: Fri, 9 Oct 2020 14:06:37 -0400
Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=96=20DOC:=20Environment=20Install?=
 =?UTF-8?q?ation=20instructions?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 41 ++++++++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/README.md b/README.md
index a78aaef..1171d69 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,31 @@
-# react-django-graphQL-postgres
+# Coding Challenge
 GraphQL API in Django
-- Nisha Chaube
+  - Nisha Chaube
 
+Method 1:
 ## Setting up using Docker
-Note: Below step may take some time
+Note: Below steps may take some time
 
-docker-compose up 
+    docker-compose up -d
 
-docker ps
+    docker ps
 
-<!-- Login to react-django-graphql-postgres_core image -->
+    <!-- Login to react-django-graphql-postgres_core image -->
 
-docker exec -it ####### /bin/bash
+    docker exec -it ####### /bin/bash
 
-python manage.py makemigrations
+    python manage.py makemigrations
 
-python manage.py migrate
+    python manage.py migrate
 
-python manage.py loaddata ./Fixtures/initial_data.json
-
-Django server url: http://127.0.0.1:8000/graphql/
-React frontend url: http://localhost:3000/
+    python manage.py loaddata ./Fixtures/initial_data.json
 
+    Django server url: http://127.0.0.1:8000/graphql/  <br />
+    React frontend url: http://localhost:3000/
+    
+    
+######################################################################
+Method 2:
 ## Setting up Python environment
 
 To get this project up and running you should start by having Python installed on your computer. It's advised you create a virtual environment to store your projects dependencies separately. You can install virtualenv with <br />
@@ -87,3 +91,14 @@ DATABASES = {
 ```SQL
 grant all privileges on database postgres to postgres
 ```
+
+## Setting up Python environment
+<br />
+
+```
+cd ui
+
+npm install
+
+npm start
+```

From 89813ff384470dac22557856f5e243b254ad7da3 Mon Sep 17 00:00:00 2001
From: Nisha <nisha@Nishas-MacBook-Pro.local>
Date: Sun, 11 Oct 2020 14:06:24 -0400
Subject: [PATCH 3/3] Refractor the ui and backend code

---
 ui/package.json                    |   6 +
 ui/src/App.js                      |   2 +-
 ui/src/client.js                   |  39 +++++
 ui/src/component/AccordionGroup.js | 138 +++++++++++++++
 ui/src/component/City.js           |  74 +++++++++
 ui/src/component/Loading.js        |   8 +
 ui/src/component/Modal.js          | 258 +++++++++++++----------------
 ui/src/component/WorldlMap.js      |   2 +-
 ui/src/container/MapPage.js        | 258 +++++------------------------
 ui/src/container/Query.js          |  43 +++++
 ui/src/index.js                    |  12 +-
 worldapi/schema.py                 |  12 +-
 12 files changed, 476 insertions(+), 376 deletions(-)
 create mode 100644 ui/src/client.js
 create mode 100644 ui/src/component/AccordionGroup.js
 create mode 100644 ui/src/component/City.js
 create mode 100644 ui/src/component/Loading.js
 create mode 100644 ui/src/container/Query.js

diff --git a/ui/package.json b/ui/package.json
index fab7672..218d831 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -4,9 +4,15 @@
   "private": true,
   "dependencies": {
     "@apollo/client": "^3.2.2",
+    "@apollo/react-hooks": "^4.0.0",
     "@testing-library/jest-dom": "^4.2.4",
     "@testing-library/react": "^9.5.0",
     "@testing-library/user-event": "^7.2.1",
+    "apollo": "^2.31.0",
+    "apollo-cache-inmemory": "^1.6.6",
+    "apollo-client": "^2.6.10",
+    "apollo-link-context": "^1.0.20",
+    "apollo-link-http": "^1.5.17",
     "bootstrap": "^4.5.2",
     "collections": "^5.1.12",
     "graphql": "^15.3.0",
diff --git a/ui/src/App.js b/ui/src/App.js
index f78f4be..ae6dfca 100644
--- a/ui/src/App.js
+++ b/ui/src/App.js
@@ -11,7 +11,7 @@ function App() {
       <Route
         render={({ location }) => {
           return (
-            <Container fluid="md">
+            <Container>
               <TransitionGroup component={null}>
                 <CSSTransition
                   timeout={300}
diff --git a/ui/src/client.js b/ui/src/client.js
new file mode 100644
index 0000000..ce46fcf
--- /dev/null
+++ b/ui/src/client.js
@@ -0,0 +1,39 @@
+
+import { ApolloClient } from 'apollo-client'
+import { InMemoryCache } from 'apollo-cache-inmemory'
+import { HttpLink } from 'apollo-link-http'
+import { setContext } from 'apollo-link-context'
+import { ApolloLink } from 'apollo-link'
+const http = new HttpLink({ uri: "http://127.0.0.1:8000/graphql/" });
+const delay = setContext(
+  request => 
+    new Promise((success, fail) => {
+      setTimeout(() => {
+        success()
+      }, 800)
+    })
+)
+const link = ApolloLink.from([
+  delay,
+  http
+])
+const cache = new InMemoryCache()
+const client = new ApolloClient({
+    link,
+    cache,
+    onError: ({ graphQLErrors, networkError }) => {
+      if (graphQLErrors) {
+        graphQLErrors.map(({ message, locations, path }) =>
+            console.log(
+                `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`),
+            console.log('This is a graphQL error!'),
+        );
+      }
+      if (networkError) {
+        console.log('This is a Network Error!', networkError);
+        console.log('Can be called from a query error in the browser code!');
+      }
+    }
+})
+
+export default client;
\ No newline at end of file
diff --git a/ui/src/component/AccordionGroup.js b/ui/src/component/AccordionGroup.js
new file mode 100644
index 0000000..c3936e0
--- /dev/null
+++ b/ui/src/component/AccordionGroup.js
@@ -0,0 +1,138 @@
+import React, { useState, useEffect } from 'react'
+import Map from 'collections/map'
+import ListGroup from 'react-bootstrap/ListGroup'
+import Accordion from 'react-bootstrap/Accordion'
+import Card from 'react-bootstrap/Card'
+import { GET_REGIONS } from '../container/Query'
+import { useQuery } from '@apollo/react-hooks'
+import City from './City'
+import Loading from '../component/Loading'
+
+const AccordionGroup = ({ selectedContinent }) => {
+    const [selectedRegion, setSelectedRegion] = useState(null)
+    const [selectedCountry, setSelectedCountry] = useState(null)
+    const [selectedCountryCode, setSelectedCountryCode] = useState(null)
+    const [countryData, setCountryData] = useState([])
+
+    useEffect(() => {
+        setSelectedCountry(null)
+        setSelectedCountryCode(null)
+        setCountryData([])
+        setSelectedRegion(null)
+        console.log('value changed selectedContinent!')
+
+    }, [selectedContinent]);
+
+    const { loading, error, data } = useQuery(GET_REGIONS, {
+        variables: {
+            "countryContinent": `${selectedContinent}`
+        }
+    });
+
+    if (loading) return <Loading/>
+    if (error) return <p> An error occured </p>
+
+
+    /* ************************************************************ */
+    /* Get countries on selected region 
+    /* ************************************************************ */
+    const handleRegionClick = (selectedRegion) => {
+        let countryData = data.getAllRegions.filter(item => {
+            return item.countryRegion === selectedRegion;
+        });
+        setSelectedRegion(selectedRegion)
+        setCountryData(countryData)
+        setSelectedCountryCode(null)
+        setSelectedCountry(null)
+    }
+
+    /* ************************************************************ */
+    /* Get cities on selected country based on the country code
+    /* ************************************************************ */
+    const handleCountryClick = (item) => {
+        let countryCode = item.countryCode,
+            countryName = item.countryName
+
+        setSelectedCountry(countryName)
+        setSelectedCountryCode(countryCode)
+    }
+
+    const getRegionList = (data) => {
+        const result = [];
+        const map = new Map();
+
+        for (const item of data) {
+            if (!map.has(item.countryRegion)) {
+                map.set(item.countryRegion, true);    // set any value to Map
+                result.push({ countryRegion: item.countryRegion });
+            }
+        }
+        return result
+    }
+
+    const getClassname = (item, currentSelection) => {
+        if (item === currentSelection) return 'selected';
+        return 'unselected';
+    }
+
+    let regions = getRegionList(data.getAllRegions)
+    return (
+        <Accordion style={{ width: "100%" }}>
+
+            {/* Panel to show regions */}
+            <Card>
+                <Accordion.Toggle as={Card.Header} eventKey="0">
+                    Regions in Continent <b>{selectedContinent}</b> <span className="card-align">(Count:{regions.length})</span>
+                </Accordion.Toggle>
+                <Accordion.Collapse eventKey="0">
+                    <Card.Body>
+                        <ListGroup>
+                            {regions.map((item, key) => {
+                                return <ListGroup.Item key={key} className={getClassname(item.countryRegion, selectedRegion)} onClick={() => handleRegionClick(item.countryRegion)}>
+                                    {item.countryRegion}
+                                </ListGroup.Item>
+                            })
+                            }
+                        </ListGroup>
+                    </Card.Body>
+                </Accordion.Collapse>
+            </Card>
+
+            {/* Panel to show countries */}
+            {/* <Button type="primary">Get more info</Button> */}
+            <Card>
+                <Accordion.Toggle as={Card.Header} eventKey="1">
+                    Countries filtered by selected region  <b>{selectedRegion}</b> <span className="card-align">(Count:{countryData.length})</span>
+                </Accordion.Toggle>
+                <Accordion.Collapse eventKey="1">
+                    <Card.Body>
+                        <ListGroup>
+                            {countryData.map((item, key) => {
+                                return <ListGroup.Item className={getClassname(item.countryName, selectedCountry)} key={key} onClick={() => handleCountryClick(item)}>
+                                    {item.countryName}
+                                </ListGroup.Item>
+                            })
+                            }
+                        </ListGroup>
+                    </Card.Body>
+                </Accordion.Collapse>
+            </Card>
+
+            {/* Panel to show cities */}
+            <Card>
+                <Accordion.Toggle as={Card.Header} eventKey="2">
+                        Cities filtered by selected country <b>{selectedCountry}</b>
+                </Accordion.Toggle>
+                <Accordion.Collapse eventKey="2">
+                    <Card.Body>
+                        {
+                            selectedCountryCode && <City countryCode={selectedCountryCode} />
+                        }
+                    </Card.Body>
+                </Accordion.Collapse>
+            </Card>
+        </Accordion>
+    );
+}
+
+export default AccordionGroup;
diff --git a/ui/src/component/City.js b/ui/src/component/City.js
new file mode 100644
index 0000000..8ec4404
--- /dev/null
+++ b/ui/src/component/City.js
@@ -0,0 +1,74 @@
+import React, { useState } from 'react'
+import { FaRegTrashAlt } from 'react-icons/fa'
+import { AiFillEdit } from 'react-icons/ai'
+import ListGroup from 'react-bootstrap/ListGroup'
+import { useQuery, NetworkStatus } from "@apollo/client"
+import { useMutation } from '@apollo/client'
+import { GET_CITIES, DELETE_CITY } from '../container/Query'
+import UpdateModal from './Modal'
+import Loading from './Loading'
+
+function City({ countryCode }) {
+  const [ show, setShow ] = useState(false)
+  const [ row, setRow ] = useState("")
+
+  const [ deleteCity,{ loading: delMutationLoading, error: delMutationError } ] = useMutation(DELETE_CITY)
+
+  const { loading, error, data, refetch, networkStatus } = useQuery(GET_CITIES, {
+      variables: {countryCode},
+      fetchPolicy: "no-cache",
+      notifyOnNetworkStatusChange: true
+    },
+  );
+
+  if (networkStatus === NetworkStatus.refetch) return 'Refetching!' && <Loading/>;
+  if (loading) return null;
+  if (error) return `Error! ${error}`;
+
+
+  const toggleOpen = (item) => {
+    setShow(true)
+    setRow(item)
+  }
+
+  const closeModal = () => {
+    refetch()
+    setShow(false)
+  }
+
+  const handleDelete = (item) => {
+      deleteCity({
+        variables: { 
+            "cityId": `${item.cityId}`,
+            refetchQueries: [{query: GET_CITIES}]
+          }
+      });
+      console.log("Deleted")
+      refetch()
+
+  }
+
+  const getClassname = (item, currentSelection) => {
+    if (item === currentSelection) return 'selected';
+    return 'unselected';
+  } 
+
+  return (<>
+    <UpdateModal show={show} row={row} handleCloseModal={() => setShow(false)} handleClose={closeModal}></UpdateModal>
+    {delMutationLoading && <p>Loading after delete...</p>}
+    {delMutationError && <p>Error :( Please try again</p>}
+    { 
+      data && data.getAllCities && data.getAllCities.map((item, key) =>
+        <ListGroup.Item key={key} className={getClassname(item.cityName, row.cityName)}>
+          {item.cityName}
+          <span className="card-align">
+            <AiFillEdit onClick={() => toggleOpen(item)} />  |  <FaRegTrashAlt onClick={() => {handleDelete(item)}} />
+          </span>
+  
+        </ListGroup.Item>)
+    }
+  </>
+  )
+}
+
+export default City;
diff --git a/ui/src/component/Loading.js b/ui/src/component/Loading.js
new file mode 100644
index 0000000..a1c094b
--- /dev/null
+++ b/ui/src/component/Loading.js
@@ -0,0 +1,8 @@
+import React from 'react';
+import {Spinner} from 'react-bootstrap'
+
+export default function Loading() {
+    return <Spinner animation="border" role="status">
+            <span className="sr-only">Loading...</span>
+        </Spinner>
+}
\ No newline at end of file
diff --git a/ui/src/component/Modal.js b/ui/src/component/Modal.js
index 83c92c7..d148c77 100644
--- a/ui/src/component/Modal.js
+++ b/ui/src/component/Modal.js
@@ -1,172 +1,146 @@
-import React, { useState } from 'react';
+import React, { useState } from 'react'
 import Modal from 'react-bootstrap/Modal'
 import Button from 'react-bootstrap/Button'
-import InputGroup from 'react-bootstrap/InputGroup'
 import Form from 'react-bootstrap/Form'
 import FormControl from 'react-bootstrap/FormControl'
 import Col from 'react-bootstrap/Col'
-import { gql,useMutation  } from '@apollo/client';
-import { client } from '../index';
+import { useMutation } from '@apollo/client'
+import { ADD_CITY, GET_CITIES } from '../container/Query'
 
+const UpdateModal = ({ show, row, handleClose, handleCloseModal }) => {
+  const [ validated, setValidated ] = useState(false);
+  const [ addCity ] = useMutation(ADD_CITY);
+  const [ state, setState]  = useState({
+    id: null,
+    name: null,
+    code: null,
+    district: null,
+    population: null
+  });
 
-const UpdateModal=({show, handleClose, item}) =>{
-    const [state, setState] = useState({
-        id: item[0],
-        name: item[1],
-        code: item[2],
-        district: item[3],
-        population: item[4]
-      });
-    const [validated, setValidated] = useState(false);
+  const handleSubmit = (event) => {
+    const form = event.currentTarget;
 
-    
-    const SET_MUTATION = gql `
-    mutation{
-        addCity(cityId:${state.id},cityName:"${state.name}",cityCountrycode:"${state.code}",cityDistrict:"${state.district}",cityPopulation:${state.population}) {
-            city{
-             cityId,
-             cityName,
-             cityCountrycode,
-             cityDistrict,
-             cityPopulation
-             }
-           }
-        }`;
-      const DELETE_MUTATION = gql`
-      mutation{
-        deleteCity(cityId:${item[0]}) {
-            city{
-            cityId
+    if (form.checkValidity() === false) {
+      event.preventDefault();
+      event.stopPropagation();
+    }
+    else {
+      setValidated(true);
+      addCity({
+        variables: { 
+            "cityId": `${state.id}`,
+            "cityName": `${state.name}`,
+            "cityCountrycode": `${state.code}`,
+            "cityDistrict": `${state.district}`,
+            "cityPopulation": `${state.population}`,
+            refetchQueries: [{query: GET_CITIES}]
           }
-      }
-      }`;
-    const [ addCity ] = useMutation(SET_MUTATION);
-    const [ deleteCity, { loading, error } ] = useMutation(DELETE_MUTATION);
-
-    if (loading) return <p>Loading</p>;;
-    if (error) return <p>An error occurred</p>;
-
-    const handleSubmit = (event) => {
-      const form = event.currentTarget;
-
-      if (form.checkValidity() === false) {
-        event.preventDefault();
-        event.stopPropagation();
-      } else {
-        setValidated(true);
-        addCity();
-        handleClose();
-      }  
-    };
-  
-
-     const handleDelete = (event) => {  
-        deleteCity()
-        handleClose()
-     }
+      });
+      handleClose();
+    }
+  };
 
-    return (
-      <>
-        <Modal show={show} onHide={handleClose}>
-          <Modal.Header closeButton>
-            <Modal.Title>Admin Panel</Modal.Title>
-          </Modal.Header>
-          <Modal.Body>Woohoo, you can now edit the city records!</Modal.Body>
-          <Form noValidate validated={validated} onSubmit={handleSubmit}>
-            <Form.Group as={Col} md="4" >
-              <Form.Label>Id</Form.Label>
-                <FormControl
-                placeholder={item[0]}
-                required
-                aria-label="Id"
-                aria-describedby="Id"
-                //defaultValue={item[0]}
-                onChange={e =>{
-                    let inputValue = e.target.value;
-                    (setState({
-                        ...state,
-                        id: inputValue
-                    }
-                ))}}
-                />
-            </Form.Group>
+  return (
+    <>
+      <Modal show={show} onHide={handleCloseModal}>
+        <Modal.Header closeButton>
+          <Modal.Title>Admin Panel</Modal.Title>
+        </Modal.Header>
+        <Modal.Body>Woohoo, you can now edit the city records!</Modal.Body>
+        <Form noValidate validated={validated} onSubmit={handleSubmit}>
+          <Form.Group as={Col} md="4" >
+            <Form.Label>Id</Form.Label>
+            <FormControl
+              placeholder={row && row.cityId && "id"}
+              required
+              aria-label="Id"
+              aria-describedby="Id"
+              onChange={e => {
+                let inputValue = e.target.value;
+                (setState({
+                  ...state,
+                  id: inputValue
+                }
+                ))
+              }}/>
+          </Form.Group>
 
-            <Form.Group as={Col} md="4" >
-              <Form.Label>Name</Form.Label>
-              <FormControl
-               required
-              placeholder={item[1]}
+          <Form.Group as={Col} md="4" >
+            <Form.Label>Name</Form.Label>
+            <FormControl
+              required
+              placeholder={row && row.cityName}
               aria-label="name"
               aria-describedby="name"
-             // defaultValue={item[1]}
-              onChange={e => 
-                { let inputValue = e.target.value;
-                  setState({
-                      ...state,
-                      name: inputValue
-              })}}
-              />
-              </Form.Group>
+              onChange={e => {
+                let inputValue = e.target.value;
+                setState({
+                  ...state,
+                  name: inputValue
+                })
+              }}
+            />
+          </Form.Group>
 
-            <Form.Group as={Col} md="4" >
+          <Form.Group as={Col} md="4" >
             <Form.Label>Code</Form.Label>
-             <FormControl
-             required
-            placeholder={item[2]}
-            aria-label="code"
-            aria-describedby="code"
-            //value={item[2]}
-            onChange={e => 
-                { let inputValue = e.target.value;
+            <FormControl
+              required
+              placeholder={row && row.cityCountrycode}
+              aria-label="code"
+              aria-describedby="code"
+              onChange={e => {
+                let inputValue = e.target.value;
                 setState({
-                    ...state,
-                    code:inputValue 
-             })}}
+                  ...state,
+                  code: inputValue
+                })
+              }}
             />
-            </Form.Group>
+          </Form.Group>
 
-            <Form.Group as={Col} md="4" >
+          <Form.Group as={Col} md="4" >
             <Form.Label>District</Form.Label>
             <FormControl
-            required
-            placeholder={item[3]}
-            aria-label="district"
-            aria-describedby="district"
-            //value={item[3]}
-            onChange={e => {
+              required
+              placeholder={row && row.cityDistrict}
+              aria-label="district"
+              aria-describedby="district"
+              onChange={e => {
                 let inputValue = e.target.value;
                 setState({
-                    ...state,
-                    district:  inputValue
-             })}}
+                  ...state,
+                  district: inputValue
+                })
+              }}
             />
-             </Form.Group>
+          </Form.Group>
 
-             <Form.Group as={Col} md="4" >
+          <Form.Group as={Col} md="4" >
             <Form.Label>Population</Form.Label>
             <FormControl
-            required
-            placeholder={item[4]}
-            aria-label="population"
-            aria-describedby="population"
-            //value={item[4]}
-            onChange={e => 
-                { let inputValue = e.target.value;
+              required
+              placeholder={row && row.cityPopulation}
+              aria-label="population"
+              aria-describedby="population"
+              onChange={e => {
+                let inputValue = e.target.value;
                 setState({
-                    ...state,
-                    population: inputValue
-             })}} 
-            />  
-            </Form.Group>
+                  ...state,
+                  population: inputValue
+                })
+              }}
+            />
+          </Form.Group>
 
           <Modal.Footer>
-          <Button type="submit">Update</Button>
-          <Button variant="secondary" onClick={handleDelete}> Delete </Button>
+            <Button type="submit">Update City</Button>
           </Modal.Footer>
-          </Form>
-        </Modal>
-      </>
-    );
-  }
-  
-  export default UpdateModal;
+        </Form>
+      </Modal>
+    </>
+  );
+}
+
+export default UpdateModal;
diff --git a/ui/src/component/WorldlMap.js b/ui/src/component/WorldlMap.js
index ce1d56c..996c676 100644
--- a/ui/src/component/WorldlMap.js
+++ b/ui/src/component/WorldlMap.js
@@ -25,7 +25,7 @@ export default class WorldMap extends React.Component {
 
     return <div className={className}>
       <ReactTooltip id="registerTip" place="top" effect="solid" getContent={(dataTip) => `Continent: ${dataTip}`} />
-      <svg className="map-img" xmlns="http://www.w3.org/2000/svg" width="400" height="600" viewBox="0 0 600 400" id="svg5249">
+      <svg className="map-img" xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 600 400" id="svg5249">
         <defs id="defs5257">
           <linearGradient id="linearGradient4299">
             <stop offset="0" id="stop4301" stopColor="#cc5252" />
diff --git a/ui/src/container/MapPage.js b/ui/src/container/MapPage.js
index c9d0d25..d7a292f 100644
--- a/ui/src/container/MapPage.js
+++ b/ui/src/container/MapPage.js
@@ -2,27 +2,12 @@ import React, { useState } from 'react';
 import styled, { keyframes } from "styled-components";
 import WorldMap from '../component/WorldlMap';
 import Footer from '../component/Footer';
-import ListGroup from 'react-bootstrap/ListGroup'
-import Accordion from 'react-bootstrap/Accordion'
-import Card from 'react-bootstrap/Card'
-import { client } from '../index';
-import { gql } from '@apollo/client';
-import { FaRegTrashAlt } from 'react-icons/fa';
-import { AiFillEdit } from 'react-icons/ai';
-import UpdateModal from '../component/Modal'
+import AccordionGroup from '../component/AccordionGroup'
 import Row from 'react-bootstrap/Row'
 import Col from 'react-bootstrap/Col'
-import Map from 'collections/map';
-import Button from 'react-bootstrap/esm/Button';
 
 
 const Page = styled.div`
-  width: 100%;
-  height: 100%;
-  position: absolute;
-  top: 0;
-  left: 0;
-  color: black;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
   font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
@@ -63,6 +48,17 @@ const MapPageElm = styled(Page)`
     animation: ${slideOutRight} 0.2s forwards;
   }
 
+  .accordion {
+    padding-top: 2rem;
+    padding-bottom: 2rem;
+  }
+  .card-align {
+    float: right;
+    font-size: 0.8rem;
+  }
+
+
+
   .map-selected {
     fill: #E3DA37;
   }
@@ -75,6 +71,10 @@ const MapPageElm = styled(Page)`
     cursor: pointer;
   }
 
+  .map-img {
+    width: 100%
+  }
+
   .map-unselected:hover{
     fill: blanchedalmond;
   }
@@ -101,29 +101,34 @@ const MapPageElm = styled(Page)`
   }
 
   .mapPage-footer {
-    position: fixed;
     color: lightslategray;
+    position: fixed;
     bottom: 0;
     font-size: 0.8rem;
     width: 100%;
     text-align: center;
   }
 
+  @media only screen and (max-width: 640px)
+  {
+    .mapPage-footer  {
+        display: none !important;
+    }
+  }
   .card-header {
     cursor: pointer;
   }
 
-  .card-align {
-    float: right;
-    font-size: 0.8rem;
-  }
-
   .card-body {
     overflow: scroll;
     max-height: 500px;
     cursor: pointer;
   }
 
+  .selected {
+    background-color: #E3DA37;
+  }
+
   .list-group-item:hover {
     background-color: lightyellow;
    }
@@ -140,221 +145,38 @@ function MapPage() {
     'AF': 'Africa',
     'EU': 'Europe'
   }
-
-  const [state, setState] = useState({
-    selectedContinentCode: null,
-    selectedRegion: null,
-    selectedCountry: null,
-    selectedCity: null,
-    regionsList: [],
-    countriesMap: new Map(),
-    citiesMap: new Map(),
-    item: '',
-    show: false
-  })
-
-  const toggleClose = item => setState({
-    ...state,
-    selectedCity: null,
-    selectedCountry: null,
-    citiesMap: new Map(),
-    item: '',
-    show: false
-  })
-
-  const toggleShow = item => {
-    setState({
-      ...state,
-      item: item,
-      show: true
-    })
-  }
+  const [selectedContinentCode, setSelectedContinentCode] = useState(null)
 
   /* ************************************************************ */
   /* Get countries on map click 
   /* ************************************************************ */
   const handleMapClick = continentCode => {
-    const GET_REGIONS = gql`
-          query {
-            getAllCountries(countryContinent:"${worldMap[continentCode]}"){
-            countryRegion,
-            countryCode
-          }
-        }`;
-    client.query({ query: GET_REGIONS }).then(result => {
-      const uniqueRegionList = [...new Set(result.data.getAllCountries.map(item => item.countryRegion))];
-      setState({
-        ...state,
-        selectedContinentCode: continentCode,
-        selectedCountry: null,
-        selectedCity: null,
-        selectedRegion: null,
-        countriesMap: new Map(),
-        citiesMap: new Map(),
-        regionsList: uniqueRegionList,
-      })
-    });
-  }
-  
-  /* ************************************************************ */
-  /* Get regions on selected country  
-  /* ************************************************************ */
-  function handleRegionClick(e) {
-    let countryMap = new Map(),
-        selectedRegion = e.target.textContent
-    const GET_COUNTRIES = gql`
-        query {
-            getAllRegions(countryRegion:"${e.target.textContent}"){
-              countryName, 
-              countryCode
-            }
-          }`;
-    client.query({
-      query: GET_COUNTRIES
-    }).then(result => {
-      result.data.getAllRegions.forEach(item => {
-        if (!countryMap.has(item.countryCode))
-          return countryMap.set(item.countryCode, item.countryName)
-      });
-    setState({
-        ...state,
-        selectedRegion: selectedRegion,
-        selectedCountry: '',
-        countriesMap: countryMap,
-        citiesMap: new Map(),
-        selectedCity: ''
-      })
-    });
-  }
-
-  /* ************************************************************ */
-  /* Get cities on selected country based on the country code
-  /* ************************************************************ */
-  function handleCountryClick(e) {
-    let countryCode = e.target.id,
-        selectedCountry = e.target.textContent,
-        cityMap = new Map()
-    const GET_CITIES = gql`
-            query{
-                getAllCities(cityCountrycode:"${countryCode}"){
-                    cityId,
-                    cityName,
-                    cityCountrycode,
-                    cityDistrict,
-                    cityPopulation
-                }
-          }`;
-    client.query({ query: GET_CITIES }).then(result => {
-      result.data.getAllCities.forEach(item => {
-        if (!cityMap.has(item.cityId))
-          cityMap.set(item.cityId, [item.cityId, item.cityName, item.cityCountrycode, item.cityDistrict, item.cityPopulation])
-      });
-    setState({
-        ...state,
-        selectedCountry: selectedCountry,
-        citiesMap: cityMap,
-      })
-    });
-
-    // To get country data
-    // const GET_COUNTRYDATA = gql`
-    //       query{
-    //         countrylanguage(countrylanguageCountrycode:"${countryCode}"){
-    //           countrylanguageIsofficial,
-    //           countrylanguageLanguage,
-    //           countrylanguagePercentage
-    //         }
-    //       }`;
-
-    // client.query({
-    //   query: GET_COUNTRYDATA
-    // }).then(result => {
-    //   result.data.countrylanguage.forEach(item => {
-    //     //console.log("item", item)
-    //   });
-    // });
+    console.log("**************handleMapClick continentCode", continentCode)
+    setSelectedContinentCode(continentCode)
   }
 
   return (
     <MapPageElm>
-      <Row >
-        <Col className="mapPage-center" md={12}>Click the map to populate the information under the accordions</Col>
+      <Row className="justify-content-md-center">
+        <Col className="mapPage-center" md={12}  sm={12}>Click the map to populate the information under the accordions</Col>
       </Row>
       <Row>
-        <Col md={5}>
-          <WorldMap className='mapPage-map' selectedContinent={state.selectedContinentCode} onClickMap={handleMapClick} />
+        <Col md={6} sm={12}>
+          <WorldMap className='mapPage-map' selectedContinent={selectedContinentCode} onClickMap={handleMapClick} />
         </Col>
-        <Col md={5}>
+        <Col md={6}  sm={12}>
           <Row>
-            <UpdateModal show={state.show} item={state.item} handleClose={toggleClose}></UpdateModal>
-            <Accordion style={{ width: "100%" }}>
-              {/* Panel to show regions */}
-              <Card>
-                <Accordion.Toggle as={Card.Header} eventKey="0">
-                  Regions in Continent <b>{worldMap[state.selectedContinentCode]}</b> <span className="card-align">(Count:{state.regionsList.length})</span>
-                </Accordion.Toggle>
-                <Accordion.Collapse eventKey="0">
-                  <Card.Body>
-                    <ListGroup>
-                      {
-                        state.regionsList.map(((item, val) =>
-                          <ListGroup.Item id={val} onClick={handleRegionClick}>
-                            {item}
-                          </ListGroup.Item>
-                        ))
-                      }
-                    </ListGroup>
-                  </Card.Body>
-                </Accordion.Collapse>
-              </Card>
-
-              {/* Panel to show countries */}
-              {/* <Button type="primary">Get more info</Button> */}
-              <Card>
-                <Accordion.Toggle as={Card.Header} eventKey="1">
-                  Countries filtered by selected region <b>{state.selectedRegion}</b> <span className="card-align">(Count:{state.countriesMap.size})</span>
-                </Accordion.Toggle>
-                <Accordion.Collapse eventKey="1">
-                  <Card.Body>
-                    Make a selection 
-                    {
-                      state.countriesMap.map(((item, val) =>
-                        <ListGroup.Item id={val} onClick={handleCountryClick}>
-                          {item}
-                        </ListGroup.Item>
-                      ))
-                    }
-                  </Card.Body>
-                </Accordion.Collapse>
-              </Card>
-
-              {/* Panel to show cities */}
-              <Card>
-                <Accordion.Toggle as={Card.Header} eventKey="2">
-                  Cities filtered by selected country <b>{state.selectedCountry}</b> <span className="card-align">(Count:{state.citiesMap.size})</span>
-                </Accordion.Toggle>
-                <Accordion.Collapse eventKey="2">
-                  <Card.Body>
-                    Make a selection again
-                    {state.citiesMap.map(((item, val) => <ListGroup.Item id={val} onClick={() => toggleShow(item)} >
-                    {item[1]}   <span className="card-align">
-                      <AiFillEdit onClick={toggleShow} />  |  <FaRegTrashAlt onClick={toggleShow} />
-                    </span>
-                  </ListGroup.Item>
-                  ))
-                    }
-                  </Card.Body>
-                </Accordion.Collapse>
-              </Card>
-            </Accordion>
-
+            <AccordionGroup selectedContinent={worldMap[selectedContinentCode]} />
           </Row>
         </Col>
       </Row>
       <Row>
+      <Col log={8} md={8}  sm={8}>
         <Footer className='mapPage-footer' text={"The gladdest moment in human life, methinks, is a departure into unknown lands. – Sir Richard Burton"} />
+      </Col>
       </Row>
     </MapPageElm>
   );
 }
-export default MapPage;
\ No newline at end of file
+
+export default MapPage;
diff --git a/ui/src/container/Query.js b/ui/src/container/Query.js
new file mode 100644
index 0000000..3f59dfe
--- /dev/null
+++ b/ui/src/container/Query.js
@@ -0,0 +1,43 @@
+import gql from 'graphql-tag'
+
+export const GET_REGIONS = gql`
+        query getAllRegions($countryContinent: String!) {
+            getAllRegions(countryContinent:$countryContinent){
+                countryRegion,
+                countryCode,
+                countryName
+            }
+        }`;
+
+export const GET_CITIES = gql`
+        query getAllCities($countryCode: String!) {
+            getAllCities(cityCountrycode: $countryCode){
+                cityId,
+                cityName,
+                cityCountrycode,
+                cityDistrict,
+                cityPopulation
+            }
+        }`;
+
+export const ADD_CITY = gql`
+        mutation updateCity($cityId: Int!, $cityName: String!, $cityCountrycode:  String!, $cityDistrict: String!, $cityPopulation: Int!) {
+            addCity(cityId: $cityId, cityName: $cityName, cityCountrycode: $cityCountrycode, cityDistrict: $cityDistrict, cityPopulation: $cityPopulation) {
+                city {
+                    cityId,
+                    cityName,
+                    cityCountrycode,
+                    cityDistrict,
+                    cityPopulation
+                }
+            }
+        }`;
+
+export const DELETE_CITY = gql`
+        mutation deleteCity($cityId: Int!){
+            deleteCity(cityId: $cityId) {
+                city {
+                    cityId
+                }
+            }
+        }`;
\ No newline at end of file
diff --git a/ui/src/index.js b/ui/src/index.js
index 5031592..e348764 100644
--- a/ui/src/index.js
+++ b/ui/src/index.js
@@ -2,19 +2,15 @@ import React from 'react';
 import ReactDOM from 'react-dom';
 import './index.css';
 import App from './App';
+import client from './client'
 import * as serviceWorker from './serviceWorker';
-import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
+import { ApolloProvider } from '@apollo/client';
 import 'bootstrap/dist/css/bootstrap.min.css';
 
-export const client = new ApolloClient({
-  uri: 'http://127.0.0.1:8000/graphql/',
-  cache: new InMemoryCache()
-});
-
 ReactDOM.render(
-  <ApolloProvider client={client}>
+    <ApolloProvider client={client}>
       <App />
-  </ApolloProvider>,
+    </ApolloProvider>,
   document.getElementById('root')
 );
 
diff --git a/worldapi/schema.py b/worldapi/schema.py
index 73c55f8..e380a42 100644
--- a/worldapi/schema.py
+++ b/worldapi/schema.py
@@ -63,14 +63,14 @@ def resolve_getAllCities(self, info, city_countrycode, **kwargs):
         return filtered  
 
     #################################################
-    # Get all countries by countinent
+    # Get all Regions by countinent
     ################################################# 
-    getAllCountries = graphene.List(
+    getAllRegions = graphene.List(
         CountryType,
         country_continent=graphene.String()
     )
 
-    def resolve_getAllCountries(self, info, country_continent, **kwargs):
+    def resolve_getAllRegions(self, info, country_continent, **kwargs):
         all_getAllCountries = Country.objects.all()
 
         if country_continent:
@@ -80,14 +80,14 @@ def resolve_getAllCountries(self, info, country_continent, **kwargs):
         return filtered  
 
     #################################################
-    # Get all regions by country region
+    # Get all countries by country region
     ################################################# 
-    getAllRegions = graphene.List(
+    getAllCountries = graphene.List(
         CountryType,
         country_region=graphene.String()
     )
 
-    def resolve_getAllRegions(self, info, country_region, **kwargs):
+    def resolve_getAllCountries(self, info, country_region, **kwargs):
         all_getAllRegions = Country.objects.all()
 
         if country_region:
