diff --git a/src/components/Header.js b/src/components/Header.js
index 9dea815..c1fee89 100644
--- a/src/components/Header.js
+++ b/src/components/Header.js
@@ -338,6 +338,8 @@ const Header = ({
Ubah profil
)}
+ {user.roleId == 0 && (
+ setModal('create_coupon', {})}>Buat Voucher)}
{shopId && user.roleId == 1 && (
Dashboard)}
{shopId &&
diff --git a/src/components/Modal.js b/src/components/Modal.js
index af7ae99..c8e5f95 100644
--- a/src/components/Modal.js
+++ b/src/components/Modal.js
@@ -19,12 +19,12 @@ import MaterialList from "../pages/MaterialList.js";
import MaterialMutationsPage from "../pages/MaterialMutationsPage.js";
import Reports from "../pages/Reports.js";
import NotificationRequest from "../pages/NotificationRequest.js";
-import Unavailable from "../pages/Unavailable.js";
import NotificationBlocked from "../pages/NotificationBlocked.js";
import WelcomePageEditor from "../pages/WelcomePageEditor.js";
import GuidePage from "../pages/GuidePage";
import Join from "../pages/Join";
import Loading from "../pages/Loading";
+import Message from "../pages/Message";
import Login from "../pages/Login";
import ResetPassword from "../pages/ResetPassword";
import { getImageUrl } from "../helpers/itemHelper.js";
@@ -76,7 +76,6 @@ const Modal = ({ user, shop, isOpen, onClose, modalContent, deviceType, setModal
{modalContent === "edit_account" && }
{modalContent === "reset-password" && }
{modalContent === "req_notification" && }
- {modalContent === "unavailable" && }
{modalContent === "blocked_notification" && }
{modalContent === "create_clerk" && }
{modalContent === "create_kedai" && }
@@ -124,6 +123,7 @@ const Modal = ({ user, shop, isOpen, onClose, modalContent, deviceType, setModal
{modalContent === "join" && }
{modalContent === "claim-coupon" && }
{modalContent === "loading" && }
+ {modalContent === "message" && }
);
diff --git a/src/components/StepByStep.js b/src/components/StepByStep.js
new file mode 100644
index 0000000..172d412
--- /dev/null
+++ b/src/components/StepByStep.js
@@ -0,0 +1,49 @@
+import React from 'react';
+import styles from './StepByStep.module.css'; // Import the CSS Module
+
+const StepByStep = () => {
+ return (
+
+
+
+

+
+
+
+
+

+

+
+
+

+

+
+
+

+
+
+
+
+

+
+
+
+ );
+};
+
+export default StepByStep;
diff --git a/src/components/StepByStep.module.css b/src/components/StepByStep.module.css
new file mode 100644
index 0000000..5ee410d
--- /dev/null
+++ b/src/components/StepByStep.module.css
@@ -0,0 +1,684 @@
+
+ .title {
+ color: #5C6AC4;
+ }
+ .container {
+ width: 188px;
+ height: 308px;
+ margin: 10px;
+ }
+ .screen {
+ width: 122px;
+ height: 264px;
+ background-color: #f0f0f0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 10px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
+ overflow: hidden;
+ position: relative;
+ z-index: 11;
+ }
+
+ .secondscreen {
+ width: 122px;
+ height: 264px;
+ background-color: #f0f0f0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 10px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
+ overflow: hidden;
+ position: relative;
+ left: 38%;
+ top: -62%;
+ z-index: 10;
+ }
+
+ .secondmain {
+ width: 100%;
+ height: 100%;
+ animation: reportScrollBottom 5s infinite; /* Apply scroll animation only once */
+ }
+ .secondmain img {
+ width: 100%;
+ }
+
+ @keyframes reportScrollBottom {
+ 0% {
+ transform: translateY(0%); /* Start from the top */
+ }
+ 30% {
+ transform: translateY(0%); /* Start from the top */
+ }
+ 50% {
+ transform: translateY(-43%); /* Start from the top */
+ }
+ 80% {
+ transform: translateY(-43%); /* Start from the top */
+ }
+ 100% {
+ transform: translateY(0%); /* Start from the top */
+ }
+ }
+
+ .main {
+ width: 100%;
+ height: 100%; /* Ensure the div fills the container */
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ animation: scrollBottom 20s infinite; /* Apply scroll animation only once */
+ position: absolute; /* Ensures it moves within the container */
+ background-color: white;
+ }
+
+ .main img{
+ width: 100%;
+ }
+
+ .main > div:nth-child(2) {
+ animation: playerClick 20s infinite;
+ }
+
+ .main > div:nth-child(3) {
+ animation: bodyDown 20s infinite;
+ }
+
+ /* Keyframes for scrolling the div content down */
+ @keyframes scrollBottom {
+ 0% {
+ transform: translateY(0); /* Start from the top */
+ }
+ 10% {
+ transform: translateY(0); /* Scale down at 20% */
+ }
+ 15% {
+ transform: translateY(-50%); /* Move the content up */
+ }
+ 57.5% {
+ transform: translateY(-50%); /* Move the content up */
+ }
+ 62.5% {
+ transform: translateY(0%); /* Move the content up */
+ }
+ 100% {
+ transform: translateY(0%); /* Move the content up */
+ }
+ }
+
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes playerClick {
+ 0% {
+ transform: scale(1); /* Initial scale */
+ }
+ 64% {
+ transform: scale(1); /* Initial scale */
+ }
+ 65% {
+ transform: scale(0.8); /* Scale down */
+ }
+ 66% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ 67% {
+ transform: scale(0.8); /* Scale down */
+ }
+ 68% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ 94% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ 95% {
+ transform: scale(0.8); /* Scale back to original size */
+ }
+ 96% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ 100% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes bodyDown {
+ 0% {
+ margin-top: 0%;
+ }
+ 64% {
+ margin-top: 0%;
+ }
+ 65% {
+ margin-top: 20%;
+ }
+ 66% {
+ margin-top: 20%;
+ }
+ 67% {
+ margin-top: 96%;
+ }
+ 90% {
+ margin-top: 96%;
+ }
+ 91% {
+ margin-top: 20%;
+ }
+ 97% {
+ margin-top: 20%;
+ }
+ 98% {
+ margin-top: 0%;
+ }
+ 100% {
+ margin-top: 0%;
+ }
+ }
+
+ .player img{
+ width: 100%;
+ }
+
+ .player > img:nth-child(1) {
+ animation: playerUnexpandedOpacity 20s infinite;
+ }
+
+ .player > img:nth-child(2) {
+ animation: player2ExpandedOpacity 20s infinite;
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+
+ .player > img:nth-child(3) {
+ animation: player3ExpandedOpacity 20s infinite;
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+
+ .player > img:nth-child(4) {
+ animation: player4ExpandedOpacity 20s infinite;
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes playerUnexpandedOpacity {
+ 0% {
+ filter: opacity(1); /* Initial scale */
+ }
+ 65% {
+ filter: opacity(1);
+ }
+ 66% {
+ filter: opacity(0);
+ }
+ 95% {
+ filter: opacity(0);
+ }
+ 96% {
+ filter: opacity(1);
+ }
+ 100% {
+ filter: opacity(1); /* Scale back to original size */
+ }
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes player2ExpandedOpacity {
+ 0% {
+ filter: opacity(0); /* Initial scale */
+ }
+ 65% {
+ filter: opacity(0);
+ }
+ 66% {
+ filter: opacity(1);
+ }
+ 67% {
+ filter: opacity(0); /* Scale back to original size */
+ }
+ 100% {
+ filter: opacity(0); /* Scale back to original size */
+ }
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes player3ExpandedOpacity {
+ 0% {
+ filter: opacity(0); /* Initial scale */
+ }
+ 66% {
+ filter: opacity(0);
+ }
+ 67% {
+ filter: opacity(1);
+ }
+ 90% {
+ filter: opacity(1);
+ }
+ 91% {
+ filter: opacity(0);
+ }
+ 100% {
+ filter: opacity(0); /* Scale back to original size */
+ }
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes player4ExpandedOpacity {
+ 0% {
+ filter: opacity(0); /* Initial scale */
+ }
+ 90% {
+ filter: opacity(0);
+ }
+ 91% {
+ filter: opacity(1);
+ }
+ 95% {
+ filter: opacity(1);
+ }
+ 97% {
+ filter: opacity(1);
+ }
+ 98% {
+ filter: opacity(0);
+ }
+ 100% {
+ filter: opacity(0); /* Scale back to original size */
+ }
+ }
+
+ .escappucino {
+ position: relative;
+ top: -63.6%;
+ width: 100%;
+ animation: escappucinoscaleAnimation 20s infinite; /* Apply the scale animation */
+ }
+
+ .escappucino img {
+ width: 100%;
+ }
+
+ .escappucino > img:nth-child(1) {
+ position: absolute;
+ animation: escappucinochildOpacityAnimation 20s infinite;
+ }
+
+ .escappucino > img:nth-child(2) {
+ animation: escappucinochildOpacityAnimation2 20s infinite;
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes escappucinoscaleAnimation {
+ 0% {
+ transform: scale(1); /* Initial scale */
+ }
+ 5% {
+ transform: scale(1); /* Initial scale */
+ }
+ 7.5% {
+ transform: scale(0.8); /* Scale down */
+ }
+ 10% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ 100% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ }
+
+ @keyframes escappucinochildOpacityAnimation {
+ 0% {
+ opacity: 1; /* Start visible */
+ }
+ 5% {
+ opacity: 1; /* Start visible */
+ }
+ 7.5% {
+ opacity: 0; /* Fade out at 70% */
+ }
+ 10% {
+ opacity: 0; /* Keep faded out */
+ }
+ 50% {
+ opacity: 0; /* Keep faded out */
+ }
+ 60% {
+ opacity: 1; /* Keep faded out */
+ }
+ 100% {
+ opacity: 1; /* Keep faded out */
+ }
+ }
+
+ @keyframes escappucinochildOpacityAnimation2 {
+ 0% {
+ opacity: 0; /* Start invisible */
+ }
+ 5% {
+ opacity: 0; /* Start invisible */
+ }
+ 7.5% {
+ opacity: 1; /* Fade in at 70% */
+ }
+ 10% {
+ opacity: 1; /* Keep visible */
+ }
+ 50% {
+ opacity: 1; /* Keep faded out */
+ }
+ 60% {
+ opacity: 0; /* Keep faded out */
+ }
+ 100% {
+ opacity: 0; /* Keep faded out */
+ }
+ }
+
+ .chickenkatsu {
+ position: relative;
+ top: -27.6%;
+ width: 100%;
+ animation: chickenkatsuscaleAnimation 20s infinite; /* Apply the scale animation */
+ }
+
+ .chickenkatsu img {
+ width: 100%;
+ }
+
+ .chickenkatsu > img:nth-child(1) {
+ position: absolute;
+ animation: chickenkatsuchildOpacityAnimation 20s infinite;
+ }
+
+ .chickenkatsu > img:nth-child(2) {
+ animation: chickenkatsuchildOpacityAnimation2 20s infinite;
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes chickenkatsuscaleAnimation {
+ 0% {
+ transform: scale(1); /* Initial scale */
+ }
+ 15% {
+ transform: scale(1); /* Initial scale */
+ }
+ 17.5% {
+ transform: scale(0.8); /* Scale down */
+ }
+ 20% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ 100% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ }
+
+ @keyframes chickenkatsuchildOpacityAnimation {
+ 0% {
+ opacity: 1; /* Start visible */
+ }
+ 15% {
+ opacity: 1; /* Start visible */
+ }
+ 17.5% {
+ opacity: 0; /* Fade out at 70% */
+ }
+ 20% {
+ opacity: 0; /* Keep faded out */
+ }
+ 50% {
+ opacity: 0; /* Keep faded out */
+ }
+ 60% {
+ opacity: 1; /* Keep faded out */
+ }
+ 100% {
+ opacity: 1; /* Keep faded out */
+ }
+ }
+
+ @keyframes chickenkatsuchildOpacityAnimation2 {
+ 0% {
+ opacity: 0; /* Start visible */
+ }
+ 15% {
+ opacity: 0; /* Start visible */
+ }
+ 17.5% {
+ opacity: 1; /* Fade out at 70% */
+ }
+ 20% {
+ opacity: 1; /* Keep faded out */
+ }
+ 50% {
+ opacity: 1; /* Keep faded out */
+ }
+ 60% {
+ opacity: 0; /* Keep faded out */
+ }
+ 100% {
+ opacity: 0; /* Keep faded out */
+ }
+ }
+
+ .cartbutton{
+ position: absolute;
+ width: 100%;
+ top: 86%;
+ animation: cartbuttonscaleAnimation 20s infinite; /* Apply the scale animation */
+ }
+
+ .cartbutton img {
+ width: 100%;
+ }
+
+ .cartbutton > img:nth-child(1) {
+ position: absolute;
+ animation: cartbuttonchildOpacityAnimation 20s infinite;
+ }
+
+ .cartbutton > img:nth-child(2) {
+ animation: cartbuttonchildOpacityAnimation2 20s infinite;
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes cartbuttonscaleAnimation {
+ 0% {
+ transform: scale(1); /* Initial scale */
+ filter: opacity(0);
+ }
+ 5% {
+ transform: scale(1); /* Initial scale */
+ filter: opacity(0);
+ }
+ 7.5% {
+ transform: scale(1); /* Initial scale */
+ filter: opacity(1);
+ }
+ 25% {
+ transform: scale(1); /* Initial scale */
+ }
+ 27.5% {
+ transform: scale(0.8); /* Scale down */
+ }
+ 30% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ 50% {
+ transform: scale(1); /* Scale back to original size */
+ filter: opacity(1);
+ }
+ 60% {
+ transform: scale(1); /* Scale back to original size */
+ filter: opacity(0);
+ }
+ 100% {
+ transform: scale(1); /* Scale back to original size */
+ filter: opacity(0);
+ }
+ }
+
+ @keyframes cartbuttonchildOpacityAnimation {
+ 0% {
+ opacity: 1; /* Start visible */
+ }
+ 15% {
+ opacity: 1; /* Start visible */
+ }
+ 17.5% {
+ opacity: 0; /* Fade out at 70% */
+ }
+ 20% {
+ opacity: 0; /* Keep faded out */
+ }
+ 100% {
+ opacity: 0; /* Keep faded out */
+ }
+ }
+
+ @keyframes cartbuttonchildOpacityAnimation2 {
+ 0% {
+ opacity: 0; /* Start invisible */
+ }
+ 15% {
+ opacity: 0; /* Start invisible */
+ }
+ 17.5% {
+ opacity: 1; /* Fade in at 70% */
+ }
+ 20% {
+ opacity: 1; /* Keep visible */
+ }
+ 100% {
+ opacity: 1; /* Keep visible */
+ }
+ }
+
+
+ .cart{
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ left: 100%;
+ animation: cartslideinAnimation 20s infinite; /* Apply the scale animation */
+ }
+
+ .cart > img:nth-child(1) {
+ width: 100%;
+ height: 100%;
+ }
+
+ .cart > img:nth-child(2) {
+ width: 100%;
+ position: absolute;
+ top: 90.7%;
+ left: 0;
+ animation: checkoutbuttonscaleAnimation 20s infinite; /* Apply the scale animation */
+ }
+
+ @keyframes cartslideinAnimation {
+ 0% {
+ left: 100%;
+ }
+ 30% {
+ left: 100%;
+ }
+ 32.5% {
+ left: 0%;
+ }
+ 55% {
+ left: 0%;
+ }
+ 57.5% {
+ left: 100%;
+ }
+ 100% {
+ left: 100%;
+ }
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes checkoutbuttonscaleAnimation {
+ 0% {
+ transform: scale(1); /* Initial scale */
+ }
+ 37.5% {
+ transform: scale(1); /* Initial scale */
+ }
+ 40% {
+ transform: scale(0.8); /* Scale down */
+ }
+ 42.5% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ 100% {
+ transform: scale(1); /* Scale back to original size */
+ }
+ }
+
+ .transaction{
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ animation: transactionAnimation 20s infinite;
+ background-color: #0000006b;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .transaction img {
+ width: 80%;
+ animation: transactionElementAnimation 20s infinite;
+ }
+
+ /* New keyframes for scaling and opacity effect */
+ @keyframes transactionAnimation {
+ 0% {
+ filter: opacity(0);
+ }
+ 42.5% {
+ filter: opacity(0);
+ }
+ 45% {
+ filter: opacity(1);
+ }
+ 52.5% {
+ filter: opacity(1);
+ }
+ 55% {
+ filter: opacity(0);
+ }
+ 100% {
+ filter: opacity(0);
+ }
+ }
+ /* New keyframes for scaling and opacity effect */
+ @keyframes transactionElementAnimation {
+ 0% {
+ transform: scale(0); /* Initial scale */
+ }
+ 42.5% {
+ transform: scale(0); /* Initial scale */
+ }
+ 45% {
+ transform: scale(1); /* Scale down */
+ }
+ 52.5% {
+ transform: scale(1); /* Scale down */
+ }
+ 55% {
+ transform: scale(0); /* Scale down */
+ }
+ 100% {
+ transform: scale(0); /* Scale back to original size */
+ }
+ }
\ No newline at end of file
diff --git a/src/components/Watermark.js b/src/components/Watermark.js
new file mode 100644
index 0000000..bd0a07c
--- /dev/null
+++ b/src/components/Watermark.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import StepByStep from './StepByStep';
+
+const Watermark = ({dontShowName}) => {
+ return (
+
+ {!dontShowName &&
KEDAIMASTER.COM
}
+
+
Gak perlu rasain antri panjang yang bikin bosen lagi. Tinggal scan QR yang ada di meja, eh tiba tiba pesanan udah dimejamu
+
+
+
© 2025 KEDIRITECHNOPARK.COM
+
+ );
+};
+
+export default Watermark;
diff --git a/src/pages/CafePage.js b/src/pages/CafePage.js
index bbd8536..4caf299 100644
--- a/src/pages/CafePage.js
+++ b/src/pages/CafePage.js
@@ -10,6 +10,7 @@ import {
import "../App.css";
+import Watermark from "../components/Watermark";
import { getImageUrl, createItem, updateItem, moveItemType } from "../helpers/itemHelper.js";
import SearchInput from "../components/SearchInput";
import ItemTypeLister from "../components/ItemTypeLister";
@@ -139,7 +140,7 @@ function CafePage({
socket.on("joined-room", (response) => {
const { isSpotifyNeedLogin, isExceededDeadline } = response;
setNeedSpotifyLogin(isSpotifyNeedLogin);
- if (isExceededDeadline) setModal('unavailable');
+ if (isExceededDeadline) setModal('message',{returnMessage:'Kafe sedang tidak tersedia'});
setIsExceededDeadline(isExceededDeadline);
});
}
@@ -210,8 +211,8 @@ function CafePage({
/>
) : (
welcomePageConfig != null && (
-
)
)}
diff --git a/src/pages/Dashboard.js b/src/pages/Dashboard.js
index c15dfea..5532942 100644
--- a/src/pages/Dashboard.js
+++ b/src/pages/Dashboard.js
@@ -14,6 +14,7 @@ import API_BASE_URL from '../config';
import DailyCharts from '../components/DailyCharts';
import Coupon from '../components/Coupon';
import Reports from './Reports'
+import Watermark from '../components/Watermark.js';
const LinktreePage = ({ user, setModal }) => {
const navigate = useNavigate();
@@ -297,7 +298,7 @@ const LinktreePage = ({ user, setModal }) => {
{getLocalStorage('auth') == null && (
+
)}
>
diff --git a/src/pages/Join.js b/src/pages/Join.js
index d3f448e..3b985c2 100644
--- a/src/pages/Join.js
+++ b/src/pages/Join.js
@@ -78,6 +78,8 @@ const LinktreePage = ({ data, setModal }) => {
// Handle manual coupon code check
const handleLogCouponForUser = async (code = couponCode) => {
const result = await logCouponForUser(code); // Call the helper
+
+ return result.success;
};
// Listen for query parameter changes (using the `location` object)
@@ -106,20 +108,11 @@ const LinktreePage = ({ data, setModal }) => {
Daftarkan kedaimu sekarang dan mulai gunakan semua fitur unggulan kami.
-