Skip to content

Commit

Permalink
Upgrade to Nuxt 3 (#21)
Browse files Browse the repository at this point in the history
* Upgrade packages to Nuxt 3

* Enable corepack for yarn 4 in CI pipeline

* Migrate header and footer to Nuxt 3

* Update error handling page

* Update layout and content render page

* Update ImageGallery, InlinePicture and SogLink

* Update map and timeline

* Remove layouts and simplify content rendering

* Make components used in content global

* Fix background color

* Update YARN packages

* Use public files instead of imported assets

* Deliver content in defaultLocale if localization is not available

* Fix external content component

* Exceptionless locale fallback

* Fix SogMap

* Fix SogTimeline

* Update CI and remove testComponent

* Fix peer dependencies

* Remove dynamic fallback page listing on error 404

* Limit concurrency in prerendering

* Optimize menu for nested pages
  • Loading branch information
daniel-lerch authored Sep 9, 2024
1 parent a849a31 commit 101407d
Show file tree
Hide file tree
Showing 41 changed files with 14,777 additions and 13,047 deletions.
15 changes: 0 additions & 15 deletions .eslintrc.js

This file was deleted.

5 changes: 3 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Enable corepack for yarn
run: corepack enable
- name: Install Yarn packages
run: yarn install --immutable

Expand All @@ -35,5 +36,5 @@ jobs:
if: github.ref == 'refs/heads/master'

- name: Deploy to kueken.studieren-ohne-grenzen.org
run: rclone sync ./dist :sftp:/html --sftp-host=${{ vars.SFTP_HOST }} --sftp-user=${{ vars.SFTP_USERNAME }} --sftp-pass=${{ secrets.SFTP_PASSWORD_OBSCURED }} --sftp-disable-hashcheck=true --progress --stats-one-line --stats=5s
run: rclone sync ./.output/public :sftp:/html --sftp-host=${{ vars.SFTP_HOST }} --sftp-user=${{ vars.SFTP_USERNAME }} --sftp-pass=${{ secrets.SFTP_PASSWORD_OBSCURED }} --sftp-disable-hashcheck=true --progress --stats-one-line --stats=5s
if: github.ref == 'refs/heads/master'
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ typings/

# nuxt.js build output
.nuxt
.nitro
.output

# Nuxt generate
dist
Expand Down
38 changes: 38 additions & 0 deletions app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<div class="flex flex-col min-h-screen">
<DesktopMenu :items="menu.items" class="hidden md:block" />
<MobileMenu :items="menu.items" class="block md:hidden" />
<NuxtPage class="flex-grow"/>
<SogFooter
:items="footer.items"
:social-icons="footer.socialIcons"
:awards="footer.awards"
/>
</div>
</template>

<script setup lang="ts">
import { useData } from '@/types/composables'
const { locale } = useI18n()
const i18nHead = useLocaleHead({ addSeoAttributes: true })
useHead({
htmlAttrs: {
lang: locale.value,
},
title: i18nHead.value.title,
meta: [
{
hid: 'description',
name: 'description',
content: i18nHead.value.description,
},
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
})
const menu = await useData(`menu-${locale.value}`, () => queryContent(locale.value, 'menu').findOne(), {watch: [locale]})
const footer = await useData(`footer-${locale.value}`, () => queryContent(locale.value, 'footer').findOne(), {watch: [locale]})
</script>
8 changes: 0 additions & 8 deletions assets/css/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,6 @@
@tailwind components;
@tailwind utilities;

/* dark blue overscroll background */
html {
@apply bg-sogblue-darker;
}
.canvas {
@apply bg-white;
}

/* CSS Global */
.nuxt-content {
@apply text-gray-800 font-overpass;
Expand Down
93 changes: 49 additions & 44 deletions components/menu.vue → components/DesktopMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
<nav class="container">
<ul class="menu-list relative">
<li class="flex-grow flex-shrink-0">
<nuxt-link :to="localePath('/')">
<NuxtLink :to="localePath('/')">
<img
src="~/content/static/Logo.png"
src="/Logo.png"
alt="Start"
class="h-14 lg:h-20 xl:h-24"
/>
</nuxt-link>
>
</NuxtLink>
</li>
<li
v-for="item in items"
Expand All @@ -17,22 +17,22 @@
@mouseenter="menuItemExtended = item.url"
@mouseleave="menuItemExtended = ''"
>
<nuxt-link
:to="localePath('/' + item.url)"
<NuxtLink
:to="itemPath(item)"
:class="{
'border-sogblue':
$route.params.slug === item.url &&
route.params.slug === item.url &&
(menuItemExtended === item.url || menuItemExtended === ''),
'border-gray-300':
$route.params.slug === item.url && menuItemExtended !== item.url,
route.params.slug === item.url && menuItemExtended !== item.url,
'text-sogblue-dark': menuItemExtended === item.url,
'text-gray-300':
menuItemExtended !== item.url && menuItemExtended !== '',
}"
class="border-b-2 border-black pb-1 transition-colors duration-200"
>
{{ item.name }}
</nuxt-link>
</NuxtLink>
<ul
v-if="
menuItemExtended === item.url &&
Expand All @@ -46,36 +46,26 @@
:key="subitem.url ?? subitem.hash"
class="w-full flex flex-col hover:text-sogblue-dark duration-200"
>
<nuxt-link
<NuxtLink
class="pt-2 flex-grow whitespace-nowrap transition-colors"
:to="
localePath(
'/' +
(subitem.url ? subitem.url : item.url + '#' + subitem.hash ?? '')
)
"
@click.native="menuItemExtended = ''"
:to="itemPath(item, subitem)"
@click="menuItemExtended = ''"
>
{{ subitem.name }}
</nuxt-link>
</NuxtLink>
<ul class="ml-6">
<li
v-for="subsubitem in subitem.children"
:key="subsubitem.url ?? subsubitem.hash"
class="flex text-black hover:text-sogblue-dark"
>
<nuxt-link
<NuxtLink
class="flex-grow whitespace-nowrap transition-colors"
:to="
localePath(
'/' +
(subsubitem.url ? subsubitem.url : item.url + '#' + subsubitem.hash ?? '')
)
"
@click.native="menuItemExtended = ''"
:to="itemPath(item, subitem, subsubitem)"
@click="menuItemExtended = ''"
>
{{ subsubitem.name }}
</nuxt-link>
</NuxtLink>
</li>
</ul>
</li>
Expand All @@ -92,7 +82,7 @@
:class="selectLanguage ? 'text-sogblue-dark' : 'text-gray-600'"
class="h-6 w-6 fill-current transition-colors duration-100"
>
<use href="~/content/static/sprites/navSymbols.svg#language" />
<use href="/sprites/navSymbols.svg#language" />
</svg>
</div>
<ul
Expand All @@ -106,36 +96,51 @@
:key="locale.code"
class="flex hover:text-sogblue-dark transition-colors duration-100 leading-tight"
>
<nuxt-link
<NuxtLink
:to="switchLocalePath(locale.code)"
:class="$i18n.locale === locale.code ? 'border-sogblue' : ''"
class="border-b-2 border-white my-1.5"
>
{{ locale.name }}
</nuxt-link>
</NuxtLink>
</li>
</ul>
</li>
</ul>
</nav>
</template>

<script>
export default {
name: 'MenuComponent',
props: {
items: {
type: Array,
default: () => [],
},
},
data() {
return {
selectLanguage: false,
menuItemExtended: '',
<script setup lang="ts">
import type { MenuItem } from '~/types/menu'
withDefaults(defineProps<{ items: MenuItem[] }>(), {
items: () => [],
})
const route = useRoute()
const localePath = useLocalePath()
const switchLocalePath = useSwitchLocalePath()
const itemPath = (item: MenuItem, subitem?: MenuItem, subsubitem?: MenuItem) => {
if (subsubitem) {
if (subsubitem.url) {
return localePath('/' + subsubitem.url)
} else if (subitem?.url) {
return localePath('/' + subitem.url + '#' + subsubitem.hash)
} else {
return localePath('/' + item.url + '#' + subsubitem.hash)
}
},
}
if (subitem) {
return localePath('/' + (subitem.url ? subitem.url : item.url + '#' + subitem.hash))
}
return localePath('/' + item.url)
}
const selectLanguage = ref(false)
const menuItemExtended = ref<string | undefined>('')
</script>

<style lang="postcss">
Expand Down
62 changes: 62 additions & 0 deletions components/ExternalContent.global.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<div class="flex items-center h-full">
<!-- Protection -->
<div
v-if="!contentAccepted"
class="w-full md:w-1/2 lg:w-1/2 p-4 my-auto mx-auto border border-gray-400"
>
<div class="pb-4">
{{ props.message }}
</div>
<div class="w-full flex items-center justify-center">
<input
type="button"
class="button"
:value="t('accept')"
@click="contentAccepted = true"
>
</div>
</div>

<!-- IFrame -->
<iframe
v-if="contentAccepted"
ref="myIframe"
:src="props.url"
:width="props.width"
:height="props.height"
title="Iframe Example"
:scrolling="scrollBar === 'yes' ? '' : 'no'"
class="border border-gray-400 my-0 mx-auto"
/>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
url: {
type: String,
required: true,
},
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: '1024px',
},
message: {
type: String,
required: true,
},
scrollBar: {
type: String,
default: 'yes',
},
})
const { t } = useI18n()
const contentAccepted = useState('externalContent', () => false)
</script>
20 changes: 9 additions & 11 deletions components/imageGalery.vue → components/ImageGallery.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<div
class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"
@click="$emit('close')"
></div>
/>

<!-- Modal -->
<div class="absolute p-2">
Expand All @@ -30,7 +30,7 @@
/>
</svg>
</div>
<nuxt-picture
<NuxtPicture
:src="`${currentImg.src}`"
:alt="`${currentImg.alt}`"
format="webp"
Expand All @@ -41,13 +41,11 @@
</div>
</template>

<script>
export default {
name: 'InlineGalery',
props: {
open: { type: Boolean, default: false },
currentImg: { type: Object, default: () => {} },
},
}
<script setup lang="ts">
defineProps<{
open: boolean
currentImg: { src: string; alt: string }
}>()
defineEmits(['close'])
</script>
<style></style>
Loading

0 comments on commit 101407d

Please sign in to comment.