Changeset 3493462
- Timestamp:
- 03/28/2026 04:42:21 PM (10 hours ago)
- Location:
- wc-reports-lite/trunk
- Files:
-
- 28 added
- 28 deleted
- 6 edited
- 1 moved
-
assets/css/admin-style-rtl.css (modified) (1 diff)
-
assets/css/admin-style.css (modified) (8 diffs)
-
assets/css/select2.min.css (added)
-
assets/images/copy.svg (added)
-
assets/images/csv.svg (added)
-
assets/images/customer.jpg (deleted)
-
assets/images/dokan.jpg (deleted)
-
assets/images/email.jpg (deleted)
-
assets/images/excel.svg (added)
-
assets/images/export.jpg (deleted)
-
assets/images/pdf.svg (added)
-
assets/images/printer.svg (added)
-
assets/images/profit.jpg (deleted)
-
assets/images/search_filter.jpg (deleted)
-
assets/images/visual_report.jpg (deleted)
-
assets/images/wooreports.png (deleted)
-
assets/js/Chart.js (added)
-
assets/js/admin.js (modified) (2 diffs)
-
assets/js/persianDatepicker.js (modified) (20 diffs)
-
assets/js/select2.min.js (added)
-
includes/admin-pages/wcrl-categories.php (deleted)
-
includes/admin-pages/wcrl-coupons.php (deleted)
-
includes/admin-pages/wcrl-locations.php (deleted)
-
includes/admin-pages/wcrl-orders-status.php (deleted)
-
includes/admin-pages/wcrl-orders.php (deleted)
-
includes/admin-pages/wcrl-overview.php (deleted)
-
includes/admin-pages/wcrl-payment-gateway.php (deleted)
-
includes/admin-pages/wcrl-products.php (deleted)
-
includes/admin-pages/wcrl-settings.php (deleted)
-
includes/admin-pages/wcrl-shippings.php (deleted)
-
includes/admin-pages/wcrl-stock.php (deleted)
-
includes/admin-pages/wcrl-tax.php (deleted)
-
includes/admin-pages/wr-categories.php (added)
-
includes/admin-pages/wr-coupons.php (added)
-
includes/admin-pages/wr-locations.php (added)
-
includes/admin-pages/wr-orders-status.php (added)
-
includes/admin-pages/wr-orders.php (added)
-
includes/admin-pages/wr-overview.php (added)
-
includes/admin-pages/wr-payment-gateway.php (added)
-
includes/admin-pages/wr-products.php (added)
-
includes/admin-pages/wr-settings.php (added)
-
includes/admin-pages/wr-shippings.php (added)
-
includes/admin-pages/wr-stock.php (added)
-
includes/admin-pages/wr-tax.php (added)
-
includes/class-wcrl-admin-assets.php (deleted)
-
includes/class-wcrl-admin-menus.php (deleted)
-
includes/class-wcrl-filters.php (deleted)
-
includes/class-wcrl-search-date.php (deleted)
-
includes/class-wcrl.php (deleted)
-
includes/class-wooreports.php (added)
-
includes/class-wr-admin-assets.php (added)
-
includes/class-wr-admin-menus.php (added)
-
includes/class-wr-autoloader.php (moved) (moved from wc-reports-lite/trunk/includes/class-wcrl-autoloader.php) (5 diffs)
-
includes/class-wr-filters.php (added)
-
includes/class-wr-order-query.php (added)
-
includes/class-wr-search-date.php (added)
-
includes/functions-wr-public.php (added)
-
languages/wc-reports-lite-fa_IR.mo (deleted)
-
languages/wc-reports-lite-fa_IR.po (deleted)
-
languages/wc-reports-lite.pot (deleted)
-
languages/wooreports.pot (added)
-
readme.txt (modified) (1 diff)
-
wcrl.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
wc-reports-lite/trunk/assets/css/admin-style-rtl.css
r2413794 r3493462 1 .wcrl_filterBox .form-field{ 1 .WR_filterBox .form-field{ 2 float: right; 3 overflow: hidden; 4 } 5 div.dt-buttons{ 2 6 float: right; 3 7 } 4 .woo_pro_content,span.wooreports_logo{float: right;} 5 .woo_pro_content{width: 27%;margin-right: 30px;} 6 .woo_pro_features{margin-top: 30px;display: flex;flex-wrap: wrap;} 7 .woo_pro_features .wcrl_col {flex: 0 0 28.9%;margin: 2.2%;} 8 .woo_pro_features .wcrl_col img{border:1px solid #dee2e6!important;max-width: 100%;height: auto;} 8 9 .wr-report-filter-bar { 10 border-left: none; 11 border-right: 3px solid var(--wr-accent); 12 } 13 14 .wr-report-filter-bar__label { 15 margin-right: 0; 16 margin-left: 10px; 17 } 18 19 /* Insights panel: slide from left in RTL */ 20 .wr-insights-panel__drawer { 21 right: auto; 22 left: 0; 23 transform: translateX(-100%); 24 } 25 .wr-insights-panel--open .wr-insights-panel__drawer { 26 transform: translateX(0); 27 } 28 29 /* Footer link arrow points left in RTL */ 30 .wr-report-card__footer-link-icon { 31 transform: scaleX(-1); 32 } -
wc-reports-lite/trunk/assets/css/admin-style.css
r2413794 r3493462 1 .wcrl_w_10{width: 10% !important;} 2 .wcrl_w_25{width: 25% !important;} 1 .wr_w_25{width: 25% !important;} 3 2 .wooreport_hide{ 4 3 display: none; … … 76 75 77 76 /*Overview admin page style*/ 78 # wcrl_overviewOrders{77 #WR_overviewOrders{ 79 78 background: none repeat scroll 0 0 rgba(0, 0, 0, 0); 80 79 border: 1px none; 81 80 margin: 0 0 10px; 82 81 } 83 # wcrl_overviewOrders tbody tr th span {82 #WR_overviewOrders tbody tr th span { 84 83 color: #21759B !important; 85 84 font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; 86 85 font-size: 18px; 87 86 } 88 . wcrl_overviewTableStyle{87 .WR_overviewTableStyle{ 89 88 border: none !important; 90 89 } 91 . wcrl_overviewTableStyle thead tr th{90 .WR_overviewTableStyle thead tr th{ 92 91 font-weight: bold; 93 92 border-bottom: none !important; … … 95 94 font-size: 13px; 96 95 } 97 . wcrl_filterBox{96 .WR_filterBox{ 98 97 background: #fff; 99 98 padding: 15px; … … 101 100 border: 1px solid #e5e5e5; 102 101 } 103 . wcrl_filterBox .form-field{102 .WR_filterBox .form-field{ 104 103 width: 50%; 105 104 float: left; 106 105 margin-bottom: 16px; 107 } 108 .wcrl_filterBox .form-field label{ 106 overflow: hidden; 107 } 108 .WR_filterBox .form-field label{ 109 109 display: block; 110 110 padding-bottom: 4px; 111 111 } 112 . wcrl_filterBox .form-field input {112 .WR_filterBox .form-field input { 113 113 padding: 5px; 114 114 } 115 . wcrl_filterBox .form-field select {115 .WR_filterBox .form-field select { 116 116 width: 95%; 117 117 } 118 .wcrl-settings-container ul.tabs { 118 .dt-buttons{ 119 margin-bottom: 12px; 120 } 121 .dt-buttons .dt-button{ 122 text-decoration: none; 123 border-radius: 4px; 124 border-bottom: 1px solid rgba(0, 0, 0, .05); 125 padding: 7px; 126 margin: 2px; 127 } 128 .dt-buttons .dt-button:first-child,.dt-buttons .dt-button:last-child{ 129 margin: 0; 130 } 131 .dt-buttons .dt-button:hover,.dt-buttons .dt-button:active,.dt-buttons .dt-button:visited{ 132 border-bottom: 1px solid rgba(0, 0, 0, .05) !important; 133 border-top: none !important; 134 border-right: none !important; 135 border-left: none !important; 136 box-shadow: none !important; 137 } 138 .dt-buttons .buttons-copy,.dt-buttons .buttons-excel:hover{ 139 background: #e5e5e5 !important; 140 color: #777; 141 } 142 .dt-buttons .buttons-copy:before { 143 content: ""; 144 display: block; 145 background-image: url(../images/copy.svg); 146 background-size: 17px 17px; 147 height: 17px; 148 width: 17px; 149 float: left; 150 margin-right: 10px; 151 vertical-align: middle; 152 margin-top: 2px; 153 } 154 .dt-buttons .buttons-excel,.dt-buttons .buttons-excel:hover{ 155 background: #c6e1c6 !important; 156 color: #5b841b; 157 } 158 .dt-buttons .buttons-excel:before { 159 content: ""; 160 display: block; 161 background-image: url(../images/excel.svg); 162 background-size: 17px 17px; 163 height: 17px; 164 width: 17px; 165 float: left; 166 margin-right: 10px; 167 vertical-align: middle; 168 margin-top: 2px; 169 } 170 .dt-buttons .buttons-csv,.dt-buttons .buttons-csv:hover{ 171 background: #eba3a3 !important;; 172 color: #761919; 173 } 174 .dt-buttons .buttons-csv:before { 175 content: ""; 176 display: block; 177 background-image: url(../images/csv.svg); 178 background-size: 17px 17px; 179 height: 17px; 180 width: 17px; 181 float: left; 182 margin-right: 10px; 183 vertical-align: middle; 184 margin-top: 2px; 185 } 186 .dt-buttons .buttons-pdf,.dt-buttons .buttons-pdf:hover{ 187 background: #f8dda7 !important; 188 color: #94660c; 189 } 190 .dt-buttons .buttons-pdf:before { 191 content: ""; 192 display: block; 193 background-image: url(../images/pdf.svg); 194 background-size: 17px 17px; 195 height: 17px; 196 width: 17px; 197 float: left; 198 margin-right: 10px; 199 vertical-align: middle; 200 margin-top: 2px; 201 } 202 .dt-buttons .buttons-print,.dt-buttons .buttons-print:hover{ 203 background: #c8d7e1 !important; 204 color: #2e4453; 205 } 206 .dt-buttons .buttons-print:before { 207 content: ""; 208 display: block; 209 background-image: url(../images/printer.svg); 210 background-size: 17px 17px; 211 height: 17px; 212 width: 17px; 213 float: left; 214 margin-right: 10px; 215 vertical-align: middle; 216 margin-top: 2px; 217 } 218 .wr-settings-container ul.tabs { 119 219 margin: 0; 120 220 padding: 0; 121 221 list-style: none; 122 222 } 123 .wcrl-settings-container ul.tabs li { 223 224 .wr-settings-container ul.tabs li { 124 225 background: none; 125 226 color: #222; … … 131 232 } 132 233 133 .w crl-settings-container ul.tabs li.current {234 .wr-settings-container ul.tabs li.current { 134 235 background: #ffffff; 135 236 color: #222; … … 141 242 } 142 243 143 .w crl-settings-container .tab-content {244 .wr-settings-container .tab-content { 144 245 display: none; 145 246 background: #ffffff; … … 151 252 } 152 253 153 .w crl-settings-container .tab-content.current {254 .wr-settings-container .tab-content.current { 154 255 display: inherit; 155 256 } 156 .wcrl_customer_products_list{display: none} 157 .wcrl_customer_products_list { 257 .WR_email_form_settings{ 258 display: none; 259 } 260 .wr_customer_products_list{display: none} 261 .wr_customer_products_list { 158 262 background: #dfedf5; 159 263 padding: 7px; … … 162 266 margin-bottom: 8px; 163 267 } 164 .woo_pro_content,span.wooreports_logo{float: left;} 165 span.wooreports_logo{ 166 background: url(../images/wooreports.png); 167 background-position: center; 168 background-repeat: no-repeat; 169 width: 150px; 170 height: 150px; 171 margin: 0 auto; 172 } 173 .woo_pro_content{width: 27%;margin-left: 30px;} 174 .woo_pro_features{margin-top: 30px;display: flex;flex-wrap: wrap;} 175 .woo_pro_features .wcrl_col {flex: 0 0 28.9%;margin: 2.2%;} 176 .woo_pro_features .wcrl_col img{border:1px solid #dee2e6!important;max-width: 100%;height: auto;} 268 .w-70{width: 70%;} 269 .w-30{width: 30%;} 270 .d-flex{display: flex;} 271 .mr-3{margin-right: 1.5em;} 272 .ml-3{margin-left: 1.5em;} 273 .table-striped tbody tr:nth-of-type(odd) {background-color: rgba(0,0,0,.05);} 274 .table td, .table th {padding: .75rem;vertical-align: top;border-top: 1px solid #dee2e6;} 275 .table {width: 100%;max-width: 100%;margin-bottom: 1rem;background-color: transparent;} 276 .select2-container .select2-search--inline .select2-search__field {box-sizing: border-box;border: none;font-size: 100%;margin-top: 0;margin-left: 5px;padding: 0;max-width: 100%;resize: none;height: 18px;vertical-align: bottom;font-family: sans-serif;overflow: hidden;word-break: keep-all;} 277 .nw_export_button{ text-decoration: none; border-radius: 4px; border-bottom: 1px solid rgba(0, 0, 0, .05); padding: 7px; margin: 2px 2px 10px 2px; position: relative; display: inline-block; box-sizing: border-box; cursor: pointer; font-size: 13px; line-height: 1.6em; } 278 .nw_export_excel{ background: #c6e1c6 !important; color: #5b841b; } 279 .nw_export_pdf{ background: #f8dda7 !important; color: #94660c; } 280 .nw_export_excel:before { content: ""; display: block; background-image: url(../images/excel.svg); background-size: 17px 17px; height: 17px; width: 17px; float: left; margin-right: 10px; vertical-align: middle; margin-top: 2px; } 281 .nw_export_pdf:before { content: ""; display: block; background-image: url(../images/pdf.svg); background-size: 17px 17px; height: 17px; width: 17px; float: left; margin-right: 10px; vertical-align: middle; margin-top: 2px; } 282 283 /* Consistent hover for export buttons (all reports) */ 284 .nw_export_excel:hover { 285 background: #b7d8b7 !important; 286 color: #4c6f16; 287 } 288 .nw_export_pdf:hover { 289 background: #f0d08a !important; 290 color: #7a5208; 291 } 292 .tablenav{ height: 55px; } 293 @media (max-width: 768px) { 294 .wr-before-report-table{flex-direction: column;gap:10px;} 295 .wr-before-report-table > .w-70,.wr-before-report-table > .w-30,.wr-before-report-table .WR_filterBox .form-field{width: 100% !important;} 296 .wr-before-report-table > .w-30{padding: 0} 297 } 298 299 /* ========== WooReports: shared report pages (Overview and others) ========== */ 300 /* Dark topbar, light content area, white cards. Single CSS for all report menus. */ 301 302 body.wr-report-admin { 303 overflow-x: hidden; 304 } 305 306 .wr-report-page { 307 --wr-topbar-bg: #1e2a38; 308 --wr-topbar-text: #ffffff; 309 --wr-topbar-muted: rgba(255, 255, 255, 0.85); 310 --wr-content-bg: #f0f2f5; 311 --wr-card-bg: #ffffff; 312 --wr-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); 313 --wr-card-radius: 8px; 314 --wr-text: #202124; 315 --wr-text-secondary: #5f6368; 316 --wr-accent: #1a73e8; 317 --wr-border: #dadce0; 318 --wr-font: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, sans-serif; 319 padding: 0; 320 font-family: var(--wr-font); 321 box-sizing: border-box; 322 max-width: 100%; 323 overflow-x: hidden; 324 background: var(--wr-content-bg); 325 } 326 327 /* Constrain width and align with report cards */ 328 .wr-report-page__inner { 329 max-width: 1400px; 330 margin: 0 auto; 331 padding: 24px; 332 box-sizing: border-box; 333 } 334 335 /* Single card containing filter + KPIs + quick links */ 336 .wr-report-top-card { 337 background: var(--wr-card-bg); 338 border-radius: var(--wr-card-radius); 339 box-shadow: var(--wr-card-shadow); 340 overflow: hidden; 341 margin-bottom: 24px; 342 } 343 344 .wr-report-topbar { 345 display: flex; 346 align-items: center; 347 justify-content: space-between; 348 flex-wrap: wrap; 349 gap: 12px; 350 min-height: 56px; 351 padding: 0 24px; 352 background: var(--wr-topbar-bg); 353 color: var(--wr-topbar-text); 354 box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12); 355 } 356 357 .wr-report-topbar__left { 358 display: flex; 359 align-items: center; 360 gap: 12px; 361 } 362 363 .wr-report-topbar__logo { 364 width: 24px; 365 height: 24px; 366 background: var(--wr-accent); 367 border-radius: 6px; 368 flex-shrink: 0; 369 } 370 371 .wr-report-topbar__title { 372 font-size: 18px; 373 font-weight: 600; 374 color: var(--wr-topbar-text); 375 } 376 377 .wr-report-topbar__page { 378 font-size: 14px; 379 color: var(--wr-topbar-muted); 380 font-weight: 500; 381 } 382 383 .wr-report-topbar__center { 384 display: flex; 385 align-items: center; 386 } 387 388 .wr-report-topbar__center .daterangeactions { 389 margin: 0; 390 } 391 392 /* Filter bar — inside top card */ 393 .wr-report-filter-bar { 394 display: flex; 395 align-items: center; 396 justify-content: space-between; 397 gap: 16px; 398 padding: 16px 20px; 399 margin: 0; 400 background: #f8f9fa; 401 border-bottom: 1px solid var(--wr-border); 402 border-left: 3px solid var(--wr-accent); 403 font-family: var(--wr-font); 404 } 405 406 /* Insights trigger in filter bar (opens slide-out panel) */ 407 .wr-insights-trigger { 408 flex-shrink: 0; 409 display: inline-flex; 410 align-items: center; 411 justify-content: center; 412 gap: 7px; 413 height: 38px; 414 padding: 0 18px; 415 margin-right: 20px; 416 border: none; 417 border-radius: 10px; 418 background: linear-gradient(135deg, #fbbf24, #f59e0b); 419 color: #78350f; 420 font-size: 13px; 421 font-weight: 600; 422 cursor: pointer; 423 box-shadow: 0 2px 8px rgba(245, 158, 11, 0.25); 424 transition: transform 0.2s, box-shadow 0.2s, background 0.2s; 425 letter-spacing: 0.2px; 426 } 427 428 .wr-insights-trigger:hover { 429 color: #78350f; 430 background: linear-gradient(135deg, #f59e0b, #d97706); 431 box-shadow: 0 4px 14px rgba(245, 158, 11, 0.35); 432 transform: translateY(-1px); 433 } 434 435 .wr-insights-trigger:focus { 436 box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.4); 437 outline: none; 438 } 439 440 .wr-insights-trigger:active { 441 transform: translateY(0); 442 box-shadow: 0 1px 4px rgba(245, 158, 11, 0.2); 443 } 444 445 .wr-insights-trigger__icon { 446 display: block; 447 width: 18px; 448 height: 18px; 449 flex-shrink: 0; 450 } 451 452 .wr-report-filter-bar__label { 453 font-size: 13px; 454 font-weight: 500; 455 color: var(--wr-text-secondary); 456 margin-left: 0; 457 margin-right: 10px; 458 } 459 460 .wr-date-input { 461 font-size: 13px; 462 padding: 6px 8px; 463 border: 1px solid var(--wr-border); 464 border-radius: 4px; 465 background: var(--wr-card-bg); 466 } 467 468 .wr-report-filter-bar__sep { 469 color: var(--wr-text-secondary); 470 font-size: 13px; 471 } 472 473 .wr-compare-label { 474 display: inline-flex; 475 align-items: center; 476 gap: 6px; 477 font-size: 13px; 478 color: var(--wr-text-secondary); 479 cursor: pointer; 480 white-space: nowrap; 481 } 482 483 .wr-report-filter-form { 484 display: flex; 485 align-items: center; 486 gap: 12px; 487 flex-wrap: wrap; 488 padding: 0; 489 margin: 0; 490 background: transparent; 491 border: none; 492 border-radius: 0; 493 box-shadow: none; 494 font-family: var(--wr-font); 495 } 496 497 /* Report filter layout (all pages) */ 498 .wr-report-filter-form .WR_filterBox { 499 display: flex; 500 flex-wrap: nowrap; 501 align-items: flex-start; 502 gap: 12px 16px; 503 } 504 505 .wr-report-filter-form .form-field { 506 margin-bottom: 0; 507 display: flex; 508 flex-direction: column; 509 align-items: flex-start; 510 gap: 4px; 511 } 512 513 .wr-report-filter-form input[name="WR_fromDate"], 514 .wr-report-filter-form input[name="WR_toDate"] { 515 width: 170px; 516 } 517 518 .wr-report-filter-form select[name="WR_orderStatuses[]"] { 519 min-width: 280px; 520 max-width: 320px; 521 } 522 523 .wr-report-filter-form input[name="order_number"] { 524 width: 180px; 525 } 526 527 .wr-report-filter-form .wr-filter-actions { 528 display: flex; 529 align-items: center; 530 gap: 8px; 531 } 532 533 /* KPI row — Orders, Sales, AOV, Items sold (clickable, optional % change) */ 534 .wr-report-kpis { 535 display: grid; 536 grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); 537 gap: 16px; 538 padding: 20px; 539 margin: 0; 540 background: var(--wr-card-bg); 541 border-bottom: 1px solid var(--wr-border); 542 } 543 544 .wr-kpi-card { 545 position: relative; 546 padding: 20px 20px 16px; 547 background: var(--wr-content-bg); 548 border-radius: 12px; 549 border: 1px solid var(--wr-border); 550 text-align: left; 551 display: flex; 552 flex-direction: column; 553 gap: 6px; 554 overflow: hidden; 555 transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s; 556 } 557 558 .wr-kpi-card::before { 559 content: ''; 560 position: absolute; 561 top: 0; 562 left: 0; 563 right: 0; 564 height: 3px; 565 background: linear-gradient(90deg, var(--wr-accent), rgba(26,115,232,0.3)); 566 border-radius: 12px 12px 0 0; 567 opacity: 0; 568 transition: opacity 0.2s; 569 } 570 571 .wr-kpi-card:hover::before { 572 opacity: 1; 573 } 574 575 .wr-kpi-card--link { 576 text-decoration: none; 577 color: inherit; 578 cursor: pointer; 579 } 580 581 .wr-kpi-card--link:hover, 582 .wr-kpi-card--nolink:hover { 583 border-color: rgba(26,115,232,0.35); 584 box-shadow: 0 4px 16px rgba(26, 115, 232, 0.10), 0 1px 4px rgba(0,0,0,0.04); 585 transform: translateY(-2px); 586 } 587 588 .wr-kpi-card__label { 589 font-size: 12px; 590 color: var(--wr-text-secondary); 591 font-weight: 500; 592 text-transform: uppercase; 593 letter-spacing: 0.4px; 594 line-height: 1.3; 595 order: -1; 596 } 597 598 .wr-kpi-card__value { 599 display: block; 600 font-size: 26px; 601 font-weight: 700; 602 color: var(--wr-text); 603 line-height: 1.2; 604 letter-spacing: -0.5px; 605 } 606 607 .wr-kpi-card__value .woocommerce-Price-currencySymbol { 608 font-size: 0.7em; 609 font-weight: 600; 610 opacity: 0.6; 611 margin-inline-end: 1px; 612 } 613 614 .wr-kpi-card__change { 615 display: inline-flex; 616 align-items: center; 617 gap: 3px; 618 font-size: 12px; 619 font-weight: 600; 620 margin-top: 2px; 621 padding: 3px 8px; 622 border-radius: 20px; 623 width: fit-content; 624 } 625 626 .wr-kpi-card__change--up { 627 color: #0d7c43; 628 background: rgba(52, 168, 83, 0.12); 629 } 630 631 .wr-kpi-card__change--up::before { 632 content: '↑'; 633 font-size: 11px; 634 } 635 636 .wr-kpi-card__change--down { 637 color: #c5221f; 638 background: rgba(234, 67, 53, 0.10); 639 } 640 641 .wr-kpi-card__change--down::before { 642 content: '↓'; 643 font-size: 11px; 644 } 645 646 .wr-kpi-card__period { 647 font-weight: 400; 648 opacity: 0.7; 649 font-size: 11px; 650 text-transform: none; 651 letter-spacing: 0; 652 } 653 654 /* Styled tooltip for KPI period (replaces native title on hover) */ 655 .wr-kpi-card__tooltip { 656 position: absolute; 657 bottom: calc(100% + 4px); 658 left: 50%; 659 transform: translateX(-50%) translateY(4px); 660 padding: 8px 14px; 661 background: #1e293b; 662 color: #fff; 663 font-size: 12px; 664 font-weight: 500; 665 line-height: 1.4; 666 white-space: nowrap; 667 border-radius: 8px; 668 box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); 669 opacity: 0; 670 pointer-events: none; 671 transition: opacity 0.2s ease, transform 0.2s ease; 672 z-index: 10; 673 } 674 675 .wr-kpi-card__tooltip::after { 676 content: ''; 677 position: absolute; 678 top: 100%; 679 left: 50%; 680 margin-left: -6px; 681 border: 6px solid transparent; 682 border-top-color: #1e293b; 683 } 684 685 .wr-kpi-card--link:hover .wr-kpi-card__tooltip, 686 .wr-kpi-card--nolink:hover .wr-kpi-card__tooltip { 687 opacity: 1; 688 transform: translateX(-50%) translateY(0); 689 } 690 691 /* Report card footer: link to full report page */ 692 .wr-report-card__footer { 693 display: flex; 694 align-items: center; 695 gap: 10px; 696 padding: 14px 20px; 697 border-top: 1px solid var(--wr-border); 698 background: var(--wr-card-bg); 699 border-radius: 0 0 var(--wr-card-radius) var(--wr-card-radius); 700 } 701 702 .wr-report-card__footer-link { 703 display: inline-flex; 704 align-items: center; 705 gap: 6px; 706 font-size: 12px; 707 font-weight: 600; 708 color: var(--wr-accent); 709 text-decoration: none; 710 padding: 6px 14px; 711 border: 1px solid rgba(26, 115, 232, 0.25); 712 border-radius: 8px; 713 background: rgba(26, 115, 232, 0.06); 714 transition: background 0.2s, border-color 0.2s, box-shadow 0.2s, transform 0.15s; 715 white-space: nowrap; 716 letter-spacing: 0.15px; 717 } 718 719 .wr-report-card__footer-link:hover { 720 text-decoration: none; 721 background: rgba(26, 115, 232, 0.12); 722 border-color: rgba(26, 115, 232, 0.45); 723 box-shadow: 0 2px 8px rgba(26, 115, 232, 0.12); 724 transform: translateY(-1px); 725 color: var(--wr-accent); 726 } 727 728 .wr-report-card__footer-link:active { 729 transform: translateY(0); 730 box-shadow: none; 731 } 732 733 .wr-report-card__footer-link-icon { 734 flex-shrink: 0; 735 width: 14px; 736 height: 14px; 737 } 738 739 .wr-export-csv-link::before { 740 content: ''; 741 display: inline-block; 742 width: 14px; 743 height: 14px; 744 background: currentColor; 745 mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='7 10 12 15 17 10'/%3E%3Cline x1='12' y1='15' x2='12' y2='3'/%3E%3C/svg%3E"); 746 -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='7 10 12 15 17 10'/%3E%3Cline x1='12' y1='15' x2='12' y2='3'/%3E%3C/svg%3E"); 747 mask-size: contain; 748 -webkit-mask-size: contain; 749 mask-repeat: no-repeat; 750 -webkit-mask-repeat: no-repeat; 751 flex-shrink: 0; 752 } 753 754 /* Native select (fallback when Select2 not yet init) */ 755 .wr-report-filter-form select { 756 background: #fff; 757 border: 1px solid var(--wr-border); 758 color: var(--wr-text); 759 padding: 8px 12px; 760 border-radius: 6px; 761 font-size: 13px; 762 min-width: 200px; 763 height: 38px; 764 line-height: 1.4; 765 } 766 767 .wr-report-filter-form select:focus { 768 border-color: var(--wr-accent); 769 outline: none; 770 box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2); 771 } 772 773 .wr-report-filter-form option { 774 background: #fff; 775 color: var(--wr-text); 776 } 777 778 /* Select2 container — fixed height to match button (38px) */ 779 .wr-report-filter-form .select2-container { 780 min-width: 220px; 781 height: 38px !important; 782 } 783 784 .wr-report-filter-form .select2-container .select2-selection--multiple { 785 height: 38px !important; 786 min-height: 38px !important; 787 max-height: 38px !important; 788 padding: 0 8px; 789 border: 1px solid var(--wr-border); 790 border-radius: 6px; 791 background: #fff; 792 box-sizing: border-box; 793 display: flex !important; 794 align-items: center; 795 overflow: hidden; 796 } 797 798 .wr-report-filter-form .select2-container .select2-selection--single { 799 height: 38px !important; 800 min-height: 38px !important; 801 padding: 0 8px; 802 border: 1px solid var(--wr-border); 803 border-radius: 6px; 804 background: #fff; 805 box-sizing: border-box; 806 display: flex !important; 807 align-items: center; 808 } 809 810 .wr-report-filter-form .select2-container .select2-selection--single .select2-selection__rendered { 811 padding: 0; 812 line-height: 36px; 813 color: var(--wr-text); 814 font-size: 13px; 815 } 816 817 .wr-report-filter-form .select2-container .select2-selection--single .select2-selection__arrow { 818 height: 36px; 819 top: 0; 820 } 821 822 .wr-report-filter-form .select2-container.select2-container--focus .select2-selection--multiple, 823 .wr-report-filter-form .select2-container.select2-container--open .select2-selection--multiple, 824 .wr-report-filter-form .select2-container.select2-container--focus .select2-selection--single, 825 .wr-report-filter-form .select2-container.select2-container--open .select2-selection--single { 826 border-color: var(--wr-accent); 827 outline: none; 828 box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2); 829 } 830 831 .wr-report-filter-form .select2-container .select2-selection__rendered { 832 padding: 0; 833 display: flex; 834 align-items: center; 835 flex-wrap: wrap; 836 gap: 4px; 837 min-height: 36px; 838 } 839 840 .wr-report-filter-form .select2-container .select2-search__field { 841 margin: 0; 842 padding: 4px 4px; 843 font-size: 13px; 844 color: var(--wr-text); 845 height: 28px; 846 line-height: 28px; 847 min-height: 0; 848 } 849 850 .wr-report-filter-form .select2-container .select2-selection__choice { 851 background: var(--wr-content-bg); 852 border: 1px solid var(--wr-border); 853 border-radius: 4px; 854 padding: 2px 8px; 855 font-size: 12px; 856 color: var(--wr-text); 857 } 858 859 /* Filter button — same height as Select2 (38px) */ 860 .wr-report-filter-form .button { 861 height: 38px !important; 862 min-height: 38px !important; 863 padding: 0 18px !important; 864 line-height: 36px !important; 865 font-size: 13px !important; 866 font-weight: 500; 867 border-radius: 6px; 868 cursor: pointer; 869 box-sizing: border-box; 870 transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; 871 display: inline-flex; 872 align-items: center; 873 justify-content: center; 874 } 875 876 .wr-report-filter-form .button-primary { 877 border-color: var(--wr-accent); 878 background: var(--wr-accent); 879 } 880 881 .wr-report-filter-form .button-primary:hover { 882 background: #1557b0; 883 border-color: #1557b0; 884 box-shadow: 0 1px 3px rgba(26, 115, 232, 0.35); 885 } 886 887 .wr-report-filter-form .button-primary:focus { 888 border-color: var(--wr-accent); 889 box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.35); 890 } 891 892 .wr-report-topbar__btn { 893 background: rgba(255, 255, 255, 0.2) !important; 894 border: 1px solid rgba(255, 255, 255, 0.4) !important; 895 color: var(--wr-topbar-text) !important; 896 padding: 8px 18px !important; 897 border-radius: 6px !important; 898 font-size: 13px !important; 899 font-weight: 500 !important; 900 cursor: pointer; 901 } 902 903 .wr-report-topbar__btn:hover { 904 background: rgba(255, 255, 255, 0.3) !important; 905 border-color: rgba(255, 255, 255, 0.5) !important; 906 color: #fff !important; 907 } 908 909 .wr-report-topbar__right { 910 display: flex; 911 align-items: center; 912 gap: 8px; 913 } 914 915 .wr-report-topbar__icon { 916 width: 36px; 917 height: 36px; 918 border-radius: 50%; 919 background: rgba(255, 255, 255, 0.1); 920 display: inline-flex; 921 align-items: center; 922 justify-content: center; 923 color: var(--wr-topbar-text); 924 cursor: pointer; 925 } 926 927 .wr-report-topbar__icon:hover { 928 background: rgba(255, 255, 255, 0.2); 929 } 930 931 .wr-report-topbar__icon--help:before { 932 content: "?"; 933 font-size: 16px; 934 font-weight: 600; 935 } 936 937 /* Trend chart block */ 938 #wr-card-trend .wr-report-card__body { 939 min-height: 200px; 940 } 941 942 .wr-sales-by-source-chart-wrap { 943 max-width: 320px; 944 margin: 0 auto; 945 padding: 8px 0 0; 946 position: relative; 947 } 948 949 #wr-card-trend #WR_ChartTrend { 950 max-width: 100%; 951 } 952 953 /* Insights slide-out panel (right side, like Google Analytics) */ 954 .wr-insights-panel { 955 position: fixed; 956 top: 0; 957 left: 0; 958 right: 0; 959 bottom: 0; 960 z-index: 99999; 961 pointer-events: none; 962 visibility: hidden; 963 transition: visibility 0.25s ease; 964 } 965 966 .wr-insights-panel--open { 967 pointer-events: auto; 968 visibility: visible; 969 } 970 971 .wr-insights-panel__backdrop { 972 position: absolute; 973 top: 0; 974 left: 0; 975 right: 0; 976 bottom: 0; 977 background: rgba(0, 0, 0, 0.35); 978 opacity: 0; 979 transition: opacity 0.25s ease; 980 z-index: 0; 981 } 982 983 .wr-insights-panel--open .wr-insights-panel__backdrop { 984 opacity: 1; 985 } 986 987 .wr-insights-panel__drawer { 988 position: absolute; 989 top: 0; 990 right: 0; 991 width: 100%; 992 max-width: 380px; 993 height: 100%; 994 background: #ffffff; 995 box-shadow: -4px 0 24px rgba(0, 0, 0, 0.12); 996 transform: translateX(100%); 997 transition: transform 0.25s ease; 998 display: flex; 999 flex-direction: column; 1000 overflow: hidden; 1001 z-index: 1; 1002 } 1003 1004 .wr-insights-panel--open .wr-insights-panel__drawer { 1005 transform: translateX(0); 1006 } 1007 1008 .wr-insights-panel__header { 1009 flex-shrink: 0; 1010 display: flex; 1011 align-items: center; 1012 gap: 12px; 1013 padding: 20px; 1014 border-bottom: 1px solid var(--wr-border); 1015 background: var(--wr-card-bg); 1016 } 1017 1018 .wr-insights-panel__header-icon { 1019 flex-shrink: 0; 1020 color: var(--wr-accent); 1021 } 1022 1023 .wr-insights-panel__header-text { 1024 flex: 1; 1025 min-width: 0; 1026 } 1027 1028 .wr-insights-panel__title { 1029 margin: 0; 1030 font-size: 18px; 1031 font-weight: 600; 1032 color: var(--wr-text); 1033 font-family: var(--wr-font); 1034 } 1035 1036 .wr-insights-panel__context { 1037 margin: 4px 0 0; 1038 font-size: 12px; 1039 font-weight: 400; 1040 color: var(--wr-text-secondary); 1041 line-height: 1.3; 1042 } 1043 1044 .wr-insights-panel__close { 1045 flex-shrink: 0; 1046 width: 36px; 1047 height: 36px; 1048 padding: 0; 1049 border: none; 1050 border-radius: 50%; 1051 background: transparent; 1052 color: var(--wr-text-secondary); 1053 cursor: pointer; 1054 font-size: 24px; 1055 line-height: 1; 1056 display: inline-flex; 1057 align-items: center; 1058 justify-content: center; 1059 transition: background 0.15s ease, color 0.15s ease; 1060 } 1061 1062 .wr-insights-panel__close:hover { 1063 background: var(--wr-content-bg); 1064 color: var(--wr-text); 1065 } 1066 1067 .wr-insights-panel__body { 1068 flex: 1; 1069 overflow-y: auto; 1070 padding: 20px; 1071 background: #ffffff; 1072 } 1073 1074 .wr-insights-panel__loading { 1075 display: flex; 1076 align-items: center; 1077 gap: 8px; 1078 font-size: 14px; 1079 color: var(--wr-text-secondary); 1080 } 1081 1082 .wr-insights-panel__loading .spinner { 1083 float: none; 1084 margin: 0; 1085 } 1086 1087 .wr-insights-list { 1088 margin: 0; 1089 padding: 0; 1090 list-style: none; 1091 font-size: 14px; 1092 } 1093 1094 .wr-insight-item { 1095 padding: 8px 0; 1096 border-bottom: 1px solid var(--wr-border); 1097 display: flex; 1098 flex-wrap: wrap; 1099 gap: 6px 8px; 1100 align-items: baseline; 1101 } 1102 1103 .wr-insight-item:last-child { 1104 border-bottom: none; 1105 } 1106 1107 .wr-insight-item__label { 1108 font-weight: 500; 1109 color: var(--wr-text-secondary); 1110 } 1111 1112 .wr-insight-item__value { 1113 color: var(--wr-text); 1114 } 1115 1116 .wr-report-content { 1117 background: transparent; 1118 min-height: 0; 1119 padding: 0; 1120 box-sizing: border-box; 1121 overflow-x: hidden; 1122 width: 100%; 1123 } 1124 1125 /* 2 columns max so cards are wide; prevents horizontal scroll from grid */ 1126 .wr-report-cards { 1127 display: grid; 1128 grid-template-columns: repeat(2, 1fr); 1129 gap: 24px; 1130 width: 100%; 1131 min-width: 0; 1132 } 1133 1134 /* Top row: Sales trend then Overview Orders, both full width stacked */ 1135 .wr-report-cards__top-row { 1136 grid-column: 1 / -1; 1137 display: grid; 1138 grid-template-columns: 1fr 1.25fr; 1139 gap: 24px; 1140 min-width: 0; 1141 } 1142 .wr-report-cards__top-row--stack { 1143 grid-template-columns: 1fr; 1144 } 1145 1146 /* Two-column row: Overview Orders + Sales by source side by side */ 1147 .wr-report-cards__two-col { 1148 grid-column: 1 / -1; 1149 display: grid; 1150 grid-template-columns: 1fr 1fr; 1151 gap: 24px; 1152 min-width: 0; 1153 } 1154 1155 /* Section heading above "Top" report cards */ 1156 .wr-report-cards__heading { 1157 grid-column: 1 / -1; 1158 margin: 32px 0 8px; 1159 padding: 0; 1160 font-size: 18px; 1161 font-weight: 600; 1162 color: var(--wr-text); 1163 font-family: var(--wr-font); 1164 } 1165 .wr-report-cards__heading:first-child { 1166 margin-top: 0; 1167 } 1168 1169 .wr-report-card { 1170 background: var(--wr-card-bg); 1171 border-radius: var(--wr-card-radius); 1172 box-shadow: var(--wr-card-shadow); 1173 overflow: hidden; 1174 min-width: 0; 1175 } 1176 1177 .wr-report-card__header { 1178 display: flex; 1179 align-items: center; 1180 justify-content: space-between; 1181 flex-wrap: wrap; 1182 gap: 8px; 1183 margin: 0; 1184 padding: 16px 20px; 1185 background: var(--wr-card-bg); 1186 border-bottom: 1px solid var(--wr-border); 1187 font-size: 15px; 1188 font-weight: 600; 1189 color: var(--wr-text); 1190 font-family: var(--wr-font); 1191 } 1192 1193 .wr-report-card__title { 1194 margin: 0; 1195 } 1196 1197 .wr-report-card__description { 1198 width: 100%; 1199 margin: 6px 0 0; 1200 font-size: 13px; 1201 font-weight: 400; 1202 color: var(--wr-text-secondary); 1203 line-height: 1.4; 1204 } 1205 1206 .wr-report-card__header:has(.wr-report-card__description) { 1207 flex-direction: column; 1208 align-items: flex-start; 1209 } 1210 1211 .wr-report-card__header:has(.wr-report-card__description) .wr-report-card__actions { 1212 margin-top: 4px; 1213 } 1214 1215 .wr-report-card__actions { 1216 display: flex; 1217 align-items: center; 1218 gap: 4px; 1219 } 1220 1221 /* Card actions: make Export + Summary buttons same size in one row */ 1222 .wr-report-card__actions .nw_export_button, 1223 .wr-report-card__actions .wr-summary-trigger { 1224 height: 36px; 1225 min-height: 36px; 1226 padding: 0 14px; 1227 font-size: 13px; 1228 font-weight: 500; 1229 border-radius: 6px; 1230 display: inline-flex; 1231 align-items: center; 1232 justify-content: center; 1233 box-sizing: border-box; 1234 line-height: 1; 1235 } 1236 1237 /* Remove old margins/line-height from generic export style inside card header */ 1238 .wr-report-card__actions .nw_export_button { 1239 margin: 0; 1240 border-bottom: none; 1241 } 1242 1243 .wr-report-card__actions .wr-chart-btn, 1244 .wr-report-card__actions .wr-table-btn { 1245 padding: 6px 10px; 1246 border: 1px solid transparent; 1247 border-radius: 6px; 1248 background: transparent; 1249 color: var(--wr-text-secondary); 1250 cursor: pointer; 1251 font-size: 13px; 1252 transition: color 0.15s, background 0.15s, border-color 0.15s, box-shadow 0.15s; 1253 } 1254 1255 .wr-report-card__actions .wr-chart-btn:hover, 1256 .wr-report-card__actions .wr-table-btn:hover { 1257 color: var(--wr-accent); 1258 background: rgba(26, 115, 232, 0.08); 1259 } 1260 1261 .wr-report-card__actions .wr-chart-btn.is-active, 1262 .wr-report-card__actions .wr-table-btn.is-active { 1263 color: var(--wr-accent); 1264 background: rgba(26, 115, 232, 0.10); 1265 border-color: var(--wr-accent); 1266 box-shadow: 0 1px 3px rgba(26, 115, 232, 0.15); 1267 } 1268 1269 /* Segment card chart wrapper */ 1270 .wr-report-card__body .wr-segment-chart-wrap { 1271 position: relative; 1272 padding: 16px 20px 12px; 1273 min-height: 260px; 1274 } 1275 .wr-report-card__body .wr-segment-chart-wrap canvas { 1276 max-width: 100%; 1277 } 1278 1279 .wr-report-card__body { 1280 padding: 20px; 1281 font-size: 14px; 1282 color: var(--wr-text); 1283 } 1284 1285 .wr-report-card--full { 1286 grid-column: 1 / -1; 1287 } 1288 1289 /* Empty state for report tables with no data */ 1290 .wr-report-page .wr-report-table-empty { 1291 text-align: center; 1292 padding: 24px 16px; 1293 color: var(--wr-text-secondary); 1294 font-size: 14px; 1295 } 1296 1297 .wr-report-page .wr-report-error { 1298 padding: 16px; 1299 color: var(--wr-text-secondary); 1300 background: rgba(0, 0, 0, 0.04); 1301 border-left: 4px solid var(--wr-accent); 1302 border-radius: 0 4px 4px 0; 1303 margin: 8px 0; 1304 } 1305 1306 /* Tables inside report cards; contain overflow to prevent horizontal scroll */ 1307 .wr-report-page .wr-report-card__body { 1308 overflow-x: auto; 1309 } 1310 .wr-report-page .WR_overviewTableStyle, 1311 .wr-report-page .widefat.table-stats, 1312 .wr-report-page #WR_overviewOrders { 1313 border: none; 1314 border-bottom: none; 1315 margin: 0; 1316 width: 100%; 1317 max-width: 100%; 1318 background: transparent; 1319 } 1320 1321 /* Remove any gray border at bottom of Overview Orders table (override WP .widefat) */ 1322 #wr-card-overview-orders #WR_overviewOrders, 1323 #wr-card-overview-orders #WR_overviewOrders thead, 1324 #wr-card-overview-orders #WR_overviewOrders tbody, 1325 #wr-card-overview-orders #WR_overviewOrders th, 1326 #wr-card-overview-orders #WR_overviewOrders td, 1327 #wr-card-overview-orders #WR_overviewOrders thead th, 1328 #wr-card-overview-orders #WR_overviewOrders tbody th, 1329 #wr-card-overview-orders #WR_overviewOrders tbody td, 1330 #wr-card-overview-orders #WR_overviewOrders tbody tr:last-child th, 1331 #wr-card-overview-orders #WR_overviewOrders tbody tr:last-child td { 1332 border-bottom: none !important; 1333 border-top: none !important; 1334 } 1335 1336 #wr-card-overview-orders #WR_overviewOrders { 1337 border: none !important; 1338 box-shadow: none !important; 1339 outline: none !important; 1340 } 1341 1342 /* Remove bottom border from Overview Orders card body (in case line is from container) */ 1343 #wr-card-overview-orders .wr-report-card__body { 1344 border-bottom: none !important; 1345 } 1346 .wr-report-page .wr-report-card__body canvas { 1347 max-width: 100%; 1348 } 1349 1350 .wr-report-page .WR_overviewTableStyle thead th, 1351 .wr-report-page #WR_overviewOrders thead th { 1352 font-size: 11px; 1353 font-weight: 600; 1354 text-transform: uppercase; 1355 letter-spacing: 0.04em; 1356 color: var(--wr-text-secondary); 1357 padding: 10px 14px; 1358 border: none; 1359 background: transparent; 1360 } 1361 1362 .wr-report-page .WR_overviewTableStyle thead th { 1363 border-bottom: none; 1364 } 1365 1366 .wr-report-page .WR_overviewTableStyle tbody td, 1367 .wr-report-page #WR_overviewOrders tbody th, 1368 .wr-report-page #WR_overviewOrders tbody td { 1369 padding: 12px 14px; 1370 border: none; 1371 border-bottom: none; 1372 font-size: 14px; 1373 color: var(--wr-text); 1374 background: transparent; 1375 } 1376 1377 /* Simple tables in cards: no row background, no border-bottom */ 1378 .wr-report-page .wr-report-card .WR_overviewTableStyle tbody tr, 1379 .wr-report-page .wr-report-card .widefat tbody tr { 1380 background: transparent; 1381 } 1382 1383 /* No gray border at end of table or on last row */ 1384 .wr-report-page .wr-report-card .wr-report-card__body .widefat, 1385 .wr-report-page .wr-report-card .wr-report-card__body .WR_overviewTableStyle, 1386 .wr-report-page .wr-report-card .wr-report-card__body .widefat tbody tr:last-child td, 1387 .wr-report-page .wr-report-card .wr-report-card__body .WR_overviewTableStyle tbody tr:last-child td { 1388 border-bottom: none !important; 1389 } 1390 1391 /* Odd rows (1st, 3rd, 5th…): very light gray for clearer tables */ 1392 .wr-report-page .wr-report-card .WR_overviewTableStyle tbody tr:nth-of-type(odd), 1393 .wr-report-page .wr-report-card .widefat.striped tbody tr:nth-of-type(odd), 1394 .wr-report-page .wr-report-card .widefat tbody tr:nth-of-type(odd), 1395 .wr-report-page #WR_overviewOrders tbody tr:nth-of-type(odd) { 1396 background: rgba(0, 0, 0, 0.02); 1397 } 1398 1399 .wr-report-page .WR_overviewTableStyle tbody tr:hover, 1400 .wr-report-page .wr-report-card .WR_overviewTableStyle tbody tr:hover, 1401 .wr-report-page .wr-report-card .widefat tbody tr:hover, 1402 .wr-report-page #WR_overviewOrders tbody tr:hover { 1403 background: transparent; 1404 } 1405 1406 .wr-report-page #WR_overviewOrders tbody th span { 1407 color: var(--wr-accent) !important; 1408 font-size: 16px !important; 1409 font-weight: 600; 1410 } 1411 1412 .wr-report-page .wr-report-filter-bar__label--small { 1413 font-size: 12px; 1414 margin-left: 12px; 1415 } 1416 1417 .wr-report-page .wr-select--small { 1418 min-width: 100px; 1419 max-width: 140px; 1420 padding: 2px 6px; 1421 font-size: 13px; 1422 } 1423 1424 .wr-report-page .wr-export-csv-link { 1425 margin-left: 8px; 1426 } 1427 1428 .wr-report-page .wr-report-card__footer .wr-export-csv-link { 1429 margin-right: 0; 1430 } 1431 1432 .wr-report-page .wr-kpi-card--nolink { 1433 cursor: default; 1434 text-decoration: none; 1435 } 1436 1437 .wr-report-page .wr-kpi-card--nolink:hover { 1438 text-decoration: none; 1439 transform: none; 1440 box-shadow: 0 1px 4px rgba(0,0,0,0.04); 1441 } 1442 1443 .wr-report-page .wr-report-card__loading { 1444 padding: 24px; 1445 text-align: center; 1446 color: var(--wr-text-secondary); 1447 font-size: 14px; 1448 } 1449 1450 .wr-report-page .wr-report-card .widefat a { 1451 color: var(--wr-accent); 1452 text-decoration: none; 1453 } 1454 1455 .wr-report-page .wr-report-card .widefat a:hover { 1456 text-decoration: underline; 1457 } 1458 1459 /* ----- Report filter bar: modern style for all pages ----- */ 1460 .wr-report-page .wr-report-filter-bar { 1461 padding: 0; 1462 margin: 0; 1463 display: flex; 1464 align-items: center; 1465 justify-content: space-between; 1466 gap: 16px; 1467 } 1468 1469 .wr-report-page .wr-report-filter-bar form { 1470 display: flex; 1471 flex-wrap: wrap; 1472 align-items: center; 1473 gap: 12px 16px; 1474 padding: 16px 20px; 1475 margin: 0; 1476 background: #f8f9fa; 1477 border: none; 1478 border-left: 3px solid var(--wr-accent); 1479 box-shadow: none; 1480 width: 100%; 1481 max-width: 100%; 1482 box-sizing: border-box; 1483 flex: 1; 1484 } 1485 1486 .wr-report-page .wr-report-filter-bar .WR_filterBox { 1487 padding: 0; 1488 margin: 0; 1489 width: 100%; 1490 background: transparent; 1491 border: none; 1492 box-shadow: none; 1493 } 1494 1495 .wr-report-page .wr-report-filter-bar .form-field { 1496 width: auto; 1497 float: none; 1498 margin: 0; 1499 display: flex; 1500 align-items: center; 1501 gap: 6px; 1502 } 1503 1504 .wr-report-page .wr-report-filter-bar .form-field label { 1505 margin: 0; 1506 padding: 0; 1507 font-size: 13px; 1508 font-weight: 500; 1509 color: var(--wr-text); 1510 white-space: nowrap; 1511 } 1512 1513 /* Filter labels above inputs */ 1514 .wr-report-page .wr-report-filter-bar form.wr-report-filter-form .form-field { 1515 flex-direction: column; 1516 align-items: flex-start; 1517 gap: 4px; 1518 } 1519 1520 /* Search + Reset actions on one horizontal row */ 1521 .wr-report-page .wr-report-filter-bar form.wr-report-filter-form .wr-filter-actions { 1522 flex-direction: row; 1523 align-items: center; 1524 margin-top: 22px; /* پایینتر تا همتراز با inputها شود */ 1525 } 1526 1527 /* Orders filter: same input/select/button style as Overview (.wr-report-filter-form) */ 1528 .wr-report-page .wr-report-filter-bar form input[type="text"], 1529 .wr-report-page .wr-report-filter-bar form input[type="number"] { 1530 background: #fff; 1531 border: 1px solid var(--wr-border); 1532 color: var(--wr-text); 1533 padding: 8px 12px; 1534 border-radius: 6px; 1535 font-size: 13px; 1536 min-width: 120px; 1537 height: 38px; 1538 line-height: 1.4; 1539 box-sizing: border-box; 1540 } 1541 1542 .wr-report-page .wr-report-filter-bar form input:focus { 1543 border-color: var(--wr-accent); 1544 outline: none; 1545 box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2); 1546 } 1547 1548 .wr-report-page .wr-report-filter-bar form select { 1549 background: #fff; 1550 border: 1px solid var(--wr-border); 1551 color: var(--wr-text); 1552 padding: 8px 12px; 1553 border-radius: 6px; 1554 font-size: 13px; 1555 min-width: 200px; 1556 height: 38px; 1557 line-height: 1.4; 1558 } 1559 1560 .wr-report-page .wr-report-filter-bar form select:focus { 1561 border-color: var(--wr-accent); 1562 outline: none; 1563 box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2); 1564 } 1565 1566 .wr-report-page .wr-report-filter-bar form .select2-container { 1567 min-width: 220px; 1568 height: 38px !important; 1569 } 1570 1571 .wr-report-page .wr-report-filter-bar form .select2-container .select2-selection--multiple { 1572 height: 38px !important; 1573 min-height: 38px !important; 1574 max-height: 38px !important; 1575 padding: 0 8px; 1576 border: 1px solid var(--wr-border); 1577 border-radius: 6px; 1578 background: #fff; 1579 } 1580 1581 .wr-report-page .wr-report-filter-bar form .select2-container .select2-selection--single { 1582 height: 38px !important; 1583 min-height: 38px !important; 1584 padding: 0 8px; 1585 border: 1px solid var(--wr-border); 1586 border-radius: 6px; 1587 background: #fff; 1588 display: flex !important; 1589 align-items: center; 1590 } 1591 1592 .wr-report-page .wr-report-filter-bar form .select2-container .select2-selection--single .select2-selection__rendered { 1593 padding: 0; 1594 line-height: 36px; 1595 color: var(--wr-text, #1e1e1e); 1596 font-size: 13px; 1597 } 1598 1599 .wr-report-page .wr-report-filter-bar form .select2-container .select2-selection--single .select2-selection__arrow { 1600 height: 36px; 1601 top: 0; 1602 } 1603 1604 .wr-report-page .wr-report-filter-bar form .select2-container.select2-container--focus .select2-selection--single, 1605 .wr-report-page .wr-report-filter-bar form .select2-container.select2-container--open .select2-selection--single { 1606 border-color: var(--wr-accent, #1a73e8); 1607 outline: none; 1608 box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2); 1609 } 1610 1611 .wr-report-page .wr-report-filter-bar form .button { 1612 height: 38px !important; 1613 min-height: 38px !important; 1614 padding: 0 18px !important; 1615 line-height: 36px !important; 1616 font-size: 13px !important; 1617 font-weight: 500; 1618 border-radius: 6px; 1619 cursor: pointer; 1620 box-sizing: border-box; 1621 } 1622 1623 .wr-report-page .wr-report-filter-bar form .button-primary { 1624 border-color: var(--wr-accent); 1625 background: var(--wr-accent); 1626 margin-left: 0; 1627 } 1628 1629 .wr-report-page .wr-report-filter-bar form .button-primary:hover { 1630 background: #1557b0; 1631 border-color: #1557b0; 1632 box-shadow: 0 1px 3px rgba(26, 115, 232, 0.35); 1633 } 1634 1635 .wr-report-page .wr-report-filter-bar form .button-primary:focus { 1636 border-color: var(--wr-accent); 1637 box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.35); 1638 } 1639 1640 /* Modern filter form layout for all report pages */ 1641 .wr-report-filter-form--modern .WR_filterBox { 1642 display: flex; 1643 flex-wrap: wrap; 1644 align-items: flex-end; 1645 gap: 12px; 1646 } 1647 1648 .wr-report-filter-form--modern .form-field { 1649 display: flex; 1650 flex-direction: column; 1651 align-items: flex-start; 1652 gap: 4px; 1653 } 1654 1655 .wr-report-filter-form--modern .form-field label { 1656 font-size: 11px; 1657 font-weight: 600; 1658 text-transform: uppercase; 1659 letter-spacing: 0.04em; 1660 color: var(--wr-text-secondary); 1661 white-space: nowrap; 1662 } 1663 1664 .wr-report-filter-form--modern .wr-filter-actions { 1665 flex-direction: row !important; 1666 align-items: flex-end !important; 1667 gap: 8px !important; 1668 margin-top: 0; 1669 } 1670 1671 .wr-report-filter-form--modern .clear { 1672 display: none; 1673 } 1674 1675 /* Keep Summary trigger aligned on the right side of Orders filter bar */ 1676 .wr-report-page .wr-report-filter-bar--orders .wr-orders-summary-trigger { 1677 flex-shrink: 0; 1678 } 1679 1680 /* Chart card (all reports) */ 1681 .wr-report-page .wr-report-card .wr-report-card__body--chart { 1682 position: relative; 1683 padding: 16px 20px 12px; 1684 height: 320px; 1685 } 1686 .wr-report-page .wr-report-card .wr-report-card__body--chart canvas { 1687 max-width: 100%; 1688 } 1689 1690 /* ── Generic report table card ── */ 1691 .wr-report-page .wr-report-card .wr-report-card__body--table { 1692 padding: 0; 1693 overflow-x: auto; 1694 border-radius: 0 0 var(--wr-card-radius) var(--wr-card-radius); 1695 } 1696 1697 .wr-report-page .wr-report-card .wp-list-table.widefat { 1698 border: none; 1699 box-shadow: none; 1700 border-collapse: separate; 1701 border-spacing: 0; 1702 width: max-content; 1703 min-width: 100%; 1704 table-layout: auto; 1705 font-size: 13px; 1706 } 1707 1708 .wr-report-page .wr-report-card .wp-list-table.fixed { 1709 table-layout: auto; 1710 } 1711 1712 .wr-report-page .wr-report-card .wp-list-table.widefat thead th { 1713 font-size: 11px; 1714 font-weight: 600; 1715 text-transform: uppercase; 1716 letter-spacing: 0.06em; 1717 color: var(--wr-text-secondary); 1718 padding: 14px 16px; 1719 border: none; 1720 border-bottom: 2px solid var(--wr-border); 1721 background: #f8f9fa; 1722 white-space: nowrap; 1723 } 1724 1725 .wr-report-page .wr-report-card .wp-list-table.widefat thead th a { 1726 color: var(--wr-accent); 1727 text-decoration: none; 1728 font-weight: 600; 1729 } 1730 1731 .wr-report-page .wr-report-card .wp-list-table.widefat thead th a:hover { 1732 text-decoration: underline; 1733 } 1734 1735 .wr-report-page .wr-report-card .wp-list-table.widefat tfoot { 1736 display: none; 1737 } 1738 1739 .wr-report-page .wr-report-card .wp-list-table.widefat tbody td { 1740 padding: 14px 16px; 1741 border: none; 1742 border-bottom: 1px solid rgba(0, 0, 0, 0.06); 1743 color: var(--wr-text); 1744 vertical-align: middle; 1745 white-space: nowrap; 1746 } 1747 1748 .wr-report-page .wr-report-card .wp-list-table.widefat tbody tr { 1749 transition: background 0.15s ease; 1750 } 1751 1752 .wr-report-page .wr-report-card .wp-list-table.widefat tbody tr:nth-of-type(odd) { 1753 background: rgba(0, 0, 0, 0.02); 1754 } 1755 1756 .wr-report-page .wr-report-card .wp-list-table.widefat tbody tr:hover { 1757 background: rgba(26, 115, 232, 0.04); 1758 } 1759 1760 .wr-report-page .wr-report-card .wp-list-table.widefat tbody tr:last-child td { 1761 border-bottom: none; 1762 } 1763 1764 .wr-report-page .wr-report-card .wp-list-table.widefat tbody td a { 1765 color: var(--wr-accent); 1766 text-decoration: none; 1767 font-weight: 500; 1768 } 1769 1770 .wr-report-page .wr-report-card .wp-list-table.widefat tbody td a:hover { 1771 text-decoration: underline; 1772 } 1773 1774 .wr-report-page .wr-report-card .wp-list-table.widefat .order-status { 1775 display: inline-block; 1776 padding: 4px 10px; 1777 font-size: 12px; 1778 font-weight: 600; 1779 border-radius: 20px; 1780 border: none; 1781 line-height: 1.3; 1782 } 1783 1784 .wr-report-page .wr-report-card .wp-list-table.widefat .order-status span { 1785 border: none; 1786 padding: 0; 1787 background: none; 1788 } 1789 1790 /* Modern buttons inside report tables */ 1791 .wr-report-page .wr-report-card .wp-list-table.widefat td .button, 1792 .wr-report-page .wr-report-card .wp-list-table.widefat td .button.button-primary { 1793 display: inline-flex; 1794 align-items: center; 1795 gap: 4px; 1796 padding: 5px 12px; 1797 font-size: 12px; 1798 font-weight: 500; 1799 line-height: 1.4; 1800 border: 1px solid var(--wr-accent); 1801 border-radius: 6px; 1802 background: rgba(26, 115, 232, 0.06); 1803 color: var(--wr-accent); 1804 text-decoration: none; 1805 cursor: pointer; 1806 box-shadow: none; 1807 transition: background 0.15s, color 0.15s, box-shadow 0.15s; 1808 white-space: nowrap; 1809 } 1810 .wr-report-page .wr-report-card .wp-list-table.widefat td .button:hover, 1811 .wr-report-page .wr-report-card .wp-list-table.widefat td .button.button-primary:hover { 1812 background: var(--wr-accent); 1813 color: #fff; 1814 box-shadow: 0 2px 6px rgba(26, 115, 232, 0.25); 1815 text-decoration: none; 1816 } 1817 .wr-report-page .wr-report-card .wp-list-table.widefat td .button:focus, 1818 .wr-report-page .wr-report-card .wp-list-table.widefat td .button.button-primary:focus { 1819 outline: none; 1820 box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.3); 1821 } 1822 1823 /* Stock action buttons (Edit/View) */ 1824 .wr-report-page .wr-report-card .wp-list-table.widefat td .button.tips { 1825 padding: 4px 10px; 1826 font-size: 12px; 1827 margin-right: 4px; 1828 } 1829 1830 /* ── Products Popover ── */ 1831 .wr-products-popover-wrap { 1832 display: inline-block; 1833 } 1834 1835 .wr-products-trigger { 1836 display: inline-flex; 1837 align-items: center; 1838 gap: 4px; 1839 padding: 4px 10px; 1840 font-size: 12px; 1841 font-weight: 500; 1842 color: var(--wr-accent); 1843 background: rgba(26, 115, 232, 0.06); 1844 border: 1px solid rgba(26, 115, 232, 0.18); 1845 border-radius: 20px; 1846 cursor: pointer; 1847 transition: all 0.15s ease; 1848 white-space: nowrap; 1849 line-height: 1.5; 1850 } 1851 1852 .wr-products-trigger:hover { 1853 background: rgba(26, 115, 232, 0.12); 1854 border-color: rgba(26, 115, 232, 0.35); 1855 } 1856 1857 .wr-products-trigger[aria-expanded="true"] { 1858 background: var(--wr-accent); 1859 color: #fff; 1860 border-color: var(--wr-accent); 1861 } 1862 1863 .wr-products-trigger__count { 1864 font-weight: 700; 1865 } 1866 1867 .wr-products-trigger__chevron { 1868 width: 14px; 1869 height: 14px; 1870 transition: transform 0.2s ease; 1871 flex-shrink: 0; 1872 } 1873 1874 .wr-products-trigger[aria-expanded="true"] .wr-products-trigger__chevron { 1875 transform: rotate(180deg); 1876 } 1877 1878 /* Popover card */ 1879 .wr-products-popover { 1880 display: none; 1881 position: fixed; 1882 z-index: 100000; 1883 min-width: 260px; 1884 max-width: 340px; 1885 background: #fff; 1886 border: 1px solid var(--wr-border); 1887 border-radius: 12px; 1888 box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.06); 1889 animation: wr-popover-in 0.15s ease-out; 1890 } 1891 1892 .wr-products-popover[aria-hidden="false"] { 1893 display: block; 1894 } 1895 1896 @keyframes wr-popover-in { 1897 from { opacity: 0; transform: translateY(-4px); } 1898 to { opacity: 1; transform: translateY(0); } 1899 } 1900 1901 .wr-products-popover--above { 1902 animation: wr-popover-in-above 0.15s ease-out; 1903 } 1904 @keyframes wr-popover-in-above { 1905 from { opacity: 0; transform: translateY(4px); } 1906 to { opacity: 1; transform: translateY(0); } 1907 } 1908 1909 /* Arrow */ 1910 .wr-products-popover::before { 1911 content: ''; 1912 position: absolute; 1913 top: -6px; 1914 left: var(--wr-popover-arrow, 50%); 1915 transform: translateX(-50%) rotate(45deg); 1916 width: 10px; 1917 height: 10px; 1918 background: #fff; 1919 border-top: 1px solid var(--wr-border); 1920 border-left: 1px solid var(--wr-border); 1921 } 1922 .wr-products-popover--above::before { 1923 top: auto; 1924 bottom: -6px; 1925 border-top: none; 1926 border-left: none; 1927 border-bottom: 1px solid var(--wr-border); 1928 border-right: 1px solid var(--wr-border); 1929 } 1930 1931 .wr-products-popover__header { 1932 display: flex; 1933 align-items: center; 1934 justify-content: space-between; 1935 padding: 10px 14px; 1936 border-bottom: 1px solid var(--wr-border); 1937 font-size: 12px; 1938 font-weight: 600; 1939 color: var(--wr-text-secondary); 1940 } 1941 1942 .wr-products-popover__close { 1943 display: flex; 1944 align-items: center; 1945 justify-content: center; 1946 width: 22px; 1947 height: 22px; 1948 border: none; 1949 background: transparent; 1950 color: var(--wr-text-secondary); 1951 font-size: 16px; 1952 border-radius: 6px; 1953 cursor: pointer; 1954 transition: background 0.12s ease; 1955 } 1956 1957 .wr-products-popover__close:hover { 1958 background: rgba(0, 0, 0, 0.06); 1959 color: var(--wr-text); 1960 } 1961 1962 .wr-products-popover__list { 1963 list-style: none; 1964 margin: 0; 1965 padding: 6px 0; 1966 max-height: 220px; 1967 overflow-y: auto; 1968 } 1969 1970 .wr-products-popover__item { 1971 display: flex; 1972 align-items: center; 1973 justify-content: space-between; 1974 gap: 12px; 1975 padding: 8px 14px; 1976 transition: background 0.1s ease; 1977 } 1978 1979 .wr-products-popover__item:hover { 1980 background: rgba(0, 0, 0, 0.02); 1981 } 1982 1983 .wr-products-popover__name { 1984 font-size: 13px; 1985 font-weight: 500; 1986 color: var(--wr-text); 1987 white-space: nowrap; 1988 overflow: hidden; 1989 text-overflow: ellipsis; 1990 } 1991 1992 .wr-products-popover__meta { 1993 font-size: 12px; 1994 color: var(--wr-text-secondary); 1995 white-space: nowrap; 1996 flex-shrink: 0; 1997 } 1998 1999 /* ── Tablenav: generic for all report pages ── */ 2000 .wr-report-page .wr-report-card .tablenav { 2001 display: flex; 2002 align-items: center; 2003 flex-wrap: wrap; 2004 gap: 10px; 2005 padding: 8px 16px; 2006 margin: 0; 2007 background: transparent; 2008 border: none; 2009 } 2010 2011 .wr-report-page .wr-report-card .tablenav.top { 2012 display: none; 2013 } 2014 2015 .wr-report-page .wr-report-card .tablenav.bottom { 2016 justify-content: flex-end; 2017 border-top: 1px solid var(--wr-border); 2018 margin-top: 0; 2019 padding: 10px 16px; 2020 background: #ffffff; 2021 border-radius: 0 0 var(--wr-card-radius) var(--wr-card-radius); 2022 } 2023 2024 .wr-report-page .wr-report-card .tablenav .actions { 2025 display: flex; 2026 align-items: center; 2027 gap: 6px; 2028 } 2029 2030 .wr-report-page .wr-report-card .tablenav .bulkactions { 2031 display: none; 2032 } 2033 2034 .wr-report-page .wr-report-card .nw_export_button { 2035 display: inline-flex; 2036 align-items: center; 2037 gap: 6px; 2038 padding: 6px 12px; 2039 font-size: 13px; 2040 font-weight: 500; 2041 border-radius: 8px; 2042 border: 1px solid var(--wr-border); 2043 background: #fff; 2044 color: var(--wr-text); 2045 text-decoration: none; 2046 transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease; 2047 } 2048 2049 .wr-report-page .wr-report-card .nw_export_button:hover { 2050 border-color: var(--wr-accent); 2051 background: rgba(26, 115, 232, 0.06); 2052 color: var(--wr-accent); 2053 } 2054 2055 .wr-report-page .wr-report-card .nw_export_excel:hover { 2056 background: #b7d8b7 !important; 2057 color: #4c6f16 !important; 2058 border-color: #9ac29a !important; 2059 } 2060 .wr-report-page .wr-report-card .nw_export_pdf:hover { 2061 background: #f0d08a !important; 2062 color: #7a5208 !important; 2063 border-color: #d8b96d !important; 2064 } 2065 2066 /* Orders summary side panel: show totals as stacked list, not table */ 2067 #wr-orders-summary-panel .table.table-striped { 2068 width: 100%; 2069 border: none; 2070 border-collapse: collapse; 2071 margin: 0; 2072 font-size: 13px; 2073 } 2074 2075 #wr-orders-summary-panel .table.table-striped tbody tr { 2076 display: flex; 2077 justify-content: space-between; 2078 align-items: baseline; 2079 padding: 10px 0; 2080 border: none; 2081 border-bottom: 1px solid var(--wr-border); 2082 background: transparent !important; 2083 } 2084 2085 #wr-orders-summary-panel .table.table-striped tbody tr:last-child { 2086 border-bottom: none; 2087 } 2088 2089 #wr-orders-summary-panel .table.table-striped td { 2090 padding: 0; 2091 border: none; 2092 background: transparent; 2093 } 2094 2095 #wr-orders-summary-panel .table.table-striped td:first-child { 2096 font-size: 12px; 2097 font-weight: 500; 2098 color: var(--wr-text-secondary); 2099 } 2100 2101 #wr-orders-summary-panel .table.table-striped td:last-child { 2102 font-size: 14px; 2103 font-weight: 600; 2104 color: var(--wr-text); 2105 text-align: right; 2106 } 2107 2108 /* ── Modern Pagination (all report pages) ── */ 2109 .wr-report-page .wr-report-card .tablenav .tablenav-pages { 2110 margin-left: auto; 2111 display: flex; 2112 align-items: center; 2113 gap: 8px; 2114 } 2115 2116 .wr-report-page .wr-report-card .tablenav-pages .displaying-num { 2117 font-size: 13px; 2118 font-weight: 500; 2119 color: var(--wr-text-secondary); 2120 margin-right: 4px; 2121 } 2122 2123 .wr-report-page .wr-report-card .tablenav-pages .pagination-links { 2124 display: flex; 2125 align-items: center; 2126 gap: 4px; 2127 } 2128 2129 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .tablenav-paging-text { 2130 font-size: 13px; 2131 color: var(--wr-text-secondary); 2132 } 2133 2134 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .button, 2135 .wr-report-page .wr-report-card .tablenav-pages .pagination-links a.button { 2136 display: inline-flex; 2137 align-items: center; 2138 justify-content: center; 2139 min-width: 32px; 2140 height: 32px; 2141 padding: 0 8px; 2142 font-size: 13px; 2143 font-weight: 500; 2144 color: var(--wr-text); 2145 background: #ffffff; 2146 border: 1px solid var(--wr-border); 2147 border-radius: 8px; 2148 cursor: pointer; 2149 text-decoration: none; 2150 transition: all 0.15s ease; 2151 box-shadow: none; 2152 } 2153 2154 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .button:hover, 2155 .wr-report-page .wr-report-card .tablenav-pages .pagination-links a.button:hover { 2156 background: var(--wr-accent); 2157 color: #ffffff; 2158 border-color: var(--wr-accent); 2159 } 2160 2161 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .button.disabled, 2162 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .button[disabled] { 2163 opacity: 0.35; 2164 cursor: not-allowed; 2165 background: #f5f5f5; 2166 color: var(--wr-text-secondary); 2167 border-color: var(--wr-border); 2168 } 2169 2170 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .button.disabled:hover, 2171 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .button[disabled]:hover { 2172 background: #f5f5f5; 2173 color: var(--wr-text-secondary); 2174 border-color: var(--wr-border); 2175 } 2176 2177 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .paging-input { 2178 display: inline-flex; 2179 align-items: center; 2180 gap: 6px; 2181 font-size: 13px; 2182 color: var(--wr-text-secondary); 2183 } 2184 2185 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .paging-input .current-page { 2186 width: 48px; 2187 height: 32px; 2188 padding: 0 6px; 2189 font-size: 13px; 2190 font-weight: 500; 2191 text-align: center; 2192 color: var(--wr-text); 2193 background: #ffffff; 2194 border: 1px solid var(--wr-border); 2195 border-radius: 8px; 2196 outline: none; 2197 transition: border-color 0.15s ease, box-shadow 0.15s ease; 2198 } 2199 2200 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .paging-input .current-page:focus { 2201 border-color: var(--wr-accent); 2202 box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.15); 2203 } 2204 2205 .wr-report-page .wr-report-card .tablenav-pages .pagination-links .total-pages { 2206 font-weight: 600; 2207 color: var(--wr-text); 2208 } 2209 2210 /* Orders summary card: small table */ 2211 .wr-report-page .wr-report-card .table.table-striped { 2212 width: 100%; 2213 border: none; 2214 border-collapse: collapse; 2215 margin: 0; 2216 font-size: 13px; 2217 } 2218 2219 .wr-report-page .wr-report-card .table.table-striped td { 2220 padding: 10px 12px; 2221 border: none; 2222 border-bottom: 1px solid var(--wr-border); 2223 } 2224 2225 .wr-report-page .wr-report-card .table.table-striped tbody tr:nth-of-type(odd) { 2226 background: rgba(0, 0, 0, 0.02); 2227 } 2228 2229 .wr-report-page .wr-report-card .table.table-striped tbody tr:last-child td { 2230 border-bottom: none; 2231 } 2232 2233 .wr-report-page .wr-report-cards--orders { 2234 display: grid; 2235 grid-template-columns: 1fr; 2236 gap: 24px; 2237 } 2238 2239 .wr-report-page .wr-report-cards__two-col--orders { 2240 grid-template-columns: 1fr 1fr; 2241 gap: 24px; 2242 } 2243 2244 @media screen and (max-width: 782px) { 2245 .wr-report-filter-form--modern .WR_filterBox { 2246 gap: 8px; 2247 } 2248 .wr-report-filter-form--modern .form-field { 2249 width: 100%; 2250 } 2251 .wr-report-page .wr-report-filter-bar--orders .wr-orders-summary-trigger { 2252 align-self: flex-end; 2253 } 2254 .wr-report-page .wr-report-cards__two-col--orders { 2255 grid-template-columns: 1fr; 2256 } 2257 } 2258 2259 @media screen and (max-width: 960px) { 2260 .wr-report-topbar { 2261 padding: 12px 16px; 2262 } 2263 .wr-report-topbar__center { 2264 order: 3; 2265 width: 100%; 2266 } 2267 .wr-report-page__inner { 2268 padding-left: 16px; 2269 padding-right: 16px; 2270 } 2271 .wr-report-filter-bar { 2272 padding-left: 16px; 2273 padding-right: 16px; 2274 } 2275 .wr-report-kpis { 2276 grid-template-columns: repeat(2, 1fr); 2277 gap: 12px; 2278 padding: 16px; 2279 } 2280 .wr-report-filter-form { 2281 width: 100%; 2282 } 2283 .wr-report-cards { 2284 grid-template-columns: 1fr; 2285 } 2286 .wr-report-cards__top-row { 2287 grid-template-columns: 1fr; 2288 } 2289 .wr-report-cards__two-col { 2290 grid-template-columns: 1fr; 2291 } 2292 } 2293 2294 @media screen and (max-width: 480px) { 2295 .wr-report-kpis { 2296 grid-template-columns: 1fr; 2297 } 2298 } -
wc-reports-lite/trunk/assets/js/admin.js
r2413794 r3493462 1 1 2 2 (function($) { 3 "use strict"; 3 "use strict"; 4 4 $(document).ready(function () { 5 //Display products btn 6 $('.wcrl_customer_products a').on('click',function () { 7 $(this).next().toggle(); 5 // Products popover (fixed positioning to escape overflow containers) 6 function wrCloseAllPopovers($except) { 7 $('.wr-products-trigger[aria-expanded="true"]').not($except || $()) 8 .attr('aria-expanded', 'false') 9 .closest('.wr-products-popover-wrap') 10 .find('.wr-products-popover').attr('aria-hidden', 'true').removeClass('wr-products-popover--above'); 11 } 12 13 function wrPositionPopover($btn, $popover) { 14 var rect = $btn[0].getBoundingClientRect(); 15 var popW = $popover.outerWidth(); 16 var popH = $popover.outerHeight(); 17 var vpW = window.innerWidth; 18 var vpH = window.innerHeight; 19 var gap = 8; 20 21 // Horizontal: center on the trigger, clamp to viewport 22 var left = rect.left + rect.width / 2 - popW / 2; 23 left = Math.max(8, Math.min(left, vpW - popW - 8)); 24 25 // Arrow position relative to popover 26 var arrowLeft = (rect.left + rect.width / 2 - left); 27 arrowLeft = Math.max(16, Math.min(arrowLeft, popW - 16)); 28 29 // Vertical: prefer below, flip above if not enough room 30 var spaceBelow = vpH - rect.bottom - gap; 31 var openAbove = spaceBelow < popH && rect.top - gap > popH; 32 33 var top; 34 if (openAbove) { 35 top = rect.top - popH - gap; 36 $popover.addClass('wr-products-popover--above'); 37 } else { 38 top = rect.bottom + gap; 39 $popover.removeClass('wr-products-popover--above'); 40 } 41 42 $popover.css({ top: top + 'px', left: left + 'px' }); 43 $popover[0].style.setProperty('--wr-popover-arrow', arrowLeft + 'px'); 44 } 45 46 $(document).on('click', '.wr-products-trigger', function (e) { 47 e.stopPropagation(); 48 var $btn = $(this); 49 var $wrap = $btn.closest('.wr-products-popover-wrap'); 50 var $popover = $wrap.find('.wr-products-popover'); 51 var isOpen = $btn.attr('aria-expanded') === 'true'; 52 53 wrCloseAllPopovers($btn); 54 55 if (!isOpen) { 56 $btn.attr('aria-expanded', 'true'); 57 $popover.attr('aria-hidden', 'false'); 58 wrPositionPopover($btn, $popover); 59 } else { 60 $btn.attr('aria-expanded', 'false'); 61 $popover.attr('aria-hidden', 'true').removeClass('wr-products-popover--above'); 62 } 63 }); 64 65 $(document).on('click', '.wr-products-popover__close', function (e) { 66 e.stopPropagation(); 67 var $wrap = $(this).closest('.wr-products-popover-wrap'); 68 $wrap.find('.wr-products-trigger').attr('aria-expanded', 'false'); 69 $wrap.find('.wr-products-popover').attr('aria-hidden', 'true').removeClass('wr-products-popover--above'); 70 }); 71 72 $(document).on('click', function () { 73 wrCloseAllPopovers(); 74 }); 75 76 $(document).on('click', '.wr-products-popover', function (e) { 77 e.stopPropagation(); 78 }); 79 80 // Reposition open popover on scroll/resize 81 $(window).on('scroll resize', function () { 82 var $open = $('.wr-products-trigger[aria-expanded="true"]'); 83 if ($open.length) { 84 var $popover = $open.closest('.wr-products-popover-wrap').find('.wr-products-popover'); 85 wrPositionPopover($open, $popover); 86 } 87 }); 88 $('.wr-report-card__body--table').on('scroll', function () { 89 var $open = $(this).find('.wr-products-trigger[aria-expanded="true"]'); 90 if ($open.length) { 91 var $popover = $open.closest('.wr-products-popover-wrap').find('.wr-products-popover'); 92 wrPositionPopover($open, $popover); 93 } 94 }); 95 //select2 96 $(".wr-select2, .select2-filter").each(function() { 97 var $el = $(this); 98 $el.select2({ 99 placeholder: $el.data('placeholder') || '', 100 allowClear: !!$el.attr('multiple') 101 }); 8 102 }); 9 103 10 104 // settings page 11 $('.w crl-settings-container ul.tabs li').on('click',function(){105 $('.wr-settings-container ul.tabs li').on('click',function(){ 12 106 var tab_id = $(this).attr('data-tab'); 13 107 $('ul.tabs li').removeClass('current'); … … 18 112 }); 19 113 114 // active email reporting 115 if ($('#WR_active_email_reporting').is(':checked')) { 116 $('.WR_email_form_settings').show(); 117 } 118 $('#WR_active_email_reporting').on('change',function () { 119 if ($('#WR_active_email_reporting').is(':checked')) { 120 $('.WR_email_form_settings').show('200'); 121 }else{ 122 $('.WR_email_form_settings').hide('200'); 123 } 124 }); 125 126 //hidden screen-reader-text for export options(dataTable js) 127 $(".wp-list-table .screen-reader-text").empty(); 128 129 // Generic Summary panel handler for all report pages 130 $(document).on('click', '.wr-summary-trigger', function() { 131 var panelId = $(this).data('panel'); 132 var $panel = $('#' + panelId); 133 if ($panel.length) { 134 $panel.addClass('wr-insights-panel--open').attr('aria-hidden', 'false'); 135 } 136 }); 137 $(document).on('click', '.wr-insights-panel__backdrop, .wr-insights-panel__close', function() { 138 var $panel = $(this).closest('.wr-insights-panel'); 139 $panel.removeClass('wr-insights-panel--open').attr('aria-hidden', 'true'); 140 }); 141 $(document).on('click', '.wr-insights-panel__drawer', function(e) { 142 e.stopPropagation(); 143 }); 144 145 // Generic reset filters button for all report pages 146 $(document).on('click', '.wr-report-reset-filters', function(e) { 147 e.preventDefault(); 148 var page = $(this).data('page') || new URLSearchParams(window.location.search).get('page'); 149 if (page) { 150 var url = new URL(window.location.href); 151 url.search = ''; 152 url.searchParams.set('page', page); 153 window.location = url.toString(); 154 } 155 }); 156 20 157 }); 21 158 })(jQuery); -
wc-reports-lite/trunk/assets/js/persianDatepicker.js
r2413794 r3493462 7 7 * Released under the MIT license. 8 8 * 9 * jalali Date Functions from NASA.gov9 * jalali Date Functions 10 10 * 11 11 * Date: Tue Jan 1 2013 12 * 13 * Last Update: Mon April 15 2019 14 * 12 15 */ 13 16 ; 14 17 (function ($) { 15 18 $.fn.persianDatepicker = function (options) { 16 var 'wc-reports-lite'= 'persianDatepicker';17 var instance = this.data( 'wc-reports-lite');19 var pluginName = 'persianDatepicker'; 20 var instance = this.data(pluginName); 18 21 if (!instance) { 19 22 return this.each(function () { 20 return $(this).data( 'wc-reports-lite', new persianDatepicker(this, options));23 return $(this).data(pluginName, new persianDatepicker(this, options)); 21 24 }); 22 25 } … … 52 55 y: 0, 53 56 }, 54 onShow: function () { 55 }, 56 onHide: function () { 57 }, 58 onSelect: function () { 59 }, 60 onRender: function () { 61 } 57 onShow: function () { }, 58 onHide: function () { }, 59 onSelect: function () { }, 60 onRender: function () { } 62 61 }; 63 62 var self = this; … … 87 86 } 88 87 89 if (self.options.selectedDate == undefined ) {88 if (self.options.selectedDate == undefined && !self.options.showGregorianDate) { 90 89 var patt1 = new RegExp('^([1-9][0-9][0-9][0-9])/([0]?[1-9]|[1][0-2])/([0]?[1-9]|[1-2][0-9]|[3][0-1])$'); 91 90 if (el.is('input')) { … … 138 137 if (options.selectedBefore) { 139 138 if (self.options.selectedDate != undefined) { 140 jd = self.jDateFunctions.getJulianDayFromPersian(self.persianDate.parse(self.options.selectedDate));141 self.showDate(el, self.persianDate.parse(self.options.selectedDate).toString("YYYY/MM/DD/" + self.jDateFunctions.getWeekday( jd)), self.now().gDate, options.showGregorianDate);139 //>jd = self.jDateFunctions.getJulianDayFromPersian(self.persianDate.parse(self.options.selectedDate)); 140 self.showDate(el, self.persianDate.parse(self.options.selectedDate).toString("YYYY/MM/DD/" + self.jDateFunctions.getWeekday(self.persianDate.parse(self.options.selectedDate)), self.now().gDate, options.showGregorianDate)); 142 141 } else { 143 jd = self.jDateFunctions.getJulianDayFromPersian(self.now());144 self.showDate(el, self.now().toString("YYYY/MM/DD/" + self.jDateFunctions.getWeekday( jd)), self.now().gDate, options.showGregorianDate);142 //>jd = self.jDateFunctions.getJulianDayFromPersian(self.now()); 143 self.showDate(el, self.now().toString("YYYY/MM/DD/" + self.jDateFunctions.getWeekday(self.now())), self.now().gDate, options.showGregorianDate); 145 144 } 146 145 } … … 168 167 var onResize = function () { 169 168 var elPos = el.offset(); 170 self.calendar.css( 171 { 172 top: (elPos.top + el.outerHeight() + options.calendarPosition.y) + 'px', 173 left: (elPos.left + options.calendarPosition.x) + 'px' 174 }); 169 self.calendar.css({ 170 top: (elPos.top + el.outerHeight() + options.calendarPosition.y) + 'px', 171 left: (elPos.left + options.calendarPosition.x) + 'px' 172 }); 175 173 }; 176 174 self.onresize = onResize; … … 179 177 self.render(); 180 178 onResize(); 181 } 182 ; 179 }; 183 180 184 181 // persianDatepicker methods … … 243 240 return false; 244 241 }) 245 . on('click',function (e) {242 .click(function (e) { 246 243 e.stopPropagation(); 247 _yearSelect.css({ display: 'none' }); 248 _monthSelect.css({ display: 'inline-block' }); 244 _yearSelect.css({ 245 display: 'none' 246 }); 247 _monthSelect.css({ 248 display: 'inline-block' 249 }); 249 250 }); 250 251 var _yearText = $('<span/>') … … 253 254 return false; 254 255 }) 255 . on('click',function (e) {256 .click(function (e) { 256 257 e.stopPropagation(); 257 _monthSelect.css({ display: 'none' }); 258 _yearSelect.css({ display: 'inline-block' }); 258 _monthSelect.css({ 259 display: 'none' 260 }); 261 _yearSelect.css({ 262 display: 'inline-block' 263 }); 259 264 _yearSelect.scrollTop(70); 260 265 }); … … 308 313 o.addClass('selected'); 309 314 } 310 o.data('month', { month: m, monthNum: i }); 315 o.data('month', { 316 month: m, 317 monthNum: i 318 }); 311 319 if (!o.hasClass('disableMonth')) { 312 320 o.bind("click", function () { … … 382 390 jd = self.persianDate; 383 391 jd.date = 1; 384 _start = self.jDateFunctions.getWeekday(self. jDateFunctions.getJulianDayFromPersian(jd));385 _end = self.jDateFunctions.getLastDayOf PersianMonth(self.persianDate);392 _start = self.jDateFunctions.getWeekday(self.persianDate); 393 _end = self.jDateFunctions.getLastDayOfMonth(self.persianDate); 386 394 for (var row = 0, cellIndex = 0; row < 5 + 1; row++) { 387 395 _row = $('<div />'); … … 477 485 this.options.onSelect(); 478 486 }, 479 getDate: function ( jd, d) {480 jd.date = d;481 jd.day = this.jDateFunctions.getWeekday(this.jDateFunctions.getJulianDayFromPersian(jd))482 return jd;487 getDate: function (pd, d) { 488 pd.date = d; 489 pd.day = this.jDateFunctions.getWeekday(pd) 490 return pd; 483 491 }, 484 492 now: function () { 485 return this.jDateFunctions.g etPCalendarDate(this.jDateFunctions.getJulianDay(new Date()));493 return this.jDateFunctions.gregorian_to_jalali(new Date()); 486 494 }, 487 495 }; … … 515 523 .replace("mm", this.getMinutes() == 0 ? new Date().getMinutes() : this.getMinutes()) 516 524 .replace("ss", this.getSeconds() == 0 ? new Date().getSeconds() : this.getSeconds()) 525 .replace("0h", this.getHours() > 9 ? this.getHours() : "0" + this.getHours()) 526 .replace("0m", this.getMinutes() > 9 ? this.getMinutes() : "0" + this.getMinutes()) 527 .replace("0s", this.getSeconds() > 9 ? this.getSeconds() : "0" + this.getSeconds()) 517 528 .replace("ms", this.getMilliseconds() == 0 ? new Date().getMilliseconds() : this.getMilliseconds()) 518 529 .replace("tm", (this.getHours() >= 12 && this.getMinutes() > 0) ? "PM" : "AM") … … 527 538 }; 528 539 })(); 529 })(jQuery); // end of persianDatepicker plugin540 })(jQuery); // end of persianDatepicker plugin 530 541 531 542 // persianDate object … … 540 551 self.day = 1; 541 552 self.gDate = new Date(); 542 } 543 ; 553 }; 544 554 persianDate.prototype = { 545 555 now: function () { 546 556 var jdf = new jDateFunctions(); 547 return jdf.g etPCalendarDate(jdf.getJulianDay(new Date()));557 return jdf.gregorian_to_jalali(new Date()); 548 558 }, 549 559 addDay: function (d) { … … 555 565 r.year = this.year; 556 566 r = r.addMonth(-1); 557 var lastDayOfMonth = d > 0 ? jdf.getLastDayOf PersianMonth(this) : jdf.getLastDayOfPersianMonth(r);567 var lastDayOfMonth = d > 0 ? jdf.getLastDayOfMonth(this) : jdf.getLastDayOfMonth(r); 558 568 d > 0 ? this.date += 1 : this.date -= 1; 559 569 if (d > 0) { … … 611 621 var r = new persianDate(); 612 622 jdf = new jDateFunctions(); 613 r.year = parseInt(y), r.month = parseInt(m), r.date = parseInt(d) 614 , r.day = jdf.getWeekday(jdf.getJulianDayFromPersian(r)), r.gDate = jdf.getGCalendarDate(jdf.getJulianDayFromPersian(r), "jgmonth"); 623 r.year = parseInt(y), r.month = parseInt(m), r.date = parseInt(d), r.day = jdf.getWeekday(r), r.gDate = jdf.jalali_to_gregorian(r); 615 624 return r; 616 625 }, … … 628 637 .replace("mm", this.gDate.getMinutes()) 629 638 .replace("ss", this.gDate.getSeconds()) 639 .replace("0h", this.gDate.getHours() > 9 ? this.gDate.getHours() : "0" + this.gDate.getHours()) 640 .replace("0m", this.gDate.getMinutes() > 9 ? this.gDate.getMinutes() : "0" + this.gDate.getMinutes()) 641 .replace("0s", this.gDate.getSeconds() > 9 ? this.gDate.getSeconds() : "0" + this.gDate.getSeconds()) 630 642 .replace("tm", (this.gDate.getHours() >= 12 && this.gDate.getMinutes() > 0) ? "ب.ظ" : "ق.ظ") 631 643 .replace("ms", this.gDate.getMilliseconds()) … … 641 653 // jalali Date Functions from NASA.gov 642 654 var jDateFunctions = (function () { 643 function jDateFunctions() { 644 } 645 ; 655 function jDateFunctions() { }; 646 656 647 657 jDateFunctions.prototype = { … … 654 664 return res; 655 665 }, 666 667 gregorian_to_jalali: function (dt) { 668 gy = dt.getFullYear(); 669 gm = dt.getMonth() + 1; 670 gd = dt.getDate(); 671 g_d_m = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; 672 if (gy > 1600) { 673 jy = 979; 674 gy -= 1600; 675 } else { 676 jy = 0; 677 gy -= 621; 678 } 679 gy2 = (gm > 2) ? (gy + 1) : gy; 680 days = (365 * gy) + (parseInt((gy2 + 3) / 4)) - (parseInt((gy2 + 99) / 100)) + (parseInt((gy2 + 399) / 400)) - 80 + gd + g_d_m[gm - 1]; 681 jy += 33 * (parseInt(days / 12053)); 682 days %= 12053; 683 jy += 4 * (parseInt(days / 1461)); 684 days %= 1461; 685 if (days > 365) { 686 jy += parseInt((days - 1) / 365); 687 days = (days - 1) % 365; 688 } 689 jm = (days < 186) ? 1 + parseInt(days / 31) : 7 + parseInt((days - 186) / 30); 690 jd = 1 + ((days < 186) ? (days % 31) : ((days - 186) % 30)); 691 dt = new Date(); 692 pd = new persianDate(); 693 pd.year = jy; 694 pd.month = jm; 695 pd.date = jd; 696 pd.gDate = dt; 697 return pd; 698 }, 699 700 jalali_to_gregorian: function (pd) { 701 jy = pd.year; 702 jm = pd.month; 703 jd = pd.date; 704 if (jy > 979) { 705 gy = 1600; 706 jy -= 979; 707 } else { 708 gy = 621; 709 } 710 days = (365 * jy) + ((parseInt(jy / 33)) * 8) + (parseInt(((jy % 33) + 3) / 4)) + 78 + jd + ((jm < 7) ? (jm - 1) * 31 : ((jm - 7) * 30) + 186); 711 gy += 400 * (parseInt(days / 146097)); 712 days %= 146097; 713 if (days > 36524) { 714 gy += 100 * (parseInt(--days / 36524)); 715 days %= 36524; 716 if (days >= 365) days++; 717 } 718 gy += 4 * (parseInt(days / 1461)); 719 days %= 1461; 720 if (days > 365) { 721 gy += parseInt((days - 1) / 365); 722 days = (days - 1) % 365; 723 } 724 gd = days + 1; 725 sal_a = [0, 31, ((gy % 4 == 0 && gy % 100 != 0) || (gy % 400 == 0)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; 726 for (gm = 0; gm < 13; gm++) { 727 v = sal_a[gm]; 728 if (gd <= v) break; 729 gd -= v; 730 } 731 dt = new Date(); 732 return new Date(gy, gm - 1, gd, dt.getHours(), dt.getMinutes(), dt.getSeconds(), dt.getMilliseconds()); 733 }, 656 734 getGDate: function (pd) { 657 return this.getGCalendarDate(this.getJulianDayFromPersian(pd), "gmonth"); 658 }, 659 getPCalendarDate: function (jd) { 660 var y = 0; 661 var m = 0; 662 var day = 0.0; 663 if (jd > 0.0) { 664 var jdm = jd + 0.5; 665 var z = Math.floor(jdm); 666 var f = jdm - z; 667 var jdmp = Math.floor(jd) + 0.5; 668 var pd = new persianDate(); 669 pd.year = 475; 670 pd.month = 1; 671 pd.date = 1; 672 var depoch = jdmp - this.getJulianDayFromPersian(pd); 673 var cycle = Math.floor(depoch / 1029983); 674 var cyear = depoch % 1029983; 675 var ycycle; 676 if (cyear == 1029982) { 677 ycycle = 2820; 678 } 679 else { 680 var a1 = Math.floor(cyear / 366); 681 var a2 = cyear % 366; 682 ycycle = Math.floor(((2134 * a1) + (2816 * a2) + 2815) / 1028522) + a1 + 1; 683 } 684 y = ycycle + (2820 * cycle) + 474; 685 if (y <= 0) { 686 y--; 687 } 688 pd.year = y; 689 pd.month = 1; 690 pd.date = 1; 691 var yday = (jdmp - this.getJulianDayFromPersian(pd)) + 1; 692 m = (yday <= 186) ? Math.ceil(yday / 31) : Math.ceil((yday - 6) / 30); 693 pd.year = y; 694 pd.month = m; 695 pd.date = 1; 696 day = (jdmp - this.getJulianDayFromPersian(pd)) + 1; 697 } 698 699 var r = new persianDate; 700 r.year = y, 701 r.month = m, 702 r.date = day 703 , r.day = this.getWeekday(this.getJulianDayFromPersian(r)), 704 r.gDate = new Date(); 705 return r; 706 }, 707 getGCalendarDate: function (jd, dateformat) { 708 var y = 0; 709 var m = 0; 710 var day = 0.0; 711 if (jd > 0.0) { 712 var jdm = jd + 0.5; 713 var z = Math.floor(jdm); 714 var f = jdm - z; 715 /* cases "jgmonth","gmonth","jmonth" */ 716 var a; 717 if (dateformat == "jmonth" || (dateformat == "jgmonth" && z < 2299161)) { 718 a = z; 719 } 720 else if (dateformat == "gmonth" || (dateformat == "jgmonth" && z >= 2299161)) { 721 var alpha = Math.floor((z - 1867216.25) / 36524.25); 722 a = z + 1 + alpha - Math.floor(alpha / 4); 723 } 724 var b = a + 1524; 725 var c = Math.floor((b - 122.1) / 365.25); 726 var d = Math.floor(365.25 * c); 727 var e = Math.floor((b - d) / 30.6001); 728 day = b - d - Math.floor(30.6001 * e) + f; 729 if (e < 14) { 730 m = e - 1; 731 } 732 else if (e == 14 || e == 15) { 733 m = e - 13; 734 } 735 if (m > 2) { 736 y = c - 4716; 737 } 738 else if (m == 1 || m == 2) { 739 y = c - 4715; 740 } 741 } 742 743 r = new Date(); 744 return new Date(y, m - 1, day, r.getHours(), r.getMinutes(), r.getSeconds(), r.getMilliseconds()); 745 }, 746 /* function getJulianDay(originalY, originalM, originalD) */ 747 getJulianDay: function (d, jgGOrJ) { 748 /* jgGOrJ: 0 = auto Julian/Gregorian; 1 = Gregorian; 2 = Julian */ 749 var jgGOrJ = (jgGOrJ === undefined) ? 0 : jgGOrJ; 750 /* Given UT */ 751 var y0 = d.getFullYear(); 752 var m0 = d.getMonth() + 1; 753 var d0 = d.getDate(); 754 var y = y0 + 0; 755 var m = m0 + 0; 756 var d = d0 + 0.0; 757 /* y = -4712; 758 m = 1; 759 d = 1.5; */ 760 /* Determine JD */ 761 if (m <= 2) { 762 y = y - 1; 763 m = m + 12; 764 } 765 var b = 0; 766 if (d0 < 1 || ((m0 == 1 || m0 == 3 || m0 == 5 || m0 == 7 || m0 == 8 || m0 == 10 || m0 == 12) && d0 > 31) || ((m0 == 4 || m0 == 6 || m0 == 9 || m0 == 11) && d0 > 30)) { 767 //try { 768 // console.log("Id 646"); 769 //} catch (e) { } 770 } 771 if (jgGOrJ == 2 || (jgGOrJ == 0 && (y0 < 1582 || (y0 == 1582 && m0 < 10) || (y0 == 1582 && m0 == 10 && d0 <= 4)))) { 772 /* Julian calendar */ 773 b = 0; 774 if (y0 / 4.0 == Math.round(y0 / 4.0)) { 775 /* Leap year */ 776 if (m0 == 2 && d0 > 29) { 777 //try { 778 // console.log("Id 656"); 779 //} catch (e) { } 780 } 781 } 782 } 783 else if (jgGOrJ == 1 || (jgGOrJ == 0 && (y0 > 1582 || (y0 == 1582 && m0 > 10) || (y0 == 1582 && m0 == 10 && d0 >= 15)))) { 784 /* Gregorian calendar */ 785 var a = Math.floor(y / 100); 786 b = 2 - a + Math.floor(a / 4); 787 if (y0 / 4.0 == Math.round(y0 / 4.0)) { 788 if (y0 / 100.0 == Math.round(y0 / 100.0)) { 789 if (y0 / 400.0 == Math.round(y0 / 400.0)) { 790 /* Leap year */ 791 if (m0 == 2 && d0 > 29) { 792 //try { 793 // console.log("Id 671"); 794 //} catch (e) { } 795 } 796 } 797 } 798 else { 799 /* Leap year */ 800 if (m0 == 2 && d0 > 29) { 801 //try { 802 // console.log("Id 680"); 803 //} catch (e) { } 804 } 805 } 806 } 807 } 808 //else { 809 // try { 810 // console.log("Id 687"); 811 // } catch (e) { } 812 //} 813 var jd = Math.floor(365.25 * (y + 4716)) + Math.floor(30.6001 * (m + 1)) + d + b - 1524.5; 814 return jd; 815 }, 816 getJulianDayFromPersian: function (pd) { 817 y0 = pd.year, m0 = pd.month, d0 = pd.date; 818 var epbase = y0 - ((y0 >= 0) ? 474 : 473); 819 var epyear = 474 + (epbase % 2820); 820 return d0 + ((m0 <= 7) ? ((m0 - 1) * 31) : (((m0 - 1) * 30) + 6)) + Math.floor(((epyear * 682) - 110) / 2816) + (epyear - 1) * 365 + Math.floor(epbase / 2820) * 1029983 + (1948320.5 - 1); 821 }, 822 getWeekday: function (jd) { 823 wds = [1, 2, 3, 4, 5, 6, 0]; 824 wd = Math.floor((jd + 1.5) % 7.0); 825 return wds[wd]; 826 }, 827 getLastDayOfPersianMonth: function (pd) { 735 return this.jalali_to_gregorian(pd); 736 //>return this.getGCalendarDate(this.getJulianDayFromPersian(pd), "gmonth"); 737 }, 738 getWeekday: function (pd) { 739 var gds = [1, 2, 3, 4, 5, 6, 0]; 740 return gds[this.jalali_to_gregorian(pd).getDay()]; 741 }, 742 getLastDayOfMonth: function (pd) { 828 743 y = pd.year, m = pd.month; 829 744 if (m >= 1 && m <= 6) { 830 745 return 31; 831 } 832 else if (m >= 7 && m < 12) { 746 } else if (m >= 7 && m < 12) { 833 747 return 30; 834 748 } 835 else if (m != 12) {836 //try {837 // console.log("Id 715");838 //}catch (e){}839 }840 749 /* Esfand */ 841 if (y%4==3) {750 else if (this.isLeapYear(y)) { 842 751 /* Leap year */ 843 752 return 30; … … 845 754 return 29; 846 755 }, 847 isLeapYear(year) { 848 ary = array(1, 5, 9, 13, 17, 22, 26, 30); 756 // 1244 to 1472 757 isLeapYear: function (year) { 758 var ary = year > 1342 ? [1, 5, 9, 13, 17, 22, 26, 30] : [1, 5, 9, 13, 17, 21, 26, 30]; 849 759 b = year % 33; 850 if ( in_array($b, $ary))760 if (ary._indexOf(b)>-1) 851 761 return true; 852 762 return false; -
wc-reports-lite/trunk/includes/class-wr-autoloader.php
r3493461 r3493462 5 5 * Autoloader class. 6 6 */ 7 class W CRL_Autoloader {7 class WR_Autoloader { 8 8 9 9 /** … … 18 18 */ 19 19 public function __construct() { 20 if ( function_exists( '__autoload' ) ) {21 spl_autoload_register( '__autoload' );22 }23 20 spl_autoload_register( array( $this, 'autoload' ) ); 24 $this->include_path = untrailingslashit( plugin_dir_path( W CRL_PLUGIN_FILE) ) . '/includes/';21 $this->include_path = untrailingslashit( plugin_dir_path( WR_PLUGIN_FILE) ) . '/includes/'; 25 22 } 26 23 /** … … 49 46 50 47 /** 51 * Auto-load W CRLclasses on demand to reduce memory consumption.48 * Auto-load WR classes on demand to reduce memory consumption. 52 49 * 53 50 * @param string $class Class name. … … 56 53 $class = strtolower( $class ); 57 54 58 if ( 0 !== strpos( $class, 'w crl_' ) ) {55 if ( 0 !== strpos( $class, 'wr_' ) ) { 59 56 return; 60 57 } … … 69 66 } 70 67 71 new W CRL_Autoloader();68 new WR_Autoloader(); -
wc-reports-lite/trunk/readme.txt
r3321863 r3493462 1 === NikanWP WooCommerce Reporting === 2 Contributors: nikanwp,mahdikhaksar 3 Tags: order report, report, sale report, stock report, tax report, woocommerce, woocommerce dashboard, woocommerce order pdf, woocommerce order report, woocommerce order summary, woocommerce report, woocommerce reporting, woocommerce sale 4 Requires at least: 4.9 or higher 5 Tested up to: 5.5.1 6 Requires PHP: 7.0 7 Stable tag: 1.0.0 1 === WooReports Lite — Sales Reports for WooCommerce === 2 Contributors: nikanwp 3 Tags: woocommerce, sales report, stock report, order report, revenue report 4 Requires at least: 6.0 5 Tested up to: 6.9 6 Stable tag: 3.0.0 7 Requires PHP: 7.4 8 WC requires at least: 7.0 9 WC tested up to: 10.5.3 8 10 License: GPLv2 or later 9 11 License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 12 13 Free sales reports for WooCommerce — 11 report modules including orders, products, stock, tax, coupons and payment gateways. No API key needed. 14 11 15 == Description == 12 WooCommerce Reporting is a complete reporting solution for your store. It helps you track sales, monitor order trends, analyze product performance, and make data-driven decisions — all from a beautiful and intuitive dashboard.13 [View Live Demo](https://demo.nikanwp.com/woocommerce-reporting/ "WooCommerce Reporting Demo") | [Pro Version](https://nikanwp.com/product/woocommerce-reporting/ "WooCommerce Reporting Pro")14 16 15 **Features** 16 * Summary Of Reports (FREE) 17 * Orders Reports (FREE) 18 * Products Reports (FREE) 19 * Categories Reports (FREE) 20 * Coupons Reports (FREE) 21 * Payment Gateway Reports (FREE) 22 * Orders Status Reports (FREE) 23 * Locations Reports (FREE) 24 * Shippings Reports (FREE) 25 * Tax Reports (FREE) 26 * Stock Reports (FREE) 27 * RTL & Jalali date Support (FREE) 28 * Export Reports (PRO) 29 * Advance Search Filter (PRO) 30 * Email Scheduler (PRO) 31 * Visual Reports (PRO) 32 * Profit Of Sales Reports (PRO) 33 * Dokan Seller Reports (PRO) 34 * Customer Reports (PRO) 17 WooReports Lite gives you a clear view of your store performance — directly inside your WordPress dashboard. Reports are generated fresh from your WooCommerce database each time you open a page. No external API, no monthly fee, no setup required. 35 18 19 **Free report modules:** 20 21 * **Overview** — revenue KPIs, orders count, AOV, sales trend chart, top products, top categories, top payment gateways 22 * **Orders** — full order list with date, customer name, status, items, shipping, discount, tax and total 23 * **Products** — revenue and quantity sold per product 24 * **Categories** — sales broken down by product category 25 * **Coupons** — usage count and total discount amount per coupon code 26 * **Payment Gateway** — revenue and order count by payment method 27 * **Orders Status** — orders grouped and counted by status 28 * **Locations** — sales by country and state/province 29 * **Shippings** — shipping method usage, order count and revenue 30 * **Tax** — tax collected by rate and country 31 * **Stock** — inventory levels, stock status and value for all products 32 33 **Upgrade to [WooReports — the advanced reporting plugin for WooCommerce](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=readme&utm_campaign=upgrade) to unlock:** 34 35 * Advanced date range filter — filter every report by any custom date range and compare periods side by side 36 * Customer reports — lifetime value, total orders, average order value, purchase history, searchable by name, email or phone 37 * Profit reports — net profit per product using Cost of Goods (COG) tracking 38 * Profit by payment gateway and profit per order 39 * Export to Excel (XLSX), PDF & CSV — one click on every report 40 * Scheduled email reports — automatically delivered to any recipient on your schedule 41 * Admin bar quick stats — today's revenue and order count always visible 42 * Dokan vendor reports — full multi-vendor reporting 43 44 == Installation == 45 46 1. Upload the plugin folder to `/wp-content/plugins/` 47 2. Activate through the **Plugins** menu in WordPress 48 3. Go to **WooReports** in your WordPress admin sidebar 49 4. The Overview dashboard loads instantly — no configuration needed 50 51 == Frequently Asked Questions == 52 53 = Does this plugin require WooCommerce? = 54 Yes. WooReports Lite requires WooCommerce to be installed and active. It reads data directly from your WooCommerce orders. 55 56 = Is it compatible with HPOS (High-Performance Order Storage)? = 57 Yes. WooReports Lite is fully compatible with WooCommerce HPOS (custom order tables). It uses the WooCommerce order API exclusively and does not query the posts table directly. 58 59 = Does it work with the latest version of WordPress and WooCommerce? = 60 Yes. WooReports Lite is tested with WordPress 6.9 and WooCommerce 10.5. It is compatible with PHP 7.4 through 8.3. 61 62 = How up to date is the data in the reports? = 63 Reports are generated directly from your WooCommerce database each time you open a report page — so you always see your latest orders and store data. 64 65 = Can I filter reports by date range? = 66 The Overview dashboard includes a built-in date preset filter (today, yesterday, last 7 days, last 30 days, last 365 days). Custom date range filtering across all reports — including orders, products, categories and more — is available in [WooReports Pro](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=faq&utm_campaign=upgrade). 67 68 = Can I see which products are most profitable? = 69 Profit tracking with Cost of Goods (COG) per product, payment gateway and order is a Pro feature. [WooReports Pro](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=faq&utm_campaign=upgrade) lets you enter a cost price per product and see real net profit across all reports. 70 71 = Can I export reports to Excel or PDF? = 72 Export to Excel (XLSX), PDF and CSV is available in [WooReports Pro](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=faq&utm_campaign=upgrade). In Lite, reports are available as on-screen tables only. 73 74 = Can I see customer purchase history and lifetime value? = 75 Customer reports — including lifetime spend, total orders, average order value, and searchable by name, email or phone — are available in [WooReports Pro](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=faq&utm_campaign=upgrade). 76 77 = What is the difference between Lite and Pro? = 78 Lite includes 11 free report modules with overview-level date filtering. Pro adds custom date ranges on all reports, customer lifetime value reports, profit tracking with Cost of Goods, export to Excel/PDF/CSV, scheduled email reports, admin bar quick stats and Dokan vendor reports. 79 80 = Does it support multisite? = 81 WooReports Lite has not been tested on WordPress Multisite. It is designed for single-site WooCommerce stores. 82 83 == Screenshots == 84 85 1. Overview dashboard — KPI cards, sales trend chart and top segments 86 2. Orders report — full order list with status, items, shipping, tax and total 87 3. Products report — revenue and quantity sold per product 88 4. Stock report — inventory levels and stock status for all products 89 90 == Changelog == 91 92 = 3.0.0 = 93 * Full compatibility with WooCommerce HPOS (High-Performance Order Storage / custom order tables) 94 * Completely redesigned modern UI 95 * Tested with WordPress 6.9 and WooCommerce 10.5 96 * Compatible with PHP 7.4–8.3 97 98 = 1.0.0 = 99 * Initial release -
wc-reports-lite/trunk/wcrl.php
r2413794 r3493462 1 1 <?php 2 2 /** 3 * Plugin Name: Reports for WooCommerce Lite4 * Plugin URI: https://nikanwp.com/ woocommerce-reporting/5 * Description: WooCommerce reporting system6 * Version: 1.0.03 * Plugin Name: WooReports Lite — WooCommerce Reporting 4 * Plugin URI: https://nikanwp.com/product/woocommerce-reporting/ 5 * Description: Free WooCommerce reporting plugin with 11 report modules — sales, orders, products, stock, tax, coupons, payment gateways and more. No API key required. Upgrade to Pro for profit tracking, export to Excel/PDF, customer reports and scheduled emails. 6 * Version: 3.0.0 7 7 * Author: NikanWP 8 8 * Author URI: https://nikanwp.com/ 9 * Text Domain: wc-reports-lite 9 * Requires at least: 6.0 10 * Tested up to: 6.7 11 * Requires PHP: 7.4 12 * Requires Plugins: woocommerce 13 * Text Domain: wooreports 10 14 * Domain Path: /languages 15 * License: GPLv2 or later 11 16 */ 12 17 13 if (!defined( 'ABSPATH' ) ) { 14 exit;// Exit if accessed directly. 18 if ( ! defined( 'ABSPATH' ) ) { exit; } 19 if ( ! defined( 'WR_PLUGIN_FILE' ) ) { define( 'WR_PLUGIN_FILE', __FILE__ ); } 20 define( 'WR_LITE', true ); 21 22 add_action( 'before_woocommerce_init', function () { 23 if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { 24 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); 25 } 26 } ); 27 28 // Add "Upgrade to Pro" action link on the plugins list page. 29 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), function ( $links ) { 30 $upgrade_link = sprintf( 31 '<a href="%s" target="_blank" rel="noopener" style="color:#7f77dd;font-weight:600;">%s</a>', 32 esc_url( 'https://nikanwp.com/product/woocommerce-reporting/?utm_source=lite&utm_medium=plugin-list&utm_campaign=upgrade' ), 33 esc_html__( 'Upgrade to Pro', 'wooreports' ) 34 ); 35 array_unshift( $links, $upgrade_link ); 36 return $links; 37 } ); 38 39 if ( ! class_exists( 'WooReports' ) ) { 40 include_once dirname( __FILE__ ) . '/includes/class-wooreports.php'; 15 41 } 16 17 // Define WCRL_PLUGIN_FILE. 18 if (!defined('WCRL_PLUGIN_FILE') ) { 19 define( 'WCRL_PLUGIN_FILE', __FILE__ ); 20 } 21 22 // Include the main wcrl class. 23 if(!class_exists('WCRL')) { 24 include_once dirname(__FILE__).'/includes/class-wcrl.php'; 25 } 26 27 /** 28 * Plugin action links 29 * 30 * @param $links 31 * 32 * @return array 33 */ 34 add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'wcrl_plugin_action_links'); 35 function wcrl_plugin_action_links( $links ) { 36 $nurl = get_locale() === WCRL_FARSILANG ? 'https://nikanwp.ir/product/woocommerce-reporting/' : 'https://nikanwp.com/woocommerce-reporting/'; 37 $links[] = '<a href="'.$nurl.'" style="color: #389e38;font-weight: bold;" target="_blank">' . __( 'Get Pro', 'wc-reports-lite' ) . '</a>'; 38 return $links; 39 } 40 41 WCRL::getInstance(); 42 WooReports::getInstance();
Note: See TracChangeset
for help on using the changeset viewer.