diff --git a/[esx_addons]/esx_banking/README.md b/[esx_addons]/esx_banking/README.md index 88748b1d..c9c3592b 100644 --- a/[esx_addons]/esx_banking/README.md +++ b/[esx_addons]/esx_banking/README.md @@ -1,4 +1,9 @@ -# esx_banking +

[ESX] Banking

Discord - Website - Documentation + +A beautiful and Easy-To-Use Banking & ATM system for ESX, with optional OX Target Support + + +## Special thanks: Gellipapa#9186,Rav3n95#2849,Csoki, csontvazharcos, Füsti, Pécé ## Download & Installation @@ -21,7 +26,7 @@ Run the banking.sql into your database. Done. ### License esx_banking - banking script for ESX -Copyright (C) 2015-2022 Jérémie N'gadi +Copyright (C) 2022 ESX-Framework This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version. diff --git a/[esx_addons]/esx_banking/banking.sql b/[esx_addons]/esx_banking/banking.sql index f190ddb5..f225e2cc 100644 --- a/[esx_addons]/esx_banking/banking.sql +++ b/[esx_addons]/esx_banking/banking.sql @@ -1,8 +1,11 @@ - --- Dumping structure for table legacy.banking CREATE TABLE IF NOT EXISTS `banking` ( - `identifier` varchar(50) DEFAULT NULL, + `identifier` varchar(46) DEFAULT NULL, `type` varchar(50) DEFAULT NULL, `amount` int(64) DEFAULT NULL, - `time` date DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `time` bigint(20) DEFAULT NULL, + `ID` int(11) NOT NULL AUTO_INCREMENT, + `balance` int(11) DEFAULT 0, + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; + +ALTER TABLE `users` ADD COLUMN `pincode` INT NULL; diff --git a/[esx_addons]/esx_banking/client/main.lua b/[esx_addons]/esx_banking/client/main.lua index 935ca6b0..42fbd455 100644 --- a/[esx_addons]/esx_banking/client/main.lua +++ b/[esx_addons]/esx_banking/client/main.lua @@ -1,125 +1,350 @@ --- internal variables -local hasAlreadyEnteredMarker, isInbankingMarker, menuIsShowed = false, false, false +local PlayerData, ActivateBlips, Peds = {}, {}, {} +local PlayerLoaded = true +local isInMarker, isInAtmMarker, isInMenu, isMarkerShowed = false, false, false, false +local _GetEntityCoords, _PlayerPedId -RegisterNetEvent('esx_banking:closebanking') -AddEventHandler('esx_banking:closebanking', function() - SetNuiFocus(false) - menuIsShowed = false - SendNUIMessage({ - hideAll = true - }) -end) - -RegisterNUICallback('escape', function(data, cb) - TriggerEvent('esx_banking:closebanking') - cb('ok') -end) - -RegisterNUICallback('deposit', function(data, cb) - TriggerServerEvent('esx_banking:deposit', data.amount) - getTransactionHistory() - cb('ok') -end) - -RegisterNUICallback('withdraw', function(data, cb) - TriggerServerEvent('esx_banking:withdraw', data.amount) - getTransactionHistory() - cb('ok') -end) - --- Create blips -CreateThread(function() - if not Config.Blips.Enabled then return end - - for _, bankingLocation in pairs(Config.bankingLocations) do - bankingLocation.blip = AddBlipForCoord(bankingLocation.x, bankingLocation.y, bankingLocation.z - Config.ZDiff) - SetBlipSprite(bankingLocation.blip, Config.Blips.Sprite) - SetBlipDisplay(bankingLocation.blip, 4) - SetBlipScale(bankingLocation.blip, Config.Blips.Scale) - SetBlipColour(bankingLocation.blip, Config.Blips.Color) - SetBlipAsShortRange(bankingLocation.blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(_U('banking_blip')) - EndTextCommandSetBlipName(bankingLocation.blip) - end -end) - --- Activate menu when player is inside marker -CreateThread(function() - while true do - local coords = GetEntityCoords(PlayerPedId()) - local Sleep = 1500 - isInbankingMarker = false - - for k,v in pairs(Config.bankingLocations) do - local Pos = vector3(v.x,v.y,v.z) - if #(coords - Pos) < 2.0 then - Sleep = 0 - isInbankingMarker, canSleep = true, false - ESX.TextUI(_U('press_e_banking')) - DrawMarker(20, Pos.x, Pos.y, Pos.z,0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.2, 0.2, 187, 255, 0, 255, false, true, 2, nil, nil, false) - break - end - end - - if isInbankingMarker and not hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = true - canSleep = false - end - - if not isInbankingMarker and hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = false - SetNuiFocus(false) - menuIsShowed = false - canSleep = false - ESX.HideUI() - - SendNUIMessage({ - hideAll = true - }) - end - Wait(Sleep) - end -end) - --- Menu interactions -CreateThread(function() - while true do - local Sleep = 1500 - if isInbankingMarker and not menuIsShowed then - Sleep = 0 - if IsControlJustReleased(0, 38) and IsPedOnFoot(PlayerPedId()) then - menuIsShowed = true - getTransactionHistory() - ESX.TriggerServerCallback('esx:getPlayerData', function(data) - SendNUIMessage({ - showMenu = true, - player = { - money = data.money, - accounts = data.accounts - } - }) - end) - SetNuiFocus(true, true) - end - end - Wait(Sleep) - end -end) - --- close the menu when script is stopping to avoid being stuck in NUI focus -AddEventHandler('onResourceStop', function(resource) - if resource == GetCurrentResourceName() then - if menuIsShowed then - TriggerEvent('esx_banking:closebanking') - end - end -end) - -function getTransactionHistory() - ESX.TriggerServerCallback("esx_banking:gethistory", function(_history) - SendNUIMessage({ - history = {json.encode(_history)} - }) - end) +-- Functions +-- Listen for keypress while player inside the marker +local function Listen4Key() + CreateThread(function() + while (isInMarker or isInAtmMarker) and not isInMenu do + if IsControlJustReleased(0, 38) then + OpenUi(isInAtmMarker) + end + Wait(0) + end + end) end + +-- Create Blips +local function CreateBlips() + local tmpActiveBlips = {} + for i = 1, #Config.Banks do + if type(Config.Banks[i].Blip) == 'table' and Config.Banks[i].Blip.Activate then + local blip = AddBlipForCoord(Config.Banks[i].Position.xy) + SetBlipSprite(blip, Config.Banks[i].Blip.Sprite) + SetBlipScale(blip, Config.Banks[i].Blip.Scale) + SetBlipColour(blip, Config.Banks[i].Blip.Color) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(Config.Banks[i].Blip.Label) + EndTextCommandSetBlipName(blip) + tmpActiveBlips[#tmpActiveBlips + 1] = blip + end + end + + ActivateBlips = tmpActiveBlips +end + +-- Remove blips +local function RemoveBlips() + for i = 1, #ActivateBlips do + if DoesBlipExist(ActivateBlips[i]) then + RemoveBlip(ActivateBlips[i]) + end + end + ActivateBlips = {} +end + +-- Ped Handler +local function PedHandler(ids) + local tmpPeds = {} + + for _, id in pairs(ids) do + if not Peds[id] then + + if not HasModelLoaded(Config.Peds[id].Model) then + RequestModel(Config.Peds[id].Model) + Wait(100) + while not HasModelLoaded(Config.Peds[id].Model) do + Wait(10) + end + end + + local npc = CreatePed(6, Config.Peds[id].Model, Config.Peds[id].Position + vector4(0, 0, -1, 0), false, + false) + TaskStartScenarioInPlace(npc, Config.Peds[id].Scenario, 0, true) + SetEntityInvincible(npc, true) + SetEntityProofs(npc, true, true, true, true, true, true, 1, true) + SetBlockingOfNonTemporaryEvents(npc, true) + FreezeEntityPosition(npc, true) + SetPedDiesWhenInjured(npc, false) + SetEntityCanBeDamaged(npc, false) + SetPedCanRagdollFromPlayerImpact(npc, false) + SetPedCanRagdoll(npc, false) + SetEntityAsMissionEntity(npc, true, true) + SetEntityDynamic(npc, false) + + if Config.Target then + exports.ox_target:addGlobalPed(npc, { + options = {{ + icon = "fas fa-money-bill-wave", + label = _U('access_bank'), + action = function() + OpenUi() + end + }}, + distance = 2 + }) + end + + Peds[id] = npc + end + end + + for id, handle in pairs(Peds) do + local del = true + + for i = 1, #ids do + + if ids[i] == id then + del = false + tmpPeds[id] = handle + end + end + + if del then + DeletePed(handle) + if Config.Target then + exports.ox_target:removeGlobalPed(handle, {_U('access_bank')}) + end + end + end + + Peds = tmpPeds +end + +function OpenUi(atm) + atm = atm or false + isInMenu = true + if not Config.Target then + ESX.HideUI() + end + ESX.TriggerServerCallback('esx_banking:getPlayerData', function(data) + SendNUIMessage({ + showMenu = true, + openATM = atm, + datas = { + your_money_panel = { + title = _U('your_money_title'), + desc = _U('your_money_desc'), + accountsData = {{ + title = _U('your_money_cash'), + name = "cash", + amount = data.money + }, { + title = _U('your_money_bank'), + name = "bank", + amount = data.bankMoney + }} + }, + bankCardData = { + bankName = _U('bank_name'), + cardNumber = "2232 2222 2222 2222", + createdDate = "08/08", + name = data.playerName + }, + transactionsData = data.transactionHistory + } + }) + end) + SetNuiFocus(true, true) +end + +local function CloseUi() + SetNuiFocus(false) + isInMenu = false + SendNUIMessage({ + showMenu = false + }) + + if not Config.Target and (isInMarker or isInAtmMarker) then + ESX.TextUI(_U('press_e_banking')) + Listen4Key() + end +end + +local function ShowMarker(coord) + CreateThread(function() + while isMarkerShowed do + DrawMarker(20, coord.x, coord.y, coord.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.2, 0.2, 187, 255, 0, 255, + false, true, 2, nil, nil, false) + Wait(0) + end + end) +end + +local function StartThread() + CreateThread(function() + CreateBlips() + + if Config.Target then + exports.ox_target:addModel(Config.AtmModels, { + options = {{ + icon = 'fas fa-credit-card', + label = _U('access_bank'), + action = function() + OpenUi(true) + end + }}, + distance = 1.5 + }) + if not Config.EnablePeds then + for i = 1, #Config.Banks do + local targetInfo = Config.Banks[i].Position + exports.ox_target:addBoxZone('openBank' .. i, targetInfo.xyz, 1.5, 1.5, { + name = 'openBank' .. i, + heading = targetInfo.w, + minZ = targetInfo.z - 1.0, + maxZ = targetInfo.z + 1.5, + debugPoly = Config.Debug + }, { + options = {{ + icon = 'fas fa-money-bill-wave', + label = _U('access_bank'), + action = function() + OpenUi() + end + }}, + distance = 2.0 + }) + end + end + end + + while PlayerLoaded do + _PlayerPedId = PlayerPedId() + _GetEntityCoords = GetEntityCoords(_PlayerPedId) + + if Config.EnablePeds then + local closestPed = {} + + for i = 1, #Config.Peds do + local distance = #(_GetEntityCoords - Config.Peds[i].Position.xyz) + if distance <= Config.DrawMarker then + closestPed[#closestPed + 1] = i + end + end + + PedHandler(closestPed) + end + + if not Config.Target and not isInMenu and IsPedOnFoot(PlayerPedId()) then + local closestBank = {} + + for i = 1, #Config.AtmModels do + local atm = GetClosestObjectOfType(_GetEntityCoords, 3.0, Config.AtmModels[i], false) + if atm ~= 0 then + local atmOffset = GetOffsetFromEntityInWorldCoords(atm, 0.0, -0.7, 0.0) + local atmHeading = GetEntityHeading(atm) + local atmDistance = #(_GetEntityCoords - atmOffset) + if not isInAtmMarker and atmDistance <= 1.5 then + isInAtmMarker = true + ESX.TextUI(_U('press_e_banking')) + Listen4Key() + elseif isInAtmMarker and atmDistance > 1.5 then + isInAtmMarker = false + ESX.HideUI() + end + end + end + + for i = 1, #Config.Banks do + local bankDistance = #(_GetEntityCoords - Config.Banks[i].Position.xyz) + + if bankDistance <= Config.DrawMarker then + closestBank = {Config.Banks[i].Position, bankDistance} + end + end + + if not isMarkerShowed and next(closestBank) then + isMarkerShowed = true + ShowMarker(closestBank[1].xyz) + elseif isMarkerShowed and not next(closestBank) then + isMarkerShowed = false + end + + if next(closestBank) then + if not isInMarker and closestBank[2] <= 1.0 then + isInMarker = true + ESX.TextUI(_U('press_e_banking')) + Listen4Key() + elseif isInMarker and closestBank[2] > 1.0 then + isInMarker = false + ESX.HideUI() + end + end + + end + Wait(1000) + end + end) +end + +-- NuiCallbacks +RegisterNUICallback('close', function(data, cb) + CloseUi() + cb('ok') +end) + +RegisterNUICallback('clickButton', function(data, cb) + if data ~= nil and isInMenu then + TriggerServerEvent("esx_banking:doingType", data) + end + cb('ok') +end) + +RegisterNUICallback('checkPincode', function(data, cb) + if data ~= nil and isInMenu then + ESX.TriggerServerCallback("esx_banking:checkPincode", function(pincode) + if pincode then + cb({ + success = true + }) + ESX.ShowNotification(_U('pincode_found'), "success") + + else + cb({ + error = true + }) + ESX.ShowNotification(_U('pincode_not_found'), "error") + end + end, data) + end +end) + +-- Events +RegisterNetEvent('esx_banking:closebanking', function() + CloseUi() +end) + +RegisterNetEvent('esx_banking:updateMoneyInUI') +AddEventHandler('esx_banking:updateMoneyInUI', function(doingType, bankMoney, money) + SendNUIMessage({ + updateData = true, + data = { + type = doingType, + bankMoney = bankMoney, + money = money + } + }) +end) + +-- Resource starting +AddEventHandler('onResourceStart', function(resource) + if resource ~= GetCurrentResourceName() then + return + end + StartThread() +end) + +-- Resource stopping +AddEventHandler('onResourceStop', function(resource) + if resource ~= GetCurrentResourceName() then + return + end + RemoveBlips() + if isInMenu then + CloseUi() + end +end) diff --git a/[esx_addons]/esx_banking/config.lua b/[esx_addons]/esx_banking/config.lua index 12f47043..a76209c3 100644 --- a/[esx_addons]/esx_banking/config.lua +++ b/[esx_addons]/esx_banking/config.lua @@ -1,26 +1,133 @@ -Config = {} - -Config.ZDiff = 2.0 - -Config.Locale = 'en' - -Config.Blips = { - Enabled = true, - Sprite = 106, - Scale = 0.7, - Color = 2, +Config = { + Debug = false, + DrawMarker = 10, + Target = false, -- ox_target (https://github.com/overextended/ox_target) + Locale = 'en', + EnablePeds = true, + AtmModels = {`prop_fleeca_atm`, `prop_atm_01`, `prop_atm_02`, `prop_atm_03`}, + Banks = { + { + Position = vector4(149.91, -1040.74, 29.374, 160), + Blip = { + Enabled = true, + Color = 69, + Label = 'Bank', + Sprite = 108, + Scale = 0.7 + } + }, + { + Position = vector4(-1212.63, -330.78, 37.59, 210), + Blip = { + Enabled = true, + Color = 69, + Label = 'Bank', + Sprite = 108, + Scale = 0.7 + } + }, + { + Position = vector4(-2962.47, 482.93, 15.5, 270), + Blip = { + Enabled = true, + Color = 69, + Label = 'Bank', + Sprite = 108, + Scale = 0.7 + } + }, + { + Position = vector4(-113.01, 6470.24, 31.43, 315), + Blip = { + Enabled = true, + Color = 69, + Label = 'Bank', + Sprite = 108, + Scale = 0.7 + } + }, + { + Position = vector4(314.16, -279.09, 53.97, 160), + Blip = { + Enabled = true, + Color = 69, + Label = 'Bank', + Sprite = 108, + Scale = 0.7 + } + }, + { + Position = vector4(-350.99, -49.99, 48.84, 160), + Blip = { + Enabled = true, + Color = 69, + Label = 'Bank', + Sprite = 108, + Scale = 0.7 + } + }, + { + Position = vector4(1175.02, 2706.87, 37.89, 0), + Blip = { + Enabled = true, + Color = 69, + Label = 'Bank', + Sprite = 108, + Scale = 0.7 + } + }, + { + Position = vector4(246.63, 223.62, 106.0, 160), + Blip = { + Enabled = true, + Color = 69, + Label = 'Bank', + Sprite = 108, + Scale = 0.7 + } + }, + }, + Peds = { + { + Position = vector4(149.5513, -1042.1570, 29.3680, 341.6520), + Model = `U_M_M_BankMan`, + Scenario = 'WORLD_HUMAN_CLIPBOARD' + }, + { + Position = vector4(-1211.8585, -331.9854, 37.7809, 28.5983), + Model = `U_M_M_BankMan`, + Scenario = 'WORLD_HUMAN_CLIPBOARD' + }, + { + Position = vector4(-2961.0720, 483.1107, 15.6970, 88.1986), + Model = `U_M_M_BankMan`, + Scenario = 'WORLD_HUMAN_CLIPBOARD' + }, + { + Position = vector4(-112.2223, 6471.1128, 31.6267, 132.7517), + Model = `U_M_M_BankMan`, + Scenario = 'WORLD_HUMAN_CLIPBOARD' + }, + { + Position = vector4(313.8176, -280.5338, 54.1647, 339.1609), + Model = `U_M_M_BankMan`, + Scenario = 'WORLD_HUMAN_CLIPBOARD' + }, + { + Position = vector4(-351.3247, -51.3466, 49.0365, 339.3305), + Model = `U_M_M_BankMan`, + Scenario = 'WORLD_HUMAN_CLIPBOARD' + }, + { + Position = vector4(1174.9718, 2708.2034, 38.0879, 178.2974), + Model = `U_M_M_BankMan`, + Scenario = 'WORLD_HUMAN_CLIPBOARD' + }, + { + Position = vector4(247.0348, 225.1851, 106.2875, 158.7528), + Model = `U_M_M_BankMan`, + Scenario = 'WORLD_HUMAN_CLIPBOARD' + } + } } - - -Config.bankingLocations = { - { ['x'] = 149.644, ['y'] = -1040.492, ['z'] = 29.366}, - { ['x'] = -112.64, ['y'] = 6469.72, ['z'] = 31.366}, - { ['x'] = -2962.58, ['y'] = 482.67, ['z'] = 15.69}, - { ['x'] = -1213.27, ['y'] = -331.461, ['z'] = 37.773}, - { ['x'] = 314.187, ['y'] = -278.621, ['z'] = 54.170}, - { ['x'] = -351.534, ['y'] = -49.529, ['z'] = 49.042}, - { ['x'] = -1570.197, ['y'] = -546.651, ['z'] = 34.955}, - { ['x'] = 33.232, ['y'] = -1347.849, ['z'] = 29.497}, - { ['x'] = 129.216, ['y'] = -1292.347, ['z'] = 29.269} -} diff --git a/[esx_addons]/esx_banking/fxmanifest.lua b/[esx_addons]/esx_banking/fxmanifest.lua index 44c8ddfc..d168de5f 100644 --- a/[esx_addons]/esx_banking/fxmanifest.lua +++ b/[esx_addons]/esx_banking/fxmanifest.lua @@ -1,4 +1,4 @@ -fx_version 'adamant' +fx_version 'cerulean' game 'gta5' @@ -25,10 +25,7 @@ client_scripts { ui_page 'html/ui.html' files { - 'html/ui.html', - 'html/roboto.ttf', - 'html/css/app.css', - 'html/scripts/app.js' + 'html/**', } dependency 'es_extended' diff --git a/[esx_addons]/esx_banking/html/config.json b/[esx_addons]/esx_banking/html/config.json new file mode 100644 index 00000000..5eacc1c5 --- /dev/null +++ b/[esx_addons]/esx_banking/html/config.json @@ -0,0 +1,191 @@ +{ + "lang":"EN", + "__comment":"On DYNAMIC_FORM_DATA do not change 'componentName', 'elementID'!", + "EN":{ + "DYNAMIC_FORM_DATA":[ + { + "componentName":"moreGraph", + "elementID":"#wrapper", + "title":"", + "closeButtonText":"Close", + "bankTitle":"Fleeca Bank", + "mainExitButtonText": "Log out" + }, + { + "elementID":"#cpincode", + "name":"cpincode", + "buttonText":"Approve", + "inputPlaceholder": "Enter 4 digit...", + "title":"PIN CODE SETUP", + "description": "Here you can set or change the PIN code.", + "type":"password" + }, + { + "elementID":"#withdraw", + "name":"withdraw", + "buttonText":"Approve", + "inputPlaceholder": "Amount", + "title":"WITHDRAW", + "description": "Here you can withdraw your money from the bank.", + "type":"number" + }, + { + "elementID":"#deposit", + "name":"deposit", + "buttonText":"Approval", + "inputPlaceholder": "Amount", + "title":"DEPOSIT", + "description": "Here, you can deposit your money to the bank.", + "type":"number" + }, + { + "elementID":"#transfer", + "name":"transfer", + "buttonText":"Transfer", + "inputPlaceholder": "Amount", + "inputPlaceholder2": "Player ID", + "title":"TRANSFER", + "description": "Here you can transfer your money to someone else." + }, + { + "componentName":"trans", + "elementID":"#third-column", + "title":"TRANSACTION HISTORY", + "description": "Here you can see your transaction history.", + "moreHistoryText": "Show more history", + "moreGraphText": "Show more graph" + }, + { + "componentName":"pincodePanel", + "elementID":"#wrapper", + "title":"Enter PIN", + "deleteButtonText": "", + "loginButtonText": "", + "closeButtonText": "Close" + }, + { + "componentName":"atmComponent", + "elementID":"#wrapper", + "title":"Fleeca Bank", + "closeButtonText":"Log out" + } + ], + "LAUNGAGE": { + "withdraw":"WITHDRAW", + "deposit":"DEPOSIT", + "transfer":"TRANSFER", + "transferReceive":"RECEIVED TRANSFER", + "moneyFormat":"$__replaceData__", + "graphTitle":"Your balance", + "moreGraphTitle": "Big Graph", + "moreHistoryTitle":"Show more history", + "inputErrorTitle":"Data is incorrect", + "inputErrorMessage":"It cannot be empty or a value less than 1!", + "showPincodeErrorTitle":"PIN incorrect", + "showPincodeErrorMessage":"The pin must have at least 4 characters!", + "tableLang":{ + "typeLabel": "Transaction type", + "balanceLabel":"Balance", + "amountLabel":"Amount", + "timeLabel":"Time", + "searchInputPlaceholder":"Search ...", + "_comment": "tableFullLanguage options: English,Hungarian you can find here all lang: https://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/", + "tableFullLanguage":"English" + } + } + }, + "HU":{ + "DYNAMIC_FORM_DATA":[ + { + "componentName":"moreGraph", + "elementID":"#wrapper", + "title":"", + "closeButtonText":"Bezárás", + "bankTitle":"OTP BANK FELÜLET", + "mainExitButtonText": "Kijelentkezés" + }, + { + "elementID":"#cpincode", + "name":"cpincode", + "buttonText":"Jóváhagyás", + "inputPlaceholder": "Írj be 4 számot...", + "title":"PIN KÓD BEÁLLÍTÁS", + "description": "Itt tudod beállítani vagy cserélni pinkódodat.", + "type":"password" + }, + { + "elementID":"#withdraw", + "name":"withdraw", + "buttonText":"Jóváhagyás", + "inputPlaceholder": "Összeg", + "title":"PÉNZ KIVÉTEL", + "description": "Itt tudsz pénzt kivenni a számládról.", + "type":"number" + }, + { + "elementID":"#deposit", + "name":"deposit", + "buttonText":"Jóváhagyás", + "inputPlaceholder": "Összeg", + "title":"PÉNZ BETÉTEL", + "description": "Itt tudsz pénzt be tenni a számládra.", + "type":"number" + }, + { + "elementID":"#transfer", + "name":"transfer", + "buttonText":"Utalás", + "inputPlaceholder": "Összeg", + "inputPlaceholder2": "Játékos azonosító", + "title":"UTALÁS", + "description": "Itt tudsz pénzt utalni egy adott játékosnak." + }, + { + "componentName":"trans", + "elementID":"#third-column", + "title":"SZÁMLA TÖRTÉNET", + "description": "Itt látod a számla történeted.", + "moreHistoryText": "Több számla történet mutatása", + "moreGraphText": "Nagyított diagram mutatása" + }, + { + "componentName":"pincodePanel", + "elementID":"#wrapper", + "title":"Írd be a PIN kódod", + "deleteButtonText": "", + "loginButtonText": "", + "closeButtonText": "Bezárás" + }, + { + "componentName":"atmComponent", + "elementID":"#wrapper", + "title":"OTP BANK", + "closeButtonText":"Kijelentkezés" + } + + ], + "LAUNGAGE": { + "withdraw":"KIVÉTEL", + "deposit":"BETÉTEL", + "transfer":"UTALÁS", + "transferReceive":"KAPOTT UTALÁS", + "moneyFormat":"__replaceData__ Ft", + "graphTitle":"Egyenleged", + "moreGraphTitle": "Nagyított grafikon", + "moreHistoryTitle":"Teljes számla történet", + "inputErrorTitle":"Adat hibás", + "inputErrorMessage":"Nem lehet üres vagy érték kisebb mint 1!", + "showPincodeErrorTitle":"PIN hibás", + "showPincodeErrorMessage":"Legalább 4 karakternek kell lennie a pinnek!", + "tableLang":{ + "typeLabel": "Tranzakció típus", + "balanceLabel":"Egyenleged", + "amountLabel":"Összeg", + "timeLabel":"Idő", + "searchInputPlaceholder":"Kereső ...", + "_comment": "tableFullLanguage options: English,Hungarian you can find here all lang: https://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/", + "tableFullLanguage":"Hungarian" + } + } + } +} diff --git a/[esx_addons]/esx_banking/html/css/app.css b/[esx_addons]/esx_banking/html/css/app.css index b4a69d0e..3c53fbfd 100644 --- a/[esx_addons]/esx_banking/html/css/app.css +++ b/[esx_addons]/esx_banking/html/css/app.css @@ -1,126 +1,760 @@ -@font-face { - font-family: roboto; - src: url('../roboto.ttf'); +:root{ + --primary-color: #2e69d5; + --secondary-color: #378cbf; + --text-color:#ffff; + --background-light:#232934; + --background-light-2:#202020; + --background-dark:#0a0e19; + --accent-red: #378cbf; + --accent-green:#45b157; + --accent-gray: #474e57; + --accent-gray-2:#545457; + + --columnsBackground:var(--background-dark); + --allTitleColor:var(--text-color); + --yourMoneyPriceTextColor:var(--accent-green); + --bankCardBackgroundColor: linear-gradient(110deg, var(--primary-color) 0%, var(--secondary-color) 100%); + --buttonBackgroundColor:var(--background-light); + --inputBackgroundColor:var(--background-light); + --inputTextColor:var(--text-color); + --inputPlaceholderColor:var(--accent-gray-2); + --checkmarkColor:var(--text-color); + --acceptExitButtonColorText:var(--text-color); + --exitButtonHoverBackgroundColor:var(--primary-color); + --acceptButtonHoverBackgroundColor:var(--secondary-color); + --bankCardTextColor:var(--text-color); + --bankCardNumberColor:var(--text-color); + --moneyContainerBackgroundColor:var(--background-light); + --moneyAndTransactionContainer:var(--background-light); + --transactionContainerBackgroundColor:var(--background-light); + --moneyAndTransactionallTitleColorText:var(--text-color); + --transactionDataTextColor:var(--text-color); + --cardSubtitleTextColor:var(--accent-gray); + --depositColorText:var(--accent-green); + --withDrawColorText:var(--primary-color); + --moreHistoryButtonHoverColor: var(--secondary-color); + --moreGraphButtonHoverColor:var(--secondary-color); + --hrRowColor:var(--accent-gray); + --loadingCircle:var(--secondary-color); + --tableAllTextColor:var(--text-color); + --tableBackgroundColorPaginationButton: var(--secondary-color); + --tableBackgroundColorPaginationButtonHover:var(--secondary-color); + --tableRowHoverBackgroundColor:var(--secondary-color); + --tableScrollBarBackgroundColor:var(--background-light); + --tableScrollBarBackgroundColorHover:var(--secondary-color); + --tableSelectBoxBackgroundColor:var(--background-light); + --tableSearchInputBackgroundColor:var(--background-light); + --tableScrollBarBackgroundColor2:var(--background-light); + --disableButtonBackgroundColor:var(--background-light-2); + --graphLineColor:var(--secondary-color); + --graphLineBackgroundColor:var(--secondary-color); } -body { + + +@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@100;400;500;800&display=swap'); + +*{ + margin:0; + padding:0; +} + +#wrapper{ width: 100%; - height: 100%; - overflow: hidden; - font-family: roboto; -} - -#cursor { - position: absolute; - z-index: 999999; + height: 93.24vmin; + display:flex; + justify-content: center; + align-items: center; + font-family: 'Raleway', sans-serif; + user-select: none; + min-width: 42vmin; + font-size: 2vmin; display: none; } #container { - position: absolute; - background: #232934; - height: 700px; - width: 1000px; - top: 40%; - left: 40%; - margin: -250px 0 0 -300px; + height: 73vmin; + width: 139.41vmin; cursor: default; display: flex; flex-direction: column; -} - -#header { - color: white; - padding:20px; - background: #353e4f; + justify-content: center; + align-items: center; + max-width: 150vmin; + flex-wrap: wrap; + margin:2vmin; + position: relative; + display: none; } #menu { display: flex; flex-direction: row; - justify-content: space-between; + gap:3vmin; + flex-wrap: wrap; + height: 68.15vmin; } -.right-side { - width: 50%; +/* FIRST COLUMN START */ + +#menu #first-column { + width: 36vmin; + background: var(--columnsBackground); + padding: 1.85vmin; + display: flex; + flex-direction: column; + gap: 1.79vmin; + border-radius: 1.38vmin; + flex: 1 1 27.7vmin; + height: 72.56vmin; } -.left-side { - width: 50%; - margin: 20px; - color: white; - border: solid #353e4f 2px; - border-radius: 10px; - height: 205px; - overflow-y: auto; - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ +#menu #first-column hr { + border: 1px solid var(--hrRowColor); + width: 80%; + margin: 0 auto; } -.left-side::-webkit-scrollbar { - display: none; +#bankcard { + height: 16.6vmin; + width: 25vmin; + margin: 0 auto; + background: var(--bankCardBackgroundColor); + border-radius: 1.38vmin; + padding: 1.85vmin 1.6vmin 0px 1.85vmin; + position: relative; } -.webgl { - position: fixed; - left: 0; - top: 0; - outline: none; +#bankcard .content p{ + margin: 0; + color:var(--bankCardTextColor); + font-size: 0.92vmin; } - -.left-side .transaction-header { +#bankcard .title{ display: flex; justify-content: space-between; - padding: 10px 20px; - background: #353e4f; } +#bankcard .title span{ + color:var(--bankCardTextColor); +} -.group { - margin: 20px; - color: white; +#bankcard .title svg{ + width: 4.16vmin; + height: 4.16vmin; +} + +#bankcard .content { + position: absolute; + bottom: 1.66vmin; +} + +#bankcard .content .card-data{ + display: flex; + justify-content: space-between; +} + +#bankcard .content .cardnumber { + color: var(--bankCardNumberColor); + font-size: 1.85vmin; + letter-spacing: 0.37vmin; + margin-bottom: 0.46vmin; +} + +#bankcard .content .card-data:nth-child(2){ + margin-right: 0.27vmin; +} + +#bankcard .content .card-data p { + font-size: 1.48vmin; +} + +#your-money-panel #money-containers{ display: flex; flex-direction: column; - margin-bottom: 20px; - padding: 10px; - border: solid #353e4f 2px; - border-radius: 10px; + gap: 0.92vmin; } -.group > button { - color: white; - width: 50%; - padding: 12px 20px; - margin: 8px 0; - border: 1px solid #353e4f; - border-radius: 4px; - background-color: #353e4f; +.exit-button , .accept-button , #pincode-container .button-groups button { + background-color:var(--buttonBackgroundColor); + padding:1.85vmin 1.85vmin; + /*width: 35vmin;*/ + width: 100%; + outline: none; + border:none; + color:var(--acceptExitButtonColorText); + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; + font-weight: bold; + border-radius: 0.27vmin; + font-family: 'Raleway', sans-serif; + font-size: 1.5vmin; +} + +.exit-button:hover , #modal-container #title-container button:hover{ + background-color: var(--exitButtonHoverBackgroundColor); + box-shadow: -1vmin 1vmin 1vmin -1vmin var(--exitButtonHoverBackgroundColor); +} + +.accept-button:hover{ + background-color: var(--acceptButtonHoverBackgroundColor); + box-shadow: -1vmin 1vmin 1vmin -1vmin var(--acceptButtonHoverBackgroundColor); +} + +/* FIRST COLUMN END */ + + +/* SECOND COLUMN START*/ + +#menu #second-column{ + width: 35.18vmin; + border-radius: 1.38vmin; + display: flex; + align-items: center; + flex-direction: column; + gap: 0.92vmin; + flex: 1 1 27.77vmin; + padding-right: 1.85vmin; + padding-left: 1.85vmin; +} + +#withdraw,#deposit,#transfer{ + background: var(--columnsBackground); + padding: 1.85vmin; + border-radius: 1.38vmin; + width: 35.18vmin; +} + +#menu #second-column #withdraw { + height: 18.48vmin; +} + +#menu #second-column #deposit { + height: 18.48vmin; +} + +#menu #second-column #transfer { + height: 26.63vmin; +} + +/* SECOND COLUMN END*/ + +/* THIRD COLUMN START*/ + +#menu #third-column{ + width: 32.77vmin; + background: var(--columnsBackground); + border-radius: 1.38vmin; + padding:1.85vmin; + flex: 1 1 37.03vmin; +} + +#menu #third-column #graph-container{ + width: calc(100% - 0.46vmin); + height: 38vmin; +} + +#menu #third-column #buttons-container{ + display: flex; + justify-content: center; + align-items: center; + margin: 0px 1.9vmin; + margin-top: 1.48vmin; + gap:0.92vmin; +} + +#menu #third-column #buttons-container button{ + padding: 0.92vmin; + width: 20.92vmin; +} + +#menu #third-column #buttons-container #more_history:hover{ + background-color: var(--moreHistoryButtonHoverColor); + box-shadow: 0px 3.42vmin 9.25vmin -1.20vmin var(--moreHistoryButtonHoverColor); +} + +#menu #third-column #buttons-container #more_graph:hover{ + background-color: var(--moreGraphButtonHoverColor); + box-shadow: 0px 3.42vmin 9.25vmin -1.20vmin var(--moreGraphButtonHoverColor); +} + +#menu #third-column #transactions-container { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.92vmin; + padding: 1.85vmin; +} + +#menu #third-column #transactions-container .transaction-container{ + /* width: 40.37vmin; */ + width: 100%; + background-color: var(--transactionContainerBackgroundColor); + padding: 0.92vmin 0.92vmin 0.92vmin 1.85vmin; + font-size: 1.8vmin; +} + +#menu #third-column #transactions-container .transaction-container .transaction{ + display: flex; + justify-content: space-between; + align-items: center; + font-size: 1.5vmin; +} + +#menu #third-column #transactions-container .transaction-container .transaction span { + color: var(--transactionDataTextColor); + background: var(--columnsBackground); + border-radius: 0.27vmin; + padding: 0.46vmin; + font-size: 1.20vmin; +} + +/* THIRD COLUMN END*/ + + +/* GENERAL START*/ + +.money-container,.transaction-container { + background-color: var(--moneyAndTransactionContainer); + padding: 0.92vmin 0.92vmin 0.92vmin 1.85vmin; + border-radius: 0.27vmin; +} + +.money-container{ + background-color: var(--moneyContainerBackgroundColor); } -.group > input { - color: white; - width: 100%; - padding: 12px 20px; - margin: 8px 0; - background-color: #353e4f; - border: none; - border-radius: 4px; - appearance: none; - -moz-appearance: none; - -webkit-appearance: none; +.money-container h4 { + margin-bottom: 0.5vmin; } -.group > input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { - -webkit-appearance: none; +.money-container h4 , .transaction h4{ + color:var(--moneyAndTransactionallTitleColorText); + text-shadow: 0.09vmin 0.09vmin 0.18vmin black; + font-size: 1.5vmin; +} + +.money-container span , .transaction-container span{ + color:var(--yourMoneyPriceTextColor); + text-shadow: 0.09vmin 0.09vmin 0.18vmin black; + font-size: 1.5vmin; +} + +.accept-button svg{ + height: 1.38vmin; + fill:var(--checkmarkColor); +} + +.green-text{ + color:var(--depositColorText) !important; +} + +.red-text{ + color:var(--withDrawColorText) !important; +} + + +.disable-button{ + background-color: var(--disableButtonBackgroundColor) !important; + pointer-events: none; +} + +h3 { + color: #ecedef; + color: var(--allTitleColor); + font-size: 2.31vmin; + text-shadow: 0.09vmin 0.09vmin 0.92vmin rgb(255 255 255 / 47%); + text-transform: uppercase; +} + +p{ + color: var(--cardSubtitleTextColor); + margin-bottom: 0.92vmin; + font-size: 1.5vmin; +} + +input{ + width: 100%; + font-family: 'Raleway', sans-serif; + font-size: 1.38vmin; + background-color: var(--inputBackgroundColor); + padding: 1.85vmin 1.85vmin; + outline: none; + border:none; + color:var(--inputTextColor); + margin-bottom:1.85vmin; + border-radius: 0.46vmin; +} + +input::placeholder { + color: var(--inputPlaceholderColor); + opacity: 1; +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; margin: 0; } -.transaction-listing { +/* GENERAL END*/ + +#modal-container { + background-color: var(--columnsBackground); + position: absolute; + top: 50%; + height: 100%; + width: 100%; + z-index: 2; + transform: translateY(-50%); + display: none; + border-radius: 1.38vmin; +} + +#more-modal-container { + height: 93%; + padding: 0 6vmin; +} + +#modal-container h3{ + text-align: center; + width: 100%; + margin-top: 1vmin; +} + +#modal-container #title-container button { + background-color: var(--buttonBackgroundColor); + padding: 1.85vmin 1.85vmin; + transition: all 0.3s ease; + font-weight: bold; + border-radius: 0.27vmin 0.27vmin 0.27vmin 1.27vmin; + font-family: 'Raleway', sans-serif; + font-size: 1.5vmin; + border: none; + color: var(--inputTextColor); + margin-left: auto; + position: absolute; + right: 0vmin; + top: 0vmin; + width: 14vmin; +} + +/*DATA TABLES DESIGN */ + +.dataTables_wrapper .dataTables_info { + clear: both; + float: left; + padding-top: .755em; + color:var(--tableAllTextColor) !important; +} + +#example_wrapper { + margin-top: 4vmin; + color: var(--tableAllTextColor) !important; + padding: 1vmin; + font-family: 'Raleway', sans-serif !important; +} + +#example_filter input{ display: flex; - flex-direction: row; - justify-content: space-between; - border-bottom: 5px solid rgba(255,255,255, 0.5); - padding: 10px 20px; -} \ No newline at end of file + gap: 1vmin; + border: none; + padding:2vmin; + background-color: var(--tableSearchInputBackgroundColor); +} + +.dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, .dataTables_wrapper .dataTables_paginate{ + color: var(--tableAllTextColor) !important; +} + +table.dataTable thead>tr>th.sorting, table.dataTable thead>tr>th.sorting_asc, table.dataTable thead>tr>th.sorting_desc, table.dataTable thead>tr>th.sorting_asc_disabled, table.dataTable thead>tr>th.sorting_desc_disabled, table.dataTable thead>tr>td.sorting, table.dataTable thead>tr>td.sorting_asc, table.dataTable thead>tr>td.sorting_desc, table.dataTable thead>tr>td.sorting_asc_disabled, table.dataTable thead>tr>td.sorting_desc_disabled ,table.dataTable thead>tr>td.sorting_disabled { + cursor: pointer; + position: relative; + padding-right: 26px; + color: var(--tableAllTextColor) !important; +} + +table.dataTable tbody tr td { + color: var(--tableAllTextColor); + font-weight: 500; +} + +.greenTableText{ + color: var(--depositColorText) !important; +} + +.redTableText{ + color: var(--withDrawColorText) !important; +} + +table.dataTable.no-footer { + border-bottom: 1px solid rgba(0, 0, 0, 0.3); +} + +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active { + cursor: default; + color:var(--tableAllTextColor) !important; + border: 1px solid #828282; + background: transparent; + box-shadow: none; +} + +.dataTables_wrapper .dataTables_paginate .paginate_button { + background: none; + color:var(--tableAllTextColor) !important; + border-radius: 4px; + border: 1px solid #828282; +} + +.dataTables_wrapper .dataTables_paginate .paginate_button:hover { + color: white !important; + background: var(--tableBackgroundColorPaginationButtonHover) !important; + background: var(--tableBackgroundColorPaginationButtonHover) !important; + background: var(--tableBackgroundColorPaginationButtonHover) !important; + background: var(--tableBackgroundColorPaginationButtonHover) !important; + box-shadow: 0px 3.42vmin 9.25vmin -1.20vmin var(--tableBackgroundColorPaginationButtonHover) !important; +} + +.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover { + background: var(--tableBackgroundColorPaginationButton) !important; + background: var(--tableBackgroundColorPaginationButton) !important; + background: var(--tableBackgroundColorPaginationButton) !important; + background: var(--tableBackgroundColorPaginationButton) !important; + box-shadow: 0px 3.42vmin 9.25vmin -1.20vmin var(--tableBackgroundColorPaginationButton) !important; + color:var(--tableAllTextColor) !important; +} + + +.dataTables_wrapper .dataTables_length select { + border-radius: 3px; + padding: 5px; + background-color: var(--tableSelectBoxBackgroundColor) !important; + padding: 4px; + color: var(--tableAllTextColor) !important; + padding: 1vmin; + border: none; + outline: none; +} + + +table.dataTable tbody tr{ height: 50px !important; } + +table.dataTable tbody tr:hover { + background-color:var(--tableRowHoverBackgroundColor) !important; + } + + #example_wrapper > div.dataTables_scroll > div.dataTables_scrollHead > div > table > thead > tr > th.sorting_disabled{ + color: var(--tableAllTextColor) !important; +} + + /*DATA TABLE DESIGN END*/ + + /*SCROLLBAR DESIGN*/ +::-webkit-scrollbar { + width: 5px; +} +::-webkit-scrollbar-track { + background: var(--tableScrollBarBackgroundColor2); +} +::-webkit-scrollbar-thumb { + background: var(--tableScrollBarBackgroundColor); +} +::-webkit-scrollbar-thumb:hover { + background: var(--tableScrollBarBackgroundColorHover); +} + + + + +/* LOADING CIRCLE*/ + +:root { + --rotation-animation-speed: 2s; + --rotation-animation-easing: linear; + --stroke-animation-speed: 1.5s; + --stroke-animation-easing: ease-in-out; + --stroke-width: 3px; + --stroke-start-dasharray: 1, 200; + --stroke-end-dasharray: 89, 200; +} + +.loader { + margin: 0px auto; + width: 23.14vmin; + height: 23.14vmin; + position: absolute; + top:50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 2; + display: none; +} + +.circular-loader { + animation: rotate var(--rotation-animation-speed) var(--rotation-animation-easing) infinite; +} + +.loader-path { + fill: none; + stroke-width: var(--stroke-width); + animation: animate-stroke var(--stroke-animation-speed) var(--stroke-animation-easing) infinite; + stroke-linecap: round; +} + +@keyframes rotate { + 100% { + transform: rotate(360deg); + } +} + +@keyframes animate-stroke { + 0% { + stroke-dasharray: var(--stroke-start-dasharray); + stroke-dashoffset: 0; + stroke: var(--columnsBackground); + } + 50% { + stroke-dasharray: var(--stroke-end-dasharray); + stroke-dashoffset: -35; + stroke: var(--loadingCircle); + } + 100% { + stroke-dasharray: var(--stroke-end-dasharray); + stroke-dashoffset: -124; + stroke: var(--loadingCircle); + } +} + + +#pincode-container{ + background-color: var(--columnsBackground); + height: 80%; + width: 40vmin; + color: white; + display: flex; + border-radius: 3vmin; + flex-direction: column; + justify-content: center; + gap: 5vmin; +} + +#pincode-container h4{ + text-align: center; + margin-top: 2vmin; +} + +#pincode-container .pincode-input { + display: flex; + justify-content: center; + align-items: center; + height: 15vmin; + width: 100%; + gap: 10px; +} + +#pincode-container .pincode-input span{ + display: block; + width: 3vmin; + height: 3vmin; + border-radius: 50%; + border: 2px solid var(--secondary-color); + transition: all 0.2s ease; +} + +#pincode-container .pincode-numbers { + display: grid; + grid-template-columns: 10vmin 10vmin 10vmin; + grid-template-rows: 10vmin 10vmin 10vmin; + place-items: center; + justify-content: center; +} + +#pincode-container .pincode-numbers div { + background-color: var(--background-light); + padding: 2vmin 2vmin; + border-radius: 50%; + width: 3vmin; + height: 3vmin; + display: flex; + justify-content: center; + align-items: center; + transition: all 0.3s ease; +} + +#pincode-container .pincode-numbers div:hover{ + background-color: var(--secondary-color); + box-shadow: 0px 3.42vmin 9.25vmin -1.20vmin var(--secondary-color); +} + +#pincode-container .pincode-numbers div:nth-child(11):hover{ + background-color: var(--exitButtonHoverBackgroundColor); + box-shadow: 0px 3.42vmin 9.25vmin -1.20vmin var(--exitButtonHoverBackgroundColor); +} + +#pincode-container .pincode-numbers div:nth-child(12):hover{ + background-color: var(--acceptButtonHoverBackgroundColor); + box-shadow: 0px 3.42vmin 9.25vmin -1.20vmin var(--acceptButtonHoverBackgroundColor); +} + +#pincode-container .button-groups{ + display: flex; + flex-direction: column; + align-items: center; + gap: 2vmin; + margin-top: 2vmin; +} + +#pincode-container .button-groups button{ + width: 80%; +} + +#pincode-container .button-groups button:hover{ + background-color: var(--exitButtonHoverBackgroundColor); + box-shadow: 0px 3.42vmin 9.25vmin -1.20vmin var(--exitButtonHoverBackgroundColor); +} + +#pincode-container .button-groups .login:hover{ + background-color: var(--acceptButtonHoverBackgroundColor); + box-shadow: 0px 3.42vmin 9.25vmin -1.20vmin var(--acceptButtonHoverBackgroundColor); +} + +.circleBackground{ + background-color: var(--secondary-color); +} + + +/* ATM DESIGNS*/ + +#atm-container{ + display: grid; + grid-template-columns: 60% 60%; + gap:3vmin; + height: 58vh; +} + +.firstGridColumn, .secondGridColumn{ + display: flex; + flex-direction: column; + padding: 1.85vmin; +} + +.firstGridColumn{ + gap: 1.79vmin; + border-radius: 1.38vmin; + background: var(--columnsBackground); +} + +.secondGridColumn{ + gap: 3vmin; + justify-content: center; +} + +.secondGridColumn div{ + background: var(--columnsBackground); + padding: 3vmin; + border-radius: 1.38vmin; +} diff --git a/[esx_addons]/esx_banking/html/images/checkmark.svg b/[esx_addons]/esx_banking/html/images/checkmark.svg new file mode 100644 index 00000000..583c32e8 --- /dev/null +++ b/[esx_addons]/esx_banking/html/images/checkmark.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/[esx_addons]/esx_banking/html/scripts/app.js b/[esx_addons]/esx_banking/html/scripts/app.js index fa977645..ff2d5c01 100644 --- a/[esx_addons]/esx_banking/html/scripts/app.js +++ b/[esx_addons]/esx_banking/html/scripts/app.js @@ -1,89 +1,1004 @@ -$(window).ready(function () { - window.addEventListener('message', function (event) { - let data = event.data; - if (data.showMenu) { - $('#container').fadeIn(); - $('#menu').fadeIn(); - $('#deposit_amount').val(data.player.money); - - let bankAmount = 0; - for (let i = 0; i < data.player.accounts.length; i++) { - if (data.player.accounts[i].name == 'bank') { - bankAmount = data.player.accounts[i].money; - $('#player-details').html("Money: $" + data.player.money); - $('#bank-details').html("Bank Balance: $" + bankAmount); +class Components{ + static allComponents = [] + static generateAllComponents(generatedData,generateType = "bank"){ + $("#wrapper").empty() + generatedData.forEach((form)=>{ + let objData = {} + if(form.elementID.substring(1) == "transfer" && generateType == "bank"){ + objData = new MultiComponentsForm(form) + }else if(form.componentName == "trans" && generateType == "bank"){ + objData = this.generateTransactionContainer(form) + } + else if(form.componentName == "pincodePanel" && generateType == "atm"){ + objData = this.generatePincodeContainer(form) + } + else if(form.componentName == "moreGraph" && generateType == "bank"){ + objData = this.generateMainTemplate(form) + this.generateMenuTemplate(form) + } + else if(form.componentName == "atmComponent" && generateType == "atm"){ + objData = this.generateAtmTemplate(form) + } + else{ + if(generateType == "bank"){ + if(form.componentName == "pincodePanel" || form.componentName == "atmComponent"){ + return + } } + else if(generateType == "atm"){ + if(form.componentName == "trans" || form.componentName == "moreGraph"){ + return + } + } + objData = new SingleComponentsForm(form) } - - $('#withdraw_amount').val(bankAmount); - } else if (data.hideAll) { - $('#container').fadeOut(); - } - if(data.history) { - //Play with this poop - $('#transaction-list').html(getHistory(data.history)) - } - - }); - - document.onkeyup = function (data) { - if (data.which == 27) { - $.post('http://esx_banking/escape', '{}'); - } - }; - - $('#container').hide(); - - $('#deposit_btn').on('click', function () { - $.post('http://esx_banking/deposit', JSON.stringify({ - amount: $('#deposit_amount').val() - })); - - $('#deposit_amount').val(0); - }) - - $('#deposit_amount').on("keyup", function (e) { - if (e.keyCode == 13) { - $.post('http://esx_banking/deposit', JSON.stringify({ - amount: $('#deposit_amount').val() - })); - - $('#deposit_amount').val(0); - } - }); - - $('#withdraw_btn').on('click', function () { - $.post('http://esx_banking/withdraw', JSON.stringify({ - amount: $('#withdraw_amount').val() - })); - - $('#withdraw_amount').val(0); - }); - - $('#withdraw_amount').on("keyup", function (e) { - if (e.keyCode == 13) { - $.post('http://esx_banking/withdraw', JSON.stringify({ - amount: $('#withdraw_amount').val() - })); - - $('#withdraw_amount').val(0); - } - }); - - function getHistory(history) { - let html = ''; - let jsonData = JSON.parse(history[0]).reverse() - for(let i = 0; i < jsonData.length; i++){ - html += "

