add stocking page

This commit is contained in:
zadit frontend
2024-08-03 07:29:36 +00:00
parent c4654ce64f
commit 5b4de33afb
21 changed files with 990 additions and 248 deletions

View File

@@ -213,6 +213,7 @@ const Header = ({
HeaderText,
shopId,
shopName,
shopOwnerId,
shopClerks,
tableId,
showProfile,
@@ -305,21 +306,56 @@ const Header = ({
{user.username !== undefined && (
<Child onClick={() => setModal("edit_account")}>Edit</Child>
)}
{shopId && user.username !== undefined && user.roleId === 1 && (
<>
<Child onClick={goToAdminCafes}>see your other cafes</Child>
<Child onClick={() => setModal("edit_tables")}>
{shopName} table maps
</Child>
<Child hasChildren>
{shopName} clerks
<Child onClick={() => setModal("craete_account_clerk")}>
+ Add clerk
{shopId &&
user.userId == shopOwnerId &&
user.username !== undefined &&
user.roleId === 1 && (
<>
<Child onClick={goToAdminCafes}>see your other cafes</Child>
<Child onClick={() => setModal("edit_tables")}>
{shopName} table maps
</Child>
{shopClerks &&
shopClerks.map((key, index) => (
<Child hasChildren>
{shopName} clerks
<Child onClick={() => setModal("craete_account_clerk")}>
+ Add clerk
</Child>
{shopClerks &&
shopClerks.map((key, index) => (
<Child key={index}>
{shopClerks[index].username}
<button
onClick={() =>
removeConnectedGuestSides(guestSides[index][3])
}
>
remove
</button>
</Child>
))}
</Child>
<Child onClick={() => setModal("add_material")}>
add material
</Child>
</>
)}
{user.username !== undefined &&
((user.userId == shopOwnerId && user.roleId === 1) ||
(user.cafeId == shopId && user.roleId === 2)) && (
<Child onClick={() => setModal("update_stock")}>
update stock
</Child>
)}
{user.username !== undefined &&
user.roleId == 2 &&
user.cafeId == shopId && (
<Child hasChildren>
connected guest sides
<Child onClick={goToGuestSideLogin}>+ Add guest side</Child>
{guestSides &&
guestSides.map((key, index) => (
<Child key={index}>
{shopClerks[index].username}
guest side {index + 1}
<button
onClick={() =>
removeConnectedGuestSides(guestSides[index][3])
@@ -330,33 +366,7 @@ const Header = ({
</Child>
))}
</Child>
</>
)}
{user.username !== undefined &&
(user.roleId === 1 || user.roleId === 2) && (
<Child onClick={() => setModal("update_stock")}>
update stock
</Child>
)}
{user.username !== undefined && user.roleId === 2 && (
<Child hasChildren>
connected guest sides
<Child onClick={goToGuestSideLogin}>+ Add guest side</Child>
{guestSides &&
guestSides.map((key, index) => (
<Child key={index}>
guest side {index + 1}
<button
onClick={() =>
removeConnectedGuestSides(guestSides[index][3])
}
>
remove
</button>
</Child>
))}
</Child>
)}
{user.username !== undefined && (
<Child onClick={isLogout}>Logout</Child>
)}

View File

@@ -17,6 +17,7 @@ const ItemLister = ({
itemTypeId,
refreshTotal,
shopId,
shopOwnerId,
user,
typeName,
itemList,
@@ -27,7 +28,7 @@ const ItemLister = ({
itemList.map((item) => ({
...item,
qty: getItemQtyFromCart(shopId, item.itemId),
})),
}))
);
const [isEdit, setIsEditing] = useState(false);
const [isAddingNewItem, setIsAddingNewItem] = useState(false);
@@ -111,17 +112,22 @@ const ItemLister = ({
return (
<>
{(items.length > 0 || (user && user.roleId == 1)) && (
{(items.length > 0 ||
(user && user.roleId == 1 && user.userId == shopOwnerId)) && (
<div className={styles["item-lister"]}>
<div className={styles["title-container"]}>
<input
ref={typeNameInputRef}
className={`${styles.title} ${user && user.roleId == 1 && isEdit ? styles.border : styles.noborder}`}
className={`${styles.title} ${
user && user.roleId == 1 && user.userId == shopOwnerId && isEdit
? styles.border
: styles.noborder
}`}
value={editedTypeName}
onChange={(e) => setEditedTypeName(e.target.value)}
disabled={!isEdit}
/>
{user && user.roleId == 1 && (
{user && user.roleId == 1 && user.userId == shopOwnerId && (
<>
<button
className={styles["edit-typeItem-button"]}
@@ -141,31 +147,34 @@ const ItemLister = ({
)}
</div>
<div className={styles["item-list"]}>
{user && user.roleId == 1 && isEdit && (
<>
<button
className={styles["add-item-button"]}
onClick={toggleAddNewItem}
>
{isAddingNewItem ? "Cancel" : "Add new Item"}
</button>
{isAddingNewItem && (
<Item
blank={true}
handleCreateItem={(name, price, qty, selectedImage) =>
createItem(
shopId,
name,
price,
qty,
selectedImage,
itemTypeId,
)
}
/>
)}
</>
)}
{user &&
user.roleId == 1 &&
user.userId == shopOwnerId &&
isEdit && (
<>
<button
className={styles["add-item-button"]}
onClick={toggleAddNewItem}
>
{isAddingNewItem ? "Cancel" : "Add new Item"}
</button>
{isAddingNewItem && (
<Item
blank={true}
handleCreateItem={(name, price, qty, selectedImage) =>
createItem(
shopId,
name,
price,
qty,
selectedImage,
itemTypeId
)
}
/>
)}
</>
)}
{items.map((item) => {
return !forCart || (forCart && item.qty > 0) ? (
<Item
@@ -183,16 +192,19 @@ const ItemLister = ({
) : null;
})}
{user && user.roleId == 1 && isEdit && (
<>
<button
className={styles["add-item-button"]}
onClick={handleRemoveType}
>
Remove
</button>
</>
)}
{user &&
user.roleId == 1 &&
user.userId == shopOwnerId &&
isEdit && (
<>
<button
className={styles["add-item-button"]}
onClick={handleRemoveType}
>
Remove
</button>
</>
)}
</div>
</div>
)}

View File

@@ -1,8 +1,14 @@
import React, { useRef, useEffect, useState } from 'react';
import styles from './ItemType.module.css';
import { getImageUrl } from '../helpers/itemHelper';
import React, { useRef, useEffect, useState } from "react";
import styles from "./ItemType.module.css";
import { getImageUrl } from "../helpers/itemHelper";
export default function ItemType({ onClick, onCreate, blank, name: initialName = '', imageUrl }) {
export default function ItemType({
onClick,
onCreate,
blank,
name: initialName = "",
imageUrl,
}) {
const inputRef = useRef(null);
const [name, setName] = useState(initialName);
const [selectedImage, setSelectedImage] = useState(null);
@@ -36,17 +42,21 @@ export default function ItemType({ onClick, onCreate, blank, name: initialName =
const handleCreate = async () => {
if (!selectedImage) {
console.error('No image selected');
console.error("No image selected");
return;
}
onCreate(name, selectedImage);
};
return (
<div className={styles["item-type"]}>
<div onClick={onClick} className={styles["item-type-rect"]}>
<img src={previewUrl} alt={name} className={styles["item-type-image"]} />
<img
src={previewUrl}
alt={name}
className={styles["item-type-image"]}
/>
{blank && (
<input
type="file"
@@ -58,7 +68,9 @@ export default function ItemType({ onClick, onCreate, blank, name: initialName =
</div>
<input
ref={inputRef}
className={`${styles["item-type-name"]} ${blank ? styles.border : styles.noborder}`}
className={`${styles["item-type-name"]} ${
blank ? styles.border : styles.noborder
}`}
value={name}
onChange={handleNameChange}
disabled={!blank}

View File

@@ -1,72 +1,67 @@
.item-type {
width: calc(25vw - 20px);
/* Adjust size as needed, subtracting margin */
height: calc(39vw - 20px);
/* Adjust size as needed */
margin: 1px 10px -5px;
/* Left and right margin */
overflow: hidden;
text-align: center;
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
width: calc(25vw - 20px);
height: calc(39vw - 20px);
margin: 1px 10px -5px;
overflow: hidden;
text-align: center;
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
position: relative; /* Ensure absolute positioning inside works */
}
.item-type-rect {
position: relative;
height: 20vw;
width: 20vw;
object-fit: cover;
border-radius: 15px;
/* Rounded corners */
background-color: #fff;
/* Background color of the item */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
/* Optional: Shadow for better visual */
position: relative;
height: 20vw;
width: 20vw;
object-fit: cover;
border-radius: 15px;
background-color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.item-type-name {
position: relative;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
top: 13px;
margin-bottom: 14px;
font-size: 14px;
/* Adjust font size as needed */
color: #333;
width: calc(25vw - 30px);
/* Adjust size as needed, subtracting margin */
text-align: center;
background-color: transparent;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
margin-bottom: 10px; /* Adjust margin for spacing */
font-size: 14px;
color: #333;
width: calc(25vw - 30px);
text-align: center;
background-color: transparent;
position: relative; /* Needed for positioning the button */
}
.item-type-image {
width: 100%;
height: 100%;
object-fit: contain;
border-radius: 15px;
/* Rounded corners */
width: 100%;
height: 100%;
object-fit: contain;
border-radius: 15px;
}
.item-type-image-input {
position: absolute;
left: 0;
width: 100%;
height: 100%;
position: absolute;
left: 0;
width: 100%;
height: 100%;
}
.item-type-create {
position: absolute;
margin-top: 130px;
width: 20vw;
position: absolute;
top: 80%; /* Position below the input */
left: 50%;
transform: translateX(-50%);
margin-top: 10px; /* Space between input and button */
width: 20vw;
text-align: center; /* Center button text */
}
.border {
border: 1px solid #000000;
border: 1px solid #000000;
}
.noborder {
border: 1px solid #ffffff00;
}
border: 1px solid #ffffff00;
}

View File

@@ -1,44 +1,64 @@
import React, { useState } from 'react';
import './ItemTypeLister.css';
import ItemType from './ItemType';
import { createItemType } from '../helpers/itemHelper.js';
import React, { useState } from "react";
import "./ItemTypeLister.css";
import ItemType from "./ItemType";
import { createItemType } from "../helpers/itemHelper.js";
const ItemTypeLister = ({ shopId, user, itemTypes }) => {
const ItemTypeLister = ({ shopId, shopOwnerId, user, itemTypes }) => {
const [isAddingNewItem, setIsAddingNewItem] = useState(false);
const toggleAddNewItem = () => {
console.log("aaa")
setIsAddingNewItem(prev => !prev);
console.log("aaa");
setIsAddingNewItem((prev) => !prev);
};
async function handleCreate(name, selectedImage) {
createItemType(shopId, name, selectedImage);
};
}
return (
<div className="item-type-lister">
<div className="item-type-list">
{itemTypes && itemTypes.length > 1 &&
<ItemType name={"All"} imageUrl={"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAY1BMVEX///8BAQEEBAT09PT8/PzFxcWGhobu7u7R0dHLy8uoqKhTU1N7e3tXV1fIyMguLi7d3d08PDyenp41NTWBgYF1dXVHR0dMTEwTExPj4+O6urrp6emWlpasrKy2trZeXl4aGhrSJRZxAAADF0lEQVR4nO3Zi3aiMBCAYQIR71VbtXft+z/lJoFigAkNbYHdPf/X3VPqGeMkwdxIEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0dGBVaSOe5vuV/4giqR1mXOPXL6M1X4r9Cn5l+kqCx3R2Nq7igjWPYoeWjbPkpg09LdiJ/dyPK3P22O+iIid5ZvtebvJZxGxi/y4Pa9Px5efJvh99i56fVM3q+4RJFv5seHeseVqP/btdYDsY5hE7nZVGqn5/7jvqOHiUASVDsE+NyXsH5UfvLub4qtoP/Hd5lEkYn+Zf+Fb9d7lXAa73/fB2KUryytZvQ9Qgy9pm3TqNbW7WAai72udojqruKwq5sdOMJ4ub51SXNnrp2cxdqH8YHcd7PHnp7J+foebphu9inMl+pAyyQ5i7KE13Nj3ftQ6sDIfvkoNef22U59fmoswKqzaCTurRqz942ILaZZs/j6OVrPS805o6dS8dG3Uz65fAhVUqrG6MROFvkpdaF7ZjT1nvAj5Fm2/b1VxpsSszc+s2d96r+rf2Fv02FP/SeoSl9ildZfmUtLulbxV7kW6+Z3TOBWrVBVqWbdiN3LKxqYVuxbj3CeNUS2PON45D80+zLbBGm6z5lDzEIg0Hzdm9ZIkPHioXTN0/hiMPbfmgF0wlj78be5TxVz+l+/hSZ7vVXMstXuh7rFU14IvwaYbeyztmg/rd6mdD8UZLm3Nhzo8H6rR50N5TWN+rllz2dZjTZPYNU0qr2nkNf2AOtalPleBjnVpy0Uaw8TFwdCkvUVq9xaC6L2F9SG3xuh7C11uVG91c20fuT9UX+wPG7vlNLy1HtDnHr/KojORnnv81LtVXbmT7PHdOU119FL8Crd0/3Mav+RJzmnks7bwAbx/1pb+C2dthZ+cl4aO9l0prfPSCQ/2izPvzQBn3pupz7wL3vOFqEczsc8tkuSveW5RinqcJF/Lwf7TxsmfPcWmoIWrUGjt+eF3Uvolfdq3Pg71ehsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACASfwBIesXINu4PFgAAAAASUVORK5CYII="} />
}
{itemTypes && itemTypes.map(itemType => (
(user && user.roleId == 1 || itemType.itemList.length > 0) && (
{itemTypes && itemTypes.length > 1 && (
<ItemType
name={"All"}
imageUrl={
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAY1BMVEX///8BAQEEBAT09PT8/PzFxcWGhobu7u7R0dHLy8uoqKhTU1N7e3tXV1fIyMguLi7d3d08PDyenp41NTWBgYF1dXVHR0dMTEwTExPj4+O6urrp6emWlpasrKy2trZeXl4aGhrSJRZxAAADF0lEQVR4nO3Zi3aiMBCAYQIR71VbtXft+z/lJoFigAkNbYHdPf/X3VPqGeMkwdxIEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0dGBVaSOe5vuV/4giqR1mXOPXL6M1X4r9Cn5l+kqCx3R2Nq7igjWPYoeWjbPkpg09LdiJ/dyPK3P22O+iIid5ZvtebvJZxGxi/y4Pa9Px5efJvh99i56fVM3q+4RJFv5seHeseVqP/btdYDsY5hE7nZVGqn5/7jvqOHiUASVDsE+NyXsH5UfvLub4qtoP/Hd5lEkYn+Zf+Fb9d7lXAa73/fB2KUryytZvQ9Qgy9pm3TqNbW7WAai72udojqruKwq5sdOMJ4ub51SXNnrp2cxdqH8YHcd7PHnp7J+foebphu9inMl+pAyyQ5i7KE13Nj3ftQ6sDIfvkoNef22U59fmoswKqzaCTurRqz942ILaZZs/j6OVrPS805o6dS8dG3Uz65fAhVUqrG6MROFvkpdaF7ZjT1nvAj5Fm2/b1VxpsSszc+s2d96r+rf2Fv02FP/SeoSl9ildZfmUtLulbxV7kW6+Z3TOBWrVBVqWbdiN3LKxqYVuxbj3CeNUS2PON45D80+zLbBGm6z5lDzEIg0Hzdm9ZIkPHioXTN0/hiMPbfmgF0wlj78be5TxVz+l+/hSZ7vVXMstXuh7rFU14IvwaYbeyztmg/rd6mdD8UZLm3Nhzo8H6rR50N5TWN+rllz2dZjTZPYNU0qr2nkNf2AOtalPleBjnVpy0Uaw8TFwdCkvUVq9xaC6L2F9SG3xuh7C11uVG91c20fuT9UX+wPG7vlNLy1HtDnHr/KojORnnv81LtVXbmT7PHdOU119FL8Crd0/3Mav+RJzmnks7bwAbx/1pb+C2dthZ+cl4aO9l0prfPSCQ/2izPvzQBn3pupz7wL3vOFqEczsc8tkuSveW5RinqcJF/Lwf7TxsmfPcWmoIWrUGjt+eF3Uvolfdq3Pg71ehsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACASfwBIesXINu4PFgAAAAASUVORK5CYII="
}
/>
)}
{itemTypes &&
itemTypes.map(
(itemType) =>
((user && user.roleId == 1 && user.userId == shopOwnerId) ||
itemType.itemList.length > 0) && (
<ItemType
key={itemType.itemTypeId}
name={itemType.name}
imageUrl={itemType.image}
/>
)
)}
{user &&
user.roleId == 1 &&
user.userId == shopOwnerId &&
isAddingNewItem && (
<ItemType blank={true} name={"blank"} onCreate={handleCreate} />
)}
{!isAddingNewItem &&
user &&
user.roleId == 1 &&
user.userId == shopOwnerId && (
<ItemType
key={itemType.itemTypeId}
name={itemType.name}
imageUrl={itemType.image}
onClick={toggleAddNewItem}
name={"create"}
imageUrl={
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQnd07OYAm1f7T6JzziFU7U8X1_IL3bADiVrg&usqp=CAU"
}
/>
)
))}
{user && user.roleId == 1 && isAddingNewItem &&
<ItemType blank={true} name={"blank"} onCreate = {handleCreate} />
}
{user && user.roleId == 1 &&
<ItemType onClick = {toggleAddNewItem} name={"create"} imageUrl={"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQnd07OYAm1f7T6JzziFU7U8X1_IL3bADiVrg&usqp=CAU"} />
}
)}
</div>
</div>
);
}
};
export default ItemTypeLister;

View File

@@ -3,6 +3,10 @@ import styles from "./Modal.module.css";
import TablesPage from "./TablesPage.js";
import TableMaps from "../components/TableMaps";
import Transactions from "../pages/Transactions";
import Transaction_pending from "../pages/Transaction_pending";
import Transaction_success from "../pages/Transaction_success";
import MaterialList from "../pages/MaterialList.js";
import MaterialMutationsPage from "../pages/MaterialMutationsPage.js";
const Modal = ({ shopId, isOpen, onClose, modalContent }) => {
if (!isOpen) return null;
@@ -28,6 +32,12 @@ const Modal = ({ shopId, isOpen, onClose, modalContent }) => {
{modalContent === "edit_tables" && <TablesPage shopId={shopId} />}
{modalContent === "new_transaction" && (
<Transactions propsShopId={shopId} />
)}{" "}
{modalContent === "transaction_pending" && <Transaction_pending />}
{modalContent === "transaction_success" && <Transaction_success />}
{modalContent === "add_material" && <MaterialList cafeId={shopId} />}
{modalContent === "update_stock" && (
<MaterialMutationsPage cafeId={shopId} />
)}
</div>
</div>

View File

@@ -13,13 +13,12 @@
.modalContent {
background: white;
padding: 20px;
border-radius: 5px;
width: 80%;
width: 90%;
height: 80%;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
position: relative;
overflow: auto; /* Add this line to enable scrolling */
overflow: hidden; /* Add this line to enable scrolling */
}
.closeButton {

View File

@@ -4,7 +4,7 @@ const TableCanvas = ({
tables,
selectedTable,
newTable,
setTableNo,
isAdmin,
handleSelectTable,
handleAddTable,
moveTable,
@@ -91,11 +91,12 @@ const TableCanvas = ({
context.fillStyle = "white";
context.textAlign = "center";
context.textBaseline = "middle";
console.log(selectedTable);
context.fillText(
table.tableId === (selectedTable?.tableId || newTable?.tableId)
? tableNo === 0
? "clerk"
: tableNo
: tableNo || (isAdmin ? "" : table.tableNo)
: table.tableNo === 0
? "clerk"
: table.tableNo,
@@ -106,7 +107,7 @@ const TableCanvas = ({
}, [tables, canvasSize, newTable, selectedTable, tableNo]);
return (
<div ref={containerRef} style={{ width: "100%", height: "100%" }}>
<div ref={containerRef} style={{ height: "20%" }}>
<canvas
ref={canvasRef}
style={{
@@ -116,7 +117,7 @@ const TableCanvas = ({
}}
onClick={handleSelectTable}
/>
<div>
<div style={{ visibility: isAdmin ? "" : "hidden" }}>
{!selectedTable && !newTable && (
<button
onClick={handleAddTable}
@@ -127,11 +128,11 @@ const TableCanvas = ({
backgroundColor: "#007bff",
color: "#fff",
border: "none",
borderRadius: "4px",
fontSize: "16px",
cursor: "pointer",
marginBottom: "10px",
transition: "background-color 0.3s ease",
visibility: isAdmin ? "" : "hidden",
}}
>
Add Table
@@ -143,6 +144,7 @@ const TableCanvas = ({
display: "flex",
flexDirection: "column",
alignItems: "center",
display: isAdmin ? "visible" : "hidden",
}}
>
<div

View File

@@ -175,9 +175,18 @@ const TablesPage = ({ shopId }) => {
return (
<div
style={{ display: "flex", flexDirection: "column", alignItems: "center" }}
style={{
overflowX: "hidden", // Correct property name for horizontal overflow
backgroundColor: "#e9e9e9", // Remove duplicate property
display: "flex",
flexDirection: "column",
justifyContent: "center",
fontSize: "calc(10px + 2vmin)",
color: "rgba(88, 55, 50, 1)",
}}
>
<TableCanvas
isAdmin={true}
tables={tables}
selectedTable={selectedTable}
newTable={newTable}