<repo_name>JenyaIII/testRedux<file_sep>/src/Redux/reducers/cardReducers/cardsReducer.js
import {
  ADD_USER,
  GET_USERS,
  GET_USERS_LOADING,
  GET_USERS_ERROR,
  DELETE_USER,
  CHANGE_MODAL,
  EDIT_FORM,
  UPDATE_USER,
} from '../../actions/actionTypes';

const initialState = {
  loading: false,
  modalOpen: false,
  editForm: false,
  data: [],
  currentUser: [],
};

export default function (state = initialState, action) {
  switch (action.type) {
    case ADD_USER: {
      return {
        ...state,
        data: [...state.data, action.payload],
      };
    }
    case GET_USERS: {
      return {
        ...state,
        data: [...state.data, ...action.payload.data],
        loading: false,
      };
    }
    case GET_USERS_LOADING: {
      return {
        ...state,
        loading: true,
      };
    }
    case GET_USERS_ERROR: {
      return {
        ...state,
        loading: false,
      };
    }
    case DELETE_USER: {
      return {
        ...state,
        data: [
          ...state.data.filter((item) => item.id !== action.payload.id),
        ],
      };
    }
    case CHANGE_MODAL: {
      return {
        ...state,
        modalOpen: action.payload,
      };
    }
    case UPDATE_USER: {
      return {
        ...state,
        editForm: false,
        modalOpen: false,
        data: [
          ...state.data.filter((item) => item.id !== action.payload.id),
          action.payload,
        ],
      };
    }
    case EDIT_FORM: {
      return {
        ...state,
        currentUser: [
          ...state.currentUser, action.payload,
        ],
        editForm: true,
        modalOpen: true,
      };
    }
    default:
      return state;
  }
}
<file_sep>/src/components/Card/Card.jsx
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {
  deleteUser,
  getUsers,
  getUsersLoading,
  openOrCloseModal,
  editUser,
} from '../../Redux/actions/actions';
import styles from './Card.module.scss';
import Loader from '../Loader/Loader';

const Card = () => {
  const loading = useSelector((state) => state.cardsReducer.loading);
  const users = useSelector((state) => state.cardsReducer.data);
  const error = useSelector((state) => state.cardsReducer.usersError);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getUsersLoading());
    dispatch(getUsers());
  }, [dispatch]);

  if (error) {
    return <p>{error}</p>;
  }

  const removeUser = (id, obj) => {
    dispatch(deleteUser(id, obj));
  };
  const handleOpenEditForm = (item) => {
    dispatch(editUser(item));
  };

  return (
    <>
      {loading ? (<Loader />) : ((users || users[0]).map((item) => (
        <div className={styles.card} key={item.key}>
          <div className={styles.cardTitle}>
            <h3>{item.name}</h3>
          </div>
          <div className={styles.cardContent}>
            Email:
            {' '}
            {item.email}
          </div>
          <div className={styles.cardContent}>
            Telephone:
            {' '}
            {item.telephone}
          </div>
          <div className={styles.cardContent}>
            Position:
            {' '}
            {item.position}
          </div>
          <div className={styles.cardButtons}>
            <button type="button" onClick={() => handleOpenEditForm(item)}>
              Edit
            </button>
            <button type="button" onClick={() => removeUser(item.id, item)}>
              Delete
            </button>
          </div>
        </div>
      )))}
    </>
  );
};

export default Card;
<file_sep>/src/Redux/actions/actionTypes.js
export const ADD_USER = 'ADD_USER';
export const GET_USERS = 'GET_USERS';
export const GET_USERS_LOADING = 'GET_USERS_LOADING';
export const GET_USERS_ERROR = 'GET_USERS_ERROR';
export const DELETE_USER = 'DELETE_USER';
export const CHANGE_MODAL = 'CHANGE_MODAL';
export const EDIT_CARD = 'EDIT_CARD';
export const UPDATE_USER = 'UPDATE_USER';
export const EDIT_FORM = 'EDIT_FORM';
<file_sep>/src/components/ModalForm/AddUserForm.jsx
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { addUser, openOrCloseModal } from '../../Redux/actions/actions';

const AddUserForm = () => {
  const [user, setUser] = useState({
    id: null,
    name: '',
    email: '',
    telephone: '',
    position: '',
  });

  const dispatch = useDispatch();

  const handleChange = (e) => {
    setUser({ ...user, [e.target.name]: e.target.value });
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    user.id = Date.now();
    dispatch(addUser(user));
    dispatch(openOrCloseModal(false));
    setUser({
      id: null,
      name: '',
      email: '',
      telephone: '',
      position: '',
    });
  };

  const formList = [
    { name: 'name' },
    { name: 'email' },
    { name: 'telephone' },
    { name: 'position' },
  ];

  return (
    <div className="container">
      <form onSubmit={handleSubmit}>
        <div className="row">
          {formList.map((item) => (
            <div className="input-field" key={item.name}>
              <div className="labelBlock">
                <label>{item.name}</label>
              </div>
              <input
                type="text"
                name={item.name}
                value={user[item.name]}
                onChange={handleChange}
                required
              />
            </div>
          ))}
          <div>
            <button type="submit">
              Add
            </button>
          </div>
        </div>
      </form>
    </div>
  );
};

export default AddUserForm;
<file_sep>/src/App.jsx
import React from 'react';
import './App.css';
import { useDispatch } from 'react-redux';
import { openOrCloseModal } from './Redux/actions/actions';
import Cards from './components/Cards/Cards';
import ModalForm from './components/ModalForm/Modal';

function App() {
  const dispatch = useDispatch();

  const handleOpenModal = (bool) => {
    dispatch(openOrCloseModal(bool));
  };

  return (
    <div className="App">
      <div className="container">
        <h1 style={{ color: 'grey' }}>Redux Cards</h1>
        <Cards />
        <div className="createCard">
          <button
            className="createButton"
            type="button"
            onClick={() => handleOpenModal(true)}
          >
            Create card
          </button>
        </div>
        <div>
          <ModalForm />
        </div>
      </div>
    </div>
  );
}

export default App;
<file_sep>/src/Redux/actions/actions.js
/* eslint-disable import/prefer-default-export */
import Axios from 'axios';
import {
  ADD_USER,
  GET_USERS,
  GET_USERS_LOADING,
  GET_USERS_ERROR,
  DELETE_USER,
  CHANGE_MODAL,
  EDIT_FORM,
  UPDATE_USER,
} from './actionTypes';

export const addUser = (obj) => async (dispatch) => {
  try {
    await Axios.post(
      'http://localhost:5000/users', obj,
    );
    dispatch({
      type: ADD_USER,
      payload: obj,
    });
  } catch (err) {
    dispatch({ type: GET_USERS_ERROR, payload: err });
    console.log(`Error: ${err}`);
  }
};

export const getUsers = () => async (dispatch) => {
  // dispatch({ type: GET_USERS_LOADING });
  try {
    const userData = await Axios.get(
      'http://localhost:5000/users',
    );
    console.log('USERDATA', userData);
    dispatch({
      type: GET_USERS,
      payload: userData,
    });
  } catch (err) {
    dispatch({ type: GET_USERS_ERROR, payload: err });
    console.log(`Error: ${err}`);
  }
};

export const getUsersLoading = () => ({
  type: GET_USERS_LOADING,
});

export const deleteUser = (id, obj) => async (dispatch) => {
  try {
    await Axios.delete(
      `http://localhost:5000/users/${id}`,
    );
    dispatch({
      type: DELETE_USER,
      payload: obj,
    });
  } catch (err) {
    dispatch({ type: GET_USERS_ERROR, payload: err });
    console.log(`Error: ${err}`);
  }
};

export const openOrCloseModal = (bool) => ({
  type: CHANGE_MODAL,
  payload: bool,
});

export const updateUser = (item) => ({
  type: UPDATE_USER,
  payload: item,
});

export const editUser = (item) => ({
  type: EDIT_FORM,
  payload: item,
});
<file_sep>/src/components/ErrorScreen/ErrorScreen.jsx
import React from 'react';
import styles from './ErrorScreen.module.scss';
import background from '../../assets/error.jpeg';

const ErrorScreen = () => (
  <>
    <div className={styles.errorScreen}>
      <div className={styles.errorTitle}>
        <h3>Download users data ERROR !</h3>
      </div>
      <div className={styles.errorContent} />
    </div>
  </>
);

export default ErrorScreen;
