141 lines
6.1 KiB
HTML
141 lines
6.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="description" content="FITRA - Secure file transfer API for fast and reliable file sharing for developers">
|
|
<meta name="keywords" content="file transfer, API, file sharing, secure upload, download">
|
|
<meta name="author" content="FITRA">
|
|
<meta name="robots" content="index, follow">
|
|
|
|
<!-- Open Graph / Facebook -->
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:title" content="{{.Title}} - FITRA - File transfer API">
|
|
<meta property="og:description" content="FITRA - Secure file transfer API for fast and reliable file sharing for developers">
|
|
<meta property="og:url" content="{{.BaseURL}}">
|
|
<meta property="og:site_name" content="FITRA">
|
|
<meta property="og:image" content="{{.BaseURL}}/static/og-image.png">
|
|
<meta property="og:image:width" content="1200">
|
|
<meta property="og:image:height" content="630">
|
|
<meta property="og:image:alt" content="FITRA - Secure file transfer API">
|
|
|
|
<!-- Twitter -->
|
|
<meta property="twitter:card" content="summary_large_image">
|
|
<meta property="twitter:title" content="{{.Title}} - FITRA - File transfer API">
|
|
<meta property="twitter:description" content="FITRA - Secure file transfer API for fast and reliable file sharing for developers">
|
|
<meta property="twitter:image" content="{{.BaseURL}}/static/og-image.png">
|
|
<meta property="twitter:image:alt" content="FITRA - Secure file transfer API">
|
|
|
|
<title>{{.Title}} - FITRA - File transfer API</title>
|
|
|
|
<link rel="icon" type="image/png" href="/static/favicon-96x96.png" sizes="96x96" />
|
|
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg" />
|
|
<link rel="shortcut icon" href="/static/favicon.ico" />
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png" />
|
|
<link rel="manifest" href="/static/site.webmanifest" />
|
|
|
|
<link rel="stylesheet" href="/static/main.css">
|
|
|
|
<script
|
|
src="https://a.adhd.sh/api/script.js"
|
|
data-site-id="8"
|
|
data-track-errors="true"
|
|
data-session-replay="true"
|
|
defer
|
|
></script>
|
|
</head>
|
|
<body>
|
|
{{block "content" .}}{{end}}
|
|
|
|
<script>
|
|
async function loadStorageInfo() {
|
|
try {
|
|
const response = await fetch('/storage');
|
|
const data = await response.json();
|
|
const storage = data.storage;
|
|
|
|
document.getElementById('storage-used').textContent = `${storage.used_gb.toFixed(2)} GB used`;
|
|
document.getElementById('storage-percent').textContent = `${storage.usage_percent.toFixed(1)}% full`;
|
|
document.getElementById('storage-total').textContent = `${storage.max_gb} GB total`;
|
|
document.getElementById('progress-fill').style.width = `${storage.usage_percent}%`;
|
|
} catch (error) {
|
|
const used = document.getElementById('storage-used');
|
|
const percent = document.getElementById('storage-percent');
|
|
const total = document.getElementById('storage-total');
|
|
if (used) used.textContent = 'Error loading storage info';
|
|
if (percent) percent.textContent = '';
|
|
if (total) total.textContent = '';
|
|
}
|
|
}
|
|
|
|
function initTabs() {
|
|
const btns = Array.from(document.querySelectorAll('.tab-btn'));
|
|
const panels = Array.from(document.querySelectorAll('.tab-panel'));
|
|
if (!btns.length || !panels.length) return;
|
|
|
|
function activate(tab) {
|
|
btns.forEach(b => {
|
|
const isActive = b.dataset.tab === tab;
|
|
b.classList.toggle('active', isActive);
|
|
b.setAttribute('aria-selected', String(isActive));
|
|
});
|
|
panels.forEach(p => {
|
|
const isActive = p.id === `tab-${tab}`;
|
|
p.classList.toggle('active', isActive);
|
|
if (isActive) {
|
|
p.removeAttribute('hidden');
|
|
} else {
|
|
p.setAttribute('hidden', '');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Read initial state from hash
|
|
const hash = window.location.hash.replace('#', '');
|
|
if (hash === 'changelog' || hash === 'about' || hash === 'guide') {
|
|
activate(hash);
|
|
} else {
|
|
activate('guide');
|
|
}
|
|
|
|
// Wire click handlers
|
|
btns.forEach(b => b.addEventListener('click', () => {
|
|
const tab = b.dataset.tab;
|
|
activate(tab);
|
|
// push state without jumping
|
|
history.replaceState(null, '', `#${tab}`);
|
|
}));
|
|
}
|
|
|
|
// Initialize on DOM ready
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
loadStorageInfo();
|
|
initTabs();
|
|
});
|
|
|
|
function copyToClipboard(text) {
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
const button = event.target;
|
|
const originalText = button.innerHTML;
|
|
button.innerHTML = '✅ Copied!';
|
|
button.style.background = 'linear-gradient(135deg, #28a745, #20c997)';
|
|
|
|
setTimeout(() => {
|
|
button.innerHTML = originalText;
|
|
button.style.background = 'linear-gradient(135deg, #667eea, #764ba2)';
|
|
}, 2000);
|
|
}).catch(() => {
|
|
const button = event.target;
|
|
const originalText = button.innerHTML;
|
|
button.innerHTML = '❌ Failed';
|
|
button.style.background = 'linear-gradient(135deg, #dc3545, #c82333)';
|
|
|
|
setTimeout(() => {
|
|
button.innerHTML = originalText;
|
|
button.style.background = 'linear-gradient(135deg, #667eea, #764ba2)';
|
|
}, 2000);
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |