diff --git a/package.json b/package.json index 910845e..433b6af 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", + "axios": "^0.24.0", "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "4.0.3", diff --git a/src/App.css b/src/App.css index 74b5e05..30026f2 100644 --- a/src/App.css +++ b/src/App.css @@ -1,38 +1,66 @@ .App { text-align: center; + padding-top: 2rem; } -.App-logo { - height: 40vmin; - pointer-events: none; +.modal-overlay { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000; + opacity: .5; } -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } +.modal-wrapper { + position: fixed; + top: 0; + left: 0; + z-index: 1050; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0; } -.App-header { - background-color: #282c34; - min-height: 100vh; +.modal { + z-index: 100; + background: white; + position: relative; + margin: 1.75rem auto; + border-radius: 3px; + max-width: 500px; + padding: 2rem; +} + +.modal-header { display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; + justify-content: flex-end; } -.App-link { - color: #61dafb; +.modal-close-button { + font-size: 1.4rem; + font-weight: 700; + line-height: 1; + color: #000; + opacity: .3; + cursor: pointer; + border: none; } -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } +button { + font-size: .9rem; + font-weight: 700; + border: none; + border-radius: 3px; + padding: .3rem 1rem; + margin-left: .5rem; } + +.button-default { + background: #247BA0; + color: #fff; +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index 3784575..23cffe1 100644 --- a/src/App.js +++ b/src/App.js @@ -1,25 +1,24 @@ -import logo from './logo.svg'; +import React,{useState,useEffect, useRef} from 'react'; +import ReactDOM from 'react-dom' +import myAPI from './apis/myAPI'; import './App.css'; +import useAsync from './hooks/useAsync'; + + +const App = () => { + const [{data:employees,loading,error},fetchEmployee] = useAsync(myAPI); + + useEffect(()=>{ + fetchEmployee(); + },[]) -function App() { return (
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
+ {loading ?

Loading

:''} + {error ?

error!

: ''} + {employees? : ''}
); -} +}; -export default App; +export default App; \ No newline at end of file diff --git a/src/App.test.js b/src/App.test.js deleted file mode 100644 index 1f03afe..0000000 --- a/src/App.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/src/apis/myAPI.js b/src/apis/myAPI.js new file mode 100644 index 0000000..f604897 --- /dev/null +++ b/src/apis/myAPI.js @@ -0,0 +1,17 @@ +const myAPI = ()=>{ + return new Promise((resolve,reject)=>{ + setTimeout(()=>{ + resolve([{ + id:1, + name:'SAM', + email:'korkt1.kim@samsung.com' + },{ + id:2, + name:'SUNG', + email:'korkt2.kim@samsung.com' + }]) + },2000) + }) +} + +export default myAPI; \ No newline at end of file diff --git a/src/hooks/useAsync.js b/src/hooks/useAsync.js new file mode 100644 index 0000000..708ac5d --- /dev/null +++ b/src/hooks/useAsync.js @@ -0,0 +1,38 @@ +import React,{useReducer} from 'react'; + +const initialState ={ + data:null, + loading:false, + error: null, +} + +const reducer = (state,action) =>{ + switch (action.type){ + case 'LOADING': + return {...state,loading:true,error:null,data:null}; + case 'SUCCESS': + return {...state,data:action.data,loading:false,error:null}; + case 'ERROR' : + return {...state,data:null,loading:false,error:action.error} + default: + return {...state} + } +} + + +const useAsync = (callback) =>{ + const [state,dispatch] = useReducer(reducer,initialState) + const fetchData = async () =>{ + dispatch({type:'LOADING'}); + try{ + const data = await callback(); + dispatch({type:'SUCCESS',data}); + }catch(e){ + dispatch({type:'ERROR',error:e}); + } + + } + return [state,fetchData]; +} + +export default useAsync \ No newline at end of file diff --git a/src/index.js b/src/index.js index ef2edf8..6832e78 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; -import reportWebVitals from './reportWebVitals'; ReactDOM.render( @@ -10,8 +9,3 @@ ReactDOM.render( , document.getElementById('root') ); - -// If you want to start measuring performance in your app, pass a function -// to log results (for example: reportWebVitals(console.log)) -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); diff --git a/src/logo.svg b/src/logo.svg deleted file mode 100644 index 9dfc1c0..0000000 --- a/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js deleted file mode 100644 index 5253d3a..0000000 --- a/src/reportWebVitals.js +++ /dev/null @@ -1,13 +0,0 @@ -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/src/setupTests.js b/src/setupTests.js deleted file mode 100644 index 8f2609b..0000000 --- a/src/setupTests.js +++ /dev/null @@ -1,5 +0,0 @@ -// 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'; diff --git a/yarn.lock b/yarn.lock index 5c7137e..d4582b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2522,6 +2522,13 @@ axe-core@^4.0.2: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.2.tgz#7cf783331320098bfbef620df3b3c770147bc224" integrity sha512-V+Nq70NxKhYt89ArVcaNL9FDryB3vQOd+BFXZIfO3RP6rwtj+2yqqqdHEkacutglPaZLkJeuXKCjCJDMGPtPqg== +axios@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" + integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== + dependencies: + follow-redirects "^1.14.4" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -5032,6 +5039,11 @@ follow-redirects@^1.0.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.2.tgz#dd73c8effc12728ba5cf4259d760ea5fb83e3147" integrity sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA== +follow-redirects@^1.14.4: + version "1.14.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381" + integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA== + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"