feat(tool): improved favorite tool management
This commit is contained in:
		
							parent
							
								
									274ff02b54
								
							
						
					
					
						commit
						af075dcccc
					
				| @ -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…
	
		Reference in New Issue
	
	Block a user