" - if(jsonData[i].type.toString() === "withdraw"){ - html += "
$+" + jsonData[i].amount + "
"; + if(form.componentName != undefined){ + this.allComponents[form.componentName] = objData }else{ - html += "
$-" + jsonData[i].amount + "
"; + this.allComponents[form.elementID.substring(1)] = objData } - html += "
" + jsonData[i].type + "
"; - html += "
" - } - return html; + }) } + static getComponent(componentName){ + if(this.allComponents[componentName] != undefined){ + return this.allComponents[componentName] + } + return false + } + + static loader(appendedDiv, state){ + $(appendedDiv).empty() + if(state == "show"){ + $(appendedDiv).append(` + + + `); + $(appendedDiv).fadeIn(200) + + setTimeout(() => { + $(`${appendedDiv}`).fadeOut(200) + $("#wrapper").fadeIn().css("display","flex"); + if(appendedDiv == ".loader") $("#container").fadeIn().css("display","flex") + }, 2500); + }else if(state == "hide"){ + $(`${appendedDiv}`).fadeOut(200) + if(appendedDiv == ".loader"){ + $("#wrapper").fadeOut(200) + $("#container").fadeOut(200) + } + } + } + + static generateTransactionContainer(formData){ + $(formData.elementID).empty() + return $(formData.elementID).html(`

