├── .gitignore
├── .vscode
└── settings.json
├── README.md
├── assets
├── custom-hooks-background.png
├── custom-hooks.png
├── ecosystem.svg
├── github-actions.png
├── github-cicd-background.html
├── nextjs-1.png
├── nextjs-2.png
├── nextjs-thumb.png
├── react-2022.png
├── redux-background.png
├── storybook.jpeg
└── testing-background.jpeg
├── w1
├── 1.typescript-intro
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ ├── README.md
│ │ └── src
│ │ │ ├── 1.ts
│ │ │ ├── 2.ts
│ │ │ ├── 3.ts
│ │ │ ├── 4.ts
│ │ │ └── 5.ts
│ ├── 3.live
│ │ └── README.md
│ ├── 4.assignment
│ │ ├── README.md
│ │ └── src
│ │ │ ├── 1.ts
│ │ │ ├── 2.ts
│ │ │ └── 3.ts
│ └── README.md
├── 2.typescript-advance
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ ├── README.md
│ │ └── src
│ │ │ ├── 1.ts
│ │ │ └── 2.ts
│ ├── 3.live
│ │ └── README.md
│ ├── 4.assignment
│ │ ├── README.md
│ │ └── src
│ │ │ ├── 1.ts
│ │ │ ├── 2.ts
│ │ │ ├── 3.ts
│ │ │ └── 4.ts
│ └── README.md
├── 3.typescript-react
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ └── README.md
│ ├── 4.assignment
│ │ └── README.md
│ └── README.md
├── 4.eval
│ ├── README.md
│ └── initialData.json
└── README.md
├── w2
├── 1.custom-hooks
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ ├── README.md
│ │ └── boiler
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── db.json
│ │ │ ├── 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
│ │ │ ├── components
│ │ │ ├── Posts
│ │ │ │ ├── AddPost.jsx
│ │ │ │ ├── Post.jsx
│ │ │ │ ├── Posts.jsx
│ │ │ │ └── posts.api.js
│ │ │ ├── Stopwatch1.jsx
│ │ │ ├── Stopwatch2.jsx
│ │ │ └── Stopwatch3.jsx
│ │ │ ├── index.css
│ │ │ ├── index.js
│ │ │ ├── logo.svg
│ │ │ ├── reportWebVitals.js
│ │ │ └── setupTests.js
│ ├── 4.assignment
│ │ └── README.md
│ └── README.md
├── 2.redux
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ └── README.md
│ ├── 4.assignment
│ │ └── README.md
│ └── README.md
├── 3.react-redux
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ └── README.md
│ ├── 4.assignment
│ │ └── README.md
│ └── README.md
├── 4.redux-config
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ └── README.md
│ ├── 4.assignment
│ │ └── README.md
│ └── README.md
├── 5.redux-thunks
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ ├── README.md
│ │ └── boil
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── db.json
│ │ │ ├── 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
│ │ │ ├── components
│ │ │ └── Navbar.jsx
│ │ │ ├── context
│ │ │ └── AuthContext.jsx
│ │ │ ├── hoc
│ │ │ └── RequireAuth.jsx
│ │ │ ├── index.css
│ │ │ ├── index.js
│ │ │ ├── logo.svg
│ │ │ ├── pages
│ │ │ ├── Careers.jsx
│ │ │ ├── Feeds.jsx
│ │ │ ├── Home.jsx
│ │ │ ├── Login.jsx
│ │ │ └── Posts.jsx
│ │ │ ├── reportWebVitals.js
│ │ │ └── setupTests.js
│ ├── 4.assignment
│ │ └── README.md
│ └── README.md
├── 6.eval
│ └── README.md
└── README.md
├── w3
├── 1.nextjs
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ ├── README.md
│ │ └── pre-readme.md
│ ├── 4.assignment
│ │ └── README.md
│ ├── README.md
│ └── assets
│ │ ├── csr.png
│ │ ├── rendering.jpeg
│ │ ├── seo-2.png
│ │ ├── seo.png
│ │ ├── ssr-csr-1.png
│ │ ├── ssr-vs-csr.png
│ │ └── ssr.png
├── 2.nextjs-adv
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ ├── README.md
│ │ └── db.json
│ ├── 4.assignment
│ │ └── README.md
│ └── README.md
├── 3.github
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ └── README.md
│ ├── 4.assignment
│ │ └── README.md
│ └── README.md
├── 4.storybook
│ ├── 1.pre-class
│ │ └── README.md
│ ├── 2.pre-assignment
│ │ └── README.md
│ ├── 3.live
│ │ ├── README.md
│ │ └── lec-ts
│ │ │ ├── .gitignore
│ │ │ ├── .storybook
│ │ │ ├── main.cjs
│ │ │ ├── preview-head.html
│ │ │ └── preview.cjs
│ │ │ ├── index.html
│ │ │ ├── package-lock.json
│ │ │ ├── package.json
│ │ │ ├── public
│ │ │ └── vite.svg
│ │ │ ├── src
│ │ │ ├── App.css
│ │ │ ├── App.tsx
│ │ │ ├── MyButton
│ │ │ │ ├── MyButton.stories.tsx
│ │ │ │ └── MyButton.tsx
│ │ │ ├── assets
│ │ │ │ └── react.svg
│ │ │ ├── index.css
│ │ │ ├── main.tsx
│ │ │ ├── stories
│ │ │ │ ├── Button.stories.tsx
│ │ │ │ ├── Button.tsx
│ │ │ │ ├── Header.stories.tsx
│ │ │ │ ├── Header.tsx
│ │ │ │ ├── Introduction.stories.mdx
│ │ │ │ ├── Page.stories.tsx
│ │ │ │ ├── Page.tsx
│ │ │ │ ├── assets
│ │ │ │ │ ├── code-brackets.svg
│ │ │ │ │ ├── colors.svg
│ │ │ │ │ ├── comments.svg
│ │ │ │ │ ├── direction.svg
│ │ │ │ │ ├── flow.svg
│ │ │ │ │ ├── plugin.svg
│ │ │ │ │ ├── repo.svg
│ │ │ │ │ └── stackalt.svg
│ │ │ │ ├── button.css
│ │ │ │ ├── header.css
│ │ │ │ └── page.css
│ │ │ └── vite-env.d.ts
│ │ │ ├── tsconfig.json
│ │ │ ├── tsconfig.node.json
│ │ │ └── vite.config.ts
│ ├── 4.assignment
│ │ └── README.md
│ └── README.md
└── README.md
└── w4
├── 1.performance
├── 1.pre-class
│ └── README.md
├── 2.pre-assignment
│ └── README.md
├── 3.live
│ ├── README.md
│ └── boil
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── public
│ │ └── vite.svg
│ │ ├── src
│ │ ├── App.css
│ │ ├── App.tsx
│ │ ├── assets
│ │ │ └── react.svg
│ │ ├── components
│ │ │ ├── Counter.tsx
│ │ │ ├── TodoApp.tsx
│ │ │ ├── TodoInput.tsx
│ │ │ └── TodoItem.tsx
│ │ ├── index.css
│ │ ├── main.tsx
│ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.node.json
│ │ └── vite.config.ts
├── 4.assignment
│ └── README.md
└── README.md
├── 2.react-testing
├── 1.pre-class
│ └── README.md
├── 2.pre-assignment
│ └── README.md
├── 3.live
│ ├── README.md
│ ├── boil-1
│ │ ├── .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
│ │ │ ├── components
│ │ │ ├── Button
│ │ │ │ └── Button.jsx
│ │ │ └── Counter
│ │ │ │ └── Counter.jsx
│ │ │ ├── index.css
│ │ │ ├── index.js
│ │ │ ├── logo.svg
│ │ │ ├── reportWebVitals.js
│ │ │ └── setupTests.js
│ └── boil-2
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── initialData.json
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ │ ├── src
│ │ ├── App.css
│ │ ├── App.test.tsx
│ │ ├── App.tsx
│ │ ├── components
│ │ │ ├── TopicInput.tsx
│ │ │ ├── TopicItem.tsx
│ │ │ ├── TopicSection.tsx
│ │ │ └── TopicsBoard.tsx
│ │ ├── constants.ts
│ │ ├── context
│ │ │ └── TopicsContext.tsx
│ │ ├── index.css
│ │ ├── index.tsx
│ │ ├── logo.svg
│ │ ├── react-app-env.d.ts
│ │ ├── reportWebVitals.ts
│ │ └── setupTests.ts
│ │ └── tsconfig.json
├── 4.assignment
│ └── README.md
└── README.md
├── 3.cypress
├── 1.pre-class
│ └── README.md
├── 2.pre-assignment
│ └── README.md
├── 3.live
│ ├── README.md
│ └── boil
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── db.json
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ │ └── src
│ │ ├── App.css
│ │ ├── App.jsx
│ │ ├── App.test.js
│ │ ├── components
│ │ ├── TodoApp.jsx
│ │ ├── TodoInput.jsx
│ │ └── TodoList.jsx
│ │ ├── index.css
│ │ ├── index.jsx
│ │ ├── logo.svg
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
├── 4.assignment
│ └── README.md
└── README.md
├── 4.psc
├── .vscode
│ └── settings.json
├── README.md
└── ref
│ ├── .vscode
│ └── settings.json
│ ├── components
│ ├── Cart.tsx
│ ├── CustomImage.tsx
│ ├── Footer.tsx
│ ├── Header.tsx
│ ├── NextSEO.tsx
│ ├── ProductCart.tsx
│ └── ProductDetails.tsx
│ ├── db.json
│ ├── next.config.js
│ ├── pages
│ ├── _app.tsx
│ ├── index.tsx
│ └── products
│ │ └── [product].tsx
│ ├── public
│ ├── favicon.ico
│ ├── header_bg.svg
│ ├── logo.svg
│ ├── next.svg
│ ├── og-image.png
│ ├── raindrops-animate.svg
│ ├── raindrops.svg
│ └── text_logo.svg
│ ├── redux
│ ├── cart
│ │ ├── cart.action.ts
│ │ ├── cart.api.ts
│ │ ├── cart.reducer.ts
│ │ └── cart.type.ts
│ ├── product
│ │ ├── product.action.ts
│ │ ├── product.api.ts
│ │ ├── product.reducer.ts
│ │ └── product.type.ts
│ └── store.ts
│ ├── styles
│ └── global.css
│ └── utils
│ ├── data.utils.ts
│ └── types.ts
├── 5.eval
└── README.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | node_modules/
3 | .DS_Store
4 |
5 | # Custom
6 | **/1.pre-class/record/
7 | **/1.pre-class/practice/
8 |
9 | *.eval/
10 | **/lec/
11 | **/sol/
12 | notes.md
13 | Speech.md
14 | *.mp4
15 | # Local Netlify folder
16 | .netlify
17 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.defaultFormatter": "esbenp.prettier-vscode",
3 | "editor.formatOnSave": true,
4 | "[javascript]": {
5 | "editor.defaultFormatter": "esbenp.prettier-vscode",
6 | "editor.formatOnSave": true
7 | },
8 | "workbench.iconTheme": "vscode-icons",
9 | "terminal.integrated.scrollback": 100000,
10 | "window.zoomLevel": 3
11 | }
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## [RCT-201](https://www.canva.com/design/DAFRXlLSix8/ozz5a2veY-DEHz9lOHg5QA/view?utm_content=DAFRXlLSix8&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | 1. Welcome
4 | 2. Pre-requisites
5 | 3. Course Overview
6 | 4. Learning Topics
7 | - Typescript
8 | - Custom Hooks
9 | - Redux
10 | - NextJS
11 | - Storybook
12 | - Debugging
13 | - Testing
14 | - Advance Git
15 | 5. Roadmap
16 |
--------------------------------------------------------------------------------
/assets/custom-hooks-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/custom-hooks-background.png
--------------------------------------------------------------------------------
/assets/custom-hooks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/custom-hooks.png
--------------------------------------------------------------------------------
/assets/github-actions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/github-actions.png
--------------------------------------------------------------------------------
/assets/nextjs-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/nextjs-1.png
--------------------------------------------------------------------------------
/assets/nextjs-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/nextjs-2.png
--------------------------------------------------------------------------------
/assets/nextjs-thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/nextjs-thumb.png
--------------------------------------------------------------------------------
/assets/react-2022.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/react-2022.png
--------------------------------------------------------------------------------
/assets/redux-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/redux-background.png
--------------------------------------------------------------------------------
/assets/storybook.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/storybook.jpeg
--------------------------------------------------------------------------------
/assets/testing-background.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/assets/testing-background.jpeg
--------------------------------------------------------------------------------
/w1/1.typescript-intro/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | ### [`Introduction to Typescript`](https://www.canva.com/design/DAFRVo6KiiU/Y6terVDplneB3iad36-kJQ/view?utm_content=DAFRVo6KiiU&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton#1)
2 |
3 | ## Topics
4 |
5 | 1. Basic types
6 | - string
7 | - number
8 | - boolean
9 | - null
10 | - undefined
11 | - any
12 | - Literal Types
13 | - Union Types
14 | 2. Functions
15 | - ES5 Function
16 | - Arrow function
17 | 3. Array
18 | - Array
19 | - Array Literal
20 | 4. Object
21 | - Object
22 | - Object Literal
23 | - Record
24 | 5. Custom Type
25 | - Type
26 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | # Setup
2 |
3 | - Create a Node Project
4 | - Install `typescript` and `tsc`
5 | - Add Scripts to run the files.
6 |
7 | # Assignments
8 |
9 | 1. Create a type name with a string ?
10 |
11 | - command to execute:
12 |
13 | ```cmd
14 | npm run ts_1
15 | ```
16 |
17 | 2. Create a type age with a number ?
18 |
19 | - command to execute:
20 |
21 | ```cmd
22 | npm run ts_2
23 | ```
24 |
25 | 3. Create a type isFetching with boolean ?
26 |
27 | - command to execute:
28 |
29 | ```cmd
30 | npm run ts_3
31 | ```
32 |
33 | 4. Create an array of numbers ?
34 |
35 | - command to execute:
36 |
37 | ```cmd
38 | npm run ts_4
39 | ```
40 |
41 | 5. Create an array of strings ?
42 |
43 | - command to execute:
44 |
45 | ```cmd
46 | npm run ts_5
47 | ```
48 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/2.pre-assignment/src/1.ts:
--------------------------------------------------------------------------------
1 | // 1. Create a type name with a string ?
2 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/2.pre-assignment/src/2.ts:
--------------------------------------------------------------------------------
1 | // 2. Create a type age with a number ?
2 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/2.pre-assignment/src/3.ts:
--------------------------------------------------------------------------------
1 | // 3. Create a type isFetching with boolean ?
2 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/2.pre-assignment/src/4.ts:
--------------------------------------------------------------------------------
1 | // 4. Create an array of numbers ?
2 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/2.pre-assignment/src/5.ts:
--------------------------------------------------------------------------------
1 | // 5. Create an array of strings ?
2 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | # Setup
2 |
3 | - Create a Node Project
4 | - Install `typescript` and `tsc`
5 | - Add Scripts to run the file.
6 |
7 | # Assignments
8 |
9 | 1. Create a function that takes 2 arguments, x, y both numbers ?
10 |
11 | - it should return the product of the 2 numbers
12 | - command to execute:
13 |
14 | ```cmd
15 | npm run ts_1
16 | ```
17 |
18 | 2. Create a function that takes 2 arguments, x ,y both numbers ?
19 |
20 | - it should divide output ( x / y )
21 | - command to execute:
22 |
23 | ```cmd
24 | npm run ts_2
25 | ```
26 |
27 | 3. Create a function that takes a name and prints it without returning anything ?
28 |
29 | - command to execute:
30 |
31 | ```cmd
32 | npm run ts_3
33 | ```
34 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/4.assignment/src/1.ts:
--------------------------------------------------------------------------------
1 | // Create a function that takes 2 arguments, x, y both numbers ?
2 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/4.assignment/src/2.ts:
--------------------------------------------------------------------------------
1 | // 2. Create a function that takes 2 arguments, x ,y both numbers ?
2 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/4.assignment/src/3.ts:
--------------------------------------------------------------------------------
1 | // 3. Create a function that takes a name and prints it without returning anything ?
2 |
--------------------------------------------------------------------------------
/w1/1.typescript-intro/README.md:
--------------------------------------------------------------------------------
1 | ### [`Introduction to Typescript`](https://www.canva.com/design/DAFRVo6KiiU/Y6terVDplneB3iad36-kJQ/view?utm_content=DAFRVo6KiiU&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton#1)
2 |
3 | ## Topics
4 |
5 | 1. Basic types
6 | - string
7 | - number
8 | - boolean
9 | - null
10 | - undefined
11 | - any
12 | - Literal Types
13 | - Union Types
14 | 2. Functions
15 | - ES5 Function
16 | - Arrow function
17 | 3. Array
18 | - Array
19 | - Array Literal
20 | 4. Object
21 | - Object
22 | - Object Literal
23 | - Record
24 | 5. Custom Type
25 | - Type
26 |
--------------------------------------------------------------------------------
/w1/2.typescript-advance/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ## Getting Started
2 |
3 | 1. Node project Setup
4 | 2. `tsc --init`
5 | 3. Installed Dependencies
6 | 4. Add Scripts
7 |
8 | ## Assignments
9 |
10 | 1. Create a tuple , which keeps a string as the first value, and boolean as the second.
11 |
12 | ```cmd
13 | npm run ts_1
14 | ```
15 |
16 | 2. Create an enum
17 | - it should have User, SuperUser, Admin, SuperAdmin
18 |
19 | ```cmd
20 | npm run ts_2
21 | ```
22 |
23 | 3. Create a tsconfig file
24 | - the target version should be latest ES version.
25 | - the output should be stored in build folder.
26 | - applicable for both of the above assignments.
27 |
--------------------------------------------------------------------------------
/w1/2.typescript-advance/2.pre-assignment/src/1.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w1/2.typescript-advance/2.pre-assignment/src/1.ts
--------------------------------------------------------------------------------
/w1/2.typescript-advance/2.pre-assignment/src/2.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w1/2.typescript-advance/2.pre-assignment/src/2.ts
--------------------------------------------------------------------------------
/w1/2.typescript-advance/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ## Assignments
2 |
3 | #### Problem
4 |
5 | 1. Create an interface for an object
6 |
7 | - it should accept a title string
8 | - it should accept a status boolean
9 | - it should accept an id number
10 |
11 | ```cmd
12 | npm run ts_1
13 | ```
14 |
15 | 2. Create a function getName
16 |
17 | - it should accept an object firstname and lastname
18 | - it should return fullname
19 | - keep lastname optional.
20 | - if lastname does not exist then return only firstname
21 | - make a interface for it
22 |
23 | ```cmd
24 | npm run ts_2
25 | ```
26 |
27 | 3. Create an interface Address
28 |
29 | - it takes
30 | - houseNumber
31 | - street
32 | - city
33 | - state
34 | - postalCode
35 | - country
36 | - add appropriate types
37 |
38 | ```cmd
39 | npm run ts_3
40 | ```
41 |
42 | 4. Create a PersonDetails interface
43 |
44 | - it should have
45 | - Prefix optional
46 | - phones array of numbers
47 | - addresses array of Addresses
48 | - email optional
49 | - firstname
50 | - lastname
51 | - middlename optional
52 |
53 | ```cmd
54 | npm run ts_4
55 | ```
56 |
57 | 5. Create a function PhoneBook
58 |
59 | - it should accept PersonDetails type argument
60 | - create an array of objects outside the PhoneBook function, that is expecting PersonDetails objects.
61 | - Push the PersonDetails object in the array, from the function.
62 |
63 | ```cmd
64 | npm run ts_5
65 | ```
66 |
67 | 6. Create a tsconfig file
68 | - the target version should be latest ES version.
69 | - the output should be stored in build folder.
70 | - applicable for both of the above assignments.
71 |
--------------------------------------------------------------------------------
/w1/2.typescript-advance/4.assignment/src/1.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w1/2.typescript-advance/4.assignment/src/1.ts
--------------------------------------------------------------------------------
/w1/2.typescript-advance/4.assignment/src/2.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w1/2.typescript-advance/4.assignment/src/2.ts
--------------------------------------------------------------------------------
/w1/2.typescript-advance/4.assignment/src/3.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w1/2.typescript-advance/4.assignment/src/3.ts
--------------------------------------------------------------------------------
/w1/2.typescript-advance/4.assignment/src/4.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w1/2.typescript-advance/4.assignment/src/4.ts
--------------------------------------------------------------------------------
/w1/2.typescript-advance/README.md:
--------------------------------------------------------------------------------
1 | ### [Advance Typescript](https://www.canva.com/design/DAFRbdvZ-u0/OA0SUBxRnYXB2q83I2GtrQ/view?utm_content=DAFRbdvZ-u0&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | ## Topics
4 |
5 | 1. Enum
6 | - Numeric Enums
7 | - String Enums
8 | 2. tuple
9 | 3. keyof
10 | 4. typeof
11 | 5. generics
12 | 6. interface
13 | 7. class
14 | 8. extends
15 |
--------------------------------------------------------------------------------
/w1/3.typescript-react/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | ### [Typescript with React](https://www.typescriptlang.org/docs/handbook/react.html)
2 |
3 | - Typescript can be used with react, using command
4 |
5 | ```cmd
6 | npx create-react-app lec --template typescript
7 | ```
8 |
9 | - Explain Folder Strudture.
10 | - `.tsx` file extension.
11 |
12 | ### Task
13 |
14 | 1. Create a Button Component with Typescript
15 | - color
16 | - handleClick
17 | - children
18 | 2. Create a Simple Counter App with Typescript
19 | - Explain Generic Hook Fuction.
20 | - Props with Typescript
21 |
--------------------------------------------------------------------------------
/w1/3.typescript-react/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | # Assignments
2 |
3 | 1. Create a react typescript project using the command.
4 | 2. Create a Counter component with dynamic increment value.
5 | - Create 2 Components
6 | - Button: Props: buttomtext, handleClick Function.
7 | - Count: Used to Display Value
8 | - Keep all logic in Counter Component.
9 | - Use Typescript Correctly.
10 | - Do not use `any` type.
11 |
--------------------------------------------------------------------------------
/w1/3.typescript-react/3.live/README.md:
--------------------------------------------------------------------------------
1 | ### [Typescript with React](https://www.typescriptlang.org/docs/handbook/react.html)
2 |
3 | - Typescript can be used with react, using command
4 |
5 | ```cmd
6 | npx create-react-app lec --template typescript
7 | ```
8 |
9 | ### Topics
10 |
11 | - Props
12 | - Children
13 | - Events
14 | - useState with generics
15 | - Synthetic Events and Types
16 | - Axios API response Mapping
17 |
18 | ## Coding Task
19 |
20 | # Create a Todo App with API integration
21 |
22 | - TodoInput Component
23 | - TodoItem component
24 |
25 | # Tasks
26 |
27 | 1. `npx create-react-app lec --template typescript`
28 | 2. Create Componets
29 |
30 | - TodoApp.tsx
31 | - TodoInput.tsx
32 | - TodoItem.tsx
33 |
34 | 3. create a `db.json` file.
35 |
36 | ```json
37 | {
38 | "todos": [
39 | { "id": 1, "type": "Learned", "message": "useState", "likes": 2 },
40 | { "id": 2, "type": "Learned", "message": "useEffect", "likes": 3 },
41 | { "id": 3, "type": "Learning", "message": "useRef", "likes": 0 },
42 | { "id": 4, "type": "Pending", "message": "useReducer", "likes": 5 },
43 | { "id": 5, "type": "Revision", "message": "React-101", "likes": 2 },
44 | { "id": 6, "likes": 0, "message": "redux", "type": "Pending" },
45 | { "id": 7, "likes": 0, "message": "Typescript", "type": "Learning" }
46 | ]
47 | }
48 | ```
49 |
50 | 4. Start `json-server` on port: `8080`
51 |
52 | ```cmd
53 | json-server --watch db.json --port 8080
54 | ```
55 |
56 | 5. Create an `api.ts` file to write all API's in it
57 |
58 | 6. Write types for everything
59 |
--------------------------------------------------------------------------------
/w1/3.typescript-react/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | # Assignments
2 |
3 | 1. Create a TODO application
4 | - An user should be able to add a new item, delete, update, and toggle status
5 | - Use typescript at `events`, `state`, `props` etc
6 | - separate into smaller components
7 | - TodoInput
8 | - TodoList
9 | - Todo
10 | - Do not use `any` type.
11 |
--------------------------------------------------------------------------------
/w1/3.typescript-react/README.md:
--------------------------------------------------------------------------------
1 | ### `React with Typescript`
2 |
3 | ## Topics
4 |
5 | 1. `create-react-app` with typescript
6 | 2. Types for Hooks
7 | 3. Types for Props
8 | 4. Types for Events
9 | - ChangeEvent
10 | 5. Types for React Elements
11 | - Children
12 | - ReactNode
13 |
--------------------------------------------------------------------------------
/w1/4.eval/README.md:
--------------------------------------------------------------------------------
1 | ### On Platform
2 |
--------------------------------------------------------------------------------
/w1/4.eval/initialData.json:
--------------------------------------------------------------------------------
1 | [
2 | { "id": 1, "type": "Completed", "message": "useState", "likes": 2 },
3 | { "id": 2, "type": "Completed", "message": "useEffect", "likes": 3 },
4 | { "id": 3, "type": "Pending", "message": "useRef", "likes": 0 },
5 | { "id": 4, "type": "Revision", "message": "useReducer", "likes": 5 },
6 | { "id": 5, "type": "Revision", "message": "React-101", "likes": 2 },
7 | { "id": 5, "type": "New", "message": "Custom Hooks", "likes": 2 }
8 | ]
9 |
--------------------------------------------------------------------------------
/w1/README.md:
--------------------------------------------------------------------------------
1 | ### `Week 1`
2 |
3 | ## Topics
4 |
5 | 1. Basics of Typescript
6 | 2. Advance Typescript
7 | 3. React with Typescript
8 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | # [Custom Hooks](https://www.canva.com/design/DAFRQK1zIbg/wkxICQR28RsWOZ89u3fyTw/view?utm_content=DAFRQK1zIbg&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | ### [What are Hooks ?](https://reactjs.org/docs/hooks-intro.html)
4 |
5 | - Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.
6 | - Hooks are used for interacting with state.
7 |
8 | ### Are Hooks Needed ?
9 |
10 | - Hooks are needed to persisting information across re-render.
11 | - Hooks are needed to inform DOM for the changes happended in the component to trigger re-render.
12 |
13 | ### Example of Known Hooks ?
14 |
15 | - useState
16 |
17 | ```ts
18 | import React, { useState } from "react";
19 |
20 | function Example() {
21 | // Declare a new state variable, which we'll call "count"
22 | const [count, setCount] = useState(0);
23 |
24 | return (
25 |
26 |
You clicked {count} times
27 |
28 |
29 | );
30 | }
31 | ```
32 |
33 | ### [Rules of Hooks ?](https://reactjs.org/docs/hooks-rules.html)
34 |
35 | Hooks are JavaScript functions, but you need to follow two rules when using them. We provide a linter plugin to enforce these rules automatically:
36 |
37 | 1. Only Call Hooks at the Top Level.
38 | 2. Only Call Hooks from React Functions.
39 | - Call Hooks from React function components.
40 | - Call Hooks from custom Hooks
41 |
42 | ### What is a Custom Hook ?
43 |
44 | A Hook function that is created by us and does not come from react or any other library.
45 |
46 | ### What is the purpose of creating a Custom Hooks ?
47 |
48 | - We create Hooks to share Logic.
49 | - Context API there is used to share infroamtion across components.
50 | - But when we want a similar logic at multiple places we use Custom Hook.
51 |
52 | ### What are the rules of creating a Custom Hooks ?
53 |
54 | - The function name should start with `use`, e.g: useAlpha, useBeta, etc.
55 |
56 | ### [Lets Create Our Own Hook](https://reactjs.org/docs/hooks-custom.html)
57 |
58 | 1. Create a new React app
59 |
60 | ```cmd
61 | npx create-react-app record
62 | ```
63 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | 1. Create a React Project
4 | 2. Create an `useCounter` component that gives
5 |
6 | - Method signature
7 |
8 | ```js
9 | const { count, increment, decrement } = useCounter(initialValue);
10 | ```
11 |
12 | - count : number value.
13 | - increment : Function that takes number as argument, default 1. used to increment the count.
14 | - decrement : Function that takes number as argument, default 1. used to decrement the count.
15 |
16 | 3. use this hooks in more then 3 components to increment and decrement the values.
17 |
18 | - Component 1: increment/decrement by 1
19 | - Component 2: increment by 2/decrement by 3
20 | - Component 1: increment by -5/decrement by from an input element.
21 |
22 | 4. (Bonus) if able to use typescript with this example.
23 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/README.md:
--------------------------------------------------------------------------------
1 | # [Custom Hooks](https://www.canva.com/design/DAFRQK1zIbg/wkxICQR28RsWOZ89u3fyTw/view?utm_content=DAFRQK1zIbg&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | Creating our own hooks to common-out the logic.
4 |
5 | ### Getting started
6 |
7 | - Go to `boiler` folder
8 | - `npm i`
9 | - `npm start`
10 |
11 | ### Goal
12 |
13 | - Create custom hook for Stopwatch
14 |
15 | ```js
16 | const { time, start, stop, pause } = useStopwatch();
17 | ```
18 |
19 | - Create custom hook for Fetch API
20 |
21 | ```js
22 | const { loading, error, data, refetch } = useFetch(apiFn);
23 | ```
24 |
25 | - Create custom hook for Delayed Fetch API
26 |
27 | ```js
28 | const { loading, data, error, execute } = useDelayedFetch(apiFn);
29 | // Here execute is used to execute the apiFn with params
30 | execute(params);
31 | ```
32 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/.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 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/README.md:
--------------------------------------------------------------------------------
1 | ## Getting Started
2 |
3 | 1. `npm i `
4 | 2. `json-server --watch db.json --port 8080`
5 | 3. `npm start`
6 |
7 | ## This is a mixed app with
8 |
9 | - Multiple Stopwatch with similar logic
10 | - Multiple api with
11 | - loading
12 | - error
13 | - data
14 |
15 | ## Goal
16 |
17 | 1. Avoid repeatation of logic
18 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "posts": [
3 | {
4 | "content": "A",
5 | "id": 1
6 | },
7 | {
8 | "content": "B",
9 | "id": 2
10 | },
11 | {
12 | "content": "C",
13 | "id": 3
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "2.pre-assignment",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@chakra-ui/react": "^2.3.7",
7 | "@emotion/react": "^11.10.5",
8 | "@emotion/styled": "^11.10.5",
9 | "@testing-library/jest-dom": "^5.16.5",
10 | "@testing-library/react": "^13.4.0",
11 | "@testing-library/user-event": "^13.5.0",
12 | "axios": "^1.1.3",
13 | "framer-motion": "^7.6.5",
14 | "json-server": "^0.17.1",
15 | "react": "^18.2.0",
16 | "react-dom": "^18.2.0",
17 | "react-scripts": "5.0.1",
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 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w2/1.custom-hooks/3.live/boiler/public/favicon.ico
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w2/1.custom-hooks/3.live/boiler/public/logo192.png
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w2/1.custom-hooks/3.live/boiler/public/logo512.png
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/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 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/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 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Box, Center, Divider, Flex, Heading } from "@chakra-ui/react";
3 | import Stopwatch1 from "./components/Stopwatch1";
4 | import Stopwatch2 from "./components/Stopwatch2";
5 | import Stopwatch3 from "./components/Stopwatch3";
6 | import Posts from "./components/Posts/Posts";
7 |
8 | function App() {
9 | return (
10 |
11 |
12 | StopWatchs
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | );
27 | }
28 |
29 | export default App;
30 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/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 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/components/Posts/AddPost.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { Button, Center, Input, useToast } from "@chakra-ui/react";
3 | import { addPost } from "./posts.api";
4 |
5 | const AddPost = ({ onAddPost }) => {
6 | const toast = useToast();
7 | const [loading, setLoading] = useState(false);
8 | const [message, setMessage] = useState("");
9 |
10 | const handleAdd = async () => {
11 | try {
12 | setLoading(true);
13 | let post = await addPost({ content: message });
14 | onAddPost(post);
15 | toast({
16 | title: `Post added successfully`,
17 | status: "success",
18 | duration: 3000,
19 | isClosable: true,
20 | position: "top-right",
21 | });
22 | } catch (e) {
23 | toast({
24 | title: "Error Occurred while trying to add Post",
25 | description: e.message,
26 | status: "error",
27 | duration: 3000,
28 | isClosable: true,
29 | position: "top-right",
30 | });
31 | } finally {
32 | setLoading(false);
33 | }
34 | };
35 | return (
36 |
37 | setMessage(e.target.value)} />
38 |
41 |
42 | );
43 | };
44 |
45 | export default AddPost;
46 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/components/Posts/Post.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { Box, Button, Flex, useToast } from "@chakra-ui/react";
3 | import { deletePost } from "./posts.api";
4 |
5 | const Post = ({ id, content, onDelete }) => {
6 | const toast = useToast();
7 | const [loading, setLoading] = useState(false);
8 |
9 | const handleDelete = async () => {
10 | try {
11 | setLoading(true);
12 | await deletePost(id);
13 | onDelete(id);
14 | toast({
15 | title: `Post with id: ${id}, deleted successfully`,
16 | status: "success",
17 | duration: 3000,
18 | isClosable: true,
19 | position: "top-right",
20 | });
21 | } catch (e) {
22 | toast({
23 | title: "Error Occurred while fetching data",
24 | description: e.message,
25 | status: "error",
26 | duration: 3000,
27 | isClosable: true,
28 | position: "top-right",
29 | });
30 | } finally {
31 | setLoading(false);
32 | }
33 | };
34 |
35 | return (
36 |
37 | {content}
38 |
46 |
47 | );
48 | };
49 |
50 | export default Post;
51 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/components/Posts/Posts.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import {
3 | Box,
4 | Button,
5 | Center,
6 | CircularProgress,
7 | Flex,
8 | Heading,
9 | useToast,
10 | } from "@chakra-ui/react";
11 |
12 | import AddPost from "./AddPost";
13 | import Post from "./Post";
14 | import { getPosts } from "./posts.api";
15 |
16 | const Posts = () => {
17 | const toast = useToast();
18 | const [loading, setLoading] = useState(false);
19 | const [success, setSuccess] = useState(false);
20 | const [data, setData] = useState([]);
21 |
22 | const getData = async () => {
23 | try {
24 | setLoading(true);
25 | let data = await getPosts();
26 | setData(data);
27 | setSuccess(true);
28 | } catch (e) {
29 | toast({
30 | title: "Error Occurred while fetching data",
31 | description: e.message,
32 | status: "error",
33 | duration: 3000,
34 | isClosable: true,
35 | position: "top-right",
36 | });
37 | setSuccess(false);
38 | } finally {
39 | setLoading(false);
40 | }
41 | };
42 |
43 | const onAddPost = (post) => {
44 | setData([...data, post]);
45 | };
46 | const onDelete = (id) => {
47 | setData(data.filter((p) => p.id !== id));
48 | };
49 |
50 | useEffect(() => {
51 | getData();
52 | // eslint-disable-next-line react-hooks/exhaustive-deps
53 | }, []);
54 |
55 | return (
56 |
57 |
58 | Posts
59 |
62 |
63 |
64 | {loading && }
65 |
66 | {success &&
67 | data.map((post) => (
68 |
69 | ))}
70 |
71 |
72 | );
73 | };
74 |
75 | export default Posts;
76 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/components/Posts/posts.api.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | export const getPosts = async () => {
4 | const response = await axios.get("http://localhost:8080/posts");
5 | return response.data;
6 | };
7 |
8 | export const addPost = async (content) => {
9 | let response = await axios.post("http://localhost:8080/posts", content);
10 | return response.data;
11 | };
12 |
13 | export const deletePost = async (id) => {
14 | let response = await axios.delete(`http://localhost:8080/posts/${id}`);
15 | let data = response.data;
16 | return data;
17 | };
18 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/components/Stopwatch1.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from "react";
2 | import { Box, Button, Center, Flex, Heading } from "@chakra-ui/react";
3 |
4 | const Stopwatch1 = () => {
5 | const [time, setTime] = useState(0);
6 | const timerId = useRef(null);
7 | const start = () => {
8 | if (!timerId.current) {
9 | timerId.current = setInterval(() => {
10 | setTime((prevValue) => prevValue + 1);
11 | }, 1000);
12 | }
13 | };
14 | const pause = () => {
15 | clearInterval(timerId.current);
16 | timerId.current = null;
17 | };
18 | const reset = () => {
19 | clearInterval(timerId.current);
20 | timerId.current = null;
21 | setTime(0);
22 | };
23 |
24 | const addSeconds = (count) => {
25 | setTime((prevValue) => prevValue + count);
26 | };
27 | useEffect(() => {
28 | return reset;
29 | }, []);
30 | return (
31 |
32 |
33 | {time}
34 |
35 |
36 |
39 |
42 |
45 |
46 |
47 |
50 |
53 |
56 |
57 |
58 | );
59 | };
60 |
61 | export default Stopwatch1;
62 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/components/Stopwatch2.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from "react";
2 | import { Box, Button, Center, Flex, Heading } from "@chakra-ui/react";
3 |
4 | const Stopwatch2 = () => {
5 | const [time, setTime] = useState(0);
6 | const timerId = useRef(null);
7 | const start = () => {
8 | if (!timerId.current) {
9 | timerId.current = setInterval(() => {
10 | setTime((prevValue) => prevValue + 1);
11 | }, 1000);
12 | }
13 | };
14 |
15 | const reset = () => {
16 | clearInterval(timerId.current);
17 | timerId.current = null;
18 | setTime(0);
19 | };
20 |
21 | const addSeconds = (count) => {
22 | setTime((prevValue) => prevValue + count);
23 | };
24 |
25 | useEffect(() => {
26 | return reset;
27 | }, []);
28 | return (
29 |
30 |
31 | {time}
32 |
33 |
34 |
37 |
40 |
41 |
42 |
45 |
48 |
51 |
52 |
53 | );
54 | };
55 |
56 | export default Stopwatch2;
57 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/components/Stopwatch3.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from "react";
2 | import { Box, Button, Center, Flex, Heading } from "@chakra-ui/react";
3 |
4 | const Stopwatch3 = () => {
5 | const [time, setTime] = useState(0);
6 | const timerId = useRef(null);
7 | const start = () => {
8 | if (!timerId.current) {
9 | timerId.current = setInterval(() => {
10 | setTime((prevValue) => prevValue + 1);
11 | }, 1000);
12 | }
13 | };
14 | const pause = () => {
15 | clearInterval(timerId.current);
16 | timerId.current = null;
17 | };
18 | const reset = () => {
19 | clearInterval(timerId.current);
20 | timerId.current = null;
21 | setTime(0);
22 | };
23 | useEffect(() => {
24 | return reset;
25 | }, []);
26 | return (
27 |
28 |
29 | {time}
30 |
31 |
32 |
35 |
38 |
39 |
40 | );
41 | };
42 |
43 | export default Stopwatch3;
44 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/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 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import { ChakraProvider } from "@chakra-ui/react";
4 |
5 | import App from "./App";
6 |
7 | import reportWebVitals from "./reportWebVitals";
8 | import "./index.css";
9 |
10 | const root = ReactDOM.createRoot(document.getElementById("root"));
11 | root.render(
12 |
13 |
14 |
15 | );
16 |
17 | // If you want to start measuring performance in your app, pass a function
18 | // to log results (for example: reportWebVitals(console.log))
19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
20 | reportWebVitals();
21 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/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 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/3.live/boiler/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 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | 1. Create a React Project
4 | 2. Create a `useFetch` Hook
5 |
6 | - Signature:
7 |
8 | ```js
9 | const { loading, data, error, refetch } = useFetch(apiFn, initialData);
10 | // Here refetch is used to re-execute the apiFn.
11 | ```
12 |
13 | 3. Create a `useDelayedFetch` Hook
14 |
15 | - Signature:
16 |
17 | ```js
18 | const { loading, data, error, execute } = useDelayedFetch(apiFn);
19 | // Here execute is used to execute the apiFn with params
20 | execute(params);
21 | ```
22 |
--------------------------------------------------------------------------------
/w2/1.custom-hooks/README.md:
--------------------------------------------------------------------------------
1 | ### [Custom Hooks](https://www.canva.com/design/DAFRQK1zIbg/wkxICQR28RsWOZ89u3fyTw/view?utm_content=DAFRQK1zIbg&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | ## Topics
4 |
5 | 1. What are Custom Hooks
6 | 2. Why do we need Custom Hooks
7 | 3. How to Create Custom Hooks
8 | 4. Examples
9 | - useCounter
10 | - useStopwatch
11 | - useAPI
12 | - useDelayedAPI
13 | - useFetch custom
14 | - useMyReducer
15 |
--------------------------------------------------------------------------------
/w2/2.redux/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | ### [Introduction to Redux](https://www.canva.com/design/DAFSjNrlxoE/0E97JA1DYWFdfUWFe6H90A/view?utm_content=DAFSjNrlxoE&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | - MVC Architecture
4 | - Flux Architecture
5 | - Introduction to Redux
6 | - Why Redux
7 | - Where to use Redux
8 | - Getting started
9 |
--------------------------------------------------------------------------------
/w2/2.redux/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Getting Started
2 |
3 | - Initialize a Node Project
4 | - Install `redux`
5 | - Install `nodemon` as devDependency.
6 | - In package.json, add
7 | - `"type": "module"`
8 | - add start script
9 |
10 | ### Task
11 |
12 | 1. Create a Simple Counter App using redux
13 | 2. This app should support folling actions:
14 | - incrementBy(value: number)
15 | - decrementBy(value: number)
16 | 3. create folling for the same.
17 | - actionTypes
18 | - actions
19 | - reducer
20 | - store
21 |
--------------------------------------------------------------------------------
/w2/2.redux/3.live/README.md:
--------------------------------------------------------------------------------
1 | ### Getting Started
2 |
3 | 1. npm init -y
4 | 2. npm i redux
5 | 3. npm i nodemon -D
6 | 4. Update package.json, add
7 |
8 | ```json
9 | "type": "module"
10 | ```
11 |
12 | 5. Update package.json, add start script
13 |
14 | ```json
15 | "start": "nodemon src"
16 | ```
17 |
18 | 6. Create `actionTypes`, `actions`, `reducer`, `store` for
19 |
20 | #### Goal
21 |
22 | Create a Counter + Todo App that supports following operations:
23 |
24 | 1. incrementCounter
25 | 2. decrementCounter
26 | 3. addTodo
27 | 4. updateTodo
28 | 5. deleteTodo
29 |
--------------------------------------------------------------------------------
/w2/2.redux/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Getting Started
2 |
3 | - Initialize a Node Project
4 | - Install `redux`
5 | - Install `nodemon` as devDependency.
6 | - In package.json, add
7 | - `"type": "module"`
8 | - add start script
9 |
10 | ### Task
11 |
12 | 1. Create a TODO App using redux
13 |
14 | ```ts
15 | type Todo = {
16 | id: number;
17 | content: string;
18 | isCompleted: false;
19 | };
20 | ```
21 |
22 | 2. This app should support folling actions:
23 | - Add
24 | - Update Status
25 | - Delete
26 | 3. create folling for the same.
27 | - actionTypes
28 | - actions
29 | - reducer
30 | - store
31 |
--------------------------------------------------------------------------------
/w2/2.redux/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w2/3.react-redux/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | ### [react-redux](https://www.canva.com/design/DAFSjrBo_CQ/gIz-YdVIBrf51Q0WMVuWRg/view?utm_content=DAFSjrBo_CQ&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | - react-redux
4 | - useSelector
5 | - useDispatch
6 | - Coding
7 | - counter example
8 |
--------------------------------------------------------------------------------
/w2/3.react-redux/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Learning Goals
2 |
3 | - Redux Provider
4 | - Use useDispatch
5 | - Use useSelector
6 |
7 | ### Getting started
8 |
9 | 1. create a react application.
10 | 2. install `redux` and `react-redux`.
11 | 3. Create `actionTypes`, `actions`, `reducer` and `store`.
12 | 4. Wrap our App with react-redux -> Provider
13 |
14 | ### Task
15 |
16 | - Create a TODO App with chakra-ui and redux.
17 |
18 | - This TODO App should have following features, all of this features should be using redux.
19 |
20 | 1. User should be able to add a new Todo.
21 | 2. User should be able to toggle the status of Todo to `Completed` and `InComplete`.
22 | 3. User should be able to delete the TODO.
23 | 4. (Bonus): User should also be able to edit TODO.
24 |
--------------------------------------------------------------------------------
/w2/3.react-redux/3.live/README.md:
--------------------------------------------------------------------------------
1 | ### [react-redux](https://react-redux.js.org/)
2 |
3 | A Library that allows us to use redux with react.
4 |
5 | ### Getting started
6 |
7 | 1. `npx create-react-app lec`
8 | 2. `cd lec`
9 | 3. `npm i redux react-redux`
10 | 4. create a simple todo app.
11 | - create types
12 | - create actions
13 | - create reudcer
14 | - create store
15 | 5. Bind this with react app, by wrapping react app with react-redux provider.
16 |
17 | ```jsx
18 | //index.js
19 | import { Provider } from "react-redux";
20 | import { store } from "./redux/store";
21 |
22 | root.render(
23 |
24 |
25 |
26 | );
27 | ```
28 |
29 | 5. Now we can access this redux store in react app using react-redux hooks.
30 |
31 | - useSelector : to read values
32 |
33 | ```js
34 | import { useSelector } from "react-redux";
35 |
36 | const todos = useSelector((store) => store.todos);
37 | console.log(todos); // [{"id": 1, "value": "Todo 1", "isCompleted": false }]
38 | ```
39 |
40 | - useDispatch: gives us a dispatch fucntion used to update the redux store.
41 |
42 | ```js
43 | import { useDispatch } from "react-redux";
44 |
45 | const dispatch = useDispatch();
46 |
47 | dispatch({
48 | type: "ADD_TODO",
49 | payload: { id: 1, value: "Todo 1", isCompleted: false },
50 | });
51 | ```
52 |
--------------------------------------------------------------------------------
/w2/3.react-redux/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Learning Goals
2 |
3 | - Redux Provider
4 | - Use useDispatch
5 | - Use useSelector
6 |
7 | ### Getting started
8 |
9 | 1. create a react application.
10 | 2. install `redux` and `react-redux`.
11 | 3. Create `actionTypes`, `actions`, `reducer` and `store`.
12 | 4. Wrap our App with react-redux -> Provider
13 |
14 | ### Task
15 |
16 | - Create a Simple Calculator App with chakra-ui and redux.
17 |
18 | - The Calculator App should have following features, all of this features should be using redux.
19 |
20 | 1. User should be type numbers.
21 | 2. User should be `add`, `multiple`, `substract`, `devide` this numbers.
22 |
--------------------------------------------------------------------------------
/w2/3.react-redux/README.md:
--------------------------------------------------------------------------------
1 | ### [react-redux](https://www.canva.com/design/DAFSjrBo_CQ/gIz-YdVIBrf51Q0WMVuWRg/view?utm_content=DAFSjrBo_CQ&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | - react-redux
4 | - useSelector
5 | - useDispatch
6 | - Coding
7 | - counter example
8 | - task example
9 |
--------------------------------------------------------------------------------
/w2/4.redux-config/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | ### [Redux Configuation](https://www.canva.com/design/DAFSjrJiW5Q/d1fPeaqdgBhC9BtDyY5ipQ/view?utm_content=DAFSjrJiW5Q&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | - combinedReducer
4 | - ReduxDevTools (chrome extension)
5 | - compose
6 |
--------------------------------------------------------------------------------
/w2/4.redux-config/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Learning Goals
2 |
3 | - combineReducers
4 | - Redux DevTools
5 | - debugging
6 | - Time Travel and other features
7 | - compose
8 | - applyMiddleware
9 | - logger
10 |
11 | ### Getting started
12 |
13 | 1. create a react application.
14 | 2. install `redux` and `react-redux`.
15 | 3. Create `actionTypes`, `actions`, `reducer` and `store`.
16 | 4. Wrap our App with react-redux -> Provider
17 |
18 | ### Task
19 |
20 | Create a 2 page application.
21 |
22 | - `/` : Todo App
23 | - `/tasks`: Task App
24 |
25 | - This App should have following features, all of this features should be using redux.
26 |
27 | 1. Should have a Navbar with Home and Task tabs.
28 | 2. With the help for Redux try to manage state of this two application.
29 | 3. Inject Redux DevTools configuration so that the application is easy to debug.
30 |
--------------------------------------------------------------------------------
/w2/4.redux-config/3.live/README.md:
--------------------------------------------------------------------------------
1 | ### Learning Goals
2 |
3 | - recap
4 |
5 | - Redux DevTools
6 | - debugging
7 | - Time Travel and other features
8 | - compose
9 |
10 | - combineReducers
11 | - applyMiddleware
12 | - logger
13 |
14 | ### Getting started
15 |
16 | 1. `npm create vite@latest`.
17 | 2. Project name: `lec`
18 | 3. Select a framework: › React
19 | 4. Select a variant: › JavaScript
20 | 5. cd lec
21 | 6. `npm i redux react-redux axios`
22 | 7. `npm run dev`
23 |
24 | ### Do Following
25 |
26 | 1. Create `actionTypes`, `actions`, `reducer` and `store`.
27 | 2. Wrap our App with react-redux -> Provider.
28 | 3. create a whole todo + counter app.
29 |
--------------------------------------------------------------------------------
/w2/4.redux-config/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Learning Goals
2 |
3 | - combineReducers
4 | - Redux DevTools
5 | - debugging
6 | - Time Travel and other features
7 | - compose
8 | - applyMiddleware
9 | - logger
10 |
11 | ### Getting started
12 |
13 | 1. create a react application.
14 | 2. install `redux` and `react-redux`.
15 | 3. Create `actionTypes`, `actions`, `reducer` and `store`.
16 | 4. Wrap our App with react-redux -> Provider
17 |
18 | ### Task
19 |
20 | Create a 2 page application.
21 |
22 | - `/` : List all Products
23 | - `/cart`: Shows all Items added to cart
24 |
25 | - This App should have following features, all of this features should be using redux.
26 |
27 | 1. Should have a Navbar with Home and Cart with count.
28 | 2. User should be able to add items to cart, update count of a product in cart.
29 | 3. With the help for Redux try to manage state of this two application.
30 | 4. Inject Redux DevTools configuration so that the application is easy to debug.
31 |
--------------------------------------------------------------------------------
/w2/4.redux-config/README.md:
--------------------------------------------------------------------------------
1 | ### [Redux Configuation](https://www.canva.com/design/DAFSjrJiW5Q/d1fPeaqdgBhC9BtDyY5ipQ/view?utm_content=DAFSjrJiW5Q&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
2 |
3 | - combinedReducer
4 | - ReduxDevTools (chrome extension)
5 | - compose
6 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | ### Redux-Thunk
2 |
3 | Redux Thunk is a middleware used in Redux to handle async requests
4 |
5 | ### Getting started
6 |
7 | - `npx create-react-app record`
8 | - Note: Vite App is also fine
9 | - `npm i redux react-redux redux-thunk`
10 | - update store file
11 |
12 | ```js
13 | import { createStore, applyMiddleware } from "redux";
14 | import thunk from "redux-thunk";
15 | import rootReducer from "./reducers/index";
16 |
17 | const store = createStore(rootReducer, applyMiddleware(thunk));
18 | ```
19 |
20 | ### Goal
21 |
22 | - ## Create a Todo App with API integrations
23 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Create a Todo App with API integration on json-server
2 |
3 | ### Goal
4 |
5 | - create action types
6 | - create APIs
7 | - create actions
8 | - create reducer
9 | - integrate react-redux
10 | - integrate redux-thunk
11 |
12 | ### APIs:
13 |
14 | - GET /todos
15 | - POST /todos
16 | - PATCH /todos/:id
17 | - DELETE /todos/:id
18 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/README.md:
--------------------------------------------------------------------------------
1 | ### Redux-Thunk
2 |
3 | Redux Thunk is a middleware used in Redux to handle async requests
4 |
5 | ### Itenary
6 |
7 | - applyMiddleware
8 | - logger
9 | - async actions
10 | - how to handle them in redux
11 | - redux-thunk
12 |
13 | ### Getting started
14 |
15 | - `cd boil`
16 | - `npm i redux react-redux redux-thunk`
17 | - `json-server --watch db.json --port 8080`
18 | - in second terminal: `npm start`
19 |
20 | ### Goal
21 |
22 | - Migrate the given multi-page auth based application with API integrations to redux application.
23 |
24 | ## Redux Thunk code
25 |
26 | ```js
27 | import { createStore, applyMiddleware } from "redux";
28 | import thunk from "redux-thunk";
29 | import rootReducer from "./reducers/index";
30 |
31 | const store = createStore(rootReducer, applyMiddleware(thunk));
32 | ```
33 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/.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 | .vercel
25 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/README.md:
--------------------------------------------------------------------------------
1 | ### Instructions to follow before Starting class:
2 |
3 | ### Getting started
4 |
5 | - `npm i `
6 | - `json-server --watch db.json --port 8080`
7 | - in second terminal: `npm start`
8 |
9 | ## Note:
10 |
11 | - Go through the code to understand the structure.
12 |
13 | ### Goal
14 |
15 | - Migrate the given multi-page auth based application with API integrations to redux application.
16 |
17 | ## Redux Thunk code
18 |
19 | ```js
20 | import { createStore, applyMiddleware } from "redux";
21 | import thunk from "redux-thunk";
22 | import rootReducer from "./reducers/index";
23 |
24 | const store = createStore(rootReducer, applyMiddleware(thunk));
25 | ```
26 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "posts": [
3 | { "id": 1, "message": "POST 1" },
4 | { "id": 2, "message": "POST 2" },
5 | { "id": 3, "message": "POST 3" },
6 | { "id": 4, "message": "POST 4" }
7 | ],
8 | "feeds": [
9 | { "id": 1, "message": "Feed 1" },
10 | { "id": 2, "message": "Feed 2" },
11 | { "id": 3, "message": "Feed 3" },
12 | { "id": 4, "message": "Feed 4" }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lec",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.4",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^0.27.2",
10 | "react": "^18.1.0",
11 | "react-dom": "^18.1.0",
12 | "react-router-dom": "^6.3.0",
13 | "react-scripts": "5.0.1",
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 | "homepage": "."
41 | }
42 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w2/5.redux-thunks/3.live/boil/public/favicon.ico
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w2/5.redux-thunks/3.live/boil/public/logo192.png
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w2/5.redux-thunks/3.live/boil/public/logo512.png
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/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 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/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 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/App.js:
--------------------------------------------------------------------------------
1 | import { Route, Routes } from "react-router-dom";
2 |
3 | import RequireAuth from "./hoc/RequireAuth";
4 | import Navbar from "./components/Navbar";
5 | import Home from "./pages/Home";
6 | import Login from "./pages/Login";
7 | import Feeds from "./pages/Feeds";
8 | import Careers from "./pages/Careers";
9 | import Posts from "./pages/Posts";
10 | import "./App.css";
11 |
12 | function App() {
13 | return (
14 |
15 |
16 |
17 | } />
18 | } />
19 |
23 |
24 |
25 | }
26 | />
27 |
31 |
32 |
33 | }
34 | />
35 |
39 |
40 |
41 | }
42 | />
43 |
44 |
45 | );
46 | }
47 |
48 | export default App;
49 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/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 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/components/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useContext } from "react";
3 | import { Link, useNavigate } from "react-router-dom";
4 | import { AuthContext } from "../context/AuthContext";
5 |
6 | const Navbar = () => {
7 | const { isAuth, logout } = useContext(AuthContext);
8 | const navigate = useNavigate();
9 | const handleLoginClick = () => {
10 | // login screen
11 | if (isAuth) {
12 | logout();
13 | // he wants to logout
14 | } else {
15 | // he wants to login
16 | navigate("/login");
17 | }
18 | };
19 | return (
20 |
21 | Navbar:
22 | Home
23 | Posts
24 | Careers
25 | Feeds
26 |
30 |
31 | );
32 | };
33 |
34 | export default Navbar;
35 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/context/AuthContext.jsx:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import React, { createContext, useState } from "react";
3 | import { useEffect } from "react";
4 | import { useLocation, useNavigate } from "react-router-dom";
5 |
6 | export const AuthContext = createContext();
7 |
8 | export const AuthProvider = ({ children }) => {
9 | const [isAuth, setIsAuth] = useState(false);
10 | const navigate = useNavigate();
11 | const { state } = useLocation();
12 | const login = (creds) => {
13 | axios
14 | .post("https://reqres.in/api/login", creds)
15 | .then((d) => {
16 | setIsAuth(true);
17 | localStorage.setItem("token", d.token);
18 | if (state.from) {
19 | navigate(state.from, { replace: true });
20 | } else {
21 | navigate("/");
22 | }
23 | })
24 | .catch((e) => {
25 | console.log(e.message);
26 | setIsAuth(false);
27 | localStorage.removeItem("token");
28 | });
29 | };
30 |
31 | const logout = () => {
32 | setIsAuth(false);
33 | navigate("/");
34 | localStorage.setItem("token", "");
35 | };
36 |
37 | useEffect(() => {
38 | let token = localStorage.getItem("token");
39 | if (token) {
40 | setIsAuth(token);
41 | }
42 | }, []);
43 | return (
44 |
45 | {children}
46 |
47 | );
48 | };
49 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/hoc/RequireAuth.jsx:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { Navigate, useLocation } from "react-router-dom";
3 | import { AuthContext } from "../context/AuthContext";
4 |
5 | const RequireAuth = ({ children }) => {
6 | const { isAuth } = useContext(AuthContext);
7 | const { pathname } = useLocation();
8 |
9 | if (isAuth) {
10 | return children;
11 | } else {
12 | return (
13 | // Redirecting to Login page
14 |
20 | );
21 | }
22 | };
23 |
24 | export default RequireAuth;
25 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/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 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import { BrowserRouter } from "react-router-dom";
4 |
5 | import "./index.css";
6 | import App from "./App";
7 | import reportWebVitals from "./reportWebVitals";
8 | import { AuthProvider } from "./context/AuthContext";
9 |
10 | const root = ReactDOM.createRoot(document.getElementById("root"));
11 | root.render(
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | );
20 |
21 | // If you want to start measuring performance in your app, pass a function
22 | // to log results (for example: reportWebVitals(console.log))
23 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
24 | reportWebVitals();
25 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/pages/Careers.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Careers = () => {
4 | return Random Page without auth
;
5 | };
6 |
7 | export default Careers;
8 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/pages/Feeds.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import axios from "axios";
3 |
4 | const Feeds = () => {
5 | const [feeds, setFeeds] = useState([]);
6 |
7 | useEffect(() => {
8 | axios.get("http://localhost:8080/feeds").then((d) => {
9 | setFeeds(d.data);
10 | });
11 | }, []);
12 | return (
13 |
14 |
Feeds
15 | {feeds.map((post) => (
16 |
19 | ))}
20 |
21 | );
22 | };
23 |
24 | export default Feeds;
25 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/pages/Home.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Home = () => {
4 | return (
5 |
6 |
Homepage without auth
7 |
8 | );
9 | };
10 |
11 | export default Home;
12 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/pages/Login.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext } from "react";
2 | import { AuthContext } from "../context/AuthContext";
3 |
4 | const Login = () => {
5 | const [loginCreds, setLoginCreds] = useState({});
6 | const { login } = useContext(AuthContext);
7 |
8 | const hanldeChange = (e) => {
9 | const { name, value } = e.target;
10 | setLoginCreds({
11 | ...loginCreds,
12 | [name]: value,
13 | });
14 | };
15 |
16 | const handleSubmit = (e) => {
17 | e.preventDefault();
18 | login(loginCreds);
19 | };
20 | return (
21 |
22 | Login
23 |
47 |
48 | );
49 | };
50 |
51 | export default Login;
52 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/src/pages/Posts.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import axios from "axios";
3 |
4 | const Posts = () => {
5 | const [posts, setPosts] = useState([]);
6 |
7 | useEffect(() => {
8 | axios.get("http://localhost:8080/posts").then((d) => {
9 | setPosts(d.data);
10 | });
11 | }, []);
12 | return (
13 |
14 |
Post
15 | {posts.map((post) => (
16 |
19 | ))}
20 |
21 | );
22 | };
23 |
24 | export default Posts;
25 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/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 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/3.live/boil/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 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Create a online product sell app integration on json-server
2 |
3 | ### Getting started
4 |
5 | - create action types
6 | - create APIs
7 | - create actions
8 | - create reducer
9 | - integrate react-redux
10 | - integrate redux-thunk
11 |
12 | ### Task
13 |
14 | - User should be able to see all products.
15 | - User should be able to see add items to cart, count shown in navbar.
16 | - User should be able to see add/uodate/remove item from cart.
17 |
18 | ### APIs:
19 |
20 | - GET /products
21 | - GET /cartItems
22 | - POST /cartItems
23 | - PATCH /cartItems/:id
24 | - DELETE /cartItems/:id
25 |
--------------------------------------------------------------------------------
/w2/5.redux-thunks/README.md:
--------------------------------------------------------------------------------
1 | ### Redux-Thunk
2 |
3 | - applyMiddleware
4 | - logger
5 | - async actions
6 | - how to handle them in redux
7 | - redux-thunk
8 |
--------------------------------------------------------------------------------
/w2/6.eval/README.md:
--------------------------------------------------------------------------------
1 | ## Evaluation Assignment
2 |
--------------------------------------------------------------------------------
/w2/README.md:
--------------------------------------------------------------------------------
1 | ### `Week 2`
2 |
3 | ## Topics
4 |
5 | 1. Custom Hooks
6 | 2. Redux
7 | 3. redux-thunk
8 | 4. Redux DevTools
9 | - Chrome Extension
10 |
--------------------------------------------------------------------------------
/w3/1.nextjs/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Create a Simple Todo App without any api integration with NextJS.
2 |
--------------------------------------------------------------------------------
/w3/1.nextjs/3.live/README.md:
--------------------------------------------------------------------------------
1 | ### Introduction to NextJS
2 |
3 | NextJS is a React tool used to make server-side rendered frontend applications.
4 |
5 | ### Getting Start
6 |
7 | - `npx create-next-app@latest`
8 | - Need to install the following packages:.....Ok to proceed? (y) y
9 | - What is your project named? … lec
10 | - Would you like to use TypeScript with this project? … No / Yes - `No`
11 | - Would you like to use ESLint with this project? … No / Yes - `Yes`
12 | - cd lec
13 | - npm run dev
14 |
15 | ## Goal
16 |
17 | - Project structure
18 | - File-based routing.
19 | - [Rendering](https://nextjs.org/docs/basic-features/data-fetching/overview)
20 | - [getServerSideProps](https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props)
21 | - [Head tag](https://nextjs.org/docs/api-reference/next/head)
22 | - [Link tag](https://nextjs.org/docs/api-reference/next/link)
23 | ```jsx
24 | import Link from "next/link";
25 | Home;
26 | ```
27 | - [useRouter hook](https://nextjs.org/docs/api-reference/next/router)
28 | ```js
29 | import { useRouter } from "next/router";
30 | const router = useRouter();
31 | ```
32 |
33 | ## Coding
34 |
35 | - Build a Static multi page Website.
36 | - Routes:
37 | - `/`: Default page
38 | - `/counter`: Counter APP page
39 | - `/todo`: about page
40 | - `/404` : Not found page
41 |
--------------------------------------------------------------------------------
/w3/1.nextjs/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ## Tasks
2 |
3 | - Create an Deploy own bloggin application on vercel.
4 |
5 | 1. Project Setup
6 | 2. Build a Blog/Feeds Website.
7 | 3. Routes:
8 | - `/`: Should/lists all blogs
9 | - `/feeds`: Shows all the feeds
10 | 4. Note: Data should rednered on server.
11 |
--------------------------------------------------------------------------------
/w3/1.nextjs/README.md:
--------------------------------------------------------------------------------
1 | ### Introduction to NextJS
2 |
3 | 1. What is rendering ?
4 | 2. What is CSR ?
5 | 3. What is SSR ?
6 | 4. What is NextJS ?
7 | 5. Advantages of using NextJS ?
8 | 6. When to use NextJS ?
9 | 7. Where to use NextJS ?
10 | 8. Explain NextJS folder and file structure.
11 | 9. Explain build process in NextJS.
12 | 10. Routing
13 | - File based routing
14 | - Dynamic Routes
15 | - Link tag
16 |
17 | ### Coding
18 |
19 | - PA: Create a Simple Todo App with NextJS
20 | - Live: Create a Blogs Website.
21 | - A: Create your own blogging website.
22 |
--------------------------------------------------------------------------------
/w3/1.nextjs/assets/csr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w3/1.nextjs/assets/csr.png
--------------------------------------------------------------------------------
/w3/1.nextjs/assets/rendering.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w3/1.nextjs/assets/rendering.jpeg
--------------------------------------------------------------------------------
/w3/1.nextjs/assets/seo-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w3/1.nextjs/assets/seo-2.png
--------------------------------------------------------------------------------
/w3/1.nextjs/assets/seo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w3/1.nextjs/assets/seo.png
--------------------------------------------------------------------------------
/w3/1.nextjs/assets/ssr-csr-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w3/1.nextjs/assets/ssr-csr-1.png
--------------------------------------------------------------------------------
/w3/1.nextjs/assets/ssr-vs-csr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w3/1.nextjs/assets/ssr-vs-csr.png
--------------------------------------------------------------------------------
/w3/1.nextjs/assets/ssr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w3/1.nextjs/assets/ssr.png
--------------------------------------------------------------------------------
/w3/2.nextjs-adv/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | ### Next JS Advance
2 |
3 | ### Getting started
4 |
5 | - `npx create-next-app@latest`
6 | - Need to install the following packages:.....Ok to proceed? (y) y
7 | - What is your project named? … record
8 | - Would you like to use TypeScript with this project? … No / Yes - `No`
9 | - Would you like to use ESLint with this project? … No / Yes - `Yes`
10 | - cd record
11 | - npm run dev
12 |
13 | ### Topics
14 |
15 | - [layout](https://nextjs.org/docs/basic-features/layouts)
16 | - Single Shared Layout with Custom App
17 | - Per-Page Layouts
18 | - [Data Fetching](https://nextjs.org/docs/basic-features/data-fetching/overview)
19 | - [getServerSideProps](https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props)
20 | - [getStaticPaths](https://nextjs.org/docs/api-reference/data-fetching/get-static-paths)
21 | - [getStaticProps](https://nextjs.org/docs/api-reference/data-fetching/get-static-props)
22 | - [CSR](https://nextjs.org/docs/basic-features/data-fetching/client-side)
23 | - Routing
24 | - Dynamic Routing
25 | - Link tag vs Imperative routing
26 |
27 | ### Coding
28 |
29 | - [getStaticPaths](https://nextjs.org/docs/api-reference/data-fetching/get-static-paths): Used for creating dynamic pages.
30 | - `getStaticProps`: Used for getting data only once.
31 | - [Image Optimization](https://nextjs.org/docs/api-reference/next/image)
32 |
33 | ```jsx
34 | import Image from "next/image";
35 |
36 | const myLoader = ({ src, width, quality }) => {
37 | return `https://example.com/${src}?w=${width}&q=${quality || 75}`;
38 | };
39 |
40 | const MyImage = (props) => {
41 | return (
42 |
49 | );
50 | };
51 | ```
52 |
53 | - Static file serving
54 |
55 | - Client side rendering
56 |
--------------------------------------------------------------------------------
/w3/2.nextjs-adv/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Build a Static Blogs website
2 |
3 | Use Following
4 |
5 | - getStaticProps
6 | - getStaticPath
7 | - Dynamic Routing
8 |
--------------------------------------------------------------------------------
/w3/2.nextjs-adv/3.live/README.md:
--------------------------------------------------------------------------------
1 | ### Next JS Advance
2 |
3 | ### Getting started
4 |
5 | - `npx create-next-app@latest`
6 | - Need to install the following packages:.....Ok to proceed? (y) y
7 | - What is your project named? … record
8 | - Would you like to use TypeScript with this project? … No / Yes - `No`
9 | - Would you like to use ESLint with this project? … No / Yes - `Yes`
10 | - cd record
11 | - npm run dev
12 |
13 | ### Topics
14 |
15 | - [layout](https://nextjs.org/docs/basic-features/layouts)
16 | - Single Shared Layout with Custom App
17 | - Per-Page Layouts
18 | - [Data Fetching](https://nextjs.org/docs/basic-features/data-fetching/overview)
19 | - [getServerSideProps](https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props)
20 | - [getStaticPaths](https://nextjs.org/docs/api-reference/data-fetching/get-static-paths)
21 | - [getStaticProps](https://nextjs.org/docs/api-reference/data-fetching/get-static-props)
22 | - [CSR](https://nextjs.org/docs/basic-features/data-fetching/client-side)
23 | - Routing
24 | - Dynamic Routing
25 | - Link tag vs Imperative routing
26 |
27 | ### Coding
28 |
29 | - [getStaticPaths](https://nextjs.org/docs/api-reference/data-fetching/get-static-paths): Used for creating dynamic pages.
30 | - `getStaticProps`: Used for getting data only once.
31 | - [Image Optimization](https://nextjs.org/docs/api-reference/next/image)
32 |
33 | ```jsx
34 | import Image from "next/image";
35 |
36 | const myLoader = ({ src, width, quality }) => {
37 | return `https://example.com/${src}?w=${width}&q=${quality || 75}`;
38 | };
39 |
40 | const MyImage = (props) => {
41 | return (
42 |
49 | );
50 | };
51 | ```
52 |
53 | - Static file serving
54 |
55 | - Client side rendering
56 |
--------------------------------------------------------------------------------
/w3/2.nextjs-adv/3.live/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "blogs": [
3 | {
4 | "id": 1,
5 | "title": "Blog 1",
6 | "description": "This is blog 1",
7 | "author": "ritesh",
8 | "createdOn": 1669728310804
9 | },
10 | {
11 | "id": 2,
12 | "title": "Blog 2",
13 | "description": "This is blog 2",
14 | "author": "ritesh",
15 | "createdOn": 1669728320804
16 | },
17 | {
18 | "id": 3,
19 | "title": "Blog 3",
20 | "description": "This is blog 3",
21 | "author": "ritesh",
22 | "createdOn": 1669748310804
23 | },
24 | {
25 | "id": 4,
26 | "title": "Blog 4",
27 | "description": "This is blog 4",
28 | "author": "ritesh",
29 | "createdOn": 1669748310804
30 | }
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/w3/2.nextjs-adv/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Create a movie rating app using nextjs
2 |
3 | - create a db.json file and use this as a database {https://gist.github.com/saniyusuf/406b843afdfb9c6a86e25753fe2761f4}
4 |
5 | - Use any Chakra-UI to provide a better UI to it.
6 | - Create 3 Routes:
7 | - "/" renders all the movie data in form of a card. [Make a separate card component]
8 | - "/:id" renders one single movie's data. Also, make sure to add one Button with the label "Add to watchlist" that adds a specific movie to the watchlist. Create a separate key as "watchlists" where you will add all the movies. Reference: https://chakra-templates.dev/templates/page-sections/productDetails/simple
9 | - "/watchlist" renders all the movies that are in your watchlist in form of a table. Add a column as removed from the watchlist.
10 | - Remove from a watchlist will have a button, clicking on which the respective movie will be deleted from the db.json
11 |
--------------------------------------------------------------------------------
/w3/2.nextjs-adv/README.md:
--------------------------------------------------------------------------------
1 | ### Next JS Advance
2 |
3 | - [Data Fetching](https://nextjs.org/docs/basic-features/data-fetching/overview)
4 | - [getServerSideProps](https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props)
5 | - [getStaticPaths](https://nextjs.org/docs/api-reference/data-fetching/get-static-paths)
6 | - [getStaticProps](https://nextjs.org/docs/api-reference/data-fetching/get-static-props)
7 | - client side data fetching
8 | - layout
9 | - Single Shared Layout with Custom App
10 | - Per-Page Layouts
11 | - Routing
12 | - Dynamic Routing
13 | - Link tag vs Imperative routing
14 | - Shallow Routing
15 | - [Image Optimization](https://nextjs.org/docs/api-reference/next/image)
16 | - Font Optimization
17 | - Static File Serving
18 |
19 | ### Coding
20 |
21 | - PA: TODO
22 | - Live: TODO
23 | - A: Create a github profile
24 |
--------------------------------------------------------------------------------
/w3/3.github/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w3/3.github/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w3/3.github/README.md:
--------------------------------------------------------------------------------
1 | ### Github Actions
2 |
3 | - What is Github Actions ?
4 | - Developer Workflow usecases.
5 | - Basic Concepts:
6 | - Github Events
7 | - Github Actions
8 | - Automation
9 | - What does Github Actions Solve ?
10 | - What is CI/CD
11 | - Benefits
12 | - Demo
13 | - Workflow File
14 | - Synatx
15 |
--------------------------------------------------------------------------------
/w3/4.storybook/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | ### [Storybook](https://storybook.js.org/)
2 |
3 | Storybook is a tool for UI development. It makes development faster and easier by isolating components. This allows you to work on one component at a time. You can develop entire UIs without needing to start up a complex dev stack, force certain data into your database, or navigate around your application.
4 |
5 | ### Getting Started
6 |
7 | - Create React APP
8 | 1. `npx create-react-app record`
9 | 2. `cd record`
10 | 3. `npm i storybook`
11 | 4. `npx storybook init`
12 | 5. `npm run storybook`
13 | - Vite
14 | 1. `npm create vite@latest`.
15 | 2. Project name: `record`
16 | 3. Select a framework: › React
17 | 4. Select a variant: › JavaScript
18 | 5. cd record
19 | 6. `npx storybook init`
20 | 7. type `y` and then enter to proceed.
21 | 8. `npm run storybook`
22 |
--------------------------------------------------------------------------------
/w3/4.storybook/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Learning Goals
2 |
3 | - Storybook
4 |
5 | ### Getting started
6 |
7 | 1. create a react application.
8 | 2. install `storybook`.
9 | 3. `npx storybook init`.
10 |
11 | ### Task
12 |
13 | Create a [Navbar](https://chakra-templates.dev/templates/navigation/navbar/simple) using storybook.
14 |
15 | It accepts props followin props:
16 |
17 | ```ts
18 | type NavbarProps = {
19 | links: string[];
20 | logo: stirng;
21 | color?: stirng;
22 | bgColor?: stirng;
23 | userImage?: string;
24 | };
25 |
26 | // default values
27 | // color = black
28 | // bgColor = #4D79FF
29 | // userImage = https://images.unsplash.com/photo-1493666438817-866a91353ca9?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&fit=crop&h=200&w=200&s=b616b2c5b373a80ffc9636ba24f7a4a9
30 | ```
31 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/README.md:
--------------------------------------------------------------------------------
1 | ### [Storybook](https://storybook.js.org/)
2 |
3 | Storybook is a tool for UI development. It makes development faster and easier by isolating components. This allows you to work on one component at a time. You can develop entire UIs without needing to start up a complex dev stack, force certain data into your database, or navigate around your application.
4 |
5 | ### Getting Started
6 |
7 | - Create React APP
8 | 1. `npx create-react-app record`
9 | 2. `cd record`
10 | 3. `npm i storybook`
11 | 4. `npx storybook init`
12 | 5. `npm run storybook`
13 |
14 | - Vite
15 | 1. `npm create vite@latest`.
16 | 2. Project name: `lec`
17 | 3. Select a framework: › React
18 | 4. Select a variant: › JavaScript
19 | 5. cd lec
20 | 6. `npx storybook init`
21 | 7. type `y` and then enter to proceed.
22 | 8. If asked for npm7 migration: say `N`
23 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/.storybook/main.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
3 | addons: [
4 | "@storybook/addon-links",
5 | "@storybook/addon-essentials",
6 | "@storybook/addon-interactions",
7 | ],
8 | framework: "@storybook/react",
9 | core: {
10 | builder: "@storybook/builder-vite",
11 | },
12 | features: {
13 | storyStoreV7: true,
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/.storybook/preview-head.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/.storybook/preview.cjs:
--------------------------------------------------------------------------------
1 | export const parameters = {
2 | actions: { argTypesRegex: "^on[A-Z].*" },
3 | controls: {
4 | matchers: {
5 | color: /(background|color)$/i,
6 | date: /Date$/,
7 | },
8 | },
9 | }
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lec-ts",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview",
10 | "storybook": "start-storybook -p 6006",
11 | "build-storybook": "build-storybook"
12 | },
13 | "dependencies": {
14 | "react": "^18.2.0",
15 | "react-dom": "^18.2.0"
16 | },
17 | "devDependencies": {
18 | "@babel/core": "^7.20.12",
19 | "@storybook/addon-actions": "^6.5.15",
20 | "@storybook/addon-essentials": "^6.5.15",
21 | "@storybook/addon-interactions": "^6.5.15",
22 | "@storybook/addon-links": "^6.5.15",
23 | "@storybook/builder-vite": "^0.2.6",
24 | "@storybook/react": "^6.5.15",
25 | "@storybook/testing-library": "^0.0.13",
26 | "@types/react": "^18.0.26",
27 | "@types/react-dom": "^18.0.9",
28 | "@vitejs/plugin-react": "^3.0.0",
29 | "babel-loader": "^8.3.0",
30 | "typescript": "^4.9.3",
31 | "vite": "^4.0.0"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | }
13 | .logo:hover {
14 | filter: drop-shadow(0 0 2em #646cffaa);
15 | }
16 | .logo.react:hover {
17 | filter: drop-shadow(0 0 2em #61dafbaa);
18 | }
19 |
20 | @keyframes logo-spin {
21 | from {
22 | transform: rotate(0deg);
23 | }
24 | to {
25 | transform: rotate(360deg);
26 | }
27 | }
28 |
29 | @media (prefers-reduced-motion: no-preference) {
30 | a:nth-of-type(2) .logo {
31 | animation: logo-spin infinite 20s linear;
32 | }
33 | }
34 |
35 | .card {
36 | padding: 2em;
37 | }
38 |
39 | .read-the-docs {
40 | color: #888;
41 | }
42 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import reactLogo from './assets/react.svg'
3 | import './App.css'
4 |
5 | function App() {
6 | const [count, setCount] = useState(0)
7 |
8 | return (
9 |
10 |
18 |
Vite + React
19 |
20 |
23 |
24 | Edit src/App.tsx
and save to test HMR
25 |
26 |
27 |
28 | Click on the Vite and React logos to learn more
29 |
30 |
31 | )
32 | }
33 |
34 | export default App
35 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/MyButton/MyButton.stories.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { ComponentStory, ComponentMeta } from "@storybook/react";
3 |
4 | import MyButton from "./MyButton";
5 |
6 | export default {
7 | title: "components/MyButton",
8 | component: MyButton,
9 | } as ComponentMeta;
10 |
11 | const Template: ComponentStory = (args) => (
12 |
13 | );
14 |
15 | export const DisabledButton = Template.bind({});
16 | DisabledButton.args = {
17 | disabled: true,
18 | };
19 |
20 | export const ClickableButton = Template.bind({});
21 | ClickableButton.args = {
22 | onClick: () => console.log("Hello"),
23 | };
24 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/MyButton/MyButton.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | interface MybuttonProps {
4 | /**
5 | * If true this will disbale the button
6 | */
7 | disabled: boolean;
8 | /**
9 | * Onc click of button this function is executed
10 | */
11 | onClick: Function;
12 | }
13 | const MyButton = ({ disabled = false, onClick }: MybuttonProps) => {
14 | return (
15 |
18 | );
19 | };
20 |
21 | export default MyButton;
22 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/index.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
3 | font-size: 16px;
4 | line-height: 24px;
5 | font-weight: 400;
6 |
7 | color-scheme: light dark;
8 | color: rgba(255, 255, 255, 0.87);
9 | background-color: #242424;
10 |
11 | font-synthesis: none;
12 | text-rendering: optimizeLegibility;
13 | -webkit-font-smoothing: antialiased;
14 | -moz-osx-font-smoothing: grayscale;
15 | -webkit-text-size-adjust: 100%;
16 | }
17 |
18 | a {
19 | font-weight: 500;
20 | color: #646cff;
21 | text-decoration: inherit;
22 | }
23 | a:hover {
24 | color: #535bf2;
25 | }
26 |
27 | body {
28 | margin: 0;
29 | display: flex;
30 | place-items: center;
31 | min-width: 320px;
32 | min-height: 100vh;
33 | }
34 |
35 | h1 {
36 | font-size: 3.2em;
37 | line-height: 1.1;
38 | }
39 |
40 | button {
41 | border-radius: 8px;
42 | border: 1px solid transparent;
43 | padding: 0.6em 1.2em;
44 | font-size: 1em;
45 | font-weight: 500;
46 | font-family: inherit;
47 | background-color: #1a1a1a;
48 | cursor: pointer;
49 | transition: border-color 0.25s;
50 | }
51 | button:hover {
52 | border-color: #646cff;
53 | }
54 | button:focus,
55 | button:focus-visible {
56 | outline: 4px auto -webkit-focus-ring-color;
57 | }
58 |
59 | @media (prefers-color-scheme: light) {
60 | :root {
61 | color: #213547;
62 | background-color: #ffffff;
63 | }
64 | a:hover {
65 | color: #747bff;
66 | }
67 | button {
68 | background-color: #f9f9f9;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/Button.stories.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ComponentStory, ComponentMeta } from '@storybook/react';
3 |
4 | import { Button } from './Button';
5 |
6 | // More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
7 | export default {
8 | title: 'Example/Button',
9 | component: Button,
10 | // More on argTypes: https://storybook.js.org/docs/react/api/argtypes
11 | argTypes: {
12 | backgroundColor: { control: 'color' },
13 | },
14 | } as ComponentMeta;
15 |
16 | // More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
17 | const Template: ComponentStory = (args) => ;
18 |
19 | export const Primary = Template.bind({});
20 | // More on args: https://storybook.js.org/docs/react/writing-stories/args
21 | Primary.args = {
22 | primary: true,
23 | label: 'Button',
24 | };
25 |
26 | export const Secondary = Template.bind({});
27 | Secondary.args = {
28 | label: 'Button',
29 | };
30 |
31 | export const Large = Template.bind({});
32 | Large.args = {
33 | size: 'large',
34 | label: 'Button',
35 | };
36 |
37 | export const Small = Template.bind({});
38 | Small.args = {
39 | size: 'small',
40 | label: 'Button',
41 | };
42 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/Button.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './button.css';
3 |
4 | interface ButtonProps {
5 | /**
6 | * Is this the principal call to action on the page?
7 | */
8 | primary?: boolean;
9 | /**
10 | * What background color to use
11 | */
12 | backgroundColor?: string;
13 | /**
14 | * How large should the button be?
15 | */
16 | size?: 'small' | 'medium' | 'large';
17 | /**
18 | * Button contents
19 | */
20 | label: string;
21 | /**
22 | * Optional click handler
23 | */
24 | onClick?: () => void;
25 | }
26 |
27 | /**
28 | * Primary UI component for user interaction
29 | */
30 | export const Button = ({
31 | primary = false,
32 | size = 'medium',
33 | backgroundColor,
34 | label,
35 | ...props
36 | }: ButtonProps) => {
37 | const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
38 | return (
39 |
47 | );
48 | };
49 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/Header.stories.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ComponentStory, ComponentMeta } from '@storybook/react';
3 |
4 | import { Header } from './Header';
5 |
6 | export default {
7 | title: 'Example/Header',
8 | component: Header,
9 | parameters: {
10 | // More on Story layout: https://storybook.js.org/docs/react/configure/story-layout
11 | layout: 'fullscreen',
12 | },
13 | } as ComponentMeta;
14 |
15 | const Template: ComponentStory = (args) => ;
16 |
17 | export const LoggedIn = Template.bind({});
18 | LoggedIn.args = {
19 | user: {
20 | name: 'Jane Doe',
21 | },
22 | };
23 |
24 | export const LoggedOut = Template.bind({});
25 | LoggedOut.args = {};
26 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/Header.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { Button } from './Button';
4 | import './header.css';
5 |
6 | type User = {
7 | name: string;
8 | };
9 |
10 | interface HeaderProps {
11 | user?: User;
12 | onLogin: () => void;
13 | onLogout: () => void;
14 | onCreateAccount: () => void;
15 | }
16 |
17 | export const Header = ({ user, onLogin, onLogout, onCreateAccount }: HeaderProps) => (
18 |
56 | );
57 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/Page.stories.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ComponentStory, ComponentMeta } from '@storybook/react';
3 | import { within, userEvent } from '@storybook/testing-library';
4 | import { Page } from './Page';
5 |
6 | export default {
7 | title: 'Example/Page',
8 | component: Page,
9 | parameters: {
10 | // More on Story layout: https://storybook.js.org/docs/react/configure/story-layout
11 | layout: 'fullscreen',
12 | },
13 | } as ComponentMeta;
14 |
15 | const Template: ComponentStory = (args) => ;
16 |
17 | export const LoggedOut = Template.bind({});
18 |
19 | export const LoggedIn = Template.bind({});
20 |
21 | // More on interaction testing: https://storybook.js.org/docs/react/writing-tests/interaction-testing
22 | LoggedIn.play = async ({ canvasElement }) => {
23 | const canvas = within(canvasElement);
24 | const loginButton = await canvas.getByRole('button', { name: /Log in/i });
25 | await userEvent.click(loginButton);
26 | };
27 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/assets/code-brackets.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/assets/comments.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/assets/direction.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/assets/flow.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/assets/plugin.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/assets/repo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/assets/stackalt.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/button.css:
--------------------------------------------------------------------------------
1 | .storybook-button {
2 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
3 | font-weight: 700;
4 | border: 0;
5 | border-radius: 3em;
6 | cursor: pointer;
7 | display: inline-block;
8 | line-height: 1;
9 | }
10 | .storybook-button--primary {
11 | color: white;
12 | background-color: #1ea7fd;
13 | }
14 | .storybook-button--secondary {
15 | color: #333;
16 | background-color: transparent;
17 | box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
18 | }
19 | .storybook-button--small {
20 | font-size: 12px;
21 | padding: 10px 16px;
22 | }
23 | .storybook-button--medium {
24 | font-size: 14px;
25 | padding: 11px 20px;
26 | }
27 | .storybook-button--large {
28 | font-size: 16px;
29 | padding: 12px 24px;
30 | }
31 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/header.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
3 | border-bottom: 1px solid rgba(0, 0, 0, 0.1);
4 | padding: 15px 20px;
5 | display: flex;
6 | align-items: center;
7 | justify-content: space-between;
8 | }
9 |
10 | svg {
11 | display: inline-block;
12 | vertical-align: top;
13 | }
14 |
15 | h1 {
16 | font-weight: 900;
17 | font-size: 20px;
18 | line-height: 1;
19 | margin: 6px 0 6px 10px;
20 | display: inline-block;
21 | vertical-align: top;
22 | }
23 |
24 | button + button {
25 | margin-left: 10px;
26 | }
27 |
28 | .welcome {
29 | color: #333;
30 | font-size: 14px;
31 | margin-right: 10px;
32 | }
33 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/stories/page.css:
--------------------------------------------------------------------------------
1 | section {
2 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
3 | font-size: 14px;
4 | line-height: 24px;
5 | padding: 48px 20px;
6 | margin: 0 auto;
7 | max-width: 600px;
8 | color: #333;
9 | }
10 |
11 | section h2 {
12 | font-weight: 900;
13 | font-size: 32px;
14 | line-height: 1;
15 | margin: 0 0 4px;
16 | display: inline-block;
17 | vertical-align: top;
18 | }
19 |
20 | section p {
21 | margin: 1em 0;
22 | }
23 |
24 | section a {
25 | text-decoration: none;
26 | color: #1ea7fd;
27 | }
28 |
29 | section ul {
30 | padding-left: 30px;
31 | margin: 1em 0;
32 | }
33 |
34 | section li {
35 | margin-bottom: 8px;
36 | }
37 |
38 | section .tip {
39 | display: inline-block;
40 | border-radius: 1em;
41 | font-size: 11px;
42 | line-height: 12px;
43 | font-weight: 700;
44 | background: #e7fdd8;
45 | color: #66bf3c;
46 | padding: 4px 12px;
47 | margin-right: 10px;
48 | vertical-align: top;
49 | }
50 |
51 | section .tip-wrapper {
52 | font-size: 13px;
53 | line-height: 20px;
54 | margin-top: 40px;
55 | margin-bottom: 40px;
56 | }
57 |
58 | section .tip-wrapper svg {
59 | display: inline-block;
60 | height: 12px;
61 | width: 12px;
62 | margin-right: 4px;
63 | vertical-align: top;
64 | margin-top: 3px;
65 | }
66 |
67 | section .tip-wrapper svg path {
68 | fill: #1ea7fd;
69 | }
70 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx"
18 | },
19 | "include": ["src"],
20 | "references": [{ "path": "./tsconfig.node.json" }]
21 | }
22 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/w3/4.storybook/3.live/lec-ts/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/w3/4.storybook/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### Learning Goals
2 |
3 | - Storybook
4 |
5 | ### Getting started
6 |
7 | 1. create a react application.
8 | 2. install `storybook`.
9 | 3. `npx storybook init`.
10 |
11 | ### Task
12 |
13 | 1. Create a [Testimonial](https://chakra-templates.dev/templates/page-sections/testimonials/withSpeechBubbles) using storybook.
14 |
15 | - It accepts props followin props:
16 |
17 | ```ts
18 | type NavbarProps = {
19 | heading: string:
20 | subHeading: string:
21 | testimonials: {
22 | userName: string;
23 | userImage: string;
24 | userDesignation: string;
25 | title: string;
26 | comment: string;
27 | }[];
28 | };
29 | ```
30 |
31 | - Create following stories.
32 |
33 | 1. Story for Simple Testimonials
34 | 2. Testimonails with very long comments(5000-6000 characters.)
35 | - Have fixed height, height does not change as per comment length.
36 | - if more than 5 lines of comment is found then add scroll bar in the box.
37 |
38 | 2. (Bonus) Create a [Footer](https://chakra-templates.dev/templates/page-sections/footer/largeWithNewsletter) with 4 columns.
39 | - Column 1: Has the company logo, patent, social media links / buttons
40 | - Column 2: Has the title "Company" and links like: [About us, Blog, Contact us, pricing, testimonials]
41 | - Column 3: Has the title "Support" and links [Help Center, Terms of service, Legal, Privacy Policy, Status]
42 | - Column 4: Has the title "Stay up to data" and has one input with submit button where the user can type his/her emial address.
43 | - **_NOTE_**: Props and propTypes you have to decide on your own
44 |
--------------------------------------------------------------------------------
/w3/4.storybook/README.md:
--------------------------------------------------------------------------------
1 | ### [Storybook](https://storybook.js.org/)
2 |
3 | Storybook is a tool for UI development. It makes development faster and easier by isolating components. This allows you to work on one component at a time. You can develop entire UIs without needing to start up a complex dev stack, force certain data into your database, or navigate around your application.
4 |
5 | - What is Storybook ?
6 | - Why do we use it ?
7 | - How do we use it ?
8 |
9 | - Coding
10 | - PC: Button, Header, Page
11 | - PA: Navbar
12 | - Live:
13 | - A: Testimonials, Footer
14 |
--------------------------------------------------------------------------------
/w3/README.md:
--------------------------------------------------------------------------------
1 | ### `Week 3`
2 |
3 | ## Topics
4 |
5 | 1. Storybook
6 | 2. Introduction to NextJS
7 | 3. Advance NextJS
8 | 4. Github CICD
9 |
--------------------------------------------------------------------------------
/w4/1.performance/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/README.md:
--------------------------------------------------------------------------------
1 | ## What is Memoization?
2 |
3 | - Memoization is a speed optimization technique in programming, given a function, you return a cached version of the output if the same inputs are used.
4 | - A Memorized function remembers the results of output for a given t of inputs.
5 | - In React we can memorize
6 |
7 | - component.
8 | - function.
9 | - or just a regular component value/variable.
10 |
11 | - By Default React does a Shallow comparison of variables/props/functions, if react sees that a reference to a variable has been changed, react will re-render that element.
12 |
13 | ## Component Memoization
14 |
15 | When we memoize a Component, we have to make sure that we avoid shallow comparison.
16 |
17 | - `Note`: Memoization is not free, we trade for Space to save time.
18 |
19 | ## Topics:
20 |
21 | - useMemo
22 | - memo
23 | - useCallback
24 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "boil",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "react": "^18.2.0",
13 | "react-dom": "^18.2.0"
14 | },
15 | "devDependencies": {
16 | "@types/react": "^18.0.24",
17 | "@types/react-dom": "^18.0.8",
18 | "@vitejs/plugin-react": "^2.2.0",
19 | "typescript": "^4.6.4",
20 | "vite": "^3.2.3"
21 | }
22 | }
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | }
13 | .logo:hover {
14 | filter: drop-shadow(0 0 2em #646cffaa);
15 | }
16 | .logo.react:hover {
17 | filter: drop-shadow(0 0 2em #61dafbaa);
18 | }
19 |
20 | @keyframes logo-spin {
21 | from {
22 | transform: rotate(0deg);
23 | }
24 | to {
25 | transform: rotate(360deg);
26 | }
27 | }
28 |
29 | @media (prefers-reduced-motion: no-preference) {
30 | a:nth-of-type(2) .logo {
31 | animation: logo-spin infinite 20s linear;
32 | }
33 | }
34 |
35 | .card {
36 | padding: 2em;
37 | }
38 |
39 | .read-the-docs {
40 | color: #888;
41 | }
42 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | import Counter from "./components/Counter";
4 | import TodoApp from "./components/TodoApp";
5 | import "./App.css";
6 |
7 | function App() {
8 | const [answer, setAnswer] = useState();
9 | const [value, setValue] = useState(0);
10 |
11 | const fibo = (n: number): number => {
12 | if (n <= 1) return n;
13 | return fibo(n - 1) + fibo(n - 1);
14 | };
15 |
16 | const calc = () => {
17 | console.time("t1");
18 | let result = fibo(value);
19 | console.timeEnd("t1");
20 |
21 | setAnswer(result);
22 | };
23 | return (
24 |
25 |
26 |
{answer}
27 |
28 | setValue(Number(e.target.value))}
32 | />
33 |
34 |
35 |
36 |
37 |
38 |
39 | );
40 | }
41 |
42 | export default App;
43 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/src/components/Counter.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | const Counter = () => {
4 | console.log("CounterApp");
5 | const [count, setCount] = useState(10);
6 |
7 | const increment = (value: number = 1) => setCount(count + value);
8 | const decrement = (value: number = 1) => setCount(count - value);
9 |
10 | return (
11 |
12 |
Counter: {count}
13 |
14 |
15 |
16 |
17 |
18 | );
19 | };
20 |
21 | export default Counter;
22 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/src/components/TodoApp.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | import TodoItem from "./TodoItem";
4 | import TodoInput from "./TodoInput";
5 |
6 | type Todo = {
7 | id: number;
8 | content: string;
9 | isCompleted: boolean;
10 | };
11 |
12 | const TodoApp = () => {
13 | console.log("TodoApp");
14 | const [todos, setTodos] = useState([
15 | { id: 1, content: "hello", isCompleted: false },
16 | { id: 2, content: "welcome", isCompleted: true },
17 | ]);
18 |
19 | const onAdd = (content: string) => {
20 | setTodos([
21 | ...todos,
22 | {
23 | id: todos.length + 1,
24 | content,
25 | isCompleted: false,
26 | },
27 | ]);
28 | };
29 | return (
30 |
31 | Todos : {todos.length}
32 |
33 |
34 |
35 | {todos.map((todo) => (
36 |
37 | ))}
38 |
39 | );
40 | };
41 |
42 | export default TodoApp;
43 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/src/components/TodoInput.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | type TodoInputProp = {
3 | onAdd: Function;
4 | };
5 | const TodoInput = ({ onAdd }: TodoInputProp) => {
6 | const [value, setValue] = useState("");
7 | return (
8 |
9 | setValue(e.target.value)}
13 | />
14 |
25 |
26 | );
27 | };
28 |
29 | export default TodoInput;
30 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/src/components/TodoItem.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | type TodoItemProp = {
4 | id: number;
5 | content: string;
6 | isCompleted: boolean;
7 | };
8 |
9 | const TodoItem = ({ id, content, isCompleted }: TodoItemProp) => {
10 | return (
11 |
14 |
15 | {content} - {isCompleted ? "Done" : "Not Done"}
16 |
17 |
18 | );
19 | };
20 |
21 | export default TodoItem;
22 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/src/index.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
3 | font-size: 16px;
4 | line-height: 24px;
5 | font-weight: 400;
6 |
7 | color-scheme: light dark;
8 | color: rgba(255, 255, 255, 0.87);
9 | background-color: #242424;
10 |
11 | font-synthesis: none;
12 | text-rendering: optimizeLegibility;
13 | -webkit-font-smoothing: antialiased;
14 | -moz-osx-font-smoothing: grayscale;
15 | -webkit-text-size-adjust: 100%;
16 | }
17 |
18 | a {
19 | font-weight: 500;
20 | color: #646cff;
21 | text-decoration: inherit;
22 | }
23 | a:hover {
24 | color: #535bf2;
25 | }
26 |
27 | body {
28 | margin: 0;
29 | display: flex;
30 | place-items: center;
31 | min-width: 320px;
32 | min-height: 100vh;
33 | }
34 |
35 | h1 {
36 | font-size: 3.2em;
37 | line-height: 1.1;
38 | }
39 |
40 | button {
41 | border-radius: 8px;
42 | border: 1px solid transparent;
43 | padding: 0.6em 1.2em;
44 | font-size: 1em;
45 | font-weight: 500;
46 | font-family: inherit;
47 | background-color: #1a1a1a;
48 | cursor: pointer;
49 | transition: border-color 0.25s;
50 | }
51 | button:hover {
52 | border-color: #646cff;
53 | }
54 | button:focus,
55 | button:focus-visible {
56 | outline: 4px auto -webkit-focus-ring-color;
57 | }
58 |
59 | @media (prefers-color-scheme: light) {
60 | :root {
61 | color: #213547;
62 | background-color: #ffffff;
63 | }
64 | a:hover {
65 | color: #747bff;
66 | }
67 | button {
68 | background-color: #f9f9f9;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
7 |
8 |
9 |
10 | )
11 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx"
18 | },
19 | "include": ["src"],
20 | "references": [{ "path": "./tsconfig.node.json" }]
21 | }
22 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/w4/1.performance/3.live/boil/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()]
7 | })
8 |
--------------------------------------------------------------------------------
/w4/1.performance/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w4/1.performance/README.md:
--------------------------------------------------------------------------------
1 | ## What is Memorization?
2 |
3 | - Memorization is a speed optimization technique in programming, given a function, you return a cached version of the output if the same inputs are used.
4 | - A Memorized function remembers the results of output for a given t of inputs.
5 | - In React we can memorize
6 |
7 | - component.
8 | - function.
9 | - or just a regular component value/variable.
10 |
11 | - By Default React does a Shallow comparison of variables/props/functions, if react sees that a reference to a variable has been changed, react will re-render that element.
12 |
13 | ## Component Memorization
14 |
15 | When we memorize a Component, we have to make sure that we avoid shallow comparison.
16 |
17 | - `Note`: Memorization is not free, we trade for Space to save time.
18 |
19 | ## Topics:
20 |
21 | - useMemo
22 | - memo
23 | - useCallback
24 |
--------------------------------------------------------------------------------
/w4/2.react-testing/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/.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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lec",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.4",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "react": "^18.2.0",
10 | "react-dom": "^18.2.0",
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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/2.react-testing/3.live/boil-1/public/favicon.ico
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/2.react-testing/3.live/boil-1/public/logo192.png
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/2.react-testing/3.live/boil-1/public/logo512.png
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/src/App.js:
--------------------------------------------------------------------------------
1 | import logo from "./logo.svg";
2 | import "./App.css";
3 | import Button from "./components/Button/Button";
4 |
5 | function App() {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
13 | export default App;
14 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/src/components/Button/Button.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Button = () => {
4 | return Button
;
5 | };
6 |
7 | export default Button;
8 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/src/components/Counter/Counter.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | const Counter = () => {
4 | const [countx, setCountX] = useState(0);
5 |
6 | return (
7 |
8 | Counter
9 |
{countx}
10 |
11 |
17 |
20 |
21 |
22 | );
23 | };
24 |
25 | export default Counter;
26 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-1/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/.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 | # Mock Data
26 | src/initialData.json
27 |
28 | # Testing
29 | # cypress/
30 | cypress.config.ts
31 | results.json
32 | submissions.json
33 | # Local Netlify folder
34 | .netlify
35 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/initialData.json:
--------------------------------------------------------------------------------
1 | [
2 | { "id": 1, "type": "Completed", "message": "useState", "likes": 2 },
3 | { "id": 2, "type": "Completed", "message": "useEffect", "likes": 3 },
4 | { "id": 3, "type": "Pending", "message": "useRef", "likes": 0 },
5 | { "id": 4, "type": "Revision", "message": "useReducer", "likes": 5 },
6 | { "id": 5, "type": "Revision", "message": "React-101", "likes": 2 },
7 | { "id": 5, "type": "New", "message": "Custom Hooks", "likes": 2 }
8 | ]
9 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sol",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@chakra-ui/react": "^2.4.1",
7 | "@emotion/react": "^11.10.5",
8 | "@emotion/styled": "^11.10.5",
9 | "@testing-library/jest-dom": "^5.16.5",
10 | "@testing-library/react": "^13.4.0",
11 | "@testing-library/user-event": "^13.5.0",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "^16.18.3",
14 | "@types/react": "^18.0.25",
15 | "@types/react-dom": "^18.0.9",
16 | "axios": "^1.1.3",
17 | "framer-motion": "^7.6.7",
18 | "react": "^18.2.0",
19 | "react-dom": "^18.2.0",
20 | "react-icons": "^4.6.0",
21 | "react-scripts": "5.0.1",
22 | "styled-components": "^5.3.6",
23 | "typescript": "^4.9.3",
24 | "web-vitals": "^2.1.4"
25 | },
26 | "scripts": {
27 | "start": "react-scripts start",
28 | "build": "react-scripts build",
29 | "test": "react-scripts test",
30 | "eject": "react-scripts eject"
31 | },
32 | "eslintConfig": {
33 | "extends": [
34 | "react-app",
35 | "react-app/jest"
36 | ]
37 | },
38 | "browserslist": {
39 | "production": [
40 | ">0.2%",
41 | "not dead",
42 | "not op_mini all"
43 | ],
44 | "development": [
45 | "last 1 chrome version",
46 | "last 1 firefox version",
47 | "last 1 safari version"
48 | ]
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/2.react-testing/3.live/boil-2/public/favicon.ico
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/2.react-testing/3.live/boil-2/public/logo192.png
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/2.react-testing/3.live/boil-2/public/logo512.png
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Box } from "@chakra-ui/react";
3 |
4 | import TopicsBoard from "./components/TopicsBoard";
5 | import "./App.css";
6 |
7 | function App() {
8 | return (
9 |
10 |
11 |
12 | );
13 | }
14 |
15 | export default App;
16 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/components/TopicInput.tsx:
--------------------------------------------------------------------------------
1 | import React, { useContext, useState } from "react";
2 | import { Button, Card, CardBody, Flex, Input } from "@chakra-ui/react";
3 | import { BiSave } from "react-icons/bi";
4 | import { MdOutlineCancel } from "react-icons/md";
5 |
6 | import { TopicType } from "../constants";
7 | import { TopicsContext } from "../context/TopicsContext";
8 |
9 | type TopicInputProps = {
10 | type: TopicType;
11 | onCancel: () => void;
12 | };
13 | const TopicInput = ({ type, onCancel }: TopicInputProps) => {
14 | const [value, setValue] = useState("");
15 | const { addTopic } = useContext(TopicsContext);
16 |
17 | const handleChange = (e: React.ChangeEvent) => {
18 | setValue(e.target.value);
19 | };
20 |
21 | const handleSave = () => {
22 | addTopic && addTopic(value, type);
23 | };
24 | return (
25 |
26 |
27 |
28 |
36 |
37 | }
41 | onClick={handleSave}
42 | data-testid="save-topic-btn"
43 | >
44 | Save
45 |
46 | }
50 | onClick={onCancel}
51 | data-testid="cancel-add-topic-btn"
52 | >
53 | Cancel
54 |
55 |
56 |
57 |
58 |
59 | );
60 | };
61 |
62 | export default TopicInput;
63 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/components/TopicItem.tsx:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { Button, Card, CardBody, Flex, Heading } from "@chakra-ui/react";
3 | import { BiLike, BiTrash } from "react-icons/bi";
4 |
5 | import { TopicsContext } from "../context/TopicsContext";
6 | import { Topic, topicInfo } from "../constants";
7 |
8 | interface TopicItemProps extends Topic {}
9 |
10 | const TopicItem = (props: TopicItemProps) => {
11 | const info = topicInfo[props.type];
12 | const { likeTopic, deleteTopic } = useContext(TopicsContext);
13 | const updateLikeCountHandle = async () => {
14 | likeTopic && likeTopic(props.id, props.likes + 1);
15 | };
16 | const onDeleteHandle = async () => {
17 | deleteTopic && deleteTopic(props.id);
18 | };
19 | return (
20 |
21 |
22 |
23 | {props.message}
24 |
25 |
26 | }
30 | onClick={updateLikeCountHandle}
31 | data-testid="like-topic-btn"
32 | >
33 | ({props.likes}) Likes
34 |
35 | }
39 | onClick={onDeleteHandle}
40 | data-testid="delete-topic-btn"
41 | >
42 | Delete
43 |
44 |
45 |
46 |
47 | );
48 | };
49 |
50 | export default TopicItem;
51 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/components/TopicSection.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import {
3 | Button,
4 | Card,
5 | CardBody,
6 | CardFooter,
7 | CardHeader,
8 | Flex,
9 | Heading,
10 | } from "@chakra-ui/react";
11 | import { Topic, topicInfo, TopicType } from "../constants";
12 | import TopicItem from "./TopicItem";
13 | import TopicInput from "./TopicInput";
14 | import { BiMessageSquareAdd } from "react-icons/bi";
15 |
16 | type TopicSectionProps = {
17 | topicType: TopicType;
18 | topics: Topic[];
19 | };
20 |
21 | const TopicSection = ({ topicType, topics }: TopicSectionProps) => {
22 | const [addNew, setAddNew] = useState(false);
23 | const info = topicInfo[topicType];
24 |
25 | useEffect(() => {
26 | if (addNew) {
27 | setAddNew(false);
28 | }
29 | // eslint-disable-next-line react-hooks/exhaustive-deps
30 | }, [topics]);
31 |
32 | return (
33 |
37 |
38 |
39 | {info.title}
40 |
41 |
42 |
43 |
44 | {topics.map((topic) => (
45 |
46 | ))}
47 | {addNew && (
48 | setAddNew(false)} />
49 | )}
50 |
51 |
52 |
53 | }
57 | disabled={addNew}
58 | onClick={() => setAddNew(true)}
59 | data-testid="topic-add-btn"
60 | >
61 | Add New
62 |
63 |
64 |
65 | );
66 | };
67 |
68 | export default TopicSection;
69 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/components/TopicsBoard.tsx:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import {
3 | Center,
4 | Container,
5 | Divider,
6 | Heading,
7 | SimpleGrid,
8 | } from "@chakra-ui/react";
9 |
10 | import { TopicsContext } from "../context/TopicsContext";
11 | import TopicSection from "./TopicSection";
12 |
13 | import { Topic, TopicType } from "../constants";
14 |
15 | const TopicsBoard = () => {
16 | const { topics } = useContext(TopicsContext);
17 | return (
18 |
19 |
20 | Topics Board
21 |
22 | Total topics: {topics.length}
23 |
24 |
25 |
26 |
27 | {Object.values(TopicType).map((topic) => (
28 | topicItem.type === topic
33 | )}
34 | />
35 | ))}
36 |
37 |
38 | );
39 | };
40 |
41 | export default TopicsBoard;
42 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/constants.ts:
--------------------------------------------------------------------------------
1 | export enum TopicType {
2 | Pending = "Pending",
3 | Completed = "Completed",
4 | Revision = "Revision",
5 | New = "New",
6 | }
7 |
8 | export type Topic = {
9 | id: number;
10 | type: TopicType;
11 | message: string;
12 | likes: number;
13 | };
14 |
15 | export type TopicInfo = {
16 | title: string;
17 | sectionBgColor: string;
18 | itemBgColor: string;
19 | };
20 |
21 | export const topicInfo: Record = {
22 | Pending: {
23 | title: "Pending Topics...",
24 | sectionBgColor: "red.200",
25 | itemBgColor: "red.500",
26 | },
27 | Completed: {
28 | title: "Completed Topics...",
29 | sectionBgColor: "green.200",
30 | itemBgColor: "green.500",
31 | },
32 | Revision: {
33 | title: "Topics needing revision...",
34 | sectionBgColor: "blue.200",
35 | itemBgColor: "blue.500",
36 | },
37 | New: {
38 | title: "New Topics....",
39 | sectionBgColor: "yellow.200",
40 | itemBgColor: "yellow.500",
41 | },
42 | };
43 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/context/TopicsContext.tsx:
--------------------------------------------------------------------------------
1 | import React, { createContext, useState } from "react";
2 |
3 | import { Topic, TopicType } from "../constants";
4 | import initialTopics from "../initialData.json";
5 |
6 | type TopicsContextProps = {
7 | topics: Topic[];
8 | addTopic?: (value: string, type: TopicType) => void;
9 | likeTopic?: (id: number, newLikesCount: number) => void;
10 | deleteTopic?: (id: number) => void;
11 | };
12 |
13 | export const TopicsContext = createContext({
14 | topics: [],
15 | });
16 |
17 | const TopicsProviders = ({ children }: { children: React.ReactNode }) => {
18 | const [topics, setTopics] = useState(initialTopics as Topic[]);
19 |
20 | const addTopic = async (message: string, type: TopicType) => {
21 | setTopics([
22 | ...topics,
23 | {
24 | id: Date.now(),
25 | message,
26 | type,
27 | likes: 0,
28 | },
29 | ]);
30 | };
31 |
32 | const likeTopic = async (id: number, newLikesCount: number) => {
33 | let updatedTopics = topics.map((topic) => {
34 | if (topic.id === id) {
35 | topic.likes = newLikesCount;
36 | }
37 | return topic;
38 | });
39 | setTopics(updatedTopics);
40 | };
41 |
42 | const deleteTopic = (id: number) => {
43 | let updatedTopics = topics.filter((topic) => topic.id !== id);
44 | setTopics(updatedTopics);
45 | };
46 |
47 | return (
48 |
51 | {children}
52 |
53 | );
54 | };
55 |
56 | export default TopicsProviders;
57 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/index.tsx:
--------------------------------------------------------------------------------
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 | import { ChakraProvider } from "@chakra-ui/react";
7 | import TopicsProviders from "./context/TopicsContext";
8 |
9 | const root = ReactDOM.createRoot(
10 | document.getElementById("root") as HTMLElement
11 | );
12 | root.render(
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | );
21 |
22 | // If you want to start measuring performance in your app, pass a function
23 | // to log results (for example: reportWebVitals(console.log))
24 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
25 | reportWebVitals();
26 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/src/setupTests.ts:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/w4/2.react-testing/3.live/boil-2/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/w4/2.react-testing/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w4/2.react-testing/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w4/3.cypress/1.pre-class/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w4/3.cypress/2.pre-assignment/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/.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 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "todos": []
3 | }
4 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "boil",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^1.2.1",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.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 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/3.cypress/3.live/boil/public/favicon.ico
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/3.cypress/3.live/boil/public/logo192.png
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/3.cypress/3.live/boil/public/logo512.png
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/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 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/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 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/src/App.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./App.css";
3 | import TodoApp from "./components/TodoApp";
4 |
5 | function App() {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
13 | export default App;
14 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/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 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/src/components/TodoApp.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import axios from "axios";
3 | import TodoInput from "./TodoInput";
4 | import TodoList from "./TodoList";
5 | import { useEffect } from "react";
6 |
7 | const TodoApp = () => {
8 | const [value, setValue] = useState("");
9 | const [todos, setTodos] = useState([]);
10 |
11 | const handleChange = (e) => {
12 | setValue(e.target.value);
13 | };
14 |
15 | const handleSubmit = async () => {
16 | let resp = await axios.post("http://localhost:4004/todos", {
17 | value: value,
18 | isCompleted: true,
19 | });
20 | setTodos([...todos, resp.data]);
21 | setValue("");
22 | };
23 |
24 | useEffect(() => {
25 | axios.get("http://localhost:4004/todos").then((r) => {
26 | setTodos(r.data);
27 | });
28 | }, []);
29 | return (
30 |
31 |
TodoApp
32 |
37 |
38 |
39 | );
40 | };
41 |
42 | export default TodoApp;
43 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/src/components/TodoInput.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const TodoInput = ({ value, handleChange, handleSubmit }) => {
4 | const submit = (e) => {
5 | e.preventDefault();
6 | handleSubmit();
7 | };
8 | return (
9 |
22 | );
23 | };
24 |
25 | export default TodoInput;
26 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/src/components/TodoList.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const TodoList = ({ todos = [] }) => {
4 | return (
5 |
6 | {todos.map((todo) => (
7 |
8 |
13 | {todo.value}
14 |
15 | ))}
16 |
17 | );
18 | };
19 |
20 | export default TodoList;
21 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/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 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/src/index.jsx:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/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 |
--------------------------------------------------------------------------------
/w4/3.cypress/3.live/boil/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 |
--------------------------------------------------------------------------------
/w4/3.cypress/4.assignment/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w4/3.cypress/README.md:
--------------------------------------------------------------------------------
1 | ### TODO
2 |
--------------------------------------------------------------------------------
/w4/4.psc/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.defaultFormatter": "esbenp.prettier-vscode",
3 | "editor.formatOnSave": true,
4 | "[javascript]": {
5 | "editor.defaultFormatter": "esbenp.prettier-vscode",
6 | "editor.formatOnSave": true
7 | },
8 | "workbench.iconTheme": "vscode-icons",
9 | "terminal.integrated.scrollback": 100000,
10 | "window.zoomLevel": 3,
11 | "typescript.enablePromptUseWorkspaceTsdk": true,
12 | "typescript.tsdk": "node_modules/typescript/lib"
13 | }
14 |
--------------------------------------------------------------------------------
/w4/4.psc/README.md:
--------------------------------------------------------------------------------
1 | ### `PSC`
2 |
3 | ## Topics
4 |
5 | 1. Typescript
6 | 2. NextJS
7 | - SSR
8 | - SSG
9 | 3. Redux
10 | 4. Testing
11 | 5. Chakra
12 | 6. Git Actions
13 |
14 | ## Getting Started
15 |
16 | 1. `npx create-next-app@latest lec`.
17 | 2. `cd lec`.
18 | 3. `npm i redux react-redux redux-thunk axios`.
19 | 4. `npm install @chakra-ui/react @emotion/react @emotion/styled framer-motion react-icons`.
20 | 5. Wrap `_app.tsx` file with Chakra Provider.
21 | 6. Copy paste folders from ref:
22 | - folders
23 | - `public` replace
24 | - `src/components` add
25 | - `src/styles` replace
26 | - `src/utils` replace
27 | - files
28 | - `next.config.js` replace
29 | - `src/pages/_app.tsx` replace
30 | - `src/pages/index.tsx` remove all code from this file, just a basic component
31 |
32 | ## Thinking
33 |
34 | 1. How many Pages do we need ?
35 |
36 | - 2 Pages: "Products Listing Page" "Product Details Page"
37 |
38 | 2. How many Components do we need and what are those ?
39 |
40 | - Shared
41 | - Header
42 | - Cart
43 | - Footer
44 | - Homepage
45 | - ProductCart
46 | - ProductDetails
47 |
48 | 3. How many API's do we need ?
49 |
50 | - GET /products
51 | - GET /cartItems
52 | - GET /products/[id]
53 | - POST /cartItems
54 | - PATCH /cartItems/[id] //increment and decrement quantity
55 | - DELETE /cartItems/[id]
56 |
57 | 4. How to get Started ?
58 |
59 | - (Option 1): Create Redux Logic
60 | - (Option 2): Create TSX Component
61 | - (Option 3): Create Backend Data
62 |
63 | A: 312
64 |
65 | - [Create backend Data](./lec/db.json)
66 | - Create Redux
67 | - How many reducers do we need ? : 2
68 | - create all the files
69 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.defaultFormatter": "esbenp.prettier-vscode",
3 | "editor.formatOnSave": true,
4 | "[javascript]": {
5 | "editor.defaultFormatter": "esbenp.prettier-vscode",
6 | "editor.formatOnSave": true
7 | },
8 | "workbench.iconTheme": "vscode-icons",
9 | "terminal.integrated.scrollback": 100000,
10 | "window.zoomLevel": 3,
11 | "typescript.enablePromptUseWorkspaceTsdk": true
12 | }
13 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/components/Cart.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | Button,
4 | useDisclosure,
5 | Drawer,
6 | DrawerBody,
7 | DrawerCloseButton,
8 | DrawerContent,
9 | DrawerHeader,
10 | DrawerOverlay,
11 | Box,
12 | DrawerFooter,
13 | } from "@chakra-ui/react";
14 | import { BsBag } from "react-icons/bs";
15 |
16 | const Cart = () => {
17 | const { isOpen, onOpen, onClose } = useDisclosure();
18 | const btnRef = React.useRef(null);
19 | return (
20 |
21 |
36 |
43 |
44 |
45 |
46 | Shopping Cart
47 | TODO
48 |
49 |
58 |
59 |
60 |
61 |
62 |
63 | );
64 | };
65 |
66 | export default Cart;
67 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/components/CustomImage.tsx:
--------------------------------------------------------------------------------
1 | import NextImage from "next/image";
2 | import { chakra } from "@chakra-ui/react";
3 |
4 | const CustomImage = chakra(NextImage, {
5 | baseStyle: { maxH: 120, maxW: 120 },
6 | shouldForwardProp: (prop) => ["width", "height", "src", "alt"].includes(prop),
7 | });
8 |
9 | export default CustomImage;
10 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/components/Footer.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 | import { Box } from "@chakra-ui/react";
4 | import { FaGithub } from "react-icons/fa";
5 |
6 | import CustomImage from "./CustomImage";
7 |
8 | const Footer = () => {
9 | return (
10 |
21 |
22 |
23 |
29 |
30 |
31 |
37 |
38 | Source
39 |
40 |
41 |
42 |
43 | );
44 | };
45 |
46 | export default Footer;
47 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/components/Header.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 | import { Box } from "@chakra-ui/react";
4 |
5 | import CustomImage from "./CustomImage";
6 | import Cart from "./Cart";
7 |
8 | const Header = () => {
9 | return (
10 |
18 |
25 |
34 |
35 |
36 |
37 |
38 |
44 |
45 |
46 |
47 |
48 | );
49 | };
50 |
51 | export default Header;
52 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/components/NextSEO.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Head from "next/head";
3 |
4 | export type NextSEOProps = {
5 | url: URL;
6 | title: string;
7 | description: string;
8 | ogImage?: string;
9 | };
10 |
11 | const NextSEO = ({ description, ogImage, title, url }: NextSEOProps) => {
12 | return (
13 |
14 | {title}
15 |
16 |
17 |
18 | {/* Facebook Meta Tags */}
19 |
20 |
21 |
22 |
23 | {ogImage && }
24 |
25 | {/* Twitter Meta Tags */}
26 |
27 |
28 |
29 |
30 |
31 | {ogImage && }
32 |
33 | );
34 | };
35 |
36 | export default NextSEO;
37 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | images: {
5 | unoptimized: true,
6 | domains: ["merch-clone.s3.ap-south-1.amazonaws.com"],
7 | },
8 | };
9 |
10 | module.exports = nextConfig;
11 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import type { AppProps } from "next/app";
3 | import { ChakraProvider } from "@chakra-ui/react";
4 | import { Provider } from "react-redux";
5 |
6 | import Header from "../components/Header";
7 | import Footer from "../components/Footer";
8 |
9 | import { store } from "../redux/store";
10 |
11 | // css
12 | import "../styles/global.css";
13 |
14 | export default function App({ Component, pageProps }: AppProps) {
15 | return (
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { Box } from "@chakra-ui/react";
4 |
5 | import NextSEO from "../components/NextSEO";
6 | import ProductCard from "../components/ProductCart";
7 |
8 | import data from "../db.json";
9 |
10 | export default function Home() {
11 | return (
12 | <>
13 |
19 |
20 |
27 |
38 | {data.products.map((product: any) => (
39 |
40 | ))}
41 |
42 |
43 |
44 | >
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/pages/products/[product].tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 | import { Box, Text } from "@chakra-ui/react";
4 | import { MdKeyboardBackspace } from "react-icons/md";
5 |
6 | import NextSEO from "../../components/NextSEO";
7 | import ProductDetails from "../../components/ProductDetails";
8 | import data from "../../db.json";
9 |
10 | const Prodcut = () => {
11 | const product: any = data.products[0];
12 | return (
13 | <>
14 |
20 |
30 |
31 |
42 |
43 | Back to shop
44 |
45 |
46 |
47 |
48 | >
49 | );
50 | };
51 |
52 | export default Prodcut;
53 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/4.psc/ref/public/favicon.ico
--------------------------------------------------------------------------------
/w4/4.psc/ref/public/header_bg.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/public/og-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/riteshf/RCT-201/b0c1888d5a5f73269b5252ac2fce3ca12d581430/w4/4.psc/ref/public/og-image.png
--------------------------------------------------------------------------------
/w4/4.psc/ref/redux/cart/cart.action.ts:
--------------------------------------------------------------------------------
1 | import { getCartAPI } from "./cart.api";
2 | import { AppDispatch } from "../store";
3 | import { CART_LOADING, CART_ERROR, GET_CART } from "./cart.type";
4 |
5 | export const getCart = () => async (dispatch: AppDispatch) => {
6 | dispatch({ type: CART_LOADING });
7 | try {
8 | let data = await getCartAPI();
9 | dispatch({ type: GET_CART, payload: data });
10 | } catch (e) {
11 | dispatch({ type: CART_ERROR });
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/redux/cart/cart.api.ts:
--------------------------------------------------------------------------------
1 | import { Cart } from "@/utils/types";
2 | import axios, { AxiosResponse } from "axios";
3 |
4 | export const getCartAPI = async () => {
5 | let response: AxiosResponse = await axios.get(
6 | "http://localhost:8080/carts"
7 | );
8 | return response.data;
9 | };
10 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/redux/cart/cart.reducer.ts:
--------------------------------------------------------------------------------
1 | import { Cart } from "@/utils/types";
2 | import { GET_CART, CART_ERROR, CART_LOADING } from "./cart.type";
3 |
4 | type CartState = {
5 | loading: boolean;
6 | error: boolean;
7 | data: Cart[];
8 | };
9 |
10 | type CartAction = {
11 | type: string;
12 | payload?: any;
13 | };
14 |
15 | const initialState: CartState = {
16 | loading: false,
17 | error: false,
18 | data: [],
19 | };
20 |
21 | const cartReducer = (
22 | state: CartState = initialState,
23 | { type, payload }: CartAction
24 | ): CartState => {
25 | switch (type) {
26 | case CART_LOADING: {
27 | return {
28 | ...state,
29 | loading: true,
30 | };
31 | }
32 | case CART_ERROR: {
33 | return {
34 | ...state,
35 | loading: false,
36 | error: true,
37 | };
38 | }
39 | case GET_CART: {
40 | return {
41 | ...state,
42 | loading: false,
43 | data: payload,
44 | };
45 | }
46 | default: {
47 | return state;
48 | }
49 | }
50 | };
51 |
52 | export default cartReducer;
53 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/redux/cart/cart.type.ts:
--------------------------------------------------------------------------------
1 | export const CART_LOADING = "cart/loading";
2 | export const CART_ERROR = "cart/error";
3 |
4 | export const GET_CART = "cart/get";
5 | export const ADD_TO_CART = "cart/add";
6 | export const UPDATE_TO_CART = "cart/update";
7 | export const REMOVE_FROM_CART = "cart/delete";
8 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/redux/product/product.action.ts:
--------------------------------------------------------------------------------
1 | import { getProductsAPI } from "./product.api";
2 | import { AppDispatch } from "../store";
3 | import { PRODUCTS_LOADING, PRODUCTS_ERROR, GET_PRODUCTS } from "./product.type";
4 |
5 | export const getProducts = () => async (dispatch: AppDispatch) => {
6 | dispatch({ type: PRODUCTS_LOADING });
7 | try {
8 | let data = await getProductsAPI();
9 | dispatch({ type: GET_PRODUCTS, payload: data });
10 | } catch (e) {
11 | dispatch({ type: PRODUCTS_ERROR });
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/redux/product/product.api.ts:
--------------------------------------------------------------------------------
1 | import { Product } from "@/utils/types";
2 | import axios, { AxiosResponse } from "axios";
3 |
4 | export const getProductsAPI = async () => {
5 | let response: AxiosResponse = await axios.get(
6 | "http://localhost:8080/products"
7 | );
8 | return response.data;
9 | };
10 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/redux/product/product.reducer.ts:
--------------------------------------------------------------------------------
1 | import { Product } from "@/utils/types";
2 | import { GET_PRODUCTS, PRODUCTS_ERROR, PRODUCTS_LOADING } from "./product.type";
3 |
4 | type ProductState = {
5 | loading: boolean;
6 | error: boolean;
7 | data: Product[];
8 | };
9 |
10 | type ProductAction = {
11 | type: string;
12 | payload?: any;
13 | };
14 |
15 | const initialState: ProductState = {
16 | loading: false,
17 | error: false,
18 | data: [],
19 | };
20 |
21 | const productReducer = (
22 | state: ProductState = initialState,
23 | { type, payload }: ProductAction
24 | ): ProductState => {
25 | switch (type) {
26 | case PRODUCTS_LOADING: {
27 | return {
28 | ...state,
29 | loading: true,
30 | };
31 | }
32 | case PRODUCTS_ERROR: {
33 | return {
34 | ...state,
35 | loading: false,
36 | error: true,
37 | };
38 | }
39 | case GET_PRODUCTS: {
40 | return {
41 | ...state,
42 | loading: false,
43 | data: payload,
44 | };
45 | }
46 | default: {
47 | return state;
48 | }
49 | }
50 | };
51 |
52 | export default productReducer;
53 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/redux/product/product.type.ts:
--------------------------------------------------------------------------------
1 | export const PRODUCTS_LOADING = "products/loading";
2 | export const PRODUCTS_ERROR = "products/error";
3 |
4 | export const GET_PRODUCTS = "products/get";
5 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/redux/store.ts:
--------------------------------------------------------------------------------
1 | import {
2 | legacy_createStore,
3 | combineReducers,
4 | applyMiddleware,
5 | compose,
6 | } from "redux";
7 | import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
8 | import thunk from "redux-thunk";
9 | import productReducer from "./product/product.reducer";
10 | import cartReducer from "./cart/cart.reducer";
11 |
12 | const rootReducer = combineReducers({
13 | product: productReducer,
14 | cart: cartReducer,
15 | });
16 |
17 | export const store = legacy_createStore(
18 | rootReducer,
19 | compose(applyMiddleware(thunk))
20 | );
21 |
22 | export type RootState = ReturnType;
23 | export type AppDispatch = typeof store.dispatch;
24 |
25 | type DisppatchFn = () => AppDispatch;
26 | export const useAppDispatch: DisppatchFn = useDispatch;
27 | export const useAppSelector: TypedUseSelectorHook = useSelector;
28 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/styles/global.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: #f9f9f9;
3 | }
4 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/utils/data.utils.ts:
--------------------------------------------------------------------------------
1 | import { Money } from "./types";
2 |
3 | export function formatCurrency(amount: Money) {
4 | const intl = new Intl.NumberFormat("en-US", {
5 | style: "currency",
6 | currency: amount.currencyCode,
7 | });
8 | return intl.format(amount.amount);
9 | }
10 |
--------------------------------------------------------------------------------
/w4/4.psc/ref/utils/types.ts:
--------------------------------------------------------------------------------
1 | export interface Money {
2 | amount: number;
3 | currencyCode: string;
4 | }
5 |
6 | export interface Product {
7 | id: number;
8 | handle: string;
9 | title: string;
10 | description: string;
11 | featuredImage: {
12 | url: string;
13 | altText: string;
14 | };
15 | priceRange: {
16 | minVariantPrice: Money;
17 | maxVariantPrice: Money;
18 | };
19 | }
20 |
21 | export interface Cart {
22 | id: number;
23 | productId: number;
24 | quantity: number;
25 | }
26 |
--------------------------------------------------------------------------------
/w4/5.eval/README.md:
--------------------------------------------------------------------------------
1 | ## Evaluation Assignment
2 |
--------------------------------------------------------------------------------
/w4/README.md:
--------------------------------------------------------------------------------
1 | ### `Week 4`
2 |
3 | ## Topics
4 |
5 | 1. Debugging
6 | 2. Performance Optimization
7 | 3. React Testing Library
8 | 4. E2E testing with Cypress
9 |
--------------------------------------------------------------------------------