├── .gitignore ├── .prettierrc ├── 00-template ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── index.css │ └── index.js ├── 01-vannila-js └── index.html ├── 02-react-hello-world └── index.html ├── 03-react-vs-vannila-js └── index.html ├── 04-jsx-hello-world └── index.html ├── 05-react-jsx-green-button ├── index.html └── script.js ├── 06-create-react-app ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ └── setupTests.js ├── 07-create-react-app-eject ├── .gitignore ├── README.md ├── config │ ├── env.js │ ├── getHttpsConfig.js │ ├── jest │ │ ├── babelTransform.js │ │ ├── cssTransform.js │ │ └── fileTransform.js │ ├── modules.js │ ├── paths.js │ ├── webpack.config.js │ ├── webpack │ │ └── persistentCache │ │ │ └── createEnvironmentHash.js │ └── webpackDevServer.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── scripts │ ├── build.js │ ├── start.js │ └── test.js └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ └── setupTests.js ├── 08-reusable-components ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── MyComponent.js │ └── OtherComponent.js │ ├── index.css │ └── index.js ├── 09-props ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ └── PetInfo.js │ ├── index.css │ └── index.js ├── 10-conditional-rendering ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ └── PetInfo.js │ ├── index.css │ └── index.js ├── 11-state ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ └── RandomNumber.js │ ├── index.css │ ├── index.js │ └── utils │ └── generateRandomNum.js ├── 12-state-via-props ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Button.js │ └── Counter.js │ ├── index.css │ └── index.js ├── 13-map ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Button.js │ └── Counter.js │ ├── index.css │ └── index.js ├── 14-map-array-of-objects ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Person.js │ └── Persons.js │ ├── data │ └── persons.js │ ├── index.css │ └── index.js ├── 15-logical-and-operator ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Button.js │ ├── Counter.js │ └── ResetBtn.js │ ├── index.css │ └── index.js ├── 16-react-fragment ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ └── Card.js │ ├── index.css │ └── index.js ├── 17-uncontrolled-input ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ └── Login.js │ ├── index.css │ └── index.js ├── 18-controlled-input ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ └── Login.js │ ├── index.css │ └── index.js ├── 19-children-prop ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ └── Wrapper.js │ ├── index.css │ └── index.js ├── 20-useEffect ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Post.js │ └── Posts.js │ ├── index.css │ └── index.js ├── 21-jsonplaceholder-posts ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Post.css │ ├── Post.js │ └── Posts.js │ ├── index.css │ └── index.js ├── 22-useEffect-async-await ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Post.css │ ├── Post.js │ └── Posts.js │ ├── index.css │ └── index.js ├── 23-css-modules ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Info.css │ ├── Info.js │ └── info.module.css │ ├── index.css │ └── index.js ├── 24-todo-app-v1 ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Todo │ │ ├── Todo.js │ │ └── Todo.module.css │ ├── TodoForm │ │ ├── TodoForm.js │ │ └── TodoForm.module.css │ ├── TodoList │ │ ├── TodoList.js │ │ └── TodoList.module.css │ └── UI │ │ ├── Button.js │ │ └── Button.module.css │ ├── index.css │ └── index.js ├── 25-todo-app-v2 ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── Todo │ │ ├── Todo.js │ │ └── Todo.module.css │ ├── TodoForm │ │ ├── TodoForm.js │ │ └── TodoForm.module.css │ ├── TodoList │ │ ├── TodoList.js │ │ └── TodoList.module.css │ ├── TodosActions │ │ ├── TodosActions.js │ │ └── TodosActions.module.css │ └── UI │ │ ├── Button.js │ │ └── Button.module.css │ ├── index.css │ └── index.js ├── 26-react-router ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.jsx │ ├── components │ ├── About.jsx │ ├── Contacts.jsx │ ├── Courses.jsx │ ├── Home.jsx │ ├── Menu.jsx │ ├── NotFound.jsx │ └── SingleCourse.jsx │ ├── data │ └── courses.js │ ├── index.css │ ├── index.js │ └── layouts │ └── MainLayout.jsx ├── 27-context-api ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── index.html │ └── site.webmanifest └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── ChangeUser.jsx │ ├── User.jsx │ └── UserInfo.jsx │ ├── context │ └── UserContext.js │ ├── index.css │ └── index.js ├── 28-reducer └── reducer.js ├── 29-pure-redux ├── index.html ├── index.js ├── redux │ ├── reducer.js │ └── store.js └── utils │ └── getCurrentTime.js ├── 30-react-redux ├── api │ ├── .gitignore │ ├── README.md │ ├── data │ │ └── books.json │ ├── index.js │ ├── package-lock.json │ ├── package.json │ └── vercel.json └── frontend │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt │ └── src │ ├── App.css │ ├── App.js │ ├── components │ ├── BookForm │ │ ├── BookForm.css │ │ └── BookForm.js │ ├── BookList │ │ ├── BookList.css │ │ └── BookList.js │ ├── Error │ │ └── Error.js │ └── Filter │ │ ├── Filter.css │ │ └── Filter.js │ ├── data │ └── books.json │ ├── index.css │ ├── index.js │ ├── redux │ ├── slices │ │ ├── booksSlice.js │ │ ├── errorSlice.js │ │ └── filterSlice.js │ └── store.js │ └── utils │ └── createBookWithID.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac desktop service store files 2 | 3 | .DS_Store 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | 12 | 13 | # Compiled binary addons (http://nodejs.org/api/addons.html) 14 | build/Release 15 | 16 | # Dependency directories 17 | node_modules/ 18 | jspm_packages/ 19 | 20 | # Distribution directories 21 | dist/ 22 | 23 | # Typescript v1 declaration files 24 | typings/ 25 | 26 | # Optional npm cache directory 27 | .npm 28 | 29 | # Optional eslint cache 30 | .eslintcache 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | 35 | # Output of 'npm pack' 36 | *.tgz 37 | 38 | # Yarn Integrity file 39 | .yarn-integrity 40 | 41 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all", 8 | "bracketSpacing": true, 9 | "jsxBracketSameLine": false, 10 | "arrowParens": "avoid", 11 | "proseWrap": "always" 12 | } 13 | -------------------------------------------------------------------------------- /00-template/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /00-template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /00-template/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/00-template/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /00-template/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/00-template/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /00-template/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/00-template/public/apple-touch-icon.png -------------------------------------------------------------------------------- /00-template/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/00-template/public/favicon-16x16.png -------------------------------------------------------------------------------- /00-template/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/00-template/public/favicon-32x32.png -------------------------------------------------------------------------------- /00-template/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/00-template/public/favicon.ico -------------------------------------------------------------------------------- /00-template/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /00-template/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /00-template/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | font-size: 90px; 7 | margin-top: 20px; 8 | } 9 | 10 | button { 11 | padding: 15px; 12 | font-size: 30px; 13 | border-radius: 5px; 14 | border: 0; 15 | margin: 20px; 16 | cursor: pointer; 17 | } 18 | -------------------------------------------------------------------------------- /00-template/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | 3 | function App() { 4 | return
; 5 | } 6 | 7 | export default App; 8 | -------------------------------------------------------------------------------- /00-template/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /00-template/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /01-vannila-js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vanilla JS 7 | 17 | 18 | 19 |
20 | 23 | 26 |
27 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /02-react-hello-world/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React Hello World 7 | 8 | 9 |
10 | 14 | 18 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /03-react-vs-vannila-js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React Hello World 7 | 8 | 9 |
10 |
11 | 15 | 19 | 27 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /04-jsx-hello-world/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | JSX Hello World 7 | 8 | 9 |
10 | 14 | 18 | 19 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /05-react-jsx-green-button/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React JSX Green Button 7 | 17 | 18 | 19 |
20 | 24 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /05-react-jsx-green-button/script.js: -------------------------------------------------------------------------------- 1 | const App = ({ initialButtonText, initialClassesList }) => { 2 | const [buttonText, setButtonText] = React.useState(initialButtonText); 3 | const [classesList, setClassesList] = React.useState(initialClassesList); 4 | 5 | const onButtonClick = () => { 6 | setButtonText('Hello from React'); 7 | setClassesList('green-btn'); 8 | }; 9 | 10 | return ( 11 |
12 | 15 |
16 | ); 17 | }; 18 | 19 | const container = document.getElementById('app'); 20 | const root = ReactDOM.createRoot(container); 21 | root.render(); 22 | 23 | // npx live-server --open=05-react-jsx-green-button 24 | -------------------------------------------------------------------------------- /06-create-react-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /06-create-react-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "06-create-react-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /06-create-react-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/06-create-react-app/public/favicon.ico -------------------------------------------------------------------------------- /06-create-react-app/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/06-create-react-app/public/logo192.png -------------------------------------------------------------------------------- /06-create-react-app/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/06-create-react-app/public/logo512.png -------------------------------------------------------------------------------- /06-create-react-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /06-create-react-app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /06-create-react-app/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /06-create-react-app/src/App.js: -------------------------------------------------------------------------------- 1 | import logo from './logo.svg'; 2 | import './App.css'; 3 | 4 | function App() { 5 | return ( 6 |
7 |
8 | logo 9 |

10 | Edit src/App.js and save to reload. 11 |