${formData.title}

+

${formData.description}

+
+ +
+
+ + +
+
`); + } + + static generatePincodeContainer(formData){ + return $(formData.elementID).append(` +
+
+

${formData.title}

+
+
+
${formData.deleteButtonText}
+
${formData.loginButtonText}
+
+
+ +
+
+
`); + + } + + static generateMainTemplate(formData){ + return $(formData.elementID).append(` +
+ +
`); + } + + static generateMenuTemplate(formData){ + $("#container").append(` + `); + } + + static generateAtmTemplate(formData){ + $(formData.elementID).append(` +
+
+

${formData.title}

+
+
+
+ +
+
+
+ `); + + return $(`${formData.elementID} #atm-container`) + } + +} + +class SingleComponentsForm { + elementID = "" + buttonText = "" + inputPlaceholder = "" + title = "" + description = "" + type = "number" + template = "" + name = "" + + constructor(form){ + this.elementID = form.elementID + this.buttonText = form.buttonText + this.inputPlaceholder = form.inputPlaceholder + this.title = form.title + this.description = form.description + this.type = form.type + this.name = form.name + this.renderInputAndButton() + } + + setElementId(newElementID){ + this.elementID = newElementID + } + + renderInputAndButton(){ + + this.template = `

${this.title}

${this.description}

