From 5c76d59baf076095b3a242f4eac1199999eaab98 Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Tue, 19 May 2026 20:58:57 -0500 Subject: [PATCH] feat: add mobile banking app and integrate into phone UI - Implemented wallet app functionality including account management, transaction handling, and user notifications. - Updated HomeScreen to include Wallet app icon. - Enhanced StateManager to maintain mobile bank state. - Created wallet-specific styles for UI consistency. - Updated CSS and JS concatenation scripts to include wallet resources. --- .../client/addons/bank/XEH_postInitClient.sqf | 24 + .../phone/functions/fnc_handleUIEvents.sqf | 50 + .../addons/phone/ui/_site/dist/app.bundle.css | 969 +++++++---- .../addons/phone/ui/_site/dist/app.bundle.js | 1539 +++++++++++------ .../phone/ui/_site/images/dark/Wallet.png | Bin 0 -> 65969 bytes .../phone/ui/_site/images/dark/Wallet.png.b64 | 1 + .../phone/ui/_site/images/iPhoneIcons.xcf | Bin 924418 -> 1002672 bytes .../phone/ui/_site/images/light/Wallet.png | Bin 0 -> 65969 bytes .../ui/_site/images/light/Wallet.png.b64 | 1 + arma/client/addons/phone/ui/_site/js/app.js | 6 +- .../phone/ui/_site/js/apps/wallet/index.js | 436 +++++ .../ui/_site/js/components/HomeScreen.js | 1 + .../phone/ui/_site/js/core/StateManager.js | 17 + .../ui/_site/styles/components/wallet.css | 314 ++++ .../addons/phone/ui/_site/tools/concat-css.js | 5 +- .../addons/phone/ui/_site/tools/concat-js.js | 16 +- 16 files changed, 2511 insertions(+), 868 deletions(-) create mode 100644 arma/client/addons/phone/ui/_site/images/dark/Wallet.png create mode 100644 arma/client/addons/phone/ui/_site/images/dark/Wallet.png.b64 create mode 100644 arma/client/addons/phone/ui/_site/images/light/Wallet.png create mode 100644 arma/client/addons/phone/ui/_site/images/light/Wallet.png.b64 create mode 100644 arma/client/addons/phone/ui/_site/js/apps/wallet/index.js create mode 100644 arma/client/addons/phone/ui/_site/styles/components/wallet.css diff --git a/arma/client/addons/bank/XEH_postInitClient.sqf b/arma/client/addons/bank/XEH_postInitClient.sqf index 4a79659..90c8646 100644 --- a/arma/client/addons/bank/XEH_postInitClient.sqf +++ b/arma/client/addons/bank/XEH_postInitClient.sqf @@ -3,6 +3,26 @@ if (isNil QGVAR(BankRepository)) then { call FUNC(initRepository); }; if (isNil QGVAR(BankUIBridge)) then { call FUNC(initUIBridge); }; +GVAR(sendPhoneBankEvent) = { + params [["_functionName", "", [""]], ["_arguments", [], [[]]]]; + + private _display = uiNamespace getVariable ["RscPhone", displayNull]; + if (isNull _display || { _functionName isEqualTo "" }) exitWith { false }; + + private _control = _display displayCtrl 1001; + if (isNull _control) exitWith { false }; + + private _serializedArguments = _arguments apply { toJSON _x }; + private _script = format [ + "window.%1 && window.%1(%2)", + _functionName, + _serializedArguments joinString ", " + ]; + + _control ctrlWebBrowserAction ["ExecJS", _script]; + true +}; + [QGVAR(initBank), { GVAR(BankRepository) call ["init", []]; }] call CFUNC(addEventHandler); @@ -14,6 +34,7 @@ if (isNil QGVAR(BankUIBridge)) then { call FUNC(initUIBridge); }; if !(isNil QGVAR(BankUIBridge)) then { GVAR(BankUIBridge) call ["handleAccountSyncResponse", [_data]]; }; + ["updateMobileBankAccount", [_data]] call GVAR(sendPhoneBankEvent); }] call CFUNC(addEventHandler); [QGVAR(responseSyncBank), { @@ -23,6 +44,7 @@ if (isNil QGVAR(BankUIBridge)) then { call FUNC(initUIBridge); }; if !(isNil QGVAR(BankUIBridge)) then { GVAR(BankUIBridge) call ["handleAccountSyncResponse", [_data]]; }; + ["updateMobileBankAccount", [_data]] call GVAR(sendPhoneBankEvent); }] call CFUNC(addEventHandler); [QGVAR(responseHydrateBank), { @@ -31,6 +53,7 @@ if (isNil QGVAR(BankUIBridge)) then { call FUNC(initUIBridge); }; if !(isNil QGVAR(BankUIBridge)) then { GVAR(BankUIBridge) call ["handleHydrateResponse", [_data, "bank::hydrate"]]; }; + ["updateMobileBank", [_data]] call GVAR(sendPhoneBankEvent); }] call CFUNC(addEventHandler); [QGVAR(responseBankNotice), { @@ -39,6 +62,7 @@ if (isNil QGVAR(BankUIBridge)) then { call FUNC(initUIBridge); }; if !(isNil QGVAR(BankUIBridge)) then { GVAR(BankUIBridge) call ["handleNoticeResponse", [_type, _message]]; }; + ["showMobileBankNotice", [_type, _message]] call GVAR(sendPhoneBankEvent); }] call CFUNC(addEventHandler); [{ diff --git a/arma/client/addons/phone/functions/fnc_handleUIEvents.sqf b/arma/client/addons/phone/functions/fnc_handleUIEvents.sqf index c715b27..a5c4936 100644 --- a/arma/client/addons/phone/functions/fnc_handleUIEvents.sqf +++ b/arma/client/addons/phone/functions/fnc_handleUIEvents.sqf @@ -345,6 +345,56 @@ switch (_event) do { profileNamespace setVariable ["FORGE_Phone_Alarms", _alarms]; }; + case "phone::bank::refresh": { + ["forge_server_bank_requestHydrateBank", [getPlayerUID player, "bank", false]] call CFUNC(serverEvent); + }; + case "phone::bank::transfer::request": { + private _amount = floor (_data getOrDefault ["amount", 0]); + private _target = _data getOrDefault ["target", ""]; + private _from = toLowerANSI (_data getOrDefault ["from", "bank"]); + + if (_target isNotEqualTo "" && { _amount > 0 }) then { + ["forge_server_bank_requestTransfer", [getPlayerUID player, _target, _from, _amount]] call CFUNC(serverEvent); + } else { + private _display = uiNamespace getVariable ["RscPhone", displayNull]; + if !(isNull _display) then { + private _control = _display displayCtrl 1001; + if !(isNull _control) then { + _control ctrlWebBrowserAction ["ExecJS", "window.showMobileBankNotice && window.showMobileBankNotice('error', 'Choose a recipient and valid amount.')"]; + }; + }; + }; + }; + case "phone::bank::depositEarnings::request": { + private _amount = floor (_data getOrDefault ["amount", 0]); + + if (_amount > 0) then { + ["forge_server_bank_requestDepositEarnings", [getPlayerUID player, _amount]] call CFUNC(serverEvent); + } else { + private _display = uiNamespace getVariable ["RscPhone", displayNull]; + if !(isNull _display) then { + private _control = _display displayCtrl 1001; + if !(isNull _control) then { + _control ctrlWebBrowserAction ["ExecJS", "window.showMobileBankNotice && window.showMobileBankNotice('error', 'Enter a valid earnings amount.')"]; + }; + }; + }; + }; + case "phone::bank::repayCreditLine::request": { + private _amount = floor (_data getOrDefault ["amount", 0]); + + if (_amount > 0) then { + ["forge_server_bank_requestRepayCreditLine", [getPlayerUID player, _amount]] call CFUNC(serverEvent); + } else { + private _display = uiNamespace getVariable ["RscPhone", displayNull]; + if !(isNull _display) then { + private _control = _display displayCtrl 1001; + if !(isNull _control) then { + _control ctrlWebBrowserAction ["ExecJS", "window.showMobileBankNotice && window.showMobileBankNotice('error', 'Enter a valid payment amount.')"]; + }; + }; + }; + }; default { hint format ["Unhandled phone event: %1", _event]; }; }; diff --git a/arma/client/addons/phone/ui/_site/dist/app.bundle.css b/arma/client/addons/phone/ui/_site/dist/app.bundle.css index e5ac873..502f764 100644 --- a/arma/client/addons/phone/ui/_site/dist/app.bundle.css +++ b/arma/client/addons/phone/ui/_site/dist/app.bundle.css @@ -1666,6 +1666,76 @@ body::-webkit-scrollbar { } +/* ---- ../styles/components/settings.css ---- */ +/* Settings */ +.settings-list { + background: var(--bg-primary); +} + +.settings-item { + border-bottom: 1px solid var(--border-color); + color: var(--text-primary); +} + +.settings-item:hover { + background: var(--bg-secondary); +} + +/* Theme Toggle Switch */ +.theme-toggle { + display: flex; + align-items: center; + justify-content: space-between; + padding: 15px 20px; + border-bottom: 1px solid var(--border-color); + background: var(--bg-primary); + color: var(--text-primary); +} + +.toggle-switch { + position: relative; + width: 51px; + height: 31px; +} + +.toggle-switch input { + opacity: 0; + width: 0; + height: 0; +} + +.toggle-slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #e9ecef; + transition: .4s; + border-radius: 34px; +} + +.toggle-slider:before { + position: absolute; + content: ""; + height: 27px; + width: 27px; + left: 2px; + bottom: 2px; + background-color: white; + transition: .4s; + border-radius: 50%; +} + +input:checked+.toggle-slider { + background-color: var(--accent-color); +} + +input:checked+.toggle-slider:before { + transform: translateX(20px); +} + /* ---- ../styles/components/notes.css ---- */ /* Notes App Styles */ @@ -1956,6 +2026,302 @@ body::-webkit-scrollbar { +/* ---- ../styles/components/calendar.css ---- */ +/* Calendar App Styles */ +.app-container { + display: flex; + flex-direction: column; + height: 100%; + background: var(--bg-primary); +} + +.content { + flex: 1; + overflow-y: auto; + padding: 16px; +} + +/* Calendar Container */ +.calendar-container { + background: var(--bg-primary); + border-radius: 12px; + width: 100%; + max-width: 375px; + margin: 0 auto; +} + +/* Calendar Header */ +.calendar-header { + display: flex; + justify-content: space-between; + align-items: center; + margin: 10px; + padding: 0 16px; +} + +.calendar-title { + font-size: 20px; + font-weight: 600; + color: var(--text-primary); +} + +.calendar-nav { + display: flex; + gap: 8px; +} + +.calendar-nav-btn { + background: var(--bg-secondary); + border: none; + border-radius: 8px; + padding: 8px; + color: var(--accent-color); + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s; + display: flex; + align-items: center; + justify-content: center; + min-width: 36px; + height: 36px; +} + +.calendar-nav-btn img { + width: 20px; + height: 20px; + color: var(--accent-color); +} + +.calendar-nav-btn:hover { + background: var(--border-color); +} + +.nav-button.add-button img { + width: 24px; + height: 24px; + color: var(--accent-color); +} + +/* Calendar Grid */ +.calendar-grid { + display: grid; + grid-template-columns: repeat(7, 1fr); + gap: 4px; + padding: 0 16px; +} + +.calendar-weekday { + text-align: center; + font-size: 12px; + color: var(--text-secondary); + padding: 8px 0; + font-weight: 500; +} + +.calendar-day { + aspect-ratio: 1; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + font-size: 14px; + cursor: pointer; + transition: all 0.2s; + position: relative; + border: 2px solid transparent; +} + +.calendar-day:hover { + background: var(--bg-secondary); +} + +.calendar-day.today { + background: var(--accent-color); + color: white; + border: 2px solid transparent; +} + +.calendar-day.selected { + background: var(--accent-color); + color: white; +} + +.calendar-day.today:not(.selected) { + background: transparent; + color: var(--text-primary); + border: 2px solid var(--accent-color); +} + +.calendar-day.today.selected { + border: 2px solid white; +} + +.calendar-day.other-month { + color: var(--text-secondary); + opacity: 0.5; +} + +.calendar-day.has-events::after { + content: ''; + position: absolute; + bottom: 4px; + width: 4px; + height: 4px; + border-radius: 50%; + background: var(--accent-color); +} + +/* Calendar Events */ +.calendar-events { + margin-top: 20px; + border-top: 1px solid var(--border-color); + padding: 16px; +} + +.no-events { + text-align: center; + color: var(--text-secondary); + font-size: 14px; + padding: 20px 0; +} + +.event-item { + display: flex; + align-items: center; + padding: 12px; + border-radius: 8px; + margin-bottom: 8px; + background: var(--bg-secondary); + cursor: pointer; + transition: background-color 0.2s; +} + +.event-item:hover { + background: var(--border-color); +} + +.event-time { + font-size: 12px; + color: var(--text-secondary); + margin-right: 12px; + min-width: 60px; +} + +.event-title { + font-size: 14px; + color: var(--text-primary); + flex-grow: 1; +} + +.event-dot { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--accent-color); + margin-right: 8px; +} + +/* Event Editor */ +.event-editor { + display: flex; + flex-direction: column; + height: 100%; + background: var(--bg-primary); +} + +.event-form { + display: flex; + flex-direction: column; + padding: 16px; + gap: 16px; +} + +.event-title-input { + font-size: 20px; + padding: 8px 0; + border: none; + border-bottom: 1px solid var(--border-color); + background: none; + color: var(--text-primary); + outline: none; +} + +.time-container { + display: flex; + gap: 16px; +} + +.time-input { + flex: 1; + padding: 8px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: var(--bg-secondary); + color: var(--text-primary); + font-size: 14px; +} + +.event-description-input { + min-height: 100px; + padding: 8px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: var(--bg-secondary); + color: var(--text-primary); + font-size: 14px; + resize: none; +} + +.delete-event-button { + background: transparent; + border: none; + color: #ff4444; + font-size: 0.9rem; + padding: 0.5rem 1rem; + border-radius: 4px; + cursor: pointer; + transition: all 0.2s ease; +} + +.delete-event-button:hover { + background: rgba(255, 68, 68, 0.1); +} + +.delete-event-button:active { + background: rgba(255, 68, 68, 0.2); +} + +/* Navigation Buttons - Event Editor specific */ +.event-editor .navigation-bar .nav-button.cancel-button { + color: var(--text-secondary) !important; + font-size: 0.9rem !important; + font-weight: 400 !important; + padding: 0.5rem 1rem !important; + background: transparent; + border: none; + cursor: pointer; + transition: color 0.2s ease; +} + +.event-editor .navigation-bar .nav-button.cancel-button:hover { + color: var(--text-primary) !important; +} + +.event-editor .navigation-bar .nav-button.save-button { + color: var(--accent-color) !important; + font-size: 0.9rem !important; + font-weight: 600 !important; + padding: 0.5rem 1rem !important; + background: transparent; + border: none; + cursor: pointer; + transition: color 0.2s ease; +} + +.event-editor .navigation-bar .nav-button.save-button:hover { + color: var(--accent-color-hover) !important; +} + /* ---- ../styles/components/clock.css ---- */ /* Clock App Styles */ @@ -2543,371 +2909,322 @@ body::-webkit-scrollbar { -/* ---- ../styles/components/calendar.css ---- */ -/* Calendar App Styles */ -.app-container { +/* ---- ../styles/components/wallet.css ---- */ +/* Wallet */ +.wallet-app { + background: var(--bg-primary); +} + +.wallet-content { + background: var(--bg-primary); + color: var(--text-primary); display: flex; flex-direction: column; - height: 100%; - background: var(--bg-primary); -} - -.content { - flex: 1; + gap: 12px; + height: calc(100% - 44px); overflow-y: auto; - padding: 16px; + padding: 12px 16px 28px; } -/* Calendar Container */ -.calendar-container { - background: var(--bg-primary); +.wallet-nav-button { + background: transparent; + border: 0; + color: #275a8c; + cursor: pointer; + font-size: 13px; + font-weight: 700; +} + +[data-theme="dark"] .wallet-nav-button { + color: #8bb9e6; +} + +.wallet-notice { border-radius: 12px; - width: 100%; - max-width: 375px; - margin: 0 auto; + font-size: 13px; + font-weight: 700; + line-height: 1.35; + padding: 10px 12px; } -/* Calendar Header */ -.calendar-header { +.wallet-notice-success { + background: rgba(47, 125, 91, 0.16); + color: #2f7d5b; +} + +.wallet-notice-error { + background: rgba(196, 57, 57, 0.16); + color: #b42323; +} + +.wallet-notice-info { + background: rgba(39, 90, 140, 0.14); + color: #275a8c; +} + +.wallet-balance-card { + background: linear-gradient(160deg, #142f52 0%, #275a8c 58%, #4f86bd 100%); + border-radius: 20px; + box-shadow: 0 14px 26px rgba(20, 47, 82, 0.22); + color: #ffffff; display: flex; - justify-content: space-between; - align-items: center; - margin: 10px; - padding: 0 16px; + flex-direction: column; + min-height: 142px; + padding: 18px; } -.calendar-title { - font-size: 20px; - font-weight: 600; +.wallet-eyebrow, +.wallet-card-title, +.wallet-metric span, +.wallet-transaction-meta { + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.wallet-eyebrow { + color: rgba(255, 255, 255, 0.72); + font-size: 11px; + font-weight: 800; +} + +.wallet-balance { + font-size: 34px; + letter-spacing: 0; + line-height: 1.1; + margin-top: 14px; +} + +.wallet-owner { + color: rgba(255, 255, 255, 0.8); + font-size: 13px; + margin-top: auto; +} + +.wallet-metrics { + display: grid; + gap: 10px; + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.wallet-metric, +.wallet-card { + background: linear-gradient(180deg, #ffffff 0%, #f4f8fd 100%); + border: 1px solid rgba(18, 54, 93, 0.12); + border-radius: 16px; +} + +[data-theme="dark"] .wallet-metric, +[data-theme="dark"] .wallet-card { + background: linear-gradient(180deg, #1c1c1e 0%, #151b23 100%); + border-color: rgba(139, 185, 230, 0.18); +} + +.wallet-metric { + display: flex; + flex-direction: column; + gap: 6px; + min-width: 0; + padding: 12px; +} + +.wallet-metric span, +.wallet-card-title { + color: #6f86a3; + font-size: 11px; + font-weight: 800; +} + +[data-theme="dark"] .wallet-metric span, +[data-theme="dark"] .wallet-card-title, +[data-theme="dark"] .wallet-transaction-meta { + color: #8ea2bb; +} + +.wallet-metric strong { + color: #142f52; + font-size: 18px; + line-height: 1.15; +} + +[data-theme="dark"] .wallet-metric strong { + color: #ffffff; +} + +.wallet-card { + display: flex; + flex-direction: column; + gap: 10px; + padding: 14px; +} + +.wallet-input { + background: var(--input-bg); + border: 1px solid rgba(18, 54, 93, 0.16); + border-radius: 12px; color: var(--text-primary); + font: inherit; + min-height: 42px; + padding: 0 12px; + width: 100%; } -.calendar-nav { +[data-theme="dark"] .wallet-input { + border-color: var(--input-border); +} + +.wallet-primary-button { + background: #275a8c; + border: 0; + border-radius: 12px; + color: #ffffff; + cursor: pointer; + font: inherit; + font-weight: 800; + min-height: 42px; +} + +.wallet-secondary-button { + background: rgba(39, 90, 140, 0.12); + border: 1px solid rgba(39, 90, 140, 0.18); + border-radius: 12px; + color: #275a8c; + cursor: pointer; + font: inherit; + font-size: 12px; + font-weight: 800; + min-height: 42px; + padding: 0 10px; +} + +.wallet-full-button { + width: 100%; +} + +[data-theme="dark"] .wallet-secondary-button { + background: rgba(139, 185, 230, 0.13); + border-color: rgba(139, 185, 230, 0.2); + color: #8bb9e6; +} + +.wallet-action-block { + background: rgba(39, 90, 140, 0.08); + border-radius: 12px; + display: grid; + gap: 10px; + padding: 10px 12px; +} + +.wallet-action-block + .wallet-action-block { + margin-top: 2px; +} + +[data-theme="dark"] .wallet-action-block { + background: rgba(139, 185, 230, 0.1); +} + +.wallet-action-summary { + display: grid; + gap: 3px; +} + +.wallet-action-summary span { + color: #6f86a3; + font-size: 11px; + font-weight: 800; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.wallet-action-summary strong { + color: #142f52; + font-size: 18px; +} + +.wallet-action-summary small { + color: var(--text-secondary); + font-size: 12px; + line-height: 1.25; +} + +[data-theme="dark"] .wallet-action-summary span, +[data-theme="dark"] .wallet-action-summary strong { + color: #ffffff; +} + +.wallet-action-controls { + display: grid; + gap: 8px; + grid-template-columns: minmax(0, 1fr) 112px; +} + +.wallet-primary-button:disabled, +.wallet-secondary-button:disabled, +.wallet-nav-button:disabled { + cursor: not-allowed; + opacity: 0.58; +} + +.wallet-transaction-list { display: flex; + flex-direction: column; gap: 8px; } -.calendar-nav-btn { - background: var(--bg-secondary); - border: none; - border-radius: 8px; - padding: 8px; - color: var(--accent-color); - font-weight: 500; - cursor: pointer; - transition: background-color 0.2s; - display: flex; +.wallet-transaction-row { align-items: center; - justify-content: center; - min-width: 36px; - height: 36px; -} - -.calendar-nav-btn img { - width: 20px; - height: 20px; - color: var(--accent-color); -} - -.calendar-nav-btn:hover { - background: var(--border-color); -} - -.nav-button.add-button img { - width: 24px; - height: 24px; - color: var(--accent-color); -} - -/* Calendar Grid */ -.calendar-grid { - display: grid; - grid-template-columns: repeat(7, 1fr); - gap: 4px; - padding: 0 16px; -} - -.calendar-weekday { - text-align: center; - font-size: 12px; - color: var(--text-secondary); - padding: 8px 0; - font-weight: 500; -} - -.calendar-day { - aspect-ratio: 1; + border-top: 1px solid rgba(18, 54, 93, 0.1); display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - font-size: 14px; - cursor: pointer; - transition: all 0.2s; - position: relative; - border: 2px solid transparent; + gap: 10px; + justify-content: space-between; + padding-top: 10px; } -.calendar-day:hover { - background: var(--bg-secondary); +[data-theme="dark"] .wallet-transaction-row { + border-top-color: rgba(139, 185, 230, 0.14); } -.calendar-day.today { - background: var(--accent-color); - color: white; - border: 2px solid transparent; -} - -.calendar-day.selected { - background: var(--accent-color); - color: white; -} - -.calendar-day.today:not(.selected) { - background: transparent; - color: var(--text-primary); - border: 2px solid var(--accent-color); -} - -.calendar-day.today.selected { - border: 2px solid white; -} - -.calendar-day.other-month { - color: var(--text-secondary); - opacity: 0.5; -} - -.calendar-day.has-events::after { - content: ''; - position: absolute; - bottom: 4px; - width: 4px; - height: 4px; - border-radius: 50%; - background: var(--accent-color); -} - -/* Calendar Events */ -.calendar-events { - margin-top: 20px; - border-top: 1px solid var(--border-color); - padding: 16px; -} - -.no-events { - text-align: center; - color: var(--text-secondary); - font-size: 14px; - padding: 20px 0; -} - -.event-item { - display: flex; - align-items: center; - padding: 12px; - border-radius: 8px; - margin-bottom: 8px; - background: var(--bg-secondary); - cursor: pointer; - transition: background-color 0.2s; -} - -.event-item:hover { - background: var(--border-color); -} - -.event-time { - font-size: 12px; - color: var(--text-secondary); - margin-right: 12px; - min-width: 60px; -} - -.event-title { - font-size: 14px; - color: var(--text-primary); - flex-grow: 1; -} - -.event-dot { - width: 8px; - height: 8px; - border-radius: 50%; - background: var(--accent-color); - margin-right: 8px; -} - -/* Event Editor */ -.event-editor { +.wallet-transaction-copy { display: flex; flex-direction: column; - height: 100%; - background: var(--bg-primary); + gap: 3px; + min-width: 0; } -.event-form { - display: flex; - flex-direction: column; - padding: 16px; - gap: 16px; -} - -.event-title-input { - font-size: 20px; - padding: 8px 0; - border: none; - border-bottom: 1px solid var(--border-color); - background: none; - color: var(--text-primary); - outline: none; -} - -.time-container { - display: flex; - gap: 16px; -} - -.time-input { - flex: 1; - padding: 8px; - border: 1px solid var(--border-color); - border-radius: 8px; - background: var(--bg-secondary); +.wallet-transaction-title { color: var(--text-primary); font-size: 14px; + font-weight: 700; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } -.event-description-input { - min-height: 100px; - padding: 8px; - border: 1px solid var(--border-color); - border-radius: 8px; - background: var(--bg-secondary); - color: var(--text-primary); +.wallet-transaction-meta { + color: #6f86a3; + font-size: 10px; + font-weight: 700; +} + +.wallet-transaction-value { + color: #142f52; + flex-shrink: 0; font-size: 14px; - resize: none; + font-weight: 800; } -.delete-event-button { - background: transparent; - border: none; - color: #ff4444; - font-size: 0.9rem; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; - transition: all 0.2s ease; +[data-theme="dark"] .wallet-transaction-value { + color: #ffffff; } -.delete-event-button:hover { - background: rgba(255, 68, 68, 0.1); +.wallet-empty-state { + border: 1px dashed rgba(18, 54, 93, 0.18); + border-radius: 12px; + color: var(--text-secondary); + font-size: 13px; + padding: 14px; + text-align: center; } -.delete-event-button:active { - background: rgba(255, 68, 68, 0.2); -} - -/* Navigation Buttons - Event Editor specific */ -.event-editor .navigation-bar .nav-button.cancel-button { - color: var(--text-secondary) !important; - font-size: 0.9rem !important; - font-weight: 400 !important; - padding: 0.5rem 1rem !important; - background: transparent; - border: none; - cursor: pointer; - transition: color 0.2s ease; -} - -.event-editor .navigation-bar .nav-button.cancel-button:hover { - color: var(--text-primary) !important; -} - -.event-editor .navigation-bar .nav-button.save-button { - color: var(--accent-color) !important; - font-size: 0.9rem !important; - font-weight: 600 !important; - padding: 0.5rem 1rem !important; - background: transparent; - border: none; - cursor: pointer; - transition: color 0.2s ease; -} - -.event-editor .navigation-bar .nav-button.save-button:hover { - color: var(--accent-color-hover) !important; -} - -/* ---- ../styles/components/settings.css ---- */ -/* Settings */ -.settings-list { - background: var(--bg-primary); -} - -.settings-item { - border-bottom: 1px solid var(--border-color); - color: var(--text-primary); -} - -.settings-item:hover { - background: var(--bg-secondary); -} - -/* Theme Toggle Switch */ -.theme-toggle { - display: flex; - align-items: center; - justify-content: space-between; - padding: 15px 20px; - border-bottom: 1px solid var(--border-color); - background: var(--bg-primary); - color: var(--text-primary); -} - -.toggle-switch { - position: relative; - width: 51px; - height: 31px; -} - -.toggle-switch input { - opacity: 0; - width: 0; - height: 0; -} - -.toggle-slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #e9ecef; - transition: .4s; - border-radius: 34px; -} - -.toggle-slider:before { - position: absolute; - content: ""; - height: 27px; - width: 27px; - left: 2px; - bottom: 2px; - background-color: white; - transition: .4s; - border-radius: 50%; -} - -input:checked+.toggle-slider { - background-color: var(--accent-color); -} - -input:checked+.toggle-slider:before { - transform: translateX(20px); -} /* ---- ../styles/components/loader.css ---- */ #script-loader { diff --git a/arma/client/addons/phone/ui/_site/dist/app.bundle.js b/arma/client/addons/phone/ui/_site/dist/app.bundle.js index d2d2b3a..a270d21 100644 --- a/arma/client/addons/phone/ui/_site/dist/app.bundle.js +++ b/arma/client/addons/phone/ui/_site/dist/app.bundle.js @@ -326,6 +326,23 @@ const initialAppState = { events: [], currentEvent: null, showEventEditor: false, + + // Mobile bank state + mobileBank: { + account: { + bank: 0, + cash: 0, + earnings: 0, + transactions: [], + }, + session: { + playerName: '', + transferTargets: [], + uid: '', + }, + notice: null, + pendingAction: '', + }, }; /** @@ -1404,6 +1421,7 @@ class HomeScreen extends Component { { name: 'photos', title: 'Photos', icon: 'Photos', color: '' }, { name: 'clock', title: 'Clock', icon: 'Clock', color: '' }, { name: 'calendar', title: 'Calendar', icon: 'Calendar', color: '' }, + { name: 'wallet', title: 'Wallet', icon: 'Wallet', color: '' }, { name: 'store', title: 'App Store', icon: 'AppStore', color: '' }, ]; } @@ -2831,6 +2849,416 @@ function initializeMessagesApp(container) { window.initializeMessagesApp = initializeMessagesApp; +// ---- ../js/apps/mail/components/MailList.js ---- +/** @format */ + +class MailList extends Component { + constructor(props = {}) { + super(props); + this.state = { + searchTerm: '' + }; + + this.handleSearch = this.handleSearch.bind(this); + this.renderEmailItem = this.renderEmailItem.bind(this); + } + + handleSearch(searchTerm) { + this.setState({ searchTerm }); + } + + formatEmailTime(timestamp) { + const parsed = new Date(timestamp); + if (Number.isNaN(parsed.getTime())) return ''; + + return parsed.toLocaleString('en-US', { + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }); + } + + resolveContactName(uid) { + const contact = (this.props.contacts || []).find((entry) => entry.uid === uid || entry.id === uid); + return contact ? contact.name : uid; + } + + getFilteredEmails() { + const { emails = [] } = this.props; + const searchTerm = (this.state.searchTerm || '').toLowerCase(); + + if (!searchTerm) return emails; + + return emails.filter((email) => { + const senderName = this.resolveContactName(email.from || '').toLowerCase(); + const recipientName = this.resolveContactName(email.to || '').toLowerCase(); + return ( + (email.subject || '').toLowerCase().includes(searchTerm) || + (email.body || '').toLowerCase().includes(searchTerm) || + senderName.includes(searchTerm) || + recipientName.includes(searchTerm) + ); + }); + } + + renderEmailItem(email) { + const { currentUid, onEmailClick } = this.props; + const isSent = email.from === currentUid; + const actorName = this.resolveContactName(isSent ? email.to : email.from); + const bodyPreview = email.body || ''; + + return this.createElement( + 'button', + { + className: `mail-item ${email.read ? 'read' : 'unread'}`, + type: 'button', + onClick: () => onEmailClick && onEmailClick(email), + 'aria-label': `Open email ${email.subject || 'No subject'}` + }, + this.createElement('div', { className: 'mail-item-header' }, + this.createElement('strong', {}, `${isSent ? 'To' : 'From'}: ${actorName || 'Unknown'}`), + this.createElement('span', {}, this.formatEmailTime(email.timestamp)) + ), + this.createElement('div', { className: 'mail-item-subject' }, email.subject || 'No subject'), + this.createElement('div', { className: 'mail-item-preview' }, bodyPreview) + ); + } + + render() { + const filteredEmails = this.getFilteredEmails(); + + return this.createElement( + 'div', + { className: 'mail-list-container' }, + new SearchBar({ + placeholder: 'Search mail...', + onSearch: this.handleSearch, + value: this.state.searchTerm + }), + this.createElement( + 'div', + { className: 'mail-list', role: 'list', 'aria-label': 'Email list' }, + filteredEmails.length > 0 + ? filteredEmails.map(this.renderEmailItem) + : this.createElement('div', { className: 'mail-empty' }, 'No email yet.') + ) + ); + } +} + + +// ---- ../js/apps/mail/components/MailDetail.js ---- +/** @format */ + +class MailDetail extends Component { + resolveContactName(uid) { + const contact = (this.props.contacts || []).find((entry) => entry.uid === uid || entry.id === uid); + return contact ? contact.name : uid; + } + + formatEmailTime(timestamp) { + const parsed = new Date(timestamp); + if (Number.isNaN(parsed.getTime())) return ''; + + return parsed.toLocaleString('en-US', { + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }); + } + + componentDidMount() { + const { email } = this.props; + if (!email || email.read) return; + + if (typeof A3API !== 'undefined' && A3API.SendAlert) { + A3API.SendAlert(JSON.stringify({ + event: 'phone::mark::email::read', + data: { emailId: email.id } + })); + } + } + + handleDeleteEmail(emailId) { + if (!emailId) return; + + if (typeof A3API !== 'undefined' && A3API.SendAlert) { + A3API.SendAlert(JSON.stringify({ + event: 'phone::delete::email', + data: { emailId } + })); + } + } + + render() { + const { email } = this.props; + + if (!email) { + return this.createElement('div', { className: 'mail-empty' }, 'No email selected.'); + } + + return this.createElement( + 'article', + { className: 'mail-detail' }, + this.createElement('h2', {}, email.subject || 'No subject'), + this.createElement('div', { className: 'mail-meta' }, + this.createElement('span', {}, `From: ${this.resolveContactName(email.from) || 'Unknown'}`), + this.createElement('span', {}, `To: ${this.resolveContactName(email.to) || 'Unknown'}`), + this.createElement('span', {}, this.formatEmailTime(email.timestamp)) + ), + this.createElement('p', { className: 'mail-body' }, email.body || ''), + this.createElement( + 'button', + { + type: 'button', + className: 'mail-delete-button', + onClick: () => this.handleDeleteEmail(email.id) + }, + 'Delete Email' + ) + ); + } +} + + +// ---- ../js/apps/mail/components/MailComposer.js ---- +/** @format */ + +class MailComposer extends Component { + constructor(props = {}) { + super(props); + const contacts = this.emailableContacts(props.contacts || []); + const defaultRecipient = contacts.length === 1 ? (contacts[0].uid || contacts[0].id || '') : ''; + this.state = { + toUid: defaultRecipient, + subject: '', + body: '' + }; + + this.toRef = null; + this.subjectRef = null; + this.bodyRef = null; + this.lastSendAt = 0; + + this.handleSend = this.handleSend.bind(this); + this.syncSubject = this.syncSubject.bind(this); + this.syncBody = this.syncBody.bind(this); + } + + emailableContacts(contacts = []) { + return contacts.filter((contact) => contact && contact.canEmail !== false && (contact.uid || contact.id)); + } + + readField(id, ref, fallback = '') { + const scopedElement = this.element ? this.element.querySelector(`#${id}`) : null; + const documentElement = typeof document !== 'undefined' ? document.getElementById(id) : null; + const element = scopedElement || documentElement || ref; + if (!element) return fallback; + + if (typeof element.value === 'string' && element.value.length > 0) { + return element.value; + } + + if (typeof element.textContent === 'string' && element.textContent.length > 0) { + return element.textContent; + } + + return fallback; + } + + syncSubject(event) { + this.state.subject = event?.target?.value || ''; + } + + syncBody(event) { + this.state.body = event?.target?.value || ''; + } + + handleSend(event) { + event?.preventDefault?.(); + event?.stopPropagation?.(); + + const now = Date.now(); + if (now - this.lastSendAt < 500) return; + + const toUid = this.readField('phone-mail-recipient', this.toRef, this.state.toUid).trim(); + const subject = this.readField('phone-mail-subject', this.subjectRef, this.state.subject).trim() || 'No subject'; + const body = this.readField('phone-mail-body', this.bodyRef, this.state.body).trim(); + + if (!toUid || !body) { + console.warn('MailComposer: missing required email fields', { + hasRecipient: !!toUid, + hasSubject: subject !== 'No subject', + hasBody: !!body, + toUid, + subjectLength: subject.length, + bodyLength: body.length + }); + return; + } + + this.lastSendAt = now; + + if (typeof A3API !== 'undefined' && A3API.SendAlert) { + console.log('MailComposer: sending email', { toUid, subjectLength: subject.length, bodyLength: body.length }); + A3API.SendAlert(JSON.stringify({ + event: 'phone::send::email', + data: { toUid, subject, body } + })); + } else { + console.warn('MailComposer: A3API.SendAlert unavailable'); + } + + globalState.setState({ + showEmailComposer: false, + selectedEmail: null + }); + } + + renderContactOptions() { + const contacts = this.emailableContacts(this.props.contacts || []); + + return [ + this.createElement('option', { value: '' }, 'Select recipient'), + ...contacts.map((contact) => this.createElement( + 'option', + { value: contact.uid || contact.id }, + `${contact.fullName || contact.name || 'Unknown'}${contact.email ? ` (${contact.email})` : ''}` + )) + ]; + } + + render() { + return this.createElement( + 'div', + { className: 'mail-composer' }, + this.createElement('label', {}, + 'To', + this.createElement( + 'select', + { + id: 'phone-mail-recipient', + name: 'phone-mail-recipient', + value: this.state.toUid, + onInput: (event) => { this.state.toUid = event.target.value; }, + onChange: (event) => { this.state.toUid = event.target.value; }, + ref: (element) => { + this.toRef = element; + if (element && this.state.toUid && !element.value) { + element.value = this.state.toUid; + } + }, + 'aria-label': 'Email recipient' + }, + ...this.renderContactOptions() + ) + ), + this.createElement('label', {}, + 'Subject', + this.createElement('input', { + id: 'phone-mail-subject', + name: 'phone-mail-subject', + type: 'text', + value: this.state.subject, + onInput: this.syncSubject, + onChange: this.syncSubject, + onKeyUp: this.syncSubject, + ref: (element) => { this.subjectRef = element; }, + placeholder: 'Subject' + }) + ), + this.createElement('label', {}, + 'Message', + this.createElement('textarea', { + id: 'phone-mail-body', + name: 'phone-mail-body', + value: this.state.body, + onInput: this.syncBody, + onChange: this.syncBody, + onKeyUp: this.syncBody, + ref: (element) => { this.bodyRef = element; }, + placeholder: 'Write email body...', + rows: 8 + }) + ), + this.createElement( + 'button', + { + type: 'button', + className: 'mail-send-button', + onClick: this.handleSend, + onMouseDown: this.handleSend + }, + 'Send' + ) + ); + } +} + + +// ---- ../js/apps/mail/index.js ---- +/** @format */ + +function initializeMailApp(container) { + const { emails, contacts, currentUid, selectedEmail, showEmailComposer } = globalState.getState(); + const appContainer = document.createElement('div'); + + appContainer.className = 'app-container'; + appContainer.setAttribute('role', 'main'); + appContainer.setAttribute('aria-label', 'Mail'); + + if (typeof requestEmails === 'function') requestEmails(); + if (typeof requestContacts === 'function') requestContacts(); + + const navBar = new NavigationBar({ + title: selectedEmail ? 'Email' : (showEmailComposer ? 'New Email' : 'Mail'), + showBackButton: !!selectedEmail || !!showEmailComposer, + rightButton: (!selectedEmail && !showEmailComposer) ? { + element: 'button', + props: { + type: 'button', + className: 'nav-button add-button', + onClick: () => globalState.setState({ showEmailComposer: true, selectedEmail: null }), + 'aria-label': 'Compose email', + style: { + fontSize: '24px', + padding: '0 15px', + background: 'none', + border: 'none', + color: 'var(--accent-color)', + cursor: 'pointer' + } + }, + content: '+' + } : null + }); + navBar.mount(appContainer); + + const contentContainer = document.createElement('div'); + contentContainer.className = 'content mail-content'; + appContainer.appendChild(contentContainer); + + if (showEmailComposer) { + new MailComposer({ contacts }).mount(contentContainer); + } else if (selectedEmail) { + new MailDetail({ email: selectedEmail, contacts }).mount(contentContainer); + } else { + new MailList({ + emails, + contacts, + currentUid, + onEmailClick: (email) => globalState.setState({ selectedEmail: email, showEmailComposer: false }) + }).mount(contentContainer); + } + + container.appendChild(appContainer); +} + +window.initializeMailApp = initializeMailApp; + + // ---- ../js/apps/contacts/components/ContactList.js ---- /** @format */ @@ -3295,415 +3723,152 @@ function initializeContactsApp(container) { window.initializeContactsApp = initializeContactsApp; -// ---- ../js/apps/mail/components/MailList.js ---- -/** @format */ +// ---- ../js/apps/settings/components/Settings.js ---- +/** + * @format + * @class Settings + * @extends Component + * @description A settings component for the phone app. + */ -class MailList extends Component { - constructor(props = {}) { - super(props); - this.state = { - searchTerm: '' - }; +class Settings extends Component { + /** + * @constructor + * @param {Object} props - Component properties + */ + constructor() { + super(); + // Get current theme from document attribute + const currentTheme = document.documentElement.getAttribute('data-theme'); + this.state = { isDarkTheme: currentTheme === 'dark' }; + } - this.handleSearch = this.handleSearch.bind(this); - this.renderEmailItem = this.renderEmailItem.bind(this); - } + /** + * @method componentDidMount + * @description Sets the initial theme when the component mounts + */ + componentDidMount() { + // Get current theme from game + const alert = { + "event": "phone::get::theme", + "data": {} + }; + A3API.SendAlert(JSON.stringify(alert)); + } - handleSearch(searchTerm) { - this.setState({ searchTerm }); - } + /** + * @method updateTheme + * @param {boolean} isDark - Whether the theme is dark + * @description Updates the theme and phone screen background + */ + updateTheme(isDark) { + const theme = isDark ? 'dark' : 'light'; - formatEmailTime(timestamp) { - const parsed = new Date(timestamp); - if (Number.isNaN(parsed.getTime())) return ''; + // Update document theme + document.documentElement.setAttribute('data-theme', theme); - return parsed.toLocaleString('en-US', { - month: 'short', - day: 'numeric', - hour: '2-digit', - minute: '2-digit' - }); - } + // Update phone screen background + const phoneScreen = document.querySelector('.phone-screen'); + if (phoneScreen) { + phoneScreen.style.background = isDark ? '#000000' : '#ffffff'; + } - resolveContactName(uid) { - const contact = (this.props.contacts || []).find((entry) => entry.uid === uid || entry.id === uid); - return contact ? contact.name : uid; - } + // Save theme preference to game + const alert = { + "event": "phone::set::theme", + "data": { + "isDark": isDark + } + }; + A3API.SendAlert(JSON.stringify(alert)); - getFilteredEmails() { - const { emails = [] } = this.props; - const searchTerm = (this.state.searchTerm || '').toLowerCase(); + // Update state + this.setState({ isDarkTheme: isDark }); - if (!searchTerm) return emails; + // Dispatch theme change event + const themeEvent = new CustomEvent('themeChanged', { + detail: { theme } + }); + document.dispatchEvent(themeEvent); + } - return emails.filter((email) => { - const senderName = this.resolveContactName(email.from || '').toLowerCase(); - const recipientName = this.resolveContactName(email.to || '').toLowerCase(); - return ( - (email.subject || '').toLowerCase().includes(searchTerm) || - (email.body || '').toLowerCase().includes(searchTerm) || - senderName.includes(searchTerm) || - recipientName.includes(searchTerm) - ); - }); - } + /** + * @method handleThemeToggle + * @description Handles the theme toggle click + */ + handleThemeToggle = () => { + const newTheme = !this.state.isDarkTheme; + this.updateTheme(newTheme); + } - renderEmailItem(email) { - const { currentUid, onEmailClick } = this.props; - const isSent = email.from === currentUid; - const actorName = this.resolveContactName(isSent ? email.to : email.from); - const bodyPreview = email.body || ''; - - return this.createElement( - 'button', - { - className: `mail-item ${email.read ? 'read' : 'unread'}`, - type: 'button', - onClick: () => onEmailClick && onEmailClick(email), - 'aria-label': `Open email ${email.subject || 'No subject'}` - }, - this.createElement('div', { className: 'mail-item-header' }, - this.createElement('strong', {}, `${isSent ? 'To' : 'From'}: ${actorName || 'Unknown'}`), - this.createElement('span', {}, this.formatEmailTime(email.timestamp)) - ), - this.createElement('div', { className: 'mail-item-subject' }, email.subject || 'No subject'), - this.createElement('div', { className: 'mail-item-preview' }, bodyPreview) - ); - } - - render() { - const filteredEmails = this.getFilteredEmails(); - - return this.createElement( - 'div', - { className: 'mail-list-container' }, - new SearchBar({ - placeholder: 'Search mail...', - onSearch: this.handleSearch, - value: this.state.searchTerm - }), - this.createElement( - 'div', - { className: 'mail-list', role: 'list', 'aria-label': 'Email list' }, - filteredEmails.length > 0 - ? filteredEmails.map(this.renderEmailItem) - : this.createElement('div', { className: 'mail-empty' }, 'No email yet.') - ) - ); - } + /** + * @method render + * @description Renders the settings component + */ + render() { + return this.createElement('div', { className: 'settings-list' }, + this.createElement('div', { className: 'theme-toggle' }, + this.createElement('span', {}, 'Dark Mode'), + this.createElement('div', { + className: this.state.isDarkTheme ? 'custom-toggle active' : 'custom-toggle', + onClick: this.handleThemeToggle, + style: { + width: '50px', + height: '25px', + backgroundColor: this.state.isDarkTheme ? '#0a84ff' : '#e9ecef', + borderRadius: '34px', + position: 'relative', + cursor: 'pointer', + transition: 'background-color 0.2s' + } + }, + this.createElement('div', { + style: { + width: '25px', + height: '25px', + backgroundColor: '#fff', + borderRadius: '50%', + position: 'absolute', + left: this.state.isDarkTheme ? '25px' : '0px', + transition: 'left 0.2s' + } + }) + ) + ) + ); + } } +// ---- ../js/apps/settings/index.js ---- +/** + * @fileoverview Main entry point for the Settings application + * + * This module initializes the Settings app UI, including: + * - Rendering the Settings component + * - Mounting the Settings component into the provided container + * + * The initializeSettingsApp function is exposed globally for use by the main app. + */ -// ---- ../js/apps/mail/components/MailComposer.js ---- -/** @format */ - -class MailComposer extends Component { - constructor(props = {}) { - super(props); - const contacts = this.emailableContacts(props.contacts || []); - const defaultRecipient = contacts.length === 1 ? (contacts[0].uid || contacts[0].id || '') : ''; - this.state = { - toUid: defaultRecipient, - subject: '', - body: '' - }; - - this.toRef = null; - this.subjectRef = null; - this.bodyRef = null; - this.lastSendAt = 0; - - this.handleSend = this.handleSend.bind(this); - this.syncSubject = this.syncSubject.bind(this); - this.syncBody = this.syncBody.bind(this); - } - - emailableContacts(contacts = []) { - return contacts.filter((contact) => contact && contact.canEmail !== false && (contact.uid || contact.id)); - } - - readField(id, ref, fallback = '') { - const scopedElement = this.element ? this.element.querySelector(`#${id}`) : null; - const documentElement = typeof document !== 'undefined' ? document.getElementById(id) : null; - const element = scopedElement || documentElement || ref; - if (!element) return fallback; - - if (typeof element.value === 'string' && element.value.length > 0) { - return element.value; - } - - if (typeof element.textContent === 'string' && element.textContent.length > 0) { - return element.textContent; - } - - return fallback; - } - - syncSubject(event) { - this.state.subject = event?.target?.value || ''; - } - - syncBody(event) { - this.state.body = event?.target?.value || ''; - } - - handleSend(event) { - event?.preventDefault?.(); - event?.stopPropagation?.(); - - const now = Date.now(); - if (now - this.lastSendAt < 500) return; - - const toUid = this.readField('phone-mail-recipient', this.toRef, this.state.toUid).trim(); - const subject = this.readField('phone-mail-subject', this.subjectRef, this.state.subject).trim() || 'No subject'; - const body = this.readField('phone-mail-body', this.bodyRef, this.state.body).trim(); - - if (!toUid || !body) { - console.warn('MailComposer: missing required email fields', { - hasRecipient: !!toUid, - hasSubject: subject !== 'No subject', - hasBody: !!body, - toUid, - subjectLength: subject.length, - bodyLength: body.length - }); - return; - } - - this.lastSendAt = now; - - if (typeof A3API !== 'undefined' && A3API.SendAlert) { - console.log('MailComposer: sending email', { toUid, subjectLength: subject.length, bodyLength: body.length }); - A3API.SendAlert(JSON.stringify({ - event: 'phone::send::email', - data: { toUid, subject, body } - })); - } else { - console.warn('MailComposer: A3API.SendAlert unavailable'); - } - - globalState.setState({ - showEmailComposer: false, - selectedEmail: null - }); - } - - renderContactOptions() { - const contacts = this.emailableContacts(this.props.contacts || []); - - return [ - this.createElement('option', { value: '' }, 'Select recipient'), - ...contacts.map((contact) => this.createElement( - 'option', - { value: contact.uid || contact.id }, - `${contact.fullName || contact.name || 'Unknown'}${contact.email ? ` (${contact.email})` : ''}` - )) - ]; - } - - render() { - return this.createElement( - 'div', - { className: 'mail-composer' }, - this.createElement('label', {}, - 'To', - this.createElement( - 'select', - { - id: 'phone-mail-recipient', - name: 'phone-mail-recipient', - value: this.state.toUid, - onInput: (event) => { this.state.toUid = event.target.value; }, - onChange: (event) => { this.state.toUid = event.target.value; }, - ref: (element) => { - this.toRef = element; - if (element && this.state.toUid && !element.value) { - element.value = this.state.toUid; - } - }, - 'aria-label': 'Email recipient' - }, - ...this.renderContactOptions() - ) - ), - this.createElement('label', {}, - 'Subject', - this.createElement('input', { - id: 'phone-mail-subject', - name: 'phone-mail-subject', - type: 'text', - value: this.state.subject, - onInput: this.syncSubject, - onChange: this.syncSubject, - onKeyUp: this.syncSubject, - ref: (element) => { this.subjectRef = element; }, - placeholder: 'Subject' - }) - ), - this.createElement('label', {}, - 'Message', - this.createElement('textarea', { - id: 'phone-mail-body', - name: 'phone-mail-body', - value: this.state.body, - onInput: this.syncBody, - onChange: this.syncBody, - onKeyUp: this.syncBody, - ref: (element) => { this.bodyRef = element; }, - placeholder: 'Write email body...', - rows: 8 - }) - ), - this.createElement( - 'button', - { - type: 'button', - className: 'mail-send-button', - onClick: this.handleSend, - onMouseDown: this.handleSend - }, - 'Send' - ) - ); - } -} - - -// ---- ../js/apps/mail/components/MailDetail.js ---- -/** @format */ - -class MailDetail extends Component { - resolveContactName(uid) { - const contact = (this.props.contacts || []).find((entry) => entry.uid === uid || entry.id === uid); - return contact ? contact.name : uid; - } - - formatEmailTime(timestamp) { - const parsed = new Date(timestamp); - if (Number.isNaN(parsed.getTime())) return ''; - - return parsed.toLocaleString('en-US', { - month: 'short', - day: 'numeric', - hour: '2-digit', - minute: '2-digit' - }); - } - - componentDidMount() { - const { email } = this.props; - if (!email || email.read) return; - - if (typeof A3API !== 'undefined' && A3API.SendAlert) { - A3API.SendAlert(JSON.stringify({ - event: 'phone::mark::email::read', - data: { emailId: email.id } - })); - } - } - - handleDeleteEmail(emailId) { - if (!emailId) return; - - if (typeof A3API !== 'undefined' && A3API.SendAlert) { - A3API.SendAlert(JSON.stringify({ - event: 'phone::delete::email', - data: { emailId } - })); - } - } - - render() { - const { email } = this.props; - - if (!email) { - return this.createElement('div', { className: 'mail-empty' }, 'No email selected.'); - } - - return this.createElement( - 'article', - { className: 'mail-detail' }, - this.createElement('h2', {}, email.subject || 'No subject'), - this.createElement('div', { className: 'mail-meta' }, - this.createElement('span', {}, `From: ${this.resolveContactName(email.from) || 'Unknown'}`), - this.createElement('span', {}, `To: ${this.resolveContactName(email.to) || 'Unknown'}`), - this.createElement('span', {}, this.formatEmailTime(email.timestamp)) - ), - this.createElement('p', { className: 'mail-body' }, email.body || ''), - this.createElement( - 'button', - { - type: 'button', - className: 'mail-delete-button', - onClick: () => this.handleDeleteEmail(email.id) - }, - 'Delete Email' - ) - ); - } -} - - -// ---- ../js/apps/mail/index.js ---- -/** @format */ - -function initializeMailApp(container) { - const { emails, contacts, currentUid, selectedEmail, showEmailComposer } = globalState.getState(); - const appContainer = document.createElement('div'); - - appContainer.className = 'app-container'; - appContainer.setAttribute('role', 'main'); - appContainer.setAttribute('aria-label', 'Mail'); - - if (typeof requestEmails === 'function') requestEmails(); - if (typeof requestContacts === 'function') requestContacts(); - +// Initialize the settings app +function initializeSettingsApp(container) { + /** + * Navigation bar with toggle button + * - Button toggles add contact form visibility + * - Icon switches between '+' (show form) and '-' (hide form) + */ const navBar = new NavigationBar({ - title: selectedEmail ? 'Email' : (showEmailComposer ? 'New Email' : 'Mail'), - showBackButton: !!selectedEmail || !!showEmailComposer, - rightButton: (!selectedEmail && !showEmailComposer) ? { - element: 'button', - props: { - type: 'button', - className: 'nav-button add-button', - onClick: () => globalState.setState({ showEmailComposer: true, selectedEmail: null }), - 'aria-label': 'Compose email', - style: { - fontSize: '24px', - padding: '0 15px', - background: 'none', - border: 'none', - color: 'var(--accent-color)', - cursor: 'pointer' - } - }, - content: '+' - } : null + title: 'Settings' }); - navBar.mount(appContainer); + navBar.mount(container); - const contentContainer = document.createElement('div'); - contentContainer.className = 'content mail-content'; - appContainer.appendChild(contentContainer); - - if (showEmailComposer) { - new MailComposer({ contacts }).mount(contentContainer); - } else if (selectedEmail) { - new MailDetail({ email: selectedEmail, contacts }).mount(contentContainer); - } else { - new MailList({ - emails, - contacts, - currentUid, - onEmailClick: (email) => globalState.setState({ selectedEmail: email, showEmailComposer: false }) - }).mount(contentContainer); - } - - container.appendChild(appContainer); + // Create and mount the Settings component + const settings = new Settings(); + settings.mount(container); } -window.initializeMailApp = initializeMailApp; - +// Make initialization function globally available +window.initializeSettingsApp = initializeSettingsApp; // ---- ../js/apps/notes/components/NotesList.js ---- /** @@ -5815,153 +5980,6 @@ function initializeClockApp(container) { // Make initialization function globally available window.initializeClockApp = initializeClockApp; -// ---- ../js/apps/settings/components/Settings.js ---- -/** - * @format - * @class Settings - * @extends Component - * @description A settings component for the phone app. - */ - -class Settings extends Component { - /** - * @constructor - * @param {Object} props - Component properties - */ - constructor() { - super(); - // Get current theme from document attribute - const currentTheme = document.documentElement.getAttribute('data-theme'); - this.state = { isDarkTheme: currentTheme === 'dark' }; - } - - /** - * @method componentDidMount - * @description Sets the initial theme when the component mounts - */ - componentDidMount() { - // Get current theme from game - const alert = { - "event": "phone::get::theme", - "data": {} - }; - A3API.SendAlert(JSON.stringify(alert)); - } - - /** - * @method updateTheme - * @param {boolean} isDark - Whether the theme is dark - * @description Updates the theme and phone screen background - */ - updateTheme(isDark) { - const theme = isDark ? 'dark' : 'light'; - - // Update document theme - document.documentElement.setAttribute('data-theme', theme); - - // Update phone screen background - const phoneScreen = document.querySelector('.phone-screen'); - if (phoneScreen) { - phoneScreen.style.background = isDark ? '#000000' : '#ffffff'; - } - - // Save theme preference to game - const alert = { - "event": "phone::set::theme", - "data": { - "isDark": isDark - } - }; - A3API.SendAlert(JSON.stringify(alert)); - - // Update state - this.setState({ isDarkTheme: isDark }); - - // Dispatch theme change event - const themeEvent = new CustomEvent('themeChanged', { - detail: { theme } - }); - document.dispatchEvent(themeEvent); - } - - /** - * @method handleThemeToggle - * @description Handles the theme toggle click - */ - handleThemeToggle = () => { - const newTheme = !this.state.isDarkTheme; - this.updateTheme(newTheme); - } - - /** - * @method render - * @description Renders the settings component - */ - render() { - return this.createElement('div', { className: 'settings-list' }, - this.createElement('div', { className: 'theme-toggle' }, - this.createElement('span', {}, 'Dark Mode'), - this.createElement('div', { - className: this.state.isDarkTheme ? 'custom-toggle active' : 'custom-toggle', - onClick: this.handleThemeToggle, - style: { - width: '50px', - height: '25px', - backgroundColor: this.state.isDarkTheme ? '#0a84ff' : '#e9ecef', - borderRadius: '34px', - position: 'relative', - cursor: 'pointer', - transition: 'background-color 0.2s' - } - }, - this.createElement('div', { - style: { - width: '25px', - height: '25px', - backgroundColor: '#fff', - borderRadius: '50%', - position: 'absolute', - left: this.state.isDarkTheme ? '25px' : '0px', - transition: 'left 0.2s' - } - }) - ) - ) - ); - } -} - -// ---- ../js/apps/settings/index.js ---- -/** - * @fileoverview Main entry point for the Settings application - * - * This module initializes the Settings app UI, including: - * - Rendering the Settings component - * - Mounting the Settings component into the provided container - * - * The initializeSettingsApp function is exposed globally for use by the main app. - */ - -// Initialize the settings app -function initializeSettingsApp(container) { - /** - * Navigation bar with toggle button - * - Button toggles add contact form visibility - * - Icon switches between '+' (show form) and '-' (hide form) - */ - const navBar = new NavigationBar({ - title: 'Settings' - }); - navBar.mount(container); - - // Create and mount the Settings component - const settings = new Settings(); - settings.mount(container); -} - -// Make initialization function globally available -window.initializeSettingsApp = initializeSettingsApp; - // ---- ../js/apps/calendar/components/Calendar.js ---- /** * @format @@ -6569,6 +6587,445 @@ function initializeCalendarApp(container) { // Make initialization function globally available window.initializeCalendarApp = initializeCalendarApp; +// ---- ../js/apps/wallet/index.js ---- +/** @format */ + +let lastMobileBankRequest = 0; +let mobileBankNoticeTimer = null; +const MOBILE_BANK_REQUEST_COOLDOWN = 1000; + +function defaultMobileBankState() { + return { + account: { + bank: 0, + cash: 0, + earnings: 0, + transactions: [], + }, + session: { + creditLine: { + amountDue: 0, + approvedAmount: 0, + availableAmount: 0, + outstandingPrincipal: 0, + }, + orgName: '', + playerName: '', + transferTargets: [], + uid: '', + }, + notice: null, + pendingAction: '', + }; +} + +function getMobileBankState() { + return { + ...defaultMobileBankState(), + ...(globalState.getState().mobileBank || {}), + }; +} + +function setMobileBankState(patch) { + globalState.setState({ + mobileBank: { + ...getMobileBankState(), + ...patch, + }, + }); +} + +function formatMobileBankCurrency(value) { + const amount = Math.floor(Number(value || 0)); + return `$${Math.max(0, amount).toLocaleString()}`; +} + +function normalizeMobileBankAmount(value) { + const amount = Math.floor(Number(value || 0)); + return Number.isFinite(amount) ? amount : 0; +} + +function sendMobileBankEvent(event, data = {}) { + if (typeof A3API !== 'undefined' && A3API.SendAlert) { + A3API.SendAlert(JSON.stringify({ event, data })); + return true; + } + + showMobileBankNotice('error', 'Bank bridge is unavailable.'); + return false; +} + +function requestMobileBankRefresh(force = false) { + const now = Date.now(); + if (!force && now - lastMobileBankRequest < MOBILE_BANK_REQUEST_COOLDOWN) { + return false; + } + + lastMobileBankRequest = now; + return sendMobileBankEvent('phone::bank::refresh', {}); +} + +function requestMobileBankTransfer(target, amountValue) { + const targetUid = String(target || '').trim(); + const amount = normalizeMobileBankAmount(amountValue); + + if (!targetUid) { + showMobileBankNotice('error', 'Choose a recipient.'); + return false; + } + + if (amount <= 0) { + showMobileBankNotice('error', 'Enter a valid transfer amount.'); + return false; + } + + setMobileBankState({ pendingAction: 'transfer' }); + const sent = sendMobileBankEvent('phone::bank::transfer::request', { + amount, + from: 'bank', + target: targetUid, + }); + + if (!sent) { + setMobileBankState({ pendingAction: '' }); + } + + return sent; +} + +function requestMobileBankDepositEarnings() { + const state = getMobileBankState(); + const availableEarnings = normalizeMobileBankAmount(state.account.earnings); + + if (availableEarnings <= 0) { + showMobileBankNotice('error', 'No earnings are available to deposit.'); + return false; + } + + setMobileBankState({ pendingAction: 'depositearnings' }); + const sent = sendMobileBankEvent('phone::bank::depositEarnings::request', { + amount: availableEarnings, + }); + + if (!sent) { + setMobileBankState({ pendingAction: '' }); + } + + return sent; +} + +function requestMobileBankRepayCreditLine(amountValue) { + const amount = normalizeMobileBankAmount(amountValue); + const state = getMobileBankState(); + const amountDue = normalizeMobileBankAmount(state.session.creditLine?.amountDue); + + if (amountDue <= 0) { + showMobileBankNotice('error', 'No credit line payment is due.'); + return false; + } + + if (amount <= 0) { + showMobileBankNotice('error', 'Enter a valid payment amount.'); + return false; + } + + setMobileBankState({ pendingAction: 'repaycreditline' }); + const sent = sendMobileBankEvent('phone::bank::repayCreditLine::request', { + amount: Math.min(amount, amountDue), + }); + + if (!sent) { + setMobileBankState({ pendingAction: '' }); + } + + return sent; +} + +function updateMobileBank(payload) { + const current = getMobileBankState(); + setMobileBankState({ + account: { + ...current.account, + ...(payload && payload.account ? payload.account : {}), + }, + session: { + ...current.session, + ...(payload && payload.session ? payload.session : {}), + }, + pendingAction: '', + }); +} + +function updateMobileBankAccount(accountPatch) { + const current = getMobileBankState(); + setMobileBankState({ + account: { + ...current.account, + ...(accountPatch || {}), + }, + pendingAction: '', + }); +} + +function showMobileBankNotice(type, message) { + if (!message) return; + + setMobileBankState({ + notice: { + type: type || 'info', + message, + }, + pendingAction: '', + }); + + if (mobileBankNoticeTimer) { + clearTimeout(mobileBankNoticeTimer); + } + + mobileBankNoticeTimer = setTimeout(() => { + setMobileBankState({ notice: null }); + mobileBankNoticeTimer = null; + }, 3200); +} + +function mobileBankTransactionRows(transactions) { + const rows = Array.isArray(transactions) ? transactions.slice(0, 5) : []; + + if (rows.length === 0) { + const empty = document.createElement('div'); + empty.className = 'wallet-empty-state'; + empty.textContent = 'No recent transactions'; + return empty; + } + + const list = document.createElement('div'); + list.className = 'wallet-transaction-list'; + + rows.forEach((entry) => { + const row = document.createElement('div'); + row.className = 'wallet-transaction-row'; + + const copy = document.createElement('div'); + copy.className = 'wallet-transaction-copy'; + + const title = document.createElement('span'); + title.className = 'wallet-transaction-title'; + title.textContent = entry.type || 'Transaction'; + + const meta = document.createElement('span'); + meta.className = 'wallet-transaction-meta'; + meta.textContent = entry.date || 'Pending timestamp'; + + const value = document.createElement('span'); + value.className = 'wallet-transaction-value'; + value.textContent = formatMobileBankCurrency(entry.amount || 0); + + copy.append(title, meta); + row.append(copy, value); + list.appendChild(row); + }); + + return list; +} + +function initializeMobileBankApp(container) { + const state = getMobileBankState(); + const { account, session, notice, pendingAction } = state; + const transferTargets = Array.isArray(session.transferTargets) + ? session.transferTargets + : []; + const creditLine = session.creditLine || {}; + const amountDue = normalizeMobileBankAmount(creditLine.amountDue); + const outstandingPrincipal = normalizeMobileBankAmount(creditLine.outstandingPrincipal); + + requestMobileBankRefresh(false); + + const appContainer = document.createElement('div'); + appContainer.className = 'app-container wallet-app'; + appContainer.setAttribute('role', 'main'); + appContainer.setAttribute('aria-label', 'Wallet'); + + const navBar = new NavigationBar({ + title: 'Wallet', + rightButton: { + element: 'button', + props: { + className: 'wallet-nav-button', + type: 'button', + disabled: pendingAction !== '', + onClick: () => requestMobileBankRefresh(true), + 'aria-label': 'Refresh wallet', + }, + content: 'Refresh', + }, + }); + navBar.mount(appContainer); + + const content = document.createElement('div'); + content.className = 'content wallet-content'; + + if (notice && notice.message) { + const noticeElement = document.createElement('div'); + noticeElement.className = `wallet-notice wallet-notice-${notice.type || 'info'}`; + noticeElement.textContent = notice.message; + content.appendChild(noticeElement); + } + + const hero = document.createElement('section'); + hero.className = 'wallet-balance-card'; + hero.innerHTML = ` + Available Balance + ${formatMobileBankCurrency(account.bank)} + ${session.playerName || 'Personal account'} + `; + content.appendChild(hero); + + const metrics = document.createElement('section'); + metrics.className = 'wallet-metrics'; + metrics.innerHTML = ` +
+ Cash + ${formatMobileBankCurrency(account.cash)} +
+
+ Earnings + ${formatMobileBankCurrency(account.earnings)} +
+ `; + content.appendChild(metrics); + + const bankingActions = document.createElement('section'); + bankingActions.className = 'wallet-card'; + + const bankingTitle = document.createElement('div'); + bankingTitle.className = 'wallet-card-title'; + bankingTitle.textContent = 'Account Actions'; + + const earningsAction = document.createElement('div'); + earningsAction.className = 'wallet-action-block'; + + const earningsSummary = document.createElement('div'); + earningsSummary.className = 'wallet-action-summary'; + earningsSummary.innerHTML = ` + Deposit Earnings + ${formatMobileBankCurrency(account.earnings)} available + Move mission earnings into your bank balance. + `; + + const earningsButton = document.createElement('button'); + earningsButton.className = 'wallet-secondary-button wallet-full-button'; + earningsButton.type = 'button'; + earningsButton.disabled = pendingAction !== '' || normalizeMobileBankAmount(account.earnings) <= 0; + earningsButton.textContent = pendingAction === 'depositearnings' ? 'Depositing...' : 'Deposit Earnings'; + earningsButton.addEventListener('click', () => { + requestMobileBankDepositEarnings(); + }); + earningsAction.append(earningsSummary, earningsButton); + + const creditAction = document.createElement('div'); + creditAction.className = 'wallet-action-block'; + + const creditSummary = document.createElement('div'); + creditSummary.className = 'wallet-action-summary'; + creditSummary.innerHTML = ` + Credit Line Payment + ${formatMobileBankCurrency(amountDue)} due + ${session.orgName || 'Organization'} - ${formatMobileBankCurrency(outstandingPrincipal)} outstanding + `; + + const creditControls = document.createElement('div'); + creditControls.className = 'wallet-action-controls'; + + const creditAmount = document.createElement('input'); + creditAmount.className = 'wallet-input'; + creditAmount.type = 'number'; + creditAmount.min = '1'; + creditAmount.step = '1'; + creditAmount.placeholder = amountDue > 0 ? 'Payment amount' : 'No payment due'; + creditAmount.setAttribute('aria-label', 'Credit line payment amount'); + creditAmount.inputMode = 'numeric'; + creditAmount.disabled = pendingAction !== '' || amountDue <= 0; + + const creditButton = document.createElement('button'); + creditButton.className = 'wallet-secondary-button'; + creditButton.type = 'button'; + creditButton.disabled = pendingAction !== '' || amountDue <= 0; + creditButton.textContent = pendingAction === 'repaycreditline' ? 'Paying...' : 'Pay Credit'; + creditButton.addEventListener('click', () => { + requestMobileBankRepayCreditLine(creditAmount.value || amountDue); + }); + + creditControls.append(creditAmount, creditButton); + creditAction.append(creditSummary, creditControls); + bankingActions.append(bankingTitle, earningsAction, creditAction); + content.appendChild(bankingActions); + + const transferCard = document.createElement('section'); + transferCard.className = 'wallet-card'; + + const transferTitle = document.createElement('div'); + transferTitle.className = 'wallet-card-title'; + transferTitle.textContent = 'Transfer'; + + const targetSelect = document.createElement('select'); + targetSelect.className = 'wallet-input'; + targetSelect.setAttribute('aria-label', 'Transfer recipient'); + targetSelect.disabled = pendingAction !== '' || transferTargets.length === 0; + + const placeholder = document.createElement('option'); + placeholder.value = ''; + placeholder.textContent = transferTargets.length === 0 ? 'No online recipients' : 'Choose recipient'; + targetSelect.appendChild(placeholder); + + transferTargets.forEach((target) => { + const option = document.createElement('option'); + option.value = target.uid || ''; + option.textContent = target.name || target.uid || 'Player'; + targetSelect.appendChild(option); + }); + + const amountInput = document.createElement('input'); + amountInput.className = 'wallet-input'; + amountInput.type = 'number'; + amountInput.min = '1'; + amountInput.step = '1'; + amountInput.placeholder = 'Amount'; + amountInput.inputMode = 'numeric'; + amountInput.disabled = pendingAction !== ''; + + const transferButton = document.createElement('button'); + transferButton.className = 'wallet-primary-button'; + transferButton.type = 'button'; + transferButton.disabled = pendingAction !== '' || transferTargets.length === 0; + transferButton.textContent = pendingAction === 'transfer' ? 'Sending...' : 'Send Transfer'; + transferButton.addEventListener('click', () => { + requestMobileBankTransfer(targetSelect.value, amountInput.value); + }); + + transferCard.append(transferTitle, targetSelect, amountInput, transferButton); + content.appendChild(transferCard); + + const historyCard = document.createElement('section'); + historyCard.className = 'wallet-card'; + + const historyTitle = document.createElement('div'); + historyTitle.className = 'wallet-card-title'; + historyTitle.textContent = 'Recent Activity'; + + historyCard.append(historyTitle, mobileBankTransactionRows(account.transactions)); + content.appendChild(historyCard); + + appContainer.appendChild(content); + container.appendChild(appContainer); +} + +window.initializeMobileBankApp = initializeMobileBankApp; +window.requestMobileBankRefresh = requestMobileBankRefresh; +window.updateMobileBank = updateMobileBank; +window.updateMobileBankAccount = updateMobileBankAccount; +window.showMobileBankNotice = showMobileBankNotice; + + // ---- ../js/app.js ---- /** * @fileoverview Root application component and integration logic. @@ -6662,6 +7119,9 @@ class App extends Component { case 'settings': window.initializeSettingsApp(appContainer); break; + case 'wallet': + window.initializeMobileBankApp(appContainer); + break; default: return this.renderPlaceholderApp(currentApp); } @@ -6683,7 +7143,8 @@ class App extends Component { mail: '', icloud: '', photos: '', - safari: '' + safari: '', + wallet: '' }; return this.createElement( diff --git a/arma/client/addons/phone/ui/_site/images/dark/Wallet.png b/arma/client/addons/phone/ui/_site/images/dark/Wallet.png new file mode 100644 index 0000000000000000000000000000000000000000..0d7928056165c9634e70167272a1550df26ba1e0 GIT binary patch literal 65969 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
2m9R;ge7cr^w#@=+^qhT&JZVQtV4i}-@w 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

hK27 zin?KlvfhXyvlk8sPY!YCNg`F&f}H&P@w8VGt_uQZ;JN@G7C9#57~p1v=^()~sl21) z<^RfcEpPeK4R>6_&{%h523SO^3ns}@0jH%b=gx5)DdbB*oI-D6@PKxmLHx>y{4=DM z7?9L}R1=eA&bL^rvhLjIPcAGD0KC1I(NeoAVE}=KB{WzYA_n@qmWib{1&2$<;D++D z3X{c@btlUIuKt~Q&HXA4?D2vV$1x({7%2w~2{?M>(9z@4kz%+tM~_G4SDG@jZ$g|J zNHI^nYP=#|6>;fy=h+dXo*O-S#52grcyW&;ULMOu=rNdQ4WR7B6aqe&6&R8%@*IX(4z_Va{$ zEHptS)Fq*p(0dD@sAum&AoP$z5)ufV)ZLl+y+6-v`Zn%=f5_}^cAt6XnVHRe-t+l< zp3kf6gx}%u6@HiD?p1lo4#_J5{ES7^qzLhb+~fap&lF|)WTSv;+t1Ppm|KN~m+}yV zCddddVYw(-SLPNS>qz~Q@a^1X40jNt76=NCQPu!@)DY_zgiDd^&FphWJJM`3H0|8E z%UCY@DGNZA#0V);yd+p2!JG}KPp+b&^q!V}kuh_MQY-vyAXzkYrCQZ7LM{(YtX z#hAo0_?{*YAJ5NBBq2&SY@Irf`Po8}KS4?)vb~COy+{b)Pei4c63aUE>@(=t*-U6x zB6ta%)X_g#p!8{tvZTa>ghVVZtYvatqgp=BgkBFH$vcwRk#&}7Y@MFsl2aF+*snys zDHjFyD>^=TI0qwx<5cLRbRNa^zUaK@qN+lSTH*(BawpAvbKbxNxQRiyd9SZRzfR=^^S@lY09L+JQ~CirYDsVPh#?uG(x~~1DTg2UU=!ZlLxU=d{g7N?5BhQ$^$Sx z9zheMo)8`{A3pZo?~fmZkC`_c!yUhf`isMb$AsZ|j}3o}J%)KvSRQ$lKj86^N1k}; z%VWPM;4T59L4tFq2~hm_k-k>HB2V+93K~g|UjOS~xa0WYVMB)wc~~5J71;tqAAbJR zL%(Bl$cYf4$XV-n6+D!^&2FXo z9xCd4p!7#pbE*xJ5d#2oG?E6I8oFuP@hC%gJX#DrG%byi1|pF(K#2pG$cNMcZ5gAy z0a~=_;bXCs*yXb2#qxO!A1f-Ckr#)r-)`@&-Me?myOmvkOEM-_xg0jEAf1=cP{BI% zjN1*YfKlvHpG%Sx$}voPYyss*<321nW3)()mbO)G z-S!MJ%S2ZNz6!S3+!72^DijI?v~5Y9Y%P8oJA&LZoF!Xq&IR1-udpJe(0htuZA4GXW$_4)8vWFA13=r`?M6 z&dJDO649qnAY(1ufMSucM%AXx@K$UVHwl|PnUtsQ7k#)8U1T+Isd8P5dw z(pJngq)iGM8l6>kYy0dA$V@k(ZzD3rjTns)4U8KVL^8yU-lt%&C<)GEx5k}3FJXf? zu)Lu_E8titd@iB9(X(MZ+Dfh}9Fe#mu$zM34Ew6(GkvfM27s+^@QjCTM!#rlkKa_& zR-*mNk19}c`87nXSI|nNli;++zgUc+M;5601ri$Q{fO(d^%3i?jKeP59q12zb@;LX z+3q-{1;%{r6Ygi}c;Sv*TBofwty3pBP4*iO9G#)33-Zq5R#(i|uvDDQLo5mBBZB{m zjjvUobIPa;S8B7ywtM0y1eJ1fBwXPY#C63SH8&>`zt9bVxJFoOTBE+~kZsrOHoMIl z-@Z-!M_->llVe8Gk&vtAYyRmFtwvj!H9oF=o7T5j z`wTNZTtfB%_Kl1jGU6T{It1CJSZhZ_TGi^bw26**-zu@-+qQ0va^bgWx5~anyiEWt zO1hQWTUIO6?eUUTuuHZIYaEO1(7s*UwqiR0i`urG)K+LGVv*ZwZP0wXWtBS5C0Qf* zXyRgHJ9LPPlVgQAEmrIx#%di*u|fxUp!cj=wGuz_s`8cHtk!s|)rLbP+9azIA4eO* z=!AG7E+Srw6XP{2dfpecQXORz8GbX_0TRF_P@val#Vak|Xw_^+v{DbOw5(A7ZI$9Z zID&TGXBA%H2S`dR=+*`TfX!~Q;rssS^5rX*uP`lF7Iws@MVrN5j+LmwfDL<#&Dtca zgF1q62QCwrSHbVhu!zf*XKYq6o~j8O?Sjoqo5Bl+gkL18WK0{wnE%scnKH-aYbn~X z*$6NVj1Ix>#h4r>w7LA%(xuDrU;kOQ^d-9(uUc&}=ndm_T*Y^hj|g8({I?@7PyKm` zyi~&?EV;UE%v9`pxSe@n)t@KT$@jH;*>JV%y{$?FA{fhF+n6&VpMND2SEYcQBi>ekcT0E^2 z4yc4(7ad0I7S15HsGxT={c3g0BF{&?ZB~3UqwxWbBpTolzyoriS!&gSkq&qdM`E7Gjdv$>uF075>0&RXYmbO@=1@L`+zNY(pi~GRa=JryPc~S1Hx6QGw%=0k+ zW?$F2sJe4tRr@)@+~_$m?q>foyNt@5*>jq^AN-g3c6KFscC!A1sanaiXD4G~k9J_! z+BV7B?5N~h4dvR8pMSnDefy?O;tDOL%`7dMgdVOr`@AG2Fq@oIP4;IfX6-Q>Ce|{n|Q3! z6z!#g8`xT5@r{kc9(`gsx|jE8yN!F)=Y7J4IUQ&!p&eaYWjxd6ys)z9O2(wW{Pi*H zz;5+#a2jJTp>T4FjrlNyXQT4vf{Oft!jfy5pRR+p*;TZA*RE=9lK^d#Tbz$eGy?ue z`pj3)=F4XzU@es5OP3*Sc6kvF*(vW*cK$7iLEAvKU!q!r;STj#-Vm9}_P880%*!+7BI6W`lpC4nJqv?@ zi~sg(m?yb?`wl!l2iXV_QpNBMj?F$N=HbfEEd|!e5%DrASH=7$gUshwdbe$V7Fq0Q z?{eB=&zzGeLp7U9HASMaF$Y7~=6wb|N@#%&vkFligKSW?oD-2N}BtQ9NV9g08k` z6Uf{P+>FPbDv-0Apqx`AZ-S3ED-#lMi+mY>aOmh%el`_;%Hl3u`idhoI4L2ULJdo*uXN-BBGOkwT{4I~~4NV0z zo<=2x(_)r_j&UB>YU?7_ULEU`IyjE;9rj_s6;!f;wv1zlstG2n!X)2166R2w)~ZiA zMSBUqO5-RF$~;3ezOjdN*u9j;E1#~!Za^8Tny|Ve?Vk?P05(7=HM24Q~9K=P@H zgS-R#KQxe}O2lfZY&B0xi8oB$1^#^R+G zXNrXw+P!k+3jD|`%U9GDLrlVIwOYssy#Y{>u7>tTtsphT#ZUw+D9jwJqZxZbdqa9< zg=M)q2^~O8kVa833T}RN9aL(?(SmKJ!O`)?-^v%uAZ?bLmMLx$L$H?&M$>}N${;+b z9d=oQp~mig-DH{iG~bdLpTnR+kvT{zN!%<$+n~`8O_nONN&H|0P&&HZC2>Hq1o8~l z-iUUWe#U%y{MUb$E_u-o?bnRt4?{~xE1O-0-Nr5*T`Vurun3FQ)IKBzOk8q_4%JSE z-GMtX^bUdHlRcZ7F80iV?7^4?M+G(qE#*KlKI-aXe@29Nb{k5ep}Ohp2gkkU2~g=n7L5~?=Kq{WSHBwHqV9l zInZ?u#Lu^@+Rql|M9)So!r%6~@614eQGwKHZYck0@5))p$+MDYiOJe56BapHm?b1% z!8`g7eTD|4iN4#r-ZhK#Q05Qceeu~YWLK|*9{NO^rRyP)Dje|Wz4s-gtzxE8QdOcO z9#{32XRgEk6`gr>08OwNJQzlm9ner3LHYc^OLC_haKAcgYEmmI@!oPv~MMB*nVxFxL??J`R{NulJ5yt&mNzZhe;VSF0@E7!gXE3MOVSfxXfqeks~H* zpYr#PiE;#X(|WOkmQrF2Pd!=HqBKgpCOMbQI5FNxhGGGCuCgu zk>!R}kZW~PIHh9Juc2Ibf-!i)#B}v}c$O-mt+2OP0kbWRAp;L7CC87OPIxKT4;O^= zJrZ1DC>-)aq6GIoD#F=gPv+2M4vEjU&=40Bka{9fJqT3Jh}v`Id1x!5_fgXm*~d{| zLp_T0Ir*4;RLHD4iWy-HQ^Jm_$B^4a@)8|W#R161V`orkf<6;6O-Ca#v6=~Ogx$g} zVK%Kw_2io{yugbTlf{bVSWOYC_^y)GjYRMrhy$wu_!numaT&jYovc$Rkpw z=SU{attC16l_EsC*J0s^c38%OdArmUvJ$}qUKrmVn|T^N z9L|vOp@JkiDZ|K{)2jFa?a;PMJG{?gWQaD9+B$j)t;G!Ca7D&pY#6m}Xm%|M>tGQW zwgq#H7(Z(DVcNpwZOjIQb~*0cQ3iqPgoLex6O7s7e>*82F&~b~h(rqo z30mS7dF$0JaAHyD17B;q^|RBoZ^jJuaE5fqggym~0NriTHp^SCJq`B}MM!Xxt;;dd z*~7C2CGnB~-MHx)e1&jBjay7>hXKE4 z{(g`~eMmuOpb>{&J#a3*SDe&Vu$Njpw26Ih_fJ1#4vU0N!pe|KQfmof$q1K`P){!@yVtEXuk+4ya07|0RbgxJ9<^#Gv=`ec zZQGGh+7r3fv&Nl3O-QAv)_5jD7?Hoo7$-p>>3T_lCkd_ho8cp?OzX~-iwRB?m_ZW> z0jLb~et_emid#{oT}P5gKttZ`>82|y z|A9jZ6=5P54#_9H@{lw^J9LOICpye-x}s`XKYn2FrUuc%wF%81Mn|#}&K;aiZJV@Q zTVY&Yv10l1xjmsIOr(l{Yj+x%qsmS$P_)N4OIJw0NXvy~((*DAh|6arpuG_zlh7$V zSq@woOlT(6wJ}STPaZ%Ue35Vj>Ffyn zbB$rxI84|-$e)Aa5_Rbkap?^%5lJL29F3a_I)CKNqZKuK3|f|-T#VdL{49=GQi&Q( z)BCt^T7V$q8z5=M2Z6q!l74ToxN`aQCvij0`++ZxWFhwsIaFrnM~Z%jljvAl6vUxv zQN@zQ(_bFkkuLGR8QB!!MRZt8j4+g+fE46Yl|(2*G4(iprHMJv3oVASlk44|A2Yk|hL$?H&Aq_n))t6Zj9A*aA*z0AzCd%gUqH2- z*EgB3Er^*fEHL6ZVt$OF^32!nxZ_mWWqxym_xRWA=1TLlxy`Xi^MtwTytzia6z7qi zI{x*RHgmOkQFBRC<(xSF>kpsp*(0VwCC}03w#1_As_>`i){WV*y1)GY^IEH{Gj$o$ znDxk{=H)Y-*=#**iLcjjJ(P*B#In0FHCj{kSf?KM)Y5wRrch%#_3>_eVs$iPrAVC1 zxPvBMXLX`k*l}ti<`!d8w&Kv}un3;ADzBoHUA}tl;zbD=Gqgk?Fn8%c%i%` z+s@k}(LzalDqY;I?J@1fcn~LzLL4yyZMI)JH&P5d&kt->mLxLv)muP21Z3ZP_>@IPK0`HwfO3PqA zrxlqHHAGq^76s8lxrjHG;aXD?MzEb0w4$0zFo)6nTrWACR*y?1*c` z4)ZpZiX-zt6oOH5p-7=C6FFv!inHt}CXs+{Jx#XoVY^1tgo40fe{s-wmSF)&pR45o6TD= zd6G}9r#ettp-fZm3yX?QqLH5OQt3iF#2m%V8W!qSLy!30o|is8ily1b?C+8~UaL?Kz73 zbPPm9r=vEL%g?wGz7_Ihw-3 zj)~KD{$+7`Q7@O5khDc4(h>rEyr_l`h5c=KW9JkT3 z9)H|uMte@tQyM^%f--itV1JyA!i@X?jM{*R;(8-o)nY*a6x9lxI9kJQ@8oxyMoo8jt3>0?9@EAze|+5wG4SaPpD;l=fqwXpTM`0Pqf zF6EZ+AC{ey2lp}ZMkYmwDQpKtfhQZBF8qmP9fgz-RQxb% zg@y|{sS>W*a9qhTM*WybE~1ggwwA3}zCvE^f%01MDfSF%gPdX_96p+(IrfKp>a6PP z>qLkyVYvq3MG5L$jIl4^tGPJ;skdl(o zw+X@9cl0?w0IEa1Ij6BY$ELr+3uDI9_ z9vL*Fm65-+!AgXb+Xr)a6h z6eTrfm(fr`2hffKM;=SsQJd8av034GdhSXD7E{E9<`gfyap@)lmH$Cf1^sc-MOdNA zK2Dr(S5?PHU!T5gY0HJ`+Px;jnd#G}Oo8M>ym0E2sZ(8(Cr_O+W%AUilc!9ZIWNV% zGIgPQVWb=3ODs@x`yvdAdx6{R-Zj(gaHmF!)yYxh1Vnpw$B5lXbo(o)0~R=*L%z&qd%eTAjKg6jtKGPs#=bA0a!Q+Gin+@^}U2hPy8nBliXud@T7Q zzd+M(-gB5dA)_^v)wq4)o(hUN(ht^qr0mh>zPnnC3vdDK7ULNoup2y*hc2pU)kFv* z3~R(*^B#3K36>Q*j$ST-K`syx@I%xQ_Ann;V^|P5zr66Iu39Lwbi`f@36{(1g(4ZB z2?fS{@vJGo9K~l&P%FqFfwavYahJB+vin*S=v%D=;$?`&djo4v9qh{Gc zjyYRGhu*Wt?2s9i++{OjyLqd+4VnbOE(F~K0AnPA#_$jyUQ+Ypb|)p-D&x1oF@%sL zTttvvXEciYA+{%HMVzUEkvnGN&D06oERZe~h>OXR7y@$@XYgqz*EWz&38S}e-eQK) zvLLvpW+4_v0W}frgwv(jxw%Ks5V8?Yas^Gv7o;z^BxfP6hyREQQoxai{p74lc$BGg zT@xv;r#F*qq3D|tF+@f&J_Hfb_y&fNdjwjH4k7hEVY3DDg9iW+g~R~ha7Ncv6l0^^ z!m8O-IR|x}!{ys3%nlbe8cC7VjKYlW1&p5}qbMKsg%z@h&MAb>h)wI+h7IdCtVgN# z^;k*7kZ7+FR;2JB-&l6eidwP5HH?;JI-^ohQ$RG4LW6WV#*x&a3!vf}w*lpqaXTd8 z3~*!*^@TB0nIZCQXYYpGq2g#H&Df~*2q&&HLYatw`yglwm$VTvNAfVs7zsvm%9HiW zpW^KiBzVSQCaJcDnrq}VM!6pK_z5$L?}!KoRvbTZ>Z>8KR=eyZ6PEDeItzr00%x>% z@+!>-#}CC9(d-n0jmOK69b}(P;*v*(iAGe+^~zer57&rk>Y6ls#Rr{1j1d2+ScJX| zMC5Sbpn(Gh41SRCm15(5wg-zVas2~-nvrWCc(Az2lNkoFUR)`xkg$*l z@aZ0-9-%^qBz<7WxhaQ$u-Ts6Xwh53#KO#SuZz(xBdo@wV=$uj=~2r`eenInKETn$ zrG##}Wo(%ewmh~q$e&s+FY_!%sPR8IWay5h5@{dui0LUnWXU0+Y_R-TNquc?)H3ZG z(my7=t^3Bvmt#go9jOfLY`lHFxKvwaUW$pn5DW+ik^rLKY&i4~E!^#d02%sYo;Oy* zjbwsT2@?wpEM5ZtJ$c5+n`VN>Fk;lyC$(}cX}Xxp zAJJ*V4wRAO3|qzU>Zm$w6-sgTlBSEa&r!-JA@=vS7n-@0$#7vKDJgsUBC zNCisn4f?exJI8{w65wnr2B2peqR+jlpMb;VI zYh^kUO&z_M(>eAF@j%7r2R=s$l>-Ox6&+kLXz;)RQ%mx)&A6<}xbV`YItT5MfKA~^ zxN|57iQu9{?FUs1cxd39^8nq@MVRtqkf@?Z7q6VbYLvH4KS`a&AE4qXH*onH^VP*X zvQDQNF4(6PL>EmI_&b7GtjG$dO^oD|SgRIoK765&_Dqjfo>ox|_>^?|27-lW4wE!O z*HV&q2xv$$9|G)#1p8sqQ&5h< zhMYV}?M=w`N*ue7f{Gp_tN}&i^XRksUy-QIJ%7F#>x~BOB68AuKXyX zi^oqMgu^BA5;>~i#Db@b{?h}D0YZFYCg#r_L0C}Eq)6WpJYLI0AQ5p;iMyaP*6Tnk$LpQL1c<6EIGq; zxH#i*=F#K7aR-b~x+umcW>jJjzgV57v=EQbZqueDz8xInBUg_tve|JZ zBrOLg(YA;!3a`SC&e`G0BecJ?0uP$fx->q4e=r*BArXwGfQ{SAePM?cw5J9V_8Gxm ztVfM2G7e>Kj)UroaH*rVNYJ51$PNmrULjZsez4!Xh}}W)keY!wWI3uJAO4y>2nA?@ zvoB#h++ymcjnXD?dT^K#QAEYK-+znv)l1<;@mJ$-<%jkUgq-5uCPb?eUfjHKgBhCi z`oZ6RudZWq@Hg>y;WzK^D3~YxF8*5n-OjgSJH+FN$uNvc!mHdtCiWBh=h6hdzI_;q z_xAa7pFRjEVgg^kKmWOZulBdKCASlqOe6w1-`*Ixo;!pfnHox{3P`9}_?e&~$nWBO z7lBB1{W^KQhQBtYU3)#0$Q?)sDYln+4ps#eRXnW(o9$#I*i_eS-EpSjuP!2vGSc-Z zqljlE&I;#{9xH>Tb}hE7rDnP##0YC^!h%>SDJzm3CJaS&ZL+N4QA2cxf~FK_BeM;k#p@fRR%yRcSCZof`6ifyM#r@ci5O}K z#|CCEKqA;TAofWAAq~a+L9Awe?-wbOoO}>_8=B6IV~PVH&AMzrz`$I+t3O3oDf6d*D9OLz8eJAr%RS z(oV;~?6{1P(~-0}=B`{$qH(#nOkS>i2gnh2jJkr1rgfy2Z=X${wf3Kdr@L?K_Aj z+*eDOF+`VY1XW-)=(<-*c?}7j9(&`%6)P-=Hi}rJMe63`CPV3r52sC?Idl5d=`*H@ z(}k%Qrca$V?L$0F|78B6)HO>NBha`g)wt+7MH^|M$0GnIq(T`&*`+EesduJWP)gB= zUz?_CKbj3aQnZ~AP!N7*WXs>O&;zH|LcCVjXGR*lP*q$lUt2 z?U_-At_!pupt5*8QCYC`NVLJ^jxIL0XFp>SVI-o5&9F3`r!4(B6Y6TNH|_f)C!wz9 z%xwx^lw}U~EUkRYo^QVSHS@%2uCV^Q0AizFARpc@9pfxS&A$G=}^@n%yL<`=3ZkYc3o=zB!T&x4XBX{!A&}U4F zH(cNH=%asRLmnCWP(PGzA1L*^)_)L6E+X}|f8PQ9`#;pqP<7zJ2YUCq*W!o%+s07& z>>p4U#6Rp;>e<@hdHaETdZLhoU(oMu2G8L8dZOq9qXG~p@KG1=d#l0o$9qDseQz;T zJ#Y`$20>}QtqkRVx|`4*fl0oMcyBEY*Zbca4#fAa9xV*zFZ8Oxx}nAe)jdIh5!9uq zMfbKaC=c94poDHzqAd`zx4EJ6p}QGXp5PTC>f?HG;HYv6Dtt6EC{NuJE~>YgL45&u zi%^VSG`mmd^D`oOzTPpuBE%|C!Q z2B$ep_->5BdtXE7F4Y(C%iKlddr>Mx?8f}#c4G_|@7HTYmkTTt;l%;Aq?!!_m8L3X6+_&>h8SsKP=BD6Tk)2_x|b z+aoL*E{;Zz@L0GQLAQV;+&UoK7z4}e##5k?jU5*KmQEhZC4|Mj#g3u#;Lux!bA0(u zD&2r$UT{DJW8U&@hbG+$^tI_0CgPTP(fCfl&%!0#;?Q~oa?st7qzZ!`#01|`U&@~2C81o06h0b`o zT4z+V$50Ne4q_HcRish=JMpXER z#FC`o2EE&5*neJkwwevrh!E>j6p%7O*|2EVJ2)5CS8o?zGB3#koksxu7YGQ8hHvT( zgF;|^Qi5uCQROu1IS}_1rsoe0nXk+r^c9=#6&~!BFktwL)U^cdNkGagHr|`QK@AA6 ztO4Q`n?|!BcvsL}V+>_nQsDa(F4YxVzsoPlmH9=vA_3JWC<1a^(IcsdpcGdenY*d} zSrB$B!{v`OgVg2H9i2jvTXArp9m40fQr{tPt&9jEK3prB-_~Z z&)R^_iv2I_aZ^mz8ubt!k(JIoWN;uDEAvNV#d+)D6A+RF!6&~MB$z0KeqbRXf01OVjy08DQ+T>JCA{@|sI zfb_Q*%DFQmB($`Z;mV)6Ln9EYl!ONNWKb>7hL}>H_PGlZ;>BJ*LMcjgqB<#6#P@?J zZDH{K;jU0%Qp`^nbax#XX%E!UY{(*QW~h4VUcVqx)}sN5l=Mc=a44kB4Bq?UhzSfH z#kbAN9Vf84RM6fpZItn1qA`Z6Z{9-%KzT7uJai9)8to1RJg6sEazq<|cc39<6yM%I zghd#QF_hoegK^;kX^L|3{?MW*-H83@6@n^?CijO=6vfqs`z{D1%21!P4oS2wNEFTR zRSJt9il+Dq1Y(EsPoaJNkV7S=)FFprH|`CC8S3jVAStx^^G2M|dYDk0r+d1|3>EIf zq=dp!-+hy8P;8@Ta2zNTB~3)L9-(QV)G9a&6gv*@M;Q3e7{jri)bNhZEKKYt?MYqa zXGr2FjW#6j6Zij@XvAS)KGEM@H%0f1Fzkl< zqIp+>f`-rR#Gm?|1nXqs(K=~I!^U*-#*HAI$eQuP=%hf%H8HZ|14CYTd*Y;bfZv)Z zP7)>xlRWQCnmF+tynd&hp;Bn`)cjv7l(t$MgI6B9w=zy^ZSV>Ye6LzHFg}|s@!B!1 zOtt^y)Na9nJLl3`8Ptx&2{h%b`H@7e1?v8;N}{LXN)l$Hsm-%H(xkNaJ82B|u4!Q> zt(id^*_j?!bjGALRX)p~620`K4Z4FK-{Oz&^G6Uw@y;Ipcz{2C{@*>a|8BMab}h^& zGzbH1Nsc;+i%dIN1p6I?2V1(v4AE8gl_ikbzk4XOWFm2 zZI%;k^Pb)hzkd045S4=QHG2(X@3i(0*7Wwge*#WwIj<^@67l|_nkbch&xk{}_+Xl$ zSei$BL|wZLJ43CBI}{j)$#fp(d-&$- zz@mUCOl<$oXFW0Daxe#7j1gw%Zq*XqFb^LHD{b4GVE~7Du z;Ec*~yt}|`O6YG6r+ggk8lWi~ktzAm!r@Ym!4V7-M#+3MO63mPmzxDq4#%i(4ns+6 z)P+zoPN8fBq4c0K`Y3$4Z-zWM8tud4PJ$am!{EqC7A|v=PEbhDBrri99D3Z-C<@0* z)~8F3!G{gllFS|T|l1eB3t?)`{H^q;nzkDJ`h5?QoT^5Z@7p^!4)hLc?!O@=!4hF^X zx~@0^V;Xz+>fLw9;&uV>jHQqWz%$-+KNlQ9p^UwTLT=Q9F|tN9#wySldp`x~5sJhJ zBMbHMWR3a=31HOahmPeY`9Z`*#J?IK7j+Sm*Rm0BkvvL0ONawg4ex=KCn*A9+mN$Z z3||xXD%ImG-pl1kJ+dOJCUz6>MCmaIg!eFUib`WO5*VZC6C|gr1xYnSQK0w}g$3cY zs>4vMl_P=qiM4u!&@;i|i9Rvn11BOzRl`kW^_bjCaa)9A3d~^uSYovv37?YK<6pWa z2>?iB6faY_8VQO=L=(t}AWTG(A|Y{zFX0ceJ_?ZqWg+^+Nag-O48(c}L{cK5$%kBv z)Nl`3F!13x*wK2(!&QEXhjc}{Db67c!ACe`K@o>_35Rr{43llBbR7jt6BgKz)shWK zs)Pg@(uMt|aE7#k5Ey32s%eJRFvBrq#j6R1Il&2rBw50y7Y;`*XAQfs23^SfvI|Kb zghMVQ%pr|899*HVZ39*z`!X1;uv)3y45*MF@cB2wgcCAC8{%tzQ%pjxWBd>a{QwD- zP9$UkV+h%y8V(_*gVT3BZ2q81N+w+RV2z3yTc10~f`bRu8iji$OxhsrLfEXqF;xs- z%HWtm%w9vf6An(bnyDQ4&|u7SeMszo9h^u;p}qt9^&dRsu@OEo69nPMwG7-R zfU6O{k3j`M0Kmb4*cNg2#JeiFmU#otlX~pFV)BG=5MH(U$1lBxO{^+^Y1{P6jZIm>GJe3bv{^QKUQEg+hYTquFDdoEn2^wSfh}B0vlv>sv#orpi_O5g7M91UK?!&T3vyjIq7-_E- zw8y234&e)e*@JKBxvCg2_E>1h-jG7>N%05RGy3D}LBxc`)`MH6ipQTCgZ1D?2?*8m z!_*^RN@$!OBn;ig)Mx22zc4*6X6k_S{BiV@9;9ac6ZE{@xDy4pZmJQ~Jpbf8k}F2$ z7o1m*n>QNm!l34jgCPosmp2yDpq7%yfXNF?$>Un-CK!2i@e7-d*R=}CQ>-huKB6Rv zf)omiM+!v{1hDM_S63cQ0(~j zvCd7g>qxp1wT}70)&-!}aZwsRvySgZ0Ak&>8e$#t&pXon%S~YFs&$Bf*qAWs+`kYg z``0`F!ZK+RLTHmFzVoj)NBsGL4#qe`JFUul{w-^#Mb*bEnW>_tfT5|B+2Q3Xrnp*Wh3qwauJs#DZ=3u=;k7`kL zGec)h8_OSe(xZB#X$%4K9_EjXKd$DF|Di`UOQMNfYMGHgmDfHY{-sv`YHIjlozH65 zX#8fd^@4pyeX`ok2iru5&k(-u!XYwYpz&bLyVi2?SR*hVa$%6-9S#u>MjA2PkQ6-H zU_ksG1OEsP=) zcsm4;x=^FWSUXmqYlrQ1!YtFER68HkjyDa2w8IyoGfMpiK-pn}QAdmhGsj)v_5>%{ z;p8MGxWdBN(MD16J0!dg?K-&}4i2ni^@()_Vm@HxR0PsofGwk0KwKSq=?I%c6&wR$ z>d*vr?0x8#Mszv}wa8?~OK9T!B+>NiU~D=Jrz7oLATnKy;R-fJ^S5cHcK{|GPFiPY zT^JohJu$yDI<&kq92Ong^>PHI(CH95wCn8!ccxm_?4s>ZoqypD>5b7K3KSfhsiNy)j)5SrreUtP%&$Bx(7QBoo$528%wt_j9Ev_a;-Vr5jRA4U98jOY0pWF`P;d&9?on-^J{hi+ z!FztR3yn~7kqT@YQNKX13_vxNFw;eQp&P0VGyuWfYN*s$FaH!c%)mMLd{3vH7h^~D z1k1{AS4YN?I4PtOw z8g)emu@NGTp=4q{F14_Rp$Ta<&4TgKC|Lp(_+Z00!Ym*Y4V`sK6d7;l^an#DGl70W zqR`NhZZkOut(Jp^s|0Ky>_agA8ADnaGO0R}8S#rhLocv@!Qp2$>@y6dbGXDa8n(;C z!o!^LV?p*QAmfZ$aEp)Hf%Xt=Gqi;o;dYTZZ1G?FW12NEi9vy8bc||EV*s2P{y3`b zBUm5RATvhg2T}Q|mSm=b%;-qo1i}o>?+hDYhQ?$vQ3J(R%D^rQjxNJosNTG=2@1Br zc80+#L;qc1>->Yt>T=4^kPWnlhLoY*AO~HrLjuZRLEo!yLH$$7YAh%NptUiRjGNDJ zab(pNluEVug^-~E3@9Ct#so4Hydg^mH)^k2=)^Lfsv{vi;?65!~->x@Snh9tqhf9Kw%@P8P&~g*_*nI zuo}yWTNx;NKYTDUofSWPylfUXov&4!&evc%8MmEp)!5Fi!I@jQRNfg1wFP6@JuJQ! zzJ%RaFuYbhx)%NjFrg|qSBvgQ!zOCc#P5zM_@|?^LXosESWJ!%i=#z<|6x$Hcr$QI zgOamouTl9eBrppHy$ewgg5t7#v@G=58GUkA7V{6w!rpcch{%HZxC4ecC?E^l=mg+; zNIDi=HE0+P9E-LJs}&9w3#IXJJg@`w_YfR~#dujczPkVnghj%_KyaH2-9iMcx&SPE z`@m!)cW7Yl724pYmWoR0#48pQc|`{Y^Al=;R}Fbr7&xear1QfgUC}|TN4H`D@K)Gz zHy0Jh56QMd%lmGEY=!2%>kzG2L!?z>q7~NY5)Q=*`!*2JC0tu^*VKq#g--{=GKy3Y zm(W$BUQ>?68sqAtt6=Zn=T~=Bpbr48LX+aoHo8xxI%>gLRWPNv>kEjfVs=}|x1?%}Z?xFm^sG1up%KnIh0vqd}M8&AwS_?zfzq^plp*u~#7%H-! ziLgku=&6R}DddZ(Pf#^Ex}Wq*o8mW~iLiN8!mS!L#YB{a^RcFGfpL7HI~p|NOkr3$ zW{TU-`}|O)_&w;|fjCmP8!D79UVaF=6TNewy91|we6HB6?PzYQTPwEW~YXbgY6h)ZB12jE`?N(i2;li1yc|9~!ATkpVTl!}*QRue; zjEOa%G0|oMu$Wv46oCp2Vj6*TqJa3Nk@&DKbcy+)F3}jmLoQLv5VR$5lj!sX!YnbJ zvs4$eL`NwUWJ#qjS8%|R;-WVGu}Za6C5AHlG~ppEsM6R9>M%4?i9&yVU`h>GN{S0% zS!NImF@}&dBr3_u8}E&& zMgjOoAU%Ewaz`(bil@f-BgHleGpR`4F{*1%C2kwSk5t=MBp%@-@(NSY|9ZfqS1vU} zVO+gHZ3D=W#~N?jezjRJx)GXKU%Y||kamd$gBty5Pm2I3BgL_Vj1FQu!8t}VFSNu~ zd`N+Y2%|X_tqi{X_s1-{C-urLsLbmhRWxF!dTR})=wi*?Iy4ks51joQ%v}IDk;gG6 z`G@Pb`+!7)n3umWRw$R_%rJOCinWAZ2o+!lg!pa$phaC6v@!oxtJ zX^i0^i>SaaOb{Nh2++4*1`pZ8n<4O!1!}yU}OIjYX9I050XbQI^Sq!9dYbQmxuFfzC$ zcfm@A3(?`mG6XyaHOp(wWI$pLv)P8jSdw`o?=_i3qg}`4RM6e5)jkoHGB_(owQV6& z>8q&@QyGwt^ABz|>#}he!EtVojmD2P-cFV?1Qkbp@hWC)2V&un&7@-MbR*w@fTJ7D z`t%zB7wX!0I1wNi$ZGm0-^_-|$u^#Uyp)w~k@(VYt!s&xOJD2Yi?YU>Le;)WgCAqQcN+DoiE}pUKde z1j8DmV7SQ)0f6E5AYA+lH|u`kFIP^ny7ZSsZZ(5*UkE2d_V6ZXFLcl8hxNiyFRU)> zg$C-M@>0pMC-ix^Xcul!InyO5(uJwx=ytO)(dA-BL!t{;av@kQx-kw9;KGe81K$KJ zm2mhiWNm}fTWa7fG}Q30EiA!FB6{s=5gXe+d-)OT`o8j(&-yMrtlzNKOQ2?ymR+5IT|dh?SnBlu?6dzW|J#>F zUL^B`@gD_x(zfz+b4+T&>%YcOPI~3-{ArIsPuhfLl)8Sk6+LMmHK(NZQ_Y$)%5nGf zZGk6k2G4t6Be$ev_?=O$49JaF+{RmoH*#Tucq`@3d)KyUZHU*rCCl#+Zs!U1r3aUc zifU)bN&aZYN6E83n)%7cAIf#6+|oAk=Q93AWbS4Cxx%S8 zuvDZ!m};Ip%w2AaJlMPif3y0*(tZN(&C-6F-uSUs_1-M))Actxt zcdw)9^aj!nH%2l%{lpiM<8O7hY-%~^ zwj4uGQRWkF);r2-F)Mn*2R_n!ii*^kE>SJ?osDw7pf~8eGX1S%k&Ewg=dQLKY#z98Re1xwkyr z@hUGS4Z$P9epTT59^<5dIBm`ra%0IxFM!PMW^ALVx3vRQ-AJGW~h!$BEX26CE|h+6t{*u586KjwT;3nN m$^5OD!K?NDVhnfbZ?u}MKPUdIKlk2BBXg#w{nm8!;Qt4DxZi^S delta 11069 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 diff --git a/arma/client/addons/phone/ui/_site/images/light/Wallet.png b/arma/client/addons/phone/ui/_site/images/light/Wallet.png new file mode 100644 index 0000000000000000000000000000000000000000..66bf53cf14289a50bd2078db14946d6d3b9948e4 GIT binary patch literal 65969 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 z z_|wiVmtFAu#(JU*){iNW;(z+Fzv@5qzr>u|?BfX29h4?yh+iR{bfzUXOe9Df`w z`+8iMciZs1Z z{f7BnYVONsrH_xH^3yTr*Q-v_2J2CsgW;zi!}TD>aPN>q4=HocJbv>qeP4Y?u`lir z{Zn83`fc}bzVVc8+wjqEl=j%=WzU0Om(~Ozeb`h^lnihX&l9QY7=IA2+T_u8UsEsb zq;6s+JvCjo%drQrF71gh>|3>**j~;(ITD}Rd01jQbCPw^Si7|O9hI;CXKoI~;BP$T zjLkpr+|!?(7>`v~j~`1i_?!e=@4V%d2k!s&$T4adV)PhRlS!vpnB*MDoH*tj*f#gF zQ9R=w7|Q;o+KJFgCOrpskXO$!l3ru2z70+iCnaN{UdG1>u)q8qiMy}sPdM?zmz{h1 zkEOi>sSkPrB?SU;AQqpI}Wlaz;NvsDFa$C!YSCa`{CscwA%oxRf%-SAX`F z{(W0+E)Q?}PLd9ye&U0kd&Itv!%y7CK?L-qiPoime~`VhW_ERX`WesbU;e@~cSZMo@@2k$-ej@xcR&wH^0Aa`)DZUfU%yRlxE!aO8UKTE~!C|DcQjt?Q^ zfX1_dz-sDR$iszp71`!_TCQ|h{wHvihTzA_Y3)>z#e%pih;%?tV2*A)8Y$hdDlAitH zdS86fHPB=5$#D`XR8P2^%$n5JH|ucl%x8aG8TNmi%>HPJ|9EgxcMU$E`;3#$EGuhg zH^1!s13%H*pI=Yf1V|$YaMPzgzj@1^oe%YP?Rcm>aNoVj`mWd9`{Ty!ciq%;qmS-dxCHlVCl(j@b8YzP z*ZD`vB7U-)<S+%B2 z { + setMobileBankState({ notice: null }); + mobileBankNoticeTimer = null; + }, 3200); +} + +function mobileBankTransactionRows(transactions) { + const rows = Array.isArray(transactions) ? transactions.slice(0, 5) : []; + + if (rows.length === 0) { + const empty = document.createElement('div'); + empty.className = 'wallet-empty-state'; + empty.textContent = 'No recent transactions'; + return empty; + } + + const list = document.createElement('div'); + list.className = 'wallet-transaction-list'; + + rows.forEach((entry) => { + const row = document.createElement('div'); + row.className = 'wallet-transaction-row'; + + const copy = document.createElement('div'); + copy.className = 'wallet-transaction-copy'; + + const title = document.createElement('span'); + title.className = 'wallet-transaction-title'; + title.textContent = entry.type || 'Transaction'; + + const meta = document.createElement('span'); + meta.className = 'wallet-transaction-meta'; + meta.textContent = entry.date || 'Pending timestamp'; + + const value = document.createElement('span'); + value.className = 'wallet-transaction-value'; + value.textContent = formatMobileBankCurrency(entry.amount || 0); + + copy.append(title, meta); + row.append(copy, value); + list.appendChild(row); + }); + + return list; +} + +function initializeMobileBankApp(container) { + const state = getMobileBankState(); + const { account, session, notice, pendingAction } = state; + const transferTargets = Array.isArray(session.transferTargets) + ? session.transferTargets + : []; + const creditLine = session.creditLine || {}; + const amountDue = normalizeMobileBankAmount(creditLine.amountDue); + const outstandingPrincipal = normalizeMobileBankAmount(creditLine.outstandingPrincipal); + + requestMobileBankRefresh(false); + + const appContainer = document.createElement('div'); + appContainer.className = 'app-container wallet-app'; + appContainer.setAttribute('role', 'main'); + appContainer.setAttribute('aria-label', 'Wallet'); + + const navBar = new NavigationBar({ + title: 'Wallet', + rightButton: { + element: 'button', + props: { + className: 'wallet-nav-button', + type: 'button', + disabled: pendingAction !== '', + onClick: () => requestMobileBankRefresh(true), + 'aria-label': 'Refresh wallet', + }, + content: 'Refresh', + }, + }); + navBar.mount(appContainer); + + const content = document.createElement('div'); + content.className = 'content wallet-content'; + + if (notice && notice.message) { + const noticeElement = document.createElement('div'); + noticeElement.className = `wallet-notice wallet-notice-${notice.type || 'info'}`; + noticeElement.textContent = notice.message; + content.appendChild(noticeElement); + } + + const hero = document.createElement('section'); + hero.className = 'wallet-balance-card'; + hero.innerHTML = ` + Available Balance + ${formatMobileBankCurrency(account.bank)} + ${session.playerName || 'Personal account'} + `; + content.appendChild(hero); + + const metrics = document.createElement('section'); + metrics.className = 'wallet-metrics'; + metrics.innerHTML = ` +

