mirror of
				https://github.com/CorentinTh/it-tools.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	feat(favorites) drag-and-drop favorites section (#1360)
This commit is contained in:
		@@ -10,6 +10,7 @@ home:
 | 
			
		||||
    newestTools: Neueste Tools
 | 
			
		||||
    favoriteTools: Deine Lieblingstools
 | 
			
		||||
    allTools: Alle Tools
 | 
			
		||||
    favoritesDndToolTip: 'Ziehen und Ablegen, um Favoriten neu zu ordnen'
 | 
			
		||||
  subtitle: Praktische Tools für Entwickler
 | 
			
		||||
  toggleMenu: Menü umschalten
 | 
			
		||||
  home: Startseite
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ home:
 | 
			
		||||
    newestTools: Newest tools
 | 
			
		||||
    favoriteTools: 'Your favorite tools'
 | 
			
		||||
    allTools: 'All the tools'
 | 
			
		||||
    favoritesDndToolTip: 'Drag and drop to reorder favorites'
 | 
			
		||||
  subtitle: 'Handy tools for developers'
 | 
			
		||||
  toggleMenu: 'Toggle menu'
 | 
			
		||||
  home: Home
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ home:
 | 
			
		||||
    newestTools: Nuevas herramientas
 | 
			
		||||
    favoriteTools: 'Tus herramientas favoritas'
 | 
			
		||||
    allTools: 'Todas las herramientas'
 | 
			
		||||
    favoritesDndToolTip: 'Arrastra y suelta para reordenar favoritos'
 | 
			
		||||
  subtitle: 'Herramientas practicas para desarrolladores'
 | 
			
		||||
  toggleMenu: 'Toggle menu'
 | 
			
		||||
  home: Home
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ home:
 | 
			
		||||
    newestTools: 'Les nouveaux outils'
 | 
			
		||||
    favoriteTools: 'Vos outils favoris'
 | 
			
		||||
    allTools: 'Tous les outils'
 | 
			
		||||
    favoritesDndToolTip: 'Faites glisser et déposez pour réordonner vos favoris'
 | 
			
		||||
  subtitle: 'Outils pour les développeurs'
 | 
			
		||||
  toggleMenu: 'Menu'
 | 
			
		||||
  home: Accueil
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ home:
 | 
			
		||||
    newestTools: Nyeste verktøy
 | 
			
		||||
    favoriteTools: 'Dine favoritt verktøy'
 | 
			
		||||
    allTools: 'Alle verktøyene'
 | 
			
		||||
    favoritesDndToolTip: 'Dra og slipp for å omordne favoritter'
 | 
			
		||||
  subtitle: 'Nyttige verktøy for utviklere'
 | 
			
		||||
  toggleMenu: 'Vekslemenmy'
 | 
			
		||||
  home: Hjem
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ home:
 | 
			
		||||
    newestTools: 'Novas ferramentas'
 | 
			
		||||
    favoriteTools: 'Suas ferramentas favoritas'
 | 
			
		||||
    allTools: 'Todas as ferramentas'
 | 
			
		||||
    favoritesDndToolTip: 'Arraste e solte para reordenar favoritos'
 | 
			
		||||
  subtitle: 'Ferraentas úteis para desenvolvedores'
 | 
			
		||||
  toggleMenu: 'Menu'
 | 
			
		||||
  home: 'Início'
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ home:
 | 
			
		||||
    newestTools: Найновіші інструменти
 | 
			
		||||
    favoriteTools: 'Ваші улюблені інструменти'
 | 
			
		||||
    allTools: 'Усі інструменти'
 | 
			
		||||
    favoritesDndToolTip: 'Перетягніть і відпустіть, щоб змінити порядок улюблених'
 | 
			
		||||
  subtitle: 'Зручні інструменти для розробників'
 | 
			
		||||
  toggleMenu: 'Перемикання меню'
 | 
			
		||||
  home: Головна
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ home:
 | 
			
		||||
    newestTools: Công cụ mới nhất
 | 
			
		||||
    favoriteTools: 'Công cụ yêu thích của bạn'
 | 
			
		||||
    allTools: 'Tất cả công cụ'
 | 
			
		||||
    favoritesDndToolTip: 'Kéo thả để sắp xếp lại yêu thích'
 | 
			
		||||
  subtitle: 'Công cụ cho nhà phát triển.'
 | 
			
		||||
  toggleMenu: 'Chuyển đổi menu'
 | 
			
		||||
  home: Trang chủ
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ home:
 | 
			
		||||
    newestTools: '最新工具'
 | 
			
		||||
    favoriteTools: '我的收藏'
 | 
			
		||||
    allTools: '全部工具'
 | 
			
		||||
    favoritesDndToolTip: '拖放重新排列收藏夹'
 | 
			
		||||
  subtitle: '助力开发人员和 IT 工作者'
 | 
			
		||||
  toggleMenu: '切换菜单'
 | 
			
		||||
  home: '主页'
 | 
			
		||||
 
 | 
			
		||||
@@ -99,6 +99,7 @@
 | 
			
		||||
    "vue-router": "^4.1.6",
 | 
			
		||||
    "vue-shadow-dom": "^4.2.0",
 | 
			
		||||
    "vue-tsc": "^1.8.1",
 | 
			
		||||
    "vuedraggable": "^4.1.0",
 | 
			
		||||
    "xml-formatter": "^3.3.2",
 | 
			
		||||
    "xml-js": "^1.6.11",
 | 
			
		||||
    "yaml": "^2.2.1"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@@ -194,6 +194,9 @@ dependencies:
 | 
			
		||||
  vue-tsc:
 | 
			
		||||
    specifier: ^1.8.1
 | 
			
		||||
    version: 1.8.1(typescript@5.2.2)
 | 
			
		||||
  vuedraggable:
 | 
			
		||||
    specifier: ^4.1.0
 | 
			
		||||
    version: 4.1.0(vue@3.3.4)
 | 
			
		||||
  xml-formatter:
 | 
			
		||||
    specifier: ^3.3.2
 | 
			
		||||
    version: 3.3.2
 | 
			
		||||
@@ -8231,6 +8234,9 @@ packages:
 | 
			
		||||
      tslib: 2.5.0
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /sortablejs@1.14.0:
 | 
			
		||||
    resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==}
 | 
			
		||||
 | 
			
		||||
  /source-map-js@1.0.2:
 | 
			
		||||
    resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
 | 
			
		||||
    engines: {node: '>=0.10.0'}
 | 
			
		||||
@@ -9356,6 +9362,14 @@ packages:
 | 
			
		||||
      '@vue/server-renderer': 3.3.4(vue@3.3.4)
 | 
			
		||||
      '@vue/shared': 3.3.4
 | 
			
		||||
 | 
			
		||||
  /vuedraggable@4.1.0(vue@3.3.4):
 | 
			
		||||
    resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      vue: ^3.0.1
 | 
			
		||||
    dependencies:
 | 
			
		||||
      sortablejs: 1.14.0
 | 
			
		||||
      vue: 3.3.4
 | 
			
		||||
 | 
			
		||||
  /vueuc@0.4.51(vue@3.3.4):
 | 
			
		||||
    resolution: {integrity: sha512-pLiMChM4f+W8czlIClGvGBYo656lc2Y0/mXFSCydcSmnCR1izlKPGMgiYBGjbY9FDkFG8a2HEVz7t0DNzBWbDw==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user