489 lines
13 KiB
JavaScript
489 lines
13 KiB
JavaScript
import React, { useState, useRef, useEffect } from "react";
|
|
import styled, { keyframes } from "styled-components";
|
|
import { useLocation } from "react-router-dom";
|
|
import { useNavigationHelpers } from "../helpers/navigationHelpers";
|
|
import Switch from "react-switch";
|
|
|
|
const HeaderBarbackground = styled.div`
|
|
${({ shopName }) =>
|
|
shopName &&
|
|
`
|
|
background: linear-gradient(360deg, rgb(255 255 255) 0%, rgb(95 121 89) 100%);
|
|
`}
|
|
`;
|
|
|
|
const HeaderBar = styled.div`
|
|
pointer-events: auto;
|
|
margin-top: ${(props) => props.HeaderMargin};
|
|
box-shadow: ${(props) => (props.shopName ? '2px 2px #c1c1c1' : 'none')};
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 20px 15px;
|
|
color: black;
|
|
background-color: #ffffff;
|
|
z-index: 200;
|
|
border: 1px solid #00000000;
|
|
margin: 20px 12px;
|
|
border-radius: 13px;
|
|
`;
|
|
|
|
|
|
|
|
const Title = styled.h2`
|
|
margin: 0;
|
|
font-family: "Plus Jakarta Sans", sans-serif;
|
|
font-weight: 500;
|
|
font-style: normal;
|
|
font-size: ${(props) => props.HeaderSize};
|
|
color: rgba(88, 55, 50, 1);
|
|
text-transform: uppercase;
|
|
|
|
@media (min-width: 768px) {
|
|
font-size: 2vw;
|
|
}
|
|
`;
|
|
|
|
|
|
const ProfileName = styled.h2`
|
|
position: absolute;
|
|
font-family: "Plus Jakarta Sans", sans-serif;
|
|
font-weight: 500;
|
|
font-style: normal;
|
|
font-size: 30px;
|
|
z-index: 199;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
animation: ${(props) => {
|
|
if (props.animate === "grow") return gg;
|
|
if (props.animate === "shrink") return ss;
|
|
return nn;
|
|
}}
|
|
0.5s forwards;
|
|
text-align: left;
|
|
`;
|
|
|
|
const nn = keyframes`
|
|
0% {
|
|
top: 20px;
|
|
right: 30px;
|
|
width: 0ch;
|
|
height: 60px;
|
|
}
|
|
100% {
|
|
top: 20px;
|
|
right: 30px;
|
|
width: 0ch;
|
|
height: 60px;
|
|
}
|
|
`;
|
|
|
|
const gg = keyframes`
|
|
0% {
|
|
top: 20px;
|
|
right: 30px;
|
|
width: 0ch;
|
|
height: 60px;
|
|
}
|
|
100% {
|
|
top: 5px;
|
|
right: 20px;
|
|
width: 200px;
|
|
height: 40px;
|
|
}
|
|
`;
|
|
|
|
const ss = keyframes`
|
|
0% {
|
|
top: 5px;
|
|
right: 20px;
|
|
width: 200px;
|
|
height: 40px;
|
|
}
|
|
100% {
|
|
top: 20px;
|
|
right: 30px;
|
|
width: 0ch;
|
|
height: 60px;
|
|
}
|
|
`;
|
|
|
|
const ProfileImage = styled.img`
|
|
position: relative;
|
|
width: 60px;
|
|
height: 60px;
|
|
border-radius: 50%;
|
|
object-fit: cover;
|
|
cursor: pointer;
|
|
z-index: 199;
|
|
animation: ${(props) => {
|
|
if (props.animate === "grow") return g;
|
|
if (props.animate === "shrink") return s;
|
|
return "none";
|
|
}}
|
|
0.5s forwards;
|
|
`;
|
|
|
|
const g = keyframes`
|
|
0% {
|
|
top: 0px;
|
|
right: 0px;
|
|
width: 60px;
|
|
height: 60px;
|
|
}
|
|
100% {
|
|
top: 34px;
|
|
right: 229px;
|
|
width: 40px;
|
|
height: 40px;
|
|
}
|
|
`;
|
|
|
|
const s = keyframes`
|
|
0% {
|
|
top: 28px;
|
|
right: 229px;
|
|
width: 40px;
|
|
height: 40px;
|
|
}
|
|
100% {
|
|
top: 0px;
|
|
right: 0px;
|
|
width: 60px;
|
|
height: 60px;
|
|
}
|
|
`;
|
|
|
|
const grow = keyframes`
|
|
0% {
|
|
right: 0px;
|
|
top: 0px;
|
|
width: 60px;
|
|
height: 60px;
|
|
border-top-left-radius: 50%;
|
|
border-bottom-left-radius: 50%;
|
|
}
|
|
100% {
|
|
right: -17px;
|
|
width: 300px;
|
|
border-top-left-radius: 15px;
|
|
border-bottom-left-radius: 15px;
|
|
}
|
|
`;
|
|
|
|
const shrink = keyframes`
|
|
0% {
|
|
right: -17px;
|
|
width: 300px;
|
|
height: auto;
|
|
border-radius: 20px;
|
|
}
|
|
100% {
|
|
right: 0px;
|
|
top: 0px;
|
|
width: 60px;
|
|
height: 60px;
|
|
border-radius: 50%;
|
|
}
|
|
`;
|
|
const Rectangle = styled.div`
|
|
overflow-y: hidden;
|
|
position: absolute;
|
|
top: 9px;
|
|
right: 12px;
|
|
width: 200px;
|
|
max-height: 87vh; /* or another appropriate value */
|
|
background-color: white;
|
|
z-index: 198;
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
animation: ${(props) => (props.animate === "grow" ? grow : shrink)} 0.5s
|
|
forwards;
|
|
padding: 10px;
|
|
box-sizing: border-box;
|
|
overflow-x: hidden;
|
|
font-size: 14px;
|
|
color: #393939;
|
|
`;
|
|
|
|
const ChildContainer = styled.div`
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: flex-start;
|
|
align-items: flex-end;
|
|
flex-wrap: wrap;
|
|
padding-top: 70px;
|
|
`;
|
|
|
|
const ChildWrapper = styled.div`
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
`;
|
|
const Child = styled.div`
|
|
width: 100%;
|
|
height: 36px;
|
|
font-family: "Plus Jakarta Sans", sans-serif;
|
|
font-weight: 500;
|
|
font-style: normal;
|
|
|
|
${(props) =>
|
|
props.hasChildren
|
|
? `
|
|
margin-top: 14px;
|
|
border-top: 0.5px solid #a5a5a5;
|
|
height: auto;
|
|
`
|
|
: `
|
|
display: flex;
|
|
align-items: center;
|
|
`}
|
|
`;
|
|
|
|
|
|
const Header = ({
|
|
HeaderText,
|
|
HeaderSize = '5vw',
|
|
shopId,
|
|
shopName,
|
|
shopImage,
|
|
shopOwnerId,
|
|
shopClerks,
|
|
tableCode,
|
|
showProfile,
|
|
user,
|
|
setModal,
|
|
isLogout,
|
|
guestSides,
|
|
guestSideOfClerk,
|
|
removeConnectedGuestSides,
|
|
setIsEditMode,
|
|
isEditMode,
|
|
HeaderMargin = '25px'
|
|
}) => {
|
|
const { goToLogin, goToGuestSideLogin, goToAdminCafes } =
|
|
useNavigationHelpers(shopId, tableCode);
|
|
const [showRectangle, setShowRectangle] = useState(false);
|
|
const [animate, setAnimate] = useState("");
|
|
const rectangleRef = useRef(null);
|
|
const [guestSideOf, setGuestSideOf] = useState(null);
|
|
const location = useLocation();
|
|
|
|
const handleImageClick = () => {
|
|
if (showRectangle) {
|
|
setAnimate("shrink");
|
|
setTimeout(() => setShowRectangle(false), 500);
|
|
} else {
|
|
setAnimate("grow");
|
|
setShowRectangle(true);
|
|
}
|
|
};
|
|
|
|
const handleClickOutside = (event) => {
|
|
if (rectangleRef.current && !rectangleRef.current.contains(event.target)) {
|
|
setAnimate("shrink");
|
|
setTimeout(() => setShowRectangle(false), 500);
|
|
rectangleRef.current.style.overflow = "hidden";
|
|
}
|
|
};
|
|
|
|
const handleScroll = () => {
|
|
if (showRectangle) {
|
|
setAnimate("shrink");
|
|
setTimeout(() => setShowRectangle(false), 500);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
const queryParams = new URLSearchParams(location.search);
|
|
const hasModalParam = queryParams.has("modal");
|
|
|
|
if (showRectangle && !hasModalParam) {
|
|
document.addEventListener("mousedown", handleClickOutside);
|
|
window.addEventListener("scroll", handleScroll);
|
|
} else {
|
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
window.removeEventListener("scroll", handleScroll);
|
|
}
|
|
|
|
return () => {
|
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
window.removeEventListener("scroll", handleScroll);
|
|
};
|
|
}, [showRectangle, location.search]);
|
|
|
|
useEffect(() => {
|
|
setGuestSideOf(guestSideOfClerk);
|
|
console.log(guestSideOfClerk);
|
|
}, [guestSideOfClerk]);
|
|
|
|
const generateMenuHeader = (cafeName) => {
|
|
// Check if the name already ends with "'s"
|
|
if (cafeName.endsWith("'s")) {
|
|
return `${cafeName} menu`; // Return as-is for already possessive names
|
|
}
|
|
if (cafeName.endsWith("s")) {
|
|
return `${cafeName} menu`; // Return as-is for already possessive names
|
|
}
|
|
|
|
// Otherwise, use the possessive function
|
|
return `${cafeName}'s menu`;
|
|
};
|
|
return (
|
|
<HeaderBarbackground shopName={shopName}>
|
|
<HeaderBar HeaderMargin={HeaderMargin} shopName={shopName}>
|
|
<Title HeaderSize={HeaderSize}>
|
|
{shopName == null
|
|
? HeaderText == null
|
|
? "kedaimaster"
|
|
: HeaderText
|
|
: shopName}
|
|
</Title>
|
|
<div style={{ visibility: showProfile ? "visible" : "hidden", position: 'relative' }}>
|
|
<ProfileImage
|
|
src={shopImage && !shopImage.includes('undefined') ? shopImage || 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-DjX_bGBax4NL14ULvkAdU4FP3FKoWXWu5w&s' : "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-DjX_bGBax4NL14ULvkAdU4FP3FKoWXWu5w&s"}
|
|
alt="Profile"
|
|
onClick={user.username !== undefined ? handleImageClick : null}
|
|
animate={showRectangle && animate}
|
|
/>
|
|
<ProfileName animate={showRectangle && animate}>
|
|
{showProfile && user.username !== undefined ? user.username : "guest"}
|
|
</ProfileName>
|
|
{showRectangle && (
|
|
<Rectangle ref={rectangleRef} animate={animate}>
|
|
<ChildContainer>
|
|
{guestSideOfClerk && guestSideOfClerk.clerkUsername && (
|
|
<Child hasChildren>
|
|
this is the guest side of {guestSideOfClerk.clerkUsername}
|
|
</Child>
|
|
)}
|
|
{user.username !== undefined && (
|
|
<Child onClick={() => setModal("edit_account")}>
|
|
Kelola akun
|
|
</Child>
|
|
)}
|
|
{user.roleId == 0 && (
|
|
<Child onClick={() => setModal('create_coupon', {})}>Buat Voucher</Child>)}
|
|
{shopId && user.roleId == 1 && (
|
|
<Child onClick={goToAdminCafes}>Dashboard</Child>)}
|
|
{shopId &&
|
|
user.user_id == shopOwnerId &&
|
|
user.username !== undefined &&
|
|
user.roleId === 1 && (
|
|
<>
|
|
<Child hasChildren>
|
|
<Child>
|
|
{shopName}
|
|
</Child>
|
|
<Child onClick={() => setModal("reports")}>Lihat laporan</Child>
|
|
<Child onClick={() => setModal("add_material")}>
|
|
Kelola stok
|
|
</Child>
|
|
|
|
<Child hasChildren>
|
|
<Child>Konfigurasi</Child>
|
|
<Child onClick={() => setModal("welcome_config")}>
|
|
Desain kafe
|
|
</Child>
|
|
<Child onClick={() => setModal("edit_tables")}>
|
|
Identifikasi kedai
|
|
</Child>
|
|
<Child onClick={() => setModal("payment_option")}>
|
|
Metode pembayaran
|
|
</Child>
|
|
</Child>
|
|
<Child hasChildren>
|
|
<Child>Kasir</Child>
|
|
<Child onClick={() => setModal("create_clerk")}>
|
|
+ Tambah
|
|
</Child>
|
|
{shopClerks &&
|
|
shopClerks.map((key, index) => (
|
|
<Child key={index}>
|
|
{shopClerks[index].username}
|
|
<button
|
|
onClick={() =>
|
|
removeConnectedGuestSides(
|
|
guestSides[index][3]
|
|
)
|
|
}
|
|
>
|
|
remove
|
|
</button>
|
|
</Child>
|
|
))}
|
|
</Child>
|
|
</Child>
|
|
</>
|
|
)}
|
|
{user.username !== undefined &&
|
|
user.cafeId == shopId &&
|
|
user.roleId === 2 && (
|
|
<Child hasChildren>
|
|
<Child>{shopName}</Child>
|
|
|
|
<Child>
|
|
Mode Edit
|
|
<Switch
|
|
borderRadius={0}
|
|
checked={isEditMode}
|
|
onChange={() => setIsEditMode(!isEditMode)}
|
|
/>
|
|
</Child>
|
|
<Child onClick={() => setModal("add_material")}>
|
|
Kelola stok
|
|
</Child>
|
|
|
|
<Child hasChildren>
|
|
<Child>Konfigurasi</Child>
|
|
<Child onClick={() => setModal("welcome_config")}>
|
|
Desain kafe
|
|
</Child>
|
|
<Child onClick={() => setModal("edit_tables")}>
|
|
Identifikasi kedai
|
|
</Child>
|
|
<Child onClick={() => setModal("payment_option")}>
|
|
Metode pembayaran
|
|
</Child>
|
|
</Child>
|
|
{user.username !== undefined &&
|
|
user.roleId == 2 &&
|
|
user.cafeId == shopId && (
|
|
<Child hasChildren>
|
|
Tablet tamu
|
|
<Child onClick={goToGuestSideLogin}>
|
|
+ Tambah
|
|
</Child>
|
|
{guestSides &&
|
|
guestSides.map((key, index) => (
|
|
<Child key={index}>
|
|
guest side {index + 1}
|
|
<button
|
|
onClick={() =>
|
|
removeConnectedGuestSides(
|
|
guestSides[index][3]
|
|
)
|
|
}
|
|
>
|
|
remove
|
|
</button>
|
|
</Child>
|
|
))}
|
|
</Child>
|
|
)}
|
|
|
|
<Child onClick={() => setModal("reports")}>Laporan</Child>
|
|
</Child>
|
|
)}
|
|
{user.username !== undefined && (
|
|
<Child hasChildren ><Child onClick={isLogout}>Logout</Child></Child>
|
|
)}
|
|
</ChildContainer>
|
|
</Rectangle>
|
|
)}
|
|
</div>
|
|
</HeaderBar></HeaderBarbackground>
|
|
);
|
|
};
|
|
|
|
export default Header;
|