Changeset 3464401
- Timestamp:
- 02/18/2026 02:19:24 PM (4 days ago)
- Location:
- spider-elements/trunk
- Files:
-
- 5 added
- 24 edited
-
assets/css/admin.css (modified) (10 diffs)
-
assets/css/admin.css.map (modified) (1 diff)
-
assets/css/main.css (modified) (2 diffs)
-
assets/images/dashboard/antimanual-logo.png (added)
-
assets/images/dashboard/jobus-logo.png (added)
-
assets/js/admin.js (modified) (18 diffs)
-
assets/scss/admin.scss (modified) (1 diff)
-
assets/scss/admin/_dashboard-enhanced.scss (added)
-
assets/scss/admin/_elements.scss (modified) (5 diffs)
-
assets/scss/admin/_framework.scss (modified) (1 diff)
-
assets/scss/admin/_welcome.scss (modified) (2 diffs)
-
assets/scss/frontend/_Cheat_sheet.scss (modified) (2 diffs)
-
changelogt.txt (added)
-
includes/Admin/Assets.php (modified) (1 diff)
-
includes/Admin/Dashboard.php (modified) (8 diffs)
-
includes/Admin/Plugin_Installer.php (modified) (12 diffs)
-
includes/Admin/dashboard/elements.php (modified) (4 diffs)
-
includes/Admin/dashboard/features.php (modified) (7 diffs)
-
includes/Admin/dashboard/integration.php (modified) (5 diffs)
-
includes/Admin/dashboard/popup-pro.php (modified) (2 diffs)
-
includes/Admin/dashboard/sidebar.php (modified) (5 diffs)
-
includes/Admin/dashboard/welcome.php (modified) (3 diffs)
-
includes/Frontend/Assets.php (modified) (2 diffs)
-
includes/filters.php (modified) (6 diffs)
-
includes/freemius/assets/img/spider-elements.png (added)
-
includes/functions.php (modified) (14 diffs)
-
readme.txt (modified) (8 diffs)
-
spider-elements.php (modified) (7 diffs)
-
widgets/templates/video-playlist/video-playlist-1.php (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
spider-elements/trunk/assets/css/admin.css
r3316325 r3464401 30 30 .ezd-grid-cols-12 { 31 31 grid-template-columns: repeat(12, minmax(0, 1fr)); 32 width: 100%; 32 33 } 33 34 … … 360 361 justify-content: center; 361 362 margin-bottom: 20px; 362 }363 .spel_dashboard .tab_contents .tab-box .support_item .dashboard_title {364 margin-bottom: 15px;365 363 } 366 364 .spel_dashboard .tab_contents .tab-box .support_item p { … … 408 406 .spel_dashboard .tab_contents .dashboard_btn.save_btn { 409 407 color: #fff; 410 background: #6d27e5 ;408 background: #6d27e5 !important; 411 409 padding: 12px 24px; 412 410 } … … 714 712 } 715 713 } 716 .spel_dashboard {717 /*============ qa_inner css ===============*/718 }719 714 .spel_dashboard .tab_contents .elements_tab_menu { 720 715 display: flex; … … 856 851 display: inline-block; 857 852 line-height: 1; 853 position: relative; 858 854 } 859 855 .spel_dashboard .tab_contents .element_box .element_right .link { … … 863 859 transition: all 0.3s linear; 864 860 } 865 .spel_dashboard .tab_contents .element_box .element_right .link .tooltip-top { 866 position: relative; 861 .spel_dashboard .tab_contents .element_box .element_right .link a.tooltip-top { 867 862 display: inline-block; 868 863 text-decoration: none; 869 864 } 870 .spel_dashboard .tab_contents .element_box .element_right .link .tooltip-top::before {865 .spel_dashboard .tab_contents .element_box .element_right .link a.tooltip-top::before { 871 866 content: attr(data-tooltip); 872 top: -40px; 873 left: -20px; 867 position: absolute; 868 bottom: 100%; 869 left: 50%; 874 870 transform: translateX(-50%); 875 871 background-color: #333; … … 877 873 text-align: center; 878 874 border-radius: 6px; 879 padding: 8px 8px;875 padding: 6px 10px; 880 876 opacity: 0; 881 877 visibility: hidden; 882 878 transition: opacity 0.2s; 883 position: absolute; 884 width: 190px; 885 } 886 .spel_dashboard .tab_contents .element_box .element_right .link .tooltip-top:hover::before { 879 width: max-content; 880 max-width: 200px; 881 font-size: 11px; 882 line-height: 1.4; 883 z-index: 100; 884 white-space: nowrap; 885 margin-bottom: 2px; 886 } 887 .spel_dashboard .tab_contents .element_box .element_right .link a.tooltip-top:hover::before { 887 888 opacity: 1; 888 889 visibility: visible; … … 897 898 align-items: center; 898 899 position: relative; 899 overflow: hidden;900 900 } 901 901 .spel_dashboard .tab_contents .filter_content .element_switch .badge { … … 1181 1181 transform: translate(-50%, -50%) scale(1.02); 1182 1182 } 1183 .spel_dashboard { 1184 /*============ qa_inner css ===============*/ 1185 } 1183 1186 .spel_dashboard .qa_inner { 1184 1187 border-radius: 12px; … … 1402 1405 } 1403 1406 1407 /** 1408 * Spider Elements Dashboard - Enhanced Styles 1409 * Modern UI/UX improvements with animations and better visual hierarchy 1410 */ 1411 :root { 1412 --spel-primary: #7460ff; 1413 --spel-primary-light: #9d70ff; 1414 --spel-primary-dark: #5a4ad9; 1415 --spel-secondary: #6d27e5; 1416 --spel-success: #22c55e; 1417 --spel-success-light: #dcfce7b5; 1418 --spel-warning: #f59e0b; 1419 --spel-warning-light: #fef3c7; 1420 --spel-error: #ef4444; 1421 --spel-error-light: #fee2e2; 1422 --spel-info: #3b82f6; 1423 --spel-info-light: #dbeafe; 1424 --spel-bg-primary: #f8fafc; 1425 --spel-bg-secondary: #fff; 1426 --spel-bg-tertiary: #f1f5f9; 1427 --spel-text-primary: #0f172a; 1428 --spel-text-secondary: #475569; 1429 --spel-text-muted: #94a3b8; 1430 --spel-border: #e2e8f0; 1431 --spel-border-light: #f1f5f9; 1432 --spel-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); 1433 --spel-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 1434 0 1px 2px -1px rgba(0, 0, 0, 0.1); 1435 --spel-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 1436 0 2px 4px -2px rgba(0, 0, 0, 0.1); 1437 --spel-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 1438 0 4px 6px -4px rgba(0, 0, 0, 0.1); 1439 --spel-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 1440 0 8px 10px -6px rgba(0, 0, 0, 0.1); 1441 --spel-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1); 1442 --spel-transition: 200ms cubic-bezier(0.4, 0, 0.2, 1); 1443 --spel-transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1); 1444 --spel-radius-sm: 6px; 1445 --spel-radius: 8px; 1446 --spel-radius-md: 12px; 1447 --spel-radius-lg: 16px; 1448 --spel-radius-xl: 24px; 1449 } 1450 1451 .spel_dashboard { 1452 background: var(--spel-bg-primary); 1453 min-height: calc(100vh - 32px); 1454 position: relative; 1455 } 1456 .spel_dashboard::before { 1457 content: ""; 1458 position: absolute; 1459 top: 0; 1460 left: 0; 1461 right: 0; 1462 height: 300px; 1463 background: linear-gradient(135deg, var(--spel-primary) 0%, var(--spel-primary-light) 50%, #c084fc 100%); 1464 opacity: 0.05; 1465 pointer-events: none; 1466 } 1467 1468 .spel_dashboard .sidebar_navigation .sticky_sidebar { 1469 background: var(--spel-bg-secondary); 1470 border-radius: var(--spel-radius-lg); 1471 box-shadow: var(--spel-shadow-md); 1472 overflow: hidden; 1473 border: 1px solid var(--spel-border-light); 1474 } 1475 .spel_dashboard .sidebar_navigation .tab_left_content { 1476 padding: 8px; 1477 margin: 0; 1478 } 1479 .spel_dashboard .sidebar_navigation .tab_left_content li { 1480 margin-bottom: 4px; 1481 } 1482 .spel_dashboard .sidebar_navigation .tab_left_content li:last-child { 1483 margin-bottom: 0; 1484 } 1485 .spel_dashboard .sidebar_navigation .tab_left_content li .icon { 1486 width: 40px; 1487 height: 40px; 1488 border-radius: var(--spel-radius); 1489 transition: all var(--spel-transition); 1490 box-shadow: var(--spel-shadow-sm); 1491 } 1492 .spel_dashboard .sidebar_navigation .tab_left_content li .icon i { 1493 font-size: 18px; 1494 transition: transform var(--spel-transition); 1495 } 1496 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link { 1497 border-radius: var(--spel-radius); 1498 overflow: hidden; 1499 position: relative; 1500 box-shadow: none; 1501 } 1502 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link::before { 1503 content: ""; 1504 position: absolute; 1505 left: 0; 1506 top: 50%; 1507 transform: translateY(-50%); 1508 width: 3px; 1509 height: 0; 1510 background: linear-gradient(180deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%); 1511 border-radius: 0 3px 3px 0; 1512 transition: height var(--spel-transition); 1513 } 1514 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link:hover .tab_menu_contents { 1515 background: linear-gradient(90deg, rgba(116, 96, 255, 0.08) 0%, rgba(157, 112, 255, 0.04) 100%); 1516 } 1517 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link:hover .icon { 1518 transform: scale(1.05); 1519 } 1520 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link:hover .icon i { 1521 transform: scale(1.1); 1522 } 1523 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link .tab_menu_contents { 1524 padding: 16px 20px; 1525 transition: all var(--spel-transition); 1526 border-radius: var(--spel-radius); 1527 } 1528 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link .tab_menu_contents .content h3 { 1529 font-size: 15px; 1530 font-weight: 600; 1531 color: var(--spel-text-primary); 1532 margin-bottom: 2px; 1533 transition: color var(--spel-transition); 1534 } 1535 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link .tab_menu_contents .content p { 1536 font-size: 13px; 1537 color: var(--spel-text-secondary); 1538 transition: color var(--spel-transition); 1539 } 1540 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active { 1541 background: linear-gradient(90deg, rgba(116, 96, 255, 0.08) 0%, rgba(157, 112, 255, 0.02) 100%); 1542 } 1543 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active::before { 1544 height: 60%; 1545 } 1546 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents { 1547 background: transparent; 1548 box-shadow: none; 1549 } 1550 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents .icon { 1551 background: linear-gradient(135deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%) !important; 1552 box-shadow: var(--spel-shadow-md); 1553 } 1554 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents .icon i { 1555 color: #fff; 1556 } 1557 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents .content h3 { 1558 color: var(--spel-primary) !important; 1559 } 1560 .spel_dashboard .sidebar_navigation .tab_left_content .tab-menu-link.active .tab_menu_contents .content p { 1561 color: var(--spel-text-secondary) !important; 1562 } 1563 1564 .spel_dashboard .tab_contents { 1565 position: relative; 1566 } 1567 .spel_dashboard .tab_contents .tab-box { 1568 animation: fadeIn var(--spel-transition-slow) ease-out; 1569 } 1570 @keyframes fadeIn { 1571 from { 1572 opacity: 0; 1573 transform: translateY(10px); 1574 } 1575 to { 1576 opacity: 1; 1577 transform: translateY(0); 1578 } 1579 } 1580 .spel_dashboard .tab_contents .dashboard_banner { 1581 position: relative; 1582 overflow: hidden; 1583 border-radius: var(--spel-radius-lg); 1584 padding: 50px 60px; 1585 background: linear-gradient(135deg, var(--spel-primary) 0%, var(--spel-primary-light) 50%, #a78bfa 100%); 1586 box-shadow: var(--spel-shadow-xl); 1587 display: flex; 1588 align-items: center; 1589 justify-content: space-between; 1590 gap: 40px; 1591 } 1592 .spel_dashboard .tab_contents .dashboard_banner::before { 1593 content: ""; 1594 position: absolute; 1595 top: -50%; 1596 right: -20%; 1597 width: 500px; 1598 height: 500px; 1599 background: radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 70%); 1600 animation: floatBubble 15s infinite ease-in-out; 1601 } 1602 .spel_dashboard .tab_contents .dashboard_banner::after { 1603 content: ""; 1604 position: absolute; 1605 bottom: -30%; 1606 left: -10%; 1607 width: 400px; 1608 height: 400px; 1609 background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 60%); 1610 animation: floatBubble 20s infinite ease-in-out reverse; 1611 } 1612 @keyframes floatBubble { 1613 0%, 100% { 1614 transform: translate(0, 0) scale(1); 1615 } 1616 50% { 1617 transform: translate(30px, -30px) scale(1.1); 1618 } 1619 } 1620 .spel_dashboard .tab_contents .dashboard_banner .banner_content { 1621 position: relative; 1622 z-index: 2; 1623 flex: 1; 1624 padding-right: 40px; 1625 } 1626 .spel_dashboard .tab_contents .dashboard_banner .version_badge { 1627 display: inline-flex; 1628 align-items: center; 1629 gap: 6px; 1630 padding: 6px 14px; 1631 background: rgba(255, 255, 255, 0.2); 1632 backdrop-filter: blur(8px); 1633 border-radius: 50px; 1634 font-size: 12px; 1635 font-weight: 600; 1636 color: #fff; 1637 margin-bottom: 16px; 1638 border: 1px solid rgba(255, 255, 255, 0.2); 1639 } 1640 .spel_dashboard .tab_contents .dashboard_banner .version_badge i { 1641 font-size: 14px; 1642 } 1643 .spel_dashboard .tab_contents .dashboard_banner h2 { 1644 font-size: 32px; 1645 font-weight: 700; 1646 color: #fff; 1647 margin-bottom: 12px; 1648 text-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); 1649 } 1650 .spel_dashboard .tab_contents .dashboard_banner p { 1651 font-size: 15px; 1652 color: rgba(255, 255, 255, 0.9); 1653 max-width: 600px; 1654 line-height: 1.7; 1655 } 1656 .spel_dashboard .tab_contents .dashboard_banner img { 1657 filter: drop-shadow(0 4px 20px rgba(0, 0, 0, 0.2)); 1658 transition: transform var(--spel-transition); 1659 max-width: 280px; 1660 height: auto; 1661 object-fit: contain; 1662 flex-shrink: 0; 1663 } 1664 .spel_dashboard .tab_contents .dashboard_banner img:hover { 1665 transform: scale(1.02); 1666 } 1667 .spel_dashboard .tab_contents .quick_stats { 1668 display: grid; 1669 grid-template-columns: repeat(4, 1fr); 1670 gap: 20px; 1671 margin-top: 24px; 1672 margin-bottom: 24px; 1673 } 1674 @media (max-width: 1200px) { 1675 .spel_dashboard .tab_contents .quick_stats { 1676 grid-template-columns: repeat(2, 1fr); 1677 } 1678 } 1679 @media (max-width: 768px) { 1680 .spel_dashboard .tab_contents .quick_stats { 1681 grid-template-columns: 1fr; 1682 } 1683 } 1684 .spel_dashboard .tab_contents .stat_card { 1685 background: var(--spel-bg-secondary); 1686 border-radius: var(--spel-radius-md); 1687 padding: 24px; 1688 box-shadow: var(--spel-shadow); 1689 border: 1px solid var(--spel-border-light); 1690 transition: all var(--spel-transition); 1691 position: relative; 1692 overflow: hidden; 1693 } 1694 .spel_dashboard .tab_contents .stat_card::before { 1695 content: ""; 1696 position: absolute; 1697 top: 0; 1698 left: 0; 1699 width: 4px; 1700 height: 100%; 1701 border-radius: 4px 0 0 4px; 1702 transition: width var(--spel-transition); 1703 } 1704 .spel_dashboard .tab_contents .stat_card:hover { 1705 transform: translateY(-2px); 1706 box-shadow: var(--spel-shadow-lg); 1707 } 1708 .spel_dashboard .tab_contents .stat_card:hover::before { 1709 width: 100%; 1710 opacity: 0.1; 1711 } 1712 .spel_dashboard .tab_contents .stat_card:hover .stat_icon { 1713 transform: scale(1.1) rotate(5deg); 1714 } 1715 .spel_dashboard .tab_contents .stat_card:hover .stat_icon { 1716 transform: scale(1.1); 1717 } 1718 .spel_dashboard .tab_contents .stat_card.stat_elements::before { 1719 background: linear-gradient(180deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%); 1720 } 1721 .spel_dashboard .tab_contents .stat_card.stat_features::before { 1722 background: linear-gradient(180deg, var(--spel-success) 0%, #34d399 100%); 1723 } 1724 .spel_dashboard .tab_contents .stat_card.stat_active::before { 1725 background: linear-gradient(180deg, var(--spel-info) 0%, #60a5fa 100%); 1726 } 1727 .spel_dashboard .tab_contents .stat_card.stat_pro::before { 1728 background: linear-gradient(180deg, #ec4899 0%, #f472b6 100%); 1729 } 1730 .spel_dashboard .tab_contents .stat_card .stat_header { 1731 display: flex; 1732 align-items: center; 1733 justify-content: space-between; 1734 margin-bottom: 16px; 1735 } 1736 .spel_dashboard .tab_contents .stat_card .stat_icon { 1737 width: 48px; 1738 height: 48px; 1739 border-radius: var(--spel-radius); 1740 display: flex; 1741 align-items: center; 1742 justify-content: center; 1743 font-size: 22px; 1744 transition: transform var(--spel-transition); 1745 } 1746 .spel_dashboard .tab_contents .stat_card.stat_elements .stat_icon { 1747 background: linear-gradient(135deg, rgba(116, 96, 255, 0.12) 0%, rgba(157, 112, 255, 0.08) 100%); 1748 color: var(--spel-primary); 1749 } 1750 .spel_dashboard .tab_contents .stat_card.stat_features .stat_icon { 1751 background: linear-gradient(135deg, rgba(34, 197, 94, 0.12) 0%, rgba(52, 211, 153, 0.08) 100%); 1752 color: var(--spel-success); 1753 } 1754 .spel_dashboard .tab_contents .stat_card.stat_active .stat_icon { 1755 background: linear-gradient(135deg, rgba(59, 130, 246, 0.12) 0%, rgba(96, 165, 250, 0.08) 100%); 1756 color: var(--spel-info); 1757 } 1758 .spel_dashboard .tab_contents .stat_card.stat_pro .stat_icon { 1759 background: linear-gradient(135deg, rgba(236, 72, 153, 0.12) 0%, rgba(244, 114, 182, 0.08) 100%); 1760 color: #ec4899; 1761 } 1762 .spel_dashboard .tab_contents .stat_card .stat_value { 1763 font-size: 32px; 1764 font-weight: 700; 1765 color: var(--spel-text-primary); 1766 font-family: "Roboto", sans-serif; 1767 line-height: 1; 1768 } 1769 .spel_dashboard .tab_contents .stat_card .stat_label { 1770 font-size: 13px; 1771 color: var(--spel-text-secondary); 1772 margin-top: 4px; 1773 font-weight: 500; 1774 } 1775 .spel_dashboard .tab_contents .stat_card .stat_trend { 1776 display: inline-flex; 1777 align-items: center; 1778 gap: 4px; 1779 font-size: 12px; 1780 font-weight: 600; 1781 padding: 4px 8px; 1782 border-radius: 50px; 1783 } 1784 .spel_dashboard .tab_contents .stat_card .stat_trend.trend_up { 1785 color: var(--spel-success); 1786 background: var(--spel-success-light); 1787 } 1788 .spel_dashboard .tab_contents .stat_card .stat_trend.trend_info { 1789 color: var(--spel-info); 1790 background: var(--spel-info-light); 1791 } 1792 .spel_dashboard .tab_contents .support_item { 1793 background: var(--spel-bg-secondary); 1794 border-radius: var(--spel-radius-md); 1795 padding: 32px; 1796 border: 1px solid var(--spel-border-light); 1797 box-shadow: var(--spel-shadow); 1798 transition: all var(--spel-transition); 1799 display: flex; 1800 flex-direction: column; 1801 align-items: flex-start; 1802 } 1803 .spel_dashboard .tab_contents .support_item:hover { 1804 box-shadow: var(--spel-shadow-lg); 1805 transform: translateY(-2px); 1806 border-color: rgba(116, 96, 255, 0.2); 1807 } 1808 .spel_dashboard .tab_contents .support_item:hover .icon { 1809 transform: scale(1.1) rotate(-5deg); 1810 } 1811 .spel_dashboard .tab_contents .support_item .icon { 1812 width: 60px; 1813 height: 60px; 1814 background: linear-gradient(135deg, rgba(116, 96, 255, 0.12) 0%, rgba(157, 112, 255, 0.08) 100%); 1815 border-radius: var(--spel-radius-md); 1816 font-size: 26px; 1817 color: var(--spel-primary); 1818 display: flex; 1819 align-items: center; 1820 justify-content: center; 1821 margin-bottom: 20px; 1822 transition: transform var(--spel-transition); 1823 } 1824 .spel_dashboard .tab_contents .support_item .dashboard_title { 1825 font-size: 20px; 1826 font-weight: 600; 1827 color: var(--spel-text-primary); 1828 margin-bottom: 0; 1829 } 1830 .spel_dashboard .tab_contents .support_item p { 1831 font-size: 14px; 1832 color: var(--spel-text-secondary); 1833 line-height: 1.7; 1834 margin-bottom: 20px; 1835 } 1836 .spel_dashboard .tab_contents .quick_links_grid { 1837 margin-top: 30px; 1838 } 1839 .spel_dashboard .tab_contents .quick_links_grid .ezd-lg-col-6 { 1840 margin-bottom: 24px; 1841 } 1842 .spel_dashboard .tab_contents .section_header.has_flex { 1843 display: flex; 1844 align-items: center; 1845 justify-content: space-between; 1846 margin-bottom: 25px; 1847 gap: 10px; 1848 } 1849 .spel_dashboard .tab_contents .badge_success { 1850 display: inline-flex; 1851 align-items: center; 1852 gap: 6px; 1853 padding: 6px 14px; 1854 border-radius: 50px; 1855 font-size: 12px; 1856 font-weight: 600; 1857 background: var(--spel-success-light); 1858 color: var(--spel-success); 1859 border: 1px solid rgba(34, 197, 94, 0.2); 1860 } 1861 .spel_dashboard .tab_contents .badge_success i { 1862 font-size: 14px; 1863 } 1864 .spel_dashboard .tab_contents .note { 1865 margin-top: 24px; 1866 padding: 16px 20px; 1867 background: rgba(59, 130, 246, 0.08); 1868 border-radius: var(--spel-radius); 1869 border: 1px solid rgba(59, 130, 246, 0.2); 1870 display: flex; 1871 gap: 16px; 1872 align-items: flex-start; 1873 } 1874 .spel_dashboard .tab_contents .note i { 1875 font-size: 20px; 1876 color: var(--spel-info); 1877 flex-shrink: 0; 1878 margin-top: 2px; 1879 } 1880 .spel_dashboard .tab_contents .note p { 1881 margin: 0; 1882 font-size: 14px; 1883 color: var(--spel-text-secondary); 1884 line-height: 1.6; 1885 } 1886 .spel_dashboard .tab_contents .requirement_list { 1887 border-radius: var(--spel-radius); 1888 overflow: hidden; 1889 border: 1px solid var(--spel-border-light); 1890 } 1891 .spel_dashboard .tab_contents .requirement_list li { 1892 background: var(--spel-bg-secondary); 1893 padding: 18px 24px; 1894 border-bottom: 1px solid var(--spel-border-light); 1895 display: flex; 1896 align-items: center; 1897 transition: background var(--spel-transition); 1898 } 1899 .spel_dashboard .tab_contents .requirement_list li:nth-child(odd) { 1900 background: rgba(241, 245, 249, 0.7); 1901 } 1902 .spel_dashboard .tab_contents .requirement_list li:last-child { 1903 border-bottom: none; 1904 } 1905 .spel_dashboard .tab_contents .requirement_list li:hover { 1906 background: var(--spel-bg-tertiary); 1907 } 1908 .spel_dashboard .tab_contents .requirement_list li strong { 1909 font-size: 14px; 1910 font-weight: 600; 1911 color: var(--spel-text-primary); 1912 flex: 0 0 50%; 1913 } 1914 .spel_dashboard .tab_contents .requirement_list li span { 1915 font-size: 14px; 1916 color: var(--spel-text-secondary); 1917 display: flex; 1918 align-items: center; 1919 gap: 12px; 1920 font-weight: 500; 1921 } 1922 .spel_dashboard .tab_contents .requirement_list li span.valid i { 1923 background: var(--spel-success); 1924 box-shadow: 0 2px 4px rgba(34, 197, 94, 0.4); 1925 transform: scale(1.1); 1926 } 1927 .spel_dashboard .tab_contents .requirement_list li span.invalid i { 1928 background: var(--spel-error); 1929 box-shadow: 0 2px 4px rgba(239, 68, 68, 0.4); 1930 } 1931 .spel_dashboard .tab_contents .requirement_list li i { 1932 font-size: 10px; 1933 width: 24px; 1934 height: 24px; 1935 display: inline-flex; 1936 align-items: center; 1937 justify-content: center; 1938 border-radius: 50%; 1939 color: #fff; 1940 transition: transform var(--spel-transition); 1941 } 1942 .spel_dashboard .tab_contents .dashboard_btn { 1943 display: inline-flex; 1944 align-items: center; 1945 justify-content: center; 1946 gap: 8px; 1947 padding: 12px 24px; 1948 font-size: 14px; 1949 font-weight: 600; 1950 color: var(--spel-primary); 1951 background: transparent; 1952 border: 2px solid var(--spel-primary); 1953 border-radius: var(--spel-radius); 1954 text-decoration: none; 1955 cursor: pointer; 1956 transition: all var(--spel-transition); 1957 position: relative; 1958 overflow: hidden; 1959 } 1960 .spel_dashboard .tab_contents .dashboard_btn::before { 1961 content: ""; 1962 position: absolute; 1963 top: 0; 1964 left: 0; 1965 width: 100%; 1966 height: 100%; 1967 background: linear-gradient(90deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%); 1968 opacity: 0; 1969 transition: opacity var(--spel-transition); 1970 z-index: -1; 1971 } 1972 .spel_dashboard .tab_contents .dashboard_btn:hover { 1973 color: #fff; 1974 color: #fff; 1975 border-color: var(--spel-primary); 1976 transform: translateY(-2px); 1977 box-shadow: 0 4px 15px rgba(116, 96, 255, 0.35); 1978 } 1979 .spel_dashboard .tab_contents .dashboard_btn:hover::before { 1980 opacity: 1; 1981 } 1982 .spel_dashboard .tab_contents .dashboard_btn:hover i { 1983 transform: translateX(3px); 1984 } 1985 .spel_dashboard .tab_contents .dashboard_btn i { 1986 transition: transform var(--spel-transition); 1987 } 1988 .spel_dashboard .tab_contents .dashboard_btn.save_btn { 1989 color: #fff; 1990 background: linear-gradient(90deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%); 1991 border: none; 1992 padding: 14px 28px; 1993 box-shadow: 0 2px 8px rgba(116, 96, 255, 0.25); 1994 } 1995 .spel_dashboard .tab_contents .dashboard_btn.save_btn:hover { 1996 box-shadow: 0 6px 20px rgba(116, 96, 255, 0.4); 1997 transform: translateY(-2px); 1998 } 1999 .spel_dashboard .tab_contents .dashboard_btn.save_btn.save-now { 2000 animation: pulse 1.5s infinite; 2001 } 2002 @keyframes pulse { 2003 0%, 100% { 2004 box-shadow: 0 2px 8px rgba(116, 96, 255, 0.25); 2005 } 2006 50% { 2007 box-shadow: 0 2px 20px rgba(116, 96, 255, 0.5); 2008 } 2009 } 2010 .spel_dashboard .tab_contents .dashboard_btn.activated { 2011 background: var(--spel-success-light); 2012 color: var(--spel-success); 2013 border-color: var(--spel-success-light); 2014 pointer-events: none; 2015 } 2016 .spel_dashboard .tab_contents .dashboard_btn.activated::before { 2017 display: none; 2018 } 2019 .spel_dashboard .tab_contents .elements_tab_menu { 2020 background: var(--spel-bg-secondary); 2021 border-radius: var(--spel-radius-md); 2022 padding: 20px 24px; 2023 box-shadow: var(--spel-shadow); 2024 border: 1px solid var(--spel-border-light); 2025 margin-bottom: 0; 2026 } 2027 .spel_dashboard .tab_contents .elements_tab_menu .tab_contents .icon { 2028 width: 44px; 2029 height: 44px; 2030 border-radius: var(--spel-radius); 2031 font-size: 20px; 2032 } 2033 .spel_dashboard .tab_contents .elements_tab_menu .tab_contents .content h3 { 2034 font-size: 18px; 2035 font-weight: 700; 2036 color: var(--spel-text-primary); 2037 } 2038 .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content { 2039 gap: 20px; 2040 } 2041 .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher { 2042 background: var(--spel-bg-tertiary); 2043 padding: 8px 16px; 2044 border-radius: var(--spel-radius); 2045 } 2046 .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher .toggler { 2047 font-size: 13px; 2048 font-weight: 500; 2049 color: var(--spel-text-secondary); 2050 transition: color var(--spel-transition); 2051 line-height: 2; 2052 } 2053 .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher .toggler:hover { 2054 color: var(--spel-text-primary); 2055 } 2056 .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher .switch { 2057 width: 44px; 2058 height: 24px; 2059 background: var(--spel-text-muted); 2060 border-radius: 50px; 2061 margin: 0 16px; 2062 } 2063 .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher .switch::before { 2064 width: 18px; 2065 height: 18px; 2066 border-radius: 50%; 2067 left: 3px; 2068 top: 3px; 2069 box-shadow: var(--spel-shadow-sm); 2070 } 2071 .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher input:checked + .switch { 2072 background: linear-gradient(90deg, var(--spel-success) 0%, #34d399 100%); 2073 } 2074 .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content .plugin_active_switcher input:checked + .switch::before { 2075 transform: translateX(20px); 2076 } 2077 .spel_dashboard .tab_contents .elements_tab { 2078 background: var(--spel-bg-secondary); 2079 padding: 12px 16px; 2080 border-radius: var(--spel-radius); 2081 margin: 20px 0; 2082 display: flex; 2083 gap: 8px; 2084 box-shadow: var(--spel-shadow-sm); 2085 border: 1px solid var(--spel-border-light); 2086 } 2087 .spel_dashboard .tab_contents .elements_tab .filter_data { 2088 padding: 10px 20px; 2089 font-size: 14px; 2090 font-weight: 500; 2091 color: var(--spel-text-secondary); 2092 border-radius: var(--spel-radius-sm); 2093 cursor: pointer; 2094 transition: all var(--spel-transition); 2095 display: flex; 2096 align-items: center; 2097 gap: 8px; 2098 } 2099 .spel_dashboard .tab_contents .elements_tab .filter_data i { 2100 font-size: 14px; 2101 transition: transform var(--spel-transition); 2102 } 2103 .spel_dashboard .tab_contents .elements_tab .filter_data:hover { 2104 background: var(--spel-bg-tertiary); 2105 color: var(--spel-text-primary); 2106 } 2107 .spel_dashboard .tab_contents .elements_tab .filter_data:hover i { 2108 transform: scale(1.15); 2109 } 2110 .spel_dashboard .tab_contents .elements_tab .filter_data.active { 2111 background: linear-gradient(90deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%); 2112 color: #fff; 2113 box-shadow: 0 2px 8px rgba(116, 96, 255, 0.25); 2114 } 2115 .spel_dashboard .tab_contents .spel_search_box { 2116 background: var(--spel-bg-secondary); 2117 padding: 16px 20px; 2118 border-radius: var(--spel-radius); 2119 margin-bottom: 20px; 2120 box-shadow: var(--spel-shadow-sm); 2121 border: 1px solid var(--spel-border-light); 2122 display: flex; 2123 align-items: center; 2124 gap: 12px; 2125 margin-top: 5px; 2126 } 2127 .spel_dashboard .tab_contents .spel_search_box .search_icon { 2128 color: var(--spel-text-muted); 2129 font-size: 18px; 2130 } 2131 .spel_dashboard .tab_contents .spel_search_box input { 2132 flex: 1; 2133 border: none; 2134 background: transparent; 2135 font-size: 14px; 2136 color: var(--spel-text-primary); 2137 outline: none; 2138 } 2139 .spel_dashboard .tab_contents .spel_search_box input::placeholder { 2140 color: var(--spel-text-muted); 2141 } 2142 .spel_dashboard .tab_contents .spel_search_box .search_count { 2143 font-size: 13px; 2144 color: var(--spel-text-muted); 2145 padding: 4px 10px; 2146 background: var(--spel-bg-tertiary); 2147 border-radius: var(--spel-radius-sm); 2148 } 2149 .spel_dashboard .tab_contents .element_box { 2150 background: var(--spel-bg-secondary); 2151 border-radius: var(--spel-radius-md); 2152 padding: 26px; 2153 box-shadow: var(--spel-shadow); 2154 border: 1px solid var(--spel-border-light); 2155 transition: all var(--spel-transition); 2156 position: relative; 2157 overflow: hidden; 2158 } 2159 .spel_dashboard .tab_contents .element_box::before { 2160 content: ""; 2161 position: absolute; 2162 top: 0; 2163 left: 0; 2164 right: 0; 2165 height: 3px; 2166 background: linear-gradient(90deg, var(--spel-primary) 0%, var(--spel-primary-light) 100%); 2167 opacity: 0; 2168 transition: opacity var(--spel-transition); 2169 } 2170 .spel_dashboard .tab_contents .element_box:hover { 2171 transform: translateY(-3px); 2172 box-shadow: var(--spel-shadow-lg); 2173 border-color: rgba(116, 96, 255, 0.2); 2174 } 2175 .spel_dashboard .tab_contents .element_box:hover::before { 2176 opacity: 1; 2177 } 2178 .spel_dashboard .tab_contents .element_box:hover .element_content i { 2179 transform: scale(1.15); 2180 color: var(--spel-primary); 2181 } 2182 .spel_dashboard .tab_contents .element_box:hover .element_right .link { 2183 opacity: 1; 2184 visibility: visible; 2185 transform: translateX(0); 2186 } 2187 .spel_dashboard .tab_contents .element_box .element_content i { 2188 font-size: 28px; 2189 color: var(--spel-text-primary); 2190 margin-right: 16px; 2191 transition: all var(--spel-transition); 2192 } 2193 .spel_dashboard .tab_contents .element_box .element_content label { 2194 font-size: 14px; 2195 font-weight: 500; 2196 color: var(--spel-text-primary); 2197 } 2198 .spel_dashboard .tab_contents .element_box .element_right .link { 2199 opacity: 0; 2200 visibility: hidden; 2201 transform: translateX(-5px); 2202 transition: all var(--spel-transition); 2203 display: flex; 2204 gap: 8px; 2205 } 2206 .spel_dashboard .tab_contents .element_box .element_right .link a { 2207 width: 28px; 2208 height: 28px; 2209 display: flex !important; 2210 align-items: center; 2211 justify-content: center; 2212 background: var(--spel-bg-tertiary); 2213 border-radius: var(--spel-radius-sm); 2214 transition: all var(--spel-transition); 2215 } 2216 .spel_dashboard .tab_contents .element_box .element_right .link a:hover { 2217 background: var(--spel-primary); 2218 } 2219 .spel_dashboard .tab_contents .element_box .element_right .link a:hover img { 2220 filter: brightness(0) invert(1); 2221 } 2222 .spel_dashboard .tab_contents .element_box .element_right .link a img { 2223 width: 14px; 2224 height: 14px; 2225 transition: filter var(--spel-transition); 2226 } 2227 .spel_dashboard .tab_contents .element_box .element_right .switch_label { 2228 cursor: pointer; 2229 } 2230 .spel_dashboard .tab_contents .element_box .element_right .switch_label .widget_switcher { 2231 width: 44px; 2232 height: 24px; 2233 background: var(--spel-text-muted); 2234 border-radius: 50px; 2235 position: relative; 2236 transition: background var(--spel-transition); 2237 } 2238 .spel_dashboard .tab_contents .element_box .element_right .switch_label .widget_switcher::before { 2239 width: 18px; 2240 height: 18px; 2241 border-radius: 50%; 2242 left: 3px; 2243 top: 3px; 2244 box-shadow: var(--spel-shadow-sm); 2245 transition: transform var(--spel-transition); 2246 } 2247 .spel_dashboard .tab_contents .element_box .element_right .switch_label input:checked + .widget_switcher { 2248 background: linear-gradient(90deg, var(--spel-success) 0%, #34d399 100%); 2249 } 2250 .spel_dashboard .tab_contents .element_box .element_right .switch_label input:checked + .widget_switcher::before { 2251 transform: translateX(20px); 2252 } 2253 .spel_dashboard .tab_contents .element_box .element_right .switch_label input:disabled + .widget_switcher { 2254 opacity: 0.5; 2255 cursor: not-allowed; 2256 } 2257 .spel_dashboard .tab_contents .filter_content .pro .badge::before { 2258 width: 70px; 2259 height: 70px; 2260 left: -38px; 2261 top: -38px; 2262 font-size: 9px; 2263 font-weight: 700; 2264 background: linear-gradient(135deg, #ec4899 0%, #f472b6 100%); 2265 letter-spacing: 0.5px; 2266 } 2267 .spel_dashboard .tab_contents .integration_banner { 2268 background: linear-gradient(135deg, var(--spel-primary) 0%, var(--spel-primary-light) 50%, #a78bfa 100%) !important; 2269 padding: 45px 50px !important; 2270 border-radius: var(--spel-radius-lg) !important; 2271 } 2272 .spel_dashboard .tab_contents .integration_banner h2 { 2273 font-size: 28px !important; 2274 font-weight: 700 !important; 2275 } 2276 .spel_dashboard .tab_contents .integration_banner p { 2277 font-size: 15px !important; 2278 max-width: 700px; 2279 } 2280 .spel_dashboard .tab_contents .integration_item { 2281 background: var(--spel-bg-secondary); 2282 border-radius: var(--spel-radius-md); 2283 padding: 32px; 2284 box-shadow: var(--spel-shadow); 2285 border: 1px solid var(--spel-border-light); 2286 transition: all var(--spel-transition); 2287 } 2288 .spel_dashboard .tab_contents .integration_item:hover { 2289 transform: translateY(-4px); 2290 box-shadow: var(--spel-shadow-lg); 2291 border-color: rgba(116, 96, 255, 0.2); 2292 } 2293 .spel_dashboard .tab_contents .integration_item:hover img { 2294 transform: scale(1.1); 2295 } 2296 .spel_dashboard .tab_contents .integration_item img { 2297 width: 52px; 2298 height: auto; 2299 transition: transform var(--spel-transition); 2300 } 2301 .spel_dashboard .tab_contents .integration_item h3 { 2302 font-size: 17px; 2303 font-weight: 600; 2304 color: var(--spel-text-primary); 2305 margin-top: 16px; 2306 margin-bottom: 10px; 2307 } 2308 .spel_dashboard .tab_contents .integration_item p { 2309 font-size: 14px; 2310 color: var(--spel-text-secondary); 2311 line-height: 1.65; 2312 min-height: 50px; 2313 } 2314 .spel_dashboard .tab_contents .integration_item .action_buttons { 2315 display: flex; 2316 gap: 10px; 2317 justify-content: center; 2318 align-items: center; 2319 margin-top: 20px; 2320 } 2321 .spel_dashboard .tab_contents .integration_item .action_buttons .dashboard_btn { 2322 width: 100%; 2323 } 2324 .spel_dashboard .tab_contents .integration_item .action_buttons .dashboard_btn.learn_more_btn { 2325 background: var(--spel-bg-tertiary); 2326 color: var(--spel-text-secondary); 2327 border: 1px solid var(--spel-border-light); 2328 } 2329 .spel_dashboard .tab_contents .integration_item .action_buttons .dashboard_btn.learn_more_btn:hover { 2330 background: var(--spel-bg-primary); 2331 color: #fff; 2332 border-color: var(--spel-border); 2333 } 2334 .spel_dashboard .tab_contents .note { 2335 background: linear-gradient(135deg, rgba(116, 96, 255, 0.08) 0%, rgba(157, 112, 255, 0.04) 100%); 2336 border: 1px solid rgba(116, 96, 255, 0.1); 2337 padding: 16px 24px; 2338 margin-top: 20px; 2339 border-radius: var(--spel-radius); 2340 display: flex; 2341 align-items: flex-start; 2342 gap: 12px; 2343 } 2344 .spel_dashboard .tab_contents .note::before { 2345 content: "\f05a"; 2346 font-family: "Font Awesome 6 Pro", "Font Awesome 5 Free", sans-serif; 2347 font-weight: 900; 2348 color: var(--spel-primary); 2349 font-size: 18px; 2350 margin-top: 2px; 2351 } 2352 .spel_dashboard .tab_contents .note p { 2353 font-size: 13px !important; 2354 color: var(--spel-text-secondary) !important; 2355 line-height: 1.6 !important; 2356 margin: 0 !important; 2357 } 2358 .spel_dashboard .tab_contents .elements_pro_popup .message_content { 2359 border-radius: var(--spel-radius-lg); 2360 padding: 48px 40px; 2361 max-width: 420px; 2362 box-shadow: var(--spel-shadow-xl); 2363 } 2364 .spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-close { 2365 position: absolute; 2366 right: 16px; 2367 top: 16px; 2368 width: 32px; 2369 height: 32px; 2370 background: var(--spel-bg-tertiary); 2371 border-radius: 50%; 2372 display: flex; 2373 align-items: center; 2374 justify-content: center; 2375 cursor: pointer; 2376 transition: all var(--spel-transition); 2377 } 2378 .spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-close:hover { 2379 background: var(--spel-error-light); 2380 } 2381 .spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-close img { 2382 width: 12px; 2383 opacity: 0.7; 2384 } 2385 .spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-icon { 2386 width: 72px; 2387 height: 72px; 2388 background: linear-gradient(135deg, rgba(236, 72, 153, 0.1) 0%, rgba(244, 114, 182, 0.05) 100%); 2389 border-radius: 50%; 2390 display: flex; 2391 align-items: center; 2392 justify-content: center; 2393 margin: 0 auto 20px; 2394 } 2395 .spel_dashboard .tab_contents .elements_pro_popup .message_content .pro-icon img { 2396 width: 36px; 2397 } 2398 .spel_dashboard .tab_contents .elements_pro_popup .message_content h3 { 2399 font-size: 24px; 2400 font-weight: 700; 2401 color: var(--spel-text-primary); 2402 margin-bottom: 10px; 2403 } 2404 .spel_dashboard .tab_contents .elements_pro_popup .message_content p { 2405 font-size: 15px; 2406 color: var(--spel-text-secondary); 2407 line-height: 1.6; 2408 } 2409 .spel_dashboard .tab_contents .elements_pro_popup .message_content .dashboard_btn { 2410 margin-top: 16px; 2411 background: linear-gradient(90deg, #ec4899 0%, #f472b6 100%); 2412 border: none; 2413 color: #fff; 2414 } 2415 .spel_dashboard .tab_contents .elements_pro_popup .message_content .dashboard_btn:hover { 2416 box-shadow: 0 6px 20px rgba(236, 72, 153, 0.4); 2417 } 2418 2419 .spel_toast { 2420 position: fixed; 2421 bottom: 24px; 2422 right: 24px; 2423 background: var(--spel-bg-secondary); 2424 padding: 16px 24px; 2425 border-radius: var(--spel-radius); 2426 box-shadow: var(--spel-shadow-xl); 2427 display: flex; 2428 align-items: center; 2429 gap: 12px; 2430 z-index: 9999; 2431 transform: translateY(100px); 2432 opacity: 0; 2433 transition: all var(--spel-transition-slow); 2434 border-left: 4px solid var(--spel-success); 2435 } 2436 .spel_toast.show { 2437 transform: translateY(0); 2438 opacity: 1; 2439 } 2440 .spel_toast.toast_error { 2441 border-left-color: var(--spel-error); 2442 } 2443 .spel_toast.toast_error .toast_icon { 2444 background: var(--spel-error-light); 2445 color: var(--spel-error); 2446 } 2447 .spel_toast .toast_icon { 2448 width: 36px; 2449 height: 36px; 2450 background: var(--spel-success-light); 2451 color: var(--spel-success); 2452 border-radius: var(--spel-radius-sm); 2453 display: flex; 2454 align-items: center; 2455 justify-content: center; 2456 font-size: 18px; 2457 } 2458 .spel_toast .toast_content h4 { 2459 font-size: 14px; 2460 font-weight: 600; 2461 color: var(--spel-text-primary); 2462 margin: 0 0 2px; 2463 } 2464 .spel_toast .toast_content p { 2465 font-size: 13px; 2466 color: var(--spel-text-secondary); 2467 margin: 0; 2468 } 2469 .spel_toast .toast_close { 2470 margin-left: 16px; 2471 cursor: pointer; 2472 color: var(--spel-text-muted); 2473 transition: color var(--spel-transition); 2474 } 2475 .spel_toast .toast_close:hover { 2476 color: var(--spel-text-primary); 2477 } 2478 2479 @media (max-width: 1400px) { 2480 .spel_dashboard .tab_contents .dashboard_banner { 2481 padding: 40px; 2482 } 2483 .spel_dashboard .tab_contents .dashboard_banner h2 { 2484 font-size: 28px; 2485 } 2486 .spel_dashboard .tab_contents .stat_card { 2487 padding: 20px; 2488 } 2489 .spel_dashboard .tab_contents .stat_card .stat_value { 2490 font-size: 28px; 2491 } 2492 } 2493 @media (max-width: 1200px) { 2494 .spel_dashboard .tab_contents .quick_stats { 2495 grid-template-columns: repeat(2, 1fr); 2496 } 2497 } 2498 @media (max-width: 768px) { 2499 .spel_dashboard .tab_contents .quick_stats { 2500 grid-template-columns: 1fr; 2501 } 2502 .spel_dashboard .tab_contents .elements_tab_menu { 2503 flex-direction: column; 2504 gap: 16px; 2505 } 2506 .spel_dashboard .tab_contents .elements_tab_menu .menu_right_content { 2507 width: 100%; 2508 justify-content: space-between; 2509 } 2510 .spel_dashboard .tab_contents .elements_tab { 2511 flex-wrap: wrap; 2512 } 2513 } 2514 1404 2515 /*# sourceMappingURL=admin.css.map */ -
spider-elements/trunk/assets/css/admin.css.map
r3258212 r3464401 1 {"version":3,"sourceRoot":"","sources":["../scss/admin.scss","../scss/admin/_notice.scss","../scss/admin/_framework.scss","../scss/admin/_welcome.scss","../scss/admin/_elements.scss","../scss/admin/_theme_builder.scss" ],"names":[],"mappings":"AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;ACAA;EACE;;AACA;EACE;EACA;EACA;;AAEE;EACE;;AAIF;EACE;EACA;;;ACKR;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAGJ;EACE;;;AAEF;EACE;EACA;EACA;;;AChNF;EACE;EACA;EACA;EACA;;AACA;EALF;IAMI;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EAVF;IAWI;;;AAGF;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKN;EACE;;AAGI;EACI;;AAIR;EACE;EACA;EACA;EACA;;AACA;EALF;IAMI;;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA,aD5GR;EC6GQ;;AAGF;EACE;EACA,aDnHN;ECoHM;EACA;EACA;EACA;EACA;;AACA;EARF;IASI;;;AAON;EACE;;AACA;EACE;EACA;;AAIA;EACE;;AASd;EACE;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA,aDxLF;ECyLE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,aD9MJ;EC+MI;;AAUE;EACE;EACA;;AASZ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EACE;;AAIJ;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA,aD9QF;EC+QE;EACA;;AAGF;EACE,aDrRA;ECsRA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA,aDxSF;ECySE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA,aDpTJ;ECqTI;EACA;;AAEA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA,aD5VJ;EC6VI;EACA;EACA;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA,aDlXA;ECmXA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA,aDnZA;ECoZA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAMF;EACE;EACA,aDpaF;ECqaE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGE;EACE;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,aDtfJ;ECufI;EACA;EACA;;AAGF;EACE;EACA;EACA,aDhgBF;ECigBE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAUV;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;ACzlBJ;AA0iBE;;AAviBE;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA,aFlCN;EEmCM;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA,aF7DJ;EE8DI;EACA;;AACA;EACE;;AAGF;EACE;;AAGE;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMR;EACE;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA,aF7HF;EE8HE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGE;EACE;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAOV;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aFxOJ;EEyOI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA,aFxPJ;EEyPI;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAGE;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AASV;EACE;;AAEA;EACE;EACA;EACA;EACA,aF9UA;EE+UA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA,aF1VE;EE2VF;;AAKE;EACE;EACA;EACA;EACA;EACA,aFpWJ;EEqWI;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA,aF/WJ;EEgXI;EACA;EACA;EACA;;AFjXR;EEmXU;;AFhXV;EEgXU;;AF7WV;EE6WU;;AF1WV;EE0WU;;AAGF;EACE;;AAKN;EACE;EACA,aFjYA;EEkYA;EACA;EACA;;AAGF;EACE;;AAKN;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA,aF7ZA;EE8ZA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA,aFzaE;EE0aF;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAMR;EACE;;AAIF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,aF3cA;EE4cA;;AAGF;EACE;EACA;EACA;EACA,aFpdE;EEqdF;;AAGF;EACE;EACA;EACA;EACA,aF5dE;EE6dF;;AAEA;EACE;EACA;;AAIA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAQR;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA,aFxjBA;EEyjBA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAIJ;AAAA;AAAA;AAAA;EAIE;EACA;;;AAKJ;EACE;;;AAGF;AACA;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AC5mBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAMA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAEA;EACE","file":"admin.css"}1 {"version":3,"sourceRoot":"","sources":["../scss/admin.scss","../scss/admin/_notice.scss","../scss/admin/_framework.scss","../scss/admin/_welcome.scss","../scss/admin/_elements.scss","../scss/admin/_theme_builder.scss","../scss/admin/_dashboard-enhanced.scss"],"names":[],"mappings":"AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;ACAA;EACE;;AACA;EACE;EACA;EACA;;AAEE;EACE;;AAIF;EACE;EACA;;;ACKR;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;EAEF;IACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAGJ;EACE;;;AAEF;EACE;EACA;EACA;;;ACjNF;EACE;EACA;EACA;EACA;;AACA;EALF;IAMI;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EAVF;IAWI;;;AAGF;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKN;EACE;;AAGI;EACI;;AAIR;EACE;EACA;EACA;EACA;;AACA;EALF;IAMI;;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA,aD5GR;EC6GQ;;AAGF;EACE;EACA,aDnHN;ECoHM;EACA;EACA;EACA;EACA;;AACA;EARF;IASI;;;AAON;EACE;;AACA;EACE;EACA;;AAIA;EACE;;AASd;EACE;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA,aDpLF;ECqLE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,aD1MJ;EC2MI;;AAUE;EACE;EACA;;AASZ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EACE;;AAIJ;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA,aD1QF;EC2QE;EACA;;AAGF;EACE,aDjRA;ECkRA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA,aDpSF;ECqSE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA,aDhTJ;ECiTI;EACA;;AAEA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA,aDxVJ;ECyVI;EACA;EACA;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA,aD9WA;EC+WA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA,aD/YA;ECgZA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAMF;EACE;EACA,aDhaF;ECiaE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGE;EACE;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,aDlfJ;ECmfI;EACA;EACA;;AAGF;EACE;EACA;EACA,aD5fF;EC6fE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAUV;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;ACllBA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;EACA,aFlCN;EEmCM;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA,aF7DJ;EE8DI;EACA;;AACA;EACE;;AAGF;EACE;;AAGE;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMR;EACE;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA,aF7HF;EE8HE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGE;EACE;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAOV;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aF7OJ;EE8OI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA,aF7PJ;EE8PI;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAGE;EACE;;AAEA;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AASV;EACE;;AAEA;EACE;EACA;EACA;EACA,aFnVA;EEoVA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA,aF/VE;EEgWF;;AAKE;EACE;EACA;EACA;EACA;EACA,aFzWJ;EE0WI;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA,aFpXJ;EEqXI;EACA;EACA;EACA;;AFtXR;EEwXU;;AFrXV;EEqXU;;AFlXV;EEkXU;;AF/WV;EE+WU;;AAGF;EACE;;AAKN;EACE;EACA,aFtYA;EEuYA;EACA;EACA;;AAGF;EACE;;AAKN;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA,aFlaA;EEmaA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA,aF9aE;EE+aF;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAMR;EACE;;AAIF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,aFhdA;EEidA;;AAGF;EACE;EACA;EACA;EACA,aFzdE;EE0dF;;AAGF;EACE;EACA;EACA;EACA,aFjeE;EEkeF;;AAEA;EACE;EACA;;AAIA;EACE;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAxiBV;AA+iBE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA,aF7jBA;EE8jBA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAIJ;AAAA;AAAA;AAAA;EAIE;EACA;;;AAKJ;EACE;;;AAGF;AACA;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;AAIJ;EACE;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;;ACjnBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAMA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;;;ACrLhB;AAAA;AAAA;AAAA;AAMA;EAEE;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;AAAA;EAEA;AAAA;EAEA;AAAA;EAEA;AAAA;EAIA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAMA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;EACA;;AAIA;EACE;;AAOF;EACE;;AAEA;EACE;;AAKN;EACE;EACA;EACA;;AAGE;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKN;EACE;;AAMA;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EAKA;;AACA;EACE;;AAIJ;EACG;;AAEH;EACE;;;AASZ;EACE;;AAGA;EACE;;AAGF;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EAMA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;;AAGF;EACE;IAEE;;EAEF;IACE;;;AAKJ;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;EAPF;IAQI;;;AAGF;EAXF;IAYI;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;;AAMF;EACE;;AAEF;EACE;;AAEF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EAKA;;AAEF;EACE;EAKA;;AAEF;EACE;EAKA;;AAEF;EACE;EAKA;;AAGF;EACE;EACA;EACA;EACA,aJ9dA;EI+dA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;;AAOA;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EAKA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAIJ;EACE;;AAEA;EACI;;AAKN;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAIN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIN;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACG;;AAGH;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;EAKA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;IAEE;;EAEF;IACE;;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAMA;EACE;;AAQV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EAKA;EACA;;AAMN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAKA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAKN;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAMA;EACE;;AAIJ;EACE;EACA;;AAOR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EAMA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAQV;EACE;EAKA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAMF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EAKA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAQV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAMN;EAGM;IACE;;EAEA;IACE;;EAIJ;IACE;;EAEA;IACE;;;AAOV;EAGM;IACE;;;AAMR;EAGM;IACE;;EAGF;IACE;IACA;;EAEA;IACE;IACA;;EAIJ;IACE","file":"admin.css"} -
spider-elements/trunk/assets/css/main.css
r3416399 r3464401 8256 8256 margin-bottom: 30px; 8257 8257 background: transparent; 8258 color: rgb(29, 39, 70);8258 color: var(--black_900); 8259 8259 text-decoration: none; 8260 8260 margin-left: 8px; … … 8282 8282 margin-bottom: 0; 8283 8283 transition: all 0.3s linear; 8284 background: #ffffff;8284 background: var(--bs-white); 8285 8285 box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); 8286 8286 } -
spider-elements/trunk/assets/js/admin.js
r3416399 r3464401 2 2 3 3 "use strict"; 4 5 // ===== Toast Notification System ===== 6 window.SpelToast = { 7 show: function (title, message, type = 'success') { 8 // Remove existing toasts 9 $('.spel_toast').remove(); 10 11 const iconClass = type === 'success' ? 'icon-check' : 'icon-close'; 12 const toast = $(` 13 <div class="spel_toast ${type === 'error' ? 'toast_error' : ''}"> 14 <span class="toast_icon"><i class="${iconClass}"></i></span> 15 <div class="toast_content"> 16 <h4>${title}</h4> 17 <p>${message}</p> 18 </div> 19 <span class="toast_close"><i class="icon-close"></i></span> 20 </div> 21 `); 22 23 $('body').append(toast); 24 25 // Show toast 26 setTimeout(() => toast.addClass('show'), 100); 27 28 // Auto-hide after 4 seconds 29 setTimeout(() => { 30 toast.removeClass('show'); 31 setTimeout(() => toast.remove(), 300); 32 }, 4000); 33 34 // Close button 35 toast.find('.toast_close').on('click', function () { 36 toast.removeClass('show'); 37 setTimeout(() => toast.remove(), 300); 38 }); 39 } 40 }; 41 42 // ===== Search Functionality ===== 43 function initSearchFunctionality() { 44 // Widget Search 45 $('#spel_widget_search').on('input', function () { 46 const searchTerm = $(this).val().toLowerCase().trim(); 47 const $items = $('#elements_list .ezd-colum-space-4'); 48 let visibleCount = 0; 49 50 $items.each(function () { 51 const widgetName = $(this).data('widget-name') || ''; 52 const isMatch = widgetName.includes(searchTerm); 53 54 if (isMatch || searchTerm === '') { 55 $(this).show().css('opacity', '1'); 56 visibleCount++; 57 } else { 58 $(this).hide().css('opacity', '0'); 59 } 60 }); 61 62 // Update count 63 const totalWidgets = $items.length; 64 const countText = searchTerm 65 ? `${visibleCount} of ${totalWidgets} widgets` 66 : `${totalWidgets} widgets`; 67 $('#spel_search_count').text(countText); 68 69 // Re-apply isotope layout 70 $('#elements_list').isotope('layout'); 71 }); 72 73 // Feature Search 74 $('#spel_feature_search').on('input', function () { 75 const searchTerm = $(this).val().toLowerCase().trim(); 76 const $items = $('#features_gallery .ezd-colum-space-4'); 77 let visibleCount = 0; 78 79 $items.each(function () { 80 const featureName = $(this).data('feature-name') || ''; 81 const isMatch = featureName.includes(searchTerm); 82 83 if (isMatch || searchTerm === '') { 84 $(this).show().css('opacity', '1'); 85 visibleCount++; 86 } else { 87 $(this).hide().css('opacity', '0'); 88 } 89 }); 90 91 // Update count 92 const totalFeatures = $items.length; 93 const countText = searchTerm 94 ? `${visibleCount} of ${totalFeatures} features` 95 : `${totalFeatures} features`; 96 $('#spel_feature_search_count').text(countText); 97 98 // Re-apply isotope layout 99 $('#features_gallery').isotope('layout'); 100 }); 101 } 4 102 5 103 // Remove svg.radial-progress .complete inline styling … … 70 168 71 169 if (featureDisable && featureEnable && featureSwitcher) { 72 console.log('Feature switcher found.');73 170 featureDisable.addEventListener("click", function () { 74 171 featureSwitcher.checked = false; … … 87 184 featureDisable.classList.toggle("toggler--is-active"); 88 185 }); 89 } else {90 console.log('Feature switcher not found.');91 186 } 92 187 … … 96 191 97 192 $(document).ready(function () { 193 194 // Initialize search functionality 195 initSearchFunctionality(); 98 196 99 197 // Map of tab content names to WordPress admin submenu page slugs … … 105 203 }; 106 204 205 // LocalStorage key for tab persistence 206 const STORAGE_KEY = 'spel_active_tab'; 207 107 208 // Function to update WordPress admin menu active state 108 209 function updateAdminMenuActiveState(tabName) { … … 117 218 } 118 219 220 // Function to save active tab to localStorage 221 function saveActiveTab(tabName) { 222 try { 223 localStorage.setItem(STORAGE_KEY, tabName); 224 } catch (e) { 225 console.warn('Spider Elements: Could not save tab state to localStorage', e); 226 } 227 } 228 229 // Function to get active tab from localStorage 230 function getActiveTab() { 231 try { 232 return localStorage.getItem(STORAGE_KEY); 233 } catch (e) { 234 console.warn('Spider Elements: Could not read tab state from localStorage', e); 235 return null; 236 } 237 } 238 119 239 // Set up event listener for tab click 120 240 $(".tab-menu li a").on("click", function () { … … 138 258 filterMasonryThree(); 139 259 140 // S et a cookie to remember the active button141 s etCookie('spe_settings_current_tab', tabName, 1);260 // Save active tab to localStorage for persistence after page refresh 261 saveActiveTab(tabName); 142 262 143 263 // Update WordPress admin menu active state … … 157 277 }); 158 278 159 // Function to set a cookie 160 function setCookie(name, value, days) { 161 let expires = ""; 162 if (days) { 163 let date = new Date(); 164 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 165 expires = "; expires=" + date.toUTCString(); 166 } 167 document.cookie = name + "=" + value + expires + "; path=/"; 168 } 169 170 // Function to get a cookie 171 function getCookie(name) { 172 let nameEQ = name + "="; 173 let ca = document.cookie.split(';'); 174 for (let i = 0; i < ca.length; i++) { 175 let c = ca[i]; 176 while (c.charAt(0) === ' ') c = c.substring(1, c.length); 177 if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); 178 } 179 return null; 180 } 181 182 // Remain the last active settings tab 279 // Remain the last active settings tab after page refresh 183 280 function spel_keep_settings_current_tab() { 184 // First priority: Check for active tab from URL (via data attribute set by server)281 // Check if we're on the Spider Elements dashboard page 185 282 let spelDashboard = $('#spel_settings'); 186 let activeButton = spelDashboard.data('active-tab'); 187 188 // Fallback to cookie if no data attribute (for in-page sidebar tab clicks) 189 if (!activeButton) { 190 activeButton = getCookie('spe_settings_current_tab'); 191 } 192 193 if (activeButton) { 194 // Update sidebar tab-menu active state 195 $('.tab-menu .tab-menu-link[data-content="' + activeButton + '"]').addClass('active'); 196 $('.tab-menu .tab-menu-link:not([data-content="' + activeButton + '"])').removeClass('active'); 197 198 // Update tab content active state 199 $('.tab_contents .tab-box').removeClass('active'); 200 $('.tab_contents .tab-box#' + activeButton).addClass('active'); 201 202 // Also sync WordPress admin menu active state 203 updateAdminMenuActiveState(activeButton); 204 } 283 if (!spelDashboard.length) { 284 return; 285 } 286 287 // Priority 1: Server-side data-active-tab (URL-based, from WordPress submenu navigation) 288 // This MUST take priority so that clicking a WordPress submenu always 289 // navigates to the correct tab, regardless of what localStorage says. 290 let serverTab = spelDashboard.data('active-tab'); 291 let activeTab = serverTab || 'welcome'; 292 293 // Clear localStorage to keep it in sync with the current submenu page. 294 // This prevents stale localStorage values from overriding the URL on 295 // subsequent page loads. 296 saveActiveTab(activeTab); 297 298 // Update sidebar tab-menu active state 299 $('.tab-menu .tab-menu-link').removeClass('active'); 300 $('.tab-menu .tab-menu-link[data-content="' + activeTab + '"]').addClass('active'); 301 302 // Update tab content active state 303 $('.tab_contents .tab-box').removeClass('active'); 304 $('.tab_contents .tab-box#' + activeTab).addClass('active'); 305 306 // Sync WordPress admin menu active state 307 updateAdminMenuActiveState(activeTab); 308 309 // Update hidden input field 310 $('#spel_active_tab').val(activeTab); 205 311 } 206 312 … … 220 326 itemSelector: ".ezd-colum-space-4", 221 327 filter: "*", 328 animationOptions: { 329 duration: 750, 330 easing: 'linear', 331 queue: false 332 } 222 333 }); 223 334 }); … … 235 346 $(this).addClass("active"); 236 347 348 // Clear search when filter is clicked 349 $('#spel_widget_search').val(''); 350 $('#elements_list .ezd-colum-space-4').show().css('opacity', '1'); 351 237 352 let selector = $(this).attr("data-filter"); 238 353 filter.isotope({ 239 354 filter: selector, 240 355 }); 356 357 // Update count 358 const visibleItems = selector === '*' 359 ? $('#elements_list .ezd-colum-space-4').length 360 : $('#elements_list .ezd-colum-space-4' + selector).length; 361 const totalItems = $('#elements_list .ezd-colum-space-4').length; 362 $('#spel_search_count').text(visibleItems + ' widgets'); 363 241 364 return false; 242 365 }); … … 289 412 itemSelector: ".ezd-colum-space-4", 290 413 filter: "*", 414 animationOptions: { 415 duration: 750, 416 easing: 'linear', 417 queue: false 418 } 291 419 }); 292 420 }); … … 298 426 filterMasonryThree(); 299 427 var filter = $("#features_gallery"); 300 // Add isotope click function 428 429 // Add isotope click function for features 301 430 $("#features_filter div").on("click", function () { 302 431 $("#features_filter div").removeClass("active"); 303 432 $(this).addClass("active"); 304 433 434 // Clear search when filter is clicked 435 $('#spel_feature_search').val(''); 436 $('#features_gallery .ezd-colum-space-4').show().css('opacity', '1'); 437 305 438 var selector = $(this).attr("data-filter"); 306 439 filter.isotope({ 307 440 filter: selector, 308 441 }); 442 443 // Update count 444 const visibleItems = selector === '*' 445 ? $('#features_gallery .ezd-colum-space-4').length 446 : $('#features_gallery .ezd-colum-space-4' + selector).length; 447 $('#spel_feature_search_count').text(visibleItems + ' features'); 448 309 449 return false; 310 450 }); … … 316 456 $(".pro-close").on("click", function (e) { 317 457 $("#elements_popup1").removeClass("popup-visible"); 458 }); 459 460 // Close popup on background click 461 $(".elements_pro_popup").on("click", function (e) { 462 if ($(e.target).hasClass('elements_pro_popup')) { 463 $(this).removeClass("popup-visible"); 464 } 465 }); 466 467 // Close popup on Escape key 468 $(document).on("keyup", function (e) { 469 if (e.key === "Escape") { 470 $(".elements_pro_popup").removeClass("popup-visible"); 471 } 318 472 }); 319 473 … … 339 493 // Check if the checkbox is checked 340 494 if ($(this).is(":checked")) { 341 $(".dashboard_btn ").addClass("save-now");495 $(".dashboard_btn.save_btn").addClass("save-now"); 342 496 } else { 343 $(".dashboard_btn ")497 $(".dashboard_btn.save_btn") 344 498 .removeClass("save-now") 345 499 .removeAttr("disabled") … … 360 514 }); 361 515 362 $(".dashboard_btn ")516 $(".dashboard_btn.save_btn") 363 517 .addClass("save-now") 364 518 .removeAttr("disabled") … … 369 523 let widgetSwitcher = $(".element_right .widget-list:checked"); 370 524 widgetSwitcher.on("click", function () { 371 $(".dashboard_btn ")525 $(".dashboard_btn.save_btn") 372 526 .addClass("save-now") 373 527 .removeAttr("disabled") … … 378 532 let elementsSettingBtn = $(".elements_tab_menu .menu_right_content .save_btn"); 379 533 elementsSettingBtn.on("click", function (event) { 380 // event.preventDefault();381 // alert('Saved Successfully');534 // Show toast on save (optional - form will submit normally) 535 // SpelToast.show('Settings Saved', 'Your settings have been saved successfully.'); 382 536 }); 383 537 } … … 385 539 elementsSaveNowButton(); 386 540 541 // ===== Keyboard Shortcuts ===== 542 $(document).on('keydown', function (e) { 543 // Only work on Spider Elements dashboard 544 if (!$('.spel_dashboard').length) return; 545 546 // Ctrl/Cmd + S to save 547 if ((e.ctrlKey || e.metaKey) && e.key === 's') { 548 e.preventDefault(); 549 $('.save_btn:visible').first().trigger('click'); 550 } 551 552 // Ctrl/Cmd + F to focus search 553 if ((e.ctrlKey || e.metaKey) && e.key === 'f') { 554 const $activeTab = $('.tab-box.active'); 555 const $searchInput = $activeTab.find('input[type="text"]').first(); 556 if ($searchInput.length) { 557 e.preventDefault(); 558 $searchInput.focus().select(); 559 } 560 } 561 }); 562 387 563 })(jQuery); -
spider-elements/trunk/assets/scss/admin.scss
r3316325 r3464401 12 12 @import "admin/elements"; 13 13 @import "admin/theme_builder"; 14 @import "admin/dashboard-enhanced"; -
spider-elements/trunk/assets/scss/admin/_elements.scss
r3316325 r3464401 173 173 display: inline-block; 174 174 line-height: 1; 175 position: relative; // Add for tooltip positioning 175 176 } 176 177 … … 181 182 transition: all 0.3s linear; 182 183 183 .tooltip-top { 184 position: relative; 184 a.tooltip-top { 185 185 display: inline-block; 186 186 text-decoration: none; … … 188 188 &::before { 189 189 content: attr(data-tooltip); 190 top: -40px; 191 left: -20px; 190 position: absolute; 191 bottom: 100%; 192 left: 50%; 192 193 transform: translateX(-50%); 193 194 background-color: #333; … … 195 196 text-align: center; 196 197 border-radius: 6px; 197 padding: 8px 8px;198 padding: 6px 10px; 198 199 opacity: 0; 199 200 visibility: hidden; 200 201 transition: opacity 0.2s; 201 position: absolute; 202 width: 190px; 202 width: max-content; 203 max-width: 200px; 204 font-size: 11px; 205 line-height: 1.4; 206 z-index: 100; 207 white-space: nowrap; 208 margin-bottom: 2px; 203 209 } 204 210 … … 221 227 align-items: center; 222 228 position: relative; 223 overflow: hidden;224 229 225 230 .badge { -
spider-elements/trunk/assets/scss/admin/_framework.scss
r3316325 r3464401 25 25 .ezd-grid-cols-12 { 26 26 grid-template-columns: repeat(12, minmax(0, 1fr)); 27 width: 100%; 27 28 } 28 29 -
spider-elements/trunk/assets/scss/admin/_welcome.scss
r3316325 r3464401 178 178 } 179 179 180 .dashboard_title {181 margin-bottom: 15px;182 }183 184 180 p { 185 181 font-size: 16px; … … 243 239 &.save_btn { 244 240 color: #fff; 245 background: #6d27e5 ;241 background: #6d27e5 !important; 246 242 padding: 12px 24px; 247 243 &:hover { -
spider-elements/trunk/assets/scss/frontend/_Cheat_sheet.scss
r3316325 r3464401 25 25 margin-bottom: 30px; 26 26 background: transparent; 27 color: rgb(29 39 70);27 color: var(--black_900); 28 28 text-decoration: none; 29 29 margin-left: 8px; … … 60 60 margin-bottom: 0; 61 61 transition: all 0.3s linear; 62 background: #ffffff;62 background: var(--bs-white); 63 63 box-shadow: 0 .125rem .25rem rgba(0,0,0,.075); 64 64 -
spider-elements/trunk/includes/Admin/Assets.php
r3416399 r3464401 46 46 // Register Admin Panel Style's 47 47 wp_enqueue_style( 'spel-icomoon', SPEL_VEND . '/icomoon/style.css', [], SPEL_VERSION ); 48 wp_enqueue_style( 'spel-font-awesome', SPEL_VEND . '/font-awesome/css/all.css', [], SPEL_VERSION ); 48 49 wp_enqueue_style( 'spel-fancybox', SPEL_VEND . '/fancybox/fancybox.min.css', [], SPEL_VERSION ); 49 50 -
spider-elements/trunk/includes/Admin/Dashboard.php
r3416399 r3464401 33 33 34 34 /** 35 * Hide all admin notices on Spider Elements pages. 36 * 35 37 * @return void 36 * Hide all admin notices on Spider Elements pages.37 38 */ 38 39 public function hide_admin_notices(): void { … … 49 50 50 51 /** 52 * Add menu page to the WordPress admin dashboard. 53 * 51 54 * @return void 52 * Add menu page to the WordPress admin dashboard.53 55 */ 54 56 public function add_menu_page(): void { … … 104 106 105 107 /** 108 * Get the active tab based on the current page URL. 109 * 106 110 * @return string 107 * Get the active tab based on the current page URL.108 111 */ 109 112 public function get_active_tab(): string { 110 113 $page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : 'spider_elements_settings'; 111 114 112 115 $tab_map = [ 113 116 'spider_elements_settings' => 'welcome', … … 122 125 123 126 /** 124 * @return void125 127 * Render the content of the menu page. 126 128 * This is where you would add your custom HTML 129 * 130 * @return void 127 131 */ 128 132 public function render_plugin_page(): void { 129 133 // Get the active tab based on which submenu was clicked 130 134 $active_tab = $this->get_active_tab(); 131 135 132 136 // Map tab names to submenu page slugs 133 137 $tab_to_page = [ … … 137 141 'integration' => 'spider_elements_integration', 138 142 ]; 139 143 140 144 // Get the page slug for the active tab 141 145 $current_page = $tab_to_page[ $active_tab ] ?? 'spider_elements_settings'; 142 $form_action = admin_url( 'admin.php?page=' . $current_page );146 $form_action = admin_url( 'admin.php?page=' . $current_page ); 143 147 144 148 echo '<form action="' . esc_url( $form_action ) . '" method="post" id="spel_settings" name="spel_settings" class="wrapper spel_dashboard" data-active-tab="' . esc_attr( $active_tab ) . '">'; 145 149 146 150 // Hidden field to track current active tab (updated by JavaScript) 147 151 echo '<input type="hidden" name="spel_active_tab" id="spel_active_tab" value="' . esc_attr( $active_tab ) . '">'; … … 150 154 echo '<div class="sidebar_navigation">'; 151 155 152 if ( file_exists( require_once__DIR__ . '/dashboard/sidebar.php' ) ) {156 if ( file_exists( __DIR__ . '/dashboard/sidebar.php' ) ) { 153 157 require_once __DIR__ . '/dashboard/sidebar.php'; 154 158 } … … 160 164 echo '<div class="tab_contents">'; 161 165 162 if ( file_exists( require_once__DIR__ . '/dashboard/welcome.php' ) ) {166 if ( file_exists( __DIR__ . '/dashboard/welcome.php' ) ) { 163 167 require_once __DIR__ . '/dashboard/welcome.php'; 164 168 } 165 169 166 if ( file_exists( require_once__DIR__ . '/dashboard/elements.php' ) ) {170 if ( file_exists( __DIR__ . '/dashboard/elements.php' ) ) { 167 171 require_once __DIR__ . '/dashboard/elements.php'; 168 172 } 169 173 170 if ( file_exists( require_once__DIR__ . '/dashboard/features.php' ) ) {174 if ( file_exists( __DIR__ . '/dashboard/features.php' ) ) { 171 175 require_once __DIR__ . '/dashboard/features.php'; 172 176 } 173 177 174 if ( file_exists( require_once__DIR__ . '/dashboard/integration.php' ) ) {178 if ( file_exists( __DIR__ . '/dashboard/integration.php' ) ) { 175 179 require_once __DIR__ . '/dashboard/integration.php'; 176 180 } 177 181 178 if ( file_exists( require_once__DIR__ . '/dashboard/popup-pro.php' ) ) {182 if ( file_exists( __DIR__ . '/dashboard/popup-pro.php' ) ) { 179 183 require_once __DIR__ . '/dashboard/popup-pro.php'; 180 184 } … … 188 192 189 193 /** 194 * Return the base64 encoded SVG icon. 195 * 190 196 * @return string 191 * Return the base64 encoded SVG icon.192 197 */ 193 198 public function icon(): string { -
spider-elements/trunk/includes/Admin/Plugin_Installer.php
r3316325 r3464401 13 13 { 14 14 private static $instance; 15 private $installed_plugins = [];16 15 private $activated_plugins = []; 16 private $initialized = false; 17 17 18 18 /** … … 36 36 public function __construct() 37 37 { 38 add_action('plugins_loaded', [$this, 'init']); 38 // If this class is instantiated after `plugins_loaded` has already fired, 39 // the hook would never run and status checks would always report 40 // "not_installed". So we initialize immediately when possible. 41 if ( \did_action( 'plugins_loaded' ) ) { 42 $this->init(); 43 } else { 44 \add_action( 'plugins_loaded', [ $this, 'init' ] ); 45 } 39 46 } 40 47 … … 44 51 public function init(): void 45 52 { 46 $this->collect_installed_plugins();47 53 $this->collect_activated_plugins(); 48 54 49 // Debugging statements 50 error_log('Installed Plugins: ' . print_r($this->installed_plugins, true)); 51 error_log('Activated Plugins: ' . print_r($this->activated_plugins, true)); 52 } 53 54 /** 55 * Collects the list of installed plugins 56 */ 57 private function collect_installed_plugins(): void 58 { 59 if (!function_exists('get_plugins')) { 60 require_once ABSPATH . 'wp-admin/includes/plugin.php'; 61 } 62 63 $this->installed_plugins = array_keys(get_plugins()); 64 65 // Debugging statement 66 error_log('Collecting Installed Plugins: ' . print_r($this->installed_plugins, true)); 55 $this->initialized = true; 67 56 } 68 57 … … 72 61 private function collect_activated_plugins(): void 73 62 { 74 $this->activated_plugins = get_option('active_plugins', []); 75 76 // Debugging statement 77 error_log('Collecting Activated Plugins: ' . print_r($this->activated_plugins, true)); 63 $this->activated_plugins = \get_option( 'active_plugins', [] ); 78 64 } 79 65 … … 87 73 public function check_installed_plugin(string $name): bool 88 74 { 89 return in_array($name, $this->installed_plugins); 75 if ( $this->check_activated_plugin( $name ) ) { 76 return true; 77 } 78 79 // Security: Prevent path traversal 80 if ( 0 !== validate_file( $name ) ) { 81 return false; 82 } 83 84 // Sentinel Fix: Use file check instead of heavy get_plugins() scan 85 return file_exists( WP_PLUGIN_DIR . '/' . $name ); 90 86 } 91 87 … … 99 95 public function check_activated_plugin(string $name): bool 100 96 { 101 return in_array( $name, $this->activated_plugins);97 return in_array( $name, $this->activated_plugins, true ); 102 98 } 103 99 … … 111 107 public function get_status(string $name): array 112 108 { 109 if ( ! $this->initialized ) { 110 $this->init(); 111 } 112 113 113 $data = array( 114 114 'url' => '', … … 121 121 if ($this->check_installed_plugin($name)) { 122 122 if ($this->check_activated_plugin($name)) { 123 $data['title'] = esc_html__('Activated', 'spider-elements');123 $data['title'] = \esc_html__( 'Activated', 'spider-elements' ); 124 124 $data['status'] = 'activated'; 125 125 } else { 126 $data['title'] = esc_html__('Activate Now', 'spider-elements');127 $data['status'] = 'in stalled';126 $data['title'] = \esc_html__( 'Activate', 'spider-elements' ); 127 $data['status'] = 'inactive'; 128 128 $data['activation_url'] = $this->activation_url($name); 129 129 } 130 130 } else { 131 $data['title'] = esc_html__('Install Now', 'spider-elements');131 $data['title'] = \esc_html__( 'Install Now', 'spider-elements' ); 132 132 $data['status'] = 'not_installed'; 133 133 $data['installation_url'] = $this->installation_url($name); … … 135 135 } 136 136 137 // Debug output138 error_log("Plugin: $name");139 error_log(print_r($data, true));140 141 137 return $data; 142 138 } … … 151 147 public function activation_url(string $pluginName): string 152 148 { 153 return wp_nonce_url(154 add_query_arg(149 return \wp_nonce_url( 150 \add_query_arg( 155 151 array( 156 152 'action' => 'activate', … … 159 155 'paged' => '1&s', 160 156 ), 161 admin_url('plugins.php')157 \admin_url( 'plugins.php' ) 162 158 ), 163 159 'activate-plugin_' . $pluginName … … 177 173 $pluginSlug = $this->get_plugin_slug($pluginName); 178 174 179 return wp_nonce_url(180 add_query_arg(175 return \wp_nonce_url( 176 \add_query_arg( 181 177 array( 182 178 'action' => $action, 183 179 'plugin' => $pluginSlug, 184 180 ), 185 admin_url('update.php')181 \admin_url( 'update.php' ) 186 182 ), 187 183 $action . '_' . $pluginSlug -
spider-elements/trunk/includes/Admin/dashboard/elements.php
r3416399 r3464401 11 11 $checked_global = ( ! isset( $element_opt['element_global_switcher'] ) || $element_opt['element_global_switcher'] === 'on' ) ? ' checked' : ''; 12 12 $docy_widget_list = [ 'docly_cheatsheet', 'spel_videos_playlist', 'docy_tabs', 'docly_alerts_box' ]; 13 14 // Count widgets for search placeholder 15 $total_widgets = isset( $elements['spider_elements_widgets'] ) ? count( $elements['spider_elements_widgets'] ) : 0; 13 16 ?> 14 17 <div id="elements" class="tab-box"> … … 30 33 <label class="b switch" for="element_switcher"></label> 31 34 </div> 32 <label class="toggler" id="element_enabled"><?php esc_html_e( 'Enable dAll', 'spider-elements' ); ?></label>35 <label class="toggler" id="element_enabled"><?php esc_html_e( 'Enable All', 'spider-elements' ); ?></label> 33 36 </div> 34 37 <button type="submit" name="elements-submit" id="elements-submit" class="dashboard_btn save_btn"> 38 <i class="icon-check"></i> 35 39 <?php esc_html_e( 'Save Changes', 'spider-elements' ); ?> 36 40 </button> 37 41 <?php wp_nonce_field( 'spel_elements_nonce', 'spel_elements_nonce' ); ?> 38 42 </div> 43 </div> 44 45 <!-- Search Box --> 46 <div class="spel_search_box"> 47 <span class="search_icon"><i class="icon-search"></i></span> 48 <input type="text" id="spel_widget_search" placeholder="<?php echo esc_attr( sprintf( __( 'Search %d widgets...', 'spider-elements' ), $total_widgets ) ); ?>"> 49 <span class="search_count" id="spel_search_count"><?php echo esc_html( $total_widgets ); ?> <?php esc_html_e( 'widgets', 'spider-elements' ); ?></span> 39 50 </div> 40 51 … … 58 69 $widget_type = $item['widget_type'] ?? ''; 59 70 $widget_name = $item['name'] ?? ''; 71 $widget_label = $item['label'] ?? ''; 60 72 $is_pro = $widget_type === 'pro'; 61 73 … … 73 85 } 74 86 ?> 75 <div class="ezd-colum-space-4 <?php echo esc_attr( $item['widget_type'] ) ?>" >87 <div class="ezd-colum-space-4 <?php echo esc_attr( $item['widget_type'] ) ?>" data-widget-name="<?php echo esc_attr( strtolower( $widget_label ) ); ?>"> 76 88 <div class="element_box element_switch badge"> 77 89 <div class="element_content"> -
spider-elements/trunk/includes/Admin/dashboard/features.php
r3416399 r3464401 10 10 // Global switcher 11 11 $opt = get_option( 'spel_features_settings' ); 12 $global_switcher = $opt['features_global_switcher'] ?? ''; 13 $is_checked = ! empty ( $global_switcher == 'on' ) ? ' checked' : ''; 14 $checked = ! isset ( $opt['features_global_switcher'] ) ? ' checked' : $is_checked; 12 $checked_global = ( ! isset( $opt['features_global_switcher'] ) || $opt['features_global_switcher'] === 'on' ) ? ' checked' : ''; 15 13 16 14 // Get the current theme 17 $theme = wp_get_theme(); 18 $theme = in_array( $theme->get( 'Name' ), [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ] ); 15 $theme_obj = wp_get_theme(); 16 $theme_name = $theme_obj->get( 'Name' ); 17 $is_jobi = in_array( $theme_name, [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ], true ); 18 $is_docy = spel_unlock_docy_theme(); 19 $is_docly = in_array( $theme_name, [ 'Docly', 'docly', 'Docly Child', 'docly-child' ], true ); 20 $is_ama = in_array( $theme_name, [ 'Ama', 'ama', 'Ama Child', 'ama-child' ], true ); 21 22 // Smooth Animation is unlocked for Docy, Jobi, Docly, or Ama theme users 23 $is_smooth_anim_unlocked = $is_docy || $is_jobi || $is_docly || $is_ama; 24 25 // Count features for search placeholder 26 $total_features = isset( $features['spider_elements_features'] ) ? count( $features['spider_elements_features'] ) : 0; 19 27 ?> 20 28 <div id="features" class="tab-box"> … … 34 42 <label class="toggler" id="features_disabled"><?php esc_html_e( 'Disable All', 'spider-elements' ); ?></label> 35 43 <div class="toggle"> 36 <input type="checkbox" data-id="widget-list" id="features_switcher" name="features_global_switcher" class="check features_global_switcher" >44 <input type="checkbox" data-id="widget-list" id="features_switcher" name="features_global_switcher" class="check features_global_switcher" <?php echo esc_attr( $checked_global ); ?>> 37 45 <label class="b switch" for="features_switcher"></label> 38 46 </div> 39 <label class="toggler" id="features_enabled"><?php esc_html_e( 'Enable dAll', 'spider-elements' ); ?></label>47 <label class="toggler" id="features_enabled"><?php esc_html_e( 'Enable All', 'spider-elements' ); ?></label> 40 48 </div> 41 49 <button type="submit" name="features-submit" id="features-submit" class="dashboard_btn save_btn"> 50 <i class="icon-check"></i> 42 51 <?php esc_html_e( 'Save Changes', 'spider-elements' ); ?> 43 52 </button> … … 47 56 </div> 48 57 49 <div class="elements_tab" id="elements_filter"> 58 <!-- Search Box --> 59 <div class="spel_search_box"> 60 <span class="search_icon"><i class="icon-search"></i></span> 61 <input type="text" id="spel_feature_search" placeholder="<?php echo esc_attr( sprintf( __( 'Search %d features...', 'spider-elements' ), $total_features ) ); ?>"> 62 <span class="search_count" id="spel_feature_search_count"><?php echo esc_html( $total_features ); ?> <?php esc_html_e( 'features', 'spider-elements' ); ?></span> 63 </div> 64 65 <div class="elements_tab" id="features_filter"> 50 66 <div class="filter_data active" data-filter="*"> 51 67 <i class="icon-star"></i> … … 69 85 $feature_type = $item['feature_type'] ?? ''; 70 86 $feature_name = $item['name'] ?? ''; 87 $feature_label = $item['label'] ?? ''; 71 88 72 89 // Default class and attributes for widgets … … 75 92 76 93 // Unlock specific features for Jobi theme users 77 if ( in_array( $item['name'], [ 'spel_badge', 'spel_heading_highlighted' ] ) && $theme|| spel_is_premium() ) {94 if ( ( in_array( $item['name'], [ 'spel_badge', 'spel_heading_highlighted' ], true ) && $is_jobi ) || spel_is_premium() ) { 78 95 $is_pro_feature = ''; // Remove pro_popup class 79 96 $is_pro_feature_enabled = ''; // Enable widget 80 97 } 81 98 82 // By default, only free features are checked 83 $opt_input = $opt[ $feature_name ] ?? ''; 84 if ( $feature_type === 'pro' && ! spel_is_premium() && ! ( in_array( $item['name'], [ 'spel_badge', 'spel_heading_highlighted' ] ) && $theme ) ) { 99 // Unlock Smooth Animation for Docy, Jobi, or Docly theme users 100 if ( $item['name'] === 'spel_smooth_animation' && $is_smooth_anim_unlocked ) { 101 $is_pro_feature = ''; // Remove pro_popup class 102 $is_pro_feature_enabled = ''; // Enable widget 103 } 104 105 // Determine if this feature is unlocked via theme 106 $is_jobi_unlocked = in_array( $item['name'], [ 'spel_badge', 'spel_heading_highlighted' ], true ) && $is_jobi; 107 $is_smooth_unlocked = $item['name'] === 'spel_smooth_animation' && $is_smooth_anim_unlocked; 108 109 if ( $feature_type === 'pro' && ! spel_is_premium() && ! $is_jobi_unlocked && ! $is_smooth_unlocked ) { 85 110 // Pro feature: unchecked by default 86 $checked = ! isset( $opt[ $feature_name ] ) ? '' : ( ! empty( $opt_input == 'on' )? ' checked' : '' );111 $checked = ! isset( $opt[ $feature_name ] ) ? '' : ( $opt[ $feature_name ] === 'on' ? ' checked' : '' ); 87 112 } else { 88 113 // Free feature or unlocked pro: checked by default 89 $is_checked = ! empty( $opt_input == 'on' ) ? ' checked' : ''; 90 $checked = ! isset( $opt[ $feature_name ] ) ? ' checked' : $is_checked; 114 $checked = ( ! isset( $opt[ $feature_name ] ) || $opt[ $feature_name ] === 'on' ) ? ' checked' : ''; 91 115 } 92 116 ?> 93 <div class="ezd-colum-space-4 <?php echo esc_attr( $item['feature_type'] ) ?>" >117 <div class="ezd-colum-space-4 <?php echo esc_attr( $item['feature_type'] ) ?>" data-feature-name="<?php echo esc_attr( strtolower( $feature_label ) ); ?>"> 94 118 <div class="element_box element_switch badge"> 95 119 <div class="element_content"> … … 100 124 } 101 125 if ( ! empty( $item['label'] ) ) { ?> 102 <label for=" elementor-video"><?php echo esc_html( $item['label'] ) ?></label>126 <label for="<?php echo esc_attr( $item['name'] ) ?>"><?php echo esc_html( $item['label'] ) ?></label> 103 127 <?php 104 128 } … … 119 143 <?php 120 144 } 121 if ( ! empty( $item[' demo_url'] ) ) {145 if ( ! empty( $item['video_url'] ) ) { 122 146 ?> 123 147 <a href="<?php echo esc_url( $item['video_url'] ) ?>" class="tooltip-top" data-tooltip="<?php echo esc_attr( sprintf( __( 'View %s Video Tutorial', 'spider-elements' ), $item['label'] ) ); ?>" -
spider-elements/trunk/includes/Admin/dashboard/integration.php
r3316325 r3464401 4 4 } 5 5 6 $integrations = [7 [6 $integrations = array( 7 array( 8 8 'slug' => 'bbp-core', 9 9 'basename' => 'bbp-core/bbp-core.php', 10 10 'logo' => SPEL_IMG . '/dashboard/bbp-core-logo.svg', 11 'title' => esc_html__( 'BBP Core', 'spider-elements' ), 12 'desc' => esc_html__( 'Expand bbPress powered forums with useful features like - private reply, solved topics ...', 'spider-elements' ), 13 ], 14 [ 11 'title' => esc_html__( 'Forumax', 'spider-elements' ), 12 'desc' => esc_html__( 'A complete, self-contained platform for building support forums, or discussion communities.', 'spider-elements' ), 13 'category' => 'community', 14 ), 15 array( 15 16 'slug' => 'eazydocs', 16 17 'basename' => 'eazydocs/eazydocs.php', … … 18 19 'title' => esc_html__( 'EazyDocs', 'spider-elements' ), 19 20 'desc' => esc_html__( 'A powerful & beautiful documentation, knowledge base builder plugin.', 'spider-elements' ), 20 ], 21 [ 21 'category' => 'documentation', 22 ), 23 array( 22 24 'slug' => 'changeloger', 23 25 'basename' => 'changeloger/changeloger.php', … … 25 27 'title' => esc_html__( 'Changeloger', 'spider-elements' ), 26 28 'desc' => esc_html__( 'Auto-convert plain text changelogs into engaging visuals for WordPress.', 'spider-elements' ), 27 ], 28 [ 29 'slug' => 'advanced-accordion-block', 30 'basename' => 'advanced-accordion-block/advanced-accordion-block.php', 31 'logo' => SPEL_IMG . '/dashboard/AAGB-logo.svg', 32 'title' => esc_html__( 'Advanced Accordion Block', 'spider-elements' ), 33 'desc' => esc_html__( 'A custom Gutenberg Block that allows to showcase the content in accordion mode. It also helps to build FAQ sections easily.', 34 'spider-elements' ), 35 ], 36 ]; 29 'category' => 'utility', 30 ), 31 array( 32 'slug' => 'advanced-accordion-block', 33 'basename' => 'advanced-accordion-block/advanced-accordion-block.php', 34 'logo' => SPEL_IMG . '/dashboard/AAGB-logo.svg', 35 'title' => esc_html__( 'Advanced Accordion Block', 'spider-elements' ), 36 'desc' => esc_html__( '#1 WordPress plugin for creating professional FAQ sections, expandable content accordions.', 'spider-elements' ), 37 'category' => 'gutenberg', 38 ), 39 array( 40 'slug' => 'antimanual', 41 'basename' => 'antimanual/antimanual.php', 42 'logo' => SPEL_IMG . '/dashboard/antimanual-logo.png', 43 'title' => esc_html__( 'Antimanual', 'spider-elements' ), 44 'desc' => esc_html__( 'The ultimate AI powerhouse for your website. Do automatically with AI instead of manually.', 'spider-elements' ), 45 'category' => 'ai', 46 ), 47 array( 48 'slug' => 'jobus', 49 'basename' => 'jobus/jobus.php', 50 'logo' => SPEL_IMG . '/dashboard/jobus-logo.png', 51 'title' => esc_html__( 'Jobus', 'spider-elements' ), 52 'desc' => esc_html__( 'A modern and powerful plugin designed to transform your website into a fully functional Job portal.', 'spider-elements' ), 53 'category' => 'community', 54 ), 55 ); 37 56 ?> 38 57 39 58 <div id="integration" class="tab-box"> 40 59 <div class="dashboard_banner integration_banner"> 41 <h2><?php esc_html_e( 'Elevate Your WordPress Website to the Next Level!', 'spider-elements' ); ?></h2> 42 <p><?php esc_html_e( 'Explore our versatile range of plugins tailored to meet every need for WordPress, Gutenberg, Elementor, and WooCommerce. Discover solutions that empower your site with enhanced functionality and seamless performance.', 'spider-elements' ); ?></p> 60 <div class="banner_content"> 61 <span class="version_badge"> 62 <i class="icon-star"></i> 63 <?php esc_html_e( 'Recommended Plugins', 'spider-elements' ); ?> 64 </span> 65 <h2><?php esc_html_e( 'Elevate Your WordPress Website to the Next Level!', 'spider-elements' ); ?></h2> 66 <p><?php esc_html_e( 'Explore our versatile range of plugins tailored to meet every need for WordPress, Gutenberg, Elementor, and WooCommerce. Discover solutions that empower your site with enhanced functionality and seamless performance.', 'spider-elements' ); ?></p> 67 </div> 43 68 </div> 44 <div class="ezd-grid ezd-grid-cols-12"> 69 70 <div class="ezd-grid ezd-grid-cols-12" style="margin-top: 24px;"> 45 71 <?php 46 72 if ( isset( $integrations ) && is_array( $integrations ) ) { … … 54 80 $plugin_status_label = isset( $plugin_data['status'] ) ? ( $plugin_data['status'] == 'activated' ? 'activated' : '' ) : ''; 55 81 $plugin_status_title = $plugin_data['title'] ?? esc_html__( 'Activate', 'spider-elements' ); 82 83 // Determine button icon based on status 84 $button_icon = 'icon-download'; 85 if ( $plugin_status === 'activated' ) { 86 $button_icon = 'icon-check'; 87 } elseif ( $plugin_status === 'inactive' ) { 88 $button_icon = 'icon-power'; 89 } 56 90 ?> 57 91 <div class="ezd-lg-col-4"> … … 61 95 <p><?php echo esc_html( $plugin['desc'] ); ?></p> 62 96 63 <?php 64 echo sprintf( 65 '<a data-plugin_status="%1$s" data-activation_url="%2$s" href="%3$s" class="dashboard_btn %4$s">%5$s</a>', 66 esc_attr( $plugin_status ), 67 esc_url( $plugin_activation_url ), 68 esc_url( $plugin_status === 'not_installed' ? $plugin_installation_url : $plugin_activation_url ), 69 esc_attr( $plugin_status_label ), 70 esc_html( $plugin_status_title ) 71 ); 72 ?> 97 <?php 98 if ( $plugin['slug'] === 'bbp-core' ) { 99 $wp_org_link = 'https://wordpress.org/plugins/forumax/'; 100 } elseif($plugin['slug'] === 'advanced-accordion-block') { 101 $wp_org_link = 'https://wordpress.org/plugins/advanced-accordion-block/'; 102 } else { 103 $wp_org_link = 'https://wordpress.org/plugins/' . $plugin['slug'] . '/'; 104 } 105 106 printf( 107 '<div class="action_buttons"> 108 <a data-plugin_status="%1$s" data-activation_url="%2$s" href="%3$s" class="dashboard_btn %4$s"><i class="%5$s"></i>%6$s</a> 109 <a href="%7$s" class="dashboard_btn learn_more_btn" target="_blank"><i class="fab fa-wordpress-simple"></i> %8$s</a> 110 </div>', 111 esc_attr( $plugin_status ), 112 esc_url( $plugin_activation_url ), 113 esc_url( $plugin_status === 'not_installed' ? $plugin_installation_url : $plugin_activation_url ), 114 esc_attr( $plugin_status_label ), 115 esc_attr( $button_icon ), 116 esc_html( $plugin_status_title ), 117 esc_url( $wp_org_link ), 118 esc_html__( 'Learn More', 'spider-elements' ) 119 ); 120 ?> 73 121 </div> 74 122 </div> -
spider-elements/trunk/includes/Admin/dashboard/popup-pro.php
r3316325 r3464401 1 1 <?php 2 if ( !defined('ABSPATH')) {3 exit; // Exit if accessed directly2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 4 } 5 5 ?> … … 7 7 <div class="message_content ezd-text-center"> 8 8 <div class="close-pro"> 9 <img class="pro-close" src="<?php echo esc_url( SPEL_IMG . '/dashboard/modal-close.png') ?>"10 alt="<?php esc_attr_e( 'Popup Close', 'spider-elements'); ?>">9 <img class="pro-close" src="<?php echo esc_url( SPEL_IMG . '/dashboard/modal-close.png' ) ?>" 10 alt="<?php esc_attr_e( 'Close Popup', 'spider-elements' ); ?>"> 11 11 </div> 12 12 <div class="pro-icon"> 13 <img class="pro-image" src="<?php echo esc_url( SPEL_IMG . '/dashboard/dimond.png') ?>"14 alt="<?php esc_attr_e( 'Popup Pro Diamond', 'spider-elements'); ?>">13 <img class="pro-image" src="<?php echo esc_url( SPEL_IMG . '/dashboard/dimond.png' ) ?>" 14 alt="<?php esc_attr_e( 'Pro Feature', 'spider-elements' ); ?>"> 15 15 </div> 16 16 <div class="pro-content"> 17 <h3><?php esc_html_e('Go Pro', 'spider-elements'); ?></h3> 18 <p><?php esc_html_e('Upgrade to Pro Version for Unlock more features!', 'spider-elements'); ?></p> 19 <a href="admin.php?page=spider_elements_settings-pricing" class="dashboard_btn" target="_blank"> 20 <?php esc_html_e('Upgrade Now', 'spider-elements'); ?> 17 <h3><?php esc_html_e( 'Unlock Pro Features', 'spider-elements' ); ?></h3> 18 <p><?php esc_html_e( 'Upgrade to Spider Elements Pro to unlock all premium widgets and features for building amazing websites!', 'spider-elements' ); ?></p> 19 <ul class="pro-benefits" style="text-align: left; margin: 20px 0; padding-left: 24px;"> 20 <li style="margin-bottom: 8px; font-size: 14px; color: var(--spel-text-secondary);"> 21 <i class="icon-check" style="color: var(--spel-success); margin-right: 8px;"></i> 22 <?php esc_html_e( 'All Premium Widgets', 'spider-elements' ); ?> 23 </li> 24 <li style="margin-bottom: 8px; font-size: 14px; color: var(--spel-text-secondary);"> 25 <i class="icon-check" style="color: var(--spel-success); margin-right: 8px;"></i> 26 <?php esc_html_e( 'Premium Extensions', 'spider-elements' ); ?> 27 </li> 28 <li style="margin-bottom: 8px; font-size: 14px; color: var(--spel-text-secondary);"> 29 <i class="icon-check" style="color: var(--spel-success); margin-right: 8px;"></i> 30 <?php esc_html_e( 'Priority Support', 'spider-elements' ); ?> 31 </li> 32 <li style="margin-bottom: 8px; font-size: 14px; color: var(--spel-text-secondary);"> 33 <i class="icon-check" style="color: var(--spel-success); margin-right: 8px;"></i> 34 <?php esc_html_e( 'Regular Updates', 'spider-elements' ); ?> 35 </li> 36 </ul> 37 <a href="admin.php?page=spider_elements_settings-pricing" class="dashboard_btn"> 38 <i class="icon-premium"></i> 39 <?php esc_html_e( 'Upgrade to Pro', 'spider-elements' ); ?> 21 40 </a> 22 41 </div> -
spider-elements/trunk/includes/Admin/dashboard/sidebar.php
r3316325 r3464401 3 3 exit; // Exit if accessed directly 4 4 } 5 6 $current_page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : 'spider_elements_settings'; 7 $tab_map = array( 8 'spider_elements_settings' => 'welcome', 9 'spider_elements_elements' => 'elements', 10 'spider_elements_features' => 'features', 11 'spider_elements_integration' => 'integration', 12 ); 13 $active_tab = $tab_map[ $current_page ] ?? 'welcome'; 5 14 ?> 6 15 … … 10 19 11 20 <li> 12 <a href="#welcome" class="tab-menu-link active" data-content="welcome">21 <a href="#welcome" class="tab-menu-link <?php echo $active_tab === 'welcome' ? 'active' : ''; ?>" data-content="welcome"> 13 22 <div class="tab_menu_contents"> 14 23 <div class="icon"> … … 24 33 25 34 <li> 26 <a href="#elements" class="tab-menu-link " data-content="elements">35 <a href="#elements" class="tab-menu-link <?php echo $active_tab === 'elements' ? 'active' : ''; ?>" data-content="elements"> 27 36 <div class="tab_menu_contents"> 28 37 <div class="icon"> … … 38 47 39 48 <li> 40 <a href="#features" class="tab-menu-link " data-content="features">49 <a href="#features" class="tab-menu-link <?php echo $active_tab === 'features' ? 'active' : ''; ?>" data-content="features"> 41 50 <div class="tab_menu_contents"> 42 51 <div class="icon"> … … 52 61 53 62 <li> 54 <a href="#integration" class="tab-menu-link " data-content="integration">63 <a href="#integration" class="tab-menu-link <?php echo $active_tab === 'integration' ? 'active' : ''; ?>" data-content="integration"> 55 64 <div class="tab_menu_contents"> 56 65 <div class="icon"> -
spider-elements/trunk/includes/Admin/dashboard/welcome.php
r3370551 r3464401 3 3 exit; 4 4 } // Exit if accessed directly 5 6 use SPEL\includes\Admin\Module_Settings; 5 7 6 8 $php_version = phpversion(); … … 13 15 $close_icon = '<span class="invalid"><i class="icon-close"></i></span>'; 14 16 $environment = spel_get_environment_info(); 17 18 // Get widget and feature stats 19 $widget_settings = Module_Settings::get_widget_settings(); 20 $widget_opt = get_option( 'spe_widget_settings' ); 21 $feature_opt = get_option( 'spel_features_settings' ); 22 23 // Count active widgets and features 24 $total_widgets = isset( $widget_settings['spider_elements_widgets'] ) ? count( $widget_settings['spider_elements_widgets'] ) : 0; 25 $total_features = isset( $widget_settings['spider_elements_features'] ) ? count( $widget_settings['spider_elements_features'] ) : 0; 26 27 $active_widgets = 0; 28 if ( isset( $widget_settings['spider_elements_widgets'] ) ) { 29 foreach ( $widget_settings['spider_elements_widgets'] as $widget ) { 30 $widget_name = $widget['name'] ?? ''; 31 if ( ! isset( $widget_opt[ $widget_name ] ) || $widget_opt[ $widget_name ] === 'on' ) { 32 if ( $widget['widget_type'] !== 'pro' || spel_is_premium() ) { 33 ++$active_widgets; 34 } 35 } 36 } 37 } 38 39 $active_features = 0; 40 if ( isset( $widget_settings['spider_elements_features'] ) ) { 41 foreach ( $widget_settings['spider_elements_features'] as $feature ) { 42 $feature_name = $feature['name'] ?? ''; 43 if ( ! isset( $feature_opt[ $feature_name ] ) || $feature_opt[ $feature_name ] === 'on' ) { 44 if ( $feature['feature_type'] !== 'pro' || spel_is_premium() ) { 45 ++$active_features; 46 } 47 } 48 } 49 } 50 51 // Count pro widgets 52 $pro_widgets = 0; 53 if ( isset( $widget_settings['spider_elements_widgets'] ) ) { 54 foreach ( $widget_settings['spider_elements_widgets'] as $widget ) { 55 if ( $widget['widget_type'] === 'pro' ) { 56 ++$pro_widgets; 57 } 58 } 59 } 60 61 $free_widgets = $total_widgets - $pro_widgets; 15 62 ?> 16 63 <div id="welcome" class="tab-box active"> 17 64 18 <div class="dashboard_banner text-center"> 19 <img src="<?php echo esc_url( SPEL_IMG . '/dashboard/logo.png' ) ?>" alt="<?php esc_attr_e( 'Dashboard Banner', 'spider-elements' ); ?>"> 20 </div> 21 22 <div class="ezd-grid ezd-grid-cols-12"> 23 <div class="ezd-lg-col-12"> 24 <div class="support_item"> 25 <h2 class="dashboard_title"><?php esc_html_e( 'System Requirement', 'spider-elements' ); ?></h2> 26 <div class="ezd-grid ezd-grid-cols-12"> 27 28 <ul class="list-unstyled requirement_list ezd-lg-col-6"> 29 <li> 30 <strong><?php esc_html_e( 'PHP Version:', 'spider-elements' ); ?></strong> 31 <?php 32 if ( version_compare( $php_version, '7.4', '<' ) ) { 33 echo '<span title="' . esc_attr__( 'Minimum: 7.4 Recommended', 'spider-elements' ) . '">' 34 . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $php_version ) . '</span>'; 35 } else { 36 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $php_version ) . '</span>'; 37 } 38 ?> 39 </li> 40 <li> 41 <strong><?php esc_html_e( 'Memory Limit:', 'spider-elements' ); ?></strong> 42 <?php 43 if ( intval( $memory_limit ) < 512 ) { 44 echo '<span title="' . esc_attr__( 'Minimum 512M Recommended', 'spider-elements' ) . '">' 45 . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $memory_limit ) . '</span>'; 46 } else { 47 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $memory_limit ) . '</span>'; 48 } 49 ?> 50 </li> 51 <li> 52 <strong><?php esc_html_e( 'Uploads Folder Writable:', 'spider-elements' ); ?></strong> 53 <?php 54 if ( ! is_writable( $upload_path ) ) { 55 echo wp_kses_post( $close_icon ); 56 } else { 57 echo wp_kses_post( $check_icon ); 58 } 59 ?> 60 </li> 61 <li> 62 <strong><?php esc_html_e( 'GZip Enabled:', 'spider-elements' ); ?></strong> 63 <?php 64 if ( $environment['gzip_enabled'] ) { 65 echo wp_kses_post( $check_icon ); 66 } else { 67 echo wp_kses_post( $close_icon ); 68 } 69 ?> 70 </li> 71 </ul> 72 73 <ul class="list-unstyled requirement_list ezd-lg-col-6"> 74 <li> 75 <strong><?php esc_html_e( 'Max Execution Time:', 'spider-elements' ); ?></strong> 76 <?php 77 if ( intval( $max_execution_time ) < 90 ) { 78 echo '<span title="' . esc_attr__( 'Minimum 90 Recommended', 'spider-elements' ) . '">' 79 . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $max_execution_time ) . '</span>'; 80 } else { 81 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $max_execution_time ) . '</span>'; 82 } 83 ?> 84 </li> 85 <li> 86 <strong><?php esc_html_e( 'Max Post Limit:', 'spider-elements' ); ?></strong> 87 <?php 88 if ( intval( $post_limit ) < 32 ) { 89 echo '<span title="' . esc_attr__( 'Minimum 32M Recommended', 'spider-elements' ) . '">' 90 . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $post_limit ) . '</span>'; 91 } else { 92 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $post_limit ) . '</span>'; 93 } 94 ?> 95 </li> 96 <li> 97 <strong><?php esc_html_e( 'Multisite:', 'spider-elements' ); ?></strong> 98 <?php 99 if ( $environment['wp_multisite'] ) { 100 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Multisite', 'spider-elements' ) . '</span>'; 101 } else { 102 echo '<span>' . wp_kses_post( $close_icon ) . esc_html__( 'No Multisite', 'spider-elements' ) . '</span>'; 103 } 104 ?> 105 </li> 106 <li> 107 <strong><?php esc_html_e( 'Debug Mode:', 'spider-elements' ); ?></strong> 108 <?php 109 if ( $environment['wp_debug_mode'] ) { 110 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently Turned On', 'spider-elements' ) . '</span>'; 111 } else { 112 echo '<span>' . wp_kses_post( $close_icon ) . esc_html__( 'Currently Turned Off', 'spider-elements' ) . '</span>'; 113 } 114 ?> 115 </li> 116 </ul> 117 118 119 </div> 120 121 <div class="note"> 122 <p> 65 <!-- Enhanced Dashboard Banner --> 66 <div class="dashboard_banner"> 67 <div class="banner_content"> 68 <span class="version_badge"> 69 <i class="icon-star"></i> 70 <?php echo esc_html( sprintf( __( 'Version %s', 'spider-elements' ), SPEL_VERSION ) ); ?> 71 </span> 72 <h2><?php esc_html_e( 'Welcome to Spider Elements', 'spider-elements' ); ?></h2> 73 <p><?php esc_html_e( 'The ultimate Elementor addon bundle packed with powerful widgets and features to create stunning websites effortlessly.', 'spider-elements' ); ?></p> 74 </div> 75 <img src="<?php echo esc_url( SPEL_IMG . '/dashboard/logo.png' ); ?>" alt="<?php esc_attr_e( 'Spider Elements Logo', 'spider-elements' ); ?>"> 76 </div> 77 78 <!-- Quick Stats Section --> 79 <div class="quick_stats"> 80 <div class="stat_card stat_elements"> 81 <div class="stat_header"> 82 <span class="stat_icon"> 83 <i class="icon-element"></i> 84 </span> 85 <span class="stat_trend trend_info"> 86 <i class="icon-star"></i> <?php esc_html_e( 'Widgets', 'spider-elements' ); ?> 87 </span> 88 </div> 89 <div class="stat_value"><?php echo esc_html( $total_widgets ); ?></div> 90 <div class="stat_label"><?php esc_html_e( 'Total Widgets Available', 'spider-elements' ); ?></div> 91 </div> 92 93 <div class="stat_card stat_active"> 94 <div class="stat_header"> 95 <span class="stat_icon"> 96 <i class="icon-check"></i> 97 </span> 98 <span class="stat_trend trend_up"> 99 <i class="icon-star"></i> <?php esc_html_e( 'Active', 'spider-elements' ); ?> 100 </span> 101 </div> 102 <div class="stat_value"><?php echo esc_html( $active_widgets ); ?></div> 103 <div class="stat_label"><?php esc_html_e( 'Active Widgets', 'spider-elements' ); ?></div> 104 </div> 105 106 <div class="stat_card stat_features"> 107 <div class="stat_header"> 108 <span class="stat_icon"> 109 <i class="icon-feature_two"></i> 110 </span> 111 <span class="stat_trend trend_info"> 112 <i class="icon-star"></i> <?php esc_html_e( 'Features', 'spider-elements' ); ?> 113 </span> 114 </div> 115 <div class="stat_value"><?php echo esc_html( $total_features ); ?></div> 116 <div class="stat_label"><?php esc_html_e( 'Total Features', 'spider-elements' ); ?></div> 117 </div> 118 119 <div class="stat_card stat_pro"> 120 <div class="stat_header"> 121 <span class="stat_icon"> 122 <i class="icon-premium"></i> 123 </span> 124 <span class="stat_trend trend_info"> 125 <i class="icon-diamond"></i> <?php esc_html_e( 'Pro', 'spider-elements' ); ?> 126 </span> 127 </div> 128 <div class="stat_value"><?php echo esc_html( $pro_widgets ); ?></div> 129 <div class="stat_label"><?php esc_html_e( 'Pro Widgets', 'spider-elements' ); ?></div> 130 </div> 131 </div> 132 133 <!-- System Requirement Section --> 134 <div class="ezd-grid ezd-grid-cols-12"> 135 <div class="ezd-lg-col-12"> 136 <div class="support_item"> 137 <div class="section_header has_flex"> 138 <h2 class="dashboard_title"><?php esc_html_e( 'System Requirements', 'spider-elements' ); ?></h2> 139 <span class="requirement_status badge_success"> 140 <i class="icon-check"></i> 141 <?php esc_html_e( 'All Good', 'spider-elements' ); ?> 142 </span> 143 </div> 144 <div class="ezd-grid ezd-grid-cols-12"> 145 146 <ul class="list-unstyled requirement_list ezd-lg-col-6"> 147 <li> 148 <strong><?php esc_html_e( 'PHP Version:', 'spider-elements' ); ?></strong> 149 <?php 150 if ( version_compare( $php_version, '7.4', '<' ) ) { 151 echo '<span title="' . esc_attr__( 'Minimum: 7.4 Recommended', 'spider-elements' ) . '">' 152 . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $php_version ) . '</span>'; 153 } else { 154 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $php_version ) . '</span>'; 155 } 156 ?> 157 </li> 158 <li> 159 <strong><?php esc_html_e( 'Memory Limit:', 'spider-elements' ); ?></strong> 160 <?php 161 if ( intval( $memory_limit ) < 512 ) { 162 echo '<span title="' . esc_attr__( 'Minimum 512M Recommended', 'spider-elements' ) . '">' 163 . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $memory_limit ) . '</span>'; 164 } else { 165 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $memory_limit ) . '</span>'; 166 } 167 ?> 168 </li> 169 <li> 170 <strong><?php esc_html_e( 'Uploads Folder Writable:', 'spider-elements' ); ?></strong> 171 <?php 172 if ( ! is_writable( $upload_path ) ) { 173 echo wp_kses_post( $close_icon ); 174 } else { 175 echo wp_kses_post( $check_icon ); 176 } 177 ?> 178 </li> 179 <li> 180 <strong><?php esc_html_e( 'GZip Enabled:', 'spider-elements' ); ?></strong> 181 <?php 182 if ( $environment['gzip_enabled'] ) { 183 echo wp_kses_post( $check_icon ); 184 } else { 185 echo wp_kses_post( $close_icon ); 186 } 187 ?> 188 </li> 189 </ul> 190 191 <ul class="list-unstyled requirement_list ezd-lg-col-6"> 192 <li> 193 <strong><?php esc_html_e( 'Max Execution Time:', 'spider-elements' ); ?></strong> 194 <?php 195 if ( intval( $max_execution_time ) < 90 ) { 196 echo '<span title="' . esc_attr__( 'Minimum 90 Recommended', 'spider-elements' ) . '">' 197 . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $max_execution_time ) . '</span>'; 198 } else { 199 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $max_execution_time ) . '</span>'; 200 } 201 ?> 202 </li> 203 <li> 204 <strong><?php esc_html_e( 'Max Post Limit:', 'spider-elements' ); ?></strong> 205 <?php 206 if ( intval( $post_limit ) < 32 ) { 207 echo '<span title="' . esc_attr__( 'Minimum 32M Recommended', 'spider-elements' ) . '">' 208 . wp_kses_post( $close_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $post_limit ) . '</span>'; 209 } else { 210 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently:', 'spider-elements' ) . ' ' . esc_html( $post_limit ) . '</span>'; 211 } 212 ?> 213 </li> 214 <li> 215 <strong><?php esc_html_e( 'Multisite:', 'spider-elements' ); ?></strong> 216 <?php 217 if ( $environment['wp_multisite'] ) { 218 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Multisite', 'spider-elements' ) . '</span>'; 219 } else { 220 echo '<span>' . wp_kses_post( $close_icon ) . esc_html__( 'No Multisite', 'spider-elements' ) . '</span>'; 221 } 222 ?> 223 </li> 224 <li> 225 <strong><?php esc_html_e( 'Debug Mode:', 'spider-elements' ); ?></strong> 226 <?php 227 if ( $environment['wp_debug_mode'] ) { 228 echo '<span>' . wp_kses_post( $check_icon ) . esc_html__( 'Currently Turned On', 'spider-elements' ) . '</span>'; 229 } else { 230 echo '<span>' . wp_kses_post( $close_icon ) . esc_html__( 'Currently Turned Off', 'spider-elements' ) . '</span>'; 231 } 232 ?> 233 </li> 234 </ul> 235 </div> 236 237 <div class="note"> 238 <i class="dashicons dashicons-info-outline"></i> 239 <p> 123 240 <?php 124 241 printf( 125 /* translators: %1$s and %2$s are opening and closing strong HTML tags. */242 /* translators: %1$s and %2$s are opening and closing strong HTML tags. */ 126 243 esc_html__( 127 'Note: If you have multiple addons like %1$s Spider Elements %2$s, you may need more resources. Ensure you allocate more memory for other addons as well.', 'spider-elements' 244 'Note: If you have multiple addons like %1$s Spider Elements %2$s, you may need more resources. Ensure you allocate more memory for other addons as well.', 245 'spider-elements' 128 246 ), 129 247 '<strong>', … … 131 249 ); 132 250 ?> 133 </p> 134 </div> 135 </div> 136 </div> 137 </div> 138 139 <div class="ezd-grid ezd-grid-cols-12"> 140 <div class="ezd-lg-col-6"> 141 <div class="support_item"> 142 <span class="icon icon-documentation"></span> 143 <h2 class="dashboard_title"><?php esc_html_e( 'Documentation', 'spider-elements' ); ?></h2> 144 <p><?php esc_html_e( 'Get detailed and guided instruction to level up your website with the necessary set up.', 'spider-elements' ); ?></p> 145 <a href="https://helpdesk.spider-themes.net/docs/spider-elements" class="dashboard_btn" target="_blank"> 251 </p> 252 </div> 253 </div> 254 </div> 255 </div> 256 257 <!-- Quick Links Section --> 258 <div class="ezd-grid ezd-grid-cols-12 quick_links_grid"> 259 <div class="ezd-lg-col-6"> 260 <div class="support_item"> 261 <span class="icon icon-documentation"></span> 262 <h2 class="dashboard_title"><?php esc_html_e( 'Documentation', 'spider-elements' ); ?></h2> 263 <p><?php esc_html_e( 'Get detailed and guided instruction to level up your website with the necessary set up.', 'spider-elements' ); ?></p> 264 <a href="https://helpdesk.spider-themes.net/docs/spider-elements" class="dashboard_btn" target="_blank"> 265 <i class="icon-document"></i> 146 266 <?php esc_html_e( 'Read Documentation', 'spider-elements' ); ?> 147 </a> 148 </div> 149 </div> 150 <div class="ezd-lg-col-6"> 151 <div class="support_item"> 152 <span class="icon icon-help"></span> 153 <h2 class="dashboard_title"><?php esc_html_e( 'Need Help', 'spider-elements' ); ?></h2> 154 <p><?php esc_html_e( 'If you are stuck at anything while using our product, reach out to us immediately', 'spider-elements' ); ?> 155 </p> 156 <a href="https://wordpress.org/support/plugin/spider-elements/" class="dashboard_btn" target="_blank"> 157 <?php esc_html_e( 'Support Ticket', 'spider-elements' ); ?> 158 </a> 159 </div> 160 </div> 161 </div> 162 163 164 <div class="ezd-grid ezd-grid-cols-12"> 165 166 <div class="ezd-lg-col-6"> 167 <div class="support_item"> 168 <span class="icon icon-love"></span> 169 <h2 class="dashboard_title"><?php esc_html_e( 'Show Your Love', 'spider-elements' ); ?></h2> 170 <p><?php echo esc_html__( 'Leave your feedback to help us out if you liked our product and customer service.', 'spider-elements' ); ?></p> 171 <a href="https://wordpress.org/support/plugin/spider-elements/reviews/#new-post" class="dashboard_btn" target="_blank"> 267 </a> 268 </div> 269 </div> 270 <div class="ezd-lg-col-6"> 271 <div class="support_item"> 272 <span class="icon icon-help"></span> 273 <h2 class="dashboard_title"><?php esc_html_e( 'Need Help?', 'spider-elements' ); ?></h2> 274 <p><?php esc_html_e( 'If you are stuck at anything while using our product, reach out to us immediately!', 'spider-elements' ); ?></p> 275 <a href="https://wordpress.org/support/plugin/spider-elements/" class="dashboard_btn" target="_blank"> 276 <i class="icon-bubble"></i> 277 <?php esc_html_e( 'Get Priority Support', 'spider-elements' ); ?> 278 </a> 279 </div> 280 </div> 281 <div class="ezd-lg-col-6"> 282 <div class="support_item"> 283 <span class="icon icon-love"></span> 284 <h2 class="dashboard_title"><?php esc_html_e( 'Love Spider Elements?', 'spider-elements' ); ?></h2> 285 <p><?php echo esc_html__( 'Leave your feedback to help us out if you liked our product and customer service.', 'spider-elements' ); ?></p> 286 <a href="https://wordpress.org/support/plugin/spider-elements/reviews/#new-post" class="dashboard_btn" target="_blank"> 287 <i class="icon-star"></i> 172 288 <?php esc_html_e( 'Leave a Review', 'spider-elements' ); ?> 173 </a> 174 </div> 175 </div> 176 <div class="ezd-lg-col-6"> 177 <div class="support_item"> 178 <span class="icon icon-debug"></span> 179 <h2 class="dashboard_title"> <?php esc_html_e( 'Facing an issues?', 'spider-elements' ); ?> </h2> 180 <p> <?php echo esc_html__( "Think you've spotted a bug? Please let us know! Your feedback helps us make improvements.", "spider-elements" ); ?> </p> 181 <a href="https://github.com/spider-themes/spider-elements/issues/new" class="dashboard_btn" target="_blank"> 182 <?php esc_html_e( 'Get Help Now', 'spider-elements' ); ?> 183 </a> 184 </div> 185 </div> 186 </div> 289 </a> 290 </div> 291 </div> 292 <div class="ezd-lg-col-6"> 293 <div class="support_item"> 294 <span class="icon icon-debug"></span> 295 <h2 class="dashboard_title"> <?php esc_html_e( 'Found a Bug?', 'spider-elements' ); ?> </h2> 296 <p> <?php echo esc_html__( "Think you've spotted a bug? Please let us know! Your feedback helps us make improvements.", 'spider-elements' ); ?> </p> 297 <a href="https://github.com/spider-themes/spider-elements/issues/new" class="dashboard_btn" target="_blank"> 298 <i class="icon-github"></i> 299 <?php esc_html_e( 'Report on GitHub', 'spider-elements' ); ?> 300 </a> 301 </div> 302 </div> 303 </div> 187 304 188 305 </div> -
spider-elements/trunk/includes/Frontend/Assets.php
r3416399 r3464401 42 42 $theme = wp_get_theme(); 43 43 $features_opt = get_option( 'spel_features_settings' ); 44 $is_premium_or_theme = spel_is_premium() || in_array( $theme->get('Name'), ['jobi', 'Jobi', 'jobi-child', 'Jobi Child']);44 $is_premium_or_theme = spel_is_premium() || in_array( $theme->get( 'Name' ), [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ], true ); 45 45 46 if ( isset( $features_opt['spel_smooth_animation']) && $features_opt[ 'spel_smooth_animation' ] == 'on') {46 if ( isset( $features_opt['spel_smooth_animation'] ) && 'on' === $features_opt['spel_smooth_animation'] ) { 47 47 48 48 // Define all the handlers in one string, separated by commas … … 75 75 76 76 if ( $is_premium_or_theme ) { 77 if ( isset( $features_opt['spel_heading_highlighted']) && $features_opt[ 'spel_heading_highlighted' ] == 'on') {78 wp_enqueue_style( 'spel-extension');77 if ( isset( $features_opt['spel_heading_highlighted'] ) && 'on' === $features_opt['spel_heading_highlighted'] ) { 78 wp_enqueue_style( 'spel-extension' ); 79 79 } 80 if ( isset( $features_opt['spel_badge']) && $features_opt[ 'spel_badge' ] == 'on') {81 wp_enqueue_style( 'spel-extension');80 if ( isset( $features_opt['spel_badge'] ) && 'on' === $features_opt['spel_badge'] ) { 81 wp_enqueue_style( 'spel-extension' ); 82 82 } 83 83 } -
spider-elements/trunk/includes/filters.php
r3416399 r3464401 1 1 <?php 2 /** 3 * Plugin Filters and Actions 4 * 5 * This file handles various hooks, including image sizes, constants, 6 * and admin form submissions. 7 * 8 * @package SpiderElements 9 */ 10 2 11 if ( ! defined( 'ABSPATH' ) ) { 3 12 exit; // Exit if accessed directly … … 26 35 27 36 37 /** 38 * Handle Element Settings Form Submission 39 */ 28 40 add_action( 'admin_init', function () { 29 41 … … 51 63 'spe_timeline_widget', 52 64 'spe_counter', 53 'spel_icon_box' 65 'spel_icon_box', 54 66 ]; 55 67 … … 66 78 'spel_marquee_slider', 67 79 'spe_skill_showcase_widget', 68 'spel_stacked_image' 80 'spel_stacked_image', 69 81 ]; 70 82 … … 120 132 121 133 122 // Dashboard Features Setting Save Data 134 /** 135 * Handle Features Settings Form Submission 136 */ 123 137 add_action( 'admin_init', function () { 124 138 … … 156 170 update_option( 'spel_features_settings', $data ); 157 171 158 // If the user is not on a pro-plan or Jobi theme, reset pro- widgets172 // If the user is not on a pro-plan or Jobi theme, reset pro-features 159 173 $theme = wp_get_theme(); 160 $is_premium_or_theme = spel_is_premium() || in_array( $theme->get( 'Name' ), [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ] ); 174 $theme_name = $theme->get( 'Name' ); 175 $is_premium_or_theme = spel_is_premium() || in_array( $theme_name, [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ], true ); 176 177 // Smooth Animation is unlocked for Docy, Jobi, Docly, or Ama theme users 178 $is_smooth_anim_unlocked = spel_unlock_docy_theme() 179 || in_array( $theme_name, [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ], true ) 180 || in_array( $theme_name, [ 'Docly', 'docly', 'Docly Child', 'docly-child' ], true ) 181 || in_array( $theme_name, [ 'Ama', 'ama', 'Ama Child', 'ama-child' ], true ); 182 161 183 if ( ! $is_premium_or_theme ) { 162 184 foreach ( $pro_features as $feature ) { 185 // Keep Smooth Animation enabled for Docy, Jobi, or Docly theme users 186 if ( $feature === 'spel_smooth_animation' && $is_smooth_anim_unlocked ) { 187 continue; 188 } 163 189 $data[ $feature ] = 'off'; 164 190 } -
spider-elements/trunk/includes/functions.php
r3393425 r3464401 6 6 7 7 /** 8 * Check if the pro-plugin and plan is active 8 * Check if the pro-plugin and plan is active. 9 * 10 * @return bool True if premium code can be used, false otherwise. 11 */ 12 function spel_is_premium(): bool { 13 return spel_fs()->is_plan( 'pro' ) && spel_fs()->can_use_premium_code(); 14 } 15 16 /** 17 * Check if the Docy theme is active 9 18 * 10 19 * @return bool 11 20 */ 12 function spel_is_premium(): bool13 {14 return spel_fs()->is_plan('pro') && spel_fs()->can_use_premium_code();15 }16 17 21 function spel_unlock_docy_theme(): bool { 18 $theme = wp_get_theme(); 19 $theme_name = $theme->get('Name'); 20 $docy_themes = [ 'Docy', 'docy', 'Docy Child', 'docy-child' ]; 21 22 return in_array($theme_name, $docy_themes, true) || spel_is_premium(); 23 } 24 25 if ( ! function_exists( 'spel_rtl') ) { 26 function spel_rtl(): string { 22 $theme = wp_get_theme(); 23 $theme_name = $theme->get( 'Name' ); 24 $docy_themes = [ 'Docy', 'docy', 'Docy Child', 'docy-child' ]; 25 26 return in_array( $theme_name, $docy_themes, true ) || spel_is_premium(); 27 } 28 29 function spel_rtl(): string { 27 30 return is_rtl() ? 'true' : 'false'; 28 } 29 } 30 31 /** 31 } 32 33 /** 34 * Elementor is edit mode 35 * 32 36 * @return bool 33 * Elementor is edit mode 34 */ 35 function spider_elements_is_edit(): bool 36 { 37 */ 38 function spider_elements_is_edit(): bool { 37 39 return \Elementor\Plugin::$instance->editor->is_edit_mode(); 38 40 } 39 41 40 42 /** 43 * Elementor is preview mode 44 * 41 45 * @return bool 42 * Elementor is preview mode 43 */ 44 function spider_elements_is_preview(): bool 45 { 46 */ 47 function spider_elements_is_preview(): bool { 46 48 return \Elementor\Plugin::$instance->preview->is_preview_mode(); 47 49 } … … 49 51 /** 50 52 * Elementor Title tags 53 * 54 * @return array 51 55 */ 52 56 if ( ! function_exists( 'spel_get_title_tags' ) ) { 53 function spel_get_title_tags(): array 54 { 55 return [ 56 'h1' => esc_html__( 'H1', 'spider-elements' ), 57 'h2' => esc_html__( 'H2', 'spider-elements' ), 58 'h3' => esc_html__( 'H3', 'spider-elements' ), 59 'h4' => esc_html__( 'H4', 'spider-elements' ), 60 'h5' => esc_html__( 'H5', 'spider-elements' ), 61 'h6' => esc_html__( 'H6', 'spider-elements' ), 62 'div' => esc_html__( 'Div', 'spider-elements' ), 63 'span' => esc_html__( 'Span', 'spider-elements' ), 64 'p' => esc_html__( 'Paragraph', 'spider-elements' ), 65 ]; 66 } 57 function spel_get_title_tags(): array { 58 return [ 59 'h1' => esc_html__( 'H1', 'spider-elements' ), 60 'h2' => esc_html__( 'H2', 'spider-elements' ), 61 'h3' => esc_html__( 'H3', 'spider-elements' ), 62 'h4' => esc_html__( 'H4', 'spider-elements' ), 63 'h5' => esc_html__( 'H5', 'spider-elements' ), 64 'h6' => esc_html__( 'H6', 'spider-elements' ), 65 'div' => esc_html__( 'Div', 'spider-elements' ), 66 'span' => esc_html__( 'Span', 'spider-elements' ), 67 'p' => esc_html__( 'Paragraph', 'spider-elements' ), 68 ]; 69 } 67 70 } 68 71 … … 70 73 * Echo button link attributes. 71 74 * 72 * @param array $settings_key 73 * @param bool $is_echo 75 * @param array $settings_key Settings array. 76 * @param bool $is_echo Whether to echo the attributes. 77 * @return void 74 78 */ 75 79 if ( ! function_exists( 'spel_button_link' ) ) { 76 function spel_button_link( $settings_key, $is_echo = true ): void 77 { 78 if ( $is_echo ) { 79 echo ! empty( $settings_key['url'] ) ? 'href="' . esc_url( $settings_key['url'] ) . '"' : ''; 80 echo $settings_key['is_external'] ? ' target="_blank"' : ''; 81 echo $settings_key['nofollow'] ? ' rel="nofollow"' : ''; 82 83 if ( ! empty( $settings_key['custom_attributes'] ) ) { 84 $attrs = explode( ',', $settings_key['custom_attributes'] ); 85 86 if ( is_array( $attrs ) ) { 87 foreach ( $attrs as $data ) { 88 $data_attrs = explode( '|', $data ); 89 echo ' ' . esc_attr( $data_attrs[0] ) . '="' . esc_attr( $data_attrs[1] ) . '"'; 90 } 91 } 92 } 93 } 94 } 80 function spel_button_link( $settings_key, $is_echo = true ): void { 81 if ( $is_echo ) { 82 echo ! empty( $settings_key['url'] ) ? 'href="' . esc_url( $settings_key['url'] ) . '"' : ''; 83 echo $settings_key['is_external'] ? ' target="_blank"' : ''; 84 echo $settings_key['nofollow'] ? ' rel="nofollow"' : ''; 85 86 if ( ! empty( $settings_key['custom_attributes'] ) ) { 87 $attrs = explode( ',', $settings_key['custom_attributes'] ); 88 89 if ( is_array( $attrs ) ) { 90 foreach ( $attrs as $data ) { 91 $data_attrs = explode( '|', $data, 2 ); 92 $attr_name = trim( $data_attrs[0] ); 93 $attr_value = isset( $data_attrs[1] ) ? $data_attrs[1] : ''; 94 95 // Security: Sanitize attribute name (allow alphanumeric, dashes, colons) 96 $attr_name = preg_replace( '/[^a-zA-Z0-9_\-:]/', '', $attr_name ); 97 98 // Security: Prevent XSS by blocking event handlers (on*) and critical attributes 99 if ( preg_match( '/^(on|href|src|formaction)/i', $attr_name ) ) { 100 continue; 101 } 102 103 if ( ! empty( $attr_name ) ) { 104 echo ' ' . esc_attr( $attr_name ) . '="' . esc_attr( $attr_value ) . '"'; 105 } 106 } 107 } 108 } 109 } 110 } 95 111 } 96 112 97 113 /** 98 114 * Category IDs 115 * 99 116 * @return array 100 */ 101 if ( ! function_exists( 'spel_cat_ids') ) { 102 function spel_cat_ids() { 103 104 $taxonomys = get_terms( array( 105 'taxonomy' => 'category', 106 'hide_empty' => true, 107 ) ); 108 $taxonomy = []; 109 if ( is_array( $taxonomys ) ) { 110 foreach ( $taxonomys as $cat_id ) { 111 $taxonomy[ $cat_id->term_id ] = $cat_id->name; 112 } 113 } 114 115 return $taxonomy; 116 117 } 117 * @since 1.0.0 118 */ 119 if ( ! function_exists( 'spel_cat_ids' ) ) { 120 function spel_cat_ids() { 121 $taxonomys = get_terms( [ 122 'taxonomy' => 'category', 123 'hide_empty' => true, 124 ] ); 125 $taxonomy = []; 126 if ( is_array( $taxonomys ) ) { 127 foreach ( $taxonomys as $cat_id ) { 128 $taxonomy[ $cat_id->term_id ] = $cat_id->name; 129 } 130 } 131 132 return $taxonomy; 133 } 118 134 } 119 135 120 136 /** 121 137 * Day link to archive page 138 * 139 * @return void 122 140 **/ 123 141 if ( ! function_exists( 'spel_day_link' ) ) { 124 function spel_day_link(): void 125 { 126 $archive_year = get_the_time( 'Y' ); 127 $archive_month = get_the_time( 'm' ); 128 $archive_day = get_the_time( 'd' ); 129 echo esc_url( get_day_link( $archive_year, $archive_month, $archive_day ) ); 130 } 142 function spel_day_link(): void { 143 $archive_year = get_the_time( 'Y' ); 144 $archive_month = get_the_time( 'm' ); 145 $archive_day = get_the_time( 'd' ); 146 echo esc_url( get_day_link( $archive_year, $archive_month, $archive_day ) ); 147 } 131 148 } 132 149 … … 144 161 * 145 162 * @return string The trimmed post title, or empty string if no title exists. 163 * @since 1.0.0 146 164 */ 147 165 function spel_get_title_length( array $settings, string $settings_key, int $default = 10 ): string { … … 156 174 * Post's excerpt text 157 175 * 158 * @param $settings_key 159 * @param bool $echo 176 * @param array $settings 177 * @param string $settings_key 178 * @param int $default 160 179 * 161 180 * @return string 162 **/ 181 * @since 1.0.0 182 */ 163 183 if ( ! function_exists( 'spel_get_excerpt_length' ) ) { 164 function spel_get_excerpt_length( $settings, $settings_key, $default = 10 ): string { 165 $excerpt_length = ! empty( $settings[ $settings_key ] ) ? $settings[ $settings_key ] : $default; 166 return get_the_excerpt() ? wp_trim_words( get_the_excerpt(), $excerpt_length, '...' ) : wp_trim_words( get_the_content(), $excerpt_length, '...' ); 167 } 184 function spel_get_excerpt_length( $settings, $settings_key, $default = 10 ): string { 185 $excerpt_length = ! empty( $settings[ $settings_key ] ) ? $settings[ $settings_key ] : $default; 186 187 return get_the_excerpt() ? wp_trim_words( get_the_excerpt(), $excerpt_length, '...' ) : wp_trim_words( get_the_content(), $excerpt_length, '...' ); 188 } 168 189 } 169 190 … … 175 196 * 176 197 * @return string 198 * @since 1.0.0 177 199 */ 178 200 if ( ! function_exists( 'spel_get_first_taxonomy' ) ) { 179 function spel_get_first_taxonomy( $term = 'category' ): string 180 { 181 $cats = get_the_terms( get_the_ID(), $term ); 182 $cat = is_array( $cats ) ? $cats[0]->name : ''; 183 184 return esc_html( $cat ); 185 } 201 function spel_get_first_taxonomy( $term = 'category' ): string { 202 $cats = get_the_terms( get_the_ID(), $term ); 203 $cat = is_array( $cats ) ? $cats[0]->name : ''; 204 205 return esc_html( $cat ); 206 } 186 207 } 187 208 … … 193 214 * 194 215 * @return string 216 * @since 1.0.0 195 217 */ 196 218 if ( ! function_exists( 'spel_get_first_taxonomy_link' ) ) { 197 function spel_get_first_taxonomy_link( $term = 'category' ): string 198 { 199 200 $cats = get_the_terms( get_the_ID(), $term ); 201 $cat = is_array( $cats ) ? get_category_link( $cats[0]->term_id ) : ''; 202 203 return esc_url( $cat ); 204 } 219 function spel_get_first_taxonomy_link( $term = 'category' ): string { 220 221 $cats = get_the_terms( get_the_ID(), $term ); 222 $cat = is_array( $cats ) ? get_category_link( $cats[0]->term_id ) : ''; 223 224 return esc_url( $cat ); 225 } 205 226 } 206 227 … … 212 233 * 213 234 * @return array 235 * @since 1.0.0 214 236 */ 215 237 if ( ! function_exists( 'spel_get_categories' ) ) { 216 function spel_get_categories( $term = 'category' ) {217 218 $cats = get_terms( array( 219 'taxonomy' => $term,220 'hide_empty' => true221 ));222 223 $cat_array = [];224 $cat_array['all'] = esc_html__( 'All', 'spider-elements' );225 226 if ( is_array( $cats ) ) {227 foreach ( $cats as $cat ) {228 $cat_array[ $cat->term_id ] = $cat->name;229 }230 }231 232 return $cat_array;233 }238 function spel_get_categories( $term = 'category' ) { 239 240 $cats = get_terms( [ 241 'taxonomy' => $term, 242 'hide_empty' => true 243 ] ); 244 245 $cat_array = []; 246 $cat_array['all'] = esc_html__( 'All', 'spider-elements' ); 247 248 if ( is_array( $cats ) ) { 249 foreach ( $cats as $cat ) { 250 $cat_array[ $cat->term_id ] = $cat->name; 251 } 252 } 253 254 return $cat_array; 255 } 234 256 } 235 257 … … 238 260 * Get a category list 239 261 * 240 * @param string $term 262 * @return void 263 * @since 1.0.0 264 */ 265 if ( ! function_exists( 'spel_get_post_category_list' ) ) { 266 function spel_get_post_category_list(): void { 267 $categories = get_categories(); 268 269 if ( ! empty( $categories ) ) { 270 echo '<span class="blog-category">'; 271 272 $category_names = []; 273 274 if ( is_array( $categories ) ) { 275 foreach ( $categories as $category ) { 276 $category_link = get_category_link( $category->term_id ); 277 $category_names[] = '<a href="' . esc_url( $category_link ) . '">' . esc_html( $category->name ) . '</a>'; 278 } 279 } 280 281 echo esc_html( implode( ', ', $category_names ) ); 282 283 echo '</span>'; 284 } else { 285 echo esc_html__( 'No categories found.', 'spider-elements' ); 286 } 287 } 288 } 289 290 291 /** 292 * Get an author name array 293 * 294 * @return void 295 * @since 1.0.0 296 */ 297 if ( ! function_exists( 'spel_get_post_author_name' ) ) { 298 function spel_get_post_author_name(): void { 299 global $post; 300 $byline = sprintf( 301 /* translators: %s: post author. */ 302 esc_html_x( 'By: %s', 'post author', 'spider-elements' ), 303 '<span class="author"><a class="url fn n" href="' . esc_url( get_author_posts_url( $post->post_author ) ) . '">' . esc_html( get_the_author_meta( 304 'display_name', 305 $post->post_author 306 ) ) . '</a></span>' 307 ); 308 309 echo wp_kses_post( $byline ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 310 } 311 } 312 313 /** 314 * Get Default Image Elementor 315 * 316 * @param array $settings_key 317 * @param string $alt 318 * @param string $class 319 * @param array $atts 320 * @return void 321 * @since 1.0.0 322 */ 323 if ( ! function_exists( 'spel_el_image' ) ) { 324 function spel_el_image( $settings_key = [], $alt = '', $class = '', $atts = [] ): void { 325 if ( ! empty( $settings_key['id'] ) ) { 326 // WordPress handles escaping internally here 327 echo wp_get_attachment_image( $settings_key['id'], 'full', false, [ 'class' => esc_attr( $class ) ] ); 328 } elseif ( ! empty( $settings_key['url'] ) && empty( $settings_key['id'] ) ) { 329 $class_attr = ! empty( $class ) ? ' class="' . esc_attr( $class ) . '"' : ''; 330 $atts_str = ''; 331 332 if ( ! empty( $atts ) ) { 333 foreach ( $atts as $k => $att ) { 334 // Security: Sanitize attribute name (allow alphanumeric, dashes, colons) 335 $k = preg_replace( '/[^a-zA-Z0-9_\-:]/', '', $k ); 336 337 // Security: Prevent XSS by blocking event handlers (on*) and critical attributes 338 if ( empty( $k ) || preg_match( '/^(on|style|formaction|src|href)/i', $k ) ) { 339 continue; 340 } 341 342 $atts_str .= ' ' . esc_attr( $k ) . '="' . esc_attr( $att ) . '"'; 343 } 344 } 345 346 printf( 347 '<img src="%1$s"%2$s alt="%3$s"%4$s />', 348 esc_url( $settings_key['url'] ), 349 // $class_attr contains safe HTML attribute string 350 $class_attr, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 351 esc_attr( $alt ), 352 // $atts_str contains safe HTML attribute string 353 $atts_str // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 354 ); 355 } 356 } 357 } 358 359 360 /** 361 * Get Default Image Elementor Caption 362 * 363 * @param $image_id 364 * 365 * @return array 366 */ 367 if ( ! function_exists( 'spel_el_image_caption' ) ) { 368 function spel_el_image_caption( $image_id = '' ): array { 369 $img_attachment = get_post( $image_id ); 370 371 return [ 372 'alt' => get_post_meta( $img_attachment->ID, '_wp_attachment_image_alt', true ), 373 'caption' => $img_attachment->post_excerpt, 374 'href' => get_permalink( $img_attachment->ID ), 375 'src' => $img_attachment->guid, 376 'title' => $img_attachment->post_title 377 ]; 378 } 379 } 380 381 382 /** 383 * Filter text content to allow only safe HTML. 384 * 385 * @param string $content Text content to filter. 386 * 387 * @return string Filtered content containing only the allowed HTML. 388 * @since 1.0.0 389 */ 390 if ( ! function_exists( 'spel_kses_post' ) ) { 391 function spel_kses_post( $content ): string { 392 $allowed_tag = [ 393 'strong' => [], 394 'br' => [], 395 'p' => [ 396 'class' => [], 397 'style' => [], 398 ], 399 'i' => [ 400 'class' => [], 401 'style' => [], 402 ], 403 'ul' => [ 404 'class' => [], 405 'style' => [], 406 ], 407 'li' => [ 408 'class' => [], 409 'style' => [], 410 ], 411 'span' => [ 412 'class' => [], 413 'style' => [], 414 ], 415 'a' => [ 416 'href' => [], 417 'class' => [], 418 'title' => [] 419 ], 420 'div' => [ 421 'class' => [], 422 'style' => [], 423 ], 424 'h1' => [ 425 'class' => [], 426 'style' => [] 427 ], 428 'h2' => [ 429 'class' => [], 430 'style' => [] 431 ], 432 'h3' => [ 433 'class' => [], 434 'style' => [] 435 ], 436 'h4' => [ 437 'class' => [], 438 'style' => [] 439 ], 440 'h5' => [ 441 'class' => [], 442 'style' => [] 443 ], 444 'h6' => [ 445 'class' => [], 446 'style' => [] 447 ], 448 'img' => [ 449 'class' => [], 450 'style' => [], 451 'height' => [], 452 'width' => [], 453 'src' => [], 454 'srcset' => [], 455 'alt' => [], 456 ], 457 458 ]; 459 460 return wp_kses( $content, $allowed_tag ); 461 } 462 } 463 464 465 /** 466 * Tab data 467 * 468 * @param array $getCats 469 * @param array $schedule_cats 470 * 471 * @return array 472 * @since 1.0.0 473 */ 474 if ( ! function_exists( 'spel_get_tab_data' ) ) { 475 function spel_get_tab_data( $getCats, $schedule_cats ): array { 476 $tab_data = []; 477 478 foreach ( $getCats as $val ) { 479 $matching_data = []; 480 481 foreach ( $schedule_cats as $data ) { 482 if ( $val === $data['tab_title'] ) { 483 $matching_data[] = $data; 484 } 485 } 486 487 $tab_data[ $val ] = $matching_data; 488 } 489 490 return $tab_data; 491 } 492 } 493 494 495 /** 496 * Get reading time 497 * 498 * @param int $words_per_minute 241 499 * 242 500 * @return string 243 */ 244 if ( ! function_exists( 'spel_get_post_category_list' ) ) { 245 function spel_get_post_category_list(): void 246 { 247 $categories = get_categories(); 248 249 if ( ! empty( $categories ) ) { 250 echo '<span class="blog-category">'; 251 252 $category_names = array(); 253 254 if ( is_array( $categories ) ) { 255 foreach ( $categories as $category ) { 256 $category_link = get_category_link( $category->term_id ); 257 $category_names[] = '<a href="' . esc_url( $category_link ) . '">' . esc_html( $category->name ) . '</a>'; 258 } 259 } 260 261 echo esc_html( implode( ', ', $category_names ) ); 262 263 echo '</span>'; 264 } else { 265 echo esc_html__( 'No categories found.', 'spider-elements' ); 266 } 267 } 268 } 269 270 271 /** 272 * Get an author name array 273 * 274 * @param string $term 275 * 276 * @return array 277 */ 278 if ( ! function_exists( 'spel_get_post_author_name' ) ) { 279 function spel_get_post_author_name(): void 280 { 281 global $post; 282 $byline = sprintf( 283 /* translators: %s: post author. */ 284 esc_html_x( 'By: %s', 'post author', 'spider-elements' ), 285 '<span class="author"><a class="url fn n" href="' . esc_url( get_author_posts_url( $post->post_author ) ) . '">' . esc_html( get_the_author_meta( 286 'display_name', 287 $post->post_author 288 ) ) . '</a></span>' 289 ); 290 291 echo wp_kses_post( $byline ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 292 } 293 } 294 295 /** 296 * Get Default Image Elementor 297 * 298 * @param $settins_key 299 * @param string $class 300 * @param string $alt 301 */ 302 if ( ! function_exists( 'spel_el_image' ) ) { 303 function spel_el_image( $settings_key = [], $alt = '', $class = '', $atts = [] ): void { 304 if ( ! empty( $settings_key['id'] ) ) { 305 // WordPress handles escaping internally here 306 echo wp_get_attachment_image( $settings_key['id'], 'full', false, [ 'class' => esc_attr( $class ) ] ); 307 } elseif ( ! empty( $settings_key['url'] ) && empty( $settings_key['id'] ) ) { 308 $class_attr = ! empty( $class ) ? ' class="' . esc_attr( $class ) . '"' : ''; 309 $atts_str = ''; 310 311 if ( ! empty( $atts ) ) { 312 foreach ( $atts as $k => $att ) { 313 $atts_str .= ' ' . esc_attr( $k ) . '="' . esc_attr( $att ) . '"'; 314 } 315 } 316 317 printf( 318 '<img src="%1$s"%2$s alt="%3$s"%4$s />', 319 esc_url( $settings_key['url'] ), 320 wp_kses_post( $class_attr ), // Escape class attribute 321 esc_attr( $alt ), 322 wp_kses_post( $atts_str ) // Escape attributes string 323 ); 324 } 325 } 326 } 327 328 329 330 /** 331 * Get Default Image Elementor 332 * 333 * @param $settins_key 334 * @param string $class 335 * @param string $alt 336 */ 337 if ( ! function_exists( 'spel_el_image_caption' ) ) { 338 function spel_el_image_caption( $image_id = '' ): array 339 { 340 $img_attachment = get_post( $image_id ); 341 342 return array( 343 'alt' => get_post_meta( $img_attachment->ID, '_wp_attachment_image_alt', true ), 344 'caption' => $img_attachment->post_excerpt, 345 'href' => get_permalink( $img_attachment->ID ), 346 'src' => $img_attachment->guid, 347 'title' => $img_attachment->post_title 348 ); 349 } 350 } 351 352 353 /** 354 * @param string $content Text content to filter. 355 * 356 * @return string Filtered content containing only the allowed HTML. 357 */ 358 if ( ! function_exists( 'spel_kses_post' ) ) { 359 function spel_kses_post( $content ): string 360 { 361 $allowed_tag = array( 362 'strong' => [], 363 'br' => [], 364 'p' => [ 365 'class' => [], 366 'style' => [], 367 ], 368 'i' => [ 369 'class' => [], 370 'style' => [], 371 ], 372 'ul' => [ 373 'class' => [], 374 'style' => [], 375 ], 376 'li' => [ 377 'class' => [], 378 'style' => [], 379 ], 380 'span' => [ 381 'class' => [], 382 'style' => [], 383 ], 384 'a' => [ 385 'href' => [], 386 'class' => [], 387 'title' => [] 388 ], 389 'div' => [ 390 'class' => [], 391 'style' => [], 392 ], 393 'h1' => [ 394 'class' => [], 395 'style' => [] 396 ], 397 'h2' => [ 398 'class' => [], 399 'style' => [] 400 ], 401 'h3' => [ 402 'class' => [], 403 'style' => [] 404 ], 405 'h4' => [ 406 'class' => [], 407 'style' => [] 408 ], 409 'h5' => [ 410 'class' => [], 411 'style' => [] 412 ], 413 'h6' => [ 414 'class' => [], 415 'style' => [] 416 ], 417 'img' => [ 418 'class' => [], 419 'style' => [], 420 'height' => [], 421 'width' => [], 422 'src' => [], 423 'srcset' => [], 424 'alt' => [], 425 ], 426 427 ); 428 429 return wp_kses( $content, $allowed_tag ); 430 } 431 } 432 433 434 /** 435 * Tab data 436 * 437 * @param $getCats 438 * @param $schedule_cats 439 * 440 * @return array 441 */ 442 if ( ! function_exists( 'spel_get_tab_data' ) ) { 443 function spel_get_tab_data( $getCats, $schedule_cats ): array 444 { 445 $tab_data = []; 446 447 foreach ( $getCats as $val ) { 448 $matching_data = []; 449 450 foreach ( $schedule_cats as $data ) { 451 if ( $data['tab_title'] == $val ) { 452 $matching_data[] = $data; 453 } 454 } 455 456 $tab_data[ $val ] = $matching_data; 457 } 458 459 return $tab_data; 460 } 461 } 462 463 464 /** 465 * Get reading time 466 * 467 * @param string $term 468 * 469 * @return string 501 * @since 1.0.0 470 502 */ 471 503 if ( ! function_exists( 'spel_get_reading_time' ) ) { 472 function spel_get_reading_time( $words_per_minute = 200 ): string 473 { 474 $content = get_post_field( 'post_content', get_the_ID() ); 475 $word_count = str_word_count( wp_strip_all_tags( $content ) ); 476 $reading_time = ceil( $word_count / $words_per_minute ); 477 $timer = _n( 'minute', 'minutes', $reading_time, 'spider-elements' ); 478 479 return sprintf( '%d %s', $reading_time, $timer ); 480 } 504 function spel_get_reading_time( $words_per_minute = 200 ): string { 505 $content = get_post_field( 'post_content', get_the_ID() ); 506 $word_count = str_word_count( wp_strip_all_tags( $content ) ); 507 $reading_time = ceil( $word_count / $words_per_minute ); 508 $timer = _n( 'minute', 'minutes', $reading_time, 'spider-elements' ); 509 510 return sprintf( '%d %s', $reading_time, $timer ); 511 } 481 512 } 482 513 … … 484 515 * Render Dynamic Image 485 516 * @param $key 486 * @param $class 517 * @param $size 518 * @param $atts 487 519 * @return void 520 * @since 1.0.0 488 521 */ 489 522 if ( ! function_exists( 'spel_dynamic_image' ) ) { 490 function spel_dynamic_image( $key, $size = 'full', $atts = [] ): void 491 { 492 $image = wp_get_attachment_image( $key['id'], $size, '', $atts ); 493 echo wp_kses( $image, [ 494 'img' => [ 495 'class' => [], 496 'style' => [], 497 'height' => [], 498 'width' => [], 499 'src' => [], 500 'srcset' => [], 501 'alt' => [], 502 ], 503 ]); 504 } 505 } 506 523 function spel_dynamic_image( $key, $size = 'full', $atts = [] ): void { 524 $image = wp_get_attachment_image( $key['id'], $size, '', $atts ); 525 echo wp_kses( $image, [ 526 'img' => [ 527 'class' => [], 528 'style' => [], 529 'height' => [], 530 'width' => [], 531 'src' => [], 532 'srcset' => [], 533 'alt' => [], 534 ], 535 ] ); 536 } 537 } 507 538 508 539 … … 515 546 * 516 547 * @return array An associative array with post-IDs as keys and post-titles as values. 548 * @since 1.0.0 517 549 */ 518 550 if ( ! function_exists( 'spel_get_query_post_list' ) ) { 519 function spel_get_query_post_list( $post_type = 'any', $limit = -1, $search = '' ): array 520 { 521 $args = [ 522 'post_type' => $post_type, 523 'post_status' => 'publish', 524 'posts_per_page' => $limit, 525 's' => $search, // Search term 526 ]; 527 528 $query = new WP_Query( $args ); 529 530 $data = []; 531 if ( $query->have_posts() ) { 532 while ( $query->have_posts() ) { 533 $query->the_post(); 534 $data[ get_the_ID() ] = get_the_title(); 535 } 536 } 537 538 wp_reset_postdata(); // Reset post data after custom query 539 540 return $data; 541 } 551 function spel_get_query_post_list( $post_type = 'any', $limit = -1, $search = '' ): array { 552 $args = [ 553 'post_type' => $post_type, 554 'post_status' => 'publish', 555 'posts_per_page' => $limit, 556 's' => $search, // Search term 557 ]; 558 559 $query = new WP_Query( $args ); 560 561 $data = []; 562 if ( $query->have_posts() ) { 563 while ( $query->have_posts() ) { 564 $query->the_post(); 565 $data[ get_the_ID() ] = get_the_title(); 566 } 567 } 568 569 wp_reset_postdata(); // Reset post data after custom query 570 571 return $data; 572 } 542 573 } 543 574 … … 546 577 * Get all elementor page templates 547 578 * 548 * @param null $type579 * @param string|null $type 549 580 * 550 581 * @return array 582 * @since 1.0.0 551 583 */ 552 584 if ( ! function_exists( 'spel_get_el_templates' ) ) { 553 function spel_get_el_templates( $type = null ): array 554 { 555 $options = []; 556 557 if ( $type ) { 558 559 $args = [ 560 'post_type' => 'elementor_library', 561 'posts_per_page' => -1, 562 ]; 563 564 $args['tax_query'] = [ 565 [ 566 'taxonomy' => 'elementor_library_type', 567 'field' => 'slug', 568 'terms' => $type, 569 ], 570 ]; 571 572 $page_templates = get_posts( $args ); 573 574 if ( ! empty( $page_templates ) && ! is_wp_error( $page_templates ) ) { 575 foreach ( $page_templates as $post ) { 576 $options[ $post->ID ] = $post->post_title; 577 } 578 } 579 } else { 580 $options = spel_get_query_post_list( 'elementor_library' ); 581 } 582 583 return $options; 584 } 585 function spel_get_el_templates( $type = null ): array { 586 $options = []; 587 588 if ( $type ) { 589 590 $args = [ 591 'post_type' => 'elementor_library', 592 'posts_per_page' => -1, 593 ]; 594 595 $args['tax_query'] = [ 596 [ 597 'taxonomy' => 'elementor_library_type', 598 'field' => 'slug', 599 'terms' => $type, 600 ], 601 ]; 602 603 $page_templates = get_posts( $args ); 604 605 if ( ! empty( $page_templates ) && ! is_wp_error( $page_templates ) ) { 606 foreach ( $page_templates as $post ) { 607 $options[ $post->ID ] = $post->post_title; 608 } 609 } 610 } else { 611 $options = spel_get_query_post_list( 'elementor_library' ); 612 } 613 614 return $options; 615 } 585 616 } 586 617 … … 590 621 * 591 622 * @return array Server environment information. 623 * @since 1.0.0 592 624 */ 593 625 if ( ! function_exists( 'spel_get_environment_info' ) ) { 594 function spel_get_environment_info(): array 595 { 596 597 // Figure out cURL version, if installed. 598 $curl_version = ''; 599 if ( function_exists( 'curl_version' ) ) { 600 $curl_version = curl_version(); 601 $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; 602 } 603 604 // WP memory limit. 605 $wp_memory_limit = spel_readable_number(WP_MEMORY_LIMIT); 606 if ( function_exists( 'memory_get_usage' ) ) { 607 $wp_memory_limit = max( $wp_memory_limit, spel_readable_number( @ini_get( 'memory_limit' ) ) ); 608 } 609 610 return array( 611 'home_url' => get_option( 'home' ), 612 'site_url' => get_option( 'siteurl' ), 613 'version' => SPEL_VERSION, 614 'wp_version' => get_bloginfo( 'version' ), 615 'wp_multisite' => is_multisite(), 616 'wp_memory_limit' => $wp_memory_limit, 617 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ), 618 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ), 619 'language' => get_locale(), 620 'external_object_cache' => wp_using_ext_object_cache(), 621 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) : '', 622 'php_version' => phpversion(), 623 'php_post_max_size' => spel_readable_number( ini_get( 'post_max_size' ) ), 624 'php_max_execution_time' => ini_get( 'max_execution_time' ), 625 'php_max_input_vars' => ini_get( 'max_input_vars' ), 626 'curl_version' => $curl_version, 627 'suhosin_installed' => extension_loaded( 'suhosin' ), 628 'max_upload_size' => wp_max_upload_size(), 629 'default_timezone' => date_default_timezone_get(), 630 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ), 631 'soapclient_enabled' => class_exists( 'SoapClient' ), 632 'domdocument_enabled' => class_exists( 'DOMDocument' ), 633 'gzip_enabled' => is_callable( 'gzopen' ), 634 'mbstring_enabled' => extension_loaded( 'mbstring' ), 635 ); 636 637 } 626 function spel_get_environment_info(): array { 627 628 // Figure out cURL version, if installed. 629 $curl_version = ''; 630 if ( function_exists( 'curl_version' ) ) { 631 $curl_version = curl_version(); 632 $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; 633 } 634 635 // WP memory limit. 636 $wp_memory_limit = spel_readable_number( WP_MEMORY_LIMIT ); 637 if ( function_exists( 'memory_get_usage' ) ) { 638 $wp_memory_limit = max( $wp_memory_limit, spel_readable_number( @ini_get( 'memory_limit' ) ) ); 639 } 640 641 return [ 642 'home_url' => get_option( 'home' ), 643 'site_url' => get_option( 'siteurl' ), 644 'version' => SPEL_VERSION, 645 'wp_version' => get_bloginfo( 'version' ), 646 'wp_multisite' => is_multisite(), 647 'wp_memory_limit' => $wp_memory_limit, 648 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ), 649 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ), 650 'language' => get_locale(), 651 'external_object_cache' => wp_using_ext_object_cache(), 652 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) : '', 653 'php_version' => phpversion(), 654 'php_post_max_size' => spel_readable_number( ini_get( 'post_max_size' ) ), 655 'php_max_execution_time' => ini_get( 'max_execution_time' ), 656 'php_max_input_vars' => ini_get( 'max_input_vars' ), 657 'curl_version' => $curl_version, 658 'suhosin_installed' => extension_loaded( 'suhosin' ), 659 'max_upload_size' => wp_max_upload_size(), 660 'default_timezone' => date_default_timezone_get(), 661 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ), 662 'soapclient_enabled' => class_exists( 'SoapClient' ), 663 'domdocument_enabled' => class_exists( 'DOMDocument' ), 664 'gzip_enabled' => is_callable( 'gzopen' ), 665 'mbstring_enabled' => extension_loaded( 'mbstring' ), 666 ]; 667 668 } 638 669 } 639 670 … … 646 677 */ 647 678 if ( ! function_exists( 'spel_readable_number' ) ) { 648 function spel_readable_number($size): int 649 { 650 651 // Get the last character of the size string 652 $suffix = substr($size, -1); 653 654 // Remove the last character from the size string 655 $value = substr($size, 0, -1); 656 657 // Convert suffix to lowercase for case-insensitive comparison 658 $suffix = strtolower($suffix); 659 660 $multipliers = [ 661 'p' => 1024, 662 't' => 1024, 663 'g' => 1024, 664 'm' => 1024, 665 'k' => 1024, 666 ]; 667 668 // Check if the suffix is a valid multiplier 669 if (array_key_exists($suffix, $multipliers)) { 670 $value *= $multipliers[$suffix]; 671 } 672 673 // Return the result 674 return (int)$value; 675 676 } 677 } 678 679 680 if ( !function_exists('spel_pagination') ) { 681 function spel_pagination($query, $class = 'spel-pagination', $prev = '', $next = ''): void 682 { 683 684 if ( $query->max_num_pages <= 1 ) { 685 return; // No pagination needed if only one page 686 } 687 688 $default_prev = '<img src="' . esc_url(SPEL_IMG . '/icons/prev.svg') . '" alt="' . esc_attr__('arrow-left', 'spider-elements') . '" class="me-2" />' . esc_html__('Prev', 'spider-elements'); 689 $default_next = esc_html__('Next', 'spider-elements') . '<img src="' . esc_url(SPEL_IMG . '/icons/next.svg') . '" alt="' . esc_attr__('arrow-right', 'spider-elements') . '" class="ms-2" />'; 690 691 $prev_text = !empty($prev) ? $prev : $default_prev; 692 $next_text = !empty($next) ? $next : $default_next; 693 694 echo '<ul class="' . esc_attr($class) . '">'; 695 696 $big = 999999999; // need an unlikely integer 697 $current = max(1, get_query_var('paged') ? get_query_var('paged') : (get_query_var('page') ? get_query_var('page') : 1)); 698 699 echo wp_kses_post( 700 paginate_links( array( 701 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ), 702 'format' => '?paged=%#%', 703 'current' => $current, 704 'total' => $query->max_num_pages, 705 'prev_text' => $prev_text, 706 'next_text' => $next_text 707 ) ) 708 ); 709 710 711 echo '</ul>'; 712 } 713 } 714 715 /** 716 * Jobus pagination 717 */ 718 if ( !function_exists('spel_archive_query') ) { 719 function spel_archive_query($query): void 720 { 721 if ( $query->is_main_query() && !is_admin() && !is_home() ) { 722 $query->set('posts_per_page', -1); 723 } 724 } 725 add_action('pre_get_posts', 'spel_archive_query'); 726 } 679 function spel_readable_number( $size ): int { 680 681 // Get the last character of the size string 682 $suffix = substr( $size, -1 ); 683 684 // Remove the last character from the size string 685 $value = substr( $size, 0, -1 ); 686 687 // Convert suffix to lowercase for case-insensitive comparison 688 $suffix = strtolower( $suffix ); 689 690 $multipliers = [ 691 'p' => 1024, 692 't' => 1024, 693 'g' => 1024, 694 'm' => 1024, 695 'k' => 1024, 696 ]; 697 698 // Check if the suffix is a valid multiplier 699 if ( array_key_exists( $suffix, $multipliers ) ) { 700 $value *= $multipliers[ $suffix ]; 701 } 702 703 // Return the result 704 return (int) $value; 705 706 } 707 } 708 709 710 if ( ! function_exists( 'spel_pagination' ) ) { 711 /** 712 * Pagination 713 * 714 * @param WP_Query $query 715 * @param string $class 716 * @param string $prev 717 * @param string $next 718 * @return void 719 */ 720 function spel_pagination( $query, $class = 'spel-pagination', $prev = '', $next = '' ): void { 721 722 if ( $query->max_num_pages <= 1 ) { 723 return; // No pagination needed if only one page 724 } 725 726 $default_prev = '<img src="' . esc_url( SPEL_IMG . '/icons/prev.svg' ) . '" alt="' . esc_attr__( 'arrow-left', 'spider-elements' ) . '" class="me-2" />' . esc_html__( 'Prev', 'spider-elements' ); 727 $default_next = esc_html__( 'Next', 'spider-elements' ) . '<img src="' . esc_url( SPEL_IMG . '/icons/next.svg' ) . '" alt="' . esc_attr__( 'arrow-right', 'spider-elements' ) . '" class="ms-2" />'; 728 729 $prev_text = ! empty( $prev ) ? $prev : $default_prev; 730 $next_text = ! empty( $next ) ? $next : $default_next; 731 732 echo '<ul class="' . esc_attr( $class ) . '">'; 733 734 $big = 999999999; // need an unlikely integer 735 $current = max( 1, get_query_var( 'paged' ) ? get_query_var( 'paged' ) : ( get_query_var( 'page' ) ? get_query_var( 'page' ) : 1 ) ); 736 737 echo wp_kses_post( 738 paginate_links( [ 739 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ), 740 'format' => '?paged=%#%', 741 'current' => $current, 742 'total' => $query->max_num_pages, 743 'prev_text' => $prev_text, 744 'next_text' => $next_text, 745 ] ) 746 ); 747 748 749 echo '</ul>'; 750 } 751 } 752 753 /** 754 * Jobus pagination (Deprecated) 755 * 756 * @param WP_Query $query 757 * @return void 758 * @since 1.0.0 759 * @deprecated 1.8.0 No longer needed as we rely on native query handling. 760 */ 761 if ( ! function_exists( 'spel_archive_query' ) ) { 762 /** 763 * Archive Query 764 * 765 * @param WP_Query $query 766 * @return void 767 */ 768 function spel_archive_query( $query ): void { 769 // Optimization: Removed unbounded query override to prevent performance issues on archive pages 770 } 771 772 add_action( 'pre_get_posts', 'spel_archive_query' ); 773 } -
spider-elements/trunk/readme.txt
r3437647 r3464401 34 34 - [📚 Full Documentation](https://helpdesk.spider-themes.net/docs/spider-elements) 35 35 - [🎥 Live Demo & Widget Showcase](https://spider-elements.spider-themes.net/#widgets) 36 - [🌐 Visit Spider Themes](https://spider-themes.net) 36 37 - [⭐ Upgrade to Pro](https://spider-elements.spider-themes.net/pricing) 37 - [🌐 Visit Spider Themes](https://spider-themes.net)38 38 39 39 **Essential Tools for Web Designers & Developers** … … 43 43 ## Core Widgets Available (Free Version) 44 44 45 **Content & Layout Widgets** 45 ***Content & Layout Widgets:*** 46 46 47 - [**Accordion**](https://spider-elements.spider-themes.net/accordion) – Organize and manage content with smooth collapsible sections, perfect for FAQs, guides, and comprehensive resource documentation. Enhance user experience with elegant accordion functionality. 47 48 - [**Blog Grid**](https://spider-elements.spider-themes.net/blog-grid) – Display your WordPress posts beautifully with multiple customizable layouts, built-in pagination, and responsive design. Perfect for showcasing blog content across all devices. … … 50 51 - [**Icon Box**](https://spider-elements.spider-themes.net/icon-box) – Highlight key features and services with eye-catching custom icons and compelling text. Great for showcasing features, benefits, and value propositions elegantly. 51 52 52 **Visual & Media Widgets** 53 ***Visual & Media Widgets:*** 54 53 55 - [**Video Popup**](https://spider-elements.spider-themes.net/video-popup) – Embed videos in sleek, professional pop-up windows without page reload. Enhance user engagement with smooth video experiences and modal presentation. 54 56 - [**Team Carousel**](https://spider-elements.spider-themes.net/team-carousel) – Showcase team members in dynamic, interactive carousels with smooth transitions. Perfect for displaying staff, employees, and team introductions professionally. … … 59 61 ## Premium Widgets (Pro Version) 60 62 61 **Interactive & Animation Widgets** 63 ***Interactive & Animation Widgets:*** 64 62 65 - [**Box Hover**](https://spider-elements.spider-themes.net/box-hover) – Add stylish hover effects with smooth animations and transitions. Enhance user engagement and interactivity with professional animation effects. 63 66 - [**Flip Box**](https://spider-elements.spider-themes.net/flipbox) – Create dynamic flip effects that reveal hidden content on interaction. Perfect for showcasing before-after, features, or additional information creatively. … … 66 69 - [**Hotspot**](https://spider-elements.spider-themes.net/hotspot) – Add interactive points on images to highlight details and provide information. Great for product demos, educational content, and interactive presentations. 67 70 68 **Advanced Content Widgets** 71 ***Advanced Content Widgets:*** 72 69 73 - [**Image Slider**](https://spider-elements.spider-themes.net/image-slider) – Create beautiful, responsive image slideshows with smooth transitions. Perfect for galleries, portfolios, and showcasing multiple images effectively. 70 74 - [**Video Playlist**](https://spider-elements.spider-themes.net/video-playlist) – Organize and play multiple videos in an interactive playlist. Ideal for tutorials, video content libraries, and multimedia presentations. … … 79 83 ### Quick Features Overview 80 84 81 **User-Friendly Design** 85 ***User-Friendly Design:*** 86 82 87 - Intuitive controls and settings 83 88 - Real-time preview while editing 84 89 - Drag-and-drop simplicity 85 90 86 **Performance Optimized** 91 ***Performance Optimized:*** 92 87 93 - Fast loading times 88 94 - Lightweight code 89 95 - Optimized for all devices 90 96 91 **Developer Friendly** 97 ***Developer Friendly:*** 98 92 99 - Clean, well-documented code 93 100 - Easy customization hooks … … 100 107 4. Drag widgets onto your page 101 108 5. Customize with live preview 102 103 **Need Help?**104 - [📚 Full Documentation](https://helpdesk.spider-themes.net/docs/spider-elements)105 - [🎥 Video Tutorials](https://spider-elements.spider-themes.net/#widgets)106 - [🚀 Live Demo](https://spider-elements.spider-themes.net/#widgets)107 - [⭐ Upgrade to Pro](https://spider-elements.spider-themes.net/pricing)108 109 109 110 ## WHAT’S NEXT? … … 218 219 == Changelog == 219 220 220 = 1.8.0 (11 January 2026) = 221 New: Revamped Dashboard UI with modern design system and quick stats 222 New: Added Search functionality for Widgets and Features with real-time filtering 223 New: Added Toast notification system for better user feedback on save 224 New: Added keyboard shortcuts (Ctrl+S to save, Ctrl+F to search) 225 Improved: System Requirements section with zebra striping and better visibility 226 Improved: Sidebar navigation active states and hover effects 227 Tweaked: Refined typography, spacing, and micro-interactions across the dashboard 221 = 1.8.0 (18 February 2026) = 222 * New: Revamped Dashboard UI with modern design system and quick stats 223 * New: Added Search functionality for Widgets and Features with real-time filtering 224 * New: Added Toast notification system for better user feedback on save 225 * New: Added keyboard shortcuts (Ctrl+S to save, Ctrl+F to search) 226 * New: Added Antimanual and Jobus plugins to the recommended plugins list in the dashboard. 227 * Improved: System Requirements section with zebra striping and better visibility 228 * Improved: Sidebar navigation active states and hover effects 229 * Improved: Refined typography, spacing, and micro-interactions across the dashboard 230 * Improved: Dashboard page redesigned with enhanced UI and overall user experience. 231 * Improved: Dashboard now remembers and keeps the last opened tab active for smoother navigation. 232 * Improved: Admin classes now load conditionally to reduce unnecessary frontend overhead. 233 * Improved: Plugin installer optimized to avoid heavy filesystem scans and reduce load time. 234 * Improved: Removed unconditional Plugin_Installer loading on the frontend for better performance. 235 * Improved: Archive queries optimized by removing unbounded posts_per_page overrides. 236 * Improved: Extensive backend performance optimizations applied across core plugin components for faster execution and lower resource usage. 237 * Fixed: XSS vulnerability in the image helper function by properly sanitizing attribute inputs. 238 * Fixed: Logic issues resolved and internal documentation improved with WPCS coding standards compliance. 228 239 229 240 = 1.7.0 (11 December 2025) = 230 New: Added submenu items for improved dashboard navigation231 Fixed: Tab switcher functionality issue in the Spider Elements dashboard232 Tweaked: Minor UI enhancements and general performance improvements across the dashboard233 Improved: Enhanced RTL dashboard layout for better usability234 Security: Implemented LFI (Local File Inclusion) protection to prevent unauthorized file access235 Updated: Freemius SDK updated to 2.13.0241 * New: Added submenu items for improved dashboard navigation 242 * Fixed: Tab switcher functionality issue in the Spider Elements dashboard 243 * Tweaked: Minor UI enhancements and general performance improvements across the dashboard 244 * Improved: Enhanced RTL dashboard layout for better usability 245 * Security: Implemented LFI (Local File Inclusion) protection to prevent unauthorized file access 246 * Updated: Freemius SDK updated to 2.13.0 236 247 237 248 = 1.6.7 (11 November 2025) = 238 Fixed: Blog title function issue resolved to ensure proper display239 Fixed: Nonce field name mismatch corrected in filters.php for secure form handling240 Fixed: Missing Elementor Utils class import causing fatal error in Video Playlist widget rendering241 Fixed: Video Playlist widget showing raw paragraph tags in description by replacing esc_html with wp_kses_post242 Tweaked: Adjusted alert margins in CSS for improved visual spacing243 Secured: Added nonce verification for form submissions to strengthen security244 Secured: Added proper sanitization in nonce verification for safer data validation245 Updated: Dashboard templates modified to maintain consistent field naming conventions249 * Fixed: Blog title function issue resolved to ensure proper display 250 * Fixed: Nonce field name mismatch corrected in filters.php for secure form handling 251 * Fixed: Missing Elementor Utils class import causing fatal error in Video Playlist widget rendering 252 * Fixed: Video Playlist widget showing raw paragraph tags in description by replacing esc_html with wp_kses_post 253 * Tweaked: Adjusted alert margins in CSS for improved visual spacing 254 * Secured: Added nonce verification for form submissions to strengthen security 255 * Secured: Added proper sanitization in nonce verification for safer data validation 256 * Updated: Dashboard templates modified to maintain consistent field naming conventions 246 257 247 258 = 1.6.6 (1 October 2025) = 248 Fixed: Vulnerability issues249 Tweaked: Spider Elements widget prefix (SE) has been removed250 Updated: Freemius SDK updated to 2.12.2259 * Fixed: Vulnerability issues 260 * Tweaked: Spider Elements widget prefix (SE) has been removed 261 * Updated: Freemius SDK updated to 2.12.2 251 262 252 263 = 1.6.5 (23 Jun 2025) = 253 New: Added pagination and show/hide options to presets 1, 2, 3, and 4 of the Blog Grid widget 254 Fixed: Free and Pro Widget and features checked issue on Dashboard 255 Fixed: Testimonials ratting issue layout 3,4 and 6 256 Fixed: Tabs widget dark mood issue 257 Tweaked: Blog carousel nav arrow 258 Tweaked: ID added in the sticky tabs 259 Tweaked: SE prefix added before Widgets name 260 261 = 1.6.4 (15 May 2025) = 262 Fixed: Resolved Pagination issue of Blog grid widget 263 Tweaked: Compatibility with docy dark mode 264 Updated: Freemius SDK updated to 2.12.0 264 * New: Added pagination and show/hide options to presets 1, 2, 3, and 4 of the Blog Grid widget 265 * Fixed: Free and Pro Widget and features checked issue on Dashboard 266 * Fixed: Testimonials ratting issue layout 3,4 and 6 267 * Fixed: Tabs widget dark mood issue 268 * Tweaked: Blog carousel nav arrow 269 * Tweaked: ID added in the sticky tabs 270 * Tweaked: SE prefix added before Widgets name 271 272 [See changelog for all versions](https://spider-elements.spider-themes.net/changelog/) -
spider-elements/trunk/spider-elements.php
r3416399 r3464401 5 5 * Plugin URI: https://spider-elements.spider-themes.net 6 6 * Description: Spider Elements is a hassle-free addon bundle with super useful widgets for building beautiful websites. Plug and play to create stunning designs effortlessly. 7 * Version: 1. 7.07 * Version: 1.8.0 8 8 * Requires at least: 5.0 9 * Tested up to: 6. 89 * Tested up to: 6.9 10 10 * Requires PHP: 7.4 11 11 * Author: spider-themes … … 102 102 * @var string The plugin version. 103 103 */ 104 const VERSION = '1. 7.0';104 const VERSION = '1.8.0'; 105 105 106 106 … … 153 153 154 154 // Init Plugin 155 add_action( 'plugins_loaded', array( $this, 'init_plugin' ));155 add_action( 'plugins_loaded', [ $this, 'init_plugin' ] ); 156 156 157 157 // Load text domain for localization … … 253 253 require_once __DIR__ . '/includes/filters.php'; 254 254 255 require_once __DIR__ . '/includes/Admin/Module_Settings.php';256 257 // Admin and Frontend Scripts Loaded258 require_once __DIR__ . '/includes/Admin/Plugin_Installer.php';259 260 255 $theme = wp_get_theme(); 261 256 if ( spel_is_premium() || in_array( $theme->get( 'Name' ), [ 'jobi', 'Jobi', 'jobi-child', 'Jobi Child' ] ) ) { … … 266 261 // Admin UI 267 262 if ( is_admin() ) { 263 require_once __DIR__ . '/includes/Admin/Module_Settings.php'; 264 265 // Admin Scripts Loaded 266 require_once __DIR__ . '/includes/Admin/Plugin_Installer.php'; 267 268 268 require_once __DIR__ . '/includes/Admin/Assets.php'; 269 269 require_once __DIR__ . '/includes/Admin/Dashboard.php'; … … 313 313 314 314 // Frontend UI 315 new SPEL\includes\Admin\Plugin_Installer();316 315 new SPEL\includes\Frontend\Assets(); 317 316 } … … 378 377 379 378 /** 379 * Define Constants 380 * 381 * Define plugin constants. 382 * 380 383 * @return void 381 * @since 1.7.0382 * @access public383 * @static384 384 */ 385 385 public function define_constants(): void { -
spider-elements/trunk/widgets/templates/video-playlist/video-playlist-1.php
r3393425 r3464401 3 3 exit; // Exit if accessed directly. 4 4 } 5 $widget_id = $this->get_id(); 5 6 ?> 6 7 … … 10 11 <div class="ezd-lg-col-7"> 11 12 <div class="video_player"> 12 <div class="tab-content video_tabs" id="<?php e sc_attr( get_the_ID()); ?>">13 <div class="tab-content video_tabs" id="<?php echo esc_attr( get_the_ID() . '-' . $widget_id ); ?>"> 13 14 <?php 14 15 $all_videos = $settings['tabs'] ?? ''; … … 20 21 ?> 21 22 <div class="tab-pane ezd-tab-box pt-0 <?php echo esc_attr( $active ); ?>" 22 id="video_<?php echo esc_attr( $ i ++ ); ?>">23 id="video_<?php echo esc_attr( $widget_id . '_' . $i ++ ); ?>"> 23 24 <div class="artplayer-app" 24 25 data-src="<?php echo esc_url( $child_video['video_upload']['url'] ); ?>"> … … 65 66 ?> 66 67 <div class="card accordion-panel spe_accordion_inner"> 67 <div class="card spe-accordion" id="configuration<?php echo esc_attr( $ count ); ?>-tab">68 <div class="card spe-accordion" id="configuration<?php echo esc_attr( $widget_id . '_' . $count ); ?>-tab"> 68 69 <div class="card-header"> 69 70 <button class="text-left accordion-header <?php echo esc_attr( $nav_collapse ); ?>"> … … 89 90 </div> 90 91 </div> 91 <div id="configuration<?php echo esc_attr( $ count ); ?>" class="accordion-content collapse">92 <div id="configuration<?php echo esc_attr( $widget_id . '_' . $count ); ?>" class="accordion-content collapse"> 92 93 <div class="card-body"> 93 94 <ul class="nav nav-tabs ezd-tab-menu"> … … 99 100 <li class="nav-item"> 100 101 <a class="nav-link<?php esc_attr( $is_active ); ?>" 101 href="#video_<?php echo esc_attr( $ i ++ ); ?>">102 href="#video_<?php echo esc_attr( $widget_id . '_' . $i ++ ); ?>"> 102 103 <div class="media ezd-d-flex"> 103 104 <?php if ( ! empty( $child_video['thumbnail']['url'] ) ) : ?> … … 200 201 201 202 document.addEventListener('DOMContentLoaded', function() { 202 let video = $('#video_ 0');203 let video = $('#video_<?php echo esc_attr( $widget_id ); ?>_0'); 203 204 setTimeout(function() { 204 205 $('.video_slider_area').addClass('loaded').css('height', 'auto');
Note: See TracChangeset
for help on using the changeset viewer.