137 lines
3 KiB
Vue
137 lines
3 KiB
Vue
<script setup lang="ts">
|
|
import { useRouter } from 'vue-router';
|
|
import AppBox from 'components/app/AppBox.vue';
|
|
import AppCircle from 'components/app/AppCircle.vue';
|
|
import { Icon } from '@iconify/vue';
|
|
|
|
const router = useRouter();
|
|
|
|
defineProps<{
|
|
list: {
|
|
value: string;
|
|
icon: string;
|
|
title: string;
|
|
caption: string;
|
|
hidden?: boolean;
|
|
disabled?: boolean;
|
|
isax?: boolean;
|
|
tab?: string;
|
|
color:
|
|
| 'green'
|
|
| 'red'
|
|
| 'orange'
|
|
| 'cyan'
|
|
| 'camo'
|
|
| 'purple'
|
|
| 'violet'
|
|
| 'indigo'
|
|
| 'lime';
|
|
}[];
|
|
}>();
|
|
|
|
function navigateTo(destination: string, tab?: string) {
|
|
router.push({ path: `${destination}`, query: tab ? { tab } : {} });
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="menu-container"
|
|
:style="`grid-template-columns: repeat(${$q.screen.gt.sm ? 4 : $q.screen.gt.xs ? 2 : 1}, 1fr)`"
|
|
>
|
|
<AppBox
|
|
class="column inline-flex items-center"
|
|
:class="{ disabled: !!v.disabled }"
|
|
v-for="(v, i) in list.filter((item) => !item.hidden)"
|
|
:key="i"
|
|
:bordered="$q.dark.isActive"
|
|
@click="!v.disabled && navigateTo(v.value, v.tab)"
|
|
>
|
|
<AppCircle
|
|
:id="`menu-icon-${v.value}`"
|
|
:class="`q-pa-md menu-icon menu-icon__${v.color}${($q.dark.isActive && ' dark') || ''}`"
|
|
:bordered="$q.dark.isActive"
|
|
>
|
|
<i v-if="v.isax" :class="`isax ${v.icon}`" style="font-size: 3rem" />
|
|
<Icon v-else width="3rem" :icon="v.icon" height="3rem" />
|
|
</AppCircle>
|
|
<div class="column items-center q-mt-md text-center">
|
|
<span style="font-weight: var(--font-weight-8)">{{ $t(v.title) }}</span>
|
|
<span style="color: rgba(130 130 130 / 0.7)">{{ $t(v.caption) }}</span>
|
|
</div>
|
|
</AppBox>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.menu-container {
|
|
display: grid;
|
|
|
|
gap: var(--size-6);
|
|
& > * {
|
|
transition: 100ms border-color ease-in-out;
|
|
border: 1px solid transparent;
|
|
|
|
&.disabled {
|
|
opacity: 0.4;
|
|
filter: grayscale(1);
|
|
}
|
|
&:not(.disabled):hover {
|
|
cursor: pointer;
|
|
border-color: var(--brand-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
.menu-icon {
|
|
--_color: var(--gray-7-hsl);
|
|
--_color-dark: var(--_color);
|
|
color: hsl(var(--_color)) !important;
|
|
background-color: hsla(var(--_color) / 0.1) !important;
|
|
|
|
&.dark {
|
|
color: hsl(--_color-dark) !important;
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
&.menu-icon__green {
|
|
--_color: var(--green-6-hsl);
|
|
}
|
|
|
|
&.menu-icon__red {
|
|
--_color: var(--red-8-hsl);
|
|
}
|
|
|
|
&.menu-icon__orange {
|
|
--_color: var(--orange-6-hsl);
|
|
--_color-dark: var(--orange-5-hsl);
|
|
}
|
|
|
|
&.menu-icon__cyan {
|
|
--_color: var(--cyan-5-hsl);
|
|
--_color-dark: var(--cyan-4-hsl);
|
|
}
|
|
|
|
&.menu-icon__camo {
|
|
--_color: var(--camo-5-hsl);
|
|
--_color-dark: var(--cyan-4-hsl);
|
|
}
|
|
|
|
&.menu-icon__purple {
|
|
--_color: var(--purple-3-hsl);
|
|
--_color-dark: var(--purple-5-hsl);
|
|
}
|
|
|
|
&.menu-icon__violet {
|
|
--_color: var(--violet-5-hsl);
|
|
}
|
|
|
|
&.menu-icon__indigo {
|
|
--_color: var(--indigo-9-hsl);
|
|
}
|
|
|
|
&.menu-icon__lime {
|
|
--_color: var(--lime-11-hsl);
|
|
}
|
|
}
|
|
</style>
|