This commit is contained in:
Vassshhh
2025-08-27 02:53:44 +07:00
parent e039fc8acc
commit ba896106d4
12 changed files with 292 additions and 283 deletions

View File

@@ -23,41 +23,50 @@ const DailyCharts = ({ incomeGraph, transactionGraph, materialGraph, colors, typ
"21-24", "21-24",
]; ];
console.log(dayData) console.log(dayData)
const sumSold = (transactions) =>
Array.isArray(transactions) ? transactions.reduce((acc, t) => acc + t.sold, 0) : transactions.transaction || 0;
const sumTotal = (transactions) =>
Array.isArray(transactions) ? transactions.reduce((acc, t) => acc + t.totalPrice, 0) : transactions.income || 0;
const sumOutcome = (transactions) =>
Array.isArray(transactions) ? transactions.reduce((acc, t) => acc + t.materialOutcome || t.price, 0) : transactions.outcome || 0;
let seriesData = [] let seriesData = []
if(graphFilter == 'transactions'){ if (graphFilter == 'transactions') {
seriesData = [
dayData.hour0To3Transactions.reduce((acc, t) => acc + t.sold, 0),
dayData.hour3To6Transactions.reduce((acc, t) => acc + t.sold, 0),
dayData.hour6To9Transactions.reduce((acc, t) => acc + t.sold, 0),
dayData.hour9To12Transactions.reduce((acc, t) => acc + t.sold, 0),
dayData.hour12To15Transactions.reduce((acc, t) => acc + t.sold, 0),
dayData.hour15To18Transactions.reduce((acc, t) => acc + t.sold, 0),
dayData.hour18To21Transactions.reduce((acc, t) => acc + t.sold, 0),
dayData.hour21To24Transactions.reduce((acc, t) => acc + t.sold, 0),
];
}
else if(graphFilter == 'income'){
seriesData = [ seriesData = [
dayData.hour0To3Transactions.reduce((acc, t) => acc + t.totalPrice, 0), sumSold(dayData?.hour0To3Transactions),
dayData.hour3To6Transactions.reduce((acc, t) => acc + t.totalPrice, 0), sumSold(dayData?.hour3To6Transactions),
dayData.hour6To9Transactions.reduce((acc, t) => acc + t.totalPrice, 0), sumSold(dayData?.hour6To9Transactions),
dayData.hour9To12Transactions.reduce((acc, t) => acc + t.totalPrice, 0), sumSold(dayData?.hour9To12Transactions),
dayData.hour12To15Transactions.reduce((acc, t) => acc + t.totalPrice, 0), sumSold(dayData?.hour12To15Transactions),
dayData.hour15To18Transactions.reduce((acc, t) => acc + t.totalPrice, 0), sumSold(dayData?.hour15To18Transactions),
dayData.hour18To21Transactions.reduce((acc, t) => acc + t.totalPrice, 0), sumSold(dayData?.hour18To21Transactions),
dayData.hour21To24Transactions.reduce((acc, t) => acc + t.totalPrice, 0), sumSold(dayData?.hour21To24Transactions),
]; ];
} }
else if(graphFilter == 'outcome'){ else if (graphFilter == 'income') {
seriesData = [ seriesData = [
dayData.hour3To6MaterialIds.reduce((acc, t) => acc + t.materialOutcome, 0), sumTotal(dayData?.hour0To3Transactions),
dayData.hour6To9MaterialIds.reduce((acc, t) => acc + t.materialOutcome, 0), sumTotal(dayData?.hour3To6Transactions),
dayData.hour0To3MaterialIds.reduce((acc, t) => acc + t.materialOutcome, 0), sumTotal(dayData?.hour6To9Transactions),
dayData.hour9To12MaterialIds.reduce((acc, t) => acc + t.materialOutcome, 0), sumTotal(dayData?.hour9To12Transactions),
dayData.hour12To15MaterialIds.reduce((acc, t) => acc + t.materialOutcome, 0), sumTotal(dayData?.hour12To15Transactions),
dayData.hour15To18MaterialIds.reduce((acc, t) => acc + t.materialOutcome, 0), sumTotal(dayData?.hour15To18Transactions),
dayData.hour18To21MaterialIds.reduce((acc, t) => acc + t.materialOutcome, 0), sumTotal(dayData?.hour18To21Transactions),
dayData.hour21To24MaterialIds.reduce((acc, t) => acc + t.materialOutcome, 0), sumTotal(dayData?.hour21To24Transactions),
];
}
else if (graphFilter == 'outcome') {
seriesData = [
sumOutcome(dayData?.hour0To3MaterialIds),
sumOutcome(dayData?.hour3To6MaterialIds),
sumOutcome(dayData?.hour6To9MaterialIds),
sumOutcome(dayData?.hour9To12MaterialIds),
sumOutcome(dayData?.hour12To15MaterialIds),
sumOutcome(dayData?.hour15To18MaterialIds),
sumOutcome(dayData?.hour18To21MaterialIds),
sumOutcome(dayData?.hour21To24MaterialIds),
]; ];
} }
return { return {
@@ -85,20 +94,20 @@ const DailyCharts = ({ incomeGraph, transactionGraph, materialGraph, colors, typ
0 0
); );
const formatDate = (dateString) => { const formatDate = (dateString) => {
const date = new Date(dateString); // Parse the date string const date = new Date(dateString); // Parse the date string
// Create an array of month names (use the same names you had earlier) // Create an array of month names (use the same names you had earlier)
const monthNames = [ const monthNames = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
]; ];
// Get the month and day // Get the month and day
const month = monthNames[date.getMonth()]; // Month is 0-indexed (January = 0) const month = monthNames[date.getMonth()]; // Month is 0-indexed (January = 0)
const day = date.getDate(); // Get the day of the month const day = date.getDate(); // Get the day of the month
return { month, day }; // Return the result return { month, day }; // Return the result
}; };
return ( return (
<div className={`${styles.chartItemContainer} ${selectedIndex !== -1 ? styles.expanded : ''}`}> <div className={`${styles.chartItemContainer} ${selectedIndex !== -1 ? styles.expanded : ''}`}>
@@ -119,22 +128,22 @@ const DailyCharts = ({ incomeGraph, transactionGraph, materialGraph, colors, typ
key={indexx} key={indexx}
className={`${styles.dateSelector} ${index === indexx ? styles.dateSelectorActive : styles.dateSelectorInactive className={`${styles.dateSelector} ${index === indexx ? styles.dateSelectorActive : styles.dateSelectorInactive
}`} }`}
style={{position: 'relative' }} style={{ position: 'relative' }}
onClick={() => onClick={() =>
type == 'yesterday' && selectedIndex == -1 || type != 'yesterday' && selectedIndex !== index ? setSelectedIndex(index) : setSelectedIndex(-1) type == 'yesterday' && selectedIndex == -1 || type != 'yesterday' && selectedIndex !== index ? setSelectedIndex(index) : setSelectedIndex(-1)
} }
// style={{ backgroundColor: index === indexx ? colors[index % colors.length] : 'transparent' }} // style={{ backgroundColor: index === indexx ? colors[index % colors.length] : 'transparent' }}
> >
<div style={{position: 'absolute', bottom: 0, left: '10%', right: '10%', borderBottom: index == indexx ? `2px solid ${colors[index % colors.length]}` : 'none'}}></div> <div style={{ position: 'absolute', bottom: 0, left: '10%', right: '10%', borderBottom: index == indexx ? `2px solid ${colors[index % colors.length]}` : 'none' }}></div>
<div <div
style={{ color: index === indexx ? 'black' : 'transparent' }}> style={{ color: index === indexx ? 'black' : 'transparent' }}>
{indexx !== chartData.length - 1 ? ( {indexx !== chartData.length - 1 ? (
<> <>
{day}{" "} {day}{" "}
{(indexx === 0 || (formatDate(chartData[indexx - 1].date).month !== month && type != 'weekly')) && month} {(indexx === 0 || (formatDate(chartData[indexx - 1].date).month !== month && type != 'weekly')) && month}
</> </>
) : ( ) : (
'Kemarin' 'Hari ini'
)} )}
</div> </div>

View File

@@ -368,7 +368,7 @@ const Header = ({
{shopName} {shopName}
</Child> </Child>
<Child> <Child>
Mode pengembangan &nbsp; Mode Edit &nbsp;
<Switch <Switch
borderRadius={0} borderRadius={0}
checked={isEditMode} checked={isEditMode}
@@ -377,7 +377,7 @@ const Header = ({
</Child> </Child>
<Child onClick={() => setModal("reports")}>Lihat laporan</Child> <Child onClick={() => setModal("reports")}>Lihat laporan</Child>
<Child onClick={() => setModal("add_material")}> <Child onClick={() => setModal("add_material")}>
Kelola bahan baku Kelola stok
</Child> </Child>
<Child hasChildren> <Child hasChildren>
@@ -423,7 +423,7 @@ const Header = ({
<Child>{shopName}</Child> <Child>{shopName}</Child>
<Child> <Child>
Mode pengembangan&nbsp; Mode Edit&nbsp;
<Switch <Switch
borderRadius={0} borderRadius={0}
checked={isEditMode} checked={isEditMode}
@@ -431,7 +431,7 @@ const Header = ({
/> />
</Child> </Child>
<Child onClick={() => setModal("add_material")}> <Child onClick={() => setModal("add_material")}>
Kelola bahan baku Kelola stok
</Child> </Child>
<Child hasChildren> <Child hasChildren>

View File

@@ -200,7 +200,7 @@ const Item = ({
lineHeight: '1rem', lineHeight: '1rem',
justifyContent: 'center' justifyContent: 'center'
}}> }}>
Promo {(((initialPrice - promoPrice) / initialPrice) * 100).toFixed(0)}% Promo
</div> </div>
<div style={{ display: 'flex' }}> <div style={{ display: 'flex' }}>

View File

@@ -1,6 +1,7 @@
import React, { useState, useEffect, useRef } from "react"; import React, { useState, useEffect, useRef } from "react";
import styles from "./Modal.module.css"; import styles from "./Modal.module.css";
import { getImageUrl } from "../helpers/itemHelper.js"; import { ThreeDots } from "react-loader-spinner";
const ItemConfig = ({ const ItemConfig = ({
name: initialName, name: initialName,
@@ -24,11 +25,14 @@ const ItemConfig = ({
const fileInputRef = useRef(null); const fileInputRef = useRef(null);
const textareaRef = useRef(null); const textareaRef = useRef(null);
const [isSaving, setIsSaving] = useState(false);
useEffect(() => { useEffect(() => {
// Prevent scrolling when modal is open // Prevent scrolling when modal is open
document.body.style.overflow = "hidden"; document.body.style.overflow = "hidden";
if(selectedImage){ if (selectedImage) {
const reader = new FileReader(); const reader = new FileReader();
reader.onloadend = () => { reader.onloadend = () => {
setPreviewUrl(reader.result); setPreviewUrl(reader.result);
@@ -79,18 +83,27 @@ const ItemConfig = ({
return () => textarea.removeEventListener("input", handleResize); return () => textarea.removeEventListener("input", handleResize);
} }
}, [textareaRef.current]); }, [textareaRef.current]);
const handleCreate = async () => {
setIsSaving(true);
try {
await handleCreateItem(itemName, itemPrice, selectedImage, previewUrl, itemDescription, itemPromoPrice);
document.body.style.overflow = "auto";
} finally {
setIsSaving(false);
}
};
const handleCreate = () => { const handleUpdate = async () => {
console.log(itemPromoPrice) setIsSaving(true);
handleCreateItem(itemName, itemPrice, selectedImage, previewUrl, itemDescription, itemPromoPrice); try {
document.body.style.overflow = "auto"; await handleUpdateItem(itemName, itemPrice, selectedImage, itemDescription, itemPromoPrice);
}; document.body.style.overflow = "auto";
const handleUpdate = () => { } finally {
console.log(itemName, itemPrice, selectedImage, itemDescription, itemPromoPrice) setIsSaving(false);
handleUpdateItem(itemName, itemPrice, selectedImage, itemDescription, itemPromoPrice); }
document.body.style.overflow = "auto";
}; };
return ( return (
<div onClick={handleOverlayClick} style={{ position: 'fixed', width: '100vw', height: '100vh', left: 0, bottom: 0, display: 'flex', flexDirection: 'column-reverse', zIndex: 301, backgroundColor: '#00000061' }}> <div onClick={handleOverlayClick} style={{ position: 'fixed', width: '100vw', height: '100vh', left: 0, bottom: 0, display: 'flex', flexDirection: 'column-reverse', zIndex: 301, backgroundColor: '#00000061' }}>
<div onClick={handleContentClick} style={{ display: 'flex', flexDirection: 'column', padding: '15px', backgroundColor: 'white', borderRadius: '20px 20px 0 0', overflowY: 'auto' }}> <div onClick={handleContentClick} style={{ display: 'flex', flexDirection: 'column', padding: '15px', backgroundColor: 'white', borderRadius: '20px 20px 0 0', overflowY: 'auto' }}>
@@ -131,7 +144,7 @@ const ItemConfig = ({
transition: 'all 0.3s ease', transition: 'all 0.3s ease',
boxSizing: 'border-box', // Make sure the padding doesn't cause overflow boxSizing: 'border-box', // Make sure the padding doesn't cause overflow
}} }}
onChange={(e)=>setItemName(e.target.value)} onChange={(e) => setItemName(e.target.value)}
onFocus={(e) => e.target.style.borderColor = '#60d37e'} onFocus={(e) => e.target.style.borderColor = '#60d37e'}
onBlur={(e) => e.target.style.borderColor = '#ccc'} onBlur={(e) => e.target.style.borderColor = '#ccc'}
/> />
@@ -153,7 +166,7 @@ const ItemConfig = ({
transition: 'all 0.3s ease', transition: 'all 0.3s ease',
boxSizing: 'border-box', boxSizing: 'border-box',
}} }}
onChange={(e)=>setItemPrice(e.target.value)} onChange={(e) => setItemPrice(e.target.value)}
onFocus={(e) => e.target.style.borderColor = '#60d37e'} onFocus={(e) => e.target.style.borderColor = '#60d37e'}
onBlur={(e) => e.target.style.borderColor = '#ccc'} onBlur={(e) => e.target.style.borderColor = '#ccc'}
/> />
@@ -174,7 +187,7 @@ const ItemConfig = ({
transition: 'all 0.3s ease', transition: 'all 0.3s ease',
boxSizing: 'border-box', boxSizing: 'border-box',
}} }}
onChange={(e)=>setItemPromoPrice(e.target.value)} onChange={(e) => setItemPromoPrice(e.target.value)}
onFocus={(e) => e.target.style.borderColor = '#60d37e'} onFocus={(e) => e.target.style.borderColor = '#60d37e'}
onBlur={(e) => e.target.style.borderColor = '#ccc'} onBlur={(e) => e.target.style.borderColor = '#ccc'}
/> />
@@ -200,17 +213,40 @@ const ItemConfig = ({
}} }}
placeholder="Tambah deskripsi..." placeholder="Tambah deskripsi..."
value={itemDescription} value={itemDescription}
onChange={(e)=>setItemDescription(e.target.value)} onChange={(e) => setItemDescription(e.target.value)}
onFocus={(e) => e.target.style.borderColor = '#60d37e'} onFocus={(e) => e.target.style.borderColor = '#60d37e'}
onBlur={(e) => e.target.style.borderColor = '#ccc'} onBlur={(e) => e.target.style.borderColor = '#ccc'}
/> />
</div> </div>
<div
onClick={() => {
if (!isSaving) {
isBeingEdit ? handleUpdate() : handleCreate();
}
}}
style={{
width: '100%',
height: '40px',
alignContent: 'center',
textAlign: 'center',
borderRadius: '10px',
border: '1px solid #60d37e',
color: isSaving ? '#aaa' : '#60d37e',
backgroundColor: 'white',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
cursor: isSaving ? 'not-allowed' : 'pointer'
}}
>
{isSaving ? (
<div style={{ width: '100%', height: '35px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}> <ThreeDots height={20} width={20} />
<div onClick={() => {isBeingEdit ? handleUpdate() : handleCreate()} } style={{ width: '100%', height: '40px', alignContent: 'center', textAlign: 'center', borderRadius: '10px', border: '1px solid #60d37e', color: '#60d37e', backgroundColor: 'white', display: 'flex', justifyContent: 'center', alignItems: 'center' }}> ) : (
{isBeingEdit? 'Simpan' : 'Buat Item'} isBeingEdit ? 'Simpan' : 'Buat Item'
</div> )}
</div> </div>
</div> </div>
</div> </div>
); );

View File

@@ -713,15 +713,6 @@ const ItemLister = ({
} }
imageUrl={getImageUrl("uploads/assets/addnew.png")} imageUrl={getImageUrl("uploads/assets/addnew.png")}
/> />
{/* {typeImage != null && !previewUrl.includes(typeImage) && (
<ItemType
rectangular={true}
onClick={(previewUrl, selectedImage) =>
handleImageChange(previewUrl, selectedImage)
}
imageUrl={getImageUrl(typeImage)}
/>
)} */}
<ItemType <ItemType
rectangular={true} rectangular={true}
@@ -857,7 +848,6 @@ const ItemLister = ({
); );
})} })}
</div> </div>
<button onClick={() => setIsFirstStep(false)} style={{ width: '100%', height: '40px', borderRadius: '20px' }}>selanjutnya</button>
</> </>
)} )}
{(isEdit && !isFirstStep || !isEdit) && {(isEdit && !isFirstStep || !isEdit) &&

View File

@@ -24,60 +24,8 @@
/* padding: 10px; */ /* padding: 10px; */
/* max-height: calc(3 * (25vw - 20px) + 20px); */ /* max-height: calc(3 * (25vw - 20px) + 20px); */
overflow-y: auto; overflow-y: auto;
height: calc(49vw - 20px);
} }
@media (min-height: 0px) {
.grid-container {
height: 27vh;
}
}
@media (min-height: 630px) {
.grid-container {
height: 27vh;
}
}
@media (min-height: 636px) {
.grid-container {
height: 29vh;
}
}
@media (min-height: 650px) {
.grid-container {
height: 34vh;
}
}
@media (min-height: 705px) {
.grid-container {
height: 37vh;
}
}
@media (min-height: 735px) {
.grid-container {
height: 38vh;
}
}
@media (min-height: 759px) {
.grid-container {
height: 40vh;
}
}
@media (min-height: 819px) {
.grid-container {
height: 44vh;
}
}
@media (min-height: 830px) {
.grid-container {
height: 47vh;
}
}
@media (min-height: 892px) {
.grid-container {
height: 49vh;
}
}
.title-container { .title-container {
display: flex; display: flex;

View File

@@ -36,3 +36,4 @@
.closeButton:hover { .closeButton:hover {
color: #f44336; /* Change color on hover for better UX */ color: #f44336; /* Change color on hover for better UX */
} }

View File

@@ -19,6 +19,8 @@ import { MusicPlayer } from "../components/MusicPlayer";
import ItemLister from "../components/ItemLister"; import ItemLister from "../components/ItemLister";
import Header from "../components/Header"; import Header from "../components/Header";
import Switch from "react-switch";
import { ThreeDots } from "react-loader-spinner"; import { ThreeDots } from "react-loader-spinner";
import { getLocalStorage, updateLocalStorage, removeLocalStorage } from "../helpers/localStorageHelpers"; import { getLocalStorage, updateLocalStorage, removeLocalStorage } from "../helpers/localStorageHelpers";
@@ -152,7 +154,7 @@ function CafePage({
socket.on("joined-room", (response) => { socket.on("joined-room", (response) => {
const { isSpotifyNeedLogin, isExceededDeadline } = response; const { isSpotifyNeedLogin, isExceededDeadline } = response;
setNeedSpotifyLogin(isSpotifyNeedLogin); setNeedSpotifyLogin(isSpotifyNeedLogin);
if (isExceededDeadline) setModal("message",{captMessage:'Kafe sedang tidak tersedia'}); if (isExceededDeadline) setModal("message", { captMessage: 'Kafe sedang tidak tersedia' });
setIsExceededDeadline(isExceededDeadline); setIsExceededDeadline(isExceededDeadline);
}); });
} }
@@ -222,133 +224,156 @@ function CafePage({
isFullscreen={true} isFullscreen={true}
/> />
) : ( */} ) : ( */}
<div className={`Cafe ${isExceededDeadline ? 'grayscale' : ''}`}> <div className={`Cafe ${isExceededDeadline ? 'grayscale' : ''}`}>
{API_BASE_URL != 'https://dev.api.kedaimaster.com' && API_BASE_URL != 'https://api.kedaimaster.com' && {API_BASE_URL != 'https://dev.api.kedaimaster.com' && API_BASE_URL != 'https://api.kedaimaster.com' &&
<div className="Watermark"></div> <div className="Watermark"></div>
} }
<div className="App-header"> <div className="App-header">
<Header <Header
HeaderText={"Menu"} HeaderText={"Menu"}
showProfile={true} showProfile={true}
setModal={setModal} setModal={setModal}
isLogout={handleLogout} isLogout={handleLogout}
shopId={shopId} shopId={shopId}
shopName={shopName} shopName={shopName}
shopImage={config.image} shopImage={config.image}
shopOwnerId={shopOwnerId} shopOwnerId={shopOwnerId}
shopClerks={shopClerks} shopClerks={shopClerks}
tableCode={table.tableCode} tableCode={table.tableCode}
user={user} user={user}
guestSides={guestSides} guestSides={guestSides}
guestSideOfClerk={guestSideOfClerk} guestSideOfClerk={guestSideOfClerk}
removeConnectedGuestSides={removeConnectedGuestSides} removeConnectedGuestSides={removeConnectedGuestSides}
setIsEditMode={(e) => setIsEditMode(e)} setIsEditMode={(e) => setIsEditMode(e)}
isEditMode={isEditMode} isEditMode={isEditMode}
/> />
<MusicPlayer <MusicPlayer
socket={socket} socket={socket}
shopId={shopId} shopId={shopId}
user={user} user={user}
shopOwnerId={shopOwnerId} shopOwnerId={shopOwnerId}
isSpotifyNeedLogin={isSpotifyNeedLogin} isSpotifyNeedLogin={isSpotifyNeedLogin}
queue={queue} queue={queue}
setModal={setModal} setModal={setModal}
/> />{
<div></div> user.username !== undefined &&
<ItemTypeLister (user.cafeId === shopId || user.user_id === shopOwnerId) &&
user={user} (user.roleId === 1 || user.roleId === 2) && (
shopOwnerId={shopOwnerId} <div style={{
shopId={shopId} backgroundColor: '#5c7c5c',
itemTypes={shopItems} padding: '7px 28px',
setShopItems={setShopItems} margin: '0 10px',
isEditMode={isEditMode} borderRadius: '15px',
onFilterChange={(e) => setFilterId(e)} display: 'flex',
filterId={filterId} alignItems: 'center',
beingEditedType={beingEditedType} justifyContent: 'space-between',
setBeingEditedType={setBeingEditedType} textShadow: '2px 2px 4px rgba(0, 0, 0, 0.7)',
/> fontSize: '16px'
{/* <div style={{ marginTop: "15px" }}></div> */} }}>
<div> Mode Edit&nbsp;
{shopItems <Switch
.filter( borderRadius={0}
(itemType) => checked={isEditMode}
filterId == 0 || itemType.itemTypeId === filterId onChange={() => setIsEditMode(!isEditMode)}
) />
.map((itemType, index) => ( </div>
<ItemLister )
index={index} }
indexTotal={shopItems.length}
shopId={shopId} <ItemTypeLister
shopOwnerId={shopOwnerId} user={user}
user={user} shopOwnerId={shopOwnerId}
key={itemType.itemTypeId} shopId={shopId}
itemTypeId={itemType.itemTypeId} itemTypes={shopItems}
typeName={itemType.name} setShopItems={setShopItems}
typeImage={itemType.image} isEditMode={isEditMode}
setShopItems={setShopItems} onFilterChange={(e) => setFilterId(e)}
itemList={itemType.itemList} filterId={filterId}
typeVisibility={itemType.visibility} beingEditedType={beingEditedType}
moveItemTypeUp={(e) => moveItemTypeHandler(e, 'up', index)} setBeingEditedType={setBeingEditedType}
moveItemTypeDown={(e) => moveItemTypeHandler(e, 'down', index)} />
isEditMode={isEditMode} {/* <div style={{ marginTop: "15px" }}></div> */}
beingEditedType={beingEditedType} <div>
setBeingEditedType={setBeingEditedType} {shopItems
raw={isEditMode || filterId == 0 ? false : true} .filter(
handleCreateItem={( (itemType) =>
itemTypeID, filterId == 0 || itemType.itemTypeId === filterId
name, )
price, .map((itemType, index) => (
selectedImage, <ItemLister
description, index={index}
promoPrice, indexTotal={shopItems.length}
) => shopId={shopId}
createItem( shopOwnerId={shopOwnerId}
shopId, user={user}
name, key={itemType.itemTypeId}
price, itemTypeId={itemType.itemTypeId}
selectedImage, typeName={itemType.name}
itemTypeID, typeImage={itemType.image}
description, setShopItems={setShopItems}
promoPrice, itemList={itemType.itemList}
) typeVisibility={itemType.visibility}
moveItemTypeUp={(e) => moveItemTypeHandler(e, 'up', index)}
moveItemTypeDown={(e) => moveItemTypeHandler(e, 'down', index)}
isEditMode={isEditMode}
beingEditedType={beingEditedType}
setBeingEditedType={setBeingEditedType}
raw={isEditMode || filterId == 0 ? false : true}
handleCreateItem={(
itemTypeID,
name,
price,
selectedImage,
description,
promoPrice,
) =>
createItem(
shopId,
name,
price,
selectedImage,
itemTypeID,
description,
promoPrice,
)
}
handleUpdateItem={(itemId, name, price, selectedImage, description, promoPrice) =>
updateItem(itemId, name, price, selectedImage, description, promoPrice)
}
/>
))}
{!isEditMode && (user.username || cartItemsLength > 0) &&
<div style={{ marginTop: '10px', height: '40px', position: 'sticky', bottom: '40px', display: 'flex', justifyContent: 'center', alignItems: 'center', textAlign: 'center' }}>
{(lastTransaction != null || cartItemsLength > 0) &&
<div onClick={goToCart} style={{ backgroundColor: '#73a585', width: user.username ? '55vw' : '70vw', height: '40px', borderRadius: '30px', display: 'flex', justifyContent: 'space-between', padding: '0 20px' }}>
<div style={{ display: 'flex', flexWrap: 'wrap', alignContent: 'center' }}>{lastTransaction != null && '+'}{cartItemsLength} item</div>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', width: '130px' }}>
{((lastTransaction == null || lastTransaction?.payment_type != 'paylater')) ?
<span style={{ whiteSpace: 'nowrap' }}>Rp{totalPrice}</span>
:
<span style={{ whiteSpace: 'nowrap' }}>Open bill</span>
} }
handleUpdateItem={(itemId, name, price, selectedImage, description, promoPrice) => <div style={{ display: 'flex', alignItems: 'center', marginLeft: '5px', width: '20px' }}>
updateItem(itemId, name, price, selectedImage, description, promoPrice) <svg viewBox="0 0 34 34" style={{ fill: 'white', marginTop: '4px' }}>
} <path d="M9.79175 24.75C8.09591 24.75 6.72383 26.1375 6.72383 27.8333C6.72383 29.5292 8.09591 30.9167 9.79175 30.9167C11.4876 30.9167 12.8751 29.5292 12.8751 27.8333C12.8751 26.1375 11.4876 24.75 9.79175 24.75ZM0.541748 0.0833435V3.16668H3.62508L9.17508 14.8679L7.09383 18.645C6.84717 19.0767 6.70842 19.5854 6.70842 20.125C6.70842 21.8208 8.09591 23.2083 9.79175 23.2083H28.2917V20.125H10.4392C10.2234 20.125 10.0538 19.9554 10.0538 19.7396L10.1001 19.5546L11.4876 17.0417H22.973C24.1292 17.0417 25.1467 16.4096 25.6709 15.4538L31.1901 5.44834C31.3134 5.23251 31.3751 4.97043 31.3751 4.70834C31.3751 3.86043 30.6813 3.16668 29.8334 3.16668H7.03217L5.583 0.0833435H0.541748ZM25.2084 24.75C23.5126 24.75 22.1405 26.1375 22.1405 27.8333C22.1405 29.5292 23.5126 30.9167 25.2084 30.9167C26.9042 30.9167 28.2917 29.5292 28.2917 27.8333C28.2917 26.1375 26.9042 24.75 25.2084 24.75Z"></path>
/> </svg>
))}
{!isEditMode && (user.username || cartItemsLength > 0) &&
<div style={{ marginTop: '10px', height: '40px', position: 'sticky', bottom: '40px', display: 'flex', justifyContent: 'center', alignItems: 'center', textAlign: 'center' }}>
{(lastTransaction != null || cartItemsLength > 0) &&
<div onClick={goToCart} style={{ backgroundColor: '#73a585', width: user.username ? '55vw' : '70vw', height: '40px', borderRadius: '30px', display: 'flex', justifyContent: 'space-between', padding: '0 20px' }}>
<div style={{ display: 'flex', flexWrap: 'wrap', alignContent: 'center' }}>{lastTransaction != null && '+'}{cartItemsLength} item</div>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', width: '130px' }}>
{((lastTransaction == null || lastTransaction?.payment_type != 'paylater')) ?
<span style={{ whiteSpace: 'nowrap' }}>Rp{totalPrice}</span>
:
<span style={{ whiteSpace: 'nowrap' }}>Open bill</span>
}
<div style={{ display: 'flex', alignItems: 'center', marginLeft: '5px', width: '20px' }}>
<svg viewBox="0 0 34 34" style={{ fill: 'white', marginTop: '4px' }}>
<path d="M9.79175 24.75C8.09591 24.75 6.72383 26.1375 6.72383 27.8333C6.72383 29.5292 8.09591 30.9167 9.79175 30.9167C11.4876 30.9167 12.8751 29.5292 12.8751 27.8333C12.8751 26.1375 11.4876 24.75 9.79175 24.75ZM0.541748 0.0833435V3.16668H3.62508L9.17508 14.8679L7.09383 18.645C6.84717 19.0767 6.70842 19.5854 6.70842 20.125C6.70842 21.8208 8.09591 23.2083 9.79175 23.2083H28.2917V20.125H10.4392C10.2234 20.125 10.0538 19.9554 10.0538 19.7396L10.1001 19.5546L11.4876 17.0417H22.973C24.1292 17.0417 25.1467 16.4096 25.6709 15.4538L31.1901 5.44834C31.3134 5.23251 31.3751 4.97043 31.3751 4.70834C31.3751 3.86043 30.6813 3.16668 29.8334 3.16668H7.03217L5.583 0.0833435H0.541748ZM25.2084 24.75C23.5126 24.75 22.1405 26.1375 22.1405 27.8333C22.1405 29.5292 23.5126 30.9167 25.2084 30.9167C26.9042 30.9167 28.2917 29.5292 28.2917 27.8333C28.2917 26.1375 26.9042 24.75 25.2084 24.75Z"></path>
</svg>
</div>
</div>
</div> </div>
} </div>
{user.username && </div>
<div onClick={goToTransactions} style={{ backgroundColor: '#73a585', width: '15vw', height: '40px', borderRadius: '30px', display: 'flex', justifyContent: 'center', marginLeft: lastTransaction != null || cartItemsLength > 0 ? '6px' : '0px' }}> }
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: '38px', marginRight: '5px' }}> {user.username &&
<div style={{ display: 'flex', alignItems: 'center', marginLeft: '5px', width: '20px' }}> <div onClick={goToTransactions} style={{ backgroundColor: '#73a585', width: '15vw', height: '40px', borderRadius: '30px', display: 'flex', justifyContent: 'center', marginLeft: lastTransaction != null || cartItemsLength > 0 ? '6px' : '0px' }}>
<svg viewBox="0 0 512 512"> <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: '38px', marginRight: '5px' }}>
<g <div style={{ display: 'flex', alignItems: 'center', marginLeft: '5px', width: '20px' }}>
transform="translate(0 460) scale(0.09 -0.09)" <svg viewBox="0 0 512 512">
style={{ fill: 'white', marginTop: '4px' }} <g
stroke="none" transform="translate(0 460) scale(0.09 -0.09)"
> style={{ fill: 'white', marginTop: '4px' }}
<path stroke="none"
d="M1639 5107 c-47 -13 -70 -28 -177 -109 -119 -90 -246 -102 -381 -34 >
<path
d="M1639 5107 c-47 -13 -70 -28 -177 -109 -119 -90 -246 -102 -381 -34
-53 27 -83 36 -121 36 -88 0 -167 -57 -190 -138 -8 -26 -10 -620 -8 -1982 l3 -53 27 -83 36 -121 36 -88 0 -167 -57 -190 -138 -8 -26 -10 -620 -8 -1982 l3
-1945 24 -38 c13 -21 42 -50 64 -65 l41 -27 1535 -5 1536 -5 58 -22 c158 -60 -1945 24 -38 c13 -21 42 -50 64 -65 l41 -27 1535 -5 1536 -5 58 -22 c158 -60
291 -205 322 -352 10 -45 74 -108 119 -117 78 -14 154 25 182 93 12 27 14 398 291 -205 322 -352 10 -45 74 -108 119 -117 78 -14 154 25 182 93 12 27 14 398
@@ -364,24 +389,24 @@ function CafePage({
20 6 475 9 1183 8 l1150 -2 38 -24z m4 -903 c62 -41 88 -90 88 -168 0 -78 -26 20 6 475 9 1183 8 l1150 -2 38 -24z m4 -903 c62 -41 88 -90 88 -168 0 -78 -26
-127 -88 -168 l-41 -27 -665 0 -666 0 -38 24 c-76 47 -111 140 -88 229 14 51 -127 -88 -168 l-41 -27 -665 0 -666 0 -38 24 c-76 47 -111 140 -88 229 14 51
76 117 123 131 20 6 291 9 684 8 l650 -2 41 -27z" 76 117 123 131 20 6 291 9 684 8 l650 -2 41 -27z"
/> />
<path <path
d="M592 489 c-47 -14 -109 -79 -123 -131 -33 -122 37 -265 159 -325 l57 d="M592 489 c-47 -14 -109 -79 -123 -131 -33 -122 37 -265 159 -325 l57
-28 1815 -2 c1736 -2 1813 -2 1765 15 -125 43 -186 126 -205 279 -12 89 -28 1815 -2 c1736 -2 1813 -2 1765 15 -125 43 -186 126 -205 279 -12 89
-39 138 -97 174 l-38 24 -1650 2 c-1023 1 -1662 -2 -1683 -8z" -39 138 -97 174 l-38 24 -1650 2 c-1023 1 -1662 -2 -1683 -8z"
/> />
</g> </g>
</svg> </svg>
</div>
</div>
</div> </div>
} </div>
</div> </div>
} }
</div> </div>
</div> }
<Watermark/>
</div> </div>
</div>
<Watermark />
</div>
{/* )} */} {/* )} */}
</> </>
); );

View File

@@ -28,7 +28,7 @@ const CreateClerk = ({ shopId }) => {
try { try {
const create = await createClerks(shopId || cafeIdParam, username, password); const create = await createClerks(shopId || cafeIdParam, username, password);
if (create) setMessage('Clerk created successfully'); if (create) {setMessage('Clerk created successfully');}
else setMessage('Failed to create clerk'); else setMessage('Failed to create clerk');
} catch (error) { } catch (error) {
setMessage('Error creating clerk'); setMessage('Error creating clerk');

View File

@@ -100,7 +100,7 @@ const LinktreePage = ({ user, setModal }) => {
const modal = "product"; const modal = "product";
const productId = 1; const productId = 1;
const authorizedUri = "http://localhost:3000?token="; const authorizedUri = "https://kedaimaster.com?token=";
const unauthorizedUri = `${baseUrl}?modal=${modal}&product_id=${productId}`; const unauthorizedUri = `${baseUrl}?modal=${modal}&product_id=${productId}`;
const url = const url =

View File

@@ -231,7 +231,7 @@ const SetPaymentQr = ({ cafeId }) => {
<></> <></>
) : ( ) : (
<> <>
<h3 className={styles.title}>Bahan baku</h3> <h3 className={styles.title}>Stok</h3>
<Carousel items={materials} onSelect={(e) => setSelectedMaterialIndex(e)} selectedIndex={selectedMaterialIndex} /> <Carousel items={materials} onSelect={(e) => setSelectedMaterialIndex(e)} selectedIndex={selectedMaterialIndex} />
{selectedMaterialIndex !== -1 ? ( {selectedMaterialIndex !== -1 ? (
<> <>

View File

@@ -323,8 +323,6 @@ const App = ({ forCafe = true, cafeId = -1,
} else if (otherCafes.length === 1) { } else if (otherCafes.length === 1) {
updatedFullTexts = [ updatedFullTexts = [
[otherCafes[0].cafeIdentifyName || otherCafes[0].username, otherCafes[0].cafeId || otherCafes[0].user_id], [otherCafes[0].cafeIdentifyName || otherCafes[0].username, otherCafes[0].cafeId || otherCafes[0].user_id],
...(user.roleId == 1 ? [[-1]] : [])
]; ];
setSelectedCafeId(otherCafes[0].cafeId); // Get the cafeId (second part of the pair) setSelectedCafeId(otherCafes[0].cafeId); // Get the cafeId (second part of the pair)
@@ -507,7 +505,7 @@ const App = ({ forCafe = true, cafeId = -1,
marginTop: '30px' marginTop: '30px'
}}> }}>
<MultiSwitch <MultiSwitch
texts={["Kemarin", "Minggu ini", "Bulan ini", "Tahun ini"]} texts={["Hari ini", "Minggu ini", "Bulan ini", "Tahun ini"]}
selectedSwitch={["yesterday", "weekly", "monthly", "yearly"].indexOf( selectedSwitch={["yesterday", "weekly", "monthly", "yearly"].indexOf(
filter filter
)} )}
@@ -611,9 +609,11 @@ const App = ({ forCafe = true, cafeId = -1,
> >
<div style={{ marginRight: "5px", fontSize: "1.2em" }}></div> <div style={{ marginRight: "5px", fontSize: "1.2em" }}></div>
<h6 style={{ margin: 0, textAlign: "left", fontSize: '10px', fontWeight: 500 }}> <h6 style={{ margin: 0, textAlign: "left", fontSize: '10px', fontWeight: 500 }}>
{(filter == 'yesterday' || filter == 'weekly') ? {(filter == 'weekly') ?
`Data dihitung dengan membandingkan `Data dihitung dengan membandingkan
${comparisonText} hari terakhir dengan ${comparisonText} hari sebelumnya, dengan penghitungan dimulai dari data kemarin.` 7 hari terakhir dengan 7 hari sebelumnya, dengan penghitungan dimulai dari data kemarin.`
:
(filter == 'yesterday') ? `Data dihitung dengan membandingkan antara hari ini dan kemarin.`
: :
(filter == 'monthly') ? `Data dihitung dengan membandingkan antara awal hingga akhir bulan ini dan bulan lalu, dengan penghitungan berakhir pada data kemarin.` : `Data dihitung dengan membandingkan antara awal hingga akhir tahun ini dan tahun lalu, dengan penghitungan berakhir pada data kemarin.`} (filter == 'monthly') ? `Data dihitung dengan membandingkan antara awal hingga akhir bulan ini dan bulan lalu, dengan penghitungan berakhir pada data kemarin.` : `Data dihitung dengan membandingkan antara awal hingga akhir tahun ini dan tahun lalu, dengan penghitungan berakhir pada data kemarin.`}
</h6> </h6>
@@ -628,7 +628,7 @@ const App = ({ forCafe = true, cafeId = -1,
} }
style={{ color: 'black', position: 'relative' }} style={{ color: 'black', position: 'relative' }}
> >
<div>Item laku</div> <div>Penjualan</div>
</div> </div>
<div <div
className={`${styles.filterSelector} ${circularFilter == 'material' ? '' : styles.filterSelectorInactive} className={`${styles.filterSelector} ${circularFilter == 'material' ? '' : styles.filterSelectorInactive}