21IT116_REDUX_VIBISHANAN S
21IT116_REDUX_VIBISHANAN S
21IT116_REDUX_VIBISHANAN S
Screenshots:
Index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import 'bootstrap/dist/css/bootstrap.min.css';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Actions.js:
export const updateHeartRate = (heartRate) => {
return {
type: 'UPDATE_HEART_RATE',
payload: heartRate
};
};
Component.js
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { updateHeartRate, updateCalorieIntake, logWorkout } from
'../actions/healthActions';
const HealthStatus = () => {
const dispatch = useDispatch();
const { heartRate, calorieIntake, workouts } = useSelector((state) =>
state);
const [workoutDuration, setWorkoutDuration] = useState('');
const [workoutType, setWorkoutType] = useState('');
// State to show health dashboard summary
const [showDashboard, setShowDashboard] = useState(false);
const inputStyle = {
margin: '10px 0',
padding: '8px',
width: '100%',
maxWidth: '300px',
fontSize: '1em',
};const buttonStyle = {
marginTop: '20px',
padding: '10px 20px',
fontSize: '1em',
cursor: 'pointer',
backgroundColor: '#4CAF50',
color: '#fff',
border: 'none',
borderRadius: '5px',
};const listStyle = {
marginTop: '20px',
textAlign: 'left',
};const summaryStyle = {
marginTop: '30px',
padding: '20px',
border: '1px solid #ccc',
borderRadius: '8px',
backgroundColor: '#e8f4e8', };
return (
<div style={containerStyle}>
<h2>Health Dashboard</h2>
<div>
<label>Heart Rate: </label>
<input
style={inputStyle}
type="number"
value={heartRate}
onChange={handleHeartRateChange}/>
</div>
<div>
<label>Calorie Intake: </label>
<input
style={inputStyle}
type="number"
value={calorieIntake}
onChange={handleCalorieIntakeChange} />
</div>
<h3>Log a Workout</h3>
<div>
<label>Workout Type: </label>
<input
style={inputStyle}
type="text"
value={workoutType}
onChange={(e) => setWorkoutType(e.target.value)} />
</div>
<div>
<label>Workout Duration (mins): </label>
<input
style={inputStyle}
type="number"
value={workoutDuration}
onChange={(e) => setWorkoutDuration(e.target.value)}
/>
</div>
<button style={buttonStyle} onClick={handleWorkoutLog}>
Log Workout
</button>
<br></br>
{workouts.length > 0 && (
<ul style={listStyle}>
{workouts.map((workout, index) => (
<li key={index}>
{workout.workout} - {workout.duration} mins
</li> ))} </ul> )}
Output:
CounterComponent.js:
// CounterComponent.js
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { increment, decrement } from './store';
import './CounterComponent.css'; // Use some basic styling
const CounterComponent = () => {
const userCount = useSelector((state) => state.data.length);
const dispatch = useDispatch();
return (
<div className="counter-container">
<h1>Number of Users: {userCount}</h1>
<div className="button-group">
<button className="counter-button" onClick={() =>
dispatch(increment())}>
Increment (Fetch User)
</button>
<button
className="counter-button"
onClick={() => dispatch(decrement())}
disabled={userCount === 0} >
Decrement (Remove User)
</button>
</div>
</div>
);
};export default CounterComponent
DataComponent.js:
// DataComponent.js
import React from 'react';
import { useSelector } from 'react-redux';
import './DataComponent.css'; // Import styles
const DataComponent = () => {
const { data, loading, error } = useSelector((state) => state);
if (loading) {
return <h2>Loading...</h2>; }
if (error) {
return <h2>Error: {error}</h2>; }
return (
<div className="user-list">
<h1>Random Users</h1>
<div className="user-cards">
{data.map((user, index) => (
<div className="user-card" key={index}>
<img src={user.picture.large} alt="User Avatar" />
<h2>
{user.name.first} {user.name.last}
</h2>
<p>Email: {user.email}</p>
<p>Location: {user.location.city}, {user.location.country}</p>
</div> ))}
</div></div>);};export default DataComponent;
Store.js
import { createStore, applyMiddleware } from 'redux';
import {thunk} from 'redux-thunk';
import axios from 'axios';
// Initial state
const initialState = {
data: [], // Stores user data
loading: false,
error: null,};
// Action Types
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
const FETCH_DATA_REQUEST = 'FETCH_DATA_REQUEST';
const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
const FETCH_DATA_FAILURE = 'FETCH_DATA_FAILURE';
// Action Creators
export const increment = () => {
return async (dispatch) => {
dispatch({ type: FETCH_DATA_REQUEST });
try {
// Fetch one more user
const response = await axios.get('https://randomuser.me/api/?results=1');
dispatch({ type: FETCH_DATA_SUCCESS, payload: response.data.results });
} catch (error) {
dispatch({ type: FETCH_DATA_FAILURE, error: error.message }); } };};
export const decrement = () => {
return (dispatch, getState) => {
const { data } = getState();
if (data.length > 0) {
dispatch({ type: DECREMENT }); } };
};
// Reducer
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_DATA_REQUEST:
return { ...state, loading: true, error: null };
case FETCH_DATA_SUCCESS:
return {
...state,
loading: false,
data: [...state.data, ...action.payload], // Append new users };
case FETCH_DATA_FAILURE:
return { ...state, loading: false, error: action.error };
case DECREMENT:
return {
...state,
data: state.data.slice(0, -1), // Remove the last user
};
default:
return state; }
};
export const store = createStore(rootReducer, applyMiddleware(thunk));
App.js:
// App.js
import React from 'react';
import { Provider } from 'react-redux';
import { store } from './components/store';
import CounterComponent from './components/CounterComponent';
import DataComponent from './components/DataComponent';
import './App.css';