From 599dc379264b7846dd4b59935e04fcca6a10ccf6 Mon Sep 17 00:00:00 2001 From: MaksSlyzar Date: Sun, 29 Mar 2026 09:54:47 +0300 Subject: [PATCH] package.json, mobile version --- .../views/GameInterface/tabs/ItemListTab.jsx | 140 ++++++-------- .../GameInterface/tabs/styles/ItemListTab.css | 182 ++++++++---------- package.json | 14 ++ 3 files changed, 158 insertions(+), 178 deletions(-) create mode 100644 package.json diff --git a/client/src/views/GameInterface/tabs/ItemListTab.jsx b/client/src/views/GameInterface/tabs/ItemListTab.jsx index b7d5883..e1dc69f 100644 --- a/client/src/views/GameInterface/tabs/ItemListTab.jsx +++ b/client/src/views/GameInterface/tabs/ItemListTab.jsx @@ -8,26 +8,30 @@ const ItemListTab = () => { const [searchQuery, setSearchQuery] = useState(""); const [selectedCategory, setSelectedCategory] = useState("all"); const [selectedItem, setSelectedItem] = useState(null); + const [isMobile, setIsMobile] = useState(window.innerWidth <= 768); const ASSET_BASE_URL = "http://localhost:5003/static/"; useEffect(() => { + const handleResize = () => setIsMobile(window.innerWidth <= 768); + window.addEventListener("resize", handleResize); + const itemsArray = Array.from(GameDataManager.items.keys()).map((id) => GameDataManager.getItem(id), ); setAllItems(itemsArray); setFilteredItems(itemsArray); + + return () => window.removeEventListener("resize", handleResize); }, []); useEffect(() => { let result = allItems; - if (selectedCategory !== "all") { result = result.filter( (item) => item.meta?.category === selectedCategory, ); } - if (searchQuery) { const q = searchQuery.toLowerCase(); result = result.filter( @@ -36,7 +40,6 @@ const ItemListTab = () => { item.id.toLowerCase().includes(q), ); } - setFilteredItems(result); }, [searchQuery, selectedCategory, allItems]); @@ -50,19 +53,72 @@ const ItemListTab = () => { ...new Set(allItems.map((i) => i.meta?.category).filter(Boolean)), ]; + const renderInspector = () => ( +
isMobile && setSelectedItem(null)} + > + {selectedItem && ( +
e.stopPropagation()}> + {isMobile && ( + + )} + +
+
+ +
+
+
{selectedItem.id}
+

{selectedItem.displayName}

+ + {selectedItem.meta?.rarity?.toUpperCase()} + +
+
+ +
+
+
DATA_DESCRIPTION
+

{selectedItem.description}

+
+ + {selectedItem.stats && + Object.keys(selectedItem.stats).length > 0 && ( +
+
PARAMETER_READOUT
+
+ {Object.entries(selectedItem.stats).map(([k, v]) => ( +
+ {GameDataManager.getStatName(k)} + +{v} +
+ ))} +
+
+ )} +
+
+ )} +
+ ); + return (
- setSearchQuery(e.target.value)} />
-
{categories.map((cat) => ( ))}
-
{filteredItems.map((item) => (
{
{item.displayName}
{item.id}
-
))} - {filteredItems.length === 0 && ( -
NO_RECORDS_FOUND
- )}
- -
- {selectedItem ? ( -
-
-
- -
-
-
{selectedItem.id}
-

{selectedItem.displayName}

-
- {selectedItem.meta?.rarity?.toUpperCase()} -
-
-
- -
-
-
DATA_DESCRIPTION
-

{selectedItem.description}

-
- - {selectedItem.stats && - Object.keys(selectedItem.stats).length > 0 && ( -
-
PARAMETER_READOUT
-
- {Object.entries(selectedItem.stats).map(([k, v]) => ( -
- - {GameDataManager.getStatName(k)} - - +{v} -
- ))} -
-
- )} - -
-
OBJECT_METADATA
-
-
- CATEGORY - {selectedItem.meta?.category || "general"} -
-
- EQUIP_SLOT - {selectedItem.meta?.equipmentSlot || "none"} -
-
- STACK_LIMIT - {selectedItem.meta?.stackable ? "64" : "1"} -
-
-
-
-
- ) : ( -
-
-

AWAITING_OBJECT_SELECTION...

-
- )} -
+ {(!isMobile || (isMobile && selectedItem)) && renderInspector()} ); }; diff --git a/client/src/views/GameInterface/tabs/styles/ItemListTab.css b/client/src/views/GameInterface/tabs/styles/ItemListTab.css index 18133b4..4858264 100644 --- a/client/src/views/GameInterface/tabs/styles/ItemListTab.css +++ b/client/src/views/GameInterface/tabs/styles/ItemListTab.css @@ -6,9 +6,9 @@ font-family: "Rajdhani", "Segoe UI", sans-serif; border-top: 1px solid rgba(0, 255, 255, 0.1); overflow: hidden; + position: relative; } -/* SIDEBAR & SEARCH */ .item-list-sidebar { width: 380px; border-right: 1px solid rgba(0, 255, 255, 0.1); @@ -19,7 +19,6 @@ .search-box { padding: 20px; - position: relative; } .search-box input { @@ -31,16 +30,8 @@ text-transform: uppercase; letter-spacing: 1px; font-size: 14px; - transition: all 0.3s; } -.search-box input:focus { - outline: none; - border-color: #00ffff; - box-shadow: 0 0 10px rgba(0, 255, 255, 0.2); -} - -/* CATEGORY FILTERS */ .category-filters { display: flex; flex-wrap: wrap; @@ -55,17 +46,14 @@ padding: 4px 10px; font-size: 11px; cursor: pointer; - transition: 0.2s; } -.filter-btn.active, -.filter-btn:hover { +.filter-btn.active { background: rgba(0, 255, 255, 0.1); color: #00ffff; border-color: #00ffff; } -/* ITEM LIST ROWS */ .items-list-scroll { flex: 1; overflow-y: auto; @@ -78,60 +66,108 @@ padding: 10px; margin-bottom: 8px; background: rgba(255, 255, 255, 0.02); - border-left: 3px solid transparent; + border-left: 3px solid #9d9d9d; cursor: pointer; - transition: all 0.2s; - position: relative; -} - -.item-row:hover { - background: rgba(255, 255, 255, 0.05); - transform: translateX(5px); } .item-row.selected { background: rgba(0, 255, 255, 0.08); - border-left-color: #00ffff; } .item-row-icon { width: 44px; height: 44px; background: rgba(0, 0, 0, 0.5); - border: 1px solid rgba(255, 255, 255, 0.1); + margin-right: 15px; display: flex; align-items: center; justify-content: center; - margin-right: 15px; } .item-row-icon img { width: 32px; height: 32px; - object-fit: contain; - image-rendering: pixelated; /* Щоб іконки були чіткими */ + image-rendering: pixelated; } -.item-row-content { +/* Inspector Base */ +.item-inspector { flex: 1; + padding: 40px; + overflow-y: auto; +} + +.inspector-header { display: flex; - flex-direction: column; + gap: 25px; + margin-bottom: 30px; } -.item-row-title { - font-size: 15px; - font-weight: 600; - color: #fff; - text-transform: uppercase; +.header-visual { + width: 100px; + height: 100px; + background: rgba(0, 0, 0, 0.4); + border: 1px solid rgba(0, 255, 255, 0.2); + display: flex; + align-items: center; + justify-content: center; } -.item-row-subtitle { - font-size: 11px; - color: #666; - font-family: "Courier New", monospace; +.header-visual img { + width: 64px; + height: 64px; } -/* RARITY COLORS */ +/* Mobile Modal Logic */ +@media (max-width: 768px) { + .item-list-sidebar { + width: 100%; + border: none; + } + + .item-inspector.mobile-modal { + display: flex; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 3000; + background: rgba(0, 0, 0, 0.85); + backdrop-filter: blur(6px); + align-items: center; + justify-content: center; + padding: 20px; + } + + .inspector-content { + background: #0d121d; + border: 1px solid #00ffff44; + width: 100%; + max-height: 120vh; + overflow-y: auto; + position: relative; + padding: 20px; + box-shadow: 0 0 30px rgba(0, 0, 0, 0.5); + } + + .close-inspector { + position: absolute; + top: 10px; + right: 15px; + background: none; + border: none; + color: #00ffff; + font-size: 30px; + cursor: pointer; + } + + .item-inspector:not(.mobile-modal) { + display: none; + } +} + +/* Rarity */ .item-row.legendary { border-left-color: #ff8000; } @@ -141,67 +177,11 @@ .item-row.rare { border-left-color: #0070dd; } -.item-row.common { - border-left-color: #9d9d9d; -} -/* INSPECTOR PANEL */ -.item-inspector { - flex: 1; - padding: 40px; - background: radial-gradient( - circle at top right, - rgba(0, 255, 255, 0.03), - transparent - ); - overflow-y: auto; -} - -.inspector-header { - display: flex; - gap: 30px; - margin-bottom: 40px; - align-items: center; -} - -.header-visual { - width: 120px; - height: 120px; - background: rgba(0, 0, 0, 0.3); - border: 2px solid rgba(0, 255, 255, 0.2); - display: flex; - align-items: center; - justify-content: center; - box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); -} - -.header-visual img { - width: 80px; - height: 80px; -} - -.header-info h1 { - font-size: 32px; - margin: 5px 0; - text-transform: uppercase; - letter-spacing: 2px; -} - -.id-tag { - font-family: monospace; - color: #00ffff; - opacity: 0.6; - font-size: 14px; -} - -/* SCROLLBAR CUSTOMIZATION */ -.items-list-scroll::-webkit-scrollbar { - width: 4px; -} -.items-list-scroll::-webkit-scrollbar-thumb { - background: rgba(0, 255, 255, 0.2); -} - -.section-title { - font-size: 16px; +@media screen and (max-width: 600px) { + .section-title { + font-size: 16px; + padding: 0; + margin: 10px; + } } diff --git a/package.json b/package.json new file mode 100644 index 0000000..e212e69 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "gso-project-manager", + "version": "1.0.0", + "scripts": { + "install-all": "cd api && npm install && cd ../game-server && npm install && cd ../client && npm install", + "dev": "npx concurrently \"npm run dev-api\" \"npm run dev-server\" \"npm run dev-client\"", + "dev-api": "cd api && npm run start", + "dev-server": "cd game-server && npm run start", + "dev-client": "cd client && npm run dev" + }, + "dependencies": { + "concurrently": "^8.2.2" + } +}