diff --git a/7_react/react2/week1/my-app/src/App.css b/7_react/react2/week1/my-app/src/App.css new file mode 100644 index 00000000..567fec01 --- /dev/null +++ b/7_react/react2/week1/my-app/src/App.css @@ -0,0 +1,68 @@ +/* App.css */ +body { + font-family: "Arial", sans-serif; + margin: 0; + padding: 0; + background-color: #f4f4f4; +} + +.container { + max-width: 800px; + margin: 50px auto; + padding: 20px; + background-color: #fff; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + border-radius: 5px; +} + +input { + padding: 10px; + font-size: 16px; + margin-right: 10px; +} + +button { + padding: 10px 20px; + font-size: 16px; + background-color: #4caf50; + color: #fff; + border: none; + cursor: pointer; + border-radius: 5px; +} + +button:hover { + background-color: #45a049; +} + +ul { + list-style: none; + padding: 0; +} + +li { + margin: 10px 0; + padding: 10px; + background-color: #f0f0f0; + border-radius: 5px; +} + +p { + font-size: 16px; + margin: 10px 0; +} + +.loading { + font-size: 18px; + color: #3498db; +} + +.error { + font-size: 18px; + color: #e74c3c; +} + +.no-results { + font-size: 18px; + color: #2ecc71; +} diff --git a/7_react/react2/week1/my-app/src/App.js b/7_react/react2/week1/my-app/src/App.js new file mode 100644 index 00000000..98f7f6d8 --- /dev/null +++ b/7_react/react2/week1/my-app/src/App.js @@ -0,0 +1,42 @@ +// App.js +import React, { useState } from "react"; +import { useGithubContext } from "./Context/GithubContext"; +import "./App.css"; + +const App = () => { + const { users, loading, error, searchUsers } = useGithubContext(); + const [query, setQuery] = useState(""); + + const handleSearch = () => { + searchUsers(query); + }; + + return ( +
+
+

Github User Searcher

+
+ +
+ setQuery(e.target.value)} + /> + + + {loading &&

Loading...

} + {error &&

Error: {error}

} + {users.length === 0 && !loading && !error &&

No results...

} + + +
+
+ ); +}; + +export default App; diff --git a/7_react/react2/week1/my-app/src/Context/GithubContext.js b/7_react/react2/week1/my-app/src/Context/GithubContext.js new file mode 100644 index 00000000..c8ef1dbf --- /dev/null +++ b/7_react/react2/week1/my-app/src/Context/GithubContext.js @@ -0,0 +1,64 @@ +// GithubContext.js +import React, { createContext, useReducer, useContext } from "react"; + +const GithubContext = createContext(); + +const initialState = { + users: [], + loading: false, + error: null, +}; + +const githubReducer = (state, action) => { + switch (action.type) { + case "SEARCH_LOADING": + return { ...state, loading: true, error: null }; + case "SEARCH_SUCCESS": + return { ...state, users: action.payload, loading: false, error: null }; + case "SEARCH_ERROR": + return { ...state, loading: false, error: action.payload }; + default: + return state; + } +}; + +const GithubProvider = ({ children }) => { + const [state, dispatch] = useReducer(githubReducer, initialState); + + const searchUsers = async (query) => { + try { + dispatch({ type: "SEARCH_LOADING" }); + const response = await fetch( + `https://api.github.com/search/users?q=${query}` + ); + const data = await response.json(); + + if (data.items) { + dispatch({ type: "SEARCH_SUCCESS", payload: data.items }); + } else { + dispatch({ type: "SEARCH_ERROR", payload: "No results..." }); + } + } catch (error) { + dispatch({ + type: "SEARCH_ERROR", + payload: `Error fetching: ${error.message}`, + }); + } + }; + + return ( + + {children} + + ); +}; + +const useGithubContext = () => { + const context = useContext(GithubContext); + if (!context) { + throw new Error("useGithubContext must be used within a GithubProvider"); + } + return context; +}; + +export { GithubProvider, useGithubContext }; diff --git a/7_react/react2/week1/my-app/src/components/useGithubContext b/7_react/react2/week1/my-app/src/components/useGithubContext new file mode 100644 index 00000000..cfed5221 --- /dev/null +++ b/7_react/react2/week1/my-app/src/components/useGithubContext @@ -0,0 +1,35 @@ +// App.js +import React, { useState } from "react"; +import { useGithubContext } from "../Context/GithubContext"; + +const App = () => { + const { users, loading, error, searchUsers } = useGithubContext(); + const [query, setQuery] = useState(""); + + const handleSearch = () => { + searchUsers(query); + }; + + return ( +
+ setQuery(e.target.value)} + /> + + + {loading &&

Loading...

} + {error &&

Error: {error}

} + {users.length === 0 && !loading && !error &&

No results...

} + + +
+ ); +}; + +export default App; diff --git a/7_react/react2/week1/my-app/src/index.css b/7_react/react2/week1/my-app/src/index.css new file mode 100644 index 00000000..ec2585e8 --- /dev/null +++ b/7_react/react2/week1/my-app/src/index.css @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} diff --git a/7_react/react2/week1/my-app/src/index.js b/7_react/react2/week1/my-app/src/index.js new file mode 100644 index 00000000..2500c168 --- /dev/null +++ b/7_react/react2/week1/my-app/src/index.js @@ -0,0 +1,14 @@ +// index.js +import React from "react"; +import ReactDOM from "react-dom"; +import App from "./App"; +import { GithubProvider } from "./Context/GithubContext"; + +ReactDOM.render( + + + + + , + document.getElementById("root") +); diff --git a/7_react/react2/week1/my-app/src/reportWebVitals.js b/7_react/react2/week1/my-app/src/reportWebVitals.js new file mode 100644 index 00000000..5253d3ad --- /dev/null +++ b/7_react/react2/week1/my-app/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = onPerfEntry => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/7_react/react2/week1/my-app/src/setupTests.js b/7_react/react2/week1/my-app/src/setupTests.js new file mode 100644 index 00000000..8f2609b7 --- /dev/null +++ b/7_react/react2/week1/my-app/src/setupTests.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom';