добавлена работа со списками продуктов, попытка оптимизировать запрос по поиску коктейлей
This commit is contained in:
@@ -12,6 +12,7 @@ import {MenuPage} from "./pages/cocktails/MenuPage";
|
||||
import {EditIngredientPage} from "./pages/ingredients/EditIngredientPage";
|
||||
import {EditCocktailPage} from "./pages/cocktails/EditCocktailPage";
|
||||
import {useEffect, useState} from "react";
|
||||
import {BarChangePage} from "./pages/BarChangePage";
|
||||
|
||||
export function NavigationRoutes() {
|
||||
const {auth} = useAuth();
|
||||
@@ -64,6 +65,11 @@ const authPages = [
|
||||
children: (<MenuPage/>),
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: paths.bar.list,
|
||||
isPrivate: true,
|
||||
children: (<BarChangePage/>),
|
||||
},
|
||||
{
|
||||
path: paths.bar.ingredients,
|
||||
isPrivate: true,
|
||||
|
||||
111
front/src/app/pages/BarChangePage.js
Normal file
111
front/src/app/pages/BarChangePage.js
Normal file
@@ -0,0 +1,111 @@
|
||||
import Paper from "@mui/material/Paper";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {api} from "../../lib/clients/api";
|
||||
import {requests} from "../../requests";
|
||||
import {useAlert} from "../../hooks/useAlert";
|
||||
import {Card} from "@mui/material";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import Box from "@mui/material/Box";
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices';
|
||||
import {getComparator} from "../../components/core/getComparator";
|
||||
import Toolbar from "@mui/material/Toolbar";
|
||||
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||
import {BarCreateModal} from "../../components/BarCreateModal";
|
||||
import PowerIcon from '@mui/icons-material/Power';
|
||||
|
||||
export function BarChangePage() {
|
||||
const [bars, setBars] = useState([])
|
||||
const [open, setOpen] = useState(false)
|
||||
const {createError, createSuccess, createWarning} = useAlert();
|
||||
|
||||
useEffect(() => {
|
||||
api().get(requests.bar.list)
|
||||
.then((r) => {
|
||||
setBars(r.data.sort(getComparator("name")))
|
||||
})
|
||||
.catch(() => {
|
||||
createError("Ошибка получения списков")
|
||||
})
|
||||
}, []);
|
||||
const changeHandler = (bar) => {
|
||||
createWarning("Дождитесь окончания операции")
|
||||
api().post(`${requests.bar.change}/${bar.id}`)
|
||||
.then(() => createSuccess("Список изменен"))
|
||||
.catch(() => createError("Ошибка изменения активного списка"))
|
||||
|
||||
const newState = bars.map((b) => {
|
||||
if (b.active) {
|
||||
return {
|
||||
...b, active: false
|
||||
}
|
||||
}
|
||||
if (b.id === bar.id) {
|
||||
return {
|
||||
...b, active: true
|
||||
}
|
||||
}
|
||||
return b;
|
||||
})
|
||||
setBars(newState);
|
||||
}
|
||||
const deleteHandler = (bar) => {
|
||||
if (bar.active) {
|
||||
createError("Нельзя удалить активный бар!")
|
||||
return;
|
||||
}
|
||||
api().delete(requests.bar.crud + bar.id)
|
||||
.then(() => createSuccess("Список удален"))
|
||||
.catch(() => createError("Ошибка удаления. Обновите страницу"))
|
||||
|
||||
setBars(bars.filter((b) => b.id !== bar.id));
|
||||
}
|
||||
const createHandler = (name) => {
|
||||
api().post(requests.bar.crud + name)
|
||||
.then((r) => {
|
||||
createSuccess("Cписок создан");
|
||||
let state = bars;
|
||||
state.push(r.data);
|
||||
setBars(state)
|
||||
setOpen(false)
|
||||
}).catch(() => createError("Ошибка создания списка"))
|
||||
}
|
||||
|
||||
function closeHandler() {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
return (<>
|
||||
<BarCreateModal open={open} close={closeHandler} create={createHandler}/>
|
||||
<Paper sx={{p: 1}}>
|
||||
<Toolbar>
|
||||
<Typography variant='h6'>Списки ингредиентов (бары)</Typography>
|
||||
<IconButton edge="end" onClick={() => setOpen(true)}>
|
||||
<AddCircleIcon/>
|
||||
</IconButton>
|
||||
</Toolbar>
|
||||
{bars.map((b) => {
|
||||
return <Card key={b.id} sx={{m: 2, p: 2}}>
|
||||
<Stack direction='row' justifyContent={'space-between'}>
|
||||
<Typography>{b.name}</Typography>
|
||||
{b.active && <IconButton disabled>
|
||||
<PowerIcon/>
|
||||
</IconButton>}
|
||||
{!b.active && <Box>
|
||||
<IconButton onClick={() => deleteHandler(b)}>
|
||||
<DeleteIcon/>
|
||||
</IconButton>
|
||||
<IconButton onClick={() => changeHandler(b)}>
|
||||
<ElectricalServicesIcon/>
|
||||
</IconButton>
|
||||
</Box>}
|
||||
</Stack>
|
||||
</Card>
|
||||
})}
|
||||
</Paper>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
39
front/src/components/BarCreateModal.js
Normal file
39
front/src/components/BarCreateModal.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import Dialog from "@mui/material/Dialog";
|
||||
import DialogTitle from "@mui/material/DialogTitle";
|
||||
import * as React from "react";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import DialogContent from "@mui/material/DialogContent";
|
||||
import DialogActions from "@mui/material/DialogActions";
|
||||
import Button from "@mui/material/Button";
|
||||
import {useState} from "react";
|
||||
import TextField from "@mui/material/TextField";
|
||||
|
||||
export function BarCreateModal({open, close, create}) {
|
||||
const [value, setValue] = useState("");
|
||||
return (
|
||||
<Dialog fullWidth={true}
|
||||
open={open} onClose={close}
|
||||
sx={{
|
||||
'& .MuiDialog-paper': {
|
||||
margin: '8px',
|
||||
},
|
||||
'& .MuiPaper-root': {
|
||||
width: 'calc(100% - 16px)',
|
||||
}
|
||||
}}>
|
||||
<DialogTitle>
|
||||
<Typography>Создать список</Typography>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField sx={{width: '75%'}}
|
||||
label={"Название списка"} variant='outlined'
|
||||
value={!value ? "" : value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => create(value)}>Создать</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import EditIcon from '@mui/icons-material/Edit';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import LocalBarIcon from '@mui/icons-material/LocalBar';
|
||||
import {paths} from "../../path";
|
||||
import {useAlert} from "../../hooks/useAlert";
|
||||
|
||||
function renderFavouriteBadge(handleFavourite, row) {
|
||||
const childIcon = row.rating.favourite ? <FavoriteIcon/> : <FavoriteBorderIcon/>;
|
||||
@@ -33,6 +34,7 @@ function renderRating(handleChangeRating, row) {
|
||||
}
|
||||
|
||||
export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect, deleteHandler}) {
|
||||
const {notImplement} = useAlert();
|
||||
return (
|
||||
<Grid item sx={{pr: 2}}>
|
||||
<CocktailItemStyled>
|
||||
@@ -55,24 +57,23 @@ export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect
|
||||
image={row.image.includes("thecocktaildb") ? (row.image + "/preview") : row.image}
|
||||
/>
|
||||
<CardActions>
|
||||
<IconButton sx={{m: 0}} size='small'>
|
||||
<IconButton sx={{m: 0}} size='small' onClick={() => notImplement()}>
|
||||
<LocalBarIcon fontSize='small'/>
|
||||
</IconButton>
|
||||
{renderFavouriteBadge(handleFavourite, row)}
|
||||
{renderRating(handleChangeRating, row)}
|
||||
|
||||
<IconButton size={'small'} href={`${paths.bar.cocktailEdit}?id=${row.id}`}>
|
||||
<EditIcon fontSize={'small'}/>
|
||||
<IconButton size='small' href={`${paths.bar.cocktailEdit}?id=${row.id}`}>
|
||||
<EditIcon fontSize='small'/>
|
||||
</IconButton>
|
||||
<IconButton size={'small'} onClick={() => deleteHandler(row)}>
|
||||
<DeleteIcon fontSize={'small'}/>
|
||||
<IconButton size='small' onClick={() => deleteHandler(row)}>
|
||||
<DeleteIcon fontSize='small'/>
|
||||
</IconButton>
|
||||
</CardActions>
|
||||
<CardContent sx={{pb: 0, pl: 2, pt: 0}}>
|
||||
<Typography variant="h5" minHeight={'50px'} mt={2}>{row.name} </Typography>
|
||||
<CocktailDescription row={row}/>
|
||||
</CardContent>
|
||||
|
||||
</Box>
|
||||
</CocktailItemStyled>
|
||||
</Grid>
|
||||
|
||||
@@ -16,6 +16,10 @@ export function useAlert() {
|
||||
createAlert("Данный функционал пока не реализован", {variant: 'warning'});
|
||||
}
|
||||
|
||||
function createWarning(message) {
|
||||
createAlert(message, {variant: 'warning'})
|
||||
}
|
||||
|
||||
function createError(message) {
|
||||
createAlert(message, {variant: "error"});
|
||||
}
|
||||
@@ -28,5 +32,5 @@ export function useAlert() {
|
||||
createAlert(message, {variant: "success"});
|
||||
}
|
||||
|
||||
return {createAlert, notImplement, createError, getError, createSuccess}
|
||||
return {createAlert, notImplement, createError, getError, createSuccess, createWarning}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import {paths} from "./path";
|
||||
|
||||
export const navItems = [
|
||||
{key: 'menu', title: 'Меню', href: paths.dashboard.overview, icon: 'menu'},
|
||||
{key: 'barList', title: 'Список баров', href: paths.bar.list, icon: 'basket', forBarmen: true},
|
||||
{key: 'ingredients', title: 'Список ингредиентов', href: paths.bar.ingredients, icon: 'basket', forBarmen: true},
|
||||
{key: 'ingredientEdit', title: 'Ингредиенты', href: paths.bar.ingredientEdit, icon: 'ingredients', forAdmin: true},
|
||||
{key: 'cocktailEdit', title: 'Коктейли', href: paths.bar.cocktailEdit, icon: 'cocktail', forAdmin: true}
|
||||
|
||||
@@ -36,7 +36,9 @@ export const requests = {
|
||||
invite: routes.visitor + "/invite?"
|
||||
},
|
||||
bar: {
|
||||
list: routes.bar + "list",
|
||||
list: routes.bar + "all",
|
||||
change: routes.bar + "change",
|
||||
crud: routes.bar,
|
||||
addToMyList: routes.bar + "addToMyList",
|
||||
enter: routes.bar + "enter?id=",
|
||||
pay: routes.order + "?",
|
||||
|
||||
Reference in New Issue
Block a user