2
\$\begingroup\$

I build project Case opening simulator in React JS + tailwind. I am looking for maybe another way to implement the structure of code and tell me if I've done something wrong, what I should do better or to add something more.

 import React, { useState, useEffect } from 'react';
import ResultDisplay from './ResultDisplay';
import MenuButton from './MenuButton';
import Instructions from './Instructions';
import Controls from './Controls';
import { calculateResponsiveSizes } from './ResponsiveUtils';
const CaseOpener = () => {
 const itemsAmount = 100;
 const [ItemsList, setItemsList] = useState([]);
 const [elementWidth, setElementWidth] = useState(200);
 const [reelContainerWidth, setReelContainerWidth] = useState(1000);
 const [winningItem, setWinningItem] = useState(null);
 const [reelItems, setReelItems] = useState([]);
 const [isOpening, setIsOpening] = useState(false);
 const [hasOpened, setHasOpened] = useState(false);
 const [selectedCase, setselectedCase] = useState(null);
 const [randomSpin, setRandomSpin] = useState(0);
 const spinDuration = 10;
 const minSpin = -13000;
 const maxSpin = -12050;
 const baseRandomSpin = Math.floor(Math.random() * (maxSpin - minSpin + 1)) + minSpin;
// loading skin data
 const goToCase = () => {
 setselectedCase(true);
 };
 
// window size change chandler
useEffect(() => {
 const handleResize = () => {
 if (!isOpening) { // tylko gdy nie jest w trakcie otwierania
 calculateResponsiveSizes(setElementWidth, setReelContainerWidth, setRandomSpin, baseRandomSpin);
 }
 };
 handleResize();
 window.addEventListener('resize', handleResize);
 return () => window.removeEventListener('resize', handleResize);
}, [isOpening, baseRandomSpin]);
const openCase = async () => {
 setIsOpening(true);
 setHasOpened(false);
 const baseElementWidth = 200;
 const newRandomSpin = (baseRandomSpin * elementWidth) / baseElementWidth;
 setRandomSpin(newRandomSpin);
 try {
 const response = await fetch('http://localhost:5000/open-case-batch');
 const data = await response.json();
 setItemsList(data);
 console.log("Wylosowane przedmioty:", data);
 
 const generatedItems = [];
 for(let i = 0; i < itemsAmount; i++) {
 generatedItems.push(data[i]);
 }
 setReelItems(generatedItems);
 
 console.log("-----\\\\\\\\\\\\\\\\\\\\\\\\\\-----");
 const OFFSET_ELEMENTS = -2;
 const OFFSET_PX = OFFSET_ELEMENTS * elementWidth;
 // calc index of winning item
 const index = Math.floor((-newRandomSpin - OFFSET_PX + elementWidth / 2) / elementWidth);
 console.log("randomSpin:", randomSpin);
 console.log("elementWidth:", elementWidth);
 console.log("winning index:", index);
 setWinningItem(generatedItems[index]);
 console.log("winning item: ", generatedItems[index]?.skin_name); // Changed from 'name' to 'skin_name'
 console.log("Posibble floats: ",generatedItems[index].float_min," - ",(generatedItems[index].float_max));
 console.log("Skin float: ",generatedItems[index].float);
 console.log(generatedItems[index].condition);
 // console.log(winningItem);
 setTimeout(() => {
 setIsOpening(false);
 setHasOpened(true);
 }, spinDuration * 1000);
 } catch (error) {
 console.error("Błąd podczas pobierania przedmiotów:", error);
 setIsOpening(false);
 }
};
 //delete
const Calculator = () => {
 useEffect(() => {
 const calculate = async () => {
 try {
 const response = await fetch('http://localhost:5000/calculate');
 const data = await response.json();
 console.log('Wynik z backendu:', data);
 } catch (error) {
 console.error('error loading file:', error);
 }
 };
 calculate();
 }, []);
 return null; // nic nie renderuje
};
 const resetCase = () => {
 setIsOpening(false);
 setHasOpened(false);
 setReelItems([]);
 };
 const generateReel = () => {
 if (reelItems.length === 0) {
 return [];
 }
 const items = [];
 for (let i = 0; i < reelItems.length; i++) {
 const item = reelItems[i];
 items.push(
 <div
 key={i}
 className="flex-shrink-0 bg-gradient-to-br from-gray-600 to-[#4a90e2] rounded-lg
 border border-gray-700 flex items-center justify-center shadow-lg"
 style={{ 
 width: `${elementWidth}px`,
 height: `${elementWidth * 0.8}px`
 }}
 > 
 <img
 src={item.image_url}
 alt={item.skin_name}
 className="object-cover rounded-md"
 style={{
 width: `${elementWidth * 0.7}px`,
 height: `${elementWidth * 0.56}px`
 }}
 /> 
 </div>
 );
 }
 return items;
 };
 return (
 <>
 <div className="h-20 flex items-center relative overflow-hidden bg-[#26262B] justify-center">
 <div className="hidden sm:flex">
 <MenuButton>Menu</MenuButton>
 <MenuButton>Daily bonus</MenuButton>
 <MenuButton>Contracts</MenuButton>
 <MenuButton>Market</MenuButton>
 <MenuButton>Inventory</MenuButton>
 </div>
 <div className="sm:hidden">
 <MenuButton>☰</MenuButton>
 </div>
 </div>
 <div className="min-h-[calc(100vh-5rem)] flex items-center justify-center
 relative overflow-hidden bg-[#1a1a1a] border-t border-black px-4">
 <div className="bg-[#2a2a2a] rounded-2xl shadow-2xl p-4 sm:p-8 lg:p-16 w-full max-w-7xl
 border-2 border-[#1a1a2a]">
 <h1 className="text-2xl sm:text-3xl lg:text-4xl font-bold text-center mb-8 text-[#f8f9fa]">
 Case Opening
 </h1>
 {!selectedCase && (
 <div className="mb-8 text-center">
 <label className="inline-block bg-[#f39c12]
 hover:bg-[#e67e22] text-white font-bold py-3 px-6 rounded-lg cursor-pointer transition-colors duration-200
 border-2 border-[#f39c12]
 transform hover:scale-105" onClick={goToCase}
 >
 Select this case
 </label>
 </div>
 )}
 {/* Case Opening Area */}
 {selectedCase && (
 <div className="mb-8">
 {/* Reel Container */}
 <div className="relative bg-[#333333] rounded-xl p-4 sm:p-8 lg:p-16 mb-6 overflow-hidden flex justify-center">
 {/* Selection Line */}
 <div 
 id='marker' 
 className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-0.5 bg-[#4a90e2] z-10 shadow-lg"
 style={{ height: `${elementWidth * 0.8}px` }}
 ></div>
 
 {/* Reel */}
 <div 
 id='koniec' 
 style={{ width: `${elementWidth * 5}px`,height: `${elementWidth * 0.8}px` }} 
 className="relative overflow-hidden"
 >
 <div
 className={`flex ${isOpening ? 'animate-spin-reel' : ''}`}
 >
 {generateReel()}
 </div>
 </div>
 </div>
 <Controls
 onOpen={openCase}
 onReset={resetCase}
 onChangeImage={() => setselectedCase(null)}
 isOpening={isOpening}
 />
 <ResultDisplay hasOpened={hasOpened} winningItem={winningItem}></ResultDisplay>
 </div>
 )}
 <Instructions selectedCase={selectedCase} />
 </div>
 <style jsx>{`
 @keyframes spin-reel {
 0% { transform: translateX(0px); }
 100% { transform: translateX(${randomSpin}px); }
 }
 .animate-spin-reel {
 animation: spin-reel 9.5s cubic-bezier(0.33, 1, 0.68, 1) forwards; 
}
 `}</style>
 </div>
 </>
 );
};
export default CaseOpener;

ResponsiveUtils.jsx:

export const calculateResponsiveSizes = (
 setElementWidth,
 setReelContainerWidth,
 setRandomSpin,
 baseRandomSpin
) => {
 const screenWidth = window.innerWidth;
 let newElementWidth;
 let newContainerWidth;
 if (screenWidth < 640) {
 newElementWidth = 120;
 newContainerWidth = screenWidth * 0.8;
 } else if (screenWidth < 1024) {
 console.log("tablet");
 newElementWidth = 150;
 newContainerWidth = screenWidth * 0.7;
 } else if (screenWidth < 1296) {
 console.log("pc small screen");
 newElementWidth = 170;
 newContainerWidth = screenWidth * 0.7;
 } else {
 console.log("pc");
 newElementWidth = 200;
 newContainerWidth = 1000;
 }
 setElementWidth(newElementWidth);
 setReelContainerWidth(newContainerWidth);
 const baseElementWidth = 200;
 const newRandomSpin = (baseRandomSpin * newElementWidth) / baseElementWidth;
 setRandomSpin(newRandomSpin);
};
asked Jul 15 at 11:26
\$\endgroup\$
1
  • \$\begingroup\$ I think it should be possible to make the game responsive entirely in CSS. \$\endgroup\$ Commented Jul 22 at 10:39

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.