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,7 +23,15 @@ 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(); | ||||||
|  | 
 | ||||||
|  | const menuOptions = computed<MenuGroupOption[]>(() => | ||||||
|  |   [ | ||||||
|  |     ...(toolStore.favoriteTools.length > 0 | ||||||
|  |       ? [{ name: 'Your favorite tools', components: toolStore.favoriteTools }] | ||||||
|  |       : []), | ||||||
|  |     ...toolsByCategory, | ||||||
|  |   ].map((category) => ({ | ||||||
|     label: category.name, |     label: category.name, | ||||||
|     key: category.name, |     key: category.name, | ||||||
|     type: 'group', |     type: 'group', | ||||||
| @ -31,7 +40,8 @@ const menuOptions: MenuGroupOption[] = toolsByCategory.map((category) => ({ | |||||||
|       icon: makeIcon(tool), |       icon: makeIcon(tool), | ||||||
|       key: tool.name, |       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-space align="center" justify="space-between" :wrap="false"> | ||||||
|           <n-h1> |           <n-h1> | ||||||
|             {{ route.meta.name }} |             {{ route.meta.name }} | ||||||
| 
 |  | ||||||
|           <n-tag |  | ||||||
|             v-if="route.meta.isNew" |  | ||||||
|             round |  | ||||||
|             type="success" |  | ||||||
|             :bordered="false" |  | ||||||
|             :color="{ color: theme.primaryColor, textColor: theme.tagColor }" |  | ||||||
|           > |  | ||||||
|             New tool |  | ||||||
|           </n-tag> |  | ||||||
|           <!-- <span class="new-tool-badge">New !</span> --> |  | ||||||
|           </n-h1> |           </n-h1> | ||||||
| 
 | 
 | ||||||
|  |           <div> | ||||||
|  |             <favorite-button :tool="{name: route.meta.name} as Tool" /> | ||||||
|  |           </div> | ||||||
|  |         </n-space> | ||||||
|  | 
 | ||||||
|         <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,6 +12,7 @@ useHead({ title: 'IT Tools - Handy online tools for developers' }); | |||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
|   <div class="home-page"> |   <div class="home-page"> | ||||||
|  |     <div class="grid-wrapper"> | ||||||
|       <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> |         <n-gi> | ||||||
|           <colored-card title="You like it-tools?" :icon="Heart"> |           <colored-card title="You like it-tools?" :icon="Heart"> | ||||||
| @ -65,6 +66,7 @@ useHead({ title: 'IT Tools - Handy online tools for developers' }); | |||||||
|         </n-gi> |         </n-gi> | ||||||
|       </n-grid> |       </n-grid> | ||||||
|     </div> |     </div> | ||||||
|  |   </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <style scoped lang="less"> | <style scoped lang="less"> | ||||||
| @ -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