This commit is contained in:
everythingonblack
2025-04-04 05:03:09 +07:00
parent 931f3f90e8
commit 6b59349eff
18 changed files with 998 additions and 698 deletions

View File

@@ -2,7 +2,7 @@
"name": "groovebrew-mockup", "name": "groovebrew-mockup",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"homepage": "https://dev.kedaimaster.com", "homepage": "https://kedaimaster.com",
"dependencies": { "dependencies": {
"@emotion/react": "^11.13.3", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0", "@emotion/styled": "^11.13.0",

View File

@@ -11,6 +11,29 @@ body {
/* overflow-x: hidden; */ /* overflow-x: hidden; */
} }
.Cafe {
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 100vh;
position: relative;
}
.Cafe.grayscale {
filter: grayscale(1);
pointer-events: none; /* Disable pointer events when the deadline is exceeded */
}
.Watermark {
position: absolute;
height: 100%;
width: 100%;
background-image: url(https://i.ibb.co.com/F4FMw1jz/testuseonly.png);
z-index: 1000;
filter: opacity(0.05);
pointer-events: none;
}
.App-logo { .App-logo {
height: 40vmin; height: 40vmin;
pointer-events: none; pointer-events: none;

View File

@@ -44,6 +44,8 @@ import {
} from "./helpers/subscribeHelpers.js"; } from "./helpers/subscribeHelpers.js";
import Modal from "./components/Modal"; // Import your modal component import Modal from "./components/Modal"; // Import your modal component
import { requestNotificationPermission } from './services/notificationService'; // Import the notification service
function App() { function App() {
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
@@ -63,6 +65,7 @@ function App() {
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [modalContent, setModalContent] = useState(null); const [modalContent, setModalContent] = useState(null);
const [onModalCloseFunction, setOnModalCloseFunction] = useState(null); const [onModalCloseFunction, setOnModalCloseFunction] = useState(null);
const [onModalYesFunction, setOnModalYesFunction] = useState(null);
const transactionList = useRef(null); const transactionList = useRef(null);
const [queue, setQueue] = useState([]); const [queue, setQueue] = useState([]);
@@ -249,6 +252,18 @@ function App() {
}); });
const handleNotificationClick = async () => {
const permission = await requestNotificationPermission();
if (permission === "granted") {
console.log("Notification permission granted.");
// Set up notifications or show a success modal
} else {
console.error("Notification permission denied.");
setModal('blocked_notification'); // Show modal for blocked notifications
}
};
const checkNotifications = () => { const checkNotifications = () => {
let permission = Notification.permission; let permission = Notification.permission;
@@ -257,7 +272,7 @@ function App() {
let searchModal = searchParams.get("modal") || ''; // Get transactionId or set it to empty string let searchModal = searchParams.get("modal") || ''; // Get transactionId or set it to empty string
if (permission !== "granted" && searchModal == '') { if (permission !== "granted" && searchModal == '') {
setModal("req_notification"); setModal("message", { captMessage: 'Notifikasi tidak aktif', descMessage: 'Aktifkan notifikasi supaya kamu tetap dapat info pesanan, meski sedang buka aplikasi lain.' }, null, handleNotificationClick);
} }
}; };
@@ -268,7 +283,7 @@ function App() {
} else { } else {
console.log(data) console.log(data)
setUser(data.data.user); setUser(data.data.user);
if(data.data.latestOpenBillTransaction != null) localStorage.setItem('lastTransaction', JSON.stringify(data.data.latestOpenBillTransaction)) if (data.data.latestOpenBillTransaction != null) localStorage.setItem('lastTransaction', JSON.stringify(data.data.latestOpenBillTransaction))
if ( if (
data.data.user.password == "unsetunsetunset" && data.data.user.password == "unsetunsetunset" &&
localStorage.getItem("settings") localStorage.getItem("settings")
@@ -438,7 +453,7 @@ function App() {
}, [navigate]); }, [navigate]);
// Function to open the modal // Function to open the modal
const setModal = (content, params = {}, onCloseFunction) => { const setModal = (content, params = {}, onCloseFunction, onYesFunction) => {
const queryParams = new URLSearchParams(location.search); const queryParams = new URLSearchParams(location.search);
// Update the modal and any additional params // Update the modal and any additional params
@@ -462,6 +477,11 @@ function App() {
} else { } else {
setOnModalCloseFunction(null); setOnModalCloseFunction(null);
} }
if (onYesFunction) {
setOnModalYesFunction(() => onYesFunction); // Store the close function
} else {
setOnModalYesFunction(null);
}
}; };
const closeModal = (closeTheseContent = []) => { const closeModal = (closeTheseContent = []) => {
@@ -725,6 +745,7 @@ function App() {
onClose={closeModal} onClose={closeModal}
setModal={setModal} setModal={setModal}
onModalCloseFunction={onModalCloseFunction} onModalCloseFunction={onModalCloseFunction}
onModalYesFunction={onModalYesFunction}
/> />
</div> </div>
); );

View File

@@ -58,7 +58,7 @@ const AccountUpdatePage = ({ user, showEmail, onSubmit }) => {
<div className={styles.LoginForm}> <div className={styles.LoginForm}>
<div className={`${styles.FormUsername} ${inputtingPassword ? styles.animateForm : wasInputtingPassword ? styles.reverseForm : ''}`}> <div className={`${styles.FormUsername} ${inputtingPassword ? styles.animateForm : wasInputtingPassword ? styles.reverseForm : ''}`}>
<label htmlFor="username" className={styles.usernameLabel}>--------------------------------------------</label> <label htmlFor="username" className={styles.usernameLabel}>----------------------------------------</label>
<input <input
name="username" name="username"
@@ -85,7 +85,7 @@ const AccountUpdatePage = ({ user, showEmail, onSubmit }) => {
<div className={`${styles.FormPassword} ${inputtingPassword ? styles.animateForm : wasInputtingPassword ? styles.reverseForm : ''}`}> <div className={`${styles.FormPassword} ${inputtingPassword ? styles.animateForm : wasInputtingPassword ? styles.reverseForm : ''}`}>
<span> <span>
<label onClick={() => setInputtingPassword(false)} htmlFor="password" className={styles.usernameLabel}> &lt;--- &lt;-- kembali </label> <label onClick={() => setInputtingPassword(false)} htmlFor="password" className={styles.usernameLabel}> &lt;--- &lt;-- kembali </label>
<label htmlFor="password" className={styles.usernameLabel}>-------------------------</label> <label htmlFor="password" className={styles.usernameLabel}>----------------------</label>
</span> </span>
<input <input

View File

@@ -34,7 +34,7 @@ import CreateCoupon from "../pages/CreateCoupon";
import CheckCoupon from "../pages/CheckCoupon"; import CheckCoupon from "../pages/CheckCoupon";
import CreateUserWithCoupon from "../pages/CreateUserWithCoupon"; import CreateUserWithCoupon from "../pages/CreateUserWithCoupon";
const Modal = ({ user, shop, isOpen, onClose, modalContent, deviceType, setModal, handleMoveToTransaction,welcomePageConfig, onModalCloseFunction }) => { const Modal = ({ user, shop, isOpen, onClose, modalContent, deviceType, setModal, handleMoveToTransaction,welcomePageConfig, onModalCloseFunction, onModalYesFunction }) => {
const [shopImg, setShopImg] = useState(''); const [shopImg, setShopImg] = useState('');
const [updateKey, setUpdateKey] = useState(0); const [updateKey, setUpdateKey] = useState(0);
@@ -62,6 +62,15 @@ const Modal = ({ user, shop, isOpen, onClose, modalContent, deviceType, setModal
onClose(); // Close the modal onClose(); // Close the modal
}; };
const handleYes = (event) => {
if(onModalYesFunction)
console.log('dawnawddjwand')
onModalYesFunction();
}
const handleNo = (event) => {
if(onModalCloseFunction) onModalCloseFunction();
}
// Function to handle clicks on the modal content // Function to handle clicks on the modal content
const handleContentClick = (event) => { const handleContentClick = (event) => {
@@ -123,7 +132,7 @@ const Modal = ({ user, shop, isOpen, onClose, modalContent, deviceType, setModal
{modalContent === "join" && <Join setModal={setModal} />} {modalContent === "join" && <Join setModal={setModal} />}
{modalContent === "claim-coupon" && <Join setModal={setModal} />} {modalContent === "claim-coupon" && <Join setModal={setModal} />}
{modalContent === "loading" && <Loading setModal={setModal} />} {modalContent === "loading" && <Loading setModal={setModal} />}
{modalContent === "message" && <Message/>} {modalContent === "message" && <Message handleYes={handleYes}/>}
</div> </div>
</div> </div>
); );

View File

@@ -130,7 +130,7 @@
} }
.expandable-container > div:first-child { .expandable-container > div:first-child {
padding-top: 20px; padding-top: 28px;
-webkit-touch-callout: none; /* iOS Safari */ -webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */ -webkit-user-select: none; /* Safari */
@@ -167,7 +167,7 @@
outline: none; outline: none;
transition: padding-top 0.3s ease; transition: padding-top 0.3s ease;
padding-top: 8px; padding-top: 13px;
} }
.expand-button h5 { .expand-button h5 {

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import styles from './StepByStep.module.css'; // Import the CSS Module import styles from './StepByStep.module.css'; // Import the CSS module
const StepByStep = () => { const StepByStep = () => {
return ( return (
@@ -11,26 +11,38 @@ const StepByStep = () => {
<img src="https://i.ibb.co.com/6cGq6byM/player1.jpg" alt="Player 1" /> <img src="https://i.ibb.co.com/6cGq6byM/player1.jpg" alt="Player 1" />
<img src="https://i.ibb.co.com/0VDjJdXV/player2.jpg" alt="Player 2" /> <img src="https://i.ibb.co.com/0VDjJdXV/player2.jpg" alt="Player 2" />
<img src="https://i.ibb.co.com/8D3mSp4g/player3.jpg" alt="Player 3" /> <img src="https://i.ibb.co.com/8D3mSp4g/player3.jpg" alt="Player 3" />
<img src="https://i.ibb.co.com/XxS1DhRy/player4.jpg" alt="Player 4" /> <img src="https://i.ibb.co.com/tw7KkmZ1/player4.jpg" alt="Player 4" />
<img src="https://i.ibb.co.com/9k4PHW5W/player5.jpg" alt="Player 5" />
<div>
<img src="https://i.ibb.co.com/TBYM6htX/search.jpg" alt="Search" />
<div></div>
</div>
<img src="https://i.ibb.co.com/cSqD0LKR/music1.jpg" alt="Music 1" />
<img src="https://i.ibb.co.com/Q737mTn5/music2.jpg" alt="Music 2" />
<img src="https://i.ibb.co.com/Rk4tQW6M/music3.jpg" alt="Music 3" />
<div className={styles.borderRight}></div>
<div className={styles.whiteBg}></div>
</div> </div>
<div> <div>
<img src="https://i.ibb.co.com/4z5zdsS/body.jpg" alt="Body" /> <img src="https://i.ibb.co.com/4z5zdsS/body.jpg" alt="Body" />
<div className={styles.escappucino}> <div className={styles.escappucino}>
<img src="https://i.ibb.co.com/yFvrPX8z/pesan.png" alt="Escappucino 1" /> <img src="https://i.ibb.co.com/yFvrPX8z/pesan.png" alt="Escappucino" />
<img src="https://i.ibb.co.com/rRwPHtY7/pesan-1.png" alt="Escappucino 2" /> <img src="https://i.ibb.co.com/rRwPHtY7/pesan-1.png" alt="Escappucino 1" />
</div> </div>
<div className={styles.chickenkatsu}> <div className={styles.chickenkatsu}>
<img src="https://i.ibb.co.com/yFvrPX8z/pesan.png" alt="Chickenkatsu 1" /> <img src="https://i.ibb.co.com/yFvrPX8z/pesan.png" alt="Chicken Katsu" />
<img src="https://i.ibb.co.com/rRwPHtY7/pesan-1.png" alt="Chickenkatsu 2" /> <img src="https://i.ibb.co.com/rRwPHtY7/pesan-1.png" alt="Chicken Katsu 1" />
</div> </div>
</div> </div>
</div> </div>
<div className={styles.cartbutton}> <div className={styles.cartbutton}>
<img src="https://i.ibb.co.com/zVrfGjZw/New-Project.png" alt="Cart Button" /> <img src="https://i.ibb.co.com/zVrfGjZw/New-Project.png" alt="New Project" />
<img src="https://i.ibb.co.com/Y7wbjGDz/cart-2.png" alt="Cart Icon" /> <img src="https://i.ibb.co.com/Y 7wbjGDz/cart-2.png" alt="Cart" />
</div> </div>
<div className={styles.cart}> <div className={styles.cart}>
<img src="https://i.ibb.co.com/F4Hb7Tqg/cart.jpg" alt="Cart Image" /> <img src="https://i.ibb.co.com/F4Hb7Tqg/cart.jpg" alt="Cart" />
<img src="https://i.ibb.co.com/Mxrjc9Dc/checkout.png" alt="Checkout" /> <img src="https://i.ibb.co.com/Mxrjc9Dc/checkout.png" alt="Checkout" />
</div> </div>
<div className={styles.transaction}> <div className={styles.transaction}>
@@ -39,7 +51,7 @@ const StepByStep = () => {
</div> </div>
<div className={styles.secondscreen}> <div className={styles.secondscreen}>
<div className={styles.secondmain}> <div className={styles.secondmain}>
<img src="https://i.ibb.co.com/LDw21htp/New-Project.jpg"/> <img src="https://i.ibb.co.com/LDw21htp/New-Project.jpg" alt="Second Main" />
</div> </div>
</div> </div>
</div> </div>

View File

@@ -130,6 +130,15 @@
68% { 68% {
transform: scale(1); /* Scale back to original size */ transform: scale(1); /* Scale back to original size */
} }
90% {
transform: scale(1); /* Scale back to original size */
}
91% {
transform: scale(0.8); /* Scale back to original size */
}
92% {
transform: scale(1); /* Scale back to original size */
}
94% { 94% {
transform: scale(1); /* Scale back to original size */ transform: scale(1); /* Scale back to original size */
} }
@@ -207,6 +216,184 @@
left: 0; left: 0;
} }
.player > img:nth-child(5) {
animation: player5ExpandedOpacity 20s infinite;
position: absolute;
top: 0;
left: 0;
}
.player > div:nth-child(6) {
animation: playerSearch 20s infinite;
position: absolute;
top: 207%;
left: 0;
width: 100%;
z-index: 6;
display: flex;
justify-content: center;
align-items: center;
}
.player > div:nth-child(6) > img:nth-child(1){
width: 70%;
height: 70%;
object-fit: contain;
}
.player > div:nth-child(6) > div:nth-child(2){
position: absolute;
animation: playerSearchText 20s infinite;
width: 30%;
height: 80%;
background-color: #f3efe6;
}
.player > img:nth-child(7) {
animation: musicExpanded 20s infinite;
position: absolute;
top: 280%;
left: 0;
z-index: 6;
}
.player > img:nth-child(8) {
animation: music2Expanded 20s infinite;
position: absolute;
top: 390%;
left: 0;
z-index: 6;
}
.player > img:nth-child(9) {
animation: musicExpanded 20s infinite;
position: absolute;
top: 500%;
left: 0;
z-index: 6;
}
.borderRight {
position: absolute;
width: 5%;
height: 150%;
background-color: white;
right: -2%;
top: 370%;
animation: musicExpanded 20s infinite;
z-index: 6;
}
.whiteBg {
position: absolute;
width: 90%;
height: 180%;
background-color: white;
top: 370%;
animation: musicExpanded 20s infinite;
z-index: 5;
}
/* New keyframes for scaling and opacity effect */
@keyframes playerSearch {
0% {
filter: opacity(0); /* Initial scale */
}
67% {
filter: opacity(0); /* Initial scale */
}
70% {
filter: opacity(1); /* Initial scale */
}
79% {
filter: opacity(1); /* Initial scale */
}
81% {
filter: opacity(0); /* Initial scale */
}
100% {
filter: opacity(0); /* Initial scale */
}
}
@keyframes playerSearchText {
0% {
transform: translate(0%,0);
}
71% {
transform: translate(0%,0);
}
74% {
transform: translate(70%,0);
}
100% {
transform: translate(70%,0);
}
}
/* New keyframes for scaling and opacity effect */
@keyframes musicExpanded {
0% {
filter: opacity(0); /* Initial scale */
}
73% {
filter: opacity(0);
transform: scale(0.7);
}
75% {
filter: opacity(1);
transform: scale(0.9);
}
89% {
filter: opacity(1);
}
90% {
filter: opacity(0);
}
98% {
filter: opacity(0);
}
100% {
filter: opacity(0); /* Scale back to original size */
transform: scale(0.9);
}
}
/* New keyframes for scaling and opacity effect */
@keyframes music2Expanded {
0% {
filter: opacity(0); /* Initial scale */
}
73% {
filter: opacity(0);
transform: scale(0.7);
}
75% {
filter: opacity(1);
transform: scale(0.9);
}
77% {
filter: opacity(1);
transform: scale(0.9);
}
79% {
filter: opacity(1);
transform: scale(0.8) translate(0,0);
}
85% {
filter: opacity(1);
transform: scale(0.8) translate(120%,0);
}
89% {
filter: opacity(1);
}
90% {
filter: opacity(0);
}
98% {
filter: opacity(0);
}
100% {
filter: opacity(0); /* Scale back to original size */
transform: scale(0.8) translate(120%,0);
}
}
/* New keyframes for scaling and opacity effect */ /* New keyframes for scaling and opacity effect */
@keyframes playerUnexpandedOpacity { @keyframes playerUnexpandedOpacity {
0% { 0% {
@@ -218,10 +405,10 @@
66% { 66% {
filter: opacity(0); filter: opacity(0);
} }
95% { 94% {
filter: opacity(0); filter: opacity(0);
} }
96% { 95% {
filter: opacity(1); filter: opacity(1);
} }
100% { 100% {
@@ -259,10 +446,10 @@
67% { 67% {
filter: opacity(1); filter: opacity(1);
} }
90% { 89% {
filter: opacity(1); filter: opacity(1);
} }
91% { 90% {
filter: opacity(0); filter: opacity(0);
} }
100% { 100% {
@@ -272,6 +459,28 @@
/* New keyframes for scaling and opacity effect */ /* New keyframes for scaling and opacity effect */
@keyframes player4ExpandedOpacity { @keyframes player4ExpandedOpacity {
0% {
filter: opacity(0); /* Initial scale */
}
84% {
filter: opacity(0);
}
85% {
filter: opacity(1);
}
89% {
filter: opacity(1);
}
90% {
filter: opacity(0);
}
100% {
filter: opacity(0); /* Scale back to original size */
}
}
/* New keyframes for scaling and opacity effect */
@keyframes player5ExpandedOpacity {
0% { 0% {
filter: opacity(0); /* Initial scale */ filter: opacity(0); /* Initial scale */
} }
@@ -284,8 +493,8 @@
95% { 95% {
filter: opacity(1); filter: opacity(1);
} }
97% { 96% {
filter: opacity(1); filter: opacity(0);
} }
98% { 98% {
filter: opacity(0); filter: opacity(0);
@@ -294,7 +503,6 @@
filter: opacity(0); /* Scale back to original size */ filter: opacity(0); /* Scale back to original size */
} }
} }
.escappucino { .escappucino {
position: relative; position: relative;
top: -63.6%; top: -63.6%;

View File

@@ -6,7 +6,7 @@ const Watermark = ({dontShowName}) => {
<div style={{ zIndex: 5, marginTop: '30px', backgroundColor: 'rgb(222 237 100)', fontWeight: 700, fontSize: '15px', lineHeight: '1rem', letterSpacing: '-1px', color: 'rgb(37, 79, 26)', padding: '10px' }}> <div style={{ zIndex: 5, marginTop: '30px', backgroundColor: 'rgb(222 237 100)', fontWeight: 700, fontSize: '15px', lineHeight: '1rem', letterSpacing: '-1px', color: 'rgb(37, 79, 26)', padding: '10px' }}>
{!dontShowName && <div>KEDAIMASTER.COM</div>} {!dontShowName && <div>KEDAIMASTER.COM</div>}
<div style={{ display: 'flex' }}> <div style={{ display: 'flex' }}>
<div style={{ width: '45vw', marginTop: '10px', fontSize: '5.5vw', lineHeight: '33px' }}>Gak perlu rasain antri panjang yang bikin bosen lagi. Tinggal scan QR yang ada di meja, eh tiba tiba pesanan udah dimejamu</div> <div style={{ width: '45vw', marginTop: '10px', fontSize: '5.5vw', lineHeight: '33px' }}>Gak perlu rasain antri panjang yang bikin bosen lagi. Tinggal scan QR yang ada di meja, eh tiba tiba kamu udah kenyang wkwkkw</div>
<StepByStep /> <StepByStep />
</div> </div>
<div style={{ marginTop: '8px' }}>© 2025 KEDIRITECHNOPARK.COM</div> <div style={{ marginTop: '8px' }}>© 2025 KEDIRITECHNOPARK.COM</div>

View File

@@ -1,5 +1,5 @@
// src/config.js // src/config.js
const API_BASE_URL = 'https://dev.api.kedaimaster.com'; const API_BASE_URL = 'https://api.kedaimaster.com';
export default API_BASE_URL; export default API_BASE_URL;

View File

@@ -10,6 +10,7 @@ import {
import "../App.css"; import "../App.css";
import API_BASE_URL from '../config';
import Watermark from "../components/Watermark"; import Watermark from "../components/Watermark";
import { getImageUrl, createItem, updateItem, moveItemType } from "../helpers/itemHelper.js"; import { getImageUrl, createItem, updateItem, moveItemType } from "../helpers/itemHelper.js";
import SearchInput from "../components/SearchInput"; import SearchInput from "../components/SearchInput";
@@ -140,7 +141,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',{returnMessage:'Kafe sedang tidak tersedia'}); if (isExceededDeadline) setModal('message',{captMessage:'Kafe sedang tidak tersedia'});
setIsExceededDeadline(isExceededDeadline); setIsExceededDeadline(isExceededDeadline);
}); });
} }
@@ -199,7 +200,7 @@ function CafePage({
else else
return ( return (
<> <>
{welcomePageConfig && isStarted ? ( {/* {welcomePageConfig && isStarted ? (
<WelcomePage <WelcomePage
image={config.image} image={config.image}
welcomingText={config.welcomingText} welcomingText={config.welcomingText}
@@ -209,9 +210,12 @@ function CafePage({
onGetStarted={handleGetStarted} onGetStarted={handleGetStarted}
isFullscreen={true} isFullscreen={true}
/> />
) : ( ) : ( */}
welcomePageConfig != null && ( <div className={`Cafe ${isExceededDeadline ? 'grayscale' : ''}`}>
<div className="Cafe" style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', minHeight: '100vh', filter: isExceededDeadline ? 'grayscale(1)' : '', pointerEvents: isExceededDeadline ? 'none' : '' }}>
{API_BASE_URL != 'https://api.kedaimaster.com' &&
<div className="Watermark"></div>
}
<div className="App-header"> <div className="App-header">
<Header <Header
HeaderText={"Menu"} HeaderText={"Menu"}
@@ -363,8 +367,7 @@ function CafePage({
</div> </div>
<Watermark/> <Watermark/>
</div> </div>
) {/* )} */}
)}
</> </>
); );
} }

View File

@@ -46,7 +46,7 @@ const CreateCouponPage = () => {
let encodedCouponCode = encodeURIComponent(encryptedCouponCode); let encodedCouponCode = encodeURIComponent(encryptedCouponCode);
// Construct the URL with the encoded coupon code as a query parameter // Construct the URL with the encoded coupon code as a query parameter
const urlWithCoupon = `https://dev.coupon.kedaimaster.com/coupon?c=${encodedCouponCode}`; const urlWithCoupon = `https://coupon.kedaimaster.com/coupon?c=${encodedCouponCode}`;
// Optionally, set the URL to use with the coupon // Optionally, set the URL to use with the coupon
setCouponUrl(urlWithCoupon); setCouponUrl(urlWithCoupon);

View File

@@ -35,7 +35,6 @@ const LinktreePage = ({ user, setModal }) => {
const [selectedSubItemId, setSelectedSubItemId] = useState(0); const [selectedSubItemId, setSelectedSubItemId] = useState(0);
const [coupons, setCoupons] = useState(null); const [coupons, setCoupons] = useState(null);
useEffect(() => { useEffect(() => {
const urlParams = new URLSearchParams(location.search); const urlParams = new URLSearchParams(location.search);
const modalParam = urlParams.get('modal'); const modalParam = urlParams.get('modal');
@@ -126,6 +125,7 @@ const LinktreePage = ({ user, setModal }) => {
useEffect(() => { useEffect(() => {
if (user) { if (user) {
setLoading(true); setLoading(true);
document.body.style.backgroundColor = "white";
switch (user.roleId) { switch (user.roleId) {
case 0: case 0:
getAnalytics().then(setItems).catch(console.error).finally(() => setLoading(false)); getAnalytics().then(setItems).catch(console.error).finally(() => setLoading(false));
@@ -138,6 +138,7 @@ const LinktreePage = ({ user, setModal }) => {
break; break;
default: default:
setLoading(false); setLoading(false);
document.body.style.backgroundColor = "rgb(222, 237, 100)";
break; break;
} }
} }

View File

@@ -192,11 +192,11 @@ const LinktreePage = ({ data, setModal }) => {
const loggingcoupon = await handleLogCouponForUser(); // Await the coupon logging process const loggingcoupon = await handleLogCouponForUser(); // Await the coupon logging process
setModal('message', { setModal('message', {
returnMessage: loggingcoupon ? 'Kupon berhasil ditambahkan' : 'Kupon gagal ditambahkan' captMessage: loggingcoupon ? 'Kupon berhasil ditambahkan' : 'Kupon gagal ditambahkan'
}); });
} catch (error) { } catch (error) {
console.error('Error during coupon handling:', error); console.error('Error during coupon handling:', error);
setModal('message', { returnMessage: 'Kupon gagal ditambahkan' }); setModal('message', { captMessage: 'Kupon gagal ditambahkan' });
} }
} }
}} }}

View File

@@ -12,7 +12,7 @@
.dashboardContainer { .dashboardContainer {
z-index: 6; z-index: 6;
padding-top: 40px; padding: 40px 3px 15px 3px;
} }
/* Main Heading */ /* Main Heading */
@@ -25,7 +25,27 @@
letter-spacing: -1px; letter-spacing: -1px;
color: rgb(37, 79, 26); color: rgb(37, 79, 26);
} }
.button {
color: white;
background-color: rgb(37, 79, 26);
border-radius: 25px;
padding: 0px 0px 0px 18px;
width: 222px;
font-weight: 700;
font-size: 32px;
line-height: 2.25rem;
letter-spacing: -1px;
}
.descHeading {
width: 99%;
font-weight: 700;
font-size: 16px;
line-height: 1.25rem;
margin-bottom: 1rem;
letter-spacing: -1px;
color: rgb(37, 79, 26);
}
/* Main Heading */ /* Main Heading */
.voucherHeading { .voucherHeading {
font-weight: 700; font-weight: 700;

View File

@@ -20,6 +20,7 @@
z-index: 6; z-index: 6;
padding: 0 1rem; padding: 0 1rem;
padding-top: 100px; padding-top: 100px;
margin-bottom: 30px;
} }
/* Main Heading */ /* Main Heading */

View File

@@ -2,24 +2,26 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import styles from './Join.module.css'; // Import the module.css file import styles from './Join.module.css'; // Import the module.css file
const LinktreePage = () => { const LinktreePage = ({ handleYes }) => {
const [returnMessage, setReturnMessage] = useState(''); const [captMessage, setCaptMessage] = useState('');
const [descMessage, setDescMessage] = useState('');
useEffect(() => { useEffect(() => {
const newQueryParams = new URLSearchParams(window.location.search); const newQueryParams = new URLSearchParams(window.location.search);
const r = newQueryParams.get('returnMessage'); const r = newQueryParams.get('captMessage');
const s = newQueryParams.get('descMessage');
if (r) { if (r) {
setReturnMessage(r) setCaptMessage(r)
setDescMessage(s)
} }
}, []); }, []);
return ( return (
<div className={styles.linktreePage}> <div className={styles.linktreePage}>
<div className={styles.dashboardContainer}> <div className={styles.dashboardContainer}>
<div className={styles.mainHeading}>{returnMessage}</div> <div className={styles.mainHeading}>{captMessage}</div>
<div className={styles.subHeadingTransparent}> <div className={styles.descHeading}>{descMessage}</div>
Daftarkan kedaimu sekarang dan mulai gunakan semua fitur unggulan kami. {handleYes && <div onClick={handleYes} className={styles.button}>Aktifkan</div>}
</div>
</div> </div>
</div> </div>
); );

View File

@@ -452,7 +452,7 @@ const App = ({ forCafe = true, cafeId = -1,
setModal('loading'); setModal('loading');
const create = await createCafe(itemName); const create = await createCafe(itemName);
setModal('message', { setModal('message', {
returnMessage: create ? 'Berhasil membuat cafe' : 'Gagal membuat cafe' captMessage: create ? 'Berhasil membuat cafe' : 'Gagal membuat cafe'
}); });
// Add a 2-second delay before proceeding // Add a 2-second delay before proceeding