`; + + if(this.type == "password"){ + this.template += `` + } + else{ + this.template += `` + } + + this.template += ``; + + $(this.elementID).append(`
${this.template}
`); + } + + show(){ + $(this.elementID).fadeIn(); + } + + hide(){ + $(this.elementID).fadeOut(); + } +} + +class MultiComponentsForm { + elementID = "" + buttonText = "" + inputPlaceholder = "" + inputPlaceholder2 = "" + title = "" + description = "" + + constructor(form){ + this.elementID = form.elementID + this.buttonText = form.buttonText + this.inputPlaceholder = form.inputPlaceholder + this.inputPlaceholder2 = form.inputPlaceholder2 + this.title = form.title + this.description = form.description + this.renderInputAndButtonGroups() + } + + renderInputAndButtonGroups(){ + $(this.elementID).html(`

${this.title}

+

${this.description}

+
+ + + +
`); + } + + show(){ + $(this.elementID).fadeIn(); + } + + hide(){ + $(this.elementID).fadeOut(); + } +} + +class Render { + fullRenderData = {} + elementID = "" + language = "" + constructor(elementID){ + this.elementID = elementID + // this.fullRenderData = renderData + } + + // getCurrentTemplate(){ + // let functionName = "" + // switch(this.elementID){ + // case "bankcard": + // functionName = this.renderBankCard() + // break; + // case "your_money": + // functionName = this.renderMyMoneySection() + // break; + // case "transaction": + // functionName = this.renderTransactions() + // break; + // } + // return functionName; + // } + + renderBankCard(){ + const bankData = this.fullRenderData + $("#bankcard").empty(); + let template = `
+

