109 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<script lang="ts" setup>
 | 
						|
import { useRoute } from 'vue-router';
 | 
						|
import { useHead } from '@vueuse/head';
 | 
						|
import type { HeadObject } from '@vueuse/head';
 | 
						|
 | 
						|
import BaseLayout from './base.layout.vue';
 | 
						|
import FavoriteButton from '@/components/FavoriteButton.vue';
 | 
						|
import type { Tool } from '@/tools/tools.types';
 | 
						|
 | 
						|
const route = useRoute();
 | 
						|
 | 
						|
const head = computed<HeadObject>(() => ({
 | 
						|
  title: `${route.meta.name} - IT Tools`,
 | 
						|
  meta: [
 | 
						|
    {
 | 
						|
      name: 'description',
 | 
						|
      content: route.meta?.description as string,
 | 
						|
    },
 | 
						|
    {
 | 
						|
      name: 'keywords',
 | 
						|
      content: ((route.meta.keywords ?? []) as string[]).join(','),
 | 
						|
    },
 | 
						|
  ],
 | 
						|
}));
 | 
						|
useHead(head);
 | 
						|
const { t } = useI18n();
 | 
						|
 | 
						|
const i18nKey = computed<string>(() => route.path.trim().replace('/', ''));
 | 
						|
const toolTitle = computed<string>(() => t(`tools.${i18nKey.value}.title`, String(route.meta.name)));
 | 
						|
const toolDescription = computed<string>(() => t(`tools.${i18nKey.value}.description`, String(route.meta.description)));
 | 
						|
</script>
 | 
						|
 | 
						|
<template>
 | 
						|
  <BaseLayout>
 | 
						|
    <div class="tool-layout">
 | 
						|
      <div class="tool-header">
 | 
						|
        <div flex flex-nowrap items-center justify-between>
 | 
						|
          <n-h1>
 | 
						|
            {{ toolTitle }}
 | 
						|
          </n-h1>
 | 
						|
 | 
						|
          <div>
 | 
						|
            <FavoriteButton :tool="{ name: route.meta.name } as Tool" />
 | 
						|
          </div>
 | 
						|
        </div>
 | 
						|
 | 
						|
        <div class="separator" />
 | 
						|
 | 
						|
        <div class="description">
 | 
						|
          {{ toolDescription }}
 | 
						|
        </div>
 | 
						|
      </div>
 | 
						|
    </div>
 | 
						|
 | 
						|
    <div class="tool-content">
 | 
						|
      <slot />
 | 
						|
    </div>
 | 
						|
  </BaseLayout>
 | 
						|
</template>
 | 
						|
 | 
						|
<style lang="less" scoped>
 | 
						|
.tool-content {
 | 
						|
  display: flex;
 | 
						|
  flex-direction: row;
 | 
						|
  justify-content: center;
 | 
						|
  align-items: flex-start;
 | 
						|
  flex-wrap: wrap;
 | 
						|
  gap: 16px;
 | 
						|
 | 
						|
  ::v-deep(& > *) {
 | 
						|
    flex: 0 1 600px;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
.tool-layout {
 | 
						|
  max-width: 600px;
 | 
						|
  margin: 0 auto;
 | 
						|
  box-sizing: border-box;
 | 
						|
 | 
						|
  .tool-header {
 | 
						|
    padding: 40px 0;
 | 
						|
    width: 100%;
 | 
						|
 | 
						|
    .n-h1 {
 | 
						|
      opacity: 0.9;
 | 
						|
      font-size: 40px;
 | 
						|
      font-weight: 400;
 | 
						|
      margin: 0;
 | 
						|
      line-height: 1;
 | 
						|
    }
 | 
						|
 | 
						|
    .separator {
 | 
						|
      width: 200px;
 | 
						|
      height: 2px;
 | 
						|
      background: rgb(161, 161, 161);
 | 
						|
      opacity: 0.2;
 | 
						|
 | 
						|
      margin: 10px 0;
 | 
						|
    }
 | 
						|
 | 
						|
    .description {
 | 
						|
      margin: 0;
 | 
						|
 | 
						|
      opacity: 0.7;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
</style>
 |