Dockerized the application, fixed fonts, improved SEO, upgraded to Nuxt 3.8.2
This commit is contained in:
parent
2bd1e4a512
commit
4939d24f62
8
.dockerignore
Normal file
8
.dockerignore
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# .dockerignore
|
||||||
|
/.git
|
||||||
|
/.nuxt
|
||||||
|
/.output
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
.gitignore
|
||||||
|
README.md
|
||||||
@ -1 +1 @@
|
|||||||
[{"D:\\Software\\Development\\Websites\\enderman.ch\\index\\assets\\styles\\list-types.scss":"1","D:\\Software\\Development\\Websites\\enderman.ch\\index\\assets\\styles\\transitions.scss":"2","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Logo.vue":"3","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\LinkButton.vue":"4","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\TransitionY.vue":"5","D:\\Software\\Development\\Websites\\enderman.ch\\index\\app.vue":"6","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\EMail.vue":"7","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Navigation.vue":"8","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Separator.vue":"9","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Flooter.vue":"10","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Portal.vue":"11","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\about.vue":"12","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\index.vue":"13","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\projects.vue":"14","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\social.vue":"15","D:\\Software\\Development\\Websites\\enderman.ch\\index\\layouts\\Card.vue":"16"},{"size":389,"mtime":1700689887460,"hashOfConfig":"17"},{"size":165,"mtime":1700688268778,"hashOfConfig":"17"},{"size":1113,"mtime":1700251498711,"hashOfConfig":"17"},{"size":986,"mtime":1700324714794,"hashOfConfig":"17"},{"size":1513,"mtime":1700430002840,"hashOfConfig":"17"},{"size":1517,"mtime":1700692384277,"hashOfConfig":"17"},{"size":804,"mtime":1700688952880,"hashOfConfig":"17"},{"size":1252,"mtime":1700694015567,"hashOfConfig":"17"},{"size":300,"mtime":1700689033070,"hashOfConfig":"17"},{"size":1853,"mtime":1700508715727,"hashOfConfig":"17"},{"size":16907,"mtime":1700748650426,"hashOfConfig":"17"},{"size":2135,"mtime":1700689265787,"hashOfConfig":"17"},{"size":3117,"mtime":1700689271383,"hashOfConfig":"17"},{"size":2304,"mtime":1700689265769,"hashOfConfig":"17"},{"size":3232,"mtime":1700689265781,"hashOfConfig":"17"},{"size":1623,"mtime":1700748530633,"hashOfConfig":"17"},"5tgxr3"]
|
[{"D:\\Software\\Development\\Websites\\enderman.ch\\index\\assets\\styles\\transitions.scss":"1","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Logo.vue":"2","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\LinkButton.vue":"3","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\TransitionY.vue":"4","D:\\Software\\Development\\Websites\\enderman.ch\\index\\app.vue":"5","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\EMail.vue":"6","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Navigation.vue":"7","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Separator.vue":"8","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Flooter.vue":"9","D:\\Software\\Development\\Websites\\enderman.ch\\index\\components\\Portal.vue":"10","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\about.vue":"11","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\index.vue":"12","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\projects.vue":"13","D:\\Software\\Development\\Websites\\enderman.ch\\index\\pages\\social.vue":"14","D:\\Software\\Development\\Websites\\enderman.ch\\index\\layouts\\Card.vue":"15"},{"size":165,"mtime":1700688268778,"hashOfConfig":"16"},{"size":1113,"mtime":1700251498711,"hashOfConfig":"16"},{"size":986,"mtime":1700324714794,"hashOfConfig":"16"},{"size":1513,"mtime":1700430002840,"hashOfConfig":"16"},{"size":1550,"mtime":1700850776284,"hashOfConfig":"16"},{"size":804,"mtime":1700688952880,"hashOfConfig":"16"},{"size":1252,"mtime":1700694015567,"hashOfConfig":"16"},{"size":300,"mtime":1700689033070,"hashOfConfig":"16"},{"size":1877,"mtime":1700929377808,"hashOfConfig":"16"},{"size":16907,"mtime":1700919582401,"hashOfConfig":"16"},{"size":2135,"mtime":1700689265787,"hashOfConfig":"16"},{"size":3117,"mtime":1700689271383,"hashOfConfig":"16"},{"size":2304,"mtime":1700689265769,"hashOfConfig":"16"},{"size":3232,"mtime":1700689265781,"hashOfConfig":"16"},{"size":1623,"mtime":1700748530633,"hashOfConfig":"16"},"5tgxr3"]
|
||||||
36
Dockerfile
Normal file
36
Dockerfile
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
ARG NODE_ENV=development
|
||||||
|
ARG HOST=localhost
|
||||||
|
ARG PORT=3000
|
||||||
|
|
||||||
|
FROM node:18-alpine as build
|
||||||
|
RUN apk update && apk upgrade
|
||||||
|
|
||||||
|
# Create application directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files to the application directory and install dependencies
|
||||||
|
COPY package* ./
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
# Copy everything else from the project
|
||||||
|
COPY . ./
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
|
||||||
|
FROM node:18-alpine as production
|
||||||
|
RUN apk update && apk upgrade && apk add dumb-init && adduser -D nuxt
|
||||||
|
|
||||||
|
# Set non-root user
|
||||||
|
USER nuxt
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /opt/index
|
||||||
|
COPY --chown=nuxt:nuxt --from=build /app/.output ./
|
||||||
|
|
||||||
|
# Expose the listening port
|
||||||
|
EXPOSE ${PORT}
|
||||||
|
|
||||||
|
# Set Nitro variables and run the application
|
||||||
|
# https://go.enderman.ch/vws4k
|
||||||
|
ENV HOST=${HOST} PORT=${PORT} NODE_ENV=${NODE_ENV}
|
||||||
|
CMD ["dumb-init", "node", "/opt/index/server/index.mjs"]
|
||||||
11
app.vue
11
app.vue
@ -1,23 +1,27 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useQuasar } from 'quasar'
|
import { useQuasar } from 'quasar'
|
||||||
|
import { useRuntimeConfig } from '#imports'
|
||||||
|
|
||||||
|
const config = useRuntimeConfig()
|
||||||
const quasar = useQuasar()
|
const quasar = useQuasar()
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
titleTemplate: (chunk) => {
|
titleTemplate: (chunk) => {
|
||||||
return !chunk || chunk === 'Enderman' ? 'Enderman' : `${chunk} – Enderman`
|
return !chunk || chunk === config.public.websiteName
|
||||||
|
? config.public.websiteName
|
||||||
|
: `${chunk} – Enderman`
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NuxtLoadingIndicator color="purple" />
|
<NuxtLoadingIndicator color="purple" />
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id="ender-layout"
|
id="ender-layout"
|
||||||
class="d-flex flex-column align-items-center pt-sm-5 h-100 animate__animated-sm animate__delay-1-5s animate__fadeInDown"
|
class="d-flex flex-column align-items-center pt-sm-5 h-100 animate__animated-sm animate__delay-1-5s animate__fadeInDown"
|
||||||
>
|
>
|
||||||
<NuxtLayout name="card">
|
<NuxtLayout name="card">
|
||||||
<template #header> </template>
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<template #fallback> </template>
|
<template #fallback> </template>
|
||||||
@ -39,7 +43,10 @@ useHead({
|
|||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ClientOnly>
|
||||||
|
<template #fallback> </template>
|
||||||
<Portal layout="#ender-layout" animate randomize fade />
|
<Portal layout="#ender-layout" animate randomize fade />
|
||||||
|
</ClientOnly>
|
||||||
|
|
||||||
<Transition
|
<Transition
|
||||||
appear
|
appear
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
@charset "UTF-8";
|
|
||||||
@counter-style do {
|
|
||||||
system: cyclic;
|
|
||||||
symbols: "💻" "📌" "👻" "📷";
|
|
||||||
suffix: " ";
|
|
||||||
}
|
|
||||||
@counter-style enjoy {
|
|
||||||
system: cyclic;
|
|
||||||
symbols: "💻" "📌" "👻" "📷" "♟" "⛄";
|
|
||||||
suffix: " ";
|
|
||||||
}
|
|
||||||
.list-style-type-none {
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
.list-style-type-do {
|
|
||||||
list-style-type: do;
|
|
||||||
}
|
|
||||||
.list-style-type-enjoy {
|
|
||||||
list-style-type: enjoy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=list-types.css.map */
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["list-types.scss"],"names":[],"mappings":";AAAA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAIA;EACE;;AAGF;EACE;;AAGF;EACE","file":"list-types.css"}
|
|
||||||
@ -10,6 +10,12 @@
|
|||||||
suffix: " ";
|
suffix: " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@counter-style faq {
|
||||||
|
system: cyclic;
|
||||||
|
symbols: "\2753" "\1F4A1";
|
||||||
|
suffix: " ";
|
||||||
|
}
|
||||||
|
|
||||||
.list-style-type {
|
.list-style-type {
|
||||||
&-none {
|
&-none {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
@ -22,4 +28,8 @@
|
|||||||
&-enjoy {
|
&-enjoy {
|
||||||
list-style-type: enjoy;
|
list-style-type: enjoy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-faq {
|
||||||
|
list-style-type: faq;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
15791
assets/styles/main.css
15791
assets/styles/main.css
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
15
assets/styles/main.min.css
vendored
15
assets/styles/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -1,7 +1,6 @@
|
|||||||
// Fonts.
|
// Libraries.
|
||||||
@import '@fontsource/Lato/index.css';
|
@use '@fortawesome/fontawesome-svg-core/styles.css' as fontawesome;
|
||||||
@import '@fontsource/Alexandria/700.css';
|
@use 'bootstrap' with (
|
||||||
|
|
||||||
$grid-breakpoints: (
|
$grid-breakpoints: (
|
||||||
xs: 0,
|
xs: 0,
|
||||||
sm: 601px,
|
sm: 601px,
|
||||||
@ -9,13 +8,13 @@ $grid-breakpoints: (
|
|||||||
lg: 1281px,
|
lg: 1281px,
|
||||||
xl: 1921px,
|
xl: 1921px,
|
||||||
xxl: 2561px
|
xxl: 2561px
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@use 'animate.css';
|
||||||
|
|
||||||
// Bootstrap & animations.
|
// Modules.
|
||||||
@import '../../node_modules/bootstrap/scss/bootstrap';
|
@use 'transitions';
|
||||||
@import '../../node_modules/animate.css/animate';
|
@use 'lists';
|
||||||
@import 'transitions';
|
|
||||||
@import 'list-types';
|
|
||||||
|
|
||||||
// CSS Variables.
|
// CSS Variables.
|
||||||
:root {
|
:root {
|
||||||
@ -33,18 +32,25 @@ html {
|
|||||||
body {
|
body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
position: sticky;
|
||||||
|
|
||||||
background-color: rgb(6 25 28);
|
background-color: rgb(6 25 28);
|
||||||
background-image: url('~/assets/images/sky.png');
|
background-image: url('~/assets/images/sky.png');
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
background-blend-mode: multiply;
|
background-blend-mode: multiply;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
color: white;
|
color: white;
|
||||||
|
|
||||||
font-family: Lato, sans-serif;
|
font-family: Lato, sans-serif;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +84,7 @@ body {
|
|||||||
|
|
||||||
.alex {
|
.alex {
|
||||||
font-family: Alexandria, sans-serif;
|
font-family: Alexandria, sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.smooth-glide {
|
.smooth-glide {
|
||||||
@ -94,17 +101,21 @@ body {
|
|||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link {
|
%link {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: 0.3s ease;
|
transition: 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
@extend %link;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: cornflowerblue;
|
color: cornflowerblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-hi {
|
&-hi {
|
||||||
@extend .link;
|
@extend %link;
|
||||||
|
|
||||||
color: cornflowerblue;
|
color: cornflowerblue;
|
||||||
|
|
||||||
@ -113,7 +124,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-force-dark {
|
&-force-dark {
|
||||||
@extend .link;
|
@extend %link;
|
||||||
|
|
||||||
color: cornflowerblue;
|
color: cornflowerblue;
|
||||||
|
|
||||||
@ -210,7 +221,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic classes.
|
// Dynamic classes.
|
||||||
@include media-breakpoint-up(sm) {
|
@include bootstrap.media-breakpoint-up(sm) {
|
||||||
#ender-app {
|
#ender-app {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@ -247,22 +258,23 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-breakpoint-up(md) {
|
@include bootstrap.media-breakpoint-up(md) {
|
||||||
|
/* TODO: Fill it up :) */
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-breakpoint-up(lg) {
|
@include bootstrap.media-breakpoint-up(lg) {
|
||||||
.dimensions {
|
.dimensions {
|
||||||
width: 60%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-breakpoint-up(xl) {
|
@include bootstrap.media-breakpoint-up(xl) {
|
||||||
.dimensions {
|
.dimensions {
|
||||||
width: 40%;
|
width: 40%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-breakpoint-up(xxl) {
|
@include bootstrap.media-breakpoint-up(xxl) {
|
||||||
.dimensions {
|
.dimensions {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
.page-enter-active, .page-leave-active {
|
|
||||||
transition: all 0.4s;
|
|
||||||
}
|
|
||||||
.page-enter-from, .page-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
filter: blur(1rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=transitions.css.map */
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["transitions.scss"],"names":[],"mappings":"AACE;EAEE;;AAGF;EAEE;EACA","file":"transitions.css"}
|
|
||||||
@ -6,8 +6,10 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
const currentYear = new Date().getFullYear()
|
const version = config.public.version
|
||||||
|
const buildDate = config.public.buildDate
|
||||||
|
|
||||||
|
const currentYear = new Date().getFullYear()
|
||||||
const mailTemplate = `I've just found a bug on https://enderman.ch and would like to report it.%0D%0A%0D%0AWebsite version: ${
|
const mailTemplate = `I've just found a bug on https://enderman.ch and would like to report it.%0D%0A%0D%0AWebsite version: ${
|
||||||
config.public.version
|
config.public.version
|
||||||
}%0D%0ABuild date: ${
|
}%0D%0ABuild date: ${
|
||||||
@ -35,8 +37,8 @@ const mailTemplate = `I've just found a bug on https://enderman.ch and would lik
|
|||||||
<a class="link-hi-force-dark" href="https://enderman.ch">Enderman</a>. All
|
<a class="link-hi-force-dark" href="https://enderman.ch">Enderman</a>. All
|
||||||
rights reserved.
|
rights reserved.
|
||||||
<sub>
|
<sub>
|
||||||
β{{ config.public.version ? config.public.version : '?.?.?' }} ({{
|
β{{ version ? version : '?.?.?' }} ({{
|
||||||
config.public.buildDate ? config.public.buildDate : '1970-01-01'
|
buildDate ? buildDate : '1970-01-01'
|
||||||
}})
|
}})
|
||||||
</sub>
|
</sub>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -11,7 +11,20 @@ const pageStore = usePageStore()
|
|||||||
const { pages } = storeToRefs(pageStore)
|
const { pages } = storeToRefs(pageStore)
|
||||||
|
|
||||||
const links = toRaw(pages.value).filter((page) => page.path !== '/')
|
const links = toRaw(pages.value).filter((page) => page.path !== '/')
|
||||||
const icons = [aboutIcon, projectIcon, socialIcon]
|
const icons = [
|
||||||
|
{
|
||||||
|
src: aboutIcon,
|
||||||
|
alt: 'Information',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: projectIcon,
|
||||||
|
alt: 'Blocks',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: socialIcon,
|
||||||
|
alt: 'Users',
|
||||||
|
},
|
||||||
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -31,8 +44,8 @@ const icons = [aboutIcon, projectIcon, socialIcon]
|
|||||||
<LinkButton
|
<LinkButton
|
||||||
:path="page.path"
|
:path="page.path"
|
||||||
:name="page.name"
|
:name="page.name"
|
||||||
:icon="icons[index]"
|
:icon="icons[index].src"
|
||||||
alt="Info"
|
:alt="icons[index].alt"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
7
components/ThemeToggle.vue
Normal file
7
components/ThemeToggle.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<button type="button" data-theme-toggle aria-label="Change to light theme">
|
||||||
|
Change to light theme
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
15
docker-compose.yml
Normal file
15
docker-compose.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
index:
|
||||||
|
container_name: frontend-index
|
||||||
|
image: endermanch/index:latest
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=3000
|
||||||
|
- HOST=0.0.0.0
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:3670:3000"
|
||||||
|
restart: unless-stopped
|
||||||
@ -13,9 +13,6 @@ const { pages } = storeToRefs(pageStore)
|
|||||||
|
|
||||||
const swipe = useSwipe(card, {
|
const swipe = useSwipe(card, {
|
||||||
passive: true,
|
passive: true,
|
||||||
onSwipe: (_touch: TouchEvent) => {
|
|
||||||
console.log(card.value?.offsetWidth, swipe.lengthX.value)
|
|
||||||
},
|
|
||||||
onSwipeEnd: (_touch: TouchEvent, _direction: UseSwipeDirection) => {
|
onSwipeEnd: (_touch: TouchEvent, _direction: UseSwipeDirection) => {
|
||||||
const currentPage = pages.value.find(
|
const currentPage = pages.value.find(
|
||||||
(page) => page.path === route.fullPath,
|
(page) => page.path === route.fullPath,
|
||||||
@ -25,21 +22,18 @@ const swipe = useSwipe(card, {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
card.value?.offsetWidth &&
|
card.value?.offsetWidth &&
|
||||||
Math.abs(swipe.lengthX.value) / card.value?.offsetWidth >= 0.5
|
Math.abs(swipe.lengthX.value) > 1.5 * Math.abs(swipe.lengthY.value) &&
|
||||||
|
Math.abs(swipe.lengthX.value) / card.value?.offsetWidth >= 0.1
|
||||||
) {
|
) {
|
||||||
if (swipe.lengthX.value > 0) {
|
|
||||||
router.push(
|
router.push(
|
||||||
toRaw(pages.value)[
|
toRaw(pages.value)[
|
||||||
currentIndex - 1 < 0
|
swipe.lengthX.value > 0
|
||||||
|
? (currentIndex + 1) % pages.value.length
|
||||||
|
: currentIndex - 1 < 0
|
||||||
? pages.value.length - (currentIndex + 1)
|
? pages.value.length - (currentIndex + 1)
|
||||||
: currentIndex - 1
|
: currentIndex - 1
|
||||||
].path,
|
].path,
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
router.push(
|
|
||||||
toRaw(pages.value)[(currentIndex + 1) % pages.value.length].path,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
122
nuxt.config.ts
122
nuxt.config.ts
@ -1,6 +1,10 @@
|
|||||||
import eslint from 'vite-plugin-eslint'
|
|
||||||
import packageJSON from './package.json'
|
import packageJSON from './package.json'
|
||||||
|
|
||||||
|
const websiteName = "Enderman's Website"
|
||||||
|
const websiteURL = 'https://enderman.ch'
|
||||||
|
|
||||||
|
const buildDate = new Date().toISOString().split('T')[0]
|
||||||
|
|
||||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
app: {
|
app: {
|
||||||
@ -41,32 +45,126 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
css: [
|
css: ['~/assets/styles/main.scss'],
|
||||||
'~/assets/styles/main.min.css',
|
|
||||||
'@fortawesome/fontawesome-svg-core/styles.css',
|
|
||||||
],
|
|
||||||
plugins: [],
|
plugins: [],
|
||||||
modules: [
|
modules: [
|
||||||
'nuxt-font-loader',
|
|
||||||
'@nuxt/content',
|
|
||||||
[
|
|
||||||
'@nuxtjs/eslint-module',
|
|
||||||
{ fix: true, failOnError: true, lintOnStart: false },
|
|
||||||
],
|
|
||||||
'@pinia/nuxt',
|
'@pinia/nuxt',
|
||||||
|
'@nuxt/content',
|
||||||
'nuxt-quasar-ui',
|
'nuxt-quasar-ui',
|
||||||
|
['@nuxtjs/eslint-module', { failOnError: false, lintOnStart: false }],
|
||||||
['@nuxtjs/stylelint-module', { failOnError: true, lintOnStart: false }],
|
['@nuxtjs/stylelint-module', { failOnError: true, lintOnStart: false }],
|
||||||
|
'@nuxtjs/color-mode',
|
||||||
|
'@nuxtjs/google-fonts',
|
||||||
|
'nuxt-simple-sitemap',
|
||||||
|
'nuxt-simple-robots',
|
||||||
|
'nuxt-link-checker',
|
||||||
|
'nuxt-og-image',
|
||||||
],
|
],
|
||||||
|
nitro: {
|
||||||
|
prerender: {
|
||||||
|
crawlLinks: true,
|
||||||
|
autoSubfolderIndex: true,
|
||||||
|
failOnError: true,
|
||||||
|
routes: ['/robots.txt', '/sitemap.xml'],
|
||||||
|
},
|
||||||
|
},
|
||||||
quasar: {
|
quasar: {
|
||||||
lang: 'en-US',
|
lang: 'en-US',
|
||||||
},
|
},
|
||||||
|
googleFonts: {
|
||||||
|
download: true,
|
||||||
|
families: {
|
||||||
|
Lato: true,
|
||||||
|
Alexandria: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
site: {
|
||||||
|
url: websiteURL,
|
||||||
|
name: websiteName,
|
||||||
|
},
|
||||||
|
routeRules: {
|
||||||
|
'/': {
|
||||||
|
sitemap: {
|
||||||
|
changefreq: 'yearly',
|
||||||
|
priority: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/about': {
|
||||||
|
sitemap: {
|
||||||
|
changefreq: 'yearly',
|
||||||
|
priority: 0.8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/projects': {
|
||||||
|
sitemap: {
|
||||||
|
changefreq: 'monthly',
|
||||||
|
priority: 0.8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/social': {
|
||||||
|
sitemap: {
|
||||||
|
changefreq: 'yearly',
|
||||||
|
priority: 0.8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sitemap: {
|
||||||
|
cacheMaxAgeSeconds: 360,
|
||||||
|
exclude: [],
|
||||||
|
credits: false,
|
||||||
|
xslColumns: [
|
||||||
|
{ label: 'URL', width: '50%' },
|
||||||
|
{ label: 'Last Modified', select: 'sitemap:lastmod', width: '25%' },
|
||||||
|
{ label: 'Priority', select: 'sitemap:priority', width: '12.5%' },
|
||||||
|
{
|
||||||
|
label: 'Change Frequency',
|
||||||
|
select: 'sitemap:changefreq',
|
||||||
|
width: '12.5%',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// defaults: { ← Defaults override route rules...
|
||||||
|
// changefreq: 'monthly',
|
||||||
|
// priority: 0.7,
|
||||||
|
// lastmod: buildDate,
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
robots: {
|
||||||
|
blockNonSeoBots: true,
|
||||||
|
credits: false,
|
||||||
|
},
|
||||||
|
linkChecker: {
|
||||||
|
failOnError: true,
|
||||||
|
report: {
|
||||||
|
html: true,
|
||||||
|
markdown: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
typescript: {
|
typescript: {
|
||||||
typeCheck: true,
|
typeCheck: true,
|
||||||
},
|
},
|
||||||
runtimeConfig: {
|
runtimeConfig: {
|
||||||
public: {
|
public: {
|
||||||
version: JSON.stringify(packageJSON.version).slice(1, -1),
|
version: JSON.stringify(packageJSON.version).slice(1, -1),
|
||||||
buildDate: new Date().toISOString().split('T')[0],
|
buildDate,
|
||||||
|
websiteName,
|
||||||
|
websiteURL,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
/* vite: {
|
||||||
|
build: {
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks(id: string) {
|
||||||
|
if (id.includes('node_modules')) {
|
||||||
|
return id
|
||||||
|
.toString()
|
||||||
|
.split('node_modules/')[1]
|
||||||
|
.split('/')[0]
|
||||||
|
.toString()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, */
|
||||||
})
|
})
|
||||||
|
|||||||
3382
package-lock.json
generated
3382
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
@ -17,48 +17,48 @@
|
|||||||
"@nuxt/content": "^2.9.0",
|
"@nuxt/content": "^2.9.0",
|
||||||
"@nuxt/devtools": "latest",
|
"@nuxt/devtools": "latest",
|
||||||
"@nuxt/types": "^2.17.2",
|
"@nuxt/types": "^2.17.2",
|
||||||
|
"@nuxtjs/color-mode": "^3.3.2",
|
||||||
"@nuxtjs/eslint-config-typescript": "^12.1.0",
|
"@nuxtjs/eslint-config-typescript": "^12.1.0",
|
||||||
"@nuxtjs/eslint-module": "^4.1.0",
|
"@nuxtjs/eslint-module": "^4.1.0",
|
||||||
|
"@nuxtjs/google-fonts": "^3.1.0",
|
||||||
"@nuxtjs/stylelint-module": "^5.1.0",
|
"@nuxtjs/stylelint-module": "^5.1.0",
|
||||||
"@pinia/nuxt": "^0.5.1",
|
"@pinia/nuxt": "^0.5.1",
|
||||||
|
"@quasar/extras": "^1.16.8",
|
||||||
"@typescript-eslint/parser": "^6.10.0",
|
"@typescript-eslint/parser": "^6.10.0",
|
||||||
|
"caniuse-lite": "^1.0.30001564",
|
||||||
"csso": "^5.0.5",
|
"csso": "^5.0.5",
|
||||||
"eslint": "^8.53.0",
|
"eslint": "^8.53.0",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-nuxt": "^4.0.0",
|
"eslint-plugin-nuxt": "^4.0.0",
|
||||||
"eslint-plugin-prettier": "^5.0.1",
|
"eslint-plugin-prettier": "^5.0.1",
|
||||||
"nuxt": "^3.8.1",
|
"nuxt": "^3.8.1",
|
||||||
"nuxt-font-loader": "^2.3.4",
|
"nuxt-link-checker": "^2.1.10",
|
||||||
|
"nuxt-og-image": "^2.2.4",
|
||||||
"nuxt-quasar-ui": "^2.0.6",
|
"nuxt-quasar-ui": "^2.0.6",
|
||||||
"prettier": "^3.0.3",
|
"nuxt-simple-robots": "^3.1.9",
|
||||||
|
"nuxt-simple-sitemap": "^4.1.6",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
|
"prettier": "^3.1.0",
|
||||||
|
"quasar": "^2.14.0",
|
||||||
"sass": "^1.69.5",
|
"sass": "^1.69.5",
|
||||||
"stylelint": "^15.11.0",
|
"stylelint": "^15.11.0",
|
||||||
"stylelint-config-recommended-vue": "^1.5.0",
|
"stylelint-config-recommended-vue": "^1.5.0",
|
||||||
"stylelint-config-standard-scss": "^11.1.0",
|
"stylelint-config-standard-scss": "^11.1.0",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.3.2",
|
||||||
"vite-plugin-require": "^0.0.3",
|
"vite-plugin-require": "^0.0.3",
|
||||||
"vue": "^3.3.8",
|
"vue": "^3.3.8",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
"vue-tsc": "^1.8.22"
|
"vue-tsc": "^1.8.22"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/alexandria": "^5.0.8",
|
|
||||||
"@fontsource/jetbrains-mono": "^5.0.17",
|
|
||||||
"@fontsource/lato": "^5.0.17",
|
|
||||||
"@fortawesome/fontawesome": "^1.1.8",
|
|
||||||
"@fortawesome/fontawesome-free": "^6.4.2",
|
"@fortawesome/fontawesome-free": "^6.4.2",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.4.2",
|
"@fortawesome/fontawesome-svg-core": "^6.4.2",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.4.2",
|
"@fortawesome/free-brands-svg-icons": "^6.4.2",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.4.2",
|
"@fortawesome/free-regular-svg-icons": "^6.4.2",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.4.2",
|
"@fortawesome/free-solid-svg-icons": "^6.4.2",
|
||||||
"@fortawesome/vue-fontawesome": "^3.0.5",
|
"@fortawesome/vue-fontawesome": "^3.0.5",
|
||||||
"@quasar/extras": "^1.16.8",
|
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"bootstrap": "^5.3.2",
|
"bootstrap": "^5.3.2"
|
||||||
"caniuse-lite": "^1.0.30001564",
|
|
||||||
"humps": "^2.0.1",
|
|
||||||
"pinia": "^2.1.7",
|
|
||||||
"quasar": "^2.14.0"
|
|
||||||
},
|
},
|
||||||
"version": "0.1.1"
|
"version": "0.1.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,8 @@ useHead({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
defineRobotMeta()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -73,5 +75,15 @@ useHead({
|
|||||||
doesn't help with adhering to deadlines at all. However, you can always
|
doesn't help with adhering to deadlines at all. However, you can always
|
||||||
check them out!
|
check them out!
|
||||||
</p>
|
</p>
|
||||||
|
<h5 class="alex">FAQ</h5>
|
||||||
|
<ul class="list-style-type-faq">
|
||||||
|
<li><strong>Why are you called Endermanch?</strong></li>
|
||||||
|
<li>
|
||||||
|
There's no particular reason to it. When I was rebranding my YouTube
|
||||||
|
channel from Ender's Show to Enderman, the short URL was taken. I went
|
||||||
|
thinking for quite some time, and then concluded that adding «ch» at the
|
||||||
|
end sounded pretty good. I was 14 at the time of making that decision.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useRuntimeConfig } from '#imports'
|
||||||
|
|
||||||
|
const config = useRuntimeConfig()
|
||||||
const meta = {
|
const meta = {
|
||||||
title: 'Enderman',
|
title: 'Enderman',
|
||||||
description:
|
description:
|
||||||
'A software engineer, a malware enthusiast and, most importantly, a weird tall creature.',
|
'A software engineer, a malware enthusiast and, most importantly, a weird tall creature. I have over 300K subscribers on YouTube and over 20K followers on Twitter.',
|
||||||
image: 'https://enderman.ch/images/logo.png',
|
image: 'https://enderman.ch/images/logo.png',
|
||||||
url: 'https://enderman.ch/',
|
url: 'https://enderman.ch/',
|
||||||
}
|
}
|
||||||
@ -22,7 +25,7 @@ useSeoMeta({
|
|||||||
})
|
})
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: 'Enderman',
|
title: config.public.websiteName ? config.public.websiteName : 'Enderman',
|
||||||
htmlAttrs: {
|
htmlAttrs: {
|
||||||
lang: 'en',
|
lang: 'en',
|
||||||
},
|
},
|
||||||
@ -34,6 +37,8 @@ useHead({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
defineRobotMeta()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@ -64,6 +64,8 @@ useHead({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
defineRobotMeta()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@ -84,6 +84,8 @@ useHead({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
defineRobotMeta()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
import { library, config } from '@fortawesome/fontawesome-svg-core'
|
import { library, config } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
|
||||||
import { far } from '@fortawesome/free-regular-svg-icons'
|
|
||||||
import { fab } from '@fortawesome/free-brands-svg-icons'
|
import { fab } from '@fortawesome/free-brands-svg-icons'
|
||||||
import { fas } from '@fortawesome/free-solid-svg-icons'
|
|
||||||
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||||
|
|
||||||
// Add icon packs.
|
// Add icon packs.
|
||||||
library.add(far, fab, fas)
|
library.add(fab)
|
||||||
|
|
||||||
// Let Nuxt manage CSS.
|
// Let Nuxt manage CSS.
|
||||||
config.autoAddCss = false
|
config.autoAddCss = false
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
User-agent: *
|
|
||||||
Disallow: /images
|
|
||||||
Sitemap: https://enderman.ch/sitemap.xml
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http:www.w3.org/1999/xhtml">
|
|
||||||
<url>
|
|
||||||
<loc>https://enderman.ch/</loc>
|
|
||||||
<lastmod>2023-11-19</lastmod>
|
|
||||||
<changefreq>never</changefreq>
|
|
||||||
<priority>1</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://enderman.ch/about</loc>
|
|
||||||
<lastmod>2023-11-19</lastmod>
|
|
||||||
<changefreq>yearly</changefreq>
|
|
||||||
<priority>0.6</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://enderman.ch/projects</loc>
|
|
||||||
<lastmod>2023-11-19</lastmod>
|
|
||||||
<changefreq>monthly</changefreq>
|
|
||||||
<priority>0.9</priority>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://enderman.ch/socials</loc>
|
|
||||||
<lastmod>2023-11-19</lastmod>
|
|
||||||
<changefreq>yearly</changefreq>
|
|
||||||
<priority>0.75</priority>
|
|
||||||
</url>
|
|
||||||
</urlset>
|
|
||||||
Loading…
x
Reference in New Issue
Block a user