cyber/src/pages/Tools_home.vue

150 lines
3.5 KiB
Vue

<script setup>
import {onMounted, ref} from 'vue';
import ToolsBox from "../components/Tools_box.vue";
const categories = ref([
{ name: '计算', active: false },
]);
const searchQuery = ref('');
const tools = ref([
{ id: 1, title: 'GPA在线计算器', description: '手动输入在线算', image: null, category: ['计算'] },
{ id: 2, title: 'PDF页面提取器', description: '提取指定页和封面', image: null, category: ['提取', 'pdf'] },
{ id: 3, title: '请求测试器', description: '自定义请求测试', image: null, category: ['开发', '网络'] },
{ id: 4, title: '图片转PDF', description: '导入图片生成pdf', image: null, category: ['pdf', '生成'] },
]);
onMounted(() => {
const tags = {};
tools.value.forEach(tool => {
tool.category.forEach(tag => {
tags[tag] = tags[tag]+1 || 1;
})
})
function topNKeys(obj, n) {
let sortedEntries = Object.entries(obj).sort((a, b) => b[1] - a[1]);
return sortedEntries.slice(0, n).map(entry => entry[0]);
}
categories.value = topNKeys(tags, 10).map(tag => { return { name: tag, active: false }})
})
// Toggle function for categories, only one category can be active at a time
const toggleCategory = (category) => {
if (category.active) {
category.active = false; // Deselect if already selected
} else {
categories.value.forEach(cat => cat.active = false); // Deselect all other categories
category.active = true; // Select the clicked category
}
};
const filterTools = () => {
return tools.value.filter(tool => {
const matchesCategory = categories.value.some(cat => cat.active && tool.category.includes(cat.name));
const matchesSearch = tool.title.toLowerCase().includes(searchQuery.value.toLowerCase());
return (!categories.value.some(cat => cat.active) || matchesCategory) && matchesSearch;
});
};
</script>
<template>
<div class="container" v-if="/^\/tools\/?$/.test($route.path)">
<div class="filters">
<div class="categories">
<span
v-for="category in categories"
:key="category.name"
:class="{ active: category.active }"
@click="toggleCategory(category)"
>
{{ category.name }}
</span>
</div>
<input type="text" v-model="searchQuery" placeholder="搜索工具..." class="search-bar" />
</div>
<div class="tools">
<ToolsBox
v-for="tool in filterTools()"
:key="tool.title"
:tool="tool"
/>
</div>
</div>
<router-view v-else />
</template>
<style scoped>
.container {
height: calc(100vh - 100px);
width: 100%;
overflow-y: auto;
overflow-x: hidden;
display: flex;
justify-content: flex-start;
flex-direction: column;
align-items: center;
padding: 20px 0;
}
.filters {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
margin-bottom: 20px;
}
.categories {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
}
.categories span {
cursor: pointer;
padding: 5px 10px;
border: 1px solid #ccc;
border-radius: 3px;
}
.categories span.active {
background-color: #007bff;
color: white;
}
.search-bar {
padding: 10px;
margin: 20px 0;
width: 50%;
border-radius: 10px;
border: 1px solid #ccc;
}
.tools {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
width: 100%;
}
.theme-light .categories span.active {
background-color: #ffb74d;
color: black;
}
.theme-light .search-bar {
border: 1px solid #ffb74d;
}
::-webkit-scrollbar {
display: none;
}
</style>