Refaktor, rozdělení api, zpřehlednění kódu
This commit is contained in:
@@ -1,121 +0,0 @@
|
||||
import { toast } from "react-toastify";
|
||||
import { FeatureRequest, PizzaOrder } from "./types";
|
||||
import { getBaseUrl, getToken } from "./Utils";
|
||||
|
||||
/**
|
||||
* Wrapper pro volání API, u kterých chceme automaticky zobrazit toaster s chybou ze serveru.
|
||||
*
|
||||
* @param apiFunction volaná API funkce
|
||||
*/
|
||||
export function errorHandler<T>(apiFunction: () => Promise<T>): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
apiFunction().then((result) => {
|
||||
resolve(result);
|
||||
}).catch(e => {
|
||||
toast.error(e.message, { theme: "colored" });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function request<TResponse>(
|
||||
url: string,
|
||||
config: RequestInit = {}
|
||||
): Promise<TResponse> {
|
||||
config.headers = config?.headers ? new Headers(config.headers) : new Headers();
|
||||
config.headers.set("Authorization", `Bearer ${getToken()}`);
|
||||
try {
|
||||
const response = await fetch(getBaseUrl() + url, config);
|
||||
if (!response.ok) {
|
||||
const json = await response.json();
|
||||
// Vyhodíme samotnou hlášku z odpovědi, odchytí si jí errorHandler
|
||||
throw new Error(json.error);
|
||||
}
|
||||
return response.json() as TResponse;
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
const api = {
|
||||
get: <TResponse>(url: string) => request<TResponse>(url),
|
||||
post: <TBody extends BodyInit, TResponse>(url: string, body: TBody) => request<TResponse>(url, { method: 'POST', body, headers: { 'Content-Type': 'application/json' } }),
|
||||
}
|
||||
|
||||
export const getQrUrl = (login: string) => {
|
||||
return `${getBaseUrl()}/api/qr?login=${login}`;
|
||||
}
|
||||
|
||||
export const getData = async (dayIndex?: number) => {
|
||||
let url = '/api/data';
|
||||
if (dayIndex != null) {
|
||||
url += '?dayIndex=' + dayIndex;
|
||||
}
|
||||
return await api.get<any>(url);
|
||||
}
|
||||
export const createPizzaDay = async () => {
|
||||
return await api.post<any, any>('/api/createPizzaDay', undefined);
|
||||
}
|
||||
|
||||
export const deletePizzaDay = async () => {
|
||||
return await api.post<any, any>('/api/deletePizzaDay', undefined);
|
||||
}
|
||||
|
||||
export const lockPizzaDay = async () => {
|
||||
return await api.post<any, any>('/api/lockPizzaDay', undefined);
|
||||
}
|
||||
|
||||
export const unlockPizzaDay = async () => {
|
||||
return await api.post<any, any>('/api/unlockPizzaDay', undefined);
|
||||
}
|
||||
|
||||
export const finishOrder = async () => {
|
||||
return await api.post<any, any>('/api/finishOrder', undefined);
|
||||
}
|
||||
|
||||
export const finishDelivery = async (bankAccount?: string, bankAccountHolder?: string) => {
|
||||
return await api.post<any, any>('/api/finishDelivery', JSON.stringify({ bankAccount, bankAccountHolder }));
|
||||
}
|
||||
|
||||
export const addChoice = async (locationIndex: number, foodIndex?: number, dayIndex?: number) => {
|
||||
return await api.post<any, any>('/api/addChoice', JSON.stringify({ locationIndex, foodIndex, dayIndex }));
|
||||
}
|
||||
|
||||
export const removeChoices = async (locationIndex: number, dayIndex?: number) => {
|
||||
return await api.post<any, any>('/api/removeChoices', JSON.stringify({ locationIndex, dayIndex }));
|
||||
}
|
||||
|
||||
export const removeChoice = async (locationIndex: number, foodIndex: number, dayIndex?: number) => {
|
||||
return await api.post<any, any>('/api/removeChoice', JSON.stringify({ locationIndex, foodIndex, dayIndex }));
|
||||
}
|
||||
|
||||
export const addPizza = async (pizzaIndex: number, pizzaSizeIndex: number) => {
|
||||
return await api.post<any, any>('/api/addPizza', JSON.stringify({ pizzaIndex, pizzaSizeIndex }));
|
||||
}
|
||||
|
||||
export const removePizza = async (pizzaOrder: PizzaOrder) => {
|
||||
return await api.post<any, any>('/api/removePizza', JSON.stringify({ pizzaOrder }));
|
||||
}
|
||||
|
||||
export const updatePizzaDayNote = async (note?: string) => {
|
||||
return await api.post<any, any>('/api/updatePizzaDayNote', JSON.stringify({ note }));
|
||||
}
|
||||
|
||||
export const login = async (login?: string) => {
|
||||
return await api.post<any, any>('/api/login', JSON.stringify({ login }));
|
||||
}
|
||||
|
||||
export const changeDepartureTime = async (time: string, dayIndex?: number) => {
|
||||
return await api.post<any, any>('/api/changeDepartureTime', JSON.stringify({ time, dayIndex }));
|
||||
}
|
||||
|
||||
export const updatePizzaFee = async (login: string, text?: string, price?: number) => {
|
||||
return await api.post<any, any>('/api/updatePizzaFee', JSON.stringify({ login, text, price }));
|
||||
}
|
||||
|
||||
export const getFeatureVotes = async () => {
|
||||
return await api.get<any>('/api/getFeatureVotes');
|
||||
}
|
||||
|
||||
export const updateFeatureVote = async (option: FeatureRequest, active: boolean) => {
|
||||
return await api.post<any, any>('/api/updateFeatureVote', JSON.stringify({ option, active }));
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useContext, useEffect, useMemo, useRef, useState, useCallback } from 'react';
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import { EVENT_DISCONNECT, EVENT_MESSAGE, SocketContext } from './context/socket';
|
||||
import { addChoice, addPizza, changeDepartureTime, createPizzaDay, deletePizzaDay, errorHandler, finishDelivery, finishOrder, getData, getQrUrl, lockPizzaDay, removeChoice, removeChoices, removePizza, unlockPizzaDay, updatePizzaDayNote } from './Api';
|
||||
import { addPizza, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, lockPizzaDay, removePizza, unlockPizzaDay, updatePizzaDayNote } from './api/PizzaDayApi';
|
||||
import { useAuth } from './context/auth';
|
||||
import Login from './Login';
|
||||
import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap';
|
||||
@@ -18,6 +18,8 @@ import { ClientData, Restaurants, Food, Order, Locations, PizzaOrder, PizzaDaySt
|
||||
import Footer from './components/Footer';
|
||||
import { faChainBroken, faChevronLeft, faChevronRight, faGear, faSatelliteDish, faSearch } from '@fortawesome/free-solid-svg-icons';
|
||||
import Loader from './components/Loader';
|
||||
import { getData, errorHandler, getQrUrl } from './api/Api';
|
||||
import { addChoice, removeChoices, removeChoice, changeDepartureTime } from './api/FoodApi';
|
||||
|
||||
const EVENT_CONNECT = "connect"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { useAuth } from './context/auth';
|
||||
import { login } from './Api';
|
||||
import { login } from './api/Api';
|
||||
import './Login.css';
|
||||
|
||||
/**
|
||||
|
||||
57
client/src/api/Api.ts
Normal file
57
client/src/api/Api.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { toast } from "react-toastify";
|
||||
import { getBaseUrl, getToken } from "../Utils";
|
||||
|
||||
/**
|
||||
* Wrapper pro volání API, u kterých chceme automaticky zobrazit toaster s chybou ze serveru.
|
||||
*
|
||||
* @param apiFunction volaná API funkce
|
||||
*/
|
||||
export function errorHandler<T>(apiFunction: () => Promise<T>): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
apiFunction().then((result) => {
|
||||
resolve(result);
|
||||
}).catch(e => {
|
||||
toast.error(e.message, { theme: "colored" });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function request<TResponse>(
|
||||
url: string,
|
||||
config: RequestInit = {}
|
||||
): Promise<TResponse> {
|
||||
config.headers = config?.headers ? new Headers(config.headers) : new Headers();
|
||||
config.headers.set("Authorization", `Bearer ${getToken()}`);
|
||||
try {
|
||||
const response = await fetch(getBaseUrl() + url, config);
|
||||
if (!response.ok) {
|
||||
const json = await response.json();
|
||||
// Vyhodíme samotnou hlášku z odpovědi, odchytí si jí errorHandler
|
||||
throw new Error(json.error);
|
||||
}
|
||||
return response.json() as TResponse;
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
export const api = {
|
||||
get: <TResponse>(url: string) => request<TResponse>(url),
|
||||
post: <TBody extends BodyInit, TResponse>(url: string, body: TBody) => request<TResponse>(url, { method: 'POST', body, headers: { 'Content-Type': 'application/json' } }),
|
||||
}
|
||||
|
||||
export const getQrUrl = (login: string) => {
|
||||
return `${getBaseUrl()}/api/qr?login=${login}`;
|
||||
}
|
||||
|
||||
export const getData = async (dayIndex?: number) => {
|
||||
let url = '/api/data';
|
||||
if (dayIndex != null) {
|
||||
url += '?dayIndex=' + dayIndex;
|
||||
}
|
||||
return await api.get<any>(url);
|
||||
}
|
||||
|
||||
export const login = async (login?: string) => {
|
||||
return await api.post<any, any>('/api/login', JSON.stringify({ login }));
|
||||
}
|
||||
19
client/src/api/FoodApi.ts
Normal file
19
client/src/api/FoodApi.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { api } from "./Api";
|
||||
|
||||
const FOOD_API_PREFIX = '/api/food';
|
||||
|
||||
export const addChoice = async (locationIndex: number, foodIndex?: number, dayIndex?: number) => {
|
||||
return await api.post<any, any>(`${FOOD_API_PREFIX}/addChoice`, JSON.stringify({ locationIndex, foodIndex, dayIndex }));
|
||||
}
|
||||
|
||||
export const removeChoices = async (locationIndex: number, dayIndex?: number) => {
|
||||
return await api.post<any, any>(`${FOOD_API_PREFIX}/removeChoices`, JSON.stringify({ locationIndex, dayIndex }));
|
||||
}
|
||||
|
||||
export const removeChoice = async (locationIndex: number, foodIndex: number, dayIndex?: number) => {
|
||||
return await api.post<any, any>(`${FOOD_API_PREFIX}/removeChoice`, JSON.stringify({ locationIndex, foodIndex, dayIndex }));
|
||||
}
|
||||
|
||||
export const changeDepartureTime = async (time: string, dayIndex?: number) => {
|
||||
return await api.post<any, any>(`${FOOD_API_PREFIX}/changeDepartureTime`, JSON.stringify({ time, dayIndex }));
|
||||
}
|
||||
44
client/src/api/PizzaDayApi.ts
Normal file
44
client/src/api/PizzaDayApi.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { PizzaOrder } from "../types";
|
||||
import { api } from "./Api";
|
||||
|
||||
const PIZZADAY_API_PREFIX = '/api/pizzaDay';
|
||||
|
||||
export const createPizzaDay = async () => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/create`, undefined);
|
||||
}
|
||||
|
||||
export const deletePizzaDay = async () => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/delete`, undefined);
|
||||
}
|
||||
|
||||
export const lockPizzaDay = async () => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/lock`, undefined);
|
||||
}
|
||||
|
||||
export const unlockPizzaDay = async () => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/unlock`, undefined);
|
||||
}
|
||||
|
||||
export const finishOrder = async () => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/finishOrder`, undefined);
|
||||
}
|
||||
|
||||
export const finishDelivery = async (bankAccount?: string, bankAccountHolder?: string) => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/finishDelivery`, JSON.stringify({ bankAccount, bankAccountHolder }));
|
||||
}
|
||||
|
||||
export const addPizza = async (pizzaIndex: number, pizzaSizeIndex: number) => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/add`, JSON.stringify({ pizzaIndex, pizzaSizeIndex }));
|
||||
}
|
||||
|
||||
export const removePizza = async (pizzaOrder: PizzaOrder) => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/remove`, JSON.stringify({ pizzaOrder }));
|
||||
}
|
||||
|
||||
export const updatePizzaDayNote = async (note?: string) => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/updatePizzaDayNote`, JSON.stringify({ note }));
|
||||
}
|
||||
|
||||
export const updatePizzaFee = async (login: string, text?: string, price?: number) => {
|
||||
return await api.post<any, any>(`${PIZZADAY_API_PREFIX}/updatePizzaFee`, JSON.stringify({ login, text, price }));
|
||||
}
|
||||
12
client/src/api/VotingApi.ts
Normal file
12
client/src/api/VotingApi.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { FeatureRequest } from "../types";
|
||||
import { api } from "./Api";
|
||||
|
||||
const VOTING_API_PREFIX = '/api/voting';
|
||||
|
||||
export const getFeatureVotes = async () => {
|
||||
return await api.get<any>(`${VOTING_API_PREFIX}/getVotes`);
|
||||
}
|
||||
|
||||
export const updateFeatureVote = async (option: FeatureRequest, active: boolean) => {
|
||||
return await api.post<any, any>(`${VOTING_API_PREFIX}/updateVote`, JSON.stringify({ option, active }));
|
||||
}
|
||||
@@ -5,7 +5,8 @@ import BankAccountModal from "./modals/BankAccountModal";
|
||||
import { useBank } from "../context/bank";
|
||||
import FeaturesVotingModal from "./modals/FeaturesVotingModal";
|
||||
import { FeatureRequest } from "../types";
|
||||
import { errorHandler, getFeatureVotes, updateFeatureVote } from "../Api";
|
||||
import { errorHandler } from "../api/Api";
|
||||
import { getFeatureVotes, updateFeatureVote } from "../api/VotingApi";
|
||||
|
||||
|
||||
export default function Header() {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Table } from "react-bootstrap";
|
||||
import { useAuth } from "../context/auth";
|
||||
import { Order, PizzaDayState, PizzaOrder } from "../types";
|
||||
import { updatePizzaFee } from "../Api";
|
||||
import PizzaOrderRow from "./PizzaOrderRow";
|
||||
import { updatePizzaFee } from "../api/PizzaDayApi";
|
||||
|
||||
type Props = {
|
||||
state: PizzaDayState,
|
||||
@@ -12,8 +11,6 @@ type Props = {
|
||||
}
|
||||
|
||||
export default function PizzaOrderList({ state, orders, onDelete, creator }: Props) {
|
||||
const auth = useAuth();
|
||||
|
||||
const saveFees = async (customer: string, text?: string, price?: number) => {
|
||||
await updatePizzaFee(customer, text, price);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user