├── README.md ├── src ├── hooks │ └── contexts │ │ ├── CountriesContext.jsx │ │ └── useCountriesContext.jsx ├── index.css ├── main.jsx ├── components │ ├── Countries.jsx │ └── Country.jsx ├── App.css ├── App.jsx └── assets │ └── react.svg ├── vite.config.js ├── .gitignore ├── index.html ├── .eslintrc.cjs ├── package.json └── public └── vite.svg /README.md: -------------------------------------------------------------------------------- 1 | # Hazrat Ali 2 | 3 | # Software Engineer 4 | 5 | # Country Api -------------------------------------------------------------------------------- /src/hooks/contexts/CountriesContext.jsx: -------------------------------------------------------------------------------- 1 | // Countris api jsx 2 | import { createContext } from "react"; 3 | 4 | export const CountriesContext = createContext(); 5 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | html, 7 | body { 8 | width: 100%; 9 | height: 100%; 10 | } 11 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | 9 | // vite config 10 | -------------------------------------------------------------------------------- /src/hooks/contexts/useCountriesContext.jsx: -------------------------------------------------------------------------------- 1 | // user component Context 2 | 3 | import { useContext } from "react"; 4 | import { CountriesContext } from "./CountriesContext"; 5 | 6 | export const useCountriesContext = () => { 7 | return useContext(CountriesContext); 8 | }; 9 | -------------------------------------------------------------------------------- /src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App.jsx"; 4 | import "./index.css"; 5 | 6 | ReactDOM.createRoot(document.getElementById("root")).render( 7 | 8 | 9 | 10 | ); 11 | 12 | // main js 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Country App 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:react/recommended', 7 | 'plugin:react/jsx-runtime', 8 | 'plugin:react-hooks/recommended', 9 | ], 10 | ignorePatterns: ['dist', '.eslintrc.cjs'], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react/jsx-no-target-blank': 'off', 16 | 'react-refresh/only-export-components': [ 17 | 'warn', 18 | { allowConstantExport: true }, 19 | ], 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /src/components/Countries.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { v4 as uuidv4 } from "uuid"; 3 | 4 | 5 | 6 | // Countries Hooks 7 | import Country from "./Country"; 8 | import { useCountriesContext } from "../hooks/contexts/useCountriesContext"; 9 | 10 | const Countries = () => { 11 | const { data } = useCountriesContext(); 12 | 13 | return ( 14 |
15 | {data.map((country) => { 16 | return ( 17 | 23 | ); 24 | })} 25 |
26 | ); 27 | }; 28 | 29 | export default Countries; 30 | -------------------------------------------------------------------------------- /src/components/Country.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { FaDeleteLeft } from "react-icons/fa6"; 3 | import { useCountriesContext } from "../hooks/contexts/useCountriesContext"; 4 | 5 | const Country = ({ name, src, id }) => { 6 | const { data, setData } = useCountriesContext(); 7 | const deleteCountry = () => { 8 | const filterdCountry = data.filter((country) => country.id !== id); 9 | setData(filterdCountry); 10 | }; 11 | return ( 12 |
13 | img 14 |
15 |

Name : {name}

16 | { 19 | deleteCountry(); 20 | }} 21 | /> 22 |
23 |
24 | ); 25 | }; 26 | 27 | export default Country; 28 | // Country 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "country-app", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0", 15 | "react-icons": "^5.0.1", 16 | "uuid": "^9.0.1" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^18.2.66", 20 | "@types/react-dom": "^18.2.22", 21 | "@vitejs/plugin-react": "^4.2.1", 22 | "eslint": "^8.57.0", 23 | "eslint-plugin-react": "^7.34.1", 24 | "eslint-plugin-react-hooks": "^4.6.0", 25 | "eslint-plugin-react-refresh": "^0.4.6", 26 | "vite": "^5.2.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | #all { 2 | font-family: Verdana, Geneva, Tahoma, sans-serif; 3 | padding: 0.5rem 0 2rem 0; 4 | } 5 | h1, 6 | #load, 7 | #error { 8 | text-align: center; 9 | margin: 0.5rem 0; 10 | } 11 | #load { 12 | font-size: 1.3rem; 13 | margin: 1rem 0 0.5rem 0; 14 | } 15 | #countries { 16 | display: flex; 17 | justify-content: center; 18 | align-items: center; 19 | min-height: 15vh; 20 | width: 95%; 21 | background-color: rgba(95, 158, 160, 0.454); 22 | flex-wrap: wrap; 23 | padding: 1rem; 24 | margin: 2rem auto; 25 | border-radius: 2px; 26 | } 27 | #form { 28 | width: 300px; 29 | margin: 1rem auto; 30 | display: flex; 31 | justify-content: space-around; 32 | } 33 | input { 34 | border: none; 35 | outline: none; 36 | font-size: 1.1rem; 37 | padding: 3px 6px; 38 | border-radius: 2px; 39 | background-color: cadetblue; 40 | color: white; 41 | } 42 | 43 | input { 44 | border: 1px solid green; 45 | font-size: 1.1rem; 46 | font-family: monospace; 47 | margin: auto; 48 | text-align: center; 49 | } 50 | #country { 51 | width: 30%; 52 | margin: 1vw; 53 | padding: 1.3rem; 54 | background-color: black; 55 | border-radius: 3px; 56 | color: white; 57 | } 58 | 59 | #country img { 60 | width: 100%; 61 | height: 200px; 62 | } 63 | #country div { 64 | display: flex; 65 | justify-content: space-between; 66 | margin-top: 1.5vw; 67 | } 68 | #country div h2 { 69 | font-size: 1rem; 70 | } 71 | #del { 72 | font-size: 1.5rem; 73 | } 74 | #del:hover { 75 | cursor: pointer; 76 | } 77 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import { v4 as uuidv4 } from "uuid"; 3 | 4 | import "./App.css"; 5 | import Countries from "./components/Countries"; 6 | import { CountriesContext } from "./hooks/contexts/CountriesContext"; 7 | 8 | const App = () => { 9 | const [data, setData] = useState([]); 10 | const [isLoading, setIsLoading] = useState(true); 11 | const [error, setError] = useState(null); 12 | 13 | useEffect(() => { 14 | fetch("https://restcountries.com/v3.1/all") 15 | .then((res) => { 16 | if (!res.ok) { 17 | throw new Error("Failed To Fetching"); 18 | } 19 | return res.json(); 20 | }) 21 | .then((data) => { 22 | const countries = data.map((country) => { 23 | return { ...country, id: uuidv4() }; 24 | }); 25 | setData(countries); 26 | setIsLoading(false); 27 | setError(null); 28 | }) 29 | .catch((error) => { 30 | setError(error.message); 31 | setIsLoading(false); 32 | }); 33 | }, []); 34 | const [value, setValue] = useState(""); 35 | const handleChange = (e) => { 36 | setValue(e.target.value); 37 | }; 38 | useEffect(() => { 39 | const searchValue = value.toLowerCase(); 40 | const filterdCountry = data.filter((country) => { 41 | const countryName = country.name.common.toLowerCase(); 42 | return countryName.startsWith(searchValue); 43 | }); 44 | console.log(value); 45 | console.log(filterdCountry); 46 | setData(filterdCountry); 47 | }, [value]); 48 | 49 | return ( 50 | 51 |
52 |

All Country

53 | 54 |
55 | 56 |
57 | 58 | {error &&

{error}

} 59 | {isLoading ?

Loading data...

: } 60 |
61 |
62 | ); 63 | }; 64 | 65 | export default App; 66 | 67 | // apps 68 | -------------------------------------------------------------------------------- /src/assets/react.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------