diff --git a/index.php b/index.php index d42aa78..261c415 100644 --- a/index.php +++ b/index.php @@ -31,6 +31,30 @@ function index_scan_rarity_label(?string $rarity): string }; } +function index_itemcustom_display_value($value): string +{ + if ($value === null || $value === '') { + return '0'; + } + + if (is_numeric($value)) { + $formatted = number_format((float) $value, 2, '.', ''); + $formatted = rtrim(rtrim($formatted, '0'), '.'); + return $formatted === '' ? '0' : $formatted; + } + + return trim((string) $value) !== '' ? trim((string) $value) : '0'; +} + +function index_itemcustom_stat_preview(?string $sign, $value, ?string $unit): string +{ + $prefix = $sign === '-' ? '-' : ($sign === '+' ? '+' : ''); + $displayValue = index_itemcustom_display_value($value); + $displayUnit = trim((string) ($unit ?? '')); + + return trim($prefix . $displayValue . ($displayUnit !== '' ? ' ' . $displayUnit : '')); +} + auth_start_session(); auth_bootstrap(); @@ -44,6 +68,8 @@ $scan_reference_error = null; $ship_preset_rows = []; $ship_preset_manufacturers = []; $ship_preset_error = null; +$item_custom_public_rows = []; +$item_custom_public_error = null; try { $db = db(); @@ -136,6 +162,88 @@ try { } catch (Throwable $e) { $ship_preset_error = 'Impossible de charger les presets de vaisseaux pour le moment.'; } + +try { + if (!isset($db) || !($db instanceof PDO)) { + $db = db(); + } + + $stmt_item_custom_public = $db->query( + "SELECT + c.cl_scitemcustom_id, + o.cl_scobjs_name, + o.cl_scobjs_uuid, + o.cl_scobjs_type, + o.cl_scobjs_subtype, + COALESCE(NULLIF(TRIM(a.cl_auth_user), ''), 'Inconnu') AS creator_name, + cs.cl_scitemcustomstat_id, + cs.cl_scitemcustomstat_sign, + cs.cl_scitemcustomstat_value, + st.cl_scstatsitem_name, + st.cl_scstatsitem_unit + FROM tbl_scitemcustom c + INNER JOIN tbl_scobjs o ON o.cl_scobjs_id = c.cl_scitemcustom_obj_id + LEFT JOIN tbl_auth a ON a.cl_auth_id = c.cl_scitemcustom_owner_auth_id + LEFT JOIN tbl_scitemcustomstat cs ON cs.cl_scitemcustomstat_itemcustom_id = c.cl_scitemcustom_id + LEFT JOIN tbl_scstatsitem st ON st.cl_scstatsitem_id = cs.cl_scitemcustomstat_stat_id + WHERE c.cl_scitemcustom_owner_auth_id IS NOT NULL + ORDER BY o.cl_scobjs_name ASC, creator_name ASC, c.cl_scitemcustom_id ASC, st.cl_scstatsitem_name ASC, cs.cl_scitemcustomstat_id ASC" + ); + + $grouped_item_custom_public = []; + + foreach ($stmt_item_custom_public->fetchAll() as $row) { + $item_id = (int) ($row['cl_scitemcustom_id'] ?? 0); + if ($item_id <= 0) { + continue; + } + + if (!isset($grouped_item_custom_public[$item_id])) { + $name = trim((string) ($row['cl_scobjs_name'] ?? '')) ?: 'Objet inconnu'; + $creator = trim((string) ($row['creator_name'] ?? '')) ?: 'Inconnu'; + $type = trim((string) ($row['cl_scobjs_type'] ?? '')); + $subtype = trim((string) ($row['cl_scobjs_subtype'] ?? '')); + $uuid = trim((string) ($row['cl_scobjs_uuid'] ?? '')); + + $grouped_item_custom_public[$item_id] = [ + 'id' => $item_id, + 'name' => $name, + 'creator' => $creator, + 'type' => $type, + 'subtype' => $subtype, + 'uuid' => $uuid, + 'stats' => [], + 'search_parts' => [$name, $creator, $type, $subtype, $uuid], + ]; + } + + if (!empty($row['cl_scitemcustomstat_id'])) { + $stat_name = trim((string) ($row['cl_scstatsitem_name'] ?? '')) ?: 'Stat inconnue'; + $stat_sign = trim((string) ($row['cl_scitemcustomstat_sign'] ?? '')); + $stat_value_raw = $row['cl_scitemcustomstat_value'] ?? 0; + $stat_unit = trim((string) ($row['cl_scstatsitem_unit'] ?? '')); + $stat_preview = index_itemcustom_stat_preview($stat_sign, $stat_value_raw, $stat_unit); + + $grouped_item_custom_public[$item_id]['stats'][] = [ + 'name' => $stat_name, + 'preview' => $stat_preview, + ]; + + $grouped_item_custom_public[$item_id]['search_parts'][] = $stat_name; + $grouped_item_custom_public[$item_id]['search_parts'][] = $stat_preview; + } + } + + foreach ($grouped_item_custom_public as $item_custom_public_row) { + $item_custom_public_row['search'] = trim(implode(' ', array_filter($item_custom_public_row['search_parts'], static function ($value) { + return trim((string) $value) !== ''; + }))); + unset($item_custom_public_row['search_parts']); + $item_custom_public_rows[] = $item_custom_public_row; + } +} catch (Throwable $e) { + $item_custom_public_error = 'Impossible de charger les objets Item Custom pour le moment.'; +} ?> @@ -371,6 +479,262 @@ try { min-width: 940px; } + .modal-item-custom { + width: 92%; + max-width: 1380px; + min-width: 960px; + } + + .item-custom-dialog { + background: linear-gradient(180deg, rgba(15, 20, 29, 0.98), rgba(7, 10, 16, 0.98)); + border: 1px solid rgba(162, 155, 120, 0.35); + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.45); + } + + .item-custom-dialog h3 { + font-size: 1.75em; + letter-spacing: 0.08em; + } + + .item-custom-dialog > div { + padding: 22px 26px 26px; + } + + .item-custom-intro, + .item-custom-empty, + .item-custom-error { + margin: 0 0 18px; + padding: 12px 14px !important; + border-radius: 10px; + font-size: 0.95em; + text-align: left !important; + } + + .item-custom-intro { + background: rgba(162, 155, 120, 0.12); + border: 1px solid rgba(162, 155, 120, 0.18); + color: #f0ead2; + } + + .item-custom-empty { + background: rgba(255, 255, 255, 0.06); + border: 1px solid rgba(255, 255, 255, 0.12); + } + + .item-custom-error { + background: rgba(140, 32, 32, 0.18); + border: 1px solid rgba(255, 88, 88, 0.25); + color: #ffbdbd; + } + + .item-custom-filter-bar { + display: flex; + align-items: center; + gap: 16px; + margin: 0 0 18px; + padding: 14px 16px; + border-radius: 14px; + background: rgba(255, 255, 255, 0.04); + border: 1px solid rgba(162, 155, 120, 0.18); + flex-wrap: wrap; + } + + .item-custom-search-wrap { + display: flex; + align-items: center; + gap: 12px; + flex: 1 1 420px; + min-width: 280px; + } + + .item-custom-search-input { + width: 100%; + padding: 10px 14px; + border-radius: 10px; + border: 1px solid rgba(162, 155, 120, 0.3); + background: rgba(10, 14, 21, 0.95); + color: #ffffff; + font-size: 0.92em; + } + + .item-custom-search-input:focus-visible { + outline: 2px solid rgba(162, 155, 120, 0.45); + outline-offset: 2px; + } + + .item-custom-reset-btn { + padding: 10px 14px; + border-radius: 999px; + border: 1px solid rgba(162, 155, 120, 0.34); + background: rgba(162, 155, 120, 0.1); + color: #f6f1dc; + font-size: 0.76em; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + cursor: pointer; + } + + .item-custom-filter-status { + margin: 0 0 0 auto; + font-size: 0.85em; + color: rgba(255, 255, 255, 0.7); + text-align: right; + } + + .item-custom-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 18px; + max-height: 68vh; + overflow-y: auto; + padding-right: 4px; + } + + .item-custom-card { + display: flex; + flex-direction: column; + gap: 16px; + padding: 18px; + border-radius: 16px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.025)); + border: 1px solid rgba(162, 155, 120, 0.22); + box-shadow: 0 12px 30px rgba(0, 0, 0, 0.22); + } + + .item-custom-card-header { + display: flex; + justify-content: space-between; + gap: 14px; + align-items: center; + flex-wrap: wrap; + } + + .item-custom-card-identity { + display: flex; + align-items: center; + gap: 14px; + min-width: 0; + } + + .item-custom-card-thumb { + width: 64px; + height: 64px; + border-radius: 14px; + object-fit: contain; + background: rgba(255, 255, 255, 0.04); + border: 1px solid rgba(255, 255, 255, 0.08); + padding: 6px; + flex-shrink: 0; + } + + .item-custom-card-type { + margin: 0 0 6px; + font-size: 0.74em; + text-transform: uppercase; + letter-spacing: 0.14em; + color: rgba(162, 155, 120, 0.95); + } + + .item-custom-card-name { + margin: 0; + font-size: 1.25em; + line-height: 1.2; + color: #ffffff; + } + + .item-custom-card-meta { + margin: 6px 0 0; + font-size: 0.82em; + color: rgba(255, 255, 255, 0.68); + } + + .item-custom-card-count { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 8px 12px; + border-radius: 999px; + background: rgba(162, 155, 120, 0.12); + border: 1px solid rgba(162, 155, 120, 0.22); + color: #f6f1dc; + font-size: 0.76em; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + } + + .item-custom-card-table-wrap { + overflow-x: auto; + } + + .item-custom-card-table { + width: 100%; + border-collapse: collapse; + min-width: 520px; + } + + .item-custom-card-table th, + .item-custom-card-table td { + padding: 10px 12px; + border-bottom: 1px solid rgba(255, 255, 255, 0.08); + text-align: left; + font-size: 0.88em; + } + + .item-custom-card-table th { + color: rgba(162, 155, 120, 0.95); + text-transform: uppercase; + letter-spacing: 0.08em; + font-size: 0.72em; + } + + .item-custom-card-table tbody tr:last-child td { + border-bottom: none; + } + + .item-custom-card-empty { + margin: 0; + padding: 14px; + border-radius: 12px; + background: rgba(255, 255, 255, 0.04); + border: 1px solid rgba(255, 255, 255, 0.08); + color: rgba(255, 255, 255, 0.72); + font-size: 0.88em; + } + + .item-custom-stat-sign { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 40px; + padding: 5px 10px; + border-radius: 999px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.08); + font-weight: 700; + } + + .item-custom-stat-sign.sign-plus { + color: #7fffb9; + border-color: rgba(127, 255, 185, 0.25); + background: rgba(0, 255, 136, 0.09); + } + + .item-custom-stat-sign.sign-minus { + color: #ffb0b0; + border-color: rgba(255, 120, 120, 0.25); + background: rgba(255, 77, 77, 0.08); + } + + .item-custom-stat-sign.sign-neutral { + color: #f1f1f1; + } + + .item-custom-card.is-hidden-by-search { + display: none; + } + .ship-presets-dialog { background: linear-gradient(180deg, rgba(17, 22, 31, 0.98), rgba(8, 11, 18, 0.98)); border: 1px solid rgba(162, 155, 120, 0.35); @@ -553,13 +917,15 @@ try { @media (max-width: 1100px) { .modal-scan-reference, - .modal-ship-presets { + .modal-ship-presets, + .modal-item-custom { width: 96%; min-width: 0; } .scan-reference-dialog h3, - .ship-presets-dialog h3 { + .ship-presets-dialog h3, + .item-custom-dialog h3 { font-size: 1.2em; } @@ -584,16 +950,40 @@ try { .ship-presets-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } + + .item-custom-filter-bar { + align-items: stretch; + } + + .item-custom-filter-status { + margin-left: 0; + text-align: left; + } + + .item-custom-grid { + grid-template-columns: 1fr; + } } @media (max-width: 720px) { - .ship-presets-grid { + .ship-presets-grid, + .item-custom-grid { grid-template-columns: 1fr; } .ship-preset-card { min-height: 0; } + + .item-custom-search-wrap, + .item-custom-card-identity { + flex-direction: column; + align-items: stretch; + } + + .item-custom-card-table { + min-width: 0; + } } @@ -602,6 +992,7 @@ try {
Signatures de minage Presets de vaisseaux + Item Custom
id="accountPanel"> @@ -715,6 +1106,74 @@ try {
+ + +