12 | 18 | Learn React 19 | 20 |
21 |
22 | ); 23 | } 24 | 25 | export default App; 26 | -------------------------------------------------------------------------------- /06-create-react-app/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /06-create-react-app/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /06-create-react-app/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /06-create-react-app/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /06-create-react-app/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /07-create-react-app-eject/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /07-create-react-app-eject/config/jest/babelTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const babelJest = require('babel-jest').default; 4 | 5 | const hasJsxRuntime = (() => { 6 | if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') { 7 | return false; 8 | } 9 | 10 | try { 11 | require.resolve('react/jsx-runtime'); 12 | return true; 13 | } catch (e) { 14 | return false; 15 | } 16 | })(); 17 | 18 | module.exports = babelJest.createTransformer({ 19 | presets: [ 20 | [ 21 | require.resolve('babel-preset-react-app'), 22 | { 23 | runtime: hasJsxRuntime ? 'automatic' : 'classic', 24 | }, 25 | ], 26 | ], 27 | babelrc: false, 28 | configFile: false, 29 | }); 30 | -------------------------------------------------------------------------------- /07-create-react-app-eject/config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/en/webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /07-create-react-app-eject/config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const camelcase = require('camelcase'); 5 | 6 | // This is a custom Jest transformer turning file imports into filenames. 7 | // http://facebook.github.io/jest/docs/en/webpack.html 8 | 9 | module.exports = { 10 | process(src, filename) { 11 | const assetFilename = JSON.stringify(path.basename(filename)); 12 | 13 | if (filename.match(/\.svg$/)) { 14 | // Based on how SVGR generates a component name: 15 | // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6 16 | const pascalCaseFilename = camelcase(path.parse(filename).name, { 17 | pascalCase: true, 18 | }); 19 | const componentName = `Svg${pascalCaseFilename}`; 20 | return `const React = require('react'); 21 | module.exports = { 22 | __esModule: true, 23 | default: ${assetFilename}, 24 | ReactComponent: React.forwardRef(function ${componentName}(props, ref) { 25 | return { 26 | $$typeof: Symbol.for('react.element'), 27 | type: 'svg', 28 | ref: ref, 29 | key: null, 30 | props: Object.assign({}, props, { 31 | children: ${assetFilename} 32 | }) 33 | }; 34 | }), 35 | };`; 36 | } 37 | 38 | return `module.exports = ${assetFilename};`; 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /07-create-react-app-eject/config/webpack/persistentCache/createEnvironmentHash.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const { createHash } = require('crypto'); 3 | 4 | module.exports = env => { 5 | const hash = createHash('md5'); 6 | hash.update(JSON.stringify(env)); 7 | 8 | return hash.digest('hex'); 9 | }; 10 | -------------------------------------------------------------------------------- /07-create-react-app-eject/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/07-create-react-app-eject/public/favicon.ico -------------------------------------------------------------------------------- /07-create-react-app-eject/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/07-create-react-app-eject/public/logo192.png -------------------------------------------------------------------------------- /07-create-react-app-eject/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/07-create-react-app-eject/public/logo512.png -------------------------------------------------------------------------------- /07-create-react-app-eject/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /07-create-react-app-eject/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /07-create-react-app-eject/scripts/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Do this as the first thing so that any code reading it knows the right env. 4 | process.env.BABEL_ENV = 'test'; 5 | process.env.NODE_ENV = 'test'; 6 | process.env.PUBLIC_URL = ''; 7 | 8 | // Makes the script crash on unhandled rejections instead of silently 9 | // ignoring them. In the future, promise rejections that are not handled will 10 | // terminate the Node.js process with a non-zero exit code. 11 | process.on('unhandledRejection', err => { 12 | throw err; 13 | }); 14 | 15 | // Ensure environment variables are read. 16 | require('../config/env'); 17 | 18 | const jest = require('jest'); 19 | const execSync = require('child_process').execSync; 20 | let argv = process.argv.slice(2); 21 | 22 | function isInGitRepository() { 23 | try { 24 | execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }); 25 | return true; 26 | } catch (e) { 27 | return false; 28 | } 29 | } 30 | 31 | function isInMercurialRepository() { 32 | try { 33 | execSync('hg --cwd . root', { stdio: 'ignore' }); 34 | return true; 35 | } catch (e) { 36 | return false; 37 | } 38 | } 39 | 40 | // Watch unless on CI or explicitly running all tests 41 | if ( 42 | !process.env.CI && 43 | argv.indexOf('--watchAll') === -1 && 44 | argv.indexOf('--watchAll=false') === -1 45 | ) { 46 | // https://github.com/facebook/create-react-app/issues/5210 47 | const hasSourceControl = isInGitRepository() || isInMercurialRepository(); 48 | argv.push(hasSourceControl ? '--watch' : '--watchAll'); 49 | } 50 | 51 | 52 | jest.run(argv); 53 | -------------------------------------------------------------------------------- /07-create-react-app-eject/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /07-create-react-app-eject/src/App.js: -------------------------------------------------------------------------------- 1 | import logo from './logo.svg'; 2 | import './App.css'; 3 | 4 | function App() { 5 | return ( 6 |
7 |
8 | logo 9 |

10 | Edit src/App.js and save to reload. 11 |

12 | 18 | Learn React 19 | 20 |
21 |
22 | ); 23 | } 24 | 25 | export default App; 26 | -------------------------------------------------------------------------------- /07-create-react-app-eject/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /07-create-react-app-eject/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /07-create-react-app-eject/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /07-create-react-app-eject/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /07-create-react-app-eject/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /08-reusable-components/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /08-reusable-components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /08-reusable-components/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/08-reusable-components/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /08-reusable-components/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/08-reusable-components/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /08-reusable-components/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/08-reusable-components/public/apple-touch-icon.png -------------------------------------------------------------------------------- /08-reusable-components/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/08-reusable-components/public/favicon-16x16.png -------------------------------------------------------------------------------- /08-reusable-components/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/08-reusable-components/public/favicon-32x32.png -------------------------------------------------------------------------------- /08-reusable-components/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/08-reusable-components/public/favicon.ico -------------------------------------------------------------------------------- /08-reusable-components/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /08-reusable-components/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /08-reusable-components/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /08-reusable-components/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import MyComponent from './components/MyComponent'; 3 | import OtherComponent from './components/OtherComponent'; 4 | 5 | function App() { 6 | return ( 7 |
8 | 9 | 10 |
11 | ); 12 | } 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /08-reusable-components/src/components/MyComponent.js: -------------------------------------------------------------------------------- 1 | function MyComponent() { 2 | return ( 3 |
4 |

Hello from the reusable component

5 | 6 |
7 | ); 8 | } 9 | 10 | export default MyComponent; 11 | -------------------------------------------------------------------------------- /08-reusable-components/src/components/OtherComponent.js: -------------------------------------------------------------------------------- 1 | function OtherComponent() { 2 | return ( 3 |
4 |

Hello from React

5 |
6 | ); 7 | } 8 | 9 | export default OtherComponent; 10 | -------------------------------------------------------------------------------- /08-reusable-components/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /08-reusable-components/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /09-props/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /09-props/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /09-props/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/09-props/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /09-props/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/09-props/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /09-props/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/09-props/public/apple-touch-icon.png -------------------------------------------------------------------------------- /09-props/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/09-props/public/favicon-16x16.png -------------------------------------------------------------------------------- /09-props/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/09-props/public/favicon-32x32.png -------------------------------------------------------------------------------- /09-props/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/09-props/public/favicon.ico -------------------------------------------------------------------------------- /09-props/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /09-props/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /09-props/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /09-props/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import PetInfo from './components/PetInfo'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 | 9 |
10 | ); 11 | } 12 | 13 | export default App; 14 | -------------------------------------------------------------------------------- /09-props/src/components/PetInfo.js: -------------------------------------------------------------------------------- 1 | function PetInfo({ animal, age }) { 2 | // const { animal, age } = props; 3 | return ( 4 |

5 | My {animal} is {age} years old 6 |

7 | ); 8 | } 9 | 10 | export default PetInfo; 11 | -------------------------------------------------------------------------------- /09-props/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /09-props/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /10-conditional-rendering/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /10-conditional-rendering/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /10-conditional-rendering/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/10-conditional-rendering/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /10-conditional-rendering/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/10-conditional-rendering/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /10-conditional-rendering/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/10-conditional-rendering/public/apple-touch-icon.png -------------------------------------------------------------------------------- /10-conditional-rendering/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/10-conditional-rendering/public/favicon-16x16.png -------------------------------------------------------------------------------- /10-conditional-rendering/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/10-conditional-rendering/public/favicon-32x32.png -------------------------------------------------------------------------------- /10-conditional-rendering/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/10-conditional-rendering/public/favicon.ico -------------------------------------------------------------------------------- /10-conditional-rendering/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /10-conditional-rendering/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /10-conditional-rendering/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /10-conditional-rendering/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import PetInfo from './components/PetInfo'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 | 9 |
10 | ); 11 | } 12 | 13 | export default App; 14 | -------------------------------------------------------------------------------- /10-conditional-rendering/src/components/PetInfo.js: -------------------------------------------------------------------------------- 1 | function PetInfo({ animal, age, hasPet }) { 2 | // const text = hasPet 3 | // ? `My ${animal} is ${age} years old` 4 | // : "I don't have an animal"; 5 | // return

{text}

; 6 | 7 | return hasPet ? ( 8 |

{`My ${animal} is ${age} years old`}

9 | ) : ( 10 |

I don't have an animal

11 | ); 12 | } 13 | 14 | export default PetInfo; 15 | -------------------------------------------------------------------------------- /10-conditional-rendering/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /10-conditional-rendering/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /11-state/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /11-state/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /11-state/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/11-state/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /11-state/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/11-state/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /11-state/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/11-state/public/apple-touch-icon.png -------------------------------------------------------------------------------- /11-state/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/11-state/public/favicon-16x16.png -------------------------------------------------------------------------------- /11-state/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/11-state/public/favicon-32x32.png -------------------------------------------------------------------------------- /11-state/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/11-state/public/favicon.ico -------------------------------------------------------------------------------- /11-state/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /11-state/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /11-state/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | font-size: 90px; 7 | margin-top: 20px; 8 | } 9 | 10 | button { 11 | padding: 15px; 12 | font-size: 30px; 13 | border-radius: 5px; 14 | border: 0; 15 | margin: 20px; 16 | cursor: pointer; 17 | } 18 | -------------------------------------------------------------------------------- /11-state/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import RandomNumber from './components/RandomNumber'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /11-state/src/components/RandomNumber.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import generateRandomNum from '../utils/generateRandomNum'; 3 | 4 | function RandomNumber({ maxNum }) { 5 | const [randomNum, setRandomNum] = useState(generateRandomNum(maxNum)); 6 | const changeRandomNum = () => { 7 | setRandomNum(generateRandomNum(maxNum)); 8 | }; 9 | return ( 10 |
11 |

{randomNum}

12 | 13 |
14 | ); 15 | } 16 | 17 | export default RandomNumber; 18 | -------------------------------------------------------------------------------- /11-state/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /11-state/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /11-state/src/utils/generateRandomNum.js: -------------------------------------------------------------------------------- 1 | function generateRandomNum(maxNum) { 2 | return Math.floor(Math.random() * maxNum); 3 | } 4 | 5 | export default generateRandomNum; 6 | -------------------------------------------------------------------------------- /12-state-via-props/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /12-state-via-props/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /12-state-via-props/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/12-state-via-props/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /12-state-via-props/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/12-state-via-props/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /12-state-via-props/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/12-state-via-props/public/apple-touch-icon.png -------------------------------------------------------------------------------- /12-state-via-props/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/12-state-via-props/public/favicon-16x16.png -------------------------------------------------------------------------------- /12-state-via-props/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/12-state-via-props/public/favicon-32x32.png -------------------------------------------------------------------------------- /12-state-via-props/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/12-state-via-props/public/favicon.ico -------------------------------------------------------------------------------- /12-state-via-props/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /12-state-via-props/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /12-state-via-props/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | font-size: 90px; 7 | margin-top: 20px; 8 | } 9 | 10 | button { 11 | padding: 15px; 12 | font-size: 30px; 13 | border-radius: 5px; 14 | border: 0; 15 | margin: 20px; 16 | cursor: pointer; 17 | } 18 | -------------------------------------------------------------------------------- /12-state-via-props/src/App.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import './App.css'; 3 | import Counter from './components/Counter'; 4 | import Button from './components/Button'; 5 | 6 | function App() { 7 | const [count, setCount] = useState(0); 8 | const incrementCount = () => { 9 | setCount(count + 1); 10 | }; 11 | return ( 12 |
13 | 14 |
19 | ); 20 | } 21 | 22 | export default App; 23 | -------------------------------------------------------------------------------- /12-state-via-props/src/components/Button.js: -------------------------------------------------------------------------------- 1 | function Button({ onClick }) { 2 | return ; 3 | } 4 | 5 | export default Button; 6 | -------------------------------------------------------------------------------- /12-state-via-props/src/components/Counter.js: -------------------------------------------------------------------------------- 1 | function Counter({ count }) { 2 | return

Total clicks: {count}

; 3 | } 4 | 5 | export default Counter; 6 | -------------------------------------------------------------------------------- /12-state-via-props/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /12-state-via-props/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /13-map/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /13-map/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /13-map/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/13-map/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /13-map/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/13-map/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /13-map/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/13-map/public/apple-touch-icon.png -------------------------------------------------------------------------------- /13-map/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/13-map/public/favicon-16x16.png -------------------------------------------------------------------------------- /13-map/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/13-map/public/favicon-32x32.png -------------------------------------------------------------------------------- /13-map/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/13-map/public/favicon.ico -------------------------------------------------------------------------------- /13-map/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /13-map/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /13-map/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | font-size: 90px; 7 | margin-top: 20px; 8 | } 9 | 10 | button { 11 | padding: 15px; 12 | font-size: 30px; 13 | border-radius: 5px; 14 | border: 0; 15 | margin: 20px; 16 | cursor: pointer; 17 | } 18 | -------------------------------------------------------------------------------- /13-map/src/App.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import './App.css'; 3 | import Counter from './components/Counter'; 4 | import Button from './components/Button'; 5 | 6 | function App({ text }) { 7 | const [count, setCount] = useState(0); 8 | const incrementCount = () => { 9 | setCount(count + 1); 10 | }; 11 | 12 | const texts = ['Click me!', 'Click me please!', 'Hit me!', 'Press me!']; 13 | 14 | return ( 15 |
16 | 17 | {texts.map(text, index => { 18 | return
21 | ); 22 | } 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /13-map/src/components/Button.js: -------------------------------------------------------------------------------- 1 | function Button({ onClick, text }) { 2 | return ; 3 | } 4 | 5 | export default Button; 6 | -------------------------------------------------------------------------------- /13-map/src/components/Counter.js: -------------------------------------------------------------------------------- 1 | function Counter({ count }) { 2 | return

Total clicks: {count}

; 3 | } 4 | 5 | export default Counter; 6 | -------------------------------------------------------------------------------- /13-map/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /13-map/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /14-map-array-of-objects/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /14-map-array-of-objects/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /14-map-array-of-objects/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/14-map-array-of-objects/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /14-map-array-of-objects/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/14-map-array-of-objects/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /14-map-array-of-objects/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/14-map-array-of-objects/public/apple-touch-icon.png -------------------------------------------------------------------------------- /14-map-array-of-objects/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/14-map-array-of-objects/public/favicon-16x16.png -------------------------------------------------------------------------------- /14-map-array-of-objects/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/14-map-array-of-objects/public/favicon-32x32.png -------------------------------------------------------------------------------- /14-map-array-of-objects/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/14-map-array-of-objects/public/favicon.ico -------------------------------------------------------------------------------- /14-map-array-of-objects/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /14-map-array-of-objects/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /14-map-array-of-objects/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .cards { 6 | display: flex; 7 | flex-wrap: wrap; 8 | flex-direction: row; 9 | justify-content: space-between; 10 | gap: 15px; 11 | } 12 | 13 | .card { 14 | width: 250px; 15 | border: 1px lightgray solid; 16 | border-radius: 10px; 17 | padding-bottom: 10px; 18 | } 19 | 20 | .card > img { 21 | width: 100%; 22 | border-radius: 10px; 23 | } 24 | -------------------------------------------------------------------------------- /14-map-array-of-objects/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import Persons from './components/Persons'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /14-map-array-of-objects/src/components/Person.js: -------------------------------------------------------------------------------- 1 | function Person(props) { 2 | const { firstName, lastName, email, img } = props; 3 | 4 | return ( 5 |
6 | pic 7 |

8 | {firstName} {lastName} 9 |

10 |

{email}

11 |
12 | ); 13 | } 14 | 15 | export default Person; 16 | -------------------------------------------------------------------------------- /14-map-array-of-objects/src/components/Persons.js: -------------------------------------------------------------------------------- 1 | import persons from '../data/persons'; 2 | import Person from './Person'; 3 | 4 | function Persons() { 5 | return ( 6 |
7 | {persons.map(person => { 8 | return ; 9 | })} 10 |
11 | ); 12 | } 13 | 14 | export default Persons; 15 | -------------------------------------------------------------------------------- /14-map-array-of-objects/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /14-map-array-of-objects/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /15-logical-and-operator/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /15-logical-and-operator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /15-logical-and-operator/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/15-logical-and-operator/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /15-logical-and-operator/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/15-logical-and-operator/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /15-logical-and-operator/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/15-logical-and-operator/public/apple-touch-icon.png -------------------------------------------------------------------------------- /15-logical-and-operator/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/15-logical-and-operator/public/favicon-16x16.png -------------------------------------------------------------------------------- /15-logical-and-operator/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/15-logical-and-operator/public/favicon-32x32.png -------------------------------------------------------------------------------- /15-logical-and-operator/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/15-logical-and-operator/public/favicon.ico -------------------------------------------------------------------------------- /15-logical-and-operator/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /15-logical-and-operator/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /15-logical-and-operator/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | font-size: 90px; 7 | margin-top: 20px; 8 | } 9 | 10 | button { 11 | padding: 15px; 12 | font-size: 30px; 13 | border-radius: 5px; 14 | border: 0; 15 | margin: 20px; 16 | cursor: pointer; 17 | } 18 | -------------------------------------------------------------------------------- /15-logical-and-operator/src/App.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import './App.css'; 3 | import Counter from './components/Counter'; 4 | import Button from './components/Button'; 5 | import ResetBtn from './components/ResetBtn'; 6 | 7 | function App() { 8 | const [count, setCount] = useState(0); 9 | const incrementCount = () => { 10 | setCount(count + 1); 11 | }; 12 | 13 | const resetCount = () => { 14 | setCount(0); 15 | }; 16 | 17 | return ( 18 |
19 | 20 |
26 | ); 27 | } 28 | 29 | export default App; 30 | -------------------------------------------------------------------------------- /15-logical-and-operator/src/components/Button.js: -------------------------------------------------------------------------------- 1 | function Button({ onClick }) { 2 | return ; 3 | } 4 | 5 | export default Button; 6 | -------------------------------------------------------------------------------- /15-logical-and-operator/src/components/Counter.js: -------------------------------------------------------------------------------- 1 | function Counter({ count }) { 2 | return

Total clicks: {count}

; 3 | } 4 | 5 | export default Counter; 6 | -------------------------------------------------------------------------------- /15-logical-and-operator/src/components/ResetBtn.js: -------------------------------------------------------------------------------- 1 | function ResetBtn({ count, onClick }) { 2 | return ( 3 |
4 | {count > 0 && ( 5 |
6 | 9 |
10 | )} 11 |
12 | ); 13 | } 14 | 15 | export default ResetBtn; 16 | -------------------------------------------------------------------------------- /15-logical-and-operator/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /15-logical-and-operator/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /16-react-fragment/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /16-react-fragment/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /16-react-fragment/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/16-react-fragment/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /16-react-fragment/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/16-react-fragment/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /16-react-fragment/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/16-react-fragment/public/apple-touch-icon.png -------------------------------------------------------------------------------- /16-react-fragment/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/16-react-fragment/public/favicon-16x16.png -------------------------------------------------------------------------------- /16-react-fragment/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/16-react-fragment/public/favicon-32x32.png -------------------------------------------------------------------------------- /16-react-fragment/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/16-react-fragment/public/favicon.ico -------------------------------------------------------------------------------- /16-react-fragment/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /16-react-fragment/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /16-react-fragment/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /16-react-fragment/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import Card from './components/Card'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /16-react-fragment/src/components/Card.js: -------------------------------------------------------------------------------- 1 | const Card = () => { 2 | return ( 3 | <> 4 |

Viktor

5 |

I am recording React course

6 | 7 | 8 | ); 9 | }; 10 | 11 | export default Card; 12 | -------------------------------------------------------------------------------- /16-react-fragment/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /16-react-fragment/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /17-uncontrolled-input/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /17-uncontrolled-input/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /17-uncontrolled-input/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/17-uncontrolled-input/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /17-uncontrolled-input/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/17-uncontrolled-input/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /17-uncontrolled-input/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/17-uncontrolled-input/public/apple-touch-icon.png -------------------------------------------------------------------------------- /17-uncontrolled-input/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/17-uncontrolled-input/public/favicon-16x16.png -------------------------------------------------------------------------------- /17-uncontrolled-input/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/17-uncontrolled-input/public/favicon-32x32.png -------------------------------------------------------------------------------- /17-uncontrolled-input/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/17-uncontrolled-input/public/favicon.ico -------------------------------------------------------------------------------- /17-uncontrolled-input/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /17-uncontrolled-input/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /17-uncontrolled-input/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | font-size: 70px; 7 | margin-top: 20px; 8 | } 9 | 10 | button { 11 | padding: 15px; 12 | font-size: 30px; 13 | border-radius: 5px; 14 | border: 0; 15 | margin: 20px; 16 | cursor: pointer; 17 | } 18 | 19 | form { 20 | font-size: 30px; 21 | } 22 | 23 | input { 24 | margin: 15px; 25 | padding: 10px; 26 | font-size: 20px; 27 | } 28 | 29 | label { 30 | display: block; 31 | } 32 | -------------------------------------------------------------------------------- /17-uncontrolled-input/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import Login from './components/Login'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /17-uncontrolled-input/src/components/Login.js: -------------------------------------------------------------------------------- 1 | function Login() { 2 | function handleFormSubmit(event) { 3 | event.preventDefault(); 4 | 5 | const userData = { 6 | username: event.target.username.value, 7 | password: event.target.password.value, 8 | }; 9 | 10 | console.log(userData); 11 | alert(JSON.stringify(userData)); 12 | } 13 | return ( 14 | <> 15 |

Login Form

16 |
17 | 21 | 25 | 26 |
27 | 28 | ); 29 | } 30 | 31 | export default Login; 32 | -------------------------------------------------------------------------------- /17-uncontrolled-input/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /17-uncontrolled-input/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /18-controlled-input/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /18-controlled-input/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /18-controlled-input/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/18-controlled-input/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /18-controlled-input/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/18-controlled-input/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /18-controlled-input/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/18-controlled-input/public/apple-touch-icon.png -------------------------------------------------------------------------------- /18-controlled-input/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/18-controlled-input/public/favicon-16x16.png -------------------------------------------------------------------------------- /18-controlled-input/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/18-controlled-input/public/favicon-32x32.png -------------------------------------------------------------------------------- /18-controlled-input/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/18-controlled-input/public/favicon.ico -------------------------------------------------------------------------------- /18-controlled-input/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /18-controlled-input/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /18-controlled-input/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | font-size: 70px; 7 | margin-top: 20px; 8 | } 9 | 10 | button { 11 | padding: 15px; 12 | font-size: 30px; 13 | border-radius: 5px; 14 | border: 0; 15 | margin: 20px; 16 | cursor: pointer; 17 | } 18 | 19 | form { 20 | font-size: 30px; 21 | } 22 | 23 | input { 24 | margin: 15px; 25 | padding: 10px; 26 | font-size: 20px; 27 | } 28 | 29 | label { 30 | display: block; 31 | } 32 | -------------------------------------------------------------------------------- /18-controlled-input/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import Login from './components/Login'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /18-controlled-input/src/components/Login.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | function Login() { 4 | // const [username, setUsername] = useState(''); 5 | // const [password, setPassword] = useState(''); 6 | 7 | const [data, setData] = useState({ username: '', password: '' }); 8 | 9 | function handleFormSubmit(event) { 10 | event.preventDefault(); 11 | console.log(data); 12 | alert(JSON.stringify(data)); 13 | } 14 | 15 | function handleInputChange(event, name) { 16 | setData({ ...data, [name]: event.target.value }); 17 | } 18 | 19 | return ( 20 | <> 21 |

Login Form

22 |
23 | 31 | 39 | 40 |
41 | 42 | ); 43 | } 44 | 45 | export default Login; 46 | -------------------------------------------------------------------------------- /18-controlled-input/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /18-controlled-input/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /19-children-prop/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /19-children-prop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /19-children-prop/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/19-children-prop/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /19-children-prop/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/19-children-prop/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /19-children-prop/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/19-children-prop/public/apple-touch-icon.png -------------------------------------------------------------------------------- /19-children-prop/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/19-children-prop/public/favicon-16x16.png -------------------------------------------------------------------------------- /19-children-prop/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/19-children-prop/public/favicon-32x32.png -------------------------------------------------------------------------------- /19-children-prop/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/19-children-prop/public/favicon.ico -------------------------------------------------------------------------------- /19-children-prop/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /19-children-prop/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /19-children-prop/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /19-children-prop/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import Wrapper from './components/Wrapper'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |

