Skip to content

Commit

Permalink
Add Redux Hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
Xavier Araque committed Nov 22, 2023
1 parent 6ba490d commit 548dba2
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 19 deletions.
32 changes: 32 additions & 0 deletions .vscode/settings.back
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"quickfix.biome": true,
"source.organizeImports.biome": true
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[javascriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"editor.foldingImportsByDefault": true,
"autoimport.filesToScan": "**/*.{ts,tsx,jsx}",
"autoimport.showNotifications": true,
"autoimport.useSemiColon": false,
"editor.scrollbar.vertical": "hidden",
"editor.overviewRulerBorder": false,
"editor.hideCursorInOverviewRuler": true,
"editor.linkedEditing": true,
"editor.bracketPairColorization.independentColorPoolPerBracketType": true,
"editor.stickyScroll.enabled": true,
"editor.fontLigatures": true,
"workbench.sideBar.location": "right",
"workbench.editor.showTabs": "none"
}
32 changes: 32 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// {
// "editor.formatOnSave": true,
// "editor.codeActionsOnSave": {
// "quickfix.biome": true,
// "source.organizeImports.biome": true
// },
// "[javascript]": {
// "editor.defaultFormatter": "biomejs.biome"
// },
// "[javascriptreact]": {
// "editor.defaultFormatter": "biomejs.biome"
// },
// "[typescript]": {
// "editor.defaultFormatter": "biomejs.biome"
// },
// "[typescriptreact]": {
// "editor.defaultFormatter": "biomejs.biome"
// },
// "editor.foldingImportsByDefault": true,
// "autoimport.filesToScan": "**/*.{ts,tsx,jsx}",
// "autoimport.showNotifications": true,
// "autoimport.useSemiColon": false,
// "editor.scrollbar.vertical": "hidden",
// "editor.overviewRulerBorder": false,
// "editor.hideCursorInOverviewRuler": true,
// "editor.linkedEditing": true,
// "editor.bracketPairColorization.independentColorPoolPerBracketType": true,
// "editor.stickyScroll.enabled": true,
// "editor.fontLigatures": true,
// "workbench.sideBar.location": "right",
// "workbench.editor.showTabs": "none"
// }
4 changes: 3 additions & 1 deletion frontend/biome.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"organizeImports": {
"enabled": true
"enabled": true,
"include": ["./src/**/*.jsx", "./src/**/*.tsx", "./src/**/*.ts"],
"ignore": ["./node_modules/**/*.*", "./public/**/*.*", "./dist/**/*.*"]
},
"linter": {
"enabled": false,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useState } from 'react'
import Counter from '/src/components/Counter'
import viteLogo from '/vite.svg'
import './App.css'
import reactLogo from './assets/react.svg'
import Counter from './components/Counter'

function App() {
const [count, setCount] = useState(0)
Expand Down
111 changes: 98 additions & 13 deletions frontend/src/components/Counter/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,109 @@
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import React, { useState } from 'react'

// Material-UI components
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'

// Custom Hooks
import { useAppDispatch, useAppSelector } from '/src/hooks'

//Redux Reducers
import { decrement, increment } from '/src/store/reducers/counterSlice'
import { addUser, removeUser } from '/src/store/reducers/userSlice'

const Counter = () => {
const count = useSelector((state) => state.counter.value)
const dispatch = useDispatch()
const count = useAppSelector((state) => state.counter.value)
const user = useAppSelector((state) => state.user)
const dispatch = useAppDispatch()
//
const [name, setName] = useState('')
const [lastName, setLastName] = useState('')
const [email, setEmail] = useState('')

const handleIncrement = () => {
dispatch(increment())
}

const handleDecrement = () => {
dispatch(decrement())
}

const handleAddUser = () => {
const newUser = { name, last_name: lastName, email }
dispatch(addUser(newUser))
setName('')
setLastName('')
setEmail('')
}

const handleRemoveUser = () => {
dispatch(removeUser())
}

return (
<div>
<div>
<button type="button" aria-label="Increment value" onClick={() => dispatch(increment())}>
Increment
</button>
<span>{count}</span>
<button type="button" aria-label="Decrement value" onClick={() => dispatch(decrement())}>
Decrement
</button>
</div>
<CounterControls count={count} onIncrement={handleIncrement} onDecrement={handleDecrement} />
<UserInfo user={user} />
<UserActions
onAddUser={handleAddUser}
onRemoveUser={handleRemoveUser}
name={name}
setName={setName}
lastName={lastName}
setLastName={setLastName}
email={email}
setEmail={setEmail}
/>
</div>
)
}

const CounterControls = ({ count, onIncrement, onDecrement }) => {
return (
<Box display="flex" alignItems="center" justifyContent="center" my={2}>
<Button variant="contained" onClick={onDecrement}>
Decrement
</Button>
<Typography variant="h4" component="span" mx={2}>
{count}
</Typography>
<Button variant="contained" onClick={onIncrement}>
Increment
</Button>
</Box>
)
}

const UserInfo = ({ user }) => {
return (
<Box my={2}>
<Typography variant="h6">
Name: {user.name} <br />
Last Name: {user.last_name} <br />
Email: {user.email}
</Typography>
</Box>
)
}

const UserActions = ({ onAddUser, onRemoveUser, name, setName, lastName, setLastName, email, setEmail }) => {
return (
<Box display="flex" flexDirection="column" alignItems="center">
<TextField label="Name" value={name} onChange={(e) => setName(e.target.value)} />
<TextField label="Last Name" value={lastName} onChange={(e) => setLastName(e.target.value)} />
<TextField label="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
<Box mt={2}>
<Button variant="contained" onClick={onAddUser}>
Add User
</Button>
<Button variant="contained" onClick={onRemoveUser}>
Remove User
</Button>
</Box>
</Box>
)
}

export default Counter
5 changes: 5 additions & 0 deletions frontend/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { AppDispatch, RootState } from '../store'

export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
3 changes: 1 addition & 2 deletions frontend/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'

import { Provider } from 'react-redux'
import App from './App.tsx'
import store from './store'

const container = document.getElementById('app')
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/store/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { configureStore } from '@reduxjs/toolkit'

// Slices
import counterReducer from './reducers/counterSlice'
import userReducer from './reducers/userSlice'

const store = configureStore({
reducer: {
counter: counterReducer,
user: userReducer,
},
})

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch

export default store
4 changes: 2 additions & 2 deletions frontend/src/store/reducers/counterSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const counterSlice = createSlice({
},
},
})

// Actions
export const { increment, decrement } = counterSlice.actions

// Reducer
export default counterSlice.reducer
37 changes: 37 additions & 0 deletions frontend/src/store/reducers/userSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { createSlice } from '@reduxjs/toolkit'
import { UserType } from '/src/types/'

const initialState: UserType = {
name: '',
last_name: '',
email: '',
}

const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
addUser: (state, action) => {
const { name, last_name, email } = action.payload
return {
...state,
name,
last_name,
email,
}
},
removeUser: (state) => {
return {
name: '',
last_name: '',
email: '',
}
},
},
})

// Actions
export const { addUser, removeUser } = userSlice.actions

// Reducer
export default userSlice.reducer
6 changes: 6 additions & 0 deletions frontend/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export interface NumberType {
value: number
}

export interface UserType {
name: string
last_name: string
email: string
}

0 comments on commit 548dba2

Please sign in to comment.