diff --git a/client/src/views/GameInterface/tabs/components/CraftModal.css b/client/src/views/GameInterface/tabs/components/CraftModal.css
index 5c97861..88bf4a8 100644
--- a/client/src/views/GameInterface/tabs/components/CraftModal.css
+++ b/client/src/views/GameInterface/tabs/components/CraftModal.css
@@ -18,24 +18,23 @@
border-radius: 12px;
width: 90%;
max-width: 450px;
- padding: 24px;
box-shadow: 0 0 30px rgba(0, 204, 255, 0.15);
}
-.modal-header {
+.modal-headerr {
display: flex;
justify-content: space-between;
align-items: center;
+ padding: 10px;
+ text-align: center;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
- padding-bottom: 15px;
- margin-bottom: 20px;
}
-.modal-header h3 {
+.modal-header {
margin: 0;
color: #00ccff;
font-family: "Orbitron", sans-serif;
- font-size: 1.1rem;
+ font-size: 0.8rem;
}
.close-x {
@@ -125,7 +124,7 @@
height: 100%;
background: var(--primary-color);
box-shadow: 0 0 10px var(--primary-color);
- transition: width 1s linear; /* Плавне заповнення */
+ transition: width 1s linear;
}
@keyframes pulse {
@@ -140,7 +139,6 @@
}
}
-/* Стани інгредієнтів */
.res-item {
display: flex;
justify-content: space-between;
@@ -161,7 +159,6 @@
background: rgba(255, 68, 68, 0.1);
}
-/* Кольори значень */
.val-red {
color: #ff4444;
font-weight: bold;
@@ -181,7 +178,6 @@
font-size: 0.9rem;
}
-/* Кнопка */
.btn-start-craft {
background: #28a745;
color: white;
@@ -202,3 +198,60 @@
background: #218838;
box-shadow: 0 0 10px rgba(40, 167, 69, 0.4);
}
+
+.item-preview-header {
+ display: flex;
+ gap: 20px;
+ padding: 15px;
+ background: rgba(0, 212, 255, 0.05);
+ border: 1px solid rgba(0, 212, 255, 0.1);
+ margin-bottom: 20px;
+ border-radius: 4px;
+}
+
+.item-icon-container {
+ position: relative;
+ width: 90px;
+ height: 90px;
+ background: #000;
+ border: 1px solid var(--border-color);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+}
+
+.item-display-icon {
+ max-width: 80%;
+ max-height: 80%;
+ object-fit: contain;
+ filter: drop-shadow(0 0 5px var(--primary-color));
+}
+
+.item-qty-badge {
+ position: absolute;
+ top: -8px;
+ right: -8px;
+ background: var(--primary-color);
+ color: #000;
+ padding: 2px 8px;
+ font-size: 11px;
+ font-weight: bold;
+ border-radius: 2px;
+}
+
+.item-type-tag {
+ display: block;
+ font-size: 10px;
+ color: var(--primary-color);
+ letter-spacing: 1px;
+ margin-bottom: 5px;
+ opacity: 0.8;
+}
+
+.item-description {
+ font-size: 13px;
+ color: #ccc;
+ line-height: 1.4;
+ margin: 0;
+}
diff --git a/client/src/views/GameInterface/tabs/components/CraftModal.jsx b/client/src/views/GameInterface/tabs/components/CraftModal.jsx
index be5c3a0..d9a4d94 100644
--- a/client/src/views/GameInterface/tabs/components/CraftModal.jsx
+++ b/client/src/views/GameInterface/tabs/components/CraftModal.jsx
@@ -1,5 +1,6 @@
import React from "react";
import "./CraftModal.css";
+import { getServerUrl } from "../../../../config/api";
const CraftModal = ({
recipe,
@@ -10,6 +11,15 @@ const CraftModal = ({
}) => {
if (!recipe) return null;
+ const CONNECT_URL = getServerUrl();
+ const ASSET_BASE_URL = `${CONNECT_URL}/static/`;
+
+ const getFullTextureUrl = (path) => {
+ if (!path) return "/assets/no-image.png";
+ if (path.startsWith("http")) return path;
+ return `${ASSET_BASE_URL}${path}`;
+ };
+
const isBusy = !!activeCraft;
const outputQty = Object.values(recipe.output || {})[0] || 1;
const canAfford = recipe.ingredients?.every(
@@ -19,7 +29,7 @@ const CraftModal = ({
return (
e.stopPropagation()}>
-
+
Construction: {recipe.displayName}
@@ -29,6 +39,25 @@ const CraftModal = ({
+ {/* Секція з картинкою предмета */}
+
+
+
})
+
x{outputQty}
+
+
+
PROTOTYPE_UNIT
+
+ {recipe.description ||
+ "Technical data encrypted or unavailable."}
+
+
+
+
Required Resources
diff --git a/client/src/views/GameInterface/tabs/components/ItemModal.css b/client/src/views/GameInterface/tabs/components/ItemModal.css
index 39290a0..26fa6c0 100644
--- a/client/src/views/GameInterface/tabs/components/ItemModal.css
+++ b/client/src/views/GameInterface/tabs/components/ItemModal.css
@@ -12,133 +12,184 @@
backdrop-filter: blur(4px);
}
-.modal-content {
- background: #12151a;
- border: 1px solid #00d2ff;
- border-radius: 8px;
- width: 100%;
- max-width: 400px;
- padding: 25px;
+.datapack-modal-content {
+ background: #0f1115;
+ border: 1px solid rgba(0, 210, 255, 0.3);
+ width: 90%;
+ max-width: 450px;
+ border-radius: 12px;
position: relative;
- box-shadow: 0 0 30px rgba(0, 210, 255, 0.2);
- color: #fff;
- font-family: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
-}
-
-.modal-close {
- position: absolute;
- top: 10px;
- right: 15px;
- background: none;
- border: none;
- color: #888;
- font-size: 28px;
- cursor: pointer;
- transition: color 0.2s;
-}
-
-.modal-close:hover {
+ padding: 25px;
+ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.8);
+ animation: modalSlideUp 0.3s ease-out;
color: #fff;
}
-.details-header {
+.modal-header {
display: flex;
- justify-content: space-between;
align-items: center;
- margin-bottom: 15px;
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
- padding-bottom: 10px;
+ gap: 20px;
+ margin-bottom: 20px;
+ padding-bottom: 15px;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
-.item-name {
+.modal-icon-big {
+ width: 80px;
+ height: 80px;
+ background: rgba(0, 0, 0, 0.4);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+}
+
+.modal-icon-big img {
+ width: 60px;
+ height: 60px;
+ object-fit: contain;
+}
+
+.modal-icon-big.common {
+ border-color: #888;
+}
+.modal-icon-big.rare {
+ border-color: #0070dd;
+ box-shadow: inset 0 0 10px rgba(0, 112, 221, 0.2);
+}
+.modal-icon-big.epic {
+ border-color: #a335ee;
+ box-shadow: inset 0 0 10px rgba(163, 53, 238, 0.2);
+}
+.modal-icon-big.legendary {
+ border-color: #ff8000;
+ box-shadow: inset 0 0 10px rgba(255, 128, 0, 0.2);
+}
+
+.modal-title-group h3 {
margin: 0;
- font-size: 1.2rem;
+ font-family: "Orbitron", sans-serif;
+ font-size: 1.3rem;
text-transform: uppercase;
- letter-spacing: 1px;
}
-.rarity-badge {
- font-size: 0.7rem;
- padding: 2px 8px;
- border-radius: 4px;
- text-transform: uppercase;
- background: rgba(255, 255, 255, 0.1);
+.modal-title-group h3.common {
+ color: #fff;
}
-
-.item-name.common {
- color: #ffffff;
+.modal-title-group h3.rare {
+ color: #00d2ff;
}
-.item-name.uncommon {
- color: #1eff00;
-}
-.item-name.rare {
- color: #0070dd;
-}
-.item-name.epic {
+.modal-title-group h3.epic {
color: #a335ee;
}
-.item-name.legendary {
+.modal-title-group h3.legendary {
color: #ff8000;
}
-.item-description {
+.modal-raw-id {
+ font-size: 0.7rem;
+ color: #888;
+ margin-top: 4px;
+ font-family: monospace;
+}
+
+.details-description {
font-size: 0.9rem;
+ line-height: 1.5;
color: #aaa;
- line-height: 1.4;
margin-bottom: 20px;
+ font-style: italic;
+}
+
+.details-section h4 {
+ font-size: 0.8rem;
+ text-transform: uppercase;
+ color: #00d2ff;
+ letter-spacing: 1px;
+ margin-bottom: 10px;
+ border-left: 3px solid #00d2ff;
+ padding-left: 10px;
}
.item-stats-container {
- background: rgba(0, 0, 0, 0.3);
+ background: rgba(0, 0, 0, 0.2);
padding: 10px;
- border-radius: 4px;
- margin-bottom: 25px;
+ border-radius: 8px;
}
.stat-row {
display: flex;
justify-content: space-between;
- padding: 5px 0;
- font-size: 0.85rem;
+ padding: 8px 0;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.03);
+}
+
+.stat-row:last-child {
+ border-bottom: none;
}
.stat-label {
- color: #00d2ff;
+ color: #888;
+ font-size: 0.85rem;
display: flex;
align-items: center;
gap: 8px;
}
.stat-value {
- color: #fff;
+ color: #00ff88;
+ font-family: monospace;
font-weight: bold;
}
.btn-equip {
width: 100%;
padding: 12px;
- background: none;
+ background: rgba(0, 210, 255, 0.05);
border: 1px solid #00d2ff;
color: #00d2ff;
cursor: pointer;
- text-transform: uppercase;
- font-weight: bold;
- letter-spacing: 1px;
+ font-family: "Orbitron", sans-serif;
+ font-size: 0.8rem;
transition: all 0.2s;
}
.btn-equip:hover {
background: #00d2ff;
color: #000;
- box-shadow: 0 0 15px rgba(0, 210, 255, 0.4);
}
.btn-equip.unequip {
border-color: #ff4444;
color: #ff4444;
+ background: rgba(255, 68, 68, 0.05);
}
.btn-equip.unequip:hover {
background: #ff4444;
color: #fff;
}
+
+.modal-close {
+ position: absolute;
+ top: 15px;
+ right: 15px;
+ background: none;
+ border: none;
+ color: #444;
+ font-size: 24px;
+ cursor: pointer;
+}
+
+@keyframes modalSlideUp {
+ from {
+ transform: translateY(20px);
+ opacity: 0;
+ }
+ to {
+ transform: translateY(0);
+ opacity: 1;
+ }
+}
diff --git a/client/src/views/GameInterface/tabs/components/ItemModal.jsx b/client/src/views/GameInterface/tabs/components/ItemModal.jsx
index 4fd4a75..599cc29 100644
--- a/client/src/views/GameInterface/tabs/components/ItemModal.jsx
+++ b/client/src/views/GameInterface/tabs/components/ItemModal.jsx
@@ -1,5 +1,6 @@
import React from "react";
import "./ItemModal.css";
+import { getServerUrl } from "../../../../config/api";
const ItemModal = ({
item,
@@ -12,23 +13,45 @@ const ItemModal = ({
}) => {
if (!item) return null;
+ const CONNECT_URL = getServerUrl();
+ const ASSET_BASE_URL = `${CONNECT_URL}/static/`;
+
+ const getFullTextureUrl = (path) => {
+ if (!path) return "/assets/no-image.png";
+ if (path.startsWith("http")) return path;
+ return `${ASSET_BASE_URL}${path}`;
+ };
+
return (
-
e.stopPropagation()}>
+
e.stopPropagation()}
+ >
-
-
-
- {item.displayName || item.name}
-
-
{item.rarity}
+
+
+
+
+
{item.displayName || item.name}
+
+ {item.rarity?.toUpperCase()} SYSTEM_ID: {item.id}
+
+
+
-
{item.description}
+
+
+
+ Technical Specs
+
{item.stats &&
Object.entries(item.stats).map(([statName, value]) => (
@@ -43,7 +66,9 @@ const ItemModal = ({
))}
+
+
{isEquipped ? (
) : (
item.canEquip && (