feat(frontend): main page

This commit is contained in:
2025-11-06 09:24:44 +01:00
parent 89c7588883
commit 3f828a754b
34 changed files with 1536 additions and 442 deletions

View File

@@ -0,0 +1,33 @@
<template>
<UFooter>
<template #left>
<p class="text-300 txt-sm">
Copyright &copy; {{ new Date().getFullYear() }}
</p>
</template>
<UNavigationMenu :items="items" variant="link" />
<template #right>
<UButton
icon="i-simple-icons-github"
color="neutral"
variant="ghost"
to="https://github.com/Phundrak"
target="_blank"
aria-label="GitHub"
/>
</template>
</UFooter>
</template>
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui';
const items = computed<NavigationMenuItem[]>(() => [
{
label: $t('footer.links.source'),
to: 'https://labs.phundrak.com/phundrak/phundrak.com',
},
]);
</script>

View File

@@ -0,0 +1,29 @@
<template>
<UHeader toggle-side="right" mode="drawer">
<template #title> Phundrak </template>
<UNavigationMenu :items="items" />
<template #right>
<NavbarLanguageSwitcher />
<NavbarThemeSwitcher />
</template>
<template #body>
<UNavigationMenu :items="items" orientation="vertical" class="-mx-2.5" />
</template>
</UHeader>
</template>
<script setup lang="ts">
const route = useRoute();
const items = computed<NavigationMenuItem[]>(() => [
{
label: $t('pages.home.name'),
to: '/',
active: route.path == '/',
},
...['resume', 'vocal-synthesis', 'languages', 'contact'].map((page) => ({
label: $t(`pages.${page}.name`),
to: `/${page}`,
active: route.path.startsWith(`/${page}`),
})),
]);
</script>

View File

@@ -0,0 +1,30 @@
<template>
<UDropdownMenu
:key="locale"
:items="availableLocales"
:content="{ align: 'start' }"
>
<UButton color="neutral" variant="outline" icon="material-symbols:globe" />
</UDropdownMenu>
</template>
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui';
const { locale, locales, setLocale } = useI18n();
const availableLocales = computed(() => {
return locales.value.map(
(optionLocale) =>
({
label: optionLocale.name,
code: optionLocale.code,
type: 'checkbox' as const,
checked: optionLocale.code === locale.value,
onUpdateChecked: () => switchLocale(optionLocale.code),
}) as DropdownMenuItem,
);
});
const switchLocale = (newLocale: string) => {
setLocale(newLocale);
};
</script>

View File

@@ -0,0 +1,31 @@
<template>
<UDropdownMenu
:key="colorMode.preference"
:items="themes"
:content="{ align: 'start' }"
>
<UButton color="neutral" variant="outline" :icon="icons[currentColor]" />
</UDropdownMenu>
</template>
<script setup lang="ts">
type Theme = 'light' | 'dark' | 'system';
const icons: Dictionary<Theme, string> = {
light: 'material-symbols:light-mode',
dark: 'material-symbols:dark-mode',
system: 'material-symbols:computer-outline',
};
const colorMode = useColorMode();
const currentColor = computed<Theme>(() => colorMode.preference ?? 'system');
const themes = computed<DropdownValue[]>(() =>
['light', 'dark', 'system'].map((theme) => ({
code: theme,
label: $t(`theme.${theme}`),
icon: icons[theme],
type: 'checkbox' as const,
checked: currentColor.value === theme,
onUpdateChecked: () => switchColor(theme),
})),
);
const switchColor = (theme: Theme) => (colorMode.preference = theme);
</script>