Files
AnythingYouWant/src/components/Header.js
Vassshhh 67cf759b31 ok
2025-08-25 23:41:35 +07:00

490 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;
`;
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: 45px;
right: 51px;
width: 200px;
height: 40px;
}
`;
const ss = keyframes`
0% {
top: 45px;
right: 51px;
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: contain;
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: 28px;
right: 242px;
width: 40px;
height: 40px;
}
`;
const s = keyframes`
0% {
top: 28px;
right: 242px;
width: 40px;
height: 40px;
}
100% {
top: 0px;
right: 0px;
width: 60px;
height: 60px;
}
`;
const grow = keyframes`
0% {
right: 12px;
width: 60px;
height: 60px;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
}
100% {
right: 28px;
width: 300px;
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
}
`;
const shrink = keyframes`
0% {
right: 12px;
width: 300px;
height: auto;
border-radius: 20px;
}
100% {
right: 28px;
width: 60px;
height: 60px;
border-radius: 50%;
}
`;
const Rectangle = styled.div`
overflow-y: hidden;
position: absolute;
top: 39px;
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" }}>
<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>
Mode pengembangan &nbsp;
<Switch
borderRadius={0}
checked={isEditMode}
onChange={() => setIsEditMode(!isEditMode)}
/>
</Child>
<Child onClick={() => setModal("reports")}>Lihat laporan</Child>
<Child onClick={() => setModal("add_material")}>
Kelola bahan baku
</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 pengembangan&nbsp;
<Switch
borderRadius={0}
checked={isEditMode}
onChange={() => setIsEditMode(!isEditMode)}
/>
</Child>
<Child onClick={() => setModal("add_material")}>
Kelola bahan baku
</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;