This commit is contained in:
nospeedlimitindonesia
2024-10-09 04:35:15 +00:00
parent 1da45c528d
commit 624a9e8ec8
8 changed files with 267 additions and 184 deletions

View File

@@ -53,6 +53,7 @@ const ItemLister = ({
const [editedTypeName, setEditedTypeName] = useState(typeName); const [editedTypeName, setEditedTypeName] = useState(typeName);
const typeNameInputRef = useRef(null); const typeNameInputRef = useRef(null);
const handlePlusClick = (itemId) => { const handlePlusClick = (itemId) => {
const updatedItems = items.map((item) => { const updatedItems = items.map((item) => {
if (item.itemId === itemId) { if (item.itemId === itemId) {
@@ -124,6 +125,14 @@ const ItemLister = ({
} }
}; };
useEffect(() => {
if(beingEditedType == itemTypeId)return;
setOnEditItem(0);
setIsAddingNewItem(false);
console.log(itemTypeId)
}, [beingEditedType]);
const toggleAddNewItem = () => { const toggleAddNewItem = () => {
setIsAddingNewItem((prev) => !prev); setIsAddingNewItem((prev) => !prev);
setOnEditItem(0); setOnEditItem(0);
@@ -184,16 +193,13 @@ const ItemLister = ({
return ( return (
<> <>
{(items.length > 0 || {(items.length > 0 ||
(user && user.roleId == 1 && user.userId == shopOwnerId)) && ( (user && (user.cafeId == shopId || user.userId == shopOwnerId))) && (
<div className={styles["item-lister"]}> <div className={styles["item-lister"]}>
{!raw && ( {!raw && (
<div className={styles["title-container"]}> <div className={styles["title-container"]}>
<input <input
ref={typeNameInputRef} ref={typeNameInputRef}
className={`${styles.title} ${ className={`${styles.title} ${
user &&
user.roleId == 1 &&
user.userId == shopOwnerId &&
isEdit isEdit
? styles.border ? styles.border
: styles.noborder : styles.noborder
@@ -202,10 +208,7 @@ const ItemLister = ({
onChange={(e) => setEditedTypeName(e.target.value)} onChange={(e) => setEditedTypeName(e.target.value)}
disabled={!isEdit} disabled={!isEdit}
/> />
{isEditMode && {isEditMode && (
user &&
user.roleId == 1 &&
user.userId == shopOwnerId && (
<> <>
<button <button
className={styles["edit-typeItem-button"]} className={styles["edit-typeItem-button"]}
@@ -271,7 +274,8 @@ const ItemLister = ({
</button> </button>
)} )}
<div className={styles["itemWrapper"]}> <div className={styles["itemWrapper"]}>
{isEditMode && onEditItem != item.itemId && ( {isEditMode && onEditItem != item.itemId&&
(
<div className={styles["editModeLayout"]}> <div className={styles["editModeLayout"]}>
{isEditMode && ( {isEditMode && (
<Switch <Switch
@@ -302,8 +306,7 @@ const ItemLister = ({
onNegativeClick={() => handleNegativeClick(item.itemId)} onNegativeClick={() => handleNegativeClick(item.itemId)}
onRemoveClick={() => handleRemoveClick(item.itemId)} onRemoveClick={() => handleRemoveClick(item.itemId)}
isBeingEdit={ isBeingEdit={
onEditItem == item.itemId && onEditItem == item.itemId
beingEditedType == itemTypeId
} }
isAvailable={item.availability} isAvailable={item.availability}
handleUpdateItem={(name, price, image) => handleUpdateItem={(name, price, image) =>

View File

@@ -13,12 +13,14 @@ const ItemTypeLister = ({
onFilterChange, onFilterChange,
filterId, filterId,
isEditMode, isEditMode,
beingEditedType,
setBeingEditedType,
}) => { }) => {
const [isAddingNewItem, setIsAddingNewItem] = useState(false); const [isAddingNewItem, setIsAddingNewItem] = useState(false);
const newItemDivRef = useRef(null); const newItemDivRef = useRef(null);
const [items, setItems] = useState([]); const [items, setItems] = useState([]);
const [itemTypeName, setItemTypeName] = useState(''); const [itemTypeName, setItemTypeName] = useState("");
const handleCreateItem = (name, price, selectedImage, previewUrl) => { const handleCreateItem = (name, price, selectedImage, previewUrl) => {
console.log(previewUrl); console.log(previewUrl);
const newItem = { const newItem = {
@@ -120,7 +122,7 @@ const ItemTypeLister = ({
<input <input
className="item-type-name" className="item-type-name"
value={itemTypeName} value={itemTypeName}
onChange={(e)=>setItemTypeName(e.target.value)} onChange={(e) => setItemTypeName(e.target.value)}
placeholder="type name" placeholder="type name"
style={{ marginLeft: "10px" }} // Adjust spacing as needed style={{ marginLeft: "10px" }} // Adjust spacing as needed
/> />
@@ -236,6 +238,8 @@ const ItemTypeLister = ({
isEditMode={true} isEditMode={true}
raw={true} raw={true}
handleCreateItem={handleCreateItem} handleCreateItem={handleCreateItem}
beingEditedType={beingEditedType}
setBeingEditedType={setBeingEditedType}
/> />
<button onClick={toggleAddNewItem} className="add-button"> <button onClick={toggleAddNewItem} className="add-button">
back back

View File

@@ -6,83 +6,89 @@ img {
} */ } */
.roulette-wheel-container { .roulette-wheel-container {
position: fixed; position: fixed;
left: 50%; left: 50%;
/* Center the container horizontally */ /* Center the container horizontally */
top: 30%; top: 30%;
transform: translate(-40%, 20%); transform: translate(-40%, 20%);
scale: 3; scale: 3;
max-width: 100vw; max-width: 100vw;
/* Limit container width to viewport width */ /* Limit container width to viewport width */
max-height: 100vh; max-height: 100vh;
/* Limit container height to viewport height */ /* Limit container height to viewport height */
overflow: hidden; overflow: hidden;
/* Hide overflowing content */ /* Hide overflowing content */
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
pointer-events: none; pointer-events: none;
-webkit-user-select: none; -webkit-user-select: none;
/* Safari */ /* Safari */
-ms-user-select: none; -ms-user-select: none;
/* IE 10 and IE 11 */ /* IE 10 and IE 11 */
user-select: none; user-select: none;
/* Standard syntax */ /* Standard syntax */
} }
.roulette-wheel { .roulette-wheel {
width: 300px; width: 300px;
height: 300px; height: 300px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
pointer-events: auto; pointer-events: auto;
border-radius: 50%; border-radius: 50%;
transition: transform 0.2s ease-out; transition: transform 0.2s ease-out;
} }
.roulette-image { .roulette-image {
width: 200px; width: 200px;
height: 200px; height: 200px;
user-select: none; user-select: none;
/* Prevents the image from being selected */ /* Prevents the image from being selected */
pointer-events: none; pointer-events: none;
} }
.roulette-input { .roulette-input {
position: absolute; position: absolute;
width: 30%; width: 30%;
/* Increase size for better visibility */ /* Increase size for better visibility */
height: auto; height: auto;
/* Increase size for better visibility */ /* Increase size for better visibility */
border: none; border: none;
/* Remove border for simplicity */ /* Remove border for simplicity */
border-radius: 5px; border-radius: 5px;
/* Add border radius for rounded corners */ /* Add border radius for rounded corners */
color: rgb(2, 2, 2); color: rgb(2, 2, 2);
/* Text color */ /* Text color */
font-size: 16px; font-size: 16px;
/* Font size */ /* Font size */
border: 2px solid #ccc; border: 2px solid #ccc;
} }
.roulette-button { .roulette-button {
z-index: 100; z-index: 100;
position: absolute; position: absolute;
width: 30%; width: 30%;
/* Increase size for better visibility */ height: auto;
height: auto; border: none;
/* Increase size for better visibility */ border-radius: 5px;
border: none; color: rgb(2, 2, 2);
/* Remove border for simplicity */ font-size: 16px;
border-radius: 5px; border: 2px solid #ccc;
/* Add border radius for rounded corners */ background-color: #fff;
color: rgb(2, 2, 2);
/* Text color */
font-size: 16px;
/* Font size */
border: 2px solid #ccc;
} }
.roulette-button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.roulette-button.error {
background-color: red; /* Change button color on error */
transition: background-color 0.5s ease-in-out;
}
.hidden { .hidden {
display: none; display: none;
} }

View File

@@ -2,7 +2,9 @@ import React, { useState, useRef, useEffect } from "react";
import "./RouletteWheel.css"; import "./RouletteWheel.css";
import coffeeImage from "./coffee.png"; // Update the path to your image import coffeeImage from "./coffee.png"; // Update the path to your image
const RouletteWheel = ({ isForRegister, onSign }) => { import { ThreeDots } from "react-loader-spinner";
const RouletteWheel = ({ isForRegister, onSignIn, onSignUp }) => {
const [rotation, setRotation] = useState(0); const [rotation, setRotation] = useState(0);
const [isDragging, setIsDragging] = useState(false); const [isDragging, setIsDragging] = useState(false);
const startAngleRef = useRef(0); const startAngleRef = useRef(0);
@@ -12,21 +14,32 @@ const RouletteWheel = ({ isForRegister, onSign }) => {
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const emailInputRef = useRef(null); const emailInputRef = useRef(null);
const usernameInputRef = useRef(null); const usernameInputRef = useRef(null);
const passwordInputRef = useRef(null); const passwordInputRef = useRef(null);
const handleSign = () => { const handleSignIn = () => {
onSign(email, username, password); setError(false); // Reset error state before login attempt
onSignIn(email, username, password, setLoading, setError);
}; };
const handleSignUp = () => {
setError(false); // Reset error state before login attempt
onSignUp(email, username, password, setLoading, setError);
};
const handleStart = (x, y) => { const handleStart = (x, y) => {
setIsDragging(true); setIsDragging(true);
startAngleRef.current = getAngle(x, y); startAngleRef.current = getAngle(x, y);
startRotationRef.current = rotation; startRotationRef.current = rotation;
}; };
useEffect(() => {
setError(false);
}, [error]);
const handleMove = (x, y) => { const handleMove = (x, y) => {
if (isDragging) { if (isDragging) {
const angle = getAngle(x, y); const angle = getAngle(x, y);
@@ -153,87 +166,89 @@ const RouletteWheel = ({ isForRegister, onSign }) => {
onTouchStart={handleTouchStart} onTouchStart={handleTouchStart}
style={{ transform: `rotate(${rotation}deg)` }} style={{ transform: `rotate(${rotation}deg)` }}
> >
{!isForRegister ? ( <input
<> className={`roulette-input ${
<input isVisible(rotation % 360 !== -0) ? "" : "hidden"
className={`roulette-input ${ }`}
isVisible(rotation % 360 !== -0) ? "" : "hidden" placeholder="Username"
}`} value={username}
placeholder="Username" onChange={(e) => setUsername(e.target.value)}
value={username} ref={usernameInputRef}
onChange={(e) => setUsername(e.target.value)} style={{ transform: "translate(60%, -220%) rotate(0deg)" }}
ref={usernameInputRef} />
style={{ transform: "translate(90%, -120%) rotate(0deg)" }} <input
/> className={`roulette-input ${
<input isVisible(rotation % 360 !== -0) ? "" : "hidden"
className={`roulette-input ${ }`}
isVisible(rotation % 360 !== -90) ? "" : "hidden" placeholder="Password"
}`} type="password"
placeholder="Password" value={password}
type="password" onChange={(e) => setPassword(e.target.value)}
value={password} ref={passwordInputRef}
onChange={(e) => setPassword(e.target.value)} style={{ transform: "translate(90%, -90%) rotate(0deg)" }}
ref={passwordInputRef} />
style={{ transform: "translate(30%, 350%) rotate(90deg)" }} <button
/> className={`roulette-button ${error ? "error" : ""} ${
<button isVisible(rotation % 360 !== -0) ? "" : "hidden"
className={`roulette-input ${ }`}
isVisible(rotation % 360 !== -90) ? "" : "hidden" disabled={loading}
}`} onClick={handleSignIn}
onClick={handleSign} onMouseDown={handleChildMouseDown}
onMouseDown={handleChildMouseDown} onTouchStart={handleChildTouchStart}
onTouchStart={handleChildTouchStart} style={{ transform: "translate(110%, -10%) rotate(0deg)" }}
style={{ transform: "translate(10%, 320%) rotate(90deg)" }} >
> {loading ? (
Sign in <ThreeDots color="black" height={15} width={40} /> // Show loader when loading
</button> ) : (
</> "Sign in"
) : ( )}
<> </button>
<input <input
className={`roulette-input ${ className={`roulette-input ${
isVisible(rotation % 360 !== -0) ? "" : "hidden" isVisible(rotation % 360 !== -90) ? "" : "hidden"
}`} }`}
placeholder="Email" placeholder="Email"
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
ref={emailInputRef} ref={emailInputRef}
style={{ transform: "translate(90%, -120%) rotate(0deg)" }} style={{ transform: "translate(30%, 320%) rotate(90deg)" }}
/> />
<input <input
className={`roulette-input ${ className={`roulette-input ${
isVisible(rotation % 360 !== -90) ? "" : "hidden" isVisible(rotation % 360 !== -90) ? "" : "hidden"
}`} }`}
placeholder="Username" placeholder="Username"
value={username} value={username}
onChange={(e) => setUsername(e.target.value)} onChange={(e) => setUsername(e.target.value)}
ref={usernameInputRef} ref={usernameInputRef}
style={{ transform: "translate(30%, 350%) rotate(90deg)" }} style={{ transform: "translate(10%, 320%) rotate(90deg)" }}
/> />
<input <input
className={`roulette-input ${ className={`roulette-input ${
isVisible(rotation % 360 !== -180) ? "" : "hidden" isVisible(rotation % 360 !== -90) ? "" : "hidden"
}`} }`}
placeholder="Password" placeholder="Password"
type="password" type="password"
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
ref={passwordInputRef} ref={passwordInputRef}
style={{ transform: "translate(-90%, 115%) rotate(180deg)" }} style={{ transform: "translate(-10%, 320%) rotate(90deg)" }}
/> />
<button <button
className={`roulette-button ${ className={`roulette-button ${error ? "error" : ""} ${
isVisible(rotation % 360 !== -180) ? "" : "hidden" isVisible(rotation % 360 !== -90) ? "" : "hidden"
}`} } `}
onClick={handleSign} onClick={handleSignUp}
onMouseDown={handleChildMouseDown} onMouseDown={handleChildMouseDown}
onTouchStart={handleChildTouchStart} onTouchStart={handleChildTouchStart}
style={{ transform: "translate(-90%, 30%) rotate(180deg)" }} style={{ transform: "translate(-60%, 320%) rotate(90deg)" }}
> >
Sign up {loading ? (
</button> <ThreeDots color="black" height={15} width={40} /> // Show loader when loading
</> ) : (
)} "Sign Up"
)}
</button>
<img src={coffeeImage} className="roulette-image" alt="Coffee" /> <img src={coffeeImage} className="roulette-image" alt="Coffee" />
</div> </div>
</div> </div>

View File

@@ -1,5 +1,5 @@
// src/config.js // src/config.js
const API_BASE_URL = "https://3nvnzs-5000.csb.app"; // Replace with your actual backend URL const API_BASE_URL = "https://yjgyr4-5000.csb.app"; // Replace with your actual backend URL
export default API_BASE_URL; export default API_BASE_URL;

View File

@@ -94,6 +94,31 @@ export async function removeConnectedGuestSides(guestSideSessionId) {
} }
return { ok: false }; return { ok: false };
} }
export const signUpUser = async (email, username, password) => {
try {
const response = await fetch(API_BASE_URL + `/user/signup`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ email, username, password }),
});
console.log(username, password);
const responseData = await response.json();
if (response.ok) {
return {
success: true,
token: responseData.token,
};
} else {
return { success: false, token: null };
}
} catch (error) {
console.error("Error occurred while logging in:", error.message);
return { success: false, token: null };
}
};
export const loginUser = async (username, password) => { export const loginUser = async (username, password) => {
try { try {

View File

@@ -183,6 +183,8 @@ function CafePage({
isEditMode={isEditMode} isEditMode={isEditMode}
onFilterChange={(e) => setFilterId(e)} onFilterChange={(e) => setFilterId(e)}
filterId={filterId} filterId={filterId}
beingEditedType={beingEditedType}
setBeingEditedType={setBeingEditedType}
/> />
<div style={{ marginTop: "-13px" }}></div> <div style={{ marginTop: "-13px" }}></div>
{filterId === 0 ? ( {filterId === 0 ? (

View File

@@ -1,19 +1,25 @@
import React from "react"; import React, { useState } from "react";
import { useNavigate, useLocation } from "react-router-dom"; import { useNavigate, useLocation } from "react-router-dom";
import "./LoginPage.css"; import "./LoginPage.css";
import RouletteWheel from "../components/RouletteWheel"; import RouletteWheel from "../components/RouletteWheel";
import { loginUser } from "../helpers/userHelpers"; // Import from userHelper.js import { loginUser, signUpUser } from "../helpers/userHelpers";
const LoginPage = () => { const LoginPage = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation(); // Use useLocation hook instead of useSearchParams const location = useLocation();
const searchParams = new URLSearchParams(location.search); // Pass location.search directly const searchParams = new URLSearchParams(location.search);
const next = searchParams.get("next"); const next = searchParams.get("next");
const table = searchParams.get("table"); const table = searchParams.get("table");
const handleLogin = async (email, username, password) => { const handleLogin = async (
email,
username,
password,
setLoading,
setError
) => {
try { try {
setLoading(true);
const response = await loginUser(username, password); const response = await loginUser(username, password);
if (response.success) { if (response.success) {
@@ -23,38 +29,60 @@ const LoginPage = () => {
window.location.href = response.cafeId; window.location.href = response.cafeId;
} else { } else {
let destination = "/"; let destination = "/";
// Validate parameters and construct the destination URL
if (table && !next) { if (table && !next) {
console.error( console.error('Parameter "table" requires "next" to be present.');
'Parameter "table" requires "next" to be present in the URL.',
);
// Navigate to a default route or handle this case as needed
navigate("/"); navigate("/");
return; return;
} }
if (next) { if (next) {
destination = `/${next}`; destination = `/${next}`;
if (table) { if (table) destination += `?table=${table}`;
destination += `?table=${table}`;
}
} }
// navigate(destination, { replace: true });
window.location.href = destination; window.location.href = destination;
} }
} else { } else {
setError(true); // Trigger error state in the button
console.error("Login failed"); console.error("Login failed");
} }
} catch (error) { } catch (error) {
setError(true);
console.error("Error occurred while logging in:", error.message); console.error("Error occurred while logging in:", error.message);
} finally {
setLoading(false); // Ensure loading state is cleared
}
};
const handleSignUp = async (
email,
username,
password,
setLoading,
setError
) => {
try {
setLoading(true);
const response = await signUpUser(email, username, password);
if (response.success) {
localStorage.setItem("auth", response.token);
let destination = "/";
window.location.href = destination;
} else {
setError(true); // Trigger error state in the button
console.error("Login failed");
}
} catch (error) {
setError(true);
console.error("Error occurred while logging in:", error.message);
} finally {
setLoading(false); // Ensure loading state is cleared
} }
}; };
return ( return (
<div className="login-container"> <div className="login-container">
<RouletteWheel onSign={handleLogin} /> <RouletteWheel onSignIn={handleLogin} onSignUp={handleSignUp} />
</div> </div>
); );
}; };