Hello World

9 | 10 |
11 | 12 |

Hello City

13 |

Some text

14 | 15 |
16 |
17 | ); 18 | } 19 | 20 | export default App; 21 | -------------------------------------------------------------------------------- /19-children-prop/src/components/Wrapper.js: -------------------------------------------------------------------------------- 1 | function Wrapper(props) { 2 | const style = { 3 | backgroundColor: props.color, 4 | width: '250px', 5 | padding: '20px', 6 | margin: '20px auto', 7 | }; 8 | 9 | return
{props.children}
; 10 | } 11 | 12 | export default Wrapper; 13 | -------------------------------------------------------------------------------- /19-children-prop/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /19-children-prop/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /20-useEffect/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /20-useEffect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /20-useEffect/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/20-useEffect/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /20-useEffect/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/20-useEffect/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /20-useEffect/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/20-useEffect/public/apple-touch-icon.png -------------------------------------------------------------------------------- /20-useEffect/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/20-useEffect/public/favicon-16x16.png -------------------------------------------------------------------------------- /20-useEffect/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/20-useEffect/public/favicon-32x32.png -------------------------------------------------------------------------------- /20-useEffect/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/20-useEffect/public/favicon.ico -------------------------------------------------------------------------------- /20-useEffect/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /20-useEffect/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /20-useEffect/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /20-useEffect/src/App.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | import './App.css'; 3 | 4 | function App() { 5 | const [todo, setTodo] = useState(null); 6 | 7 | useEffect(() => { 8 | fetch('https://jsonplaceholder.typicode.com/todos/5') 9 | .then(response => response.json()) 10 | .then(json => setTodo(json)); 11 | }, []); 12 | 13 | return ( 14 |
15 | {todo &&

{todo.title}

} 16 | {todo &&

{todo.id}

} 17 | {todo &&

{todo.userId}

} 18 |
19 | ); 20 | } 21 | 22 | export default App; 23 | -------------------------------------------------------------------------------- /20-useEffect/src/components/Post.js: -------------------------------------------------------------------------------- 1 | function Post() { 2 | return

This is post

; 3 | } 4 | 5 | export default Post; 6 | -------------------------------------------------------------------------------- /20-useEffect/src/components/Posts.js: -------------------------------------------------------------------------------- 1 | import Post from './Post'; 2 | 3 | function Posts() { 4 | return ( 5 |
6 | 7 | 8 | 9 |
10 | ); 11 | } 12 | 13 | export default Posts; 14 | -------------------------------------------------------------------------------- /20-useEffect/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /20-useEffect/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/21-jsonplaceholder-posts/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/21-jsonplaceholder-posts/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/21-jsonplaceholder-posts/public/apple-touch-icon.png -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/21-jsonplaceholder-posts/public/favicon-16x16.png -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/21-jsonplaceholder-posts/public/favicon-32x32.png -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/21-jsonplaceholder-posts/public/favicon.ico -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | text-align: center; 7 | } 8 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import Posts from './components/Posts'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/src/components/Post.css: -------------------------------------------------------------------------------- 1 | .post { 2 | max-width: 50%; 3 | margin: 25px auto; 4 | padding: 15px; 5 | border-radius: 15px; 6 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); 7 | } 8 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/src/components/Post.js: -------------------------------------------------------------------------------- 1 | import './Post.css'; 2 | 3 | function Post(props) { 4 | const { id, title, userId, body } = props; 5 | return ( 6 |
7 | {id} 8 |

{title}

9 |

{body}

10 |

User ID:{userId}

11 |
12 | ); 13 | } 14 | 15 | export default Post; 16 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/src/components/Posts.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | import Post from './Post'; 3 | 4 | function Posts() { 5 | const [posts, setPosts] = useState([]); 6 | const [error, setError] = useState(''); 7 | const [isLoading, setIsLoading] = useState(true); 8 | 9 | useEffect(() => { 10 | fetch('https://jsonplaceholder.typicode.com/posts') 11 | .then(response => response.json()) 12 | .then(posts => setPosts(posts)) 13 | .catch(error => setError(error.message)) 14 | .finally(() => setIsLoading(false)); 15 | }, []); 16 | 17 | if (error) { 18 | return

Error: {error}

; 19 | } 20 | 21 | return ( 22 | <> 23 |

Posts

24 |
25 | {isLoading ? ( 26 |

Loading...

27 | ) : ( 28 | posts.map(post => ) 29 | )} 30 | 31 | ); 32 | } 33 | 34 | export default Posts; 35 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /21-jsonplaceholder-posts/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /22-useEffect-async-await/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /22-useEffect-async-await/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /22-useEffect-async-await/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/22-useEffect-async-await/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /22-useEffect-async-await/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/22-useEffect-async-await/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /22-useEffect-async-await/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/22-useEffect-async-await/public/apple-touch-icon.png -------------------------------------------------------------------------------- /22-useEffect-async-await/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/22-useEffect-async-await/public/favicon-16x16.png -------------------------------------------------------------------------------- /22-useEffect-async-await/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/22-useEffect-async-await/public/favicon-32x32.png -------------------------------------------------------------------------------- /22-useEffect-async-await/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/22-useEffect-async-await/public/favicon.ico -------------------------------------------------------------------------------- /22-useEffect-async-await/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /22-useEffect-async-await/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /22-useEffect-async-await/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | text-align: center; 7 | } 8 | -------------------------------------------------------------------------------- /22-useEffect-async-await/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import Posts from './components/Posts'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /22-useEffect-async-await/src/components/Post.css: -------------------------------------------------------------------------------- 1 | .post { 2 | max-width: 50%; 3 | margin: 25px auto; 4 | padding: 15px; 5 | border-radius: 15px; 6 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); 7 | } 8 | -------------------------------------------------------------------------------- /22-useEffect-async-await/src/components/Post.js: -------------------------------------------------------------------------------- 1 | import './Post.css'; 2 | 3 | function Post(props) { 4 | const { id, title, userId, body } = props; 5 | return ( 6 |
7 | {id} 8 |

{title}

9 |

{body}

10 |

User ID:{userId}

11 |
12 | ); 13 | } 14 | 15 | export default Post; 16 | -------------------------------------------------------------------------------- /22-useEffect-async-await/src/components/Posts.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | import Post from './Post'; 3 | 4 | const API_URL = 'https://jsonplaceholder.typicode.com/posts'; 5 | 6 | function Posts() { 7 | const [posts, setPosts] = useState([]); 8 | const [error, setError] = useState(''); 9 | const [isLoading, setIsLoading] = useState(true); 10 | 11 | useEffect(() => { 12 | async function fetchData() { 13 | try { 14 | const res = await fetch(API_URL); 15 | const posts = await res.json(); 16 | setPosts(posts); 17 | } catch (error) { 18 | setError(error.message); 19 | } 20 | setIsLoading(false); 21 | } 22 | 23 | fetchData(); 24 | }, []); 25 | 26 | // useEffect(() => { 27 | // fetch('https://jsonplaceholder.typicode.com/posts') 28 | // .then(response => response.json()) 29 | // .then(posts => setPosts(posts)) 30 | // .catch(error => setError(error.message)) 31 | // .finally(() => setIsLoading(false)); 32 | // }, []); 33 | 34 | if (error) { 35 | return

Error: {error}

; 36 | } 37 | 38 | return ( 39 | <> 40 |

Posts

41 |
42 | {isLoading ? ( 43 |

Loading...

44 | ) : ( 45 | posts.map(post => ) 46 | )} 47 | 48 | ); 49 | } 50 | 51 | export default Posts; 52 | -------------------------------------------------------------------------------- /22-useEffect-async-await/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /22-useEffect-async-await/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /23-css-modules/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /23-css-modules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /23-css-modules/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/23-css-modules/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /23-css-modules/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/23-css-modules/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /23-css-modules/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/23-css-modules/public/apple-touch-icon.png -------------------------------------------------------------------------------- /23-css-modules/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/23-css-modules/public/favicon-16x16.png -------------------------------------------------------------------------------- /23-css-modules/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/23-css-modules/public/favicon-32x32.png -------------------------------------------------------------------------------- /23-css-modules/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/23-css-modules/public/favicon.ico -------------------------------------------------------------------------------- /23-css-modules/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /23-css-modules/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /23-css-modules/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /23-css-modules/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | import Info from './components/Info'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |

