Countries

 avatar
unknown
plain_text
4 years ago
7.1 kB
4
Indexable
App.js

import React, {useEffect, useState} from 'react';
import './App.css';
import axios from 'axios';
import CountryViewer from "./CountryViewer";
import CountryForm from "./CountryForm";

const App = () => {

  const [countries, setCountries] = useState([]);
  const [query, setQuery] = useState("");
  const [sort, setSort] = useState(true);
  const [currencies, setCurrencies] = useState([]);
  const [selectedCurrency, setSelectedCurrency] = useState("");

  const getCountries = () => {
    axios.get("https://restcountries.eu/rest/v2")
        .then(response => {
          console.log(response.data);
          setCountries(response.data);
          return(response.data);
        }).then(countries => {
        const currencies = (countries.map(country => {return country.currencies}));
        return(currencies);
    }).then(currencies => {
        const currencies_names = currencies.map(country => {return country.map(c => {return c.name})}).flat();
        const unique_names = currencies_names.filter((char, index) => {return currencies_names.indexOf(char) === index})
            .filter(currency => currency !== null).filter(currency => currency.length > 3);
        console.log(unique_names);
        setCurrencies(unique_names);
    })
  }

  useEffect(
      () => {
        getCountries();
      }, []
  )

  return (
    <div className="app">
        <CountryForm changeQuery={setQuery} changeSort={setSort} currencies={currencies} changeCurrency={setSelectedCurrency}/>
        <CountryViewer countries={countries} query={query} sort={sort} selectedCurrency={selectedCurrency}> </CountryViewer>
    </div>
  );
}

export default App;

-----------------

Country.js


import React from "react";

const Country = ({name, flag}) => {
    return (
        <div className={"country"}>
            <img src={`${flag}`} alt={`${name}`}/>
            <p>{name}</p>
        </div>
    );
}

export default Country;


-----------------


CountryForm.js

import React from "react";
import {Formik, Field, Form} from 'formik';

const CountryForm = ({changeQuery, changeSort, currencies, changeCurrency}) => {

    const handleSubmit = values => {
        changeCurrency(values.currency);
        console.log(values.currency);
        changeQuery(values.query);
    }

    const handleSort = values => {
        values.sort = !values.sort;
        changeSort(values.sort);
    }

    return (
        <div className={"form"}>
          <Formik initialValues={{query: "", sort: true, currency: ""}} onSubmit={handleSubmit}>
              {(props) => (
                  <Form onSubmit={props.handleSubmit}>
                      <div className={"currency"}>
                          <label htmlFor="currency">Currency </label>
                          <Field as={"select"} name={"currency"}
                          >
                              {currencies.map(currency => (
                                  <option key={currency} value={currency} label={currency}> </option>
                                  )
                              )}
                          </Field>
                      </div>
                      <Field className="search bar" name={"query"} placeholder={"Enter country name"}/>
                      <div className={"buttons"}>
                      <button className="search button">Search</button>
                      <button className="sort button" onClick={handleSort}>Sort</button>
                      <button className="reset button" onClick={props.handleReset}>Reset</button>
                      </div>
                  </Form>
              )}
          </Formik>
        </div>
    );
}

export default CountryForm;

-----------------

CountryViewer.js

import React, {useState, useEffect} from "react";
import Country from "./Country";

const CountryViewer = ({countries, query, sort, selectedCurrency}) => {

    const [selected, setSelected] = useState([]);
    const all_shortcuts = countries.map(country => {return country.alpha3Code});
    useEffect( () => {
        if (all_shortcuts.includes(query)) {
            const selected_country = countries.filter(country => query===country.alpha3Code)[0];
            const borders_shortcuts = selected_country.borders;
            const borders_array = borders_shortcuts.map(shortcut => countries.filter(country => country.alpha3Code===shortcut))
            const borders = borders_array.map(border => {return border[0]});
            console.log(borders_shortcuts);
            console.log(borders);
            setSelected(borders);
        }
        else if (selectedCurrency!=="" && query==="") {
            const countries_with_currency = countries.filter(country => country.currencies.some(currency => currency.name === selectedCurrency));
            setSelected(countries_with_currency);
        }
        else if (query==="") {
            setSelected(countries);
        }
        else
        {
            setSelected(countries.filter(country => country.name.includes(query)));
        }
    }, [query, countries, sort, selectedCurrency])

    return (
        <div className={"countries-list"}>
            {sort? selected.map((country) => (
                <Country
                    name={country.name}
                    flag={country.flag}
                > </Country>
            )).sort():
                selected.map((country) => (
                <Country
                    name={country.name}
                    flag={country.flag}
                > </Country>
            )).reverse()}
        </div>
    );
}

export default CountryViewer;

-----------------

App.css


* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.countries-list {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    margin: 0px 50px;
}

img {
    width: 150px;
    height: 100px;
    margin-bottom: 50px;
}

.country{
    font-size: 16px;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    flex-direction: column;
    flex-grow: 1;
    width: 30%;
    height: 200px;
    border: 1px solid black;
    margin: 15px;
}

p {
    width: 100%;
}

.form {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    /*position: relative;*/
    /*padding: 30px;*/
}


.search, .sort, .reset{
    /*margin: 50px 5px;*/
    padding: 5px;
    width: 50px;
}

.search {
    width: 120px;
}

.bar {
    width: 400px;
    margin: 10px 0;
}

.currency {
    /*position: absolute;*/
    /*left: 20px;*/
    /*top: 20px;*/
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin: 10px 0;
}

.currency > * {
    padding: 5px;
}


.option {
    width: 300px;
}

.buttons {
    display: flex;
    justify-content: space-around;
    align-items: center;
}


-----------------

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);


Editor is loading...