From 91b29ce2456172d83c63916f824b89fd02ffdcfa Mon Sep 17 00:00:00 2001 From: Lian Hershkovits Date: Tue, 24 Dec 2024 12:33:34 +0200 Subject: [PATCH 1/4] finished Header&ThemeToggle component --- index.html | 12 +++++++++++- src/components/Country.jsx | 3 +-- src/components/Filter.jsx | 8 ++++++++ src/components/Header.jsx | 17 +++++++++++++++++ src/components/ThemeToggle.jsx | 23 +++++++++++++++++++++++ src/pages/Home.jsx | 9 ++++++--- 6 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 src/components/Filter.jsx create mode 100644 src/components/Header.jsx create mode 100644 src/components/ThemeToggle.jsx diff --git a/index.html b/index.html index 0c589ec..e0b01ee 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,17 @@ - Vite + React + + + + + + + + + + + Countries Info
diff --git a/src/components/Country.jsx b/src/components/Country.jsx index 177580c..a17f993 100644 --- a/src/components/Country.jsx +++ b/src/components/Country.jsx @@ -1,10 +1,9 @@ import React from 'react' -const Country = () => { +export const Country = () => { return ( // TODO: Country component
Country
) } -export default Country \ No newline at end of file diff --git a/src/components/Filter.jsx b/src/components/Filter.jsx new file mode 100644 index 0000000..22d19b8 --- /dev/null +++ b/src/components/Filter.jsx @@ -0,0 +1,8 @@ +import React from "react"; + +export const Filter=()=>{ + return ( + + ) + +} \ No newline at end of file diff --git a/src/components/Header.jsx b/src/components/Header.jsx new file mode 100644 index 0000000..7a2123f --- /dev/null +++ b/src/components/Header.jsx @@ -0,0 +1,17 @@ +import React from "react"; +import { ThemeToggle } from "./ThemeToggle"; + +export const Header = () => { + return ( +
+
+
+ +

Where in the world?

+
+
+ +
+
+    ) +} \ No newline at end of file diff --git a/src/components/ThemeToggle.jsx b/src/components/ThemeToggle.jsx new file mode 100644 index 0000000..3372e3b --- /dev/null +++ b/src/components/ThemeToggle.jsx @@ -0,0 +1,23 @@ +import React from "react"; +import { useState } from "react"; + +export const ThemeToggle = () => { + const [isDarkMode, setIsDarkMode] = useState(false); + + const toggleTheme = () => { + setIsDarkMode(!isDarkMode) + document.body.classList.toggle("dark-theme", isDarkMode); + } + return ( + + ) +} \ No newline at end of file diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index 507e0c5..1de9f82 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -1,12 +1,15 @@ import React from "react"; +import {Header} from "../components/Header"; -const Home = () => { + +export const Home = () => { return ( // TODO: Home page // Render Country component (components/Country.jsx) for each country // Take data from (assets/CountriesData.json) -
Home
+
+
+
); }; -export default Home; From b584601db7ed0d71e452e96b2ccbd400ed32a328 Mon Sep 17 00:00:00 2001 From: Lian Hershkovits Date: Sun, 29 Dec 2024 17:14:05 +0200 Subject: [PATCH 2/4] finished adding cards --- src/App.jsx | 3 ++- src/components/Country.jsx | 21 ++++++++++++++++++--- src/components/Filter.jsx | 26 ++++++++++++++++++++++++-- src/components/Header.jsx | 2 -- src/pages/Home.jsx | 32 ++++++++++++++++++++++++-------- 5 files changed, 68 insertions(+), 16 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 2a88e41..1fe3d6b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -2,7 +2,8 @@ import "../src/assets/css/common.css"; import "../src/assets/css/details.css"; import "../src/assets/css/main.css"; import "../src/assets/scss/common.scss"; -import Home from "./pages/Home"; +import { Home } from "./pages/Home"; + function App() { return ( diff --git a/src/components/Country.jsx b/src/components/Country.jsx index a17f993..ddd15f4 100644 --- a/src/components/Country.jsx +++ b/src/components/Country.jsx @@ -1,9 +1,24 @@ import React from 'react' -export const Country = () => { + +export const Country = ({ countryData }) => { return ( - // TODO: Country component -
Country
+
+ + country flag + +
+

{countryData.name}

+
    +
  • population: + {countryData.population}
  • +
  • region: + {countryData.region}
  • +
  • capital: + {countryData.capital}
  • +
+
+
) } diff --git a/src/components/Filter.jsx b/src/components/Filter.jsx index 22d19b8..089fd4b 100644 --- a/src/components/Filter.jsx +++ b/src/components/Filter.jsx @@ -1,8 +1,30 @@ import React from "react"; -export const Filter=()=>{ +export const Filter = () => { return ( - +
+
+ + +
+
+
+ Filter by Region + +
+
+
    +
  • All
  • +
  • Africa
  • +
  • America
  • +
  • Asia
  • +
  • Europe
  • +
  • Oceania
  • +
+
+
+
+ ) } \ No newline at end of file diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 7a2123f..5836217 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -3,7 +3,6 @@ import { ThemeToggle } from "./ThemeToggle"; export const Header = () => { return ( -
@@ -12,6 +11,5 @@ export const Header = () => {
-
    ) } \ No newline at end of file diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index 1de9f82..f057b97 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -1,15 +1,31 @@ import React from "react"; -import {Header} from "../components/Header"; - +import { Header } from "../components/header"; +import { Filter } from "../components/Filter"; +import datajson from "../assets/CountriesData.json" +import { Country } from "../components/Country"; export const Home = () => { return ( - // TODO: Home page - // Render Country component (components/Country.jsx) for each country - // Take data from (assets/CountriesData.json)
-
+ +
+
+
+
+ +
+ +
+
+
+ { + datajson.map((cardD, index) => ( + + )) + } +
+
+
); -}; - +}; \ No newline at end of file From baf1148903751f699d744447feabd4714c9c844d Mon Sep 17 00:00:00 2001 From: Lian Hershkovits Date: Sun, 5 Jan 2025 11:25:54 +0200 Subject: [PATCH 3/4] integrated REST countries API & added modal for country details --- src/components/Modal.css | 0 src/components/Modal.jsx | 0 src/pages/Home.jsx | 56 +++++++++++++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 src/components/Modal.css create mode 100644 src/components/Modal.jsx diff --git a/src/components/Modal.css b/src/components/Modal.css new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Modal.jsx b/src/components/Modal.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index f057b97..8c6dd85 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -1,16 +1,58 @@ import React from "react"; import { Header } from "../components/header"; import { Filter } from "../components/Filter"; -import datajson from "../assets/CountriesData.json" import { Country } from "../components/Country"; +import {useState} from "react"; +import {useEffect} from "react"; +import {Modal} from "../components/Modal" + + export const Home = () => { + + const [countries, setCountries]=UseState([]); + const[selectedCountry, setSelectedCountry]=useState(null); + + useEffect(()=>{ + const fetchCountries=async()=>{ + try{ + const response=await fetch("http://restcountries.com/v3.1/all"); + const data=await response.json(); + console.log("data fetched"); + const filteredData=data.map((country)=>({ + countryName : country.name.common, + population : country.population, + refion : country.region, + capital : country.capital ? country.capital[0] : "N/A", + flag: country.flags.svg, + + })); + console.log("filtered data", filteredData); + + setCountries(filteredData); + } + catch (error){ + console.error("error fetching countries:", error); + } + }; + fetchCountries(); + },[]); + + const openModal=(country)=>{ + console.log('opening modal for:', country); + setSelectedCountry(country); + } + const closeModal=()=>{ + setSelectedCountry(null); + } + return (
+
@@ -18,11 +60,13 @@ export const Home = () => {
- { - datajson.map((cardD, index) => ( - - )) - } + {countries.map((countryData)=>( + openModal(countryData)} + /> + ))}
From a1be08d8748064baf792732415b58fae31df399f Mon Sep 17 00:00:00 2001 From: Lian Hershkovits Date: Sun, 5 Jan 2025 12:13:00 +0200 Subject: [PATCH 4/4] added css&jsx for modal & updated country component --- src/components/Country.jsx | 44 ++++++++------ src/components/Modal.css | 115 +++++++++++++++++++++++++++++++++++++ src/components/Modal.jsx | 33 +++++++++++ src/pages/Home.jsx | 106 +++++++++++++++++++--------------- 4 files changed, 233 insertions(+), 65 deletions(-) diff --git a/src/components/Country.jsx b/src/components/Country.jsx index ddd15f4..45b042c 100644 --- a/src/components/Country.jsx +++ b/src/components/Country.jsx @@ -1,24 +1,32 @@ import React from 'react' - -export const Country = ({ countryData }) => { +export const Country = ({ countryData ,onClick }) => { return ( -
+
+ + - country flag +
+

{countryData.countryName}

+
    -
    -

    {countryData.name}

    -
      -
    • population: - {countryData.population}
    • -
    • region: - {countryData.region}
    • -
    • capital: - {countryData.capital}
    • -
    -
    -
- ) -} +
  • + Population: + {countryData.population} +
  • + +
  • + region: + {countryData.region} +
  • +
  • + capital: + {countryData.capital} +
  • + + +
    +
    + ) +} \ No newline at end of file diff --git a/src/components/Modal.css b/src/components/Modal.css index e69de29..cd7160c 100644 --- a/src/components/Modal.css +++ b/src/components/Modal.css @@ -0,0 +1,115 @@ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.7); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modal-content { + background-color: #fff; + border-radius: 10px; + padding: 20px 30px; + width: 90%; + height: 90vh; + max-width: 500px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5); + animation: fadeIn 0.3s ease-out; +} + +.country-flag img { + max-width: 100%; + height: 250px; + border-radius: 5px; + margin-right: 15px; + box-shadow: 0 10px 10px rgba(0, 0, 0, 0.813); + +} + +.country-flag { + display: flex; + align-items: center; + justify-content: center; + +} + +.country-info h1 { + font-size: 30px; + margin-top: -15px; + color: #333; + margin-bottom: 30px; + text-align: center; + +} + +.country-info ul { + list-style: none; + padding: 0; +} + +.country-info li { + margin: 8px 0; + font-size: 16px; + color: #555; +} + +.country-info li strong { + color: #333; +} + +.close-button { + position: absolute; + top: 15px; + right: 15px; + background-color: transparent; + border: none; + font-size: 20px; + cursor: pointer; + color: #999; + transition: color 0.3s ease; +} + +.close-button:hover { + color: #333; +} + +/* אנימציות */ +@keyframes fadeIn { + from { + opacity: 0; + transform: scale(0.9); + } + to { + opacity: 1; + transform: scale(1); + } +} + + + + + /* design for dark mode */ + + +.dark-theme .modal-overlay { + background-color: #5757577d; +} + +.dark-theme .modal-content { + background-color: #202c37; + color: #f5f5f5; + border: 1px solid #444; +} + +.dark-theme .close-button { + color: #f5f5f5; +} + +.dark-theme .close-button:hover { + color: #ddd; +} \ No newline at end of file diff --git a/src/components/Modal.jsx b/src/components/Modal.jsx index e69de29..5963138 100644 --- a/src/components/Modal.jsx +++ b/src/components/Modal.jsx @@ -0,0 +1,33 @@ +import React from "react"; +import "./modal.css"; + + + +export const Modal = ({ countryData, onClose }) => { + if (!countryData) return null; + + const { countryName, flag, region, population, capital } = countryData; + + return ( +
    +
    e.stopPropagation()}> + {/* */} +
    + {`${countryName} +
    +
    +

    {countryName}

    +
      +
    • Population: {population}
    • +
    • Region: {region}
    • +
    • Capital: {capital}
    • + +
    +
    + +
    +
    + ) + + +} \ No newline at end of file diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index 8c6dd85..153403f 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -1,52 +1,54 @@ import React from "react"; -import { Header } from "../components/header"; +import {Header} from "../components/Header"; import { Filter } from "../components/Filter"; import { Country } from "../components/Country"; -import {useState} from "react"; -import {useEffect} from "react"; -import {Modal} from "../components/Modal" +import { useState } from "react"; +import { useEffect } from "react"; +import { Modal } from "../components/Modal"; +export const Home = () => { + const [countries,setCountries]=useState([]); + const [selectedCountry,setSelectedCountry]=useState(null); + + useEffect(()=>{ + const fetchCountries=async()=>{ + try{ + const response=await fetch("https://restcountries.com/v3.1/all"); + const data= await response.json(); + + console.log("data fetched"); + + const filteredData=data.map((country)=>({ + countryName: country.name.common, + population: country.population, + region: country.region, + capital: country.capital ? country.capital[0] :"N/A", + flag: country.flags.svg, + })); + + console.log("filtered data",filteredData); + + setCountries(filteredData); + }catch (error){ + console.error("Error fetching countries:", error); + } + }; + fetchCountries(); + + },[]); + + const openModal=(country)=>{ + console.log('Opening modal for:', country); + setSelectedCountry(country); + } + const closeModal=()=>{ + setSelectedCountry(null); + } -export const Home = () => { - const [countries, setCountries]=UseState([]); - const[selectedCountry, setSelectedCountry]=useState(null); - - useEffect(()=>{ - const fetchCountries=async()=>{ - try{ - const response=await fetch("http://restcountries.com/v3.1/all"); - const data=await response.json(); - console.log("data fetched"); - const filteredData=data.map((country)=>({ - countryName : country.name.common, - population : country.population, - refion : country.region, - capital : country.capital ? country.capital[0] : "N/A", - flag: country.flags.svg, - - })); - console.log("filtered data", filteredData); - - setCountries(filteredData); - } - catch (error){ - console.error("error fetching countries:", error); - } - }; - fetchCountries(); - },[]); - - const openModal=(country)=>{ - console.log('opening modal for:', country); - setSelectedCountry(country); - } - const closeModal=()=>{ - setSelectedCountry(null); - } - return ( +
    @@ -60,16 +62,26 @@ export const Home = () => {
    - {countries.map((countryData)=>( + {countries.map((countryData) => ( openModal(countryData)} + countryData={countryData} + key={countryData.countryName} + onClick={()=>openModal(countryData)} /> ))} -
    +
    + {selectedCountry&& ( + <> + {console.log("Modal is rendering for:", selectedCountry)} + + + )} +
    ); -}; \ No newline at end of file +}; + + +