App component

9 |

App component

10 | 11 |
12 | ); 13 | } 14 | 15 | export default App; 16 | -------------------------------------------------------------------------------- /23-css-modules/src/components/Info.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | color: green; 3 | } 4 | 5 | .my-button { 6 | background-color: yellow; 7 | } 8 | -------------------------------------------------------------------------------- /23-css-modules/src/components/Info.js: -------------------------------------------------------------------------------- 1 | import './Info.css'; 2 | import styles from './info.module.css'; 3 | 4 | function Info() { 5 | return ( 6 |
7 |

Hello from the Info component!

8 |

Hello from the Info component!

9 | 10 |
11 | ); 12 | } 13 | 14 | export default Info; 15 | -------------------------------------------------------------------------------- /23-css-modules/src/components/info.module.css: -------------------------------------------------------------------------------- 1 | .info { 2 | border: 2px solid grey; 3 | border-radius: 10px; 4 | padding: 20px; 5 | max-width: 40%; 6 | margin: 20px auto; 7 | } 8 | 9 | h2 { 10 | color: blue; 11 | } 12 | -------------------------------------------------------------------------------- /23-css-modules/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /23-css-modules/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /24-todo-app-v1/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /24-todo-app-v1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-icons": "^5.3.0", 12 | "react-scripts": "5.0.1", 13 | "web-vitals": "^2.1.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /24-todo-app-v1/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/24-todo-app-v1/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /24-todo-app-v1/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/24-todo-app-v1/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /24-todo-app-v1/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/24-todo-app-v1/public/apple-touch-icon.png -------------------------------------------------------------------------------- /24-todo-app-v1/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/24-todo-app-v1/public/favicon-16x16.png -------------------------------------------------------------------------------- /24-todo-app-v1/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/24-todo-app-v1/public/favicon-32x32.png -------------------------------------------------------------------------------- /24-todo-app-v1/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/24-todo-app-v1/public/favicon.ico -------------------------------------------------------------------------------- /24-todo-app-v1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /24-todo-app-v1/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /24-todo-app-v1/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | max-width: 600px; 4 | margin: 0 auto; 5 | } 6 | 7 | h1 { 8 | font-size: 2.2rem; 9 | margin-bottom: 40px; 10 | margin-top: 24px; 11 | } 12 | -------------------------------------------------------------------------------- /24-todo-app-v1/src/App.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import TodoForm from './components/TodoForm/TodoForm'; 3 | import TodoList from './components/TodoList/TodoList'; 4 | import './App.css'; 5 | 6 | function App() { 7 | const [todos, setTodos] = useState([]); 8 | 9 | const addTodoHandler = text => { 10 | setTodos([...todos, text]); 11 | }; 12 | 13 | const deleteTodoHandler = index => { 14 | setTodos(todos.filter((_, idx) => idx !== index)); 15 | }; 16 | return ( 17 |
18 |

Todo App

19 | 20 | 21 |
22 | ); 23 | } 24 | 25 | export default App; 26 | -------------------------------------------------------------------------------- /24-todo-app-v1/src/components/Todo/Todo.js: -------------------------------------------------------------------------------- 1 | import { RiTodoFill } from 'react-icons/ri'; 2 | import styles from './Todo.module.css'; 3 | 4 | function Todo({ todo, index, deleteTodo }) { 5 | return ( 6 |
deleteTodo(index)}> 7 | 8 |
{todo}
9 |
10 | ); 11 | } 12 | 13 | export default Todo; 14 | -------------------------------------------------------------------------------- /24-todo-app-v1/src/components/Todo/Todo.module.css: -------------------------------------------------------------------------------- 1 | .todo { 2 | display: flex; 3 | align-items: center; 4 | padding: 10px 20px; 5 | margin: 15px 0; 6 | font-size: 1.5rem; 7 | border-radius: 5px; 8 | border: 2px solid #555; 9 | color: #112d49; 10 | background-color: #fbfef9; 11 | } 12 | 13 | .todoText { 14 | width: 100%; 15 | text-align: left; 16 | } 17 | 18 | .todoIcon { 19 | font-size: 1.8rem; 20 | margin-right: 10px; 21 | color: teal; 22 | } 23 | -------------------------------------------------------------------------------- /24-todo-app-v1/src/components/TodoForm/TodoForm.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import styles from './TodoForm.module.css'; 3 | 4 | function TodoForm({ addTodo }) { 5 | const [text, setText] = useState(''); 6 | const onSubmitHandler = event => { 7 | event.preventDefault(); 8 | addTodo(text); 9 | setText(''); 10 | }; 11 | return ( 12 |
13 |
14 | setText(e.target.value)} 17 | placeholder="Enter new todo" 18 | /> 19 | 20 |
21 |
22 | ); 23 | } 24 | 25 | export default TodoForm; 26 | -------------------------------------------------------------------------------- /24-todo-app-v1/src/components/TodoForm/TodoForm.module.css: -------------------------------------------------------------------------------- 1 | .todoFormContainer { 2 | margin-bottom: 30px; 3 | } 4 | 5 | .todoFormContainer form { 6 | display: flex; 7 | align-items: center; 8 | justify-content: center; 9 | } 10 | 11 | .todoFormContainer input { 12 | width: 45%; 13 | height: 30px; 14 | font-size: 1.3rem; 15 | } 16 | 17 | .todoFormContainer button { 18 | margin-left: 20px; 19 | height: 50px; 20 | cursor: pointer; 21 | background-color: beige; 22 | font-size: 1.5rem; 23 | } 24 | 25 | .todoFormContainer button:hover { 26 | background-color: rgb(240, 240, 155); 27 | } 28 | 29 | .todoFormContainer input, 30 | .todoFormContainer button { 31 | padding: 10px 15px; 32 | border: none; 33 | border-radius: 5px; 34 | } 35 | -------------------------------------------------------------------------------- /24-todo-app-v1/src/components/TodoList/TodoList.js: -------------------------------------------------------------------------------- 1 | import Todo from '../Todo/Todo'; 2 | import styles from './TodoList.module.css'; 3 | 4 | function TodoList({ todos, deleteTodo }) { 5 | return ( 6 |
7 | {!todos.length &&

Todo list is empty

} 8 | {todos.map((todo, index) => ( 9 | 10 | ))} 11 |
12 | ); 13 | } 14 | export default TodoList; 15 | -------------------------------------------------------------------------------- /24-todo-app-v1/src/components/TodoList/TodoList.module.css: -------------------------------------------------------------------------------- 1 | .todoListContainer { 2 | padding: 10px; 3 | } 4 | -------------------------------------------------------------------------------- /24-todo-app-v1/src/components/UI/Button.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/24-todo-app-v1/src/components/UI/Button.js -------------------------------------------------------------------------------- /24-todo-app-v1/src/components/UI/Button.module.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/24-todo-app-v1/src/components/UI/Button.module.css -------------------------------------------------------------------------------- /24-todo-app-v1/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /24-todo-app-v1/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /25-todo-app-v2/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /25-todo-app-v2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-icons": "^5.3.0", 12 | "react-scripts": "5.0.1", 13 | "uuid": "^10.0.0", 14 | "web-vitals": "^2.1.4" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /25-todo-app-v2/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/25-todo-app-v2/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /25-todo-app-v2/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/25-todo-app-v2/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /25-todo-app-v2/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/25-todo-app-v2/public/apple-touch-icon.png -------------------------------------------------------------------------------- /25-todo-app-v2/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/25-todo-app-v2/public/favicon-16x16.png -------------------------------------------------------------------------------- /25-todo-app-v2/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/25-todo-app-v2/public/favicon-32x32.png -------------------------------------------------------------------------------- /25-todo-app-v2/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/25-todo-app-v2/public/favicon.ico -------------------------------------------------------------------------------- /25-todo-app-v2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /25-todo-app-v2/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /25-todo-app-v2/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | max-width: 600px; 4 | margin: 0 auto; 5 | } 6 | 7 | h1 { 8 | font-size: 2.2rem; 9 | margin-bottom: 40px; 10 | margin-top: 24px; 11 | } 12 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/Todo/Todo.js: -------------------------------------------------------------------------------- 1 | import { RiTodoFill, RiDeleteBin2Line } from 'react-icons/ri'; 2 | import { FaCheck } from 'react-icons/fa'; 3 | import styles from './Todo.module.css'; 4 | 5 | function Todo({ todo, deleteTodo, toggleTodo }) { 6 | return ( 7 |
12 | 13 |
{todo.text}
14 | deleteTodo(todo.id)} 17 | /> 18 | toggleTodo(todo.id)} 21 | /> 22 |
23 | ); 24 | } 25 | 26 | export default Todo; 27 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/Todo/Todo.module.css: -------------------------------------------------------------------------------- 1 | .todo { 2 | display: flex; 3 | align-items: center; 4 | padding: 10px 20px; 5 | margin: 15px 0; 6 | font-size: 1.5rem; 7 | border-radius: 5px; 8 | border: 2px solid #555; 9 | color: #112d49; 10 | background-color: #fbfef9; 11 | } 12 | 13 | .todoText { 14 | width: 100%; 15 | text-align: left; 16 | } 17 | 18 | .todoIcon { 19 | font-size: 1.8rem; 20 | margin-right: 10px; 21 | color: teal; 22 | } 23 | 24 | .completedTodo { 25 | background-color: unset; 26 | border-color: gray; 27 | color: gray; 28 | } 29 | 30 | .todo.completedTodo .todoIcon, 31 | .todo.completedTodo .checkIcon, 32 | .todo.completedTodo .deleteIcon { 33 | color: gray; 34 | } 35 | 36 | .checkIcon, 37 | .deleteIcon { 38 | cursor: pointer; 39 | color: lightgrey; 40 | padding: 0 7px; 41 | font-size: 1.8rem; 42 | transition: transform 0.3s; 43 | } 44 | 45 | .checkIcon:hover, 46 | .deleteIcon:hover { 47 | cursor: pointer; 48 | transform: scale(1.3); 49 | } 50 | 51 | .checkIcon:hover { 52 | color: green; 53 | } 54 | 55 | .deleteIcon:hover { 56 | color: red; 57 | } 58 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/TodoForm/TodoForm.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import styles from './TodoForm.module.css'; 3 | import Button from '../UI/Button'; 4 | 5 | function TodoForm({ addTodo }) { 6 | const [text, setText] = useState(''); 7 | const onSubmitHandler = event => { 8 | event.preventDefault(); 9 | addTodo(text); 10 | setText(''); 11 | }; 12 | return ( 13 |
14 |
15 | setText(e.target.value)} 18 | placeholder="Enter new todo" 19 | /> 20 | 23 |
24 |
25 | ); 26 | } 27 | 28 | export default TodoForm; 29 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/TodoForm/TodoForm.module.css: -------------------------------------------------------------------------------- 1 | .todoFormContainer { 2 | margin-bottom: 30px; 3 | } 4 | 5 | .todoFormContainer form { 6 | display: flex; 7 | align-items: center; 8 | justify-content: center; 9 | } 10 | 11 | .todoFormContainer input { 12 | width: 45%; 13 | height: 30px; 14 | font-size: 1.3rem; 15 | padding: 10px 15px; 16 | border: none; 17 | border-radius: 5px; 18 | } 19 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/TodoList/TodoList.js: -------------------------------------------------------------------------------- 1 | import Todo from '../Todo/Todo'; 2 | import styles from './TodoList.module.css'; 3 | 4 | function TodoList({ todos, deleteTodo, toggleTodo }) { 5 | return ( 6 |
7 | {!todos.length &&

Todo list is empty

} 8 | {todos.map(todo => ( 9 | 15 | ))} 16 |
17 | ); 18 | } 19 | export default TodoList; 20 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/TodoList/TodoList.module.css: -------------------------------------------------------------------------------- 1 | .todoListContainer { 2 | padding: 10px; 3 | } 4 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/TodosActions/TodosActions.js: -------------------------------------------------------------------------------- 1 | import { RiDeleteBin2Line, RiRefreshLine } from 'react-icons/ri'; 2 | import Button from '../UI/Button'; 3 | import styles from './TodosActions.module.css'; 4 | 5 | function TodosActions({ 6 | resetTodos, 7 | deleteCompletedTodos, 8 | completedTodosExist, 9 | }) { 10 | return ( 11 |
12 | 15 | 22 |
23 | ); 24 | } 25 | 26 | export default TodosActions; 27 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/TodosActions/TodosActions.module.css: -------------------------------------------------------------------------------- 1 | .todosActionContainer { 2 | margin: 5px; 3 | } 4 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/UI/Button.js: -------------------------------------------------------------------------------- 1 | import styles from './Button.module.css'; 2 | 3 | function Button(props) { 4 | const { onClick, children, title, disabled = false } = props; 5 | return ( 6 | 15 | ); 16 | } 17 | 18 | export default Button; 19 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/components/UI/Button.module.css: -------------------------------------------------------------------------------- 1 | .btn { 2 | margin-left: 20px; 3 | height: 50px; 4 | cursor: pointer; 5 | background-color: beige; 6 | font-size: 1.5rem; 7 | padding: 10px 15px; 8 | border: none; 9 | border-radius: 5px; 10 | } 11 | 12 | .btn:hover { 13 | background-color: rgb(240, 240, 155); 14 | } 15 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /25-todo-app-v2/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /26-react-router/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /26-react-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-router-dom": "^6.26.1", 12 | "react-scripts": "5.0.1", 13 | "web-vitals": "^2.1.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /26-react-router/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/26-react-router/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /26-react-router/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/26-react-router/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /26-react-router/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/26-react-router/public/apple-touch-icon.png -------------------------------------------------------------------------------- /26-react-router/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/26-react-router/public/favicon-16x16.png -------------------------------------------------------------------------------- /26-react-router/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/26-react-router/public/favicon-32x32.png -------------------------------------------------------------------------------- /26-react-router/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/26-react-router/public/favicon.ico -------------------------------------------------------------------------------- /26-react-router/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /26-react-router/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /26-react-router/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .active { 6 | color: yellow; 7 | } 8 | 9 | .courseLink { 10 | font-size: 25px; 11 | } 12 | 13 | .courseLink:hover { 14 | text-decoration: underline; 15 | } 16 | 17 | a { 18 | color: wheat; 19 | font-size: 35px; 20 | text-decoration: none; 21 | } 22 | 23 | nav { 24 | background-color: darkcyan; 25 | padding: 15px; 26 | } 27 | 28 | nav a { 29 | margin: 15px; 30 | } 31 | 32 | h1 { 33 | font-size: 90px; 34 | margin-top: 20px; 35 | } 36 | 37 | button { 38 | padding: 15px; 39 | font-size: 30px; 40 | border-radius: 5px; 41 | border: 0; 42 | margin: 20px; 43 | cursor: pointer; 44 | } 45 | -------------------------------------------------------------------------------- /26-react-router/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { BrowserRouter, Route, Routes } from 'react-router-dom'; 2 | import './App.css'; 3 | import Home from './components/Home'; 4 | import About from './components/About'; 5 | import Contacts from './components/Contacts'; 6 | import Courses from './components/Courses'; 7 | import SingleCourse from './components/SingleCourse'; 8 | import NotFound from './components/NotFound'; 9 | import MainLayout from './layouts/MainLayout'; 10 | 11 | function App() { 12 | return ( 13 | 14 |
15 | 16 | }> 17 | } /> 18 | } /> 19 | } /> 20 | } /> 21 | } /> 22 | } /> 23 | 24 | 25 |
26 |
27 | ); 28 | } 29 | 30 | export default App; 31 | -------------------------------------------------------------------------------- /26-react-router/src/components/About.jsx: -------------------------------------------------------------------------------- 1 | function About() { 2 | return

About

; 3 | } 4 | 5 | export default About; 6 | -------------------------------------------------------------------------------- /26-react-router/src/components/Contacts.jsx: -------------------------------------------------------------------------------- 1 | function Contacts() { 2 | return

Contacts

; 3 | } 4 | 5 | export default Contacts; 6 | -------------------------------------------------------------------------------- /26-react-router/src/components/Courses.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from 'react-router-dom'; 2 | import courses from '../data/courses'; 3 | 4 | function Courses() { 5 | return ( 6 | <> 7 |

Courses

8 | {courses.map(course => { 9 | return ( 10 |
11 | 12 | {course.title} 13 | 14 |
15 | ); 16 | })} 17 | 18 | ); 19 | } 20 | 21 | export default Courses; 22 | -------------------------------------------------------------------------------- /26-react-router/src/components/Home.jsx: -------------------------------------------------------------------------------- 1 | function Home() { 2 | return

Home

; 3 | } 4 | 5 | export default Home; 6 | -------------------------------------------------------------------------------- /26-react-router/src/components/Menu.jsx: -------------------------------------------------------------------------------- 1 | import { NavLink } from 'react-router-dom'; 2 | 3 | function Menu() { 4 | return ( 5 | 11 | ); 12 | } 13 | 14 | export default Menu; 15 | -------------------------------------------------------------------------------- /26-react-router/src/components/NotFound.jsx: -------------------------------------------------------------------------------- 1 | function NotFound() { 2 | return

Not Found

; 3 | } 4 | 5 | export default NotFound; 6 | -------------------------------------------------------------------------------- /26-react-router/src/components/SingleCourse.jsx: -------------------------------------------------------------------------------- 1 | import { Link, useParams } from 'react-router-dom'; 2 | import courses from '../data/courses'; 3 | import NotFound from './NotFound'; 4 | // import { useEffect } from 'react'; 5 | // import { useNavigate } from 'react-router-dom'; 6 | 7 | function SingleCourse() { 8 | const params = useParams(); 9 | const course = courses.find(course => course.slug === params.slug); 10 | if (!course) { 11 | return ; 12 | } 13 | 14 | // const navigate = useNavigate(); 15 | 16 | // useEffect(() => { 17 | // if (!course) { 18 | // navigate('..', { relative: 'path' }); 19 | // } 20 | // }, [course, navigate]); 21 | 22 | // return ( 23 | // <> 24 | //

