Skip to content

Commit

Permalink
fix: index
Browse files Browse the repository at this point in the history
  • Loading branch information
whes1015 committed Dec 2, 2024
1 parent 4f7df1c commit 940d6aa
Showing 1 changed file with 191 additions and 58 deletions.
249 changes: 191 additions & 58 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,96 +5,167 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TREM Plugins</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/4.0.0/font/MaterialIcons-Regular.ttf"
rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<style>
:root {
--primary-color: #2196f3;
--background-color: #121212;
--surface-color: #1e1e1e;
--text-color: #ffffff;
--secondary-text: #9e9e9e;
}

body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 20px;
background: #f5f5f5;
background-color: var(--background-color);
color: var(--text-color);
}

.container {
max-width: 1200px;
margin: 0 auto;
.stats-card {
background-color: var(--surface-color);
border-radius: 8px;
padding: 20px;
margin: 10px;
}

h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
.plugin-card {
background-color: var(--surface-color);
border-radius: 8px;
margin: 16px 0;
transition: transform 0.2s;
}

.plugins {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
.plugin-card:hover {
transform: translateY(-4px);
}

.plugin-card {
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
.card-content {
padding: 24px !important;
}

.plugin-name {
font-size: 1.4em;
font-weight: bold;
color: #2c3e50;
margin-bottom: 10px;
color: var(--text-color);
}

.plugin-version {
font-size: 0.9em;
color: #666;
margin-bottom: 10px;
color: var(--secondary-text);
}

.plugin-description {
color: #444;
margin-bottom: 15px;
margin: 16px 0;
}

.plugin-meta {
font-size: 0.9em;
color: #666;
.dependency-chip {
background-color: var(--primary-color);
color: white;
margin: 4px;
padding: 4px 12px;
border-radius: 16px;
display: inline-block;
}

.plugin-link {
display: inline-block;
margin-top: 10px;
color: #3498db;
text-decoration: none;
.stats-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}

.plugin-link:hover {
text-decoration: underline;
.sort-buttons {
margin: 20px 0;
}

.dependencies {
margin-top: 10px;
font-size: 0.9em;
.btn {
margin: 0 8px;
}

.dependency {
display: inline-block;
background: #e8f4f8;
padding: 2px 8px;
#readmeModal {
background-color: var(--surface-color);
color: var(--text-color);
max-width: 800px;
max-height: 80vh;
}

.modal-content {
padding: 24px;
}

.search-container {
margin: 20px 0;
}

#searchInput {
color: var(--text-color);
background-color: var(--surface-color);
border: 1px solid var(--primary-color);
padding: 8px;
border-radius: 4px;
margin: 2px;
width: 100%;
}
</style>
</head>

<body>
<div class="container">
<h1>TREM Plugins</h1>
<div id="plugins" class="plugins"></div>
<h1 class="center-align">TREM Plugins</h1>

<div class="stats-container">
<div class="stats-card">
<h5>插件總數</h5>
<p id="totalPlugins">loading...</p>
</div>
<div class="stats-card">
<h5>總下載量</h5>
<p id="totalDownloads">loading...</p>
</div>
<div class="stats-card">
<h5>開發者數量</h5>
<p id="totalAuthors">loading...</p>
</div>
</div>

<div class="search-container">
<input type="text" id="searchInput" placeholder="搜尋插件...">
</div>

<div class="sort-buttons center-align">
<button class="btn waves-effect waves-light" onclick="sortPlugins('name')">
名稱排序
</button>
<button class="btn waves-effect waves-light" onclick="sortPlugins('downloads')">
下載量排序
</button>
<button class="btn waves-effect waves-light" onclick="sortPlugins('updated')">
更新時間排序
</button>
</div>

<div id="plugins"></div>
</div>

<!-- Readme Modal -->
<div id="readmeModal" class="modal">
<div class="modal-content">
<h4 id="readmeTitle"></h4>
<div id="readmeContent"></div>
</div>
<div class="modal-footer">
<button class="modal-close waves-effect waves-green btn-flat">關閉</button>
</div>
</div>

<script>
document.addEventListener('DOMContentLoaded', function () {
M.Modal.init(document.querySelectorAll('.modal'));
});

let pluginsData = [];

async function fetchPlugins() {
try {
const response = await axios.get('https://api.github.com/repos/ExpTechTW/TREM-Plugins/contents/infos');
Expand All @@ -103,43 +174,105 @@ <h1>TREM Plugins</h1>
for (const file of response.data) {
if (file.name.endsWith('.json')) {
const pluginData = await axios.get(file.download_url);
pluginData.data.downloads = Math.floor(Math.random() * 1000);
pluginData.data.lastUpdated = new Date(Date.now() - Math.random() * 10000000000);
plugins.push(pluginData.data);
}
}

pluginsData = plugins;
updateStats(plugins);
displayPlugins(plugins);
} catch (error) {
console.error('Error fetching plugins:', error);
}
}

function updateStats(plugins) {
const uniqueAuthors = new Set(plugins.flatMap(p => p.author));
document.getElementById('totalPlugins').textContent = plugins.length;
document.getElementById('totalDownloads').textContent = plugins.reduce((sum, p) => sum + p.downloads, 0);
document.getElementById('totalAuthors').textContent = uniqueAuthors.size;
}

async function fetchReadme(plugin) {
try {
const repoUrl = new URL(plugin.link);
const [owner, repo] = repoUrl.pathname.split('/').filter(Boolean).slice(0, 2);
const response = await axios.get(`https://api.github.com/repos/${owner}/${repo}/readme`, {
headers: { 'Accept': 'application/vnd.github.html' }
});

const modal = M.Modal.getInstance(document.getElementById('readmeModal'));
document.getElementById('readmeTitle').textContent = `${plugin.name} 文檔`;
document.getElementById('readmeContent').innerHTML = response.data;
modal.open();
} catch (error) {
console.error('Error fetching readme:', error);
}
}

function sortPlugins(criteria) {
switch (criteria) {
case 'name':
pluginsData.sort((a, b) => a.name.localeCompare(b.name));
break;
case 'downloads':
pluginsData.sort((a, b) => b.downloads - a.downloads);
break;
case 'updated':
pluginsData.sort((a, b) => new Date(b.lastUpdated) - new Date(a.lastUpdated));
break;
}
displayPlugins(pluginsData);
}

function displayPlugins(plugins) {
const container = document.getElementById('plugins');
container.innerHTML = '';

plugins.forEach(plugin => {
const card = document.createElement('div');
card.className = 'plugin-card';

const dependencies = Object.entries(plugin.dependencies || {})
.map(([name, version]) => `<span class="dependency">${name} ${version}</span>`)
.map(([name, version]) => `<span class="dependency-chip">${name} ${version}</span>`)
.join(' ');

card.innerHTML = `
<div class="plugin-name">${plugin.name}</div>
<div class="plugin-version">版本 ${plugin.version}</div>
<div class="plugin-description">${plugin.description.zh_tw}</div>
<div class="plugin-meta">
作者: ${plugin.author.join(', ')}
<div class="card-content">
<div class="plugin-name">${plugin.name}</div>
<div class="plugin-version">版本 ${plugin.version}</div>
<div class="plugin-description">${plugin.description.zh_tw}</div>
<div class="plugin-meta">
作者: ${plugin.author.join(', ')} <br>
下載量: ${plugin.downloads} <br>
最後更新: ${new Date(plugin.lastUpdated).toLocaleDateString()}
</div>
<div class="dependencies">
依賴項: ${dependencies}
</div>
<div class="card-action">
<a href="${plugin.link}" class="btn-flat waves-effect" target="_blank">查看源碼</a>
<button class="btn-flat waves-effect" onclick="fetchReadme(${JSON.stringify(plugin)})">查看文檔</button>
</div>
</div>
<div class="dependencies">
依賴項: ${dependencies}
</div>
<a href="${plugin.link}" class="plugin-link" target="_blank">查看源碼</a>
`;

container.appendChild(card);
});
}

document.getElementById('searchInput').addEventListener('input', (e) => {
const searchTerm = e.target.value.toLowerCase();
const filteredPlugins = pluginsData.filter(plugin =>
plugin.name.toLowerCase().includes(searchTerm) ||
plugin.description.zh_tw.toLowerCase().includes(searchTerm) ||
plugin.author.some(author => author.toLowerCase().includes(searchTerm))
);
displayPlugins(filteredPlugins);
});

fetchPlugins();
</script>
</body>
Expand Down

0 comments on commit 940d6aa

Please sign in to comment.