Guest User

b2bking

a guest
Nov 17th, 2025
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.87 KB | None | 0 0
  1. <?php
  2. /**
  3. * Plugin Name: B2BKing User Management - COMPLETE v4.0
  4. * Description: Panel kompletny z sortowaniem, popupami i WooCommerce
  5. * Version: 4.0.0
  6. */
  7.  
  8. if (!defined('ABSPATH')) exit;
  9.  
  10. add_action('admin_menu', function() {
  11. add_menu_page('Zarządzanie Użytkownikami', 'Zarządzanie Użytkownikami', 'manage_options', 'b2bking-users', function() { display_users_page(); }, 'dashicons-businessperson', 30);
  12. add_submenu_page('b2bking-users', 'Ustawienia Kredytów', 'Ustawienia Kredytów', 'manage_options', 'b2bking-credits-settings', function() { display_credits_settings(); });
  13. add_submenu_page('b2bking-users', 'Ustawienia Statusów', 'Ustawienia Statusów', 'manage_options', 'b2bking-status-settings', function() { display_status_settings(); });
  14. });
  15.  
  16. add_action('admin_enqueue_scripts', function() {
  17. if (isset($_GET['page']) && strpos($_GET['page'], 'b2bking') !== false) {
  18. wp_enqueue_script('jquery');
  19. echo '<style>
  20. .b2bking-table { width: 100%; border-collapse: collapse; margin-top: 20px; background: #fff; box-shadow: 0 1px 3px; }
  21. .b2bking-table th { background: #f6f7f7; padding: 12px; text-align: left; font-weight: 600; border-bottom: 2px solid #ddd; cursor: pointer; user-select: none; }
  22. .b2bking-table th:hover { background: #e8e8e8; }
  23. .b2bking-table th.sortable::after { content: " ↕"; }
  24. .b2bking-table th.sorted-asc::after { content: " ↑"; }
  25. .b2bking-table th.sorted-desc::after { content: " ↓"; }
  26. .b2bking-table td { padding: 12px; border-bottom: 1px solid #eee; }
  27. .b2bking-table tr.expired { background: #fff3cd !important; }
  28. .b2bking-table tr.blocked { background: #f8d7da !important; }
  29. .btn { padding: 6px 12px; background: #0073aa; color: #fff; border: none; border-radius: 3px; cursor: pointer; font-size: 12px; margin-right: 4px; text-decoration: none; display: inline-block; }
  30. .btn:hover { background: #005177; }
  31. .btn.red { background: #dc3545; }
  32. .btn.red:hover { background: #c82333; }
  33. .btn.green { background: #28a745; }
  34. .btn.green:hover { background: #218838; }
  35. .btn.orange { background: #fd7e14; }
  36. .btn.orange:hover { background: #e46c0a; }
  37. .badge { display: inline-block; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600; }
  38. .badge.active { background: #d4edda; color: #155724; }
  39. .badge.expired { background: #fff3cd; color: #856404; }
  40. .badge.blocked { background: #f8d7da; color: #721c24; }
  41. .stats { display: flex; gap: 20px; margin: 20px 0; flex-wrap: wrap; }
  42. .stat { background: #fff; padding: 20px; border-left: 4px solid #0073aa; box-shadow: 0 1px 3px; flex: 1; min-width: 150px; }
  43. .stat-num { font-size: 28px; font-weight: 700; color: #0073aa; }
  44. .stat-label { color: #666; font-size: 13px; margin-top: 5px; }
  45. .form-group { margin: 20px 0; padding: 20px; background: #fff; border-left: 4px solid #0073aa; }
  46. .form-group label { display: block; font-weight: 600; margin-bottom: 10px; font-size: 14px; }
  47. .form-group input, .form-group textarea, .form-group select { width: 100%; max-width: 500px; padding: 10px; border: 1px solid #ddd; border-radius: 3px; box-sizing: border-box; }
  48. .inline-edit { display: flex; gap: 5px; align-items: center; flex-wrap: wrap; }
  49. .inline-edit input { flex: 0.8; min-width: 80px; padding: 4px; border: 1px solid #ddd; }
  50. .inline-edit select { flex: 0.9; padding: 4px; border: 1px solid #ddd; }
  51. .info-box { background: #d4edda; border: 1px solid #c3e6cb; color: #155724; padding: 15px; border-radius: 3px; margin: 20px 0; }
  52. .info-box.warning { background: #fff3cd; border-color: #ffeeba; color: #856404; }
  53. .section-title { font-size: 18px; font-weight: 600; margin: 30px 0 20px 0; border-bottom: 2px solid #0073aa; padding-bottom: 10px; }
  54. </style>';
  55. }
  56. });
  57.  
  58. // FRONTEND - POPUP ALERT
  59. add_action('wp_footer', function() {
  60. if (is_user_logged_in()) {
  61. $user_id = get_current_user_id();
  62. $status = get_user_meta($user_id, '_b2bking_status', true);
  63.  
  64. if ($status === 'blocked' || $status === 'expired') {
  65. $block_page = get_option('b2bking_block_page_url', '');
  66. $message = get_option('b2bking_status_message_expired', 'Konto jest zablokowane');
  67. ?>
  68. <script>
  69. jQuery(document).ready(function() {
  70. if (window.location.href.includes('/checkout')) {
  71. alert('<?php echo esc_js($message); ?>');
  72. <?php if ($block_page): ?>
  73. window.location.href = '<?php echo esc_url($block_page); ?>';
  74. <?php endif; ?>
  75. }
  76. });
  77. </script>
  78. <?php
  79. }
  80. }
  81. });
  82.  
  83. // SAVE CREDIT SETTINGS
  84. add_action('admin_post_b2bking_save_credits', function() {
  85. if (!current_user_can('manage_options')) wp_die('Brak uprawnień');
  86. check_admin_referer('b2bking_nonce');
  87. update_option('b2bking_default_credit', floatval($_POST['default_credit'] ?? 0));
  88. update_option('b2bking_credit_message', sanitize_textarea_field($_POST['credit_message'] ?? ''));
  89. wp_redirect(admin_url('admin.php?page=b2bking-credits-settings&msg=saved'));
  90. exit;
  91. });
  92.  
  93. // SAVE STATUS SETTINGS
  94. add_action('admin_post_b2bking_save_statuses', function() {
  95. if (!current_user_can('manage_options')) wp_die('Brak uprawnień');
  96. check_admin_referer('b2bking_nonce');
  97. update_option('b2bking_block_days', intval($_POST['block_days'] ?? 30));
  98. update_option('b2bking_status_paid', sanitize_text_field($_POST['status_paid'] ?? 'Po zapłaceniu'));
  99. update_option('b2bking_status_expired', sanitize_text_field($_POST['status_expired'] ?? 'Po zakończeniu'));
  100. update_option('b2bking_status_message_paid', sanitize_textarea_field($_POST['message_paid'] ?? ''));
  101. update_option('b2bking_status_message_expired', sanitize_textarea_field($_POST['message_expired'] ?? ''));
  102. update_option('b2bking_deduct_on_status', sanitize_text_field($_POST['deduct_on_status'] ?? 'completed'));
  103. update_option('b2bking_block_page_url', esc_url_raw($_POST['block_page_url'] ?? ''));
  104. wp_redirect(admin_url('admin.php?page=b2bking-status-settings&msg=saved'));
  105. exit;
  106. });
  107.  
  108. // UPDATE USER
  109. add_action('admin_post_b2bking_update_user', function() {
  110. if (!current_user_can('manage_options')) wp_die('Brak uprawnień');
  111. check_admin_referer('b2bking_nonce');
  112.  
  113. $user_id = intval($_POST['user_id'] ?? 0);
  114. $credit = floatval($_POST['credit'] ?? 0);
  115. $status = sanitize_text_field($_POST['status'] ?? 'paid');
  116.  
  117. update_user_meta($user_id, 'b2bking_user_credit_limit', $credit);
  118. update_user_meta($user_id, '_b2bking_status', $status);
  119.  
  120. if ($status === 'paid') {
  121. update_user_meta($user_id, '_b2bking_credit_date', date('Y-m-d'));
  122. }
  123.  
  124. wp_redirect(admin_url('admin.php?page=b2bking-users&msg=updated'));
  125. exit;
  126. });
  127.  
  128. // BLOCK USER
  129. add_action('admin_post_b2bking_block_user', function() {
  130. if (!current_user_can('manage_options')) wp_die('Brak uprawnień');
  131. check_admin_referer('b2bking_nonce');
  132.  
  133. $user_id = intval($_POST['user_id'] ?? 0);
  134. update_user_meta($user_id, '_b2bking_status', 'blocked');
  135. update_user_meta($user_id, '_b2bking_block_date', date('Y-m-d H:i:s'));
  136.  
  137. wp_redirect(admin_url('admin.php?page=b2bking-users&msg=blocked'));
  138. exit;
  139. });
  140.  
  141. // UNBLOCK USER
  142. add_action('admin_post_b2bking_unblock_user', function() {
  143. if (!current_user_can('manage_options')) wp_die('Brak uprawnień');
  144. check_admin_referer('b2bking_nonce');
  145.  
  146. $user_id = intval($_POST['user_id'] ?? 0);
  147. update_user_meta($user_id, '_b2bking_status', 'paid');
  148.  
  149. wp_redirect(admin_url('admin.php?page=b2bking-users&msg=unblocked'));
  150. exit;
  151. });
  152.  
  153. // RESTORE
  154. add_action('admin_post_b2bking_restore', function() {
  155. if (!current_user_can('manage_options')) wp_die('Brak uprawnień');
  156. check_admin_referer('b2bking_nonce');
  157.  
  158. $user_id = intval($_POST['user_id'] ?? 0);
  159. update_user_meta($user_id, '_b2bking_status', 'paid');
  160. update_user_meta($user_id, '_b2bking_credit_date', date('Y-m-d'));
  161.  
  162. wp_redirect(admin_url('admin.php?page=b2bking-users&msg=restored'));
  163. exit;
  164. });
  165.  
  166. // WOOCOMMERCE - DEDUCT CREDITS ON COMPLETED
  167. add_action('woocommerce_order_status_changed', function($order_id, $old_status, $new_status) {
  168. $deduct_on = get_option('b2bking_deduct_on_status', 'completed');
  169.  
  170. // Sprawdź czy to status na którym odbijać
  171. if ($new_status !== $deduct_on) return;
  172.  
  173. $order = wc_get_order($order_id);
  174. if (!$order) return;
  175.  
  176. $user_id = $order->get_customer_id();
  177. if (!$user_id) return;
  178.  
  179. $payment_method = $order->get_payment_method();
  180. if ($payment_method !== 'b2bking-credit-gateway') return;
  181.  
  182. // Sprawdź czy już było odbite
  183. if (get_post_meta($order_id, '_b2bking_credit_deducted', true)) {
  184. return; // Już odbite
  185. }
  186.  
  187. $order_total = floatval($order->get_total());
  188.  
  189. // Pobierz obecny consumed balance
  190. $consumed = floatval(get_user_meta($user_id, 'b2bking_user_credit_consumed_balance', true) ?: 0);
  191. $new_consumed = $consumed + $order_total;
  192.  
  193. // Zaktualizuj consumed balance
  194. update_user_meta($user_id, 'b2bking_user_credit_consumed_balance', $new_consumed);
  195.  
  196. // Oznacz że już odbite
  197. update_post_meta($order_id, '_b2bking_credit_deducted', true);
  198.  
  199. }, 10, 3);
  200.  
  201. // CHECK IF USER IS BLOCKED - PREVENT CHECKOUT
  202. add_action('woocommerce_after_checkout_validation', function($posted_data, $errors) {
  203. $user_id = get_current_user_id();
  204. if (!$user_id) return;
  205.  
  206. $status = get_user_meta($user_id, '_b2bking_status', true);
  207.  
  208. if ($status === 'blocked' || $status === 'expired') {
  209. $message = get_option('b2bking_status_message_expired', 'Konto jest zablokowane');
  210. $errors->add('b2bking_blocked', '❌ ' . $message);
  211. }
  212. }, 10, 2);
  213.  
  214. function get_user_status($user_id) {
  215. $custom = get_user_meta($user_id, '_b2bking_status', true);
  216.  
  217. if ($custom === 'blocked') return 'blocked';
  218. if ($custom === 'expired') return 'expired';
  219.  
  220. $paid_date = get_user_meta($user_id, '_b2bking_credit_date', true);
  221. $block_days = intval(get_option('b2bking_block_days', 30));
  222.  
  223. if ($paid_date && time() > strtotime($paid_date . ' +' . $block_days . ' days')) {
  224. update_user_meta($user_id, '_b2bking_status', 'expired');
  225. return 'expired';
  226. }
  227. return 'paid';
  228. }
  229.  
  230. function get_days_left($user_id) {
  231. $paid_date = get_user_meta($user_id, '_b2bking_credit_date', true);
  232. $block_days = intval(get_option('b2bking_block_days', 30));
  233. if (!$paid_date) return -1;
  234. $expiry = strtotime($paid_date . ' +' . $block_days . ' days');
  235. return ceil(($expiry - time()) / 86400);
  236. }
  237.  
  238. function display_users_page() {
  239. if (!current_user_can('manage_options')) wp_die('Brak uprawnień');
  240.  
  241. if (isset($_GET['msg'])) {
  242. $msgs = ['updated' => '✓ Zaktualizowano', 'restored' => '✓ Przywrócono', 'blocked' => '✓ Zablokowano', 'unblocked' => '✓ Odblokowano'];
  243. if (isset($msgs[$_GET['msg']])) echo '<div class="notice notice-success"><p>' . $msgs[$_GET['msg']] . '</p></div>';
  244. }
  245.  
  246. $all = count_users();
  247. $total = $all['total_users'];
  248. $paid_q = new WP_User_Query(['meta_key' => '_b2bking_status', 'meta_value' => 'paid', 'fields' => 'ID']);
  249. $paid = $paid_q->get_total();
  250. $expired_q = new WP_User_Query(['meta_key' => '_b2bking_status', 'meta_value' => 'expired', 'fields' => 'ID']);
  251. $expired = $expired_q->get_total();
  252. $blocked_q = new WP_User_Query(['meta_key' => '_b2bking_status', 'meta_value' => 'blocked', 'fields' => 'ID']);
  253. $blocked = $blocked_q->get_total();
  254. $nonce = wp_create_nonce('b2bking_nonce');
  255.  
  256. $status_paid_label = get_option('b2bking_status_paid', 'Po zapłaceniu');
  257. $status_expired_label = get_option('b2bking_status_expired', 'Po zakończeniu');
  258. ?>
  259. <div class="wrap">
  260. <h1>Zarządzanie Użytkownikami B2BKing</h1>
  261.  
  262. <div class="stats">
  263. <div class="stat"><div class="stat-num"><?php echo $total; ?></div><div class="stat-label">Wszyscy</div></div>
  264. <div class="stat"><div class="stat-num"><?php echo $paid; ?></div><div class="stat-label"><?php echo esc_html($status_paid_label); ?></div></div>
  265. <div class="stat"><div class="stat-num"><?php echo $expired; ?></div><div class="stat-label"><?php echo esc_html($status_expired_label); ?></div></div>
  266. <div class="stat"><div class="stat-num"><?php echo $blocked; ?></div><div class="stat-label">Zablokowani</div></div>
  267. </div>
  268.  
  269. <table class="b2bking-table" id="b2bkingTable">
  270. <thead>
  271. <tr>
  272. <th class="sortable" data-column="id">ID</th>
  273. <th class="sortable" data-column="login">Użytkownik</th>
  274. <th class="sortable" data-column="email">Email</th>
  275. <th class="sortable" data-column="limit">Limit</th>
  276. <th class="sortable" data-column="consumed">Zużyto</th>
  277. <th class="sortable" data-column="available">Dostępne</th>
  278. <th class="sortable" data-column="status">Status</th>
  279. <th class="sortable" data-column="days">Dni</th>
  280. <th>Akcje</th>
  281. </tr>
  282. </thead>
  283. <tbody>
  284. <?php
  285. $users = get_users(['number' => 500, 'orderby' => 'registered', 'order' => 'DESC']);
  286. $rows = array();
  287.  
  288. foreach ($users as $user) {
  289. $limit = floatval(get_user_meta($user->ID, 'b2bking_user_credit_limit', true) ?: 0);
  290. $consumed = floatval(get_user_meta($user->ID, 'b2bking_user_credit_consumed_balance', true) ?: 0);
  291. $available = $limit - $consumed;
  292. $status = get_user_status($user->ID);
  293. $days = get_days_left($user->ID);
  294. $status_badge = ($status === 'paid') ? '<span class="badge active">✓ '.$status_paid_label.'</span>' : (($status === 'expired') ? '<span class="badge expired">⏰ '.$status_expired_label.'</span>' : '<span class="badge blocked">🔒 Zablokowany</span>');
  295. $row_class = ($status === 'blocked') ? 'blocked' : (($status === 'expired') ? 'expired' : '');
  296.  
  297. $rows[] = array(
  298. 'id' => $user->ID,
  299. 'login' => $user->user_login,
  300. 'email' => $user->user_email,
  301. 'limit' => $limit,
  302. 'consumed' => $consumed,
  303. 'available' => $available,
  304. 'status_num' => ($status === 'paid') ? 0 : (($status === 'expired') ? 1 : 2),
  305. 'status' => $status,
  306. 'days' => ($days > 0) ? $days : -999,
  307. 'status_badge' => $status_badge,
  308. 'row_class' => $row_class,
  309. 'user' => $user
  310. );
  311. }
  312.  
  313. foreach ($rows as $row) {
  314. ?>
  315. <tr class="<?php echo $row['row_class']; ?>">
  316. <td><?php echo $row['id']; ?></td>
  317. <td><strong><?php echo esc_html($row['login']); ?></strong></td>
  318. <td><?php echo esc_html($row['email']); ?></td>
  319. <td><?php echo number_format($row['limit'], 2); ?> zł</td>
  320. <td><?php echo number_format($row['consumed'], 2); ?> zł</td>
  321. <td><?php echo number_format($row['available'], 2); ?> zł</td>
  322. <td><?php echo $row['status_badge']; ?></td>
  323. <td><?php echo ($row['days'] > 0) ? $row['days'] . ' dni' : 'WYGASŁO'; ?></td>
  324. <td>
  325. <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" style="display: inline;">
  326. <input type="hidden" name="action" value="b2bking_update_user">
  327. <input type="hidden" name="user_id" value="<?php echo $row['user']->ID; ?>">
  328. <input type="hidden" name="_wpnonce" value="<?php echo $nonce; ?>">
  329. <div class="inline-edit">
  330. <input type="number" step="0.01" name="credit" value="<?php echo $row['limit']; ?>" placeholder="Limit">
  331. <select name="status">
  332. <option value="paid" <?php selected($row['status'], 'paid'); ?>>✓ <?php echo esc_html($status_paid_label); ?></option>
  333. <option value="expired" <?php selected($row['status'], 'expired'); ?>>⏰ <?php echo esc_html($status_expired_label); ?></option>
  334. <option value="blocked" <?php selected($row['status'], 'blocked'); ?>>🔒 Zablokowany</option>
  335. </select>
  336. <button type="submit" class="btn">OK</button>
  337. </div>
  338. </form>
  339.  
  340. <?php if ($row['status'] !== 'blocked'): ?>
  341. <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" style="display: inline;">
  342. <input type="hidden" name="action" value="b2bking_block_user">
  343. <input type="hidden" name="user_id" value="<?php echo $row['user']->ID; ?>">
  344. <input type="hidden" name="_wpnonce" value="<?php echo $nonce; ?>">
  345. <button type="submit" class="btn red" onclick="return confirm('Zablokować?')">Zablokuj</button>
  346. </form>
  347. <?php else: ?>
  348. <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" style="display: inline;">
  349. <input type="hidden" name="action" value="b2bking_unblock_user">
  350. <input type="hidden" name="user_id" value="<?php echo $row['user']->ID; ?>">
  351. <input type="hidden" name="_wpnonce" value="<?php echo $nonce; ?>">
  352. <button type="submit" class="btn green">Odblokuj</button>
  353. </form>
  354. <?php endif; ?>
  355.  
  356. <?php if ($row['status'] === 'expired'): ?>
  357. <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" style="display: inline;">
  358. <input type="hidden" name="action" value="b2bking_restore">
  359. <input type="hidden" name="user_id" value="<?php echo $row['user']->ID; ?>">
  360. <input type="hidden" name="_wpnonce" value="<?php echo $nonce; ?>">
  361. <button type="submit" class="btn orange">Przywróć</button>
  362. </form>
  363. <?php endif; ?>
  364. </td>
  365. </tr>
  366. <?php
  367. }
  368. ?>
  369. </tbody>
  370. </table>
  371. </div>
  372.  
  373. <script>
  374. jQuery(document).ready(function($) {
  375. let currentSort = { column: 'id', order: 'asc' };
  376.  
  377. $('th.sortable').on('click', function() {
  378. let column = $(this).data('column');
  379. let order = (currentSort.column === column && currentSort.order === 'asc') ? 'desc' : 'asc';
  380.  
  381. $('th.sortable').removeClass('sorted-asc sorted-desc');
  382. $(this).addClass('sorted-' + order);
  383.  
  384. currentSort = { column: column, order: order };
  385. sortTable(column, order);
  386. });
  387.  
  388. function sortTable(column, order) {
  389. let rows = $('#b2bkingTable tbody tr').get();
  390.  
  391. rows.sort(function(a, b) {
  392. let aVal = $(a).find('td').eq(getColumnIndex(column)).text();
  393. let bVal = $(b).find('td').eq(getColumnIndex(column)).text();
  394.  
  395. // Numeric sort
  396. if (column === 'id' || column === 'limit' || column === 'consumed' || column === 'available' || column === 'days') {
  397. aVal = parseFloat(aVal) || 0;
  398. bVal = parseFloat(bVal) || 0;
  399. }
  400.  
  401. if (order === 'asc') {
  402. return aVal > bVal ? 1 : -1;
  403. } else {
  404. return aVal < bVal ? 1 : -1;
  405. }
  406. });
  407.  
  408. $.each(rows, function(index, row) {
  409. $('#b2bkingTable tbody').append(row);
  410. });
  411. }
  412.  
  413. function getColumnIndex(column) {
  414. let columns = { id: 0, login: 1, email: 2, limit: 3, consumed: 4, available: 5, status: 6, days: 7 };
  415. return columns[column] || 0;
  416. }
  417. });
  418. </script>
  419. <?php
  420. }
  421.  
  422. function display_credits_settings() {
  423. if (!current_user_can('manage_options')) wp_die('Brak uprawnień');
  424. if (isset($_GET['msg']) && $_GET['msg'] === 'saved') echo '<div class="notice notice-success"><p>✓ Ustawienia kredytów zapisane</p></div>';
  425.  
  426. $default = floatval(get_option('b2bking_default_credit', 0));
  427. $message = get_option('b2bking_credit_message', '');
  428. $nonce = wp_create_nonce('b2bking_nonce');
  429. ?>
  430. <div class="wrap">
  431. <h1>⚙️ Ustawienia Kredytów</h1>
  432. <form method="post" action="<?php echo admin_url('admin-post.php'); ?>">
  433. <input type="hidden" name="action" value="b2bking_save_credits">
  434. <input type="hidden" name="_wpnonce" value="<?php echo $nonce; ?>">
  435. <div class="form-group">
  436. <label for="default_credit"><strong>📊 Domyślna ilość kredytów:</strong></label>
  437. <input type="number" id="default_credit" name="default_credit" value="<?php echo $default; ?>" step="0.01">
  438. </div>
  439. <div class="form-group">
  440. <label for="credit_message"><strong>💬 Wiadomość o kredytach:</strong></label>
  441. <textarea id="credit_message" name="credit_message" rows="5"><?php echo esc_textarea($message); ?></textarea>
  442. </div>
  443. <button type="submit" class="btn">💾 Zapisz</button>
  444. </form>
  445. </div>
  446. <?php
  447. }
  448.  
  449. function display_status_settings() {
  450. if (!current_user_can('manage_options')) wp_die('Brak uprawnień');
  451. if (isset($_GET['msg']) && $_GET['msg'] === 'saved') echo '<div class="notice notice-success"><p>✓ Ustawienia statusów zapisane</p></div>';
  452.  
  453. $block_days = intval(get_option('b2bking_block_days', 30));
  454. $status_paid = get_option('b2bking_status_paid', 'Po zapłaceniu');
  455. $status_expired = get_option('b2bking_status_expired', 'Po zakończeniu');
  456. $message_paid = get_option('b2bking_status_message_paid', 'Konto aktywne');
  457. $message_expired = get_option('b2bking_status_message_expired', 'Kredyty wygasły');
  458. $deduct_on = get_option('b2bking_deduct_on_status', 'completed');
  459. $block_page = get_option('b2bking_block_page_url', '');
  460. $nonce = wp_create_nonce('b2bking_nonce');
  461.  
  462. $pages = get_pages();
  463. ?>
  464. <div class="wrap">
  465. <h1>⚙️ Ustawienia Statusów</h1>
  466. <form method="post" action="<?php echo admin_url('admin-post.php'); ?>">
  467. <input type="hidden" name="action" value="b2bking_save_statuses">
  468. <input type="hidden" name="_wpnonce" value="<?php echo $nonce; ?>">
  469.  
  470. <div class="section-title">🕐 Ustawienia czasowe</div>
  471. <div class="form-group">
  472. <label for="block_days"><strong>Liczba dni do wygaśnięcia:</strong></label>
  473. <input type="number" id="block_days" name="block_days" value="<?php echo $block_days; ?>" min="1" max="365">
  474. </div>
  475.  
  476. <div class="form-group">
  477. <label for="deduct_on_status"><strong>💰 Odejmuj kredyty na statusie:</strong></label>
  478. <select id="deduct_on_status" name="deduct_on_status">
  479. <option value="completed" <?php selected($deduct_on, 'completed'); ?>>Completed (Ukończone)</option>
  480. <option value="processing" <?php selected($deduct_on, 'processing'); ?>>Processing (Przetwarzane)</option>
  481. </select>
  482. <p class="description">Na jakim statusie będą odbijane kredyty z konta</p>
  483. </div>
  484.  
  485. <div class="form-group">
  486. <label for="block_page_url"><strong>🔗 Strona do której kierować zablokowanych użytkowników:</strong></label>
  487. <select id="block_page_url" name="block_page_url">
  488. <option value="">-- Bez redirekcji --</option>
  489. <?php foreach ($pages as $page): ?>
  490. <option value="<?php echo get_page_link($page->ID); ?>" <?php selected($block_page, get_page_link($page->ID)); ?>>
  491. <?php echo esc_html($page->post_title); ?>
  492. </option>
  493. <?php endforeach; ?>
  494. </select>
  495. <p class="description">Użytkownik z zablokowanym kontem będzie przekierowany na tę stronę przy próbie wejścia do checkoutu</p>
  496. </div>
  497.  
  498. <div class="section-title">✓ Status 1: Po zapłaceniu</div>
  499. <div class="form-group">
  500. <label for="status_paid"><strong>Nazwa statusu:</strong></label>
  501. <input type="text" id="status_paid" name="status_paid" value="<?php echo esc_attr($status_paid); ?>">
  502. </div>
  503. <div class="form-group">
  504. <label for="message_paid"><strong>Wiadomość:</strong></label>
  505. <textarea id="message_paid" name="message_paid" rows="4"><?php echo esc_textarea($message_paid); ?></textarea>
  506. </div>
  507.  
  508. <div class="section-title">⏰ Status 2: Po zakończeniu</div>
  509. <div class="form-group">
  510. <label for="status_expired"><strong>Nazwa statusu:</strong></label>
  511. <input type="text" id="status_expired" name="status_expired" value="<?php echo esc_attr($status_expired); ?>">
  512. </div>
  513. <div class="form-group">
  514. <label for="message_expired"><strong>Wiadomość/Alert:</strong></label>
  515. <textarea id="message_expired" name="message_expired" rows="4" placeholder="Ta wiadomość będzie wyświetlana w popupie..."><?php echo esc_textarea($message_expired); ?></textarea>
  516. </div>
  517.  
  518. <button type="submit" class="btn">💾 Zapisz</button>
  519. </form>
  520.  
  521. <div class="info-box warning" style="margin-top: 40px;">
  522. <h3>✅ System w pełni automatyczny:</h3>
  523. <ol>
  524. <li>Kredyty odejmują się automatycznie na wybranym statusie (Completed)</li>
  525. <li>Popup alert pokazuje się gdy ktoś próbuje wejść do checkoutu ze zblokowanym kontem</li>
  526. <li>Kierowanie na wybraną stronę (np. "Skontaktuj się z nami")</li>
  527. <li>Wszystko działa bez klikania!</li>
  528. </ol>
  529. </div>
  530. </div>
  531. <?php
  532. }
  533.  
Advertisement
Add Comment
Please, Sign In to add comment