mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-24 00:36:14 -04:00
feat(favorites) drag-and-drop favorites section (#1360)
This commit is contained in:
parent
ea8c4ed077
commit
0b1b98f93e
13 changed files with 72 additions and 4 deletions
|
@ -1,6 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import { IconHeart } from '@tabler/icons-vue';
|
||||
import { IconDragDrop, IconHeart } from '@tabler/icons-vue';
|
||||
import { useHead } from '@vueuse/head';
|
||||
import { computed } from 'vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
import ColoredCard from '../components/ColoredCard.vue';
|
||||
import ToolCard from '../components/ToolCard.vue';
|
||||
import { useToolStore } from '@/tools/tools.store';
|
||||
|
@ -10,6 +12,13 @@ const toolStore = useToolStore();
|
|||
|
||||
useHead({ title: 'IT Tools - Handy online tools for developers' });
|
||||
const { t } = useI18n();
|
||||
|
||||
const favoriteTools = computed(() => toolStore.favoriteTools);
|
||||
|
||||
// Update favorite tools order when drag is finished
|
||||
function onUpdateFavoriteTools() {
|
||||
toolStore.updateFavoriteTools(favoriteTools.value); // Update the store with the new order
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -66,10 +75,21 @@ const { t } = useI18n();
|
|||
<div v-if="toolStore.favoriteTools.length > 0">
|
||||
<h3 class="mb-5px mt-25px font-500 text-neutral-400">
|
||||
{{ $t('home.categories.favoriteTools') }}
|
||||
<c-tooltip :tooltip="$t('home.categories.favoritesDndToolTip')">
|
||||
<n-icon :component="IconDragDrop" size="18" />
|
||||
</c-tooltip>
|
||||
</h3>
|
||||
<div class="grid grid-cols-1 gap-12px lg:grid-cols-3 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-4">
|
||||
<ToolCard v-for="tool in toolStore.favoriteTools" :key="tool.name" :tool="tool" />
|
||||
</div>
|
||||
<Draggable
|
||||
:list="favoriteTools"
|
||||
class="grid grid-cols-1 gap-12px lg:grid-cols-3 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-4"
|
||||
ghost-class="ghost-favorites-draggable"
|
||||
item-key="name"
|
||||
@end="onUpdateFavoriteTools"
|
||||
>
|
||||
<template #item="{ element: tool }">
|
||||
<ToolCard :tool="tool" />
|
||||
</template>
|
||||
</Draggable>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
|
@ -107,4 +127,24 @@ const { t } = useI18n();
|
|||
opacity: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.ghost-favorites-draggable {
|
||||
opacity: 0.4;
|
||||
background-color: #ccc;
|
||||
border: 2px dashed #666;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
transform: scale(1.1);
|
||||
animation: ghost-favorites-draggable-animation 0.2s ease-out;
|
||||
}
|
||||
|
||||
@keyframes ghost-favorites-draggable-animation {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
100% {
|
||||
opacity: 0.4;
|
||||
transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -59,5 +59,9 @@ export const useToolStore = defineStore('tools', () => {
|
|||
return favoriteToolsName.value.includes(get(tool).name)
|
||||
|| favoriteToolsName.value.includes(get(tool).path);
|
||||
},
|
||||
|
||||
updateFavoriteTools(newOrder: ToolWithCategory[]) {
|
||||
favoriteToolsName.value = newOrder.map(tool => tool.path);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue