Skip to content

Commit

Permalink
feat(ui-common): Rework from almost scratch make ordering dynamic wit…
Browse files Browse the repository at this point in the history
…h services and stores
  • Loading branch information
Tsukoyachi committed Sep 25, 2024
1 parent e3d388a commit 0dd4f51
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 469 deletions.
2 changes: 2 additions & 0 deletions libs/services/common/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export * from './lib/services-common';
export * from './lib/group/groupService';
export * from './lib/offer/catalogue.service';
export * from './lib/offer/offer.service';
export * from './lib/table/table.service';
export * from './lib/apis/diningApiService';
export * from './lib/container';
Expand Down
2 changes: 2 additions & 0 deletions libs/services/common/src/lib/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { TYPES } from "./types";
import { MenuApiService } from "./apis/menuApiService";
import { OfferService } from "./offer/offer.service";
import { GroupServiceWorkflow } from "./group/groupServiceWorkflow";
import { CatalogService } from "./offer/catalogue.service";
import { GroupService } from "./group/groupService";

const container = new Container();
Expand All @@ -14,5 +15,6 @@ container.bind<TableService>(TYPES.TableService).to(TableService).inSingletonSco
container.bind<DiningApiService>(TYPES.DiningApiService).to(DiningApiService).inSingletonScope();
container.bind<MenuApiService>(TYPES.MenuApiService).to(MenuApiService).inSingletonScope();
container.bind<OfferService>(TYPES.OfferService).to(OfferService).inSingletonScope();
container.bind<CatalogService>(TYPES.CatalogService).to(CatalogService).inSingletonScope();