${bankData.bankName}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

Debit Card

+
+

${bankData.name}

+

${bankData.createdDate}

+
+

${bankData.cardNumber}

+
`; + $(template).appendTo("#bankcard"); + } + + renderMyMoneySection(){ + const moneyData = this.fullRenderData + $("#your-money-panel").empty(); + let template = `

${moneyData.title}

+

${moneyData.desc}

+
`; + moneyData.accountsData.forEach((data)=>{ + + template += ` +
+

${data.title}

+ ${this.language.moneyFormat.replace("__replaceData__",data.amount)} +
+ `; + }) + + template += "
" + + $(template).appendTo("#your-money-panel"); + } + + renderTransactions(){ + const transactionData = this.fullRenderData + $("#transactions-container").empty(); + if(transactionData.length == 0){ return} + + for(let i = 0; i < transactionData.slice(0,3).length; i++){ + let oneRow = ` +
+
+

${transactionData[i].type}

+ ${Utils.dateFormat(transactionData[i].time)} +
+ ${transactionData[i].type == this.language.withdraw || transactionData[i].type == this.language.transfer ? "-" : "+"}${this.language.moneyFormat.replace("__replaceData__",transactionData[i].amount)} +
+ `; + + $(oneRow).appendTo("#transactions-container"); + } + } + + setData(newData,newLanguage){ + this.fullRenderData = newData; + this.language = newLanguage; + } + + refresh(newData){ + switch (this.elementID) { + case "your_money": + $("#money-cash").html(`${this.language.moneyFormat.replace("__replaceData__",newData.money)} `); + $("#money-bank").html(`${this.language.moneyFormat.replace("__replaceData__",newData.bankMoney)}`); + break; + case "transaction": + this.fullRenderData = newData + this.renderTransactions() + break; + default: + break; + } + } +} + +class Pincode { + elementID = "" + pincode = "" + constructor(elementID){ + this.elementID = elementID + this.renderPinInputs() + this.renderPassCode() + this.hide(false) + } + + setPincode(newPincode){ + this.pincode += newPincode + } + + getPincode(){ + return this.pincode + } + + renderPassCode(){ + $("#container").fadeOut() + this.pincode = "" + $(`${this.elementID} .pincode-input`).empty() + for(let i = 0; i < 4;i++){ + $(`${this.elementID} .pincode-input`).append(``); + } + $(".pincode-numbers div:nth-child(12)").addClass("disable-button") + $(".pincode-numbers div:nth-child(12)").prop("disabled",true) + } + + renderPinInputs(){ + let numbers = [1,2,3,4,5,6,7,8,9,0] + numbers.forEach((number)=>{ + $(`
${number}
`).insertBefore(`.pincode-numbers .deleteButton`) + }) + } + + show(){ + $(this.elementID).fadeIn(100) + } + + hide(anim = true){ + if(anim){ + $(this.elementID).fadeOut(200) + } + else{ + $(this.elementID).hide() + } + } +} + + +const timeZone = localStorage.getItem("TIME_ZONE") +class Utils { + static dateFormat(date){ + if(typeof(date) == "number"){ + var newDate = new Date(date) + }else{ + var newDate = date + } + + return newDate.toLocaleString([timeZone], { + weekday:"long", + hour:"2-digit", + minute:"2-digit", + }).capitalize() + } + + static setCardData(value){ + if(localStorage.getItem("CARD_DATA") == null){ + localStorage.setItem("CARD_DATA",JSON.stringify(value)) + } + } + + static getCardData(){ + return JSON.parse(localStorage.getItem("CARD_DATA")) + } + + static genMonth() { + var date = new Date(); + var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; + var rNum = Math.floor(Math.random() * arr.length); + var year = date.getFullYear().toString(); + year = year.substr(2, year.length); + year = parseInt(parseInt(year) + 2); + return parseInt(rNum + 1) + '/' + year; + } + + static genCardNumber() { + let char = '0123456789' + let genNum = '' + for (let i = 0; i < 16; i++) { + var rnum = Math.floor(Math.random() * char.length); + genNum += char.substring(rnum, rnum + 1); + if((i + 1) % 4 == 0){ + genNum += " " + } + } + return genNum; + } +} + +class Graph{ + transData = {} + graphData = { + type: 'line', + data: { + labels: [], + datasets: [ + { + label: "BALANCE", + data:[], + backgroundColor: [ + 'rgba(75, 192, 192, 0.2)', + ], + borderColor: [ + 'rgba(75, 192, 192, 1)', + ], + borderWidth: 1 + } + ] + }, + options: { + responsive: true, + maintainAspectRatio:false, + scales: { + y: { + beginAtZero: true + } + } + } + } + + constructor(transData,title,color){ + this.graphData.data.datasets[0].label = title + this.transData = transData + this.calculateGraphData() + } + + refreshGraphData(newTransData){ + this.transData = newTransData + this.calculateGraphData() + this.renderSmallGraph() + } + + renderSmallGraph(){ + const ctx = $('#smallGraph'); + let chartStatus = Chart.getChart("smallGraph"); + + if (chartStatus != undefined) { + chartStatus.destroy(); + } + + return new Chart(ctx,this.graphData); + } + + renderBigGraph(){ + const ctx = $('#moreGraph'); + let chartStatus = Chart.getChart("moreGraph"); + + if (chartStatus != undefined) { + chartStatus.destroy(); + } + + return new Chart(ctx,this.graphData); + } + + calculateGraphData(){ + this.graphData.data.labels = [] + this.graphData.data.datasets[0].data = [] + this.graphData.data.datasets[0].borderColor = [ getComputedStyle(document.body).getPropertyValue('--graphLineColor')] + this.graphData.data.datasets[0].backgroundColor = [getComputedStyle(document.body).getPropertyValue('--graphLineBackgroundColor')] + for(let transaction of [...this.transData].slice(0,50).reverse()){ + this.graphData.data.labels.push(Utils.dateFormat(transaction.time)) + this.graphData.data.datasets[0].data.push(transaction.balance) + } + } + +} + +class GlobalStore{ + + storedData = {} + + constructor(newStoredData){ + this.storedData = newStoredData + } + + setStoredData(newStoredData){ + this.storedData = newStoredData + } + + getStoredData(){ + return this.storedData + } +} + +Object.defineProperty(String.prototype, 'capitalize', { + value: function() { + return this.charAt(0).toUpperCase() + this.slice(1); + }, + enumerable: false }); + + +$(document).ready(function(){ + + var formData + var language + $.getJSON("config.json", function(data){ + let lang = "EN" + if(data[data.lang] != null){ + lang = data.lang + } + localStorage.setItem("TIME_ZONE",lang == "EN" ? "en-GB" : "hu-HU") + formData = new GlobalStore(data[lang]["DYNAMIC_FORM_DATA"]) + language = new GlobalStore(data[lang]["LAUNGAGE"]) + }).fail(function(error){ + console.log("Can't load JSON file! " + error); + }); + + + var inputData = new GlobalStore({}) + var transactionData + + let yourMoney = new Render("your_money") + let transaction = new Render("transaction") + let bankcard = new Render("bankcard") + let graph = "" + var pincode = "" + var type = "" + + + Utils.setCardData({cardNumber:Utils.genCardNumber(), cardExpiry:Utils.genMonth()}) + + function bankRender(){ + Components.generateAllComponents(formData.getStoredData()) + } + + function ATMRender(){ + Components.generateAllComponents(formData.getStoredData(),"atm") + pincode = new Pincode("#pincode-container") + Components.getComponent("atmComponent").fadeOut() + Components.getComponent("withdraw").setElementId(".secondGridColumn") + Components.getComponent("withdraw").renderInputAndButton() + Components.getComponent("deposit").setElementId(".secondGridColumn") + Components.getComponent("deposit").renderInputAndButton() + + pincode.show() + } + + $(document).on('click','.pincode-numbers div',function(){ + if(pincode.getPincode().length + 1 == 4){ + $(".pincode-numbers div:nth-child(12)").removeClass("disable-button") + $(".pincode-numbers div:nth-child(12)").prop("disabled",false) + } + + let currentNumber = $(this).text(); + $(".pincode-input span").each(function () { + let spanText = $(this).attr('number'); + if (!spanText) { + $(this).attr("number",currentNumber) + $(this).addClass("circleBackground"); + pincode.setPincode(currentNumber) + return false; + } + }) + }) + + + $(document).on('click','.pincode-numbers div:nth-child(11)',function(){ + pincode.renderPassCode() + }) + + $(document).on('click','.pincode-numbers div:nth-child(12)',function(){ + $.post('https://esx_banking/checkPincode', JSON.stringify(pincode.getPincode())) + .then((response) =>{ + if(response.success){ + Components.loader("#pincode-container","show") + setTimeout(()=>{ + Components.getComponent("atmComponent").fadeIn(200) + },2800) + } + else if(response.error){ + pincode.renderPassCode() + } + }); + }) + + + window.addEventListener('message', ({data}) => { + const languageText = language.getStoredData() + if(data.showMenu){ + const datas = data.datas + + transactionData = new GlobalStore(datas.transactionsData) + const transData = transactionData.getStoredData() + transData.map((trans)=>{ + trans.id = trans.time + trans.time = Utils.dateFormat(trans.time) + switch(trans.type){ + case "WITHDRAW": + trans.type = languageText.withdraw + break; + case "DEPOSIT": + trans.type = languageText.deposit + break; + case "TRANSFER_RECEIVE": + trans.type = languageText.transferReceive + break; + default: + trans.type = languageText.transfer + break; + } + return trans + }) + + graph = new Graph(transData,languageText.graphTitle) + + if(data.openATM){ + ATMRender() + type = "ATM" + } + else{ + type = "BANK" + bankRender() + graph.renderSmallGraph() + + transaction.setData(transData,languageText) + transaction.renderTransactions() + } + + const bankData = Utils.getCardData() + datas.bankCardData.cardNumber = bankData.cardNumber + datas.bankCardData.createdDate = bankData.cardExpiry + bankcard.setData(datas.bankCardData) + bankcard.renderBankCard() + + yourMoney.setData(datas.your_money_panel,languageText) + yourMoney.renderMyMoneySection() + + + Components.loader(".loader","show") + }else if(data.updateData){ + const currentInputValues = inputData.getStoredData() + const updateTransData = transactionData.getStoredData() + + let info + if(amount = currentInputValues.withdraw){ + info = {label:languageText.withdraw, amount: amount} + } + else if(amount = currentInputValues.deposit) { + info = {label:languageText.deposit, amount: amount} + } + else if (amount = currentInputValues.transfer?.moneyAmount){ + info = {label:languageText.transfer, amount: amount} + } + else if (currentInputValues.pincode){ + return + } + updateTransData.unshift({time:Utils.dateFormat(new Date()),id: new Date().getTime(),amount: info.amount, type:info.label.toUpperCase(), balance: data.data.bankMoney}) + yourMoney.refresh(data.data) + transaction.refresh(updateTransData) + if(type == "BANK") graph.refreshGraphData(updateTransData) + } + }) + + function resetContainerAndSetTitle(title){ + $("#menu").fadeOut(); + $("#title-container h3").text(title); + $("#more-modal-container").empty(); + } + + + $(document).on('click','#more_graph',function(){ + resetContainerAndSetTitle(language.getStoredData().moreGraphTitle) + $("#modal-container").fadeIn(); + $("#more-modal-container").html(''); + graph.renderBigGraph() + }) + + + $(document).on('click','#more_history',function(){ + const lang = language.getStoredData() + resetContainerAndSetTitle(lang.moreHistoryTitle) + $("#more-modal-container").html(` + + + + + + + + + + +
idtypebalanceamounttime
`); + $('#example').DataTable({ + "responsive": true, + "data": transactionData.getStoredData(), + "columns": [ + { "data" : "id", }, + { "data": "type" , "title":lang.tableLang.typeLabel}, + { "data": "balance" ,"title":lang.tableLang.balanceLabel}, + { "data": "amount" , "title":lang.tableLang.amountLabel}, + { "data": "time" , "title":lang.tableLang.timeLabel} + ], + columnDefs: [ + { + target: 0, + visible: false, + searchable: false, + }, + { + target: 4, + orderable: false, + }, + ], + createdRow: function (row, data, index) { + let parseType = data.type.replace(/[\$,]/g, '') + $('td', row).eq(1).text(`$${data.balance}`) + if (parseType == lang.deposit || parseType == lang.transferReceive) { + $('td', row).eq(2).addClass('greenTableText'); + $('td', row).eq(2).html(`+${lang.moneyFormat.replace("__replaceData__",data.amount)}`) + } + else if(parseType == lang.withdraw || parseType == lang.transfer){ + $('td', row).eq(2).addClass('redTableText'); + $('td', row).eq(2).html(`-${lang.moneyFormat.replace("__replaceData__",data.amount)}`) + } + }, + "order": [[0, 'desc']], + "scrollY": "450px", + "scrollX": true, + "scrollCollapse": true, + "fixedColumns": { + "heightMatch": 'none' + }, + "language": { + "url": `https://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/${lang.tableLang.tableFullLanguage}.json`, + "search": '', "searchPlaceholder": lang.tableLang.searchInputPlaceholder + }, + + }); + + $("#modal-container").fadeIn(); + }) + + + let inputs = { + first: false, + second: false + } + + let currentNotify = false + $(document).on('keyup','input[type="number"] , input[type="password"]',function(){ + let buttonGroup = $(this).closest('.input-groups-container').find('button'); + + if(buttonGroup.length > 0){ + let name = $(this).attr("name"); + if(name == "moneyAmount"){ + inputs.first = $(this).val() != '' + } + else{ + inputs.second = $(this).val() != '' + } + + if(inputs.first && inputs.second){ + buttonGroup.removeClass('disable-button') + buttonGroup.prop('disabled',false) + } + else{ + buttonGroup.addClass('disable-button') + buttonGroup.prop('disabled',true) + } + + return + } + + let button = $(this).next('button'); + + if($(this).val() != '') { + if($(this).attr("name") == "pincode" && $(this).val().length < 4){ + if(!currentNotify){ + currentNotify = true + setTimeout(function(){ + currentNotify = false + },3000) + } + return + } + + button.removeClass('disable-button') + button.prop('disabled',false) + } + else{ + button.addClass('disable-button') + button.prop('disabled',true) + } + + }); + + $(document).on('click','.accept-button',function(){ + let buttonGroup = $(this).closest('.input-groups-container').find('button'); + let inputValues = {} + if(buttonGroup.length > 0){ + inputValues["transfer"] = {} + $(".input-groups-container input").each(function() { + inputValues["transfer"][$(this).attr('name')] = $(this).val(); + $(this).val(null); + inputs.first = false + inputs.second = false + }); + } + else{ + let inputValue = $(this).prev('input').val(); + if(inputValue == undefined){return} + if((inputValue.length == 0 && inputValue <= 0 )){ + if(!currentNotify){ + currentNotify = true + setTimeout(function(){ + currentNotify = false + },3000) + } + return + } + + inputValues[$(this).prev('input').attr('name')] = inputValue; + + $(this).prev('input').val(null); + } + + + inputData.setStoredData(inputValues) + $.post('https://esx_banking/clickButton', JSON.stringify(inputValues)); + + $(this).addClass('disable-button') + $(this).prop('disabled',true) + }) + + + $(document).on('click','#close-button',function(){ + $("#modal-container").fadeOut(); + $("#menu").fadeIn(); + }) + + $(document).on('click','.exit-button',function(){ + Components.loader(".loader","hide") + $.post('https://esx_banking/close', JSON.stringify({})); + }) + + $(document).keyup(function(e) { + if(e.which == 27) { + Components.loader(".loader","hide") + $.post('https://esx_banking/close', JSON.stringify({})); + } + }); +}) diff --git a/[esx_addons]/esx_banking/html/ui.html b/[esx_addons]/esx_banking/html/ui.html index b23d04fb..aa5b68f9 100644 --- a/[esx_addons]/esx_banking/html/ui.html +++ b/[esx_addons]/esx_banking/html/ui.html @@ -1,46 +1,21 @@ + + + + -
- - -
- - + + + + + \ No newline at end of file diff --git a/[esx_addons]/esx_banking/locales/de.lua b/[esx_addons]/esx_banking/locales/de.lua deleted file mode 100644 index c88b05e5..00000000 --- a/[esx_addons]/esx_banking/locales/de.lua +++ /dev/null @@ -1,7 +0,0 @@ -Locales['de'] = { - ['invalid_amount'] = 'Das ist ein ungültiger Geldbetrag', - ['deposit_money'] = 'Sie haben $%s eingezahlt', - ['withdraw_money'] = 'Sie haben $%s ausgezahlt', - ['press_e_banking'] = 'Drücke [E] um auf die Bank zuzugreifen', - ['banking_blip'] = 'Bank', -} \ No newline at end of file diff --git a/[esx_addons]/esx_banking/locales/en.lua b/[esx_addons]/esx_banking/locales/en.lua index a18f9369..5fd8777b 100644 --- a/[esx_addons]/esx_banking/locales/en.lua +++ b/[esx_addons]/esx_banking/locales/en.lua @@ -2,6 +2,19 @@ Locales['en'] = { ['invalid_amount'] = 'That\'s an invalid amount of money', ['deposit_money'] = 'you have deposited $%s', ['withdraw_money'] = 'you have withdrawn $%s', + ['pincode_money'] = 'you have new pincode %s', + ['transfer_money'] = 'you success transfer money $%s ID: %s', + ['receive_transfer'] = 'you receive transfer money $%s ID: %s', ['press_e_banking'] = 'press [E] to access the bank', + ['access_bank'] = 'Access the bank', ['banking_blip'] = 'Bank', -} + ['cant_do_it'] = "Can't do it!", + ['not_enough_money'] = "Not enough money! You need %s money!", + ['pincode_not_found'] = "Invalid PIN code", + ['pincode_found'] = "Valid PIN code...", + ['bank_name'] = "Fleeca Bank", + ['your_money_title'] = "Balance", + ['your_money_desc'] = "Here you can see your current balance and cash.", + ['your_money_cash'] = "Your cash", + ['your_money_bank'] = "Your bank balance" +} \ No newline at end of file diff --git a/[esx_addons]/esx_banking/locales/fr.lua b/[esx_addons]/esx_banking/locales/fr.lua deleted file mode 100644 index 23fbe158..00000000 --- a/[esx_addons]/esx_banking/locales/fr.lua +++ /dev/null @@ -1,7 +0,0 @@ -Locales['fr'] = { - ['invalid_amount'] = 'Le montant est invalide', - ['deposit_money'] = 'vous avez déposé $%s', - ['withdraw_money'] = 'vous avez retiré $%s', - ['press_e_banking'] = 'appuyez sur [E] pour accéder à la banque', - ['banking_blip'] = 'Banque', - } \ No newline at end of file diff --git a/[esx_addons]/esx_banking/locales/hu.lua b/[esx_addons]/esx_banking/locales/hu.lua index a21a51e5..a5877b32 100644 --- a/[esx_addons]/esx_banking/locales/hu.lua +++ b/[esx_addons]/esx_banking/locales/hu.lua @@ -1,7 +1,20 @@ Locales['hu'] = { - ['invalid_amount'] = 'Érvénytelen pénz mennyiség', - ['deposit_money'] = 'Befizettél %s$-t', - ['withdraw_money'] = 'Kivettél %s$-t', - ['press_e_banking'] = 'Nyomd meg a [E] gombot a bank eléréséhez', - ['banking_blip'] = 'Bank', -} + ['invalid_amount'] = 'Érvénytelen pénz mennyiség', + ['deposit_money'] = 'Befizettél %s$-t', + ['withdraw_money'] = 'Kivettél %s$-t', + ['pincode_money'] = 'Az új PIN kódod: %s', + ['transfer_money'] = 'Sikeres utalás! Összeg: $%s ID: %s', + ['receive_transfer'] = 'Utalás érkezett! Összeg: $%s ID: %s', + ['press_e_banking'] = 'Nyomd meg a [E] gombot a bank eléréséhez', + ['access_bank'] = 'Bank megnyitása', + ['banking_blip'] = 'Bank', + ['cant_do_it'] = "Ezt nem lehet!", + ['not_enough_money'] = "Nincs elég pénzed, még szükséged lesz ennyire: %s", + ['pincode_not_found'] = "Érvénytelen PIN kód", + ['pincode_found'] = "Érvényes PIN kód...", + ['bank_name'] = "Fleeca Bank", + ['your_money_title'] = "Egyenleg", + ['your_money_desc'] = "Itt láthatod a jelenlegi egyenleged és készpénzed.", + ['your_money_cash'] = "Készpénz", + ['your_money_bank'] = "Banki egyenleged" +} \ No newline at end of file diff --git a/[esx_addons]/esx_banking/server/main.lua b/[esx_addons]/esx_banking/server/main.lua index ea89c8f5..f936db88 100644 --- a/[esx_addons]/esx_banking/server/main.lua +++ b/[esx_addons]/esx_banking/server/main.lua @@ -1,61 +1,155 @@ -RegisterServerEvent('esx_banking:deposit') -AddEventHandler('esx_banking:deposit', function(amount) - local source = source - local xPlayer = ESX.GetPlayerFromId(source) - local identifier = xPlayer.getIdentifier() - amount = tonumber(amount) +-- get keys utils +local function get_key(t) + local key + for k, _ in pairs(t) do + key = k + end + return key +end - if not tonumber(amount) then return end - amount = ESX.Math.Round(amount) - - if amount == nil or amount <= 0 or amount > xPlayer.getMoney() then - xPlayer.showNotification(_U('invalid_amount')) - else - xPlayer.removeMoney(amount) - xPlayer.addAccountMoney('bank', amount) - xPlayer.showNotification(_U('deposit_money', amount)) - MySQL.update('INSERT INTO banking (identifier, type, amount, time) VALUES (@identifier, @type, @amount, @time)', { - ['@identifier'] = identifier, - ['@type'] = "deposit", - ['@amount'] = amount, - ['@time'] = os.date('%Y-%m-%d') - }) - end +-- Resource starting +AddEventHandler('onResourceStart', function(resourceName) + if (GetCurrentResourceName() ~= resourceName) then + return + end + local twoMonthMs = (os.time() - 5259487) * 1000 + MySQL.Sync.fetchScalar('DELETE FROM banking WHERE time < ? ', {twoMonthMs}) end) -ESX.RegisterServerCallback("esx_banking:gethistory", function(source, cb) - local xPlayer = ESX.GetPlayerFromId(source) - local identifier = xPlayer.getIdentifier() - local history = MySQL.Sync.prepare('SELECT * FROM banking WHERE identifier = ?', {identifier}) - cb(history) +-- event +RegisterServerEvent('esx_banking:doingType') +AddEventHandler('esx_banking:doingType', function(typeData) + if source == nil then + return + end + if (typeData == nil) then + return + end + + local source = source + local xPlayer = ESX.GetPlayerFromId(source) + local identifier = xPlayer.getIdentifier() + local money = xPlayer.getAccount('money').money + local bankMoney = xPlayer.getAccount('bank').money + + local key = get_key(typeData) + if typeData.deposit then + amount = tonumber(typeData.deposit) + elseif typeData.withdraw then + amount = tonumber(typeData.withdraw) + elseif typeData.transfer and typeData.transfer.moneyAmount then + amount = tonumber(typeData.transfer.moneyAmount) + elseif typeData.pincode then + amount = tonumber(typeData.pincode) + end + + if not tonumber(amount) then + return + end + amount = ESX.Math.Round(amount) + + if amount == nil or amount <= 0 then + TriggerClientEvent("esx:showNotification", source, _U('invalid_amount'), "error") + else + if typeData.deposit and amount <= money then + -- deposit + BANK.Deposit(amount, xPlayer) + elseif typeData.withdraw and bankMoney ~= nil and amount <= bankMoney then + -- withdraw + BANK.Withdraw(amount, xPlayer) + elseif typeData.pincode then + -- pincode + BANK.Pincode(amount, identifier) + elseif typeData.transfer then + -- transfer + if tonumber(typeData.transfer.playerId) > 0 and bankMoney >= amount then + local xTarget = ESX.GetPlayerFromId(tonumber(typeData.transfer.playerId)) + if not BANK.Transfer(xTarget, xPlayer, amount, key) then + return + end + end + else + TriggerClientEvent("esx:showNotification", source, _U('not_enough_money', amount), "error") + return + end + + money = xPlayer.getAccount('money').money + bankMoney = xPlayer.getAccount('bank').money + if typeData.transfer then + TriggerClientEvent("esx:showNotification", source, + _U(string.format('%s_money', key), amount, typeData.transfer.playerId), "success") + else + TriggerClientEvent("esx:showNotification", source, _U(string.format('%s_money', key), amount), "success") + end + if not typeData.pincode then + BANK.LogTransaction(source, string.upper(key), amount, bankMoney) + end + + TriggerClientEvent("esx_banking:updateMoneyInUI", source, key, bankMoney, money) + end end) +-- register callbacks +ESX.RegisterServerCallback("esx_banking:getPlayerData", function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) + local identifier = xPlayer.getIdentifier() + local weekAgo = (os.time() - 604800) * 1000 + local transactionHistory = MySQL.Sync.fetchAll( + 'SELECT * FROM banking WHERE identifier = ? AND time > ? ORDER BY time DESC LIMIT 10', {identifier, weekAgo}) + local playerData = { + playerName = xPlayer.getName(), + money = xPlayer.getAccount('money').money, + bankMoney = xPlayer.getAccount('bank').money, + transactionHistory = transactionHistory + } - - -RegisterServerEvent('esx_banking:withdraw') -AddEventHandler('esx_banking:withdraw', function(amount) - local source = source - local xPlayer = ESX.GetPlayerFromId(source) - local identifier = xPlayer.getIdentifier() - local time = os.date('%Y-%m-%d') - amount = tonumber(amount) - local accountMoney = xPlayer.getAccount('bank').money - - if not tonumber(amount) then return end - amount = ESX.Math.Round(amount) - - if amount == nil or amount <= 0 or amount > accountMoney then - xPlayer.showNotification(_U('invalid_amount')) - else - xPlayer.removeAccountMoney('bank', amount) - xPlayer.addMoney(amount) - xPlayer.showNotification(_U('withdraw_money', amount)) - MySQL.update('INSERT INTO banking (identifier, type, amount, time) VALUES (@identifier, @type, @amount, @time)', { - ['@identifier'] = identifier, - ['@type'] = "withdraw", - ['@amount'] = amount, - ['@time'] = os.date('%Y-%m-%d') - }) - end + cb(playerData) end) + +ESX.RegisterServerCallback("esx_banking:checkPincode", function(source, cb, inputPincode) + local xPlayer = ESX.GetPlayerFromId(source) + local identifier = xPlayer.getIdentifier() + local pincode = MySQL.Sync.fetchScalar('SELECT COUNT(1) AS pincode FROM users WHERE identifier = ? AND pincode = ?', + {identifier, inputPincode}) + cb(pincode > 0) +end) + +-- bank functions +BANK = { + Withdraw = function(amount, xPlayer) + xPlayer.addAccountMoney('money', amount) + xPlayer.removeAccountMoney('bank', amount) + end, + Deposit = function(amount, xPlayer) + xPlayer.removeAccountMoney('money', amount) + xPlayer.addAccountMoney('bank', amount) + end, + Transfer = function(xTarget, xPlayer, amount, key) + if xTarget == nil or xPlayer.source == xTarget.source then + TriggerClientEvent("esx:showNotification", source, _U("cant_do_it"), "error") + return false + end + + xPlayer.removeAccountMoney('bank', amount) + xTarget.addAccountMoney('bank', amount) + bankMoney = xTarget.getAccount('bank').money + BANK.LogTransaction(xTarget.source, "TRANSFER_RECEIVE", amount, bankMoney) + TriggerClientEvent("esx:showNotification", xTarget.source, _U('receive_transfer', amount, xPlayer.source), + "success") + + return true + end, + Pincode = function(amount, identifier) + MySQL.update('UPDATE users SET pincode = ? WHERE identifier = ? ', {amount, identifier}) + end, + LogTransaction = function(playerId, logType, amount, bankMoney) + if source == nil then + return + end + local xPlayer = ESX.GetPlayerFromId(playerId) + local identifier = xPlayer.getIdentifier() + + MySQL.insert('INSERT INTO banking (identifier, type, amount, time, balance) VALUES (?, ?, ?, ?, ?)', + {identifier, logType, amount, os.time() * 1000, bankMoney}) + end +}