refactor(home): improved landing page ui
This commit is contained in:
		
							parent
							
								
									274ff02b54
								
							
						
					
					
						commit
						0bd8fabb85
					
				| @ -7,7 +7,7 @@ import { layouts } from './layouts'; | |||||||
| import { useStyleStore } from './stores/style.store'; | import { useStyleStore } from './stores/style.store'; | ||||||
| 
 | 
 | ||||||
| const route = useRoute(); | const route = useRoute(); | ||||||
| const layout = computed(() => route?.meta?.layout ?? layouts.base); | const layout = computed(() => route?.meta?.layout ?? layouts.navbar); | ||||||
| const styleStore = useStyleStore(); | const styleStore = useStyleStore(); | ||||||
| 
 | 
 | ||||||
| const theme = computed(() => (styleStore.isDarkTheme ? darkTheme : null)); | const theme = computed(() => (styleStore.isDarkTheme ? darkTheme : null)); | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 275"> | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 275" preserveAspectRatio="none"> | ||||||
|   <defs> |   <defs> | ||||||
|     <linearGradient id="small-hero-gradient-1" x1="13.74" y1="183.7" x2="303.96" y2="45.59" gradientUnits="userSpaceOnUse"> |     <linearGradient id="small-hero-gradient-1" x1="13.74" y1="183.7" x2="303.96" y2="45.59" gradientUnits="userSpaceOnUse"> | ||||||
|       <stop offset="0" stop-color="#25636c"/> |       <stop offset="0" stop-color="#25636c"/> | ||||||
|  | |||||||
| Before Width: | Height: | Size: 894 B After Width: | Height: | Size: 922 B | 
| @ -39,13 +39,6 @@ const siderPosition = computed(() => (isSmallScreen.value ? 'absolute' : 'static | |||||||
|   cursor: pointer; |   cursor: pointer; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .content { |  | ||||||
|   // background-color: #f1f5f9; |  | ||||||
|   ::v-deep(.n-layout-scroll-container) { |  | ||||||
|     padding: 26px; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .n-layout { | .n-layout { | ||||||
|   height: 100vh; |   height: 100vh; | ||||||
| } | } | ||||||
|  | |||||||
| @ -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> | ||||||
| @ -102,60 +112,6 @@ const menuOptions: MenuGroupOption[] = toolsByCategory.map((category) => ({ | |||||||
|     </template> |     </template> | ||||||
| 
 | 
 | ||||||
|     <template #content> |     <template #content> | ||||||
|       <div class="navigation"> |  | ||||||
|         <n-button |  | ||||||
|           :size="styleStore.isSmallScreen ? 'medium' : 'large'" |  | ||||||
|           circle |  | ||||||
|           quaternary |  | ||||||
|           aria-label="Toggle menu" |  | ||||||
|           @click="styleStore.isMenuCollapsed = !styleStore.isMenuCollapsed" |  | ||||||
|         > |  | ||||||
|           <n-icon size="25" :component="Menu2" /> |  | ||||||
|         </n-button> |  | ||||||
| 
 |  | ||||||
|         <router-link to="/" #="{ navigate, href }" custom> |  | ||||||
|           <n-tooltip trigger="hover"> |  | ||||||
|             <template #trigger> |  | ||||||
|               <n-button |  | ||||||
|                 tag="a" |  | ||||||
|                 :href="href" |  | ||||||
|                 :size="styleStore.isSmallScreen ? 'medium' : 'large'" |  | ||||||
|                 circle |  | ||||||
|                 quaternary |  | ||||||
|                 aria-label="Home" |  | ||||||
|                 @click="navigate" |  | ||||||
|               > |  | ||||||
|                 <n-icon size="25" :component="Home2" /> |  | ||||||
|               </n-button> |  | ||||||
|             </template> |  | ||||||
|             Home |  | ||||||
|           </n-tooltip> |  | ||||||
|         </router-link> |  | ||||||
| 
 |  | ||||||
|         <search-bar /> |  | ||||||
| 
 |  | ||||||
|         <navbar-buttons v-if="!styleStore.isSmallScreen" /> |  | ||||||
| 
 |  | ||||||
|         <n-tooltip trigger="hover"> |  | ||||||
|           <template #trigger> |  | ||||||
|             <n-button |  | ||||||
|               round |  | ||||||
|               type="primary" |  | ||||||
|               tag="a" |  | ||||||
|               href="https://github.com/sponsors/CorentinTh" |  | ||||||
|               rel="noopener" |  | ||||||
|               target="_blank" |  | ||||||
|               class="support-button" |  | ||||||
|               :bordered="false" |  | ||||||
|             > |  | ||||||
|               Buy me a coffee |  | ||||||
| 
 |  | ||||||
|               <n-icon v-if="!styleStore.isSmallScreen" :component="Heart" style="margin-left: 8px" size="20px" /> |  | ||||||
|             </n-button> |  | ||||||
|           </template> |  | ||||||
|           ❤ Support IT Tools development ! |  | ||||||
|         </n-tooltip> |  | ||||||
|       </div> |  | ||||||
|       <slot /> |       <slot /> | ||||||
|     </template> |     </template> | ||||||
|   </menu-layout> |   </menu-layout> | ||||||
|  | |||||||
| @ -1,7 +1,9 @@ | |||||||
| import BaseLayout from './base.layout.vue'; | import BaseLayout from './base.layout.vue'; | ||||||
|  | import NavbarLayout from './navbar.layout.vue'; | ||||||
| import ToolLayout from './tool.layout.vue'; | import ToolLayout from './tool.layout.vue'; | ||||||
| 
 | 
 | ||||||
| export const layouts = { | export const layouts = { | ||||||
|   base: BaseLayout, |   base: BaseLayout, | ||||||
|   toolLayout: ToolLayout, |   toolLayout: ToolLayout, | ||||||
|  |   navbar: NavbarLayout, | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										174
									
								
								src/layouts/navbar.layout.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								src/layouts/navbar.layout.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,174 @@ | |||||||
|  | <script lang="ts" setup> | ||||||
|  | import { NIcon, useThemeVars } from 'naive-ui'; | ||||||
|  | import { RouterLink } from 'vue-router'; | ||||||
|  | import { Heart, Menu2, Home2 } from '@vicons/tabler'; | ||||||
|  | import { useStyleStore } from '@/stores/style.store'; | ||||||
|  | import SearchBar from '../components/SearchBar.vue'; | ||||||
|  | import BaseLayout from './base.layout.vue'; | ||||||
|  | import NavbarButtons from '../components/NavbarButtons.vue'; | ||||||
|  | 
 | ||||||
|  | const themeVars = useThemeVars(); | ||||||
|  | const styleStore = useStyleStore(); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <base-layout class="base-layout"> | ||||||
|  |     <div class="navigation"> | ||||||
|  |       <n-button | ||||||
|  |         :size="styleStore.isSmallScreen ? 'medium' : 'large'" | ||||||
|  |         circle | ||||||
|  |         quaternary | ||||||
|  |         aria-label="Toggle menu" | ||||||
|  |         @click="styleStore.isMenuCollapsed = !styleStore.isMenuCollapsed" | ||||||
|  |       > | ||||||
|  |         <n-icon size="25" :component="Menu2" /> | ||||||
|  |       </n-button> | ||||||
|  | 
 | ||||||
|  |       <router-link to="/" #="{ navigate, href }" custom> | ||||||
|  |         <n-tooltip trigger="hover"> | ||||||
|  |           <template #trigger> | ||||||
|  |             <n-button | ||||||
|  |               tag="a" | ||||||
|  |               :href="href" | ||||||
|  |               :size="styleStore.isSmallScreen ? 'medium' : 'large'" | ||||||
|  |               circle | ||||||
|  |               quaternary | ||||||
|  |               aria-label="Home" | ||||||
|  |               @click="navigate" | ||||||
|  |             > | ||||||
|  |               <n-icon size="25" :component="Home2" /> | ||||||
|  |             </n-button> | ||||||
|  |           </template> | ||||||
|  |           Home | ||||||
|  |         </n-tooltip> | ||||||
|  |       </router-link> | ||||||
|  | 
 | ||||||
|  |       <search-bar /> | ||||||
|  | 
 | ||||||
|  |       <navbar-buttons v-if="!styleStore.isSmallScreen" /> | ||||||
|  | 
 | ||||||
|  |       <n-tooltip trigger="hover"> | ||||||
|  |         <template #trigger> | ||||||
|  |           <n-button | ||||||
|  |             round | ||||||
|  |             type="primary" | ||||||
|  |             tag="a" | ||||||
|  |             href="https://github.com/sponsors/CorentinTh" | ||||||
|  |             rel="noopener" | ||||||
|  |             target="_blank" | ||||||
|  |             class="support-button" | ||||||
|  |             :bordered="false" | ||||||
|  |           > | ||||||
|  |             Buy me a coffee | ||||||
|  | 
 | ||||||
|  |             <n-icon v-if="!styleStore.isSmallScreen" :component="Heart" style="margin-left: 8px" size="20px" /> | ||||||
|  |           </n-button> | ||||||
|  |         </template> | ||||||
|  |         ❤ Support IT Tools development ! | ||||||
|  |       </n-tooltip> | ||||||
|  |     </div> | ||||||
|  |     <slot /> | ||||||
|  |   </base-layout> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style lang="less" scoped> | ||||||
|  | // ::v-deep(.n-layout-scroll-container) { | ||||||
|  | //     @percent: 4%; | ||||||
|  | //     @position: 25px; | ||||||
|  | //     @size: 50px; | ||||||
|  | //     @color: #eeeeee25; | ||||||
|  | //     background-image: radial-gradient(@color @percent, transparent @percent), | ||||||
|  | //         radial-gradient(@color @percent, transparent @percent); | ||||||
|  | //     background-position: 0 0, @position @position; | ||||||
|  | //     background-size: @size @size; | ||||||
|  | // } | ||||||
|  | 
 | ||||||
|  | ::v-deep(.content .n-layout-scroll-container) { | ||||||
|  |   padding: 26px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .support-button { | ||||||
|  |   background: rgb(37, 99, 108); | ||||||
|  |   background: linear-gradient(48deg, rgba(37, 99, 108, 1) 0%, rgba(59, 149, 111, 1) 60%, rgba(20, 160, 88, 1) 100%); | ||||||
|  |   color: #fff; | ||||||
|  |   transition: all ease 0.2s; | ||||||
|  | 
 | ||||||
|  |   &:hover { | ||||||
|  |     color: #fff; | ||||||
|  |     padding-left: 30px; | ||||||
|  |     padding-right: 30px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .footer { | ||||||
|  |   text-align: center; | ||||||
|  |   color: #838587; | ||||||
|  |   margin-top: 20px; | ||||||
|  |   padding: 20px 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sider-content { | ||||||
|  |   padding-top: 160px; | ||||||
|  |   padding-bottom: 200px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .hero-wrapper { | ||||||
|  |   position: absolute; | ||||||
|  |   display: block; | ||||||
|  |   left: 0; | ||||||
|  |   width: 100%; | ||||||
|  |   z-index: 10; | ||||||
|  |   overflow: hidden; | ||||||
|  | 
 | ||||||
|  |   .gradient { | ||||||
|  |     margin-top: -65px; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .text-wrapper { | ||||||
|  |     position: absolute; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     text-align: center; | ||||||
|  |     top: 16px; | ||||||
|  |     color: #fff; | ||||||
|  | 
 | ||||||
|  |     .title { | ||||||
|  |       font-size: 25px; | ||||||
|  |       font-weight: 600; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .divider { | ||||||
|  |       width: 50px; | ||||||
|  |       height: 2px; | ||||||
|  |       border-radius: 4px; | ||||||
|  |       background-color: v-bind('themeVars.primaryColor'); | ||||||
|  |       margin: 0 auto 5px; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .subtitle { | ||||||
|  |       font-size: 16px; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ::v-deep(.n-menu-item-content-header) { | ||||||
|  | //   overflow: visible !important; | ||||||
|  | //   // overflow-x: hidden !important; | ||||||
|  | // } | ||||||
|  | 
 | ||||||
|  | .navigation { | ||||||
|  |   display: flex; | ||||||
|  |   align-items: center; | ||||||
|  |   justify-content: center; | ||||||
|  |   flex-direction: row; | ||||||
|  | 
 | ||||||
|  |   & > *:not(:last-child) { | ||||||
|  |     margin-right: 5px; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .search-bar { | ||||||
|  |     // width: 100%; | ||||||
|  |     flex-grow: 1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -4,7 +4,9 @@ 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 { useThemeVars } from 'naive-ui'; | ||||||
| import BaseLayout from './base.layout.vue'; | import FavoriteButton from '@/components/FavoriteButton.vue'; | ||||||
|  | import type { Tool } from '@/tools/tools.types'; | ||||||
|  | import NavbarLayout from './navbar.layout.vue'; | ||||||
| 
 | 
 | ||||||
| const route = useRoute(); | const route = useRoute(); | ||||||
| const theme = useThemeVars(); | const theme = useThemeVars(); | ||||||
| @ -14,11 +16,11 @@ const head = computed<HeadObject>(() => ({ | |||||||
|   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(','), | ||||||
|     }, |     }, | ||||||
|   ], |   ], | ||||||
| })); | })); | ||||||
| @ -26,25 +28,21 @@ useHead(head); | |||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
|   <base-layout> |   <navbar-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> | ||||||
| @ -54,7 +52,7 @@ useHead(head); | |||||||
|     <div class="tool-content"> |     <div class="tool-content"> | ||||||
|       <slot /> |       <slot /> | ||||||
|     </div> |     </div> | ||||||
|   </base-layout> |   </navbar-layout> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <style lang="less" scoped> | <style lang="less" scoped> | ||||||
| @ -92,6 +90,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; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import { Heart } from '@vicons/tabler'; | |||||||
| import { useHead } from '@vueuse/head'; | import { useHead } from '@vueuse/head'; | ||||||
| import ColoredCard from '../components/ColoredCard.vue'; | import ColoredCard from '../components/ColoredCard.vue'; | ||||||
| import ToolCard from '../components/ToolCard.vue'; | import ToolCard from '../components/ToolCard.vue'; | ||||||
|  | import Hero from './home/components/hero.vue'; | ||||||
| 
 | 
 | ||||||
| const toolStore = useToolStore(); | const toolStore = useToolStore(); | ||||||
| 
 | 
 | ||||||
| @ -12,7 +13,7 @@ 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"> |     <!-- <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"> | ||||||
|           Give us a star on |           Give us a star on | ||||||
| @ -34,42 +35,45 @@ useHead({ title: 'IT Tools - Handy online tools for developers' }); | |||||||
|           <n-icon :component="Heart" /> |           <n-icon :component="Heart" /> | ||||||
|         </colored-card> |         </colored-card> | ||||||
|       </n-gi> |       </n-gi> | ||||||
|     </n-grid> |     </n-grid> --> | ||||||
| 
 | 
 | ||||||
|     <transition name="height"> |     <hero /> | ||||||
|       <div v-if="toolStore.favoriteTools.length > 0"> |     <div class="grid-wrapper"> | ||||||
|         <n-h3>Your favorite tools</n-h3> |       <transition name="height"> | ||||||
|  |         <div v-if="toolStore.favoriteTools.length > 0"> | ||||||
|  |           <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> | ||||||
| 
 | 
 | ||||||
| <style scoped lang="less"> | <style scoped lang="less"> | ||||||
| .home-page { | .grid-wrapper { | ||||||
|   padding-top: 50px; |   padding: 26px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ::v-deep(.n-grid) { | ::v-deep(.n-grid) { | ||||||
|  | |||||||
							
								
								
									
										110
									
								
								src/pages/home/components/hero.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/pages/home/components/hero.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="hero"> | ||||||
|  |     <!-- <img :src="HeroGradientUrl" alt="Hero background image" class="hero-background" /> --> | ||||||
|  |     <div class="background-wrapper" :style="{ backgroundImage: `url(${HeroGradientUrl})` }"> | ||||||
|  |       <div class="navigation"> | ||||||
|  |         <n-button | ||||||
|  |           :size="styleStore.isSmallScreen ? 'medium' : 'large'" | ||||||
|  |           circle | ||||||
|  |           quaternary | ||||||
|  |           aria-label="Toggle menu" | ||||||
|  |           color="#fff" | ||||||
|  |           @click="styleStore.isMenuCollapsed = !styleStore.isMenuCollapsed" | ||||||
|  |         > | ||||||
|  |           <n-icon size="25" :component="Menu2" /> | ||||||
|  |         </n-button> | ||||||
|  | 
 | ||||||
|  |         <div class="spacer"></div> | ||||||
|  | 
 | ||||||
|  |         <navbar-buttons v-if="!styleStore.isSmallScreen" /> | ||||||
|  | 
 | ||||||
|  |         <n-tooltip trigger="hover"> | ||||||
|  |           <template #trigger> | ||||||
|  |             <n-button | ||||||
|  |               round | ||||||
|  |               type="primary" | ||||||
|  |               tag="a" | ||||||
|  |               href="https://github.com/sponsors/CorentinTh" | ||||||
|  |               rel="noopener" | ||||||
|  |               target="_blank" | ||||||
|  |               ghost | ||||||
|  |               color="#fff" | ||||||
|  |             > | ||||||
|  |               Buy me a coffee | ||||||
|  | 
 | ||||||
|  |               <n-icon v-if="!styleStore.isSmallScreen" :component="Heart" style="margin-left: 8px" size="20px" /> | ||||||
|  |             </n-button> | ||||||
|  |           </template> | ||||||
|  |           ❤ Support IT Tools development ! | ||||||
|  |         </n-tooltip> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|  |       <n-space justify="center" class="content" vertical> | ||||||
|  |         <n-h1> Hello, world! </n-h1> | ||||||
|  |         <div class="subtitle"> | ||||||
|  |           Welcome to IT-Tools! The collection of handy online tool for devs. Find everything you need to work in IT! | ||||||
|  |         </div> | ||||||
|  |         <search-bar /> | ||||||
|  |       </n-space> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script setup lang="ts"> | ||||||
|  | import HeroGradientUrl from '@/assets/hero-gradient.svg?url'; | ||||||
|  | import NavbarButtons from '@/components/NavbarButtons.vue'; | ||||||
|  | import SearchBar from '@/components/SearchBar.vue'; | ||||||
|  | import { useStyleStore } from '@/stores/style.store'; | ||||||
|  | import { Heart, Menu2 } from '@vicons/tabler'; | ||||||
|  | 
 | ||||||
|  | const styleStore = useStyleStore(); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style scoped lang="less"> | ||||||
|  | .hero { | ||||||
|  |   position: relative; | ||||||
|  |   color: #fff !important; | ||||||
|  | 
 | ||||||
|  |   .n-h1 { | ||||||
|  |     margin-bottom: 0; | ||||||
|  |     line-height: 1; | ||||||
|  |     color: #fff !important; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .subtitle { | ||||||
|  |     opacity: 0.8; | ||||||
|  |     margin-bottom: 20px; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .background-wrapper { | ||||||
|  |     //   background: rgb(37, 99, 108); | ||||||
|  |     //   background: linear-gradient(48deg, rgba(37, 99, 108, 1) 0%, rgba(59, 149, 111, 1) 60%, rgba(20, 160, 88, 1) 100%); | ||||||
|  | 
 | ||||||
|  |     background-size: 100% 150%; | ||||||
|  |     background-position: bottom; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .content { | ||||||
|  |     padding: 50px 0 300px; | ||||||
|  |     max-width: 900px; | ||||||
|  |     margin: 0 auto; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .navigation { | ||||||
|  |     padding: 26px; | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  |     justify-content: center; | ||||||
|  |     flex-direction: row; | ||||||
|  | 
 | ||||||
|  |     & > *:not(:last-child) { | ||||||
|  |       margin-right: 5px; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .spacer { | ||||||
|  |       // width: 100%; | ||||||
|  |       flex-grow: 1; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -24,6 +24,7 @@ const router = createRouter({ | |||||||
|       path: '/', |       path: '/', | ||||||
|       name: 'home', |       name: 'home', | ||||||
|       component: HomePage, |       component: HomePage, | ||||||
|  |       meta: { layout: layouts.base }, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       path: '/about', |       path: '/about', | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user