DEV Community

CodeForLife
CodeForLife

Posted on

React vite CRUD basics

Simple localised react crud
npm create vite@latest
npm i bootstrap axios

App.jsx

import TableBody from "./Table/TableBody";
import "./App.css";
import ButtonDelete from "./Button/ButtonDelete";
import TableRow from "./Table/TableRow";
import UserForm from "./UserForm";

import { createContext, useEffect, useState } from "react";
import axios from "axios";

export const fetchData = createContext();

function App() {
  const [users, setUsers] = useState([]);
  const [error, setError] = useState(null);

  async function getData() {
    try {
      const result = await axios.get("http://localhost:3001/api/users");
      setUsers(result.data);
      setError(null);
    } catch (error) {
      console.error(error);
      setError("Hiba az adat lekérésekor");
    }
  }

  useEffect(() => {
    getData();
  }, []);

  return (
    <>
      <div className="container">
        <div className="row">
          <h1 className="fw-bold text-center mt-5">
            {" "}
            Felhasználókezelő (Full-Stack CRUD)
          </h1>
          <fetchData.Provider value={{ getData, setError }}>
            <UserForm />
            <hr className="mt-4" />
            <h3 className="text-center mt-3 mb-4">Felhasználók Listája</h3>

            {error ? (
              <h1 className="text-center text-danger">{error}</h1>
            ) : (
              <TableBody users={users} />
            )}

          </fetchData.Provider>
        </div>
      </div>
    </>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

TableBody.jsx

import TableRow from "./TableRow";

function TableBody({ users }) {
  return (
    <>
      <table className="table table-bordered table-dark border-light">
        <thead className="table-light border-dark">
          <tr>
            <th>#ID</th>
            <th>Név </th>
            <th>Email</th>
            <th>Regisztráció</th>
            <th>Műveletek</th>
          </tr>
        </thead>
        <tbody>
          {users.length > 0 ? (
            users.map((user) => (
              <TableRow key={user.id} data={user} />
            ))
          ) : (
            <tr>
              <td colSpan="5" className="no-users-cell">
                Nincsenek felhasználók az adatbázisban.
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </>
  );
}
export default TableBody;
Enter fullscreen mode Exit fullscreen mode

TableRow.jsx

import { useEffect, useState, useContext } from "react";
import ButtonDelete from "../Button/ButtonDelete";
import { fetchData } from "../App";
import axios from "axios";

function TableRow({ data }) {
  const [editStart, setEditStart] = useState(false);

  const [editName, setEditName] = useState(data.name);
  const [editEmail, setEditEmail] = useState(data.email);

  const { getData, setError } = useContext(fetchData);

  function saveEdit() {
    onUpdate(data.id, editName, editEmail);
    setEditStart(false);
  }

  async function onUpdate(id, name, email) {
    try {
      await axios.patch("http://localhost:3001/api/users/" + id, { name,email });
      setError(null);
      getData();
    } catch (error) {
      console.error(error);
      setError("Hiba az adat Frissítésénél");
    }
  }

  const editView = (
    <>
      <tr className="align-middle">
        <td>{data.id}</td>
        <td>
          <input type="text" value={editName} onChange={(event) => setEditName(event.target.value)}/>
        </td>
        <td>
          <input
            type="text"
            value={editEmail}
            onChange={(e) => setEditEmail(e.target.value)}
          />
        </td>
        <td>{new Date(data.created_at).toLocaleDateString()}</td>
        <td>
          <button
            className="btn btn-success fw-bold me-2"
            onClick={() => saveEdit()}
          >
            Mentés
          </button>
          <button
            className="btn btn-danger fw-bold"
            onClick={() => setEditStart(false)}
          >
            Mégsem
          </button>
        </td>
      </tr>
    </>
  );

  const normalView = (
    <>
      <tr className="align-middle">
        <td>{data.id}</td>
        <td>{data.name}</td>
        <td>{data.email}</td>
        <td>{new Date(data.created_at).toLocaleDateString()}</td>
        <td>
          <button className="btn btn-primary fw-bold me-2" onClick={() => setEditStart(true)}>
            Szerkesztés
          </button>
          <ButtonDelete id={data.id} />
        </td>
      </tr>
    </>
  );

  return (
    editStart? editView : normalView
  );
}


export default TableRow;
Enter fullscreen mode Exit fullscreen mode

ButtonDelete.jsx

import { fetchData } from "../App";
import { useContext } from "react";
import axios from "axios";

function ButtonDelete({ id }) {
  const { getData, setError } = useContext(fetchData);

  async function onDelete(id) {
    if (
      !window.confirm(
        `Biztosan törölni szeretnéd a(z) ${id} ID-jű felhasználót?`,
      )
    ) {return;}

    try {
      await axios.delete("http://localhost:3001/api/users/" + id);
      setError(null);
      getData();
    } catch (error) {
      console.error(error);
      setError("Hiba az adat Törlésénél");
    }
  }

  return (
    <>
      <button className="btn btn-danger fw-bold" onClick={() => onDelete(id)}>
        Törlés
      </button>
    </>
  );
}
export default ButtonDelete;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)