{course?.title}

25 | //

{course?.slug}

26 | //

{course?.id}

27 | // 28 | // All courses 29 | // 30 | // 31 | // ); 32 | 33 | return ( 34 | <> 35 |

{course.title}

36 |

{course.slug}

37 |

{course.id}

38 | 39 | All courses 40 | 41 | 42 | ); 43 | } 44 | 45 | export default SingleCourse; 46 | -------------------------------------------------------------------------------- /26-react-router/src/data/courses.js: -------------------------------------------------------------------------------- 1 | const courses = [ 2 | { 3 | title: 'Complete React Guide', 4 | slug: 'react', 5 | id: 257, 6 | }, 7 | { 8 | title: 'Complete JavaScript Guide', 9 | slug: 'javascript', 10 | id: 345, 11 | }, 12 | { 13 | title: 'Complete Python Guide', 14 | slug: 'python', 15 | id: 498, 16 | }, 17 | { 18 | title: 'Complete Node.js Guide', 19 | slug: 'node-js', 20 | id: 516, 21 | }, 22 | ]; 23 | 24 | export default courses; 25 | -------------------------------------------------------------------------------- /26-react-router/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /26-react-router/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /26-react-router/src/layouts/MainLayout.jsx: -------------------------------------------------------------------------------- 1 | import { Outlet } from 'react-router-dom'; 2 | import Menu from '../components/Menu'; 3 | 4 | function MainLayout() { 5 | return ( 6 | <> 7 | 8 | 9 | 10 | ); 11 | } 12 | 13 | export default MainLayout; 14 | -------------------------------------------------------------------------------- /27-context-api/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /27-context-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "00-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /27-context-api/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/27-context-api/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /27-context-api/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/27-context-api/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /27-context-api/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/27-context-api/public/apple-touch-icon.png -------------------------------------------------------------------------------- /27-context-api/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/27-context-api/public/favicon-16x16.png -------------------------------------------------------------------------------- /27-context-api/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/27-context-api/public/favicon-32x32.png -------------------------------------------------------------------------------- /27-context-api/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/27-context-api/public/favicon.ico -------------------------------------------------------------------------------- /27-context-api/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /27-context-api/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /27-context-api/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | h1 { 6 | font-size: 90px; 7 | margin-top: 20px; 8 | } 9 | 10 | button { 11 | padding: 15px; 12 | font-size: 30px; 13 | border-radius: 5px; 14 | border: 0; 15 | margin: 20px; 16 | cursor: pointer; 17 | } 18 | -------------------------------------------------------------------------------- /27-context-api/src/App.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import './App.css'; 3 | import User from './components/User'; 4 | import UserContext from './context/UserContext'; 5 | import ChangeUser from './components/ChangeUser'; 6 | 7 | function App() { 8 | const [user, setUser] = useState('Evan'); 9 | 10 | return ( 11 | 12 |
13 | 14 | 15 |
16 |
17 | ); 18 | } 19 | 20 | export default App; 21 | -------------------------------------------------------------------------------- /27-context-api/src/components/ChangeUser.jsx: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import UserContext from '../context/UserContext'; 3 | 4 | function ChangeUser() { 5 | const { user, setUser } = useContext(UserContext); 6 | return ( 7 | 10 | ); 11 | } 12 | 13 | export default ChangeUser; 14 | -------------------------------------------------------------------------------- /27-context-api/src/components/User.jsx: -------------------------------------------------------------------------------- 1 | import UserInfo from './UserInfo'; 2 | 3 | function User() { 4 | return ; 5 | } 6 | 7 | export default User; 8 | -------------------------------------------------------------------------------- /27-context-api/src/components/UserInfo.jsx: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import UserContext from '../context/UserContext'; 3 | 4 | function UserInfo() { 5 | const { user } = useContext(UserContext); 6 | 7 | return

{user}

; 8 | } 9 | 10 | export default UserInfo; 11 | -------------------------------------------------------------------------------- /27-context-api/src/context/UserContext.js: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | const UserContext = createContext({ 4 | user: '', 5 | setUser: () => {}, 6 | }); 7 | 8 | export default UserContext; 9 | -------------------------------------------------------------------------------- /27-context-api/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | font-family: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 8 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 9 | 10 | color: white; 11 | background-color: #112d49; 12 | } 13 | -------------------------------------------------------------------------------- /27-context-api/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /28-reducer/reducer.js: -------------------------------------------------------------------------------- 1 | const initialState = []; 2 | 3 | function reducer(state, action) { 4 | switch (action.type) { 5 | case 'ADD_NAME': 6 | return [...state, action.payload]; 7 | 8 | case 'DELETE_NAME': 9 | return state.filter(personName => personName !== action.payload); 10 | 11 | case 'CLEAR_NAMES': 12 | return []; 13 | 14 | default: 15 | return state; 16 | } 17 | // if (action.type === 'ADD_NAME') { 18 | // return [...state, action.payload]; 19 | // } 20 | 21 | // if (action.type === 'DELETE_NAME') { 22 | // return state.filter(personName => personName !== action.payload); 23 | // } 24 | 25 | // if (action.type === 'CLEAR_NAMES') { 26 | // return []; 27 | // } 28 | 29 | // return state; 30 | } 31 | 32 | let newState = reducer(initialState, { type: 'ADD_NAME', payload: 'Alice' }); 33 | console.log(newState); 34 | 35 | newState = reducer(newState, { type: 'ADD_NAME', payload: 'Evan' }); 36 | console.log(newState); 37 | 38 | newState = reducer(newState, { type: 'ADD_NAME', payload: 'Inna' }); 39 | console.log(newState); 40 | 41 | newState = reducer(newState, { type: 'DELETE_NAME', payload: 'Inna' }); 42 | console.log(newState); 43 | 44 | newState = reducer(newState, { type: 'CLEAR_NAMES' }); 45 | console.log(newState); 46 | 47 | newState = reducer(newState, { type: 'ADD_NAME', payload: 'Evan' }); 48 | console.log(newState); 49 | 50 | newState = reducer(newState, { type: 'ADD_NAME', payload: 'Alice' }); 51 | console.log(newState); 52 | 53 | newState = reducer(newState, { type: 'ADD_NAME', payload: 'Inna' }); 54 | console.log(newState); 55 | -------------------------------------------------------------------------------- /29-pure-redux/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pure Redux 7 | 8 | 9 | 10 |