+ Cash + ${formatMobileBankCurrency(account.cash)} +
+
+ Earnings + ${formatMobileBankCurrency(account.earnings)} +
+ `; + content.appendChild(metrics); + + const bankingActions = document.createElement('section'); + bankingActions.className = 'wallet-card'; + + const bankingTitle = document.createElement('div'); + bankingTitle.className = 'wallet-card-title'; + bankingTitle.textContent = 'Account Actions'; + + const earningsAction = document.createElement('div'); + earningsAction.className = 'wallet-action-block'; + + const earningsSummary = document.createElement('div'); + earningsSummary.className = 'wallet-action-summary'; + earningsSummary.innerHTML = ` + Deposit Earnings + ${formatMobileBankCurrency(account.earnings)} available + Move mission earnings into your bank balance. + `; + + const earningsButton = document.createElement('button'); + earningsButton.className = 'wallet-secondary-button wallet-full-button'; + earningsButton.type = 'button'; + earningsButton.disabled = pendingAction !== '' || normalizeMobileBankAmount(account.earnings) <= 0; + earningsButton.textContent = pendingAction === 'depositearnings' ? 'Depositing...' : 'Deposit Earnings'; + earningsButton.addEventListener('click', () => { + requestMobileBankDepositEarnings(); + }); + earningsAction.append(earningsSummary, earningsButton); + + const creditAction = document.createElement('div'); + creditAction.className = 'wallet-action-block'; + + const creditSummary = document.createElement('div'); + creditSummary.className = 'wallet-action-summary'; + creditSummary.innerHTML = ` + Credit Line Payment + ${formatMobileBankCurrency(amountDue)} due + ${session.orgName || 'Organization'} - ${formatMobileBankCurrency(outstandingPrincipal)} outstanding + `; + + const creditControls = document.createElement('div'); + creditControls.className = 'wallet-action-controls'; + + const creditAmount = document.createElement('input'); + creditAmount.className = 'wallet-input'; + creditAmount.type = 'number'; + creditAmount.min = '1'; + creditAmount.step = '1'; + creditAmount.placeholder = amountDue > 0 ? 'Payment amount' : 'No payment due'; + creditAmount.setAttribute('aria-label', 'Credit line payment amount'); + creditAmount.inputMode = 'numeric'; + creditAmount.disabled = pendingAction !== '' || amountDue <= 0; + + const creditButton = document.createElement('button'); + creditButton.className = 'wallet-secondary-button'; + creditButton.type = 'button'; + creditButton.disabled = pendingAction !== '' || amountDue <= 0; + creditButton.textContent = pendingAction === 'repaycreditline' ? 'Paying...' : 'Pay Credit'; + creditButton.addEventListener('click', () => { + requestMobileBankRepayCreditLine(creditAmount.value || amountDue); + }); + + creditControls.append(creditAmount, creditButton); + creditAction.append(creditSummary, creditControls); + bankingActions.append(bankingTitle, earningsAction, creditAction); + content.appendChild(bankingActions); + + const transferCard = document.createElement('section'); + transferCard.className = 'wallet-card'; + + const transferTitle = document.createElement('div'); + transferTitle.className = 'wallet-card-title'; + transferTitle.textContent = 'Transfer'; + + const targetSelect = document.createElement('select'); + targetSelect.className = 'wallet-input'; + targetSelect.setAttribute('aria-label', 'Transfer recipient'); + targetSelect.disabled = pendingAction !== '' || transferTargets.length === 0; + + const placeholder = document.createElement('option'); + placeholder.value = ''; + placeholder.textContent = transferTargets.length === 0 ? 'No online recipients' : 'Choose recipient'; + targetSelect.appendChild(placeholder); + + transferTargets.forEach((target) => { + const option = document.createElement('option'); + option.value = target.uid || ''; + option.textContent = target.name || target.uid || 'Player'; + targetSelect.appendChild(option); + }); + + const amountInput = document.createElement('input'); + amountInput.className = 'wallet-input'; + amountInput.type = 'number'; + amountInput.min = '1'; + amountInput.step = '1'; + amountInput.placeholder = 'Amount'; + amountInput.inputMode = 'numeric'; + amountInput.disabled = pendingAction !== ''; + + const transferButton = document.createElement('button'); + transferButton.className = 'wallet-primary-button'; + transferButton.type = 'button'; + transferButton.disabled = pendingAction !== '' || transferTargets.length === 0; + transferButton.textContent = pendingAction === 'transfer' ? 'Sending...' : 'Send Transfer'; + transferButton.addEventListener('click', () => { + requestMobileBankTransfer(targetSelect.value, amountInput.value); + }); + + transferCard.append(transferTitle, targetSelect, amountInput, transferButton); + content.appendChild(transferCard); + + const historyCard = document.createElement('section'); + historyCard.className = 'wallet-card'; + + const historyTitle = document.createElement('div'); + historyTitle.className = 'wallet-card-title'; + historyTitle.textContent = 'Recent Activity'; + + historyCard.append(historyTitle, mobileBankTransactionRows(account.transactions)); + content.appendChild(historyCard); + + appContainer.appendChild(content); + container.appendChild(appContainer); +} + +window.initializeMobileBankApp = initializeMobileBankApp; +window.requestMobileBankRefresh = requestMobileBankRefresh; +window.updateMobileBank = updateMobileBank; +window.updateMobileBankAccount = updateMobileBankAccount; +window.showMobileBankNotice = showMobileBankNotice; diff --git a/arma/client/addons/phone/ui/_site/js/components/HomeScreen.js b/arma/client/addons/phone/ui/_site/js/components/HomeScreen.js index 96c2ba4..44b051f 100644 --- a/arma/client/addons/phone/ui/_site/js/components/HomeScreen.js +++ b/arma/client/addons/phone/ui/_site/js/components/HomeScreen.js @@ -94,6 +94,7 @@ class HomeScreen extends Component { { name: 'photos', title: 'Photos', icon: 'Photos', color: '' }, { name: 'clock', title: 'Clock', icon: 'Clock', color: '' }, { name: 'calendar', title: 'Calendar', icon: 'Calendar', color: '' }, + { name: 'wallet', title: 'Wallet', icon: 'Wallet', color: '' }, { name: 'store', title: 'App Store', icon: 'AppStore', color: '' }, ]; } diff --git a/arma/client/addons/phone/ui/_site/js/core/StateManager.js b/arma/client/addons/phone/ui/_site/js/core/StateManager.js index 0d2d616..95afd13 100644 --- a/arma/client/addons/phone/ui/_site/js/core/StateManager.js +++ b/arma/client/addons/phone/ui/_site/js/core/StateManager.js @@ -49,6 +49,23 @@ const initialAppState = { events: [], currentEvent: null, showEventEditor: false, + + // Mobile bank state + mobileBank: { + account: { + bank: 0, + cash: 0, + earnings: 0, + transactions: [], + }, + session: { + playerName: '', + transferTargets: [], + uid: '', + }, + notice: null, + pendingAction: '', + }, }; /** diff --git a/arma/client/addons/phone/ui/_site/styles/components/wallet.css b/arma/client/addons/phone/ui/_site/styles/components/wallet.css new file mode 100644 index 0000000..48492ba --- /dev/null +++ b/arma/client/addons/phone/ui/_site/styles/components/wallet.css @@ -0,0 +1,314 @@ +/* Wallet */ +.wallet-app { + background: var(--bg-primary); +} + +.wallet-content { + background: var(--bg-primary); + color: var(--text-primary); + display: flex; + flex-direction: column; + gap: 12px; + height: calc(100% - 44px); + overflow-y: auto; + padding: 12px 16px 28px; +} + +.wallet-nav-button { + background: transparent; + border: 0; + color: #275a8c; + cursor: pointer; + font-size: 13px; + font-weight: 700; +} + +[data-theme="dark"] .wallet-nav-button { + color: #8bb9e6; +} + +.wallet-notice { + border-radius: 12px; + font-size: 13px; + font-weight: 700; + line-height: 1.35; + padding: 10px 12px; +} + +.wallet-notice-success { + background: rgba(47, 125, 91, 0.16); + color: #2f7d5b; +} + +.wallet-notice-error { + background: rgba(196, 57, 57, 0.16); + color: #b42323; +} + +.wallet-notice-info { + background: rgba(39, 90, 140, 0.14); + color: #275a8c; +} + +.wallet-balance-card { + background: linear-gradient(160deg, #142f52 0%, #275a8c 58%, #4f86bd 100%); + border-radius: 20px; + box-shadow: 0 14px 26px rgba(20, 47, 82, 0.22); + color: #ffffff; + display: flex; + flex-direction: column; + min-height: 142px; + padding: 18px; +} + +.wallet-eyebrow, +.wallet-card-title, +.wallet-metric span, +.wallet-transaction-meta { + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.wallet-eyebrow { + color: rgba(255, 255, 255, 0.72); + font-size: 11px; + font-weight: 800; +} + +.wallet-balance { + font-size: 34px; + letter-spacing: 0; + line-height: 1.1; + margin-top: 14px; +} + +.wallet-owner { + color: rgba(255, 255, 255, 0.8); + font-size: 13px; + margin-top: auto; +} + +.wallet-metrics { + display: grid; + gap: 10px; + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.wallet-metric, +.wallet-card { + background: linear-gradient(180deg, #ffffff 0%, #f4f8fd 100%); + border: 1px solid rgba(18, 54, 93, 0.12); + border-radius: 16px; +} + +[data-theme="dark"] .wallet-metric, +[data-theme="dark"] .wallet-card { + background: linear-gradient(180deg, #1c1c1e 0%, #151b23 100%); + border-color: rgba(139, 185, 230, 0.18); +} + +.wallet-metric { + display: flex; + flex-direction: column; + gap: 6px; + min-width: 0; + padding: 12px; +} + +.wallet-metric span, +.wallet-card-title { + color: #6f86a3; + font-size: 11px; + font-weight: 800; +} + +[data-theme="dark"] .wallet-metric span, +[data-theme="dark"] .wallet-card-title, +[data-theme="dark"] .wallet-transaction-meta { + color: #8ea2bb; +} + +.wallet-metric strong { + color: #142f52; + font-size: 18px; + line-height: 1.15; +} + +[data-theme="dark"] .wallet-metric strong { + color: #ffffff; +} + +.wallet-card { + display: flex; + flex-direction: column; + gap: 10px; + padding: 14px; +} + +.wallet-input { + background: var(--input-bg); + border: 1px solid rgba(18, 54, 93, 0.16); + border-radius: 12px; + color: var(--text-primary); + font: inherit; + min-height: 42px; + padding: 0 12px; + width: 100%; +} + +[data-theme="dark"] .wallet-input { + border-color: var(--input-border); +} + +.wallet-primary-button { + background: #275a8c; + border: 0; + border-radius: 12px; + color: #ffffff; + cursor: pointer; + font: inherit; + font-weight: 800; + min-height: 42px; +} + +.wallet-secondary-button { + background: rgba(39, 90, 140, 0.12); + border: 1px solid rgba(39, 90, 140, 0.18); + border-radius: 12px; + color: #275a8c; + cursor: pointer; + font: inherit; + font-size: 12px; + font-weight: 800; + min-height: 42px; + padding: 0 10px; +} + +.wallet-full-button { + width: 100%; +} + +[data-theme="dark"] .wallet-secondary-button { + background: rgba(139, 185, 230, 0.13); + border-color: rgba(139, 185, 230, 0.2); + color: #8bb9e6; +} + +.wallet-action-block { + background: rgba(39, 90, 140, 0.08); + border-radius: 12px; + display: grid; + gap: 10px; + padding: 10px 12px; +} + +.wallet-action-block + .wallet-action-block { + margin-top: 2px; +} + +[data-theme="dark"] .wallet-action-block { + background: rgba(139, 185, 230, 0.1); +} + +.wallet-action-summary { + display: grid; + gap: 3px; +} + +.wallet-action-summary span { + color: #6f86a3; + font-size: 11px; + font-weight: 800; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.wallet-action-summary strong { + color: #142f52; + font-size: 18px; +} + +.wallet-action-summary small { + color: var(--text-secondary); + font-size: 12px; + line-height: 1.25; +} + +[data-theme="dark"] .wallet-action-summary span, +[data-theme="dark"] .wallet-action-summary strong { + color: #ffffff; +} + +.wallet-action-controls { + display: grid; + gap: 8px; + grid-template-columns: minmax(0, 1fr) 112px; +} + +.wallet-primary-button:disabled, +.wallet-secondary-button:disabled, +.wallet-nav-button:disabled { + cursor: not-allowed; + opacity: 0.58; +} + +.wallet-transaction-list { + display: flex; + flex-direction: column; + gap: 8px; +} + +.wallet-transaction-row { + align-items: center; + border-top: 1px solid rgba(18, 54, 93, 0.1); + display: flex; + gap: 10px; + justify-content: space-between; + padding-top: 10px; +} + +[data-theme="dark"] .wallet-transaction-row { + border-top-color: rgba(139, 185, 230, 0.14); +} + +.wallet-transaction-copy { + display: flex; + flex-direction: column; + gap: 3px; + min-width: 0; +} + +.wallet-transaction-title { + color: var(--text-primary); + font-size: 14px; + font-weight: 700; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.wallet-transaction-meta { + color: #6f86a3; + font-size: 10px; + font-weight: 700; +} + +.wallet-transaction-value { + color: #142f52; + flex-shrink: 0; + font-size: 14px; + font-weight: 800; +} + +[data-theme="dark"] .wallet-transaction-value { + color: #ffffff; +} + +.wallet-empty-state { + border: 1px dashed rgba(18, 54, 93, 0.18); + border-radius: 12px; + color: var(--text-secondary); + font-size: 13px; + padding: 14px; + text-align: center; +} diff --git a/arma/client/addons/phone/ui/_site/tools/concat-css.js b/arma/client/addons/phone/ui/_site/tools/concat-css.js index 0522a09..5ce7873 100644 --- a/arma/client/addons/phone/ui/_site/tools/concat-css.js +++ b/arma/client/addons/phone/ui/_site/tools/concat-css.js @@ -18,9 +18,12 @@ const files = [ '../styles/components/contacts.css', '../styles/components/dialpad.css', '../styles/components/messages.css', + '../styles/components/mail.css', '../styles/components/settings.css', '../styles/components/notes.css', + '../styles/components/calendar.css', '../styles/components/clock.css', + '../styles/components/wallet.css', '../styles/components/loader.css' ]; @@ -45,4 +48,4 @@ files.forEach(file => { }); fs.writeFileSync(outFile, bundle, 'utf8'); -console.log(`Bundled CSS written to ${outFile}`); \ No newline at end of file +console.log(`Bundled CSS written to ${outFile}`); diff --git a/arma/client/addons/phone/ui/_site/tools/concat-js.js b/arma/client/addons/phone/ui/_site/tools/concat-js.js index eeefeca..e3c45bd 100644 --- a/arma/client/addons/phone/ui/_site/tools/concat-js.js +++ b/arma/client/addons/phone/ui/_site/tools/concat-js.js @@ -12,6 +12,7 @@ const files = [ // Utils '../js/utils/helpers.js', + '../js/utils/PhoneMedia.js', // Shared Components '../js/components/StatusBar.js', @@ -34,6 +35,12 @@ const files = [ '../js/apps/messages/components/ConversationView.js', '../js/apps/messages/index.js', + // Mail App + '../js/apps/mail/components/MailList.js', + '../js/apps/mail/components/MailDetail.js', + '../js/apps/mail/components/MailComposer.js', + '../js/apps/mail/index.js', + // Contacts App '../js/apps/contacts/components/ContactList.js', '../js/apps/contacts/components/ContactItem.js', @@ -56,6 +63,13 @@ const files = [ '../js/apps/clock/components/AlarmClock.js', '../js/apps/clock/index.js', + // Calendar App + '../js/apps/calendar/components/Calendar.js', + '../js/apps/calendar/components/EventEditor.js', + '../js/apps/calendar/index.js', + + // Wallet App + '../js/apps/wallet/index.js', // Main App '../js/app.js', @@ -84,4 +98,4 @@ files.forEach(file => { }); fs.writeFileSync(outFile, bundle, 'utf8'); -console.log(`Bundled JS written to ${outFile}`); \ No newline at end of file +console.log(`Bundled JS written to ${outFile}`);