feat: init proj

This commit is contained in:
2026-03-31 13:11:54 +08:00
commit 8f75ea24d6
38 changed files with 6826 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
import { useState, useEffect } from 'react';
import { config as configApi } from '../api';
export default function Output() {
const [preview, setPreview] = useState('');
const [loading, setLoading] = useState(false);
const [copied, setCopied] = useState(false);
const surgeUrl = `${window.location.origin}/surge`;
const loadPreview = async () => {
setLoading(true);
try {
const data = await configApi.preview();
setPreview(data.config);
} catch (err: any) {
setPreview(`# Error: ${err.message}`);
} finally {
setLoading(false);
}
};
useEffect(() => { loadPreview(); }, []);
const handleCopy = () => {
navigator.clipboard.writeText(surgeUrl);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
<div>
<h2 style={styles.title}></h2>
<p style={styles.subtitle}>Surge </p>
{/* Subscription URL */}
<div style={{
background: 'var(--bg-input)',
border: '1px solid var(--border)',
borderRadius: 'var(--radius)',
padding: 16,
marginBottom: 20,
}}>
<div style={{
fontSize: 10,
fontFamily: 'var(--font-mono)',
color: 'var(--text-muted)',
textTransform: 'uppercase',
letterSpacing: '0.1em',
marginBottom: 8,
}}>
Surge
</div>
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
<code style={{
flex: 1,
fontFamily: 'var(--font-mono)',
fontSize: 13,
color: 'var(--accent)',
userSelect: 'all',
}}>
{surgeUrl}
</code>
<button className="small" onClick={handleCopy}>
{copied ? '已复制' : '复制'}
</button>
</div>
</div>
{/* Preview */}
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
<span style={{
fontSize: 10,
fontFamily: 'var(--font-mono)',
color: 'var(--text-muted)',
textTransform: 'uppercase',
letterSpacing: '0.1em',
}}>
</span>
<button className="small" onClick={loadPreview} disabled={loading}>
{loading ? '加载中...' : '刷新预览'}
</button>
</div>
<pre style={{
background: 'var(--bg-input)',
border: '1px solid var(--border)',
borderRadius: 'var(--radius)',
padding: 16,
fontFamily: 'var(--font-mono)',
fontSize: 11,
lineHeight: 1.6,
color: 'var(--text-secondary)',
overflow: 'auto',
maxHeight: 'calc(100vh - 360px)',
whiteSpace: 'pre-wrap',
wordBreak: 'break-all',
}}>
{preview || '(empty)'}
</pre>
</div>
);
}
const styles = {
title: {
fontFamily: 'var(--font-mono)' as const,
fontSize: 16,
fontWeight: 600 as const,
color: 'var(--text-primary)',
marginBottom: 4,
},
subtitle: {
fontSize: 12,
color: 'var(--text-secondary)',
marginBottom: 20,
},
};