├── 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 |

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 |
--------------------------------------------------------------------------------