diff --git a/actions-web.php b/actions-web.php index 93a5328d..5a7a8ccd 100644 --- a/actions-web.php +++ b/actions-web.php @@ -301,16 +301,6 @@ function trips($userId, $bike = 0) echo json_encode($jsoncontent); // TODO change to response function } -function getuserlist() -{ - global $db; - $result = $db->query('SELECT users.userId,username,mail,number,privileges,credit,userLimit FROM users LEFT JOIN credit ON users.userId=credit.userId LEFT JOIN limits ON users.userId=limits.userId ORDER BY username'); - while ($row = $result->fetch_assoc()) { - $jsoncontent[] = array('userid' => $row['userId'], 'username' => $row['username'], 'mail' => $row['mail'], 'number' => $row['number'], 'privileges' => $row['privileges'], 'credit' => $row['credit'], 'limit' => $row['userLimit']); - } - echo json_encode($jsoncontent); // TODO change to response function -} - function getuserstats() { global $db; @@ -335,40 +325,6 @@ function getusagestats() echo json_encode($jsoncontent); // TODO change to response function } -function edituser($userid) -{ - global $db; - $result = $db->query('SELECT users.userId,userName,mail,number,privileges,userLimit,credit FROM users LEFT JOIN limits ON users.userId=limits.userId LEFT JOIN credit ON users.userId=credit.userId WHERE users.userId=' . $userid); - $row = $result->fetch_assoc(); - $jsoncontent = array('userid' => $row['userId'], 'username' => $row['userName'], 'email' => $row['mail'], 'phone' => $row['number'], 'privileges' => $row['privileges'], 'limit' => $row['userLimit'], 'credit' => $row['credit']); - echo json_encode($jsoncontent); // TODO change to response function -} - -function saveuser($userid, $username, $email, $phone, $privileges, $limit) -{ - global $db; - $result = $db->query("UPDATE users SET username='$username',mail='$email',privileges='$privileges' WHERE userId=" . $userid); - if ($phone) { - $result = $db->query("UPDATE users SET number='$phone' WHERE userId=" . $userid); - } - - $result = $db->query("UPDATE limits SET userLimit='$limit' WHERE userId=" . $userid); - response(_('Details of user') . ' ' . $username . ' ' . _('updated') . '.'); -} - -function addcredit($userid, $creditmultiplier) -{ - global $db, $user, $creditSystem; - - $minRequiredCredit = $creditSystem->getMinRequiredCredit(); - $addcreditamount = $minRequiredCredit * $creditmultiplier; - $result = $db->query('UPDATE credit SET credit=credit+' . $addcreditamount . ' WHERE userId=' . $userid); - $result = $db->query("INSERT INTO history SET userId=$userid,bikeNum=0,action='CREDITCHANGE',parameter='" . $addcreditamount . '|add+' . $addcreditamount . "'"); - $userName = $user->findUserName($userid); - - response(_('Added') . ' ' . $addcreditamount . $creditSystem->getCreditCurrency() . ' ' . _('credit for') . ' ' . $userName . '.'); -} - function validatecoupon($userid, $coupon) { global $db, $creditSystem; diff --git a/command.php b/command.php index b3e34787..6a23acb4 100644 --- a/command.php +++ b/command.php @@ -106,12 +106,6 @@ checkprivileges($userid); liststands(); break; - case "userlist": - logrequest($userid,$action); - $auth->refreshSession(); - checkprivileges($userid); - getuserlist(); - break; case "userstats": logrequest($userid,$action); $auth->refreshSession(); @@ -124,24 +118,6 @@ checkprivileges($userid); getusagestats(); break; - case "edituser": - logrequest($userid,$action); - $auth->refreshSession(); - checkprivileges($userid); - edituser($_GET["edituserid"]); - break; - case "saveuser": - logrequest($userid,$action); - $auth->refreshSession(); - checkprivileges($userid); - saveuser($_GET["edituserid"],$_GET["username"],$_GET["email"],$_GET["phone"],$_GET["privileges"],$_GET["limit"]); - break; - case "addcredit": - logrequest($userid,$action); - $auth->refreshSession(); - checkprivileges($userid); - addcredit($_GET["edituserid"],$_GET["creditmultiplier"]); - break; case "trips": logrequest($userid,$action); $auth->refreshSession(); diff --git a/config/routes.php b/config/routes.php index 46cbeca4..4e6545d0 100644 --- a/config/routes.php +++ b/config/routes.php @@ -46,6 +46,18 @@ $routes->add('api_coupon_generate', '/api/coupon/generate') ->methods(['POST']) ->controller([\BikeShare\Controller\Api\CouponController::class, 'generate']); + $routes->add('api_user_index', '/api/user') + ->methods(['GET']) + ->controller([\BikeShare\Controller\Api\UserController::class, 'index']); + $routes->add('api_user_item', '/api/user/{userId}') + ->methods(['GET']) + ->controller([\BikeShare\Controller\Api\UserController::class, 'item']); + $routes->add('api_user_item_update', '/api/user/{userId}') + ->methods(['PUT']) + ->controller([\BikeShare\Controller\Api\UserController::class, 'update']); + $routes->add('api_credit_add', '/api/credit') + ->methods(['PUT']) + ->controller([\BikeShare\Controller\Api\CreditController::class, 'add']); $routes->add('personal_stats_year', '/personalStats/year/{year}') ->methods(['GET']) diff --git a/public/js/admin.js b/public/js/admin.js index 80f2d571..94216506 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -1,7 +1,4 @@ -var oTable; - $(document).ready(function () { - $("#edituser").hide(); $("#where").click(function () { if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-where'); bikeInfo($('#bikeNumber').val()); @@ -16,14 +13,6 @@ $(document).ready(function () { last($(this).data('bike-number')); event.preventDefault(); }); - $("#stands").click(function () { - if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-stands'); - stands(); - }); - $("#userlist").click(function () { - if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-userlist'); - userlist(); - }); $("#userstats").click(function () { if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-userstats'); userstats(); @@ -36,55 +25,54 @@ $(document).ready(function () { sellcoupon($(this).data('coupon')); event.preventDefault(); }); - $("#generatecoupons1").click(function () { - if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-generatecoupons'); - generatecoupons(1); - }); - $("#generatecoupons2").click(function () { - if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-generatecoupons'); - generatecoupons(5); + $('#userconsole').on('click', '.edituser', function (event) { + if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-edituser', $(this).attr('data-userid')); + edituser($(this).attr('data-userid')); + event.preventDefault(); + }) + $('#edituser').on('click', '.cancel', function (event) { + $('#edituser') + .addClass('d-none') + .find('input').val(''); + event.preventDefault(); }); - $("#generatecoupons3").click(function () { - if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-generatecoupons'); - generatecoupons(10); + $(".generatecoupons").click(function (event) { + generatecoupons($(this).data('multiplier')); + event.preventDefault(); }); $("#trips").click(function () { if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-trips'); trips(); }); - $("#saveuser").click(function () { - saveuser(); - return false; - }); - $("#addcredit").click(function () { - addcredit(1); - return false; - }); - $("#addcredit2").click(function () { - addcredit(5); - return false; + $("#saveuser").click(function (event) { + saveuser($('#userid').val()); + event.preventDefault(); }); - $("#addcredit3").click(function () { - addcredit(10); - return false; + $(".addcredit").click(function (event) { + addcredit($('#userid').val(), $(this).data('multiplier')); + event.preventDefault(); }); $('a[data-toggle="tab"]').on('show.bs.tab', function (e) { const target = $(e.target).attr("href"); switch (target) { case "#fleet": + if (window.ga) ga('send', 'event', 'bikes', 'admin-fleet'); bikeInfo(); break; case "#users": + if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-userlist'); userlist(); break; case "#stands": + if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-stands'); stands(); break; case "#reports": userstats(); break; case "#credit": + if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-couponlist'); couponlist(); break; } @@ -151,8 +139,6 @@ function generateBikeCards(data) { } function bikeInfo(bikeNumber) { - if (window.ga) ga('send', 'event', 'bikes', 'where', bikeNumber); - $.ajax({ url: "/api/bike" + (bikeNumber ? "/" + bikeNumber : ""), method: "GET", @@ -167,8 +153,6 @@ function bikeInfo(bikeNumber) { } function last(bikeNumber) { - if (window.ga) ga('send', 'event', 'bikes', 'last', bikeNumber); - $.ajax({ url: "/api/bikeLastUsage/" + bikeNumber, method: "GET", @@ -203,7 +187,6 @@ function last(bikeNumber) { console.error("Error fetching bike data:", error); } }); - } function stands() { @@ -216,41 +199,63 @@ function stands() { } function userlist() { - var code = ""; - $.ajax({ - url: "command.php?action=userlist" - }).done(function (jsonresponse) { - jsonobject = $.parseJSON(jsonresponse); - if (jsonobject.length > 0) code = ''; - if (creditenabled == 1) code = code + ''; - code = code + ''; - for (var i = 0, len = jsonobject.length; i < len; i++) { - code = code + ''; - if (creditenabled == 1) { - code = code + ''; + let table = $('#user-table').DataTable({ + destroy: true, + searching: false, + ajax: { + url: '/api/user', + dataSrc: '', + cache: true + }, + dom: 'lrtip', + columns: [ + { + data: 'username', + name: 'username', + render: function(data, type, row) { + return `${data} +
${row.number} +
${row.mail}`; + } + }, + { + data: 'privileges', + name: 'privileges' + }, + { + data: 'userLimit', + name: 'userLimit' + }, + { + data: 'credit', + name: 'credit', + visible: creditenabled === 1, + render: function(data, type, row) { + return `${data} ${creditcurrency}`; + } } + ], + error: function(xhr, error, code) { + console.error('Error loading data:', error); } - if (jsonobject.length > 0) code = code + '
' + _user + '' + _privileges + '' + _limit + '' + _credit + '
' + jsonobject[i]["username"] + '
' + jsonobject[i]["number"] + '
' + jsonobject[i]["mail"] + '
' + jsonobject[i]["privileges"] + '' + jsonobject[i]["limit"] + '' + jsonobject[i]["credit"] + creditcurrency + '
'; - $('#userconsole').html(code); - createeditlinks(); - oTable = $('#usertable').dataTable({ - "dom": 'f<"filtertoolbar">prti', - "paging": false, - "ordering": false, - "info": false - }); - $('div.filtertoolbar').html(''); - $('#usertable th').each(function () { - $('#columnfilter').append($("").attr('value', $(this).text()).text($(this).text())); - }); - $('#usertable_filter input').keyup(function () { - x = $('#columnfilter').prop("selectedIndex") - 1; - if (x == -1) fnResetAllFilters(); else oTable.fnFilter($(this).val(), x); - }); - $('#columnfilter').change(function () { - x = $('#columnfilter').prop("selectedIndex") - 1; - if (x == -1) fnResetAllFilters(); else oTable.fnFilter($('#usertable_filter input').val(), x); - }); + }); + + // Variable to track the column index for custom search + let searchColumnIndex = 0; + + // Update dropdown and search column index + $('.search-option').click(function () { + const columnName = $(this).data('column'); + searchColumnIndex = table.column(`${columnName}:name`).index(); // Get column index + $('#searchTypeDropdown').text($(this).text()); // Update dropdown button text + }); + + // Custom search logic + $('#customSearchInput').on('keyup', function () { + const searchTerm = this.value; + table.columns(searchColumnIndex) + .search(searchTerm) + .draw(); }); } @@ -266,7 +271,6 @@ function userstats() { } if (jsonobject.length > 0) code = code + ''; $('#reportsconsole').html(code); - createeditlinks(); $('#userstatstable').dataTable({ "paging": false, "ordering": false, @@ -290,61 +294,81 @@ function usagestats() { }); } -function createeditlinks() { - $('.edituser').each(function () { - $(this).click(function () { - if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-edituser', $(this).attr('data-userid')); - edituser($(this).attr('data-userid')); - }); - }); -} - function edituser(userid) { $.ajax({ - url: "command.php?action=edituser&edituserid=" + userid - }).done(function (jsonresponse) { - jsonobject = $.parseJSON(jsonresponse); - if (jsonobject) { - $('#userid').val(jsonobject["userid"]); - $('#username').val(jsonobject["username"]); - $('#email').val(jsonobject["email"]); - if ($('#phone')) $('#phone').val(jsonobject["phone"]); - $('#privileges').val(jsonobject["privileges"]); - $('#limit').val(jsonobject["limit"]); - $('#edituser').show(); - $('a[href="#users"]').trigger('click'); + url: "/api/user/" + userid, + method: "GET", + dataType: "json", + success: function(data) { + console.log(data); + $container = $("#edituser"); + $container.find('input').val(''); + $container.find('#userid').val(data.userId); + $container.find('#username').val(data.username); + $container.find('#email').val(data.mail); + if ($container.find('#phone').length) { + $container.find('#phone').val(data.number); + } + $container.find('#privileges').val(data.privileges); + $container.find('#limit').val(data.userLimit); + $container.removeClass('d-none'); + $('html, body').animate({ + scrollTop: $container.offset().top + }, 500); + }, + error: function(xhr, status, error) { + console.error("Error fetching user data:", error); } }); } -function saveuser() { - if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-saveuser', $('#userid').val()); - var phone = ""; - if ($('#phone')) phone = "&phone=" + $('#phone').val(); +function saveuser(userId) { + if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-saveuser', userId); + $.ajax({ - url: "command.php?action=saveuser&edituserid=" + $('#userid').val() + "&username=" + $('#username').val() + "&email=" + $('#email').val() + "&privileges=" + $('#privileges').val() + "&limit=" + $('#limit').val() + phone - }).done(function (jsonresponse) { - jsonobject = $.parseJSON(jsonresponse); - $("#edituser").hide(); - handleresponse("userconsole", jsonobject); - setTimeout(userlist, 2000); + url: "/api/user/" + userId, + method: "PUT", + dataType: "json", + data: { + 'username': $('#username').val(), + 'email': $('#email').val(), + 'number': $('#phone').length ? $('#phone').val() : '', + 'privileges': $('#privileges').val(), + 'userLimit': $('#limit').val() + + }, + success: function(data) { + $("#edituser").addClass('d-none'); + userlist(); + }, + error: function(xhr, status, error) { + console.error("Error update user data:", error); + } }); } -function addcredit(creditmultiplier) { - if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-addcredit', $('#userid').val()); +function addcredit(userId, multiplier) { + if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-addcredit', userId, multiplier); + $.ajax({ - url: "command.php?action=addcredit&edituserid=" + $('#userid').val() + "&creditmultiplier=" + creditmultiplier - }).done(function (jsonresponse) { - jsonobject = $.parseJSON(jsonresponse); - $("#edituser").hide(); - handleresponse("userconsole", jsonobject); - setTimeout(userlist, 2000); + url: "/api/credit", + method: "PUT", + dataType: "json", + data: { + 'userId': userId, + 'multiplier': multiplier + }, + success: function(data) { + $("#edituser").addClass('d-none'); + userlist(); + }, + error: function(xhr, status, error) { + console.error("Error update user data:", error); + } }); } function couponlist() { - if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-couponlist'); $.ajax({ url: "/api/coupon", method: "GET", @@ -375,6 +399,7 @@ function couponlist() { } function generatecoupons(multiplier) { + if (window.ga) ga('send', 'event', 'buttons', 'click', 'admin-generatecoupons', multiplier); $.ajax({ url: "/api/coupon/generate", method: "POST", @@ -447,11 +472,3 @@ function revert(bikeNumber) { handleresponse("fleetconsole", jsonobject); }); } - -function fnResetAllFilters() { - var oSettings = oTable.fnSettings(); - for (iCol = 0; iCol < oSettings.aoPreSearchCols.length; iCol++) { - oSettings.aoPreSearchCols[iCol].sSearch = ''; - } - oTable.fnDraw(); -} \ No newline at end of file diff --git a/src/Controller/Api/BikeController.php b/src/Controller/Api/BikeController.php index 1d79f044..04c38e4b 100644 --- a/src/Controller/Api/BikeController.php +++ b/src/Controller/Api/BikeController.php @@ -36,7 +36,7 @@ public function index( } /** - * @Route("/bike/{bikeNumber}", name="api_bike_item", methods={"GET"}) + * @Route("/api/bike/{bikeNumber}", name="api_bike_item", methods={"GET"}) */ public function item( $bikeNumber, diff --git a/src/Controller/Api/CreditController.php b/src/Controller/Api/CreditController.php new file mode 100644 index 00000000..e2dfacd2 --- /dev/null +++ b/src/Controller/Api/CreditController.php @@ -0,0 +1,73 @@ +isGranted('ROLE_ADMIN')) { + $logger->info( + 'User tried to access admin page without permission', + [ + 'user' => $this->getUser()->getUserIdentifier(), + ] + ); + + return $this->json([], Response::HTTP_FORBIDDEN); + } + + $userId = $request->request->getInt('userId'); + $multiplier = $request->request->getInt('multiplier'); + + if ( + empty($userId) + || empty($multiplier) + || !is_numeric($userId) + || !is_numeric($multiplier) + || $multiplier < 1 + || $multiplier > 10 + ) { + return $this->json([], Response::HTTP_BAD_REQUEST); + } + + $minRequiredCredit = $creditSystem->getMinRequiredCredit(); + $creditAmount = $minRequiredCredit * $multiplier; + + $creditRepository->addItem($userId, (float)$creditAmount); + $historyRepository->addItem( + $userId, + 0, //BikeNum + 'CREDITCHANGE', //action + $creditAmount . '|add+' . $creditAmount //parameter + ); + + $user = $userRepository->findItem($userId); + + return new Response( + 'Added ' . $creditAmount . $creditSystem->getCreditCurrency() . ' credit for ' + . $user['username'] . '.' + ); + } +} diff --git a/src/Controller/Api/UserController.php b/src/Controller/Api/UserController.php new file mode 100644 index 00000000..b7183259 --- /dev/null +++ b/src/Controller/Api/UserController.php @@ -0,0 +1,119 @@ +isGranted('ROLE_ADMIN')) { + $logger->info( + 'User tried to access admin page without permission', + [ + 'user' => $this->getUser()->getUserIdentifier(), + ] + ); + + return $this->json([], Response::HTTP_FORBIDDEN); + } + + $bikes = $userRepository->findAll(); + + return $this->json($bikes); + } + + /** + * @Route("/api/user/{userId}", name="api_user_item", methods={"GET"}) + */ + public function item( + $userId, + UserRepository $userRepository, + LoggerInterface $logger + ): Response { + if (!$this->isGranted('ROLE_ADMIN')) { + $logger->info( + 'User tried to access admin page without permission', + [ + 'user' => $this->getUser()->getUserIdentifier(), + ] + ); + + return $this->json([], Response::HTTP_FORBIDDEN); + } + + if (empty($userId) || !is_numeric($userId)) { + return $this->json([], Response::HTTP_BAD_REQUEST); + } + + $user = $userRepository->findItem((int)$userId); + + return $this->json($user); + } + + /** + * @Route("/api/user/{userId}", name="api_user_item_update", methods={"PUT"}) + */ + public function update( + $userId, + Request $request, + UserRepository $userRepository, + Configuration $configuration, + LoggerInterface $logger + ): Response { + if (!$this->isGranted('ROLE_ADMIN')) { + $logger->info( + 'User tried to access admin page without permission', + [ + 'user' => $this->getUser()->getUserIdentifier(), + ] + ); + + return $this->json([], Response::HTTP_FORBIDDEN); + } + + if (empty($userId) || !is_numeric($userId)) { + return $this->json([], Response::HTTP_BAD_REQUEST); + } + + $userName = $request->request->get('username'); + $email = $request->request->get('email'); + $number = $request->request->get('number'); + $privileges = $request->request->getInt('privileges'); + $userLimit = $request->request->getInt('userLimit'); + + if ( + empty($userName) + || empty($email) + || !filter_var($email, FILTER_VALIDATE_EMAIL) + || ($configuration->get('connectors')['sms'] !== '' && empty($number)) + ) { + return $this->json([], Response::HTTP_BAD_REQUEST); + } + + $userRepository->updateItem( + (int)$userId, + $userName, + $email, + $number, + $privileges, + $userLimit + ); + + return new Response('Details of user ' . $userName . ' updated.'); + } +} diff --git a/src/EventListener/ControllerEventListener.php b/src/EventListener/ControllerEventListener.php index 9535167d..88326461 100644 --- a/src/EventListener/ControllerEventListener.php +++ b/src/EventListener/ControllerEventListener.php @@ -17,6 +17,10 @@ class ControllerEventListener 'api_coupon_index', 'api_coupon_sell', 'api_coupon_generate', + 'api_user_index', + 'api_user_item', + 'api_user_item_update', + 'api_credit_add', ]; private DbInterface $db; diff --git a/src/EventListener/ResponseEventListener.php b/src/EventListener/ResponseEventListener.php index 3cb86f84..464c0a43 100644 --- a/src/EventListener/ResponseEventListener.php +++ b/src/EventListener/ResponseEventListener.php @@ -13,6 +13,9 @@ class ResponseEventListener private const LOGGED_ROUTES = [ 'api_coupon_sell', 'api_coupon_generate', + 'api_user_item', + 'api_user_item_update', + 'api_credit_add', ]; private DbInterface $db; diff --git a/src/Repository/CreditRepository.php b/src/Repository/CreditRepository.php new file mode 100644 index 00000000..c6b809b4 --- /dev/null +++ b/src/Repository/CreditRepository.php @@ -0,0 +1,25 @@ +db = $db; + } + + public function addItem(int $userId, float $creditAmount): void + { + $userId = $this->db->escape($userId); + $creditAmount = $this->db->escape($creditAmount); + $this->db->query("UPDATE credit SET credit=credit+' . $creditAmount . ' WHERE userId=' . $userId . '"); + } +} diff --git a/src/Repository/HistoryRepository.php b/src/Repository/HistoryRepository.php new file mode 100644 index 00000000..879c084f --- /dev/null +++ b/src/Repository/HistoryRepository.php @@ -0,0 +1,35 @@ +db = $db; + } + + public function addItem( + int $userId, + int $bikeNum, + string $action, + string $parameter + ): void { + $userId = $this->db->escape($userId); + $bikeNum = $this->db->escape($bikeNum); + $action = $this->db->escape($action); + $parameter = $this->db->escape($parameter); + + $this->db->query(" + INSERT INTO history (userId, bikeNum, action, parameter) + VALUES ($userId, $bikeNum, '$action', '$parameter') + "); + } +} diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php new file mode 100644 index 00000000..7feb083a --- /dev/null +++ b/src/Repository/UserRepository.php @@ -0,0 +1,83 @@ +db = $db; + } + + public function findAll(): array + { + $users = $this->db->query( + 'SELECT + users.userId, + username, + mail, + number, + privileges, + credit, + userLimit + FROM users + LEFT JOIN credit ON users.userId=credit.userId + LEFT JOIN limits ON users.userId=limits.userId + ORDER BY username' + )->fetchAllAssoc(); + + + return $users; + } + + public function findItem(int $userId): array + { + $user = $this->db->query( + 'SELECT + users.userId, + username, + mail, + number, + privileges, + credit, + userLimit + FROM users + LEFT JOIN credit ON users.userId=credit.userId + LEFT JOIN limits ON users.userId=limits.userId + WHERE users.userId=' . $userId + )->fetchAssoc(); + + return $user; + } + + public function updateItem( + int $userId, + string $username, + string $email, + string $number, + int $privileges, + int $userLimit + ): void { + $this->db->query( + 'UPDATE users + SET username="' . $username . '", + mail="' . $email . '", + number="' . $number . '", + privileges=' . $privileges . ' + WHERE userId=' . $userId + ); + + $this->db->query( + 'UPDATE limits + SET userLimit=' . $userLimit . ' + WHERE userId=' . $userId + ); + } +} diff --git a/templates/admin/credit.html.twig b/templates/admin/credit.html.twig index 75cb5bca..60394af7 100644 --- a/templates/admin/credit.html.twig +++ b/templates/admin/credit.html.twig @@ -1,15 +1,13 @@ {% block credit %}
- - - + {% set multipliers = [1, 5, 10] %} + {% for multiplier in multipliers %} + + {% endfor %}
diff --git a/templates/admin/fleet.html.twig b/templates/admin/fleet.html.twig index ebbaabb4..47bb9051 100644 --- a/templates/admin/fleet.html.twig +++ b/templates/admin/fleet.html.twig @@ -52,9 +52,9 @@ -
+
diff --git a/templates/admin/index.html.twig b/templates/admin/index.html.twig index e1a6f15a..6cb8977c 100644 --- a/templates/admin/index.html.twig +++ b/templates/admin/index.html.twig @@ -78,44 +78,7 @@
-
-
- -
-
-
-
- - -
-
- - -
- {% if configuration.get('connectors')['sms'] %} -
- - -
- {% endif %} -
- - -
-
- - -
- - - or - - - -
-
+ {% include ('admin/user.html.twig') %}
{% if creditSystem.isEnabled %}
diff --git a/templates/admin/user.html.twig b/templates/admin/user.html.twig new file mode 100644 index 00000000..44b8401d --- /dev/null +++ b/templates/admin/user.html.twig @@ -0,0 +1,78 @@ +{% block user %} +
+
+ + +
+
+ + +
+ {% if configuration.get('connectors')['sms'] %} +
+ + +
+ {% endif %} +
+ + +
+
+ + +
+ + + + {% if creditSystem.isEnabled %} + or + {% set multipliers = [1, 5, 10] %} + {% for multiplier in multipliers %} + + {% endfor %} + {% endif %} +
+
+
+
+
+
+
+ + +
+ +
+
+
+
+
+ + + + + + + {% if creditSystem.isEnabled %} + + {% endif %} + + + + +
{{ 'User'|trans }}{{ 'Privileges'|trans }}{{ 'Limit'|trans }}{{ 'Credit'|trans }}
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/base.html.twig b/templates/base.html.twig index 2a52c1b4..7f054602 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -63,9 +63,9 @@
- - - + + + {% block scripts %}{% endblock %} diff --git a/translations/messages+intl-icu.en.php b/translations/messages+intl-icu.en.php index bc3e4323..da3dc585 100644 --- a/translations/messages+intl-icu.en.php +++ b/translations/messages+intl-icu.en.php @@ -93,6 +93,7 @@ 'Privileges:' => 'Privileges:', 'Bike limit:' => 'Bike limit:', 'Save' => 'Save', + 'Cancel' => 'Cancel', 'Add' => 'Add', 'Show user stats.' => 'Show user stats.', 'User stats' => 'User stats', @@ -130,7 +131,7 @@ 'Make sure you set code to' => '', 'Rotate lockpad to 0000.' => '', 'has been returned by admin' => '', - 'Credit' => '', + 'Credit' => 'Credit', 'Bike note' => '', 'is at stand' => '', 'is rented by' => '', @@ -337,8 +338,8 @@ 'Existing user password change' => '', 'Step 2 - Change password' => '', 'Set password' => '', - 'Privileges' => '', - 'Limit' => '', + 'Privileges' => 'Privileges', + 'Limit' => 'Limit', 'Value' => 'Value', 'Status' => 'Status', 'Mark as sold' => 'Mark as sold',