From 8f50909e1a25aac7a6cf5e3eb38fbbf99c8ea180 Mon Sep 17 00:00:00 2001 From: zadit <75159257+insvrgent@users.noreply.github.com> Date: Thu, 17 Oct 2024 00:15:35 +0700 Subject: [PATCH] ok --- package-lock.json | 16 ++-- public/service-worker.js | 12 +-- src/App.js | 15 +--- src/components/Footer.js | 4 +- src/components/Footer.module.css | 2 +- src/components/Header.js | 7 +- src/components/Item.js | 4 +- src/components/Item.module.css | 26 +++--- src/components/ItemLister.js | 12 ++- src/components/ItemLister.module.css | 5 +- src/components/ItemTypeLister.js | 18 ++-- src/components/Modal.js | 2 + src/components/MusicPlayer.css | 38 ++++++-- src/components/MusicPlayer.js | 129 ++++++++++++++++++--------- src/components/TableList.js | 50 +++++++++-- src/components/TablesPage.js | 50 ++++++----- src/config.js | 2 +- src/helpers/itemHelper.js | 14 ++- src/helpers/userHelpers.js | 5 +- src/pages/CafePage.js | 29 ++---- src/pages/Cart.js | 10 +-- src/pages/CreateClerk.js | 111 +++++++++++++++++++++++ src/pages/Dashboard.js | 31 +++++-- 23 files changed, 415 insertions(+), 177 deletions(-) create mode 100644 src/pages/CreateClerk.js diff --git a/package-lock.json b/package-lock.json index 9575e92..0da4796 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8031,14 +8031,6 @@ "tslib": "^2.0.3" } }, - "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "engines": { - "node": ">=10" - } - }, "node_modules/dotenv-expand": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", @@ -16193,6 +16185,14 @@ } } }, + "node_modules/react-scripts/node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, "node_modules/react-switch": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/react-switch/-/react-switch-7.0.0.tgz", diff --git a/public/service-worker.js b/public/service-worker.js index a657dac..a00e01e 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -20,10 +20,10 @@ self.addEventListener("notificationclick", (event) => { const { cafeId, transactionId } = event.notification.data; // Get the notification data - // Open the URL with the cafeId and transactionId - event.waitUntil( - clients.openWindow( - `https://srrk5s-3000.csb.app/${cafeId}?modal=new_transaction&transactionId=${transactionId}` - ) - ); + // Dynamically detect the domain and construct the URL + const domainUrl = self.location.origin; + const url = `${domainUrl}/${cafeId}?modal=new_transaction&transactionId=${transactionId}`; + + // Open the constructed URL + event.waitUntil(clients.openWindow(url)); }); diff --git a/src/App.js b/src/App.js index 208766d..c545d83 100644 --- a/src/App.js +++ b/src/App.js @@ -142,20 +142,6 @@ function App() { setGuestSides(sessionLeft.guestSideList); }; - // const checkNotifications = async (userId) => { - // try { - // const permissionGranted = - // await NotificationService.requestNotificationPermission(setModal); - // if (permissionGranted) { - // await SubscriptionService.subscribeUserToNotifications(userId); - // } else { - // setModal("blocked_notification"); - // console.log("req notif"); - // } - // } catch (error) { - // console.error("Error handling notifications:", error); - // } - // }; useEffect(() => { if (socket == null) return; @@ -227,6 +213,7 @@ function App() { removeLocalStorage("auth"); setDeviceType("guestDevice"); } else { + console.log(data) setUser(data.data.user); if ( data.data.user.password == "unsetunsetunset" && diff --git a/src/components/Footer.js b/src/components/Footer.js index c070023..17601a0 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -124,7 +124,7 @@ export default function Footer({ {/* Rounded Rectangle with "Scan Meja" and QR Icon */} - {showTable && shopId && ( + {/* {showTable && shopId && (
)}
- )} + )} */} ); } diff --git a/src/components/Footer.module.css b/src/components/Footer.module.css index d4e17a6..c8605c1 100644 --- a/src/components/Footer.module.css +++ b/src/components/Footer.module.css @@ -3,7 +3,7 @@ .footer-rect { height: 75px; background-color: #fff; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5); display: flex; justify-content: space-around; /* Adjust spacing between SVG icons */ diff --git a/src/components/Header.js b/src/components/Header.js index 3f793eb..f62b26d 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -301,7 +301,7 @@ const Header = ({ {shopName == null ? HeaderText == null - ? "Groovebrew" + ? "kedaimaster" : HeaderText : generateMenuHeader(shopName)} @@ -331,12 +331,13 @@ const Header = ({ Edit profile )} + {shopId && user.roleId == 1 && ( + see your {user.userId == shopOwnerId ? 'other' : ''} cafes)} {shopId && user.userId == shopOwnerId && user.username !== undefined && user.roleId === 1 && ( <> - see your other cafes {/* setModal("update_stock")}> update stock @@ -365,7 +366,7 @@ const Header = ({ clerks - setModal("craete_account_clerk")}> + setModal("create_clerk")}> + Add clerk {shopClerks && diff --git a/src/components/Item.js b/src/components/Item.js index 33d52ec..c0b5981 100644 --- a/src/components/Item.js +++ b/src/components/Item.js @@ -205,11 +205,11 @@ const Item = ({
) : ( diff --git a/src/components/Item.module.css b/src/components/Item.module.css index a3f2f72..bb14c24 100644 --- a/src/components/Item.module.css +++ b/src/components/Item.module.css @@ -33,7 +33,7 @@ .itemImage { width: 139px; height: 149px; - border-radius: 20px; + border-radius: 10px; margin-right: 10px; object-fit: cover; position: relative; @@ -167,17 +167,19 @@ } .addButton { - background-color: #04aa6d; - border: none; - color: white; - display: inline-block; - font-size: 16px; - cursor: pointer; - width: 95px; - height: 35px; - margin-left: 5px; - margin-top: 5px; - border-radius: 20px; + background-color: #ffffff; + border: 2px solid #73a585; + /* border: none; */ + color: #73a585; + display: inline-block; + font-size: 16px; + font-weight: 600; + cursor: pointer; + width: 95px; + height: 35px; + margin-left: 5px; + margin-top: 5px; + border-radius: 20px; } .grayscale { filter: grayscale(100%); diff --git a/src/components/ItemLister.js b/src/components/ItemLister.js index 8a28208..66fb86b 100644 --- a/src/components/ItemLister.js +++ b/src/components/ItemLister.js @@ -151,6 +151,7 @@ const ItemLister = ({ const handleImageChange = (previewUrl, selectedImage) => { setSelectedImage(selectedImage); console.log(selectedImage); + console.log(previewUrl); setPreviewUrl(previewUrl); }; @@ -288,10 +289,13 @@ const ItemLister = ({ handleCreateItem(itemTypeId, name, price, selectedImage); } } else { + console.log(selectedImage) + console.log(previewUrl) const itemType = await createItemType( shopId, editedTypeName, - selectedImage + selectedImage, + previewUrl ); console.log(itemType); for (const { name, price, selectedImage } of itemsToCreate) { @@ -301,6 +305,7 @@ const ItemLister = ({ // Clear the itemsToUpdate after saving setItemsToUpdate([]); setIsEditing(false); + if (handleUnEdit) handleUnEdit(); } catch (error) { console.error("Failed to save item type:", error); } @@ -503,9 +508,8 @@ const ItemLister = ({ )}
- {user && - user.roleId == 1 && - user.userId == shopOwnerId && + {user &&( + user.userId == shopOwnerId || user.cafeId == shopId) && isEditMode && ( <> {!isAddingNewItem && ( diff --git a/src/components/ItemLister.module.css b/src/components/ItemLister.module.css index 265bb0d..9003e6d 100644 --- a/src/components/ItemLister.module.css +++ b/src/components/ItemLister.module.css @@ -1,15 +1,13 @@ /* ItemLister.module.css */ .item-lister { + border-top: 1px solid #888; width: 100%; padding: 10px; /* Adjust padding as needed */ box-sizing: border-box; /* Ensure padding doesn't affect width */ white-space: break-spaces; } -.item-lister:last-child { - margin-bottom: 50px; -} .fullscreen { position: fixed; /* Keep the container fixed */ top: 0; /* Adjust the top position as needed */ @@ -30,6 +28,7 @@ height: calc(49vw - 20px); } + .title-container { display: flex; align-items: center; diff --git a/src/components/ItemTypeLister.js b/src/components/ItemTypeLister.js index b81e02e..0544267 100644 --- a/src/components/ItemTypeLister.js +++ b/src/components/ItemTypeLister.js @@ -2,7 +2,7 @@ import React, { useState, useRef, useEffect } from "react"; import smoothScroll from "smooth-scroll-into-view-if-needed"; import "./ItemTypeLister.css"; import ItemType from "./ItemType"; -import { createItemType } from "../helpers/itemHelper.js"; +import { createItem, createItemType } from "../helpers/itemHelper.js"; import { getImageUrl } from "../helpers/itemHelper"; import ItemLister from "./ItemLister"; const ItemTypeLister = ({ @@ -98,18 +98,16 @@ const ItemTypeLister = ({ > {isEditMode && !isAddingNewItem && - user && - user.roleId === 1 && - user.userId === shopOwnerId && ( + user && ( + user.userId == shopOwnerId || user.cafeId == shopId) && ( )} - {user && - user.roleId === 1 && - user.userId === shopOwnerId && + {user &&( + user.userId == shopOwnerId || user.cafeId == shopId) && isAddingNewItem && ( <> createItem(shopId, name, price, selectedImage,itemTypeId)} beingEditedType={beingEditedType} setBeingEditedType={setBeingEditedType} alwaysEdit={true} @@ -137,8 +135,8 @@ const ItemTypeLister = ({ {itemTypes && itemTypes.map( (itemType) => - ((user && user.roleId === 1 && user.userId === shopOwnerId) || - itemType.itemList.length > 0) && ( + ( + itemType.itemList.length > 0 || (user && (user.userId == shopOwnerId || user.cafeId == shopId))) && ( { {modalContent === "req_notification" && } {modalContent === "blocked_notification" && } + {modalContent === "create_clerk" && } {modalContent === "edit_tables" && } {modalContent === "new_transaction" && ( diff --git a/src/components/MusicPlayer.css b/src/components/MusicPlayer.css index d3d8211..fdec5c9 100644 --- a/src/components/MusicPlayer.css +++ b/src/components/MusicPlayer.css @@ -1,7 +1,7 @@ .music-player { position: relative; width: 95%; - margin: -10px auto 20px; + margin: 7px auto 20px; /* Added padding for top and bottom */ color: white; box-sizing: border-box; @@ -24,7 +24,7 @@ /* Center the background image */ filter: blur(1.5px); -webkit-filter: blur(1.5px); - border-radius: 23px 23px 0 0; + border-radius: 13px 13px 0 0; background-color: rgb(95 121 89); /* Rounded corners at the top */ text-align: right; @@ -32,6 +32,8 @@ } .current-name { + white-space: nowrap; + pointer-events: none; position: relative; z-index: 2; text-align: left; @@ -41,7 +43,29 @@ /* Text shadow for readability */ } +/* styles.css */ +@keyframes slideAnimation { + 0% { + margin-left: 100vw; + } + 10% { + margin-left: 30px; + } + 70% { + margin-left: 30px; + } + 100% { + margin-left: -100vw; + } +} + +.animated-text { + animation: slideAnimation 3s linear infinite; /* 4s duration for the animation */ + white-space: nowrap; /* Prevent text from wrapping */ +} + .current-artist { + pointer-events: none; position: relative; z-index: 2; text-align: left; @@ -52,6 +76,7 @@ } .progress-container { + pointer-events: none; position: relative; z-index: 2; text-align: left; @@ -104,9 +129,10 @@ position: relative; left: 0; right: 0; - background-color: rgb(29, 185, 84); + /* background-color: rgb(29, 185, 84); */ + background-color: #73a585; /* background-color: rgb(218 163 99); */ - border-radius: 0 0 23px 23px; + border-radius: 0 0 13px 13px; /* Rounded corners at the bottom */ cursor: pointer; text-align: center; @@ -134,7 +160,9 @@ display: flex; align-items: center; padding: 10px; - background-color: rgb(29, 185, 84); + /* background-color: rgb(29, 185, 84); */ + + background-color: #73a585; } .search-box input[type="text"] { diff --git a/src/components/MusicPlayer.js b/src/components/MusicPlayer.js index 59f57a7..01cf6fa 100644 --- a/src/components/MusicPlayer.js +++ b/src/components/MusicPlayer.js @@ -6,6 +6,7 @@ import MusicComponent from "./MusicComponent"; export function MusicPlayer({ socket, shopId, user, isSpotifyNeedLogin }) { const [currentTime, setCurrentTime] = useState(0); const [trackLength, setTrackLength] = useState(0); + const [viewing, setViewing] = useState(false); // State for expansion const [expanded, setExpanded] = useState(false); // State for expansion const [songName, setSongName] = useState(""); @@ -251,6 +252,9 @@ export function MusicPlayer({ socket, shopId, user, isSpotifyNeedLogin }) { return `${minutes}:${formattedSeconds}`; }; + const toggleView = () => { + setViewing(!viewing); + }; const toggleExpand = () => { setExpanded(!expanded); }; @@ -263,9 +267,47 @@ export function MusicPlayer({ socket, shopId, user, isSpotifyNeedLogin }) { } }, [expanded]); + + const [text, setText] = useState("Awaiting the next hit"); + const textIndex = useRef(0); + const [messages, setMessages] = useState(["Awaiting the next hit", "Click to request your fav song"]); + + + useEffect(() => { + // Update the messages based on currentSong + const newMessages = [ + currentSong != null && currentSong.item != undefined + ? `${currentSong.item.artists[0].name} - ${currentSong.item.name}` + : "Awaiting the next hit", + "Click to request your fav song" + ]; + + setMessages(newMessages); + setText(newMessages[0]); // Update the text state to the first message + + const element = document.querySelector('.animated-text'); + + // Check if the element exists before adding the event listener + if (element) { + const handleAnimationIteration = () => { + // Toggle between the two text values based on the current index + textIndex.current = (textIndex.current + 1) % messages.length; + setText(messages[textIndex.current]); + }; + + element.addEventListener('animationiteration', handleAnimationIteration); + + return () => { + element.removeEventListener('animationiteration', handleAnimationIteration); + }; + } + }, [currentSong]); // Run effect when currentSong changes + + return ( -
+
@@ -286,44 +328,50 @@ export function MusicPlayer({ socket, shopId, user, isSpotifyNeedLogin }) { ))}
-
-
+
+
{currentSong.item && currentSong.item.name - ? currentSong.item.name - : "Awaiting the next hit"} + ? (viewing? currentSong.item.name:text) + : + viewing? messages[0]:text}
-
- {currentSong.item && - currentSong.item.album && - currentSong.item.album.images[0] && - currentSong.item.artists[0].name - ? currentSong.item.artists[0].name - : "Drop your hits below"} -
-
-
- {formatTime(currentTime)} + {viewing && <> +
+ {currentSong.item && + currentSong.item.album && + currentSong.item.album.images[0] && + currentSong.item.artists[0].name + ? currentSong.item.artists[0].name + : "Drop your hits below"}
- -
- {formatTime(trackLength)} -
-
+
+
+ {formatTime(currentTime)} +
+ +
+ {formatTime(trackLength)} +
+
+ }
+ {viewing && + <>
{expanded - ? "collapse" + ? "︿" : currentSong.item && - currentSong.item.album && - currentSong.item.album.images[0] && - currentSong.item.artists[0] + currentSong.item.album && + currentSong.item.album.images[0] && + currentSong.item.artists[0] ? "expand" : "request your song"}
-
+
+}
); } diff --git a/src/components/TableList.js b/src/components/TableList.js index ffabe4d..1dc1b63 100644 --- a/src/components/TableList.js +++ b/src/components/TableList.js @@ -1,6 +1,7 @@ -import React, { useState, useEffect } from "react"; +import React, {useState} from "react"; import QRCodeWithBackground from "./QR"; // Adjust path as needed -const TableList = ({ shop, tables, onSelectTable, selectedTable }) => { + +const TableList = ({ shop, tables, onSelectTable, selectedTable, handleSetTableNo, handleAddTable }) => { const [initialPos, setInitialPos] = useState({ left: shop.xposition, top: shop.yposition, @@ -21,16 +22,16 @@ const TableList = ({ shop, tables, onSelectTable, selectedTable }) => { } }; - const handleBackgroundUrlChange = (newUrl) => { - setBgImageUrl(newUrl); - }; - const handleQrSave = (qrPosition, qrSize, bgImage) => { setInitialPos(qrPosition); setInitialSize(qrSize); setBgImageUrl(bgImage); }; + const handleCreateTable = () => { + handleAddTable(); + }; + return (
{ /> )} + {/* Add new table input */} +
  • + + +
  • {tables && tables .filter((table) => table.tableNo !== 0) diff --git a/src/components/TablesPage.js b/src/components/TablesPage.js index 995bdcf..30fdd7a 100644 --- a/src/components/TablesPage.js +++ b/src/components/TablesPage.js @@ -130,10 +130,10 @@ const TablesPage = ({ shop }) => { }; const handleSave = async () => { - if (newTable) { + // if (newTable) { try { const createdTable = await createTable(shop.cafeId, { - ...newTable, + // ...newTable, tableNo, }); setTables([...tables, createdTable]); @@ -143,28 +143,28 @@ const TablesPage = ({ shop }) => { } catch (error) { console.error("Error creating table:", error); } - } else if (selectedTable) { - try { - const updatedTable = await updateTable(shop.cafeId, { - ...selectedTable, - tableNo, - }); - setTables( - tables.map((table) => - table.tableId === updatedTable.tableId ? updatedTable : table - ) - ); - setOriginalTables( - tables.map((table) => - table.tableId === updatedTable.tableId ? updatedTable : table - ) - ); - setSelectedTable(null); - setTableNo(""); // Reset table name - } catch (error) { - console.error("Error updating table:", error); - } - } + // } else if (selectedTable) { + // try { + // const updatedTable = await updateTable(shop.cafeId, { + // ...selectedTable, + // tableNo, + // }); + // setTables( + // tables.map((table) => + // table.tableId === updatedTable.tableId ? updatedTable : table + // ) + // ); + // setOriginalTables( + // tables.map((table) => + // table.tableId === updatedTable.tableId ? updatedTable : table + // ) + // ); + // setSelectedTable(null); + // setTableNo(""); // Reset table name + // } catch (error) { + // console.error("Error updating table:", error); + // } + // } }; const handleSetTableNo = (event) => { @@ -207,6 +207,8 @@ const TablesPage = ({ shop }) => { tables={tables} onSelectTable={handleSelect} selectedTable={selectedTable} + handleSetTableNo={handleSetTableNo} + handleAddTable={handleSave} />
    ); diff --git a/src/config.js b/src/config.js index b717ef9..03bd13a 100644 --- a/src/config.js +++ b/src/config.js @@ -1,5 +1,5 @@ // src/config.js -const API_BASE_URL = "https://wxf6vz-5000.csb.app"; // Replace with your actual backend URL +const API_BASE_URL = 'https://9qc65z-5000.csb.app'; export default API_BASE_URL; diff --git a/src/helpers/itemHelper.js b/src/helpers/itemHelper.js index 16f8342..b95dad9 100644 --- a/src/helpers/itemHelper.js +++ b/src/helpers/itemHelper.js @@ -165,12 +165,19 @@ export async function updateItemAvalilability(itemId, isAvailable) { throw error; } } - -export async function createItemType(shopId, name, selectedImage) { +export async function createItemType(shopId, name, selectedImage, previewUrl) { try { const formData = new FormData(); formData.append("name", name); - formData.append("image", selectedImage); + + // Check if selectedImage is provided + if (selectedImage) { + formData.append("image", selectedImage); + } else if (previewUrl) { + // Remove the API_BASE_URL and any leading slashes from previewUrl + const processedPreviewUrl = previewUrl.replace(API_BASE_URL, "").replace(/^\/+/, ""); + formData.append("sampleImage", processedPreviewUrl); + } const response = await fetch(`${API_BASE_URL}/item/createType/${shopId}`, { method: "POST", @@ -192,6 +199,7 @@ export async function createItemType(shopId, name, selectedImage) { throw error; } } + export async function updateItemType( shopId, itemTypeId, diff --git a/src/helpers/userHelpers.js b/src/helpers/userHelpers.js index 0430f37..a420179 100644 --- a/src/helpers/userHelpers.js +++ b/src/helpers/userHelpers.js @@ -193,12 +193,12 @@ export const getAllCafeOwner = async (formData) => { } }; -export const createCafeOwner = async (shopId, email, username, password) => { +export const createCafeOwner = async (email, username, password) => { const token = getLocalStorage("auth"); if (token) { try { const response = await fetch( - API_BASE_URL + "/user/create-clerk/" + shopId, + API_BASE_URL + "/user/create-admin/" , { method: "POST", headers: { @@ -276,6 +276,7 @@ export const createClerks = async (shopId, email, username, password) => { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); + console.log(data) return data; } catch (error) { console.error("Error getting clerk:", error); diff --git a/src/pages/CafePage.js b/src/pages/CafePage.js index fd8db40..9a9cc20 100644 --- a/src/pages/CafePage.js +++ b/src/pages/CafePage.js @@ -20,7 +20,7 @@ import Header from "../components/Header"; import { ThreeDots } from "react-loader-spinner"; -import { updateLocalStorage } from "../helpers/localStorageHelpers"; +import { updateLocalStorage, removeLocalStorage } from "../helpers/localStorageHelpers"; import { unsubscribeUser } from "../helpers/subscribeHelpers.js"; import WelcomePage from "./WelcomePage.js"; @@ -108,7 +108,7 @@ function CafePage({ }; const handleLogout = () => { - updateLocalStorage("auth", ""); + removeLocalStorage("auth"); unsubscribeUser(); navigate(0); }; @@ -172,9 +172,12 @@ function CafePage({ setIsEditMode={(e) => setIsEditMode(e)} isEditMode={isEditMode} /> -
    - -
    + -
    - {filterId === 0 ? ( - <> -

    Music Req.

    - - - ) : ( -
    - )} -
    + {/*
    */} {shopItems .filter( (itemType) => diff --git a/src/pages/Cart.js b/src/pages/Cart.js index e2428f9..d2e93bd 100644 --- a/src/pages/Cart.js +++ b/src/pages/Cart.js @@ -163,9 +163,10 @@ export default function Invoice({ table, sendParam, deviceType, socket }) { /> ))} +{table.tableNo != null && (
    - Order Type: - Pickup {table == null && } - - {/* tableId harus di check terlebih dahulu untuk mendapatkan tableNo */} - + */}
    + )} {orderType === "serve" && table.length < 1 && (
    Serve to: diff --git a/src/pages/CreateClerk.js b/src/pages/CreateClerk.js new file mode 100644 index 0000000..a7820c0 --- /dev/null +++ b/src/pages/CreateClerk.js @@ -0,0 +1,111 @@ +import React, { useState } from 'react'; +import { createClerks } from '../helpers/userHelpers'; // Adjust the import path as needed + +const CreateClerk = ({ shopId }) => { + const [email, setEmail] = useState(''); + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const [loading, setLoading] = useState(false); + const [message, setMessage] = useState(''); + + const handleSubmit = async (event) => { + event.preventDefault(); + setLoading(true); + setMessage(''); + + // Basic validation + if (!email || !username || !password) { + setMessage('All fields are required'); + setLoading(false); + return; + } + + try { + const create = await createClerks(shopId, email, username, password); + + if(create) setMessage('Clerk created successfully'); + else setMessage('failed') + } catch (error) { + setMessage('Error creating clerk'); + } finally { + setLoading(false); + } + }; + + return ( +
    +

    Create Clerk

    +
    + setEmail(e.target.value)} + style={styles.input} + /> + setUsername(e.target.value)} + style={styles.input} + /> + setPassword(e.target.value)} + style={styles.input} + /> + + {message &&

    {message}

    } +
    +
    + ); +}; + +// Basic styling to make it mobile-friendly +const styles = { + container: { + width: '100%', + maxWidth: '400px', + margin: '0 auto', + padding: '20px', + boxSizing: 'border-box', + }, + header: { + textAlign: 'center', + marginBottom: '20px', + }, + form: { + display: 'flex', + flexDirection: 'column', + gap: '15px', + }, + input: { + padding: '10px', + fontSize: '16px', + borderRadius: '5px', + border: '1px solid #ccc', + width: '100%', + boxSizing: 'border-box', + }, + button: { + padding: '10px', + fontSize: '16px', + borderRadius: '5px', + border: 'none', + backgroundColor: '#28a745', + color: 'white', + cursor: 'pointer', + }, + message: { + textAlign: 'center', + color: 'red', + marginTop: '10px', + }, +}; + +export default CreateClerk; diff --git a/src/pages/Dashboard.js b/src/pages/Dashboard.js index 7a78a7b..02cd652 100644 --- a/src/pages/Dashboard.js +++ b/src/pages/Dashboard.js @@ -3,7 +3,7 @@ import styles from "./Dashboard.module.css"; // Import module CSS for styling import Header from "../components/Header"; import { useNavigate } from "react-router-dom"; import AccountUpdateModal from "../components/AccountUpdateModal"; -import { updateLocalStorage } from "../helpers/localStorageHelpers"; +import { removeLocalStorage } from "../helpers/localStorageHelpers"; import { getAllCafeOwner, createCafeOwner } from "../helpers/userHelpers"; import { getOwnedCafes, createCafe, updateCafe } from "../helpers/cafeHelpers"; @@ -50,7 +50,7 @@ const Dashboard = ({ user, setModal }) => { }; const handleLogout = () => { - updateLocalStorage("auth", ""); + removeLocalStorage("auth"); unsubscribeUser(); navigate(0); }; @@ -58,9 +58,9 @@ const Dashboard = ({ user, setModal }) => { const handleCreateItem = () => { if (user.roleId < 1) { // Create admin functionality - createCafeOwner(newItem.name) + createCafeOwner(newItem.email, newItem.username, newItem.password) .then(() => { - setItems([...items, { name: newItem.name }]); + setItems([...items, { name: newItem.username }]); setIsCreating(false); setNewItem({ name: "", type: "" }); }) @@ -84,7 +84,7 @@ const Dashboard = ({ user, setModal }) => { return ( <>
    setIsModalOpen(true)} isLogout={handleLogout} user={user} @@ -132,12 +132,31 @@ const Dashboard = ({ user, setModal }) => { {isCreating && (

    Create New {user.roleId < 1 ? "Admin" : "Cafe"}

    + {user.roleId < 1 ?<> + setNewItem({ ...newItem, email: e.target.value })} + placeholder="email" + /> + setNewItem({ ...newItem, username: e.target.value })} + placeholder="username" + /> + setNewItem({ ...newItem, password: e.target.value })} + placeholder="Password" + /> : setNewItem({ ...newItem, name: e.target.value })} placeholder="Name" - /> + />}