mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-21 07:16:15 -04:00
feat(tool): improved favorite tool management
This commit is contained in:
parent
274ff02b54
commit
af075dcccc
3 changed files with 83 additions and 71 deletions
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { NIcon, useThemeVars, type MenuGroupOption } from 'naive-ui';
|
import { NIcon, useThemeVars, type MenuGroupOption } from 'naive-ui';
|
||||||
import { h } from 'vue';
|
import { computed, h } from 'vue';
|
||||||
import { RouterLink, useRoute } from 'vue-router';
|
import { RouterLink, useRoute } from 'vue-router';
|
||||||
import { Heart, Menu2, Home2 } from '@vicons/tabler';
|
import { Heart, Menu2, Home2 } from '@vicons/tabler';
|
||||||
import { toolsByCategory } from '@/tools';
|
import { toolsByCategory } from '@/tools';
|
||||||
|
@ -8,6 +8,7 @@ import { useStyleStore } from '@/stores/style.store';
|
||||||
import { config } from '@/config';
|
import { config } from '@/config';
|
||||||
import MenuIconItem from '@/components/MenuIconItem.vue';
|
import MenuIconItem from '@/components/MenuIconItem.vue';
|
||||||
import type { Tool } from '@/tools/tools.types';
|
import type { Tool } from '@/tools/tools.types';
|
||||||
|
import { useToolStore } from '@/tools/tools.store';
|
||||||
import SearchBar from '../components/SearchBar.vue';
|
import SearchBar from '../components/SearchBar.vue';
|
||||||
import HeroGradient from '../assets/hero-gradient.svg?component';
|
import HeroGradient from '../assets/hero-gradient.svg?component';
|
||||||
import MenuLayout from '../components/MenuLayout.vue';
|
import MenuLayout from '../components/MenuLayout.vue';
|
||||||
|
@ -22,16 +23,25 @@ const commitSha = config.app.lastCommitSha.slice(0, 7);
|
||||||
const makeLabel = (tool: Tool) => () => h(RouterLink, { to: tool.path }, { default: () => tool.name });
|
const makeLabel = (tool: Tool) => () => h(RouterLink, { to: tool.path }, { default: () => tool.name });
|
||||||
const makeIcon = (tool: Tool) => () => h(MenuIconItem, { tool });
|
const makeIcon = (tool: Tool) => () => h(MenuIconItem, { tool });
|
||||||
|
|
||||||
const menuOptions: MenuGroupOption[] = toolsByCategory.map((category) => ({
|
const toolStore = useToolStore();
|
||||||
label: category.name,
|
|
||||||
key: category.name,
|
const menuOptions = computed<MenuGroupOption[]>(() =>
|
||||||
type: 'group',
|
[
|
||||||
children: category.components.map((tool) => ({
|
...(toolStore.favoriteTools.length > 0
|
||||||
label: makeLabel(tool),
|
? [{ name: 'Your favorite tools', components: toolStore.favoriteTools }]
|
||||||
icon: makeIcon(tool),
|
: []),
|
||||||
key: tool.name,
|
...toolsByCategory,
|
||||||
|
].map((category) => ({
|
||||||
|
label: category.name,
|
||||||
|
key: category.name,
|
||||||
|
type: 'group',
|
||||||
|
children: category.components.map((tool) => ({
|
||||||
|
label: makeLabel(tool),
|
||||||
|
icon: makeIcon(tool),
|
||||||
|
key: tool.name,
|
||||||
|
})),
|
||||||
})),
|
})),
|
||||||
}));
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -149,8 +159,7 @@ const menuOptions: MenuGroupOption[] = toolsByCategory.map((category) => ({
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
>
|
>
|
||||||
Buy me a coffee
|
Buy me a coffee
|
||||||
|
<n-icon v-if="!styleStore.isSmallScreen" :component="Heart" style="margin-left: 5px" />
|
||||||
<n-icon v-if="!styleStore.isSmallScreen" :component="Heart" style="margin-left: 8px" size="20px" />
|
|
||||||
</n-button>
|
</n-button>
|
||||||
</template>
|
</template>
|
||||||
❤ Support IT Tools development !
|
❤ Support IT Tools development !
|
||||||
|
|
|
@ -3,22 +3,22 @@ import { useRoute } from 'vue-router';
|
||||||
import { useHead } from '@vueuse/head';
|
import { useHead } from '@vueuse/head';
|
||||||
import type { HeadObject } from '@vueuse/head';
|
import type { HeadObject } from '@vueuse/head';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { useThemeVars } from 'naive-ui';
|
import FavoriteButton from '@/components/FavoriteButton.vue';
|
||||||
|
import type { Tool } from '@/tools/tools.types';
|
||||||
import BaseLayout from './base.layout.vue';
|
import BaseLayout from './base.layout.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const theme = useThemeVars();
|
|
||||||
|
|
||||||
const head = computed<HeadObject>(() => ({
|
const head = computed<HeadObject>(() => ({
|
||||||
title: `${route.meta.name} - IT Tools`,
|
title: `${route.meta.name} - IT Tools`,
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
name: 'description',
|
name: 'description',
|
||||||
content: route.meta.description,
|
content: route.meta?.description as string,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'keywords',
|
name: 'keywords',
|
||||||
content: route.meta.keywords,
|
content: ((route.meta.keywords ?? []) as string[]).join(','),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
@ -29,22 +29,18 @@ useHead(head);
|
||||||
<base-layout>
|
<base-layout>
|
||||||
<div class="tool-layout">
|
<div class="tool-layout">
|
||||||
<div class="tool-header">
|
<div class="tool-header">
|
||||||
<n-h1>
|
<n-space align="center" justify="space-between" :wrap="false">
|
||||||
{{ route.meta.name }}
|
<n-h1>
|
||||||
|
{{ route.meta.name }}
|
||||||
|
</n-h1>
|
||||||
|
|
||||||
<n-tag
|
<div>
|
||||||
v-if="route.meta.isNew"
|
<favorite-button :tool="{name: route.meta.name} as Tool" />
|
||||||
round
|
</div>
|
||||||
type="success"
|
</n-space>
|
||||||
:bordered="false"
|
|
||||||
:color="{ color: theme.primaryColor, textColor: theme.tagColor }"
|
|
||||||
>
|
|
||||||
New tool
|
|
||||||
</n-tag>
|
|
||||||
<!-- <span class="new-tool-badge">New !</span> -->
|
|
||||||
</n-h1>
|
|
||||||
|
|
||||||
<div class="separator" />
|
<div class="separator" />
|
||||||
|
|
||||||
<div class="description">
|
<div class="description">
|
||||||
{{ route.meta.description }}
|
{{ route.meta.description }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -92,6 +88,7 @@ useHead(head);
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
background: rgb(161, 161, 161);
|
background: rgb(161, 161, 161);
|
||||||
|
opacity: 0.2;
|
||||||
|
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,58 +12,60 @@ useHead({ title: 'IT Tools - Handy online tools for developers' });
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="home-page">
|
<div class="home-page">
|
||||||
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
|
<div class="grid-wrapper">
|
||||||
<n-gi>
|
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
|
||||||
<colored-card title="You like it-tools?" :icon="Heart">
|
<n-gi>
|
||||||
Give us a star on
|
<colored-card title="You like it-tools?" :icon="Heart">
|
||||||
<a
|
Give us a star on
|
||||||
href="https://github.com/CorentinTh/it-tools"
|
<a
|
||||||
rel="noopener"
|
href="https://github.com/CorentinTh/it-tools"
|
||||||
target="_blank"
|
rel="noopener"
|
||||||
aria-label="IT-Tools' github repository"
|
target="_blank"
|
||||||
>github</a
|
aria-label="IT-Tools' github repository"
|
||||||
>
|
>github</a
|
||||||
or follow us on
|
>
|
||||||
<a
|
or follow us on
|
||||||
href="https://twitter.com/ittoolsdottech"
|
<a
|
||||||
rel="noopener"
|
href="https://twitter.com/ittoolsdottech"
|
||||||
target="_blank"
|
rel="noopener"
|
||||||
aria-label="IT-Tools' twitter account"
|
target="_blank"
|
||||||
>twitter</a
|
aria-label="IT-Tools' twitter account"
|
||||||
>! Thank you
|
>twitter</a
|
||||||
<n-icon :component="Heart" />
|
>! Thank you
|
||||||
</colored-card>
|
<n-icon :component="Heart" />
|
||||||
</n-gi>
|
</colored-card>
|
||||||
</n-grid>
|
</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
|
||||||
<transition name="height">
|
<transition name="height">
|
||||||
<div v-if="toolStore.favoriteTools.length > 0">
|
<div v-if="toolStore.favoriteTools.length > 0">
|
||||||
<n-h3>Your favorite tools</n-h3>
|
<n-h3>Your favorite tools</n-h3>
|
||||||
|
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
|
||||||
|
<n-gi v-for="tool in toolStore.favoriteTools" :key="tool.name">
|
||||||
|
<tool-card :tool="tool" />
|
||||||
|
</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<div v-if="toolStore.newTools.length > 0">
|
||||||
|
<n-h3>Newest tools</n-h3>
|
||||||
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
|
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
|
||||||
<n-gi v-for="tool in toolStore.favoriteTools" :key="tool.name">
|
<n-gi v-for="tool in toolStore.newTools" :key="tool.name">
|
||||||
<tool-card :tool="tool" />
|
<tool-card :tool="tool" />
|
||||||
</n-gi>
|
</n-gi>
|
||||||
</n-grid>
|
</n-grid>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
|
||||||
|
|
||||||
<div v-if="toolStore.newTools.length > 0">
|
<n-h3>All the tools</n-h3>
|
||||||
<n-h3>Newest tools</n-h3>
|
|
||||||
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
|
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
|
||||||
<n-gi v-for="tool in toolStore.newTools" :key="tool.name">
|
<n-gi v-for="tool in toolStore.tools" :key="tool.name">
|
||||||
<tool-card :tool="tool" />
|
<transition>
|
||||||
|
<tool-card :tool="tool" />
|
||||||
|
</transition>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
</n-grid>
|
</n-grid>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<n-h3>All the tools</n-h3>
|
|
||||||
<n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8">
|
|
||||||
<n-gi v-for="tool in toolStore.tools" :key="tool.name">
|
|
||||||
<transition>
|
|
||||||
<tool-card :tool="tool" />
|
|
||||||
</transition>
|
|
||||||
</n-gi>
|
|
||||||
</n-grid>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -72,8 +74,12 @@ useHead({ title: 'IT Tools - Handy online tools for developers' });
|
||||||
padding-top: 50px;
|
padding-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.n-h3 {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
::v-deep(.n-grid) {
|
::v-deep(.n-grid) {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.height-enter-active,
|
.height-enter-active,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue