Padel Net Cost Calculator

Calculate and display net cost of padel matches in the header

  1. // ==UserScript==
  2. // @name Padel Net Cost Calculator
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Calculate and display net cost of padel matches in the header
  6. // @author You
  7. // @match *://*.ballejaune.com/account*
  8. // @license MIT
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. // Function to calculate net cost from reservation history
  16. function calculateNetCost() {
  17. const rows = document.querySelectorAll('tr[data-rowid]');
  18. let valid_reservations = 0
  19. let friends_paied_for = 0
  20. rows.forEach(row => {
  21. const badge = row.querySelector('div.badge');
  22. const originTd = row.querySelector('td:nth-child(3)');
  23. if (badge && originTd) {
  24. const text = badge.textContent.trim();
  25. const match = text.match(/([+-]\s*\d+)/);
  26. if (match) {
  27. const K_str = match[1].replace(/\s+/g, ''); // e.g., "- 1" -> "-1"
  28. const K = parseInt(K_str);
  29. if (!isNaN(K) && K !== 100) { // Exclude initial +100 purchase
  30. const originText = originTd.innerHTML.trim();
  31. // Reservation for yourself
  32. if (originText.includes('Réservation') && K < 0) {
  33. valid_reservations++
  34. }
  35. // Cancellation
  36. else if (originText.includes('Réservation') && K > 0) {
  37. valid_reservations--
  38. }
  39. // Paying for friends
  40. else if (originText.includes('Club')) {
  41. friends_paied_for -= K
  42. }
  43. }
  44. }
  45. }
  46. });
  47. const totalNetCost = valid_reservations * 15 - friends_paied_for * 5
  48. return totalNetCost
  49.  
  50. }
  51.  
  52. // Function to inject net cost into the header
  53. function injectNetCost(netCost) {
  54. const menu = document.querySelector('ul#widget-menu');
  55. if (menu) {
  56. const net_cost_item_refreach = document.querySelector('#widget-netcost span');
  57. if (net_cost_item_refreach){
  58. net_cost_item_refreach.textContent = `Net Cost: ${netCost} dt`;
  59. }else{
  60. const netCostItem = document.createElement('li');
  61. netCostItem.className = 'navbar-widget-nav-line';
  62. netCostItem.id = 'widget-netcost';
  63.  
  64. const netCostLink = document.createElement('a');
  65. netCostLink.className = 'navbar-widget-nav-link';
  66. netCostLink.href = '#'; // Non-clickable link
  67. netCostLink.setAttribute('data-container', '#main-tooltips');
  68. netCostLink.setAttribute('data-placement', 'bottom');
  69. netCostLink.setAttribute('data-delay', '500');
  70. netCostLink.setAttribute('title', 'Net Cost');
  71. netCostLink.style.color = '#fff'; // Match navbar text color
  72. netCostLink.style.cursor = 'default'; // Indicate non-interactive
  73.  
  74. const netCostText = document.createElement('span');
  75. netCostText.textContent = `Net Cost: ${netCost} dt`;
  76.  
  77. netCostLink.appendChild(netCostText);
  78. netCostItem.appendChild(netCostLink);
  79. menu.insertBefore(netCostItem, menu.firstChild);
  80. }
  81. console.log(netCost);
  82. } else {
  83. console.error('Widget menu not found!');
  84. }
  85. }
  86.  
  87. // Wait for the page to fully load
  88. window.addEventListener('load', function() {
  89. setInterval(()=>{
  90. const netCost = calculateNetCost();
  91. injectNetCost(netCost)}, 5000)
  92. });
  93. })();