Prosty frontend systemu wynajmu aut w React

0

Cześć wszystkim, co prawda bardziej interesuje się backendem niż frontendem, lecz postanowiłem nauczyć się podstaw Reacta tworząc frontend do mojego API.

Potrzebuję wskazówek co należałoby poprawić w kodzie, a wiem, że takich rzeczy jest dość sporo, biorąc pod uwagę, że to moja pierwsza styczność z tworzeniem frontendu.

https://github.com/Mr-Victor16/car-rental-system-react

2

A nie prościej wrzucić to w AI i ona ci prawdę powie gdzie spier...łeś.

Ew. spisz prompta wygeneruj apkę, porównaj i będziesz wiedział lepiej niż od randomowych ludzików z 4p.

3

Fajna aplikacja. Rzuciło mi się w oczy, że sprawdzasz role w komponentach. To można spokojnie przenieść warstwę wyżej do ustawień routingu.

useEffect(() => {
    if((userDetails.token !== "") && (userDetails.roles.includes("ROLE_ADMIN"))){
        axios.get(API_URL + '/fuels')
            .then((response) => {
                if (response.data.length === 0) {
                    dispatch(showSnackbar("Error occurred while fetching the list of fuel types", false));
                    //await delay(2000);
                    navigate('/', {replace: true});
                } else {
                    setFuelList(response.data);
                }
            })
            .catch(async (error) => {
                console.log(error);
                dispatch(showSnackbar("Error occurred while fetching the list of fuel types", false));
                // await delay(5000);
                navigate('/', {replace: true});
            })
    } else {
        navigate('/', { replace: true });
    }
}, [userDetails.token]);

Według mnie możesz to poprawić dzięki temu artykułowi -> https://blog.logrocket.com/authentication-react-router-v6/#creating-protected-routes

Zauważyłem, że używasz axiosa. Możesz go sobie skonfigurować np. w src/lib/axios.js

import Axios from "axios";
const API_URL = process.env.REACT_APP_API_URL;

export const axios = Axios.create({
  baseURL: API_URL,
});

axios.interceptors.response.use((response) => response.data);

A tutaj przykładowy hook, który dodaje header oraz usuwa dane użytkownika, jeżeli api zwróciło status 401:

import { axios } from "lib/axios";
import { useEffect } from "react";
import storage from "utils/storage";
import { useAuth } from "./useAuth";

const useAuthInterceptors = () => {
  const { userData, setUserData } = useAuth();

  useEffect(() => {
    const requestInterceptor = axios.interceptors.request.use(
      (config) => {
        if (!config.headers) {
          config.headers = {};
        }
        if (!config.headers?.["Authorization"]) {
          config.headers["Authorization"] = `Bearer ${userData?.token}`;
        }
        return config;
      },
      (error) => Promise.reject(error)
    );

    const responseInterceptor = axios.interceptors.response.use(
      (response) => response,
      (error) => {
        if (error.response?.status === 401) {
          setUserData(null);
          storage.clearUserData();
        }
        return Promise.reject(error);
      }
    );
    return () => {
      axios.interceptors.request.eject(requestInterceptor);
      axios.interceptors.response.eject(responseInterceptor);
    };
  }, [userData, setUserData]);
};

export default useAuthInterceptors;
3

Funkcje mają całkiem dużo zagnieżdżeń, można je sporo uprościć

https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/AddUser.js#L58

const addUser = async () => {
  if (!formik.values.username || !formik.values.email || !formik.values.password || !formik.values.role) {
    dispatch(showSnackbar("Not all fields have been completed", false));

    return;
  }

  try {
    await axios.post(API_URL + '/user', {
        username: formik.values.username,
        email: formik.values.email,
        password: formik.values.password,
        role: formik.values.accountType
    }, { headers: token });

    dispatch(showSnackbar("User successfully added", true));
    await delay(2000);
    navigate('/users', { replace: true });
  } catch (error) {
      console.log(error);
      
      const errorMessage = error.response.status === 409
        ? "The username or email is already in use"
        : "Error occurred while adding user";

      dispatch(showSnackbar(errorMessage, false));
  }
};

Wszystkie rzeczy, które nie wykorzystują Reacta powinny być poza komponentem, ponieważ React renderując komponent wywołuje go od nowa.

https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/CarList.js

const API_URL = "http://localhost:8080/api";

const getStatusName = (name) => {
  // ...
};

const getFuelTypeName = (name) => {
  // ...
};

const CarList = () => {
  // ...  
};

Kopiujesz funkcje pomiędzy komponentami

https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/Home.js#L60
https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/CarList.js#L37
https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/EditCar.js#L80


Nie powinieneś tworzyć komponentu mui wewnątrz innego komponentu, ponieważ wywoła się to przy każdym renderowaniu

https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/components/GridItem.js
https://mui.com/system/styled/

Podobnie jak schem jeśli cały czas są identyczne

https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/AddUser.js#L27

3

if(formik.values.horsePower !== "" && formik.values.price !== "" && formik.values.mileage !== "" && formik.values.brand !== "" && formik.values.model !== "" && formik.values.capacity !== "" && formik.values.year !== '' && formik.values.fuelType !== "")

Wyżej w komponencie masz validationSchema. Nie używam formika, ale na pewno jest jakaś opcja zablokowania "onSubmit" jeżeli walidacja nie przeszła.Ostatecznie możesz wywołać walidacje samemu zamiast tego ogromnego ifa.

0

Wprowadziłem w życie Wasze rady.

Mam w zasadzie jeszcze jedną zagwostkę - mam dwa dość podobne strukturą komponenty AddCar i EditCar
https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/EditCar.js
https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/AddCar.js

Mają one dość "podobny" zakres funkcjonalności.

Co powinienem zrobić? Wyłączyć validationSchema i formularz do oddzielnego komponentu, czy raczej spróbować złączyć dwa komponenty w jeden?

0
mr-victor16 napisał(a):

Mam w zasadzie jeszcze jedną zagwostkę - mam dwa dość podobne strukturą komponenty AddCar i EditCar
https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/EditCar.js
https://github.com/Mr-Victor16/car-rental-system-react/blob/main/src/pages/AddCar.js

Mają one dość "podobny" zakres funkcjonalności.

Co powinienem zrobić? Wyłączyć validationSchema i formularz do oddzielnego komponentu, czy raczej spróbować złączyć dwa komponenty w jeden?

Tak. Warto to przenieść do osobnego komponentu. Jeżeli obecnie zdecydujesz się na zmianę zasad walidacji to musisz to zrobić w dwóch miejscach.

Co do tego kodu to:

const addCar = async () => {
    axios.post('car', {
        horsePower: formik.values.horsePower,
        price: formik.values.price,
        year: formik.values.year,
        mileage: formik.values.mileage,
        brand: formik.values.brand,
        model: formik.values.model,
        capacity: formik.values.capacity,
        fuelType: formik.values.fuelType
    }

może lepiej tak:

const addCar = async () => {
    axios.post('car', formik.values)
0

Nie zaczyna się pisania aplikacji od frontu. Zakodź najpierw podstawową funkcjonalność, a dopiero potem dobuduj UI.

1 użytkowników online, w tym zalogowanych: 0, gości: 1