Pure Redux

11 | 12 | 13 |
    14 | 15 | 16 | -------------------------------------------------------------------------------- /29-pure-redux/index.js: -------------------------------------------------------------------------------- 1 | import store from './redux/store.js'; 2 | import getCurrentTime from './utils/getCurrentTime.js'; 3 | 4 | const addTimeBtn = document.getElementById('addTime'); 5 | addTimeBtn.addEventListener('click', () => { 6 | store.dispatch({ 7 | type: 'ADD_CURRENT_TIME', 8 | payload: getCurrentTime(), 9 | }); 10 | }); 11 | 12 | const clearTimeBtn = document.getElementById('clearTimes'); 13 | clearTimeBtn.addEventListener('click', () => { 14 | store.dispatch({ 15 | type: 'CLEAR_ALL_TIMES', 16 | }); 17 | }); 18 | 19 | const timesList = document.getElementById('timesList'); 20 | 21 | store.subscribe(() => { 22 | timesList.innerHTML = ''; 23 | const times = store.getState(); 24 | times.forEach(time => { 25 | let li = document.createElement('li'); 26 | li.innerText = time; 27 | timesList.appendChild(li); 28 | }); 29 | }); 30 | 31 | // store.subscribe(() => 32 | // console.log(`Redux store just changed! ${store.getState()}`), 33 | // ); 34 | 35 | // store.dispatch({ 36 | // type: 'ADD_CURRENT_TIME', 37 | // payload: '11:30:00', 38 | // }); 39 | 40 | // store.dispatch({ 41 | // type: 'ADD_CURRENT_TIME', 42 | // payload: '11:32:00', 43 | // }); 44 | 45 | // store.dispatch({ 46 | // type: 'CLEAR_ALL_TIMES', 47 | // }); 48 | -------------------------------------------------------------------------------- /29-pure-redux/redux/reducer.js: -------------------------------------------------------------------------------- 1 | const initialState = []; 2 | 3 | function reducer(state = initialState, action) { 4 | switch (action.type) { 5 | case 'ADD_CURRENT_TIME': 6 | return [...state, action.payload]; 7 | 8 | case 'CLEAR_ALL_TIMES': 9 | return []; 10 | 11 | default: 12 | return state; 13 | } 14 | } 15 | 16 | export default reducer; 17 | -------------------------------------------------------------------------------- /29-pure-redux/redux/store.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from 'https://cdn.jsdelivr.net/npm/@reduxjs/toolkit@2.2.7/+esm'; 2 | import reducer from './reducer.js'; 3 | 4 | export default configureStore({ 5 | reducer: reducer, 6 | }); 7 | -------------------------------------------------------------------------------- /29-pure-redux/utils/getCurrentTime.js: -------------------------------------------------------------------------------- 1 | function getCurrentTime() { 2 | const now = new Date(); 3 | const hours = now.getHours().toString().padStart(2, '0'); 4 | const minutes = now.getMinutes().toString().padStart(2, '0'); 5 | const seconds = now.getSeconds().toString().padStart(2, '0'); 6 | 7 | const currentTime = `${hours}:${minutes}:${seconds}`; 8 | 9 | return currentTime; 10 | } 11 | 12 | export default getCurrentTime; 13 | -------------------------------------------------------------------------------- /30-react-redux/api/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /30-react-redux/api/README.md: -------------------------------------------------------------------------------- 1 | # Book Library App API 2 | -------------------------------------------------------------------------------- /30-react-redux/api/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const cors = require('cors'); 3 | const booksData = require('./data/books.json'); // Import the book data 4 | 5 | const app = express(); 6 | 7 | app.use(cors()); 8 | 9 | function getRandomBook() { 10 | const randomIndex = Math.floor(Math.random() * booksData.length); 11 | const randomBook = booksData[randomIndex]; 12 | return randomBook; 13 | } 14 | 15 | app.get('/random-book', (req, res) => { 16 | res.json(getRandomBook()); // http://localhost:4000/random-book 17 | }); 18 | 19 | app.get('/random-book-delayed', (req, res) => { 20 | setTimeout(() => { 21 | res.json(getRandomBook()); // http://localhost:4000/random-book-delayed 22 | }, 2000); 23 | }); 24 | 25 | const port = process.env.PORT || 4000; 26 | app.listen(port, () => { 27 | console.log(`Server is running on port ${port}`); 28 | }); 29 | -------------------------------------------------------------------------------- /30-react-redux/api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "dev": "nodemon index.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "cors": "^2.8.5", 15 | "express": "^4.21.0", 16 | "nodemon": "^3.1.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /30-react-redux/api/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "builds": [ 4 | { 5 | "src": "*.js", 6 | "use": "@vercel/node" 7 | } 8 | ], 9 | "routes": [ 10 | { 11 | "src": "/(.*)", 12 | "dest": "/" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /30-react-redux/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /30-react-redux/frontend/README.md: -------------------------------------------------------------------------------- 1 | # Book Library App 2 | -------------------------------------------------------------------------------- /30-react-redux/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@reduxjs/toolkit": "^1.9.5", 7 | "@testing-library/jest-dom": "^5.17.0", 8 | "@testing-library/react": "^13.4.0", 9 | "@testing-library/user-event": "^13.5.0", 10 | "axios": "^1.7.7", 11 | "react": "^18.3.1", 12 | "react-dom": "^18.3.1", 13 | "react-icons": "^5.3.0", 14 | "react-redux": "^8.1.2", 15 | "react-scripts": "5.0.1", 16 | "react-toastify": "^10.0.5", 17 | "uuid": "^10.0.0", 18 | "web-vitals": "^2.1.4" 19 | }, 20 | "scripts": { 21 | "start": "react-scripts start", 22 | "build": "react-scripts build", 23 | "test": "react-scripts test", 24 | "eject": "react-scripts eject" 25 | }, 26 | "eslintConfig": { 27 | "extends": [ 28 | "react-app", 29 | "react-app/jest" 30 | ] 31 | }, 32 | "browserslist": { 33 | "production": [ 34 | ">0.2%", 35 | "not dead", 36 | "not op_mini all" 37 | ], 38 | "development": [ 39 | "last 1 chrome version", 40 | "last 1 firefox version", 41 | "last 1 safari version" 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /30-react-redux/frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/30-react-redux/frontend/public/favicon.ico -------------------------------------------------------------------------------- /30-react-redux/frontend/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/30-react-redux/frontend/public/logo192.png -------------------------------------------------------------------------------- /30-react-redux/frontend/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ViktorSvertoka/react-projects/ef2eb68efe92058abd5d5ba8b40cf5547446de46/30-react-redux/frontend/public/logo512.png -------------------------------------------------------------------------------- /30-react-redux/frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /30-react-redux/frontend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/App.css: -------------------------------------------------------------------------------- 1 | .app { 2 | display: flex; 3 | flex-direction: column; 4 | align-items: center; 5 | justify-content: center; 6 | text-align: center; 7 | } 8 | 9 | .app-header { 10 | background-color: #0a1a2d; 11 | color: #fff; 12 | width: 100%; 13 | margin-bottom: 20px; 14 | } 15 | 16 | .app-main { 17 | display: flex; 18 | justify-content: space-between; 19 | width: 80%; 20 | margin: 0 auto; 21 | } 22 | 23 | .app-left-column { 24 | flex: 1; 25 | flex-basis: 35%; 26 | display: flex; 27 | align-items: center; 28 | align-self: flex-start; 29 | } 30 | 31 | .app-right-column { 32 | flex: 1; 33 | flex-basis: 65%; 34 | display: flex; 35 | flex-direction: column; 36 | } 37 | 38 | .app-block { 39 | padding: 20px; 40 | margin: 20px; 41 | background-color: #f2f2f2; 42 | border-radius: 5px; 43 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 44 | } 45 | 46 | @media (max-width: 1024px) { 47 | .app-main { 48 | width: 100%; 49 | flex-direction: column; 50 | } 51 | 52 | .app-left-column, 53 | .app-right-column { 54 | flex-basis: 100%; 55 | align-self: unset; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/App.js: -------------------------------------------------------------------------------- 1 | import BookList from './components/BookList/BookList'; 2 | import BookForm from './components/BookForm/BookForm'; 3 | import Filter from './components/Filter/Filter'; 4 | import Error from './components/Error/Error'; 5 | import './App.css'; 6 | 7 | function App() { 8 | return ( 9 |
    10 |
    11 |

    Book Library App

    12 |
    13 |
    14 |
    15 | 16 |
    17 |
    18 | 19 | 20 |
    21 |
    22 | 23 |
    24 | ); 25 | } 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/components/BookForm/BookForm.css: -------------------------------------------------------------------------------- 1 | .book-form { 2 | width: 100%; 3 | } 4 | 5 | .book-form label { 6 | display: block; 7 | width: 100%; 8 | text-align: center; 9 | margin-bottom: 10px; 10 | } 11 | 12 | .book-form input { 13 | width: 80%; 14 | padding: 8px; 15 | margin-bottom: 10px; 16 | border: 1px solid #ccc; 17 | border-radius: 3px; 18 | } 19 | 20 | .book-form button { 21 | background-color: #007bff; 22 | color: #fff; 23 | padding: 8px 12px; 24 | border: none; 25 | border-radius: 3px; 26 | cursor: pointer; 27 | margin: 10px; 28 | transition: background-color 0.3s ease; 29 | } 30 | 31 | .book-form button:hover { 32 | background-color: #0056b3; 33 | } 34 | 35 | .book-form .spinner { 36 | animation: spinner 1s infinite linear; 37 | margin-left: 10px; 38 | } 39 | 40 | @keyframes spinner { 41 | from { 42 | transform: rotate(0deg); 43 | } 44 | 45 | to { 46 | transform: rotate(360deg); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/components/BookList/BookList.css: -------------------------------------------------------------------------------- 1 | .book-list ul { 2 | padding: 0; 3 | margin: 20px -20px; 4 | list-style: none; 5 | } 6 | 7 | .book-list li { 8 | display: flex; 9 | justify-content: space-between; 10 | align-items: center; 11 | width: auto; 12 | padding: 10px 20px; 13 | border-bottom: 1px solid #ccc; 14 | background-color: #fff; 15 | list-style-type: none; 16 | } 17 | 18 | .book-list li:nth-child(even) { 19 | background-color: #f2f2f2; 20 | } 21 | 22 | .book-list li:hover { 23 | background-color: #dbe4f8; 24 | } 25 | 26 | .book-list button { 27 | background-color: #fff; 28 | color: red; 29 | border: 1px solid red; 30 | padding: 8px 12px; 31 | border-radius: 3px; 32 | cursor: pointer; 33 | transition: background-color 0.3s ease; 34 | } 35 | 36 | .book-list button:hover { 37 | background-color: #fdd; 38 | } 39 | 40 | .book-list .highlight { 41 | background-color: #ff0; 42 | } 43 | 44 | .book-list .book-info { 45 | flex: 1; 46 | text-align: left; 47 | } 48 | 49 | .book-list .book-actions { 50 | display: flex; 51 | align-items: center; 52 | } 53 | 54 | .book-list .star-icon { 55 | width: 24px; 56 | height: 24px; 57 | margin: 0 20px; 58 | cursor: pointer; 59 | transition: color 0.3s ease; 60 | color: #fca510; 61 | } 62 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/components/Error/Error.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { ToastContainer, toast } from 'react-toastify'; 3 | import { useSelector, useDispatch } from 'react-redux'; 4 | import 'react-toastify/dist/ReactToastify.css'; 5 | import { clearError, selectErrorMessage } from '../../redux/slices/errorSlice'; 6 | 7 | const Error = () => { 8 | const errorMessage = useSelector(selectErrorMessage); 9 | const dispatch = useDispatch(); 10 | 11 | useEffect(() => { 12 | if (errorMessage) { 13 | toast.info(errorMessage); 14 | dispatch(clearError()); 15 | } 16 | }, [errorMessage, dispatch]); 17 | return ; 18 | }; 19 | 20 | export default Error; 21 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/components/Filter/Filter.css: -------------------------------------------------------------------------------- 1 | .filter-row { 2 | display: flex; 3 | justify-content: space-between; 4 | align-items: center; 5 | } 6 | 7 | .filter-group { 8 | flex: 1; 9 | text-align: center; 10 | } 11 | 12 | .filter input[type='text'] { 13 | width: 80%; 14 | padding: 8px; 15 | border: 1px solid #ccc; 16 | border-radius: 3px; 17 | } 18 | 19 | .filter button { 20 | background-color: #007bff; 21 | color: #fff; 22 | padding: 8px 12px; 23 | border: none; 24 | border-radius: 3px; 25 | cursor: pointer; 26 | margin: 10px; 27 | transition: background-color 0.3s ease; 28 | } 29 | 30 | .filter button:hover { 31 | background-color: #0056b3; 32 | } 33 | 34 | @media screen and (max-width: 1024px) { 35 | .filter-row { 36 | flex-direction: column; 37 | align-items: stretch; 38 | } 39 | 40 | .filter-group { 41 | width: 100%; 42 | margin: auto; 43 | margin-bottom: 10px; 44 | } 45 | 46 | .filter button { 47 | margin: 10px auto 0; 48 | max-width: 50%; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 4 | 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 5 | 'Helvetica Neue', sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | background-color: #112d49; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Provider } from 'react-redux'; 3 | import ReactDOM from 'react-dom/client'; 4 | import store from './redux/store'; 5 | import './index.css'; 6 | import App from './App'; 7 | 8 | const root = ReactDOM.createRoot(document.getElementById('root')); 9 | root.render( 10 | 11 | 12 | , 13 | ); 14 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/redux/slices/errorSlice.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const initialState = ''; 4 | 5 | const errorSlice = createSlice({ 6 | name: 'error', 7 | initialState, 8 | reducers: { 9 | setError: (state, action) => { 10 | return action.payload; 11 | }, 12 | clearError: () => { 13 | return initialState; 14 | }, 15 | }, 16 | }); 17 | 18 | export const { setError, clearError } = errorSlice.actions; 19 | 20 | export const selectErrorMessage = state => state.error; 21 | 22 | export default errorSlice.reducer; 23 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/redux/slices/filterSlice.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const initialState = { 4 | title: '', 5 | author: '', 6 | onlyFavorite: false, 7 | }; 8 | 9 | const filterSlice = createSlice({ 10 | name: 'filter', 11 | initialState, 12 | reducers: { 13 | setTitleFilter: (state, action) => { 14 | state.title = action.payload; 15 | }, 16 | setAuthorFilter: (state, action) => { 17 | state.author = action.payload; 18 | }, 19 | setOnlyFavoriteFilter: state => { 20 | state.onlyFavorite = !state.onlyFavorite; 21 | }, 22 | resetFilters: () => { 23 | return initialState; 24 | }, 25 | }, 26 | }); 27 | 28 | export const { 29 | setTitleFilter, 30 | setAuthorFilter, 31 | setOnlyFavoriteFilter, 32 | resetFilters, 33 | } = filterSlice.actions; 34 | 35 | export const selectTitleFilter = state => state.filter.title; 36 | export const selectAuthorFilter = state => state.filter.author; 37 | export const selectOnlyFavoriteFilter = state => state.filter.onlyFavorite; 38 | 39 | export default filterSlice.reducer; 40 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/redux/store.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from '@reduxjs/toolkit'; 2 | import booksReducer from './slices/booksSlice'; 3 | import filterReducer from './slices/filterSlice'; 4 | import errorReducer from './slices/errorSlice'; 5 | 6 | const store = configureStore({ 7 | reducer: { 8 | books: booksReducer, 9 | filter: filterReducer, 10 | error: errorReducer, 11 | }, 12 | }); 13 | 14 | export default store; 15 | -------------------------------------------------------------------------------- /30-react-redux/frontend/src/utils/createBookWithID.js: -------------------------------------------------------------------------------- 1 | import { v4 as uuidv4 } from 'uuid'; 2 | 3 | const createBookWithID = (book, source) => { 4 | return { 5 | ...book, 6 | source, 7 | isFavorite: false, 8 | id: uuidv4(), 9 | }; 10 | }; 11 | 12 | export default createBookWithID; 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Udemy Course 2 | --------------------------------------------------------------------------------