({ isPro })
| 2757 | } |
| 2758 | |
| 2759 | function initGatewaysSection({ isPro }) { |
| 2760 | const container = document.getElementById('gatewaysContent'); |
| 2761 | if (!container || container.__initialized) return; |
| 2762 | container.__initialized = true; |
| 2763 | |
| 2764 | if (!isPro) { |
| 2765 | container.innerHTML = ` |
| 2766 | <div class="card" style="border-radius: var(--menu-radius); overflow:hidden;"> |
| 2767 | <div class="card-header py-2"> |
| 2768 | <strong> |
| 2769 | ${escapeHTML(tf('gateway_shares', 'Gateway Shares'))} |
| 2770 | <span class="badge bg-warning text-dark ms-1 align-middle">Pro</span> |
| 2771 | </strong> |
| 2772 | </div> |
| 2773 | <div class="card-body p-2"> |
| 2774 | <div class="small text-muted"> |
| 2775 | ${escapeHTML(tf('gateway_locked_body', 'Expose a scoped source root over SFTP, S3, or MCP with generated start commands and safety checks.'))} |
| 2776 | </div> |
| 2777 | </div> |
| 2778 | </div> |
| 2779 | `; |
| 2780 | return; |
| 2781 | } |
| 2782 | |
| 2783 | container.innerHTML = ` |
| 2784 | <div class="sources-admin"> |
| 2785 | <div class="sources-toolbar"> |
| 2786 | <button type="button" id="gwAddBtn" class="btn btn-sm btn-primary">${escapeHTML(tf('gateway_add', 'Add Gateway'))}</button> |
| 2787 | <button type="button" id="gwRefreshBtn" class="btn btn-sm btn-secondary">${escapeHTML(tf('refresh', 'Refresh'))}</button> |
| 2788 | </div> |
| 2789 | |
| 2790 | <div class="alert alert-info py-2 px-3 small" style="border-radius:8px; margin-bottom:8px;"> |
| 2791 | <div><strong>${escapeHTML(tf('gateway_runtime_title', 'Gateway runtime setup (managed recommended)'))}</strong></div> |
| 2792 | <div>${escapeHTML(tf('gateway_runtime_line_1', '1) Managed Mode can install, start, stop, and restart rclone from this panel.'))}</div> |
| 2793 | <div>${escapeHTML(tf('gateway_runtime_line_2', '2) If rclone is missing, use Download + install or upload a custom binary.'))}</div> |
| 2794 | <div>${escapeHTML(tf('gateway_runtime_line_3', '3) In Docker/container setups, publish each gateway port (example: -p 2022:2022).'))}</div> |
| 2795 | <div>${escapeHTML(tf('gateway_runtime_line_4', '4) Use listen address 0.0.0.0 for LAN access; use 127.0.0.1 for local-only.'))}</div> |
| 2796 | <div>${escapeHTML(tf('gateway_runtime_line_5', '5) Manual snippets are advanced fallback; Test validates config only.'))}</div> |
| 2797 | <a class="small" href="${escapeHTML(withBase('/docs/?page=pro-gateway-shares'))}" target="_blank" rel="noopener noreferrer"> |
| 2798 | ${escapeHTML(tf('gateway_runtime_docs', 'Open Gateway setup guide'))} |
| 2799 | </a> |
| 2800 | </div> |
| 2801 | |
| 2802 | <div id="gwStatus" class="text-muted small" style="margin-bottom:6px;"></div> |
| 2803 | <div id="gwList" class="sources-list"></div> |
| 2804 | |
| 2805 | <hr class="admin-divider"> |
| 2806 | |
| 2807 | <div id="gwFormWrap" class="sources-form"> |
| 2808 | <div class="admin-subsection-title" id="gwFormTitle">${escapeHTML(tf('gateway_add', 'Add Gateway'))}</div> |
| 2809 | <div class="sources-form-grid"> |
| 2810 | <div class="form-group"> |
| 2811 | <label for="gwName">${escapeHTML(tf('gateway_name', 'Name'))}:</label> |
| 2812 | <input type="text" id="gwName" class="form-control" maxlength="120" placeholder="Client SFTP" /> |
| 2813 | </div> |
| 2814 | <div class="form-group"> |
| 2815 | <label for="gwType">${escapeHTML(tf('gateway_type', 'Gateway Type'))}:</label> |
| 2816 | <select id="gwType" class="form-control"> |
no test coverage detected