export { container };
19 changes: 12 additions & 7 deletions libs/services/common/src/lib/offer/catalogue.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class CatalogService {

async getFilteredCatalog(offerName: string) {
const offer = await this.offerService.getOffers().then(response =>
response.find(element => element.name.toLowerCase() === offerName.toLowerCase())
response.find(element => element.name?.toLowerCase() === offerName?.toLowerCase())
);

if (!offer) return {};
Expand All @@ -27,17 +27,22 @@ export class CatalogService {
item => offer.availableItems.includes(item._id)
);

const categorizedCatalog : CategorizedCatalog = {};
const categorizedCatalog: CategorizedCatalog = {};

availableCatalog.forEach(element => {
if (element.category in categorizedCatalog) {
categorizedCatalog[element.category] = [element];
}
else {
categorizedCatalog[element.category].push(element);
if (!categorizedCatalog[element.category]) {
categorizedCatalog[element.category] = [];
}
categorizedCatalog[element.category].push(element);
});

return categorizedCatalog;
}


async getFullItemFromItemIdsArray(idList: string[]) {
return (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter(
item => idList.includes(item._id)
);
}
}
3 changes: 1 addition & 2 deletions libs/services/common/src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { OfferService } from "./offer/offer.service";

export const TYPES = {
GroupService: Symbol.for('GroupService'),
TableService: Symbol.for('TableService'),
DiningApiService: Symbol.for('DiningApiService'),
MenuApiService: Symbol.for('MenuApiService'),
OfferService: Symbol.for('OfferService'),
CatalogService: Symbol.for('CatalogService'),
BackendBffApiService: Symbol.for('BackendBffApiService'),
};

16 changes: 9 additions & 7 deletions libs/ui/common/src/lib/commandsR/commands.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useState } from 'react';
import { useState } from 'react';
import { Box, SpeedDial } from '@mui/material';
import NavBar from '../utils/navbar';
import Orders from '../orders/orders';
import BackButton from '../utils/backButton';
import OrderingChoices from './orederingChoices';
import OrderingChoices from './orderingChoices';
import { setSelectedTableById, tablesMenu } from '../utils/tableUtils';
//SpeedDial imports
import SpeedDialIcon from '@mui/material/SpeedDialIcon';
Expand All @@ -13,14 +13,16 @@ import GroupsIcon from '@mui/icons-material/Groups';
import CloseIcon from '@mui/icons-material/Close';
import DollarIcon from '@mui/icons-material/AttachMoney';
import { useNavigate, useParams } from 'react-router-dom';
import { useTableSummary } from './stores/tableSummary';
import Summary from '../summary/summary';
import { useCarts } from './stores/cart';

export function Commands() {
const navigate = useNavigate();
const {groupId} = useParams();
const [selectedTable, setSelectedTable] = useState(tablesMenu[0]);
const haveCurrentCommand = useTableSummary(state=>state.tables).length > 0;
const haveCurrentCommand = (useCarts(state => state.carts)[selectedTable.id] ?? []).length > 0;

const offerType = "Classic";

const speedDialActions = [
{ icon: <TableRestaurantIcon />, name: 'Table Payment', operation: onClickTableBilling },
Expand Down Expand Up @@ -78,9 +80,9 @@ export function Commands() {
</Box>
<Box sx={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
<BackButton onClick={onClickBackButton} color={'black'} top={20} left={150}></BackButton>
{selectedTable && <OrderingChoices selectedTable={selectedTable} />}
{haveCurrentCommand && <Summary></Summary>}
{!haveCurrentCommand && <Orders></Orders>}
{selectedTable && <OrderingChoices tableNumber={selectedTable.id} offerType={offerType} />}
{haveCurrentCommand && <Summary tableNumber={selectedTable.id} offerType='Classic'></Summary>}
{!haveCurrentCommand && <Orders groupId={groupId ?? ''}></Orders>}
</Box>
</Box>
</div>
Expand Down
156 changes: 156 additions & 0 deletions libs/ui/common/src/lib/commandsR/orderingChoices.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import React, { useState } from 'react';
import { Box, Button, Typography } from '@mui/material';
import './orderingChoices.css';
import { useCarts } from './stores/cart';
import { useQuery } from '@tanstack/react-query';
import { ContainerContext } from '../containerHook/containerContext';
import { CatalogService, TYPES } from '@spos/services/common';

interface OrderingChoicesProps {
tableNumber: number,
offerType: string
}

type Cart = {
itemId: string;
quantity: number;
}[]

export function OrderingChoices(props: Readonly<OrderingChoicesProps>) {
const currentTableCart: Cart = (useCarts(state => state.carts)[props.tableNumber] || []);
console.table(currentTableCart);
const container = React.useContext(ContainerContext);

const updateItem = useCarts(state => state.updateItem);

const {
data: catalog,
isLoading,
isError,
error,
} = useQuery({
queryKey: ['catalog'],
queryFn: async () => {
const catalogService : CatalogService = container.get<CatalogService>(TYPES.CatalogService);
console.log('', catalogService);
return catalogService.getFilteredCatalog(props.offerType);
},
refetchOnWindowFocus: 'always',
});

if(isError) {
console.log(error);
return (
<Typography variant="h6" component="h2" fontWeight="bold">
Help
</Typography>
);
}

if (isLoading) {
return (
<Typography variant="h6" component="h2" fontWeight="bold">
Loading
</Typography>
);
}

if (!catalog) {
return (
<Typography variant="h6" component="h2" fontWeight="bold">
Loading
</Typography>
);
}

function handleSelectItem(itemId: string) {
if (currentTableCart.find(element => element.itemId === itemId) !== undefined) {
updateItem(props.tableNumber, itemId, 0);
}
else {
updateItem(props.tableNumber, itemId, 1);
}
}

function handleDecrease(itemId: string) {
const quantity = currentTableCart.find(element => element.itemId === itemId)?.quantity;
if (quantity !== undefined && quantity > 0) {
updateItem(props.tableNumber, itemId, quantity-1);
}
}

function handleIncrease(itemId: string) {
const quantity = currentTableCart.find(element => element.itemId === itemId)?.quantity;
updateItem(props.tableNumber, itemId,(quantity !== undefined) ? quantity+1 : 1);
}

return (
<Box
className="custom-scrollbar"
sx={{
padding: '16px',
marginTop: '110px',
display: 'flex',
flexDirection: 'column',
gap: '14px',
height: '80vh',
overflowY: 'auto',
border: '1px solid #ccc',
width: 'calc(100% - 32px)',
position: 'relative',
left: '0',
}}
>
{Object.keys(catalog).map((category) => (
<Box key={category} sx={{ marginBottom: '24px' }}>
<Typography variant="h6">{category}</Typography>
<Box sx={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
{catalog[category].length > 0 ? (
catalog[category].map((item) => {
const count = currentTableCart.find(element => element.itemId === item._id)?.quantity ?? 0;
const isSelected = Boolean(currentTableCart.find(element => element.itemId === item._id));

return (
<Box key={item._id} sx={{ display: 'inline', flexDirection: 'column', alignItems: 'center' }}>
<Button
variant="contained"
onClick={() => handleSelectItem(item._id)}
sx={{
width: '100px',
height: '100px',
borderRadius: '0px',
backgroundColor: isSelected ? 'green' : '#ff6f61',
color: 'white',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
fontSize: '1.2rem',
'&:hover': {
backgroundColor: isSelected ? 'darkgreen' : '#ff4d94',
},
}}
>
{item.shortName}
</Button>
{isSelected && (
<Box sx={{ display: 'inline-flex', justifyContent: 'center', marginTop: '8px' }}>
<Button sx={{ minWidth: '4vh' }} onClick={() => handleDecrease(item._id)}>-</Button>
<Typography>{count}</Typography>
<Button sx={{ minWidth: '4vh'}} onClick={() => handleIncrease(item._id)}>+</Button>
</Box>
)}
</Box>
);
})
) : (
<Typography>No Choices</Typography>
)}
</Box>
</Box>
))}
</Box>
);
};

export default OrderingChoices;

Loading

0 comments on commit 0dd4f51

Please sign in to comment.