Dockerized the application, fixed fonts, improved SEO, upgraded to Nuxt 3.8.2

This commit is contained in:
endermanch committed 2023-11-25 19:52:25 +03:00
1 parent 2bd1e4a512
commit 4939d24f62
28 files changed
+3011 -16621

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
# .dockerignore
/.git
/.nuxt
/.output
/node_modules
.gitignore
README.md
+1 -1
View File
@@ -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
View 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"]
+10 -3
View File
@@ -1,23 +1,27 @@
<script setup lang="ts">
import { useQuasar } from 'quasar'
import { useRuntimeConfig } from '#imports'
const config = useRuntimeConfig()
const quasar = useQuasar()
useHead({
titleTemplate: (chunk) => {
return !chunk || chunk === 'Enderman' ? 'Enderman' : `${chunk} – Enderman`
return !chunk || chunk === config.public.websiteName
? config.public.websiteName
: `${chunk} – Enderman`
},
})
</script>
<template>
<NuxtLoadingIndicator color="purple" />
<div
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"
>
<NuxtLayout name="card">
<template #header> </template>
<template #footer>
<ClientOnly>
<template #fallback> </template>
@@ -39,7 +43,10 @@ useHead({
</NuxtLayout>
</div>
<Portal layout="#ender-layout" animate randomize fade />
<ClientOnly>
<template #fallback> </template>
<Portal layout="#ender-layout" animate randomize fade />
</ClientOnly>
<Transition
appear
-22
View File
@@ -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
View File
@@ -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: " ";
}
@counter-style faq {
system: cyclic;
symbols: "\2753" "\1F4A1";
suffix: " ";
}
.list-style-type {
&-none {
list-style-type: none;
@@ -22,4 +28,8 @@
&-enjoy {
list-style-type: enjoy;
}
&-faq {
list-style-type: faq;
}
}
-15791
View File
File diff suppressed because it is too large. Load diff
-1
View File
@@ -1 +0,0 @@
{"version":3,"sourceRoot":"","sources":["main.scss","../../node_modules/bootstrap/scss/mixins/_banner.scss","../../node_modules/bootstrap/scss/_root.scss","../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../node_modules/bootstrap/scss/_reboot.scss","../../node_modules/bootstrap/scss/_variables.scss","../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../node_modules/bootstrap/scss/_type.scss","../../node_modules/bootstrap/scss/mixins/_lists.scss","../../node_modules/bootstrap/scss/_images.scss","../../node_modules/bootstrap/scss/mixins/_image.scss","../../node_modules/bootstrap/scss/_containers.scss","../../node_modules/bootstrap/scss/mixins/_container.scss","../../node_modules/bootstrap/scss/mixins/_breakpoints.scss","../../node_modules/bootstrap/scss/_grid.scss","../../node_modules/bootstrap/scss/mixins/_grid.scss","../../node_modules/bootstrap/scss/_tables.scss","../../node_modules/bootstrap/scss/mixins/_table-variants.scss","../../node_modules/bootstrap/scss/forms/_labels.scss","../../node_modules/bootstrap/scss/forms/_form-text.scss","../../node_modules/bootstrap/scss/forms/_form-control.scss","../../node_modules/bootstrap/scss/mixins/_transition.scss","../../node_modules/bootstrap/scss/mixins/_gradients.scss","../../node_modules/bootstrap/scss/forms/_form-select.scss","../../node_modules/bootstrap/scss/forms/_form-check.scss","../../node_modules/bootstrap/scss/forms/_form-range.scss","../../node_modules/bootstrap/scss/forms/_floating-labels.scss","../../node_modules/bootstrap/scss/forms/_input-group.scss","../../node_modules/bootstrap/scss/mixins/_forms.scss","../../node_modules/bootstrap/scss/_buttons.scss","../../node_modules/bootstrap/scss/mixins/_buttons.scss","../../node_modules/bootstrap/scss/_transitions.scss","../../node_modules/bootstrap/scss/_dropdown.scss","../../node_modules/bootstrap/scss/mixins/_caret.scss","../../node_modules/bootstrap/scss/_button-group.scss","../../node_modules/bootstrap/scss/_nav.scss","../../node_modules/bootstrap/scss/_navbar.scss","../../node_modules/bootstrap/scss/_card.scss","../../node_modules/bootstrap/scss/_accordion.scss","../../node_modules/bootstrap/scss/_breadcrumb.scss","../../node_modules/bootstrap/scss/_pagination.scss","../../node_modules/bootstrap/scss/mixins/_pagination.scss","../../node_modules/bootstrap/scss/_badge.scss","../../node_modules/bootstrap/scss/_alert.scss","../../node_modules/bootstrap/scss/_progress.scss","../../node_modules/bootstrap/scss/_list-group.scss","../../node_modules/bootstrap/scss/_close.scss","../../node_modules/bootstrap/scss/_toasts.scss","../../node_modules/bootstrap/scss/_modal.scss","../../node_modules/bootstrap/scss/mixins/_backdrop.scss","../../node_modules/bootstrap/scss/_tooltip.scss","../../node_modules/bootstrap/scss/mixins/_reset-text.scss","../../node_modules/bootstrap/scss/_popover.scss","../../node_modules/bootstrap/scss/_carousel.scss","../../node_modules/bootstrap/scss/mixins/_clearfix.scss","../../node_modules/bootstrap/scss/_spinners.scss","../../node_modules/bootstrap/scss/_offcanvas.scss","../../node_modules/bootstrap/scss/_placeholders.scss","../../node_modules/bootstrap/scss/helpers/_color-bg.scss","../../node_modules/bootstrap/scss/helpers/_colored-links.scss","../../node_modules/bootstrap/scss/helpers/_focus-ring.scss","../../node_modules/bootstrap/scss/helpers/_icon-link.scss","../../node_modules/bootstrap/scss/helpers/_ratio.scss","../../node_modules/bootstrap/scss/helpers/_position.scss","../../node_modules/bootstrap/scss/helpers/_stacks.scss","../../node_modules/bootstrap/scss/helpers/_visually-hidden.scss","../../node_modules/bootstrap/scss/mixins/_visually-hidden.scss","../../node_modules/bootstrap/scss/helpers/_stretched-link.scss","../../node_modules/bootstrap/scss/helpers/_text-truncation.scss","../../node_modules/bootstrap/scss/mixins/_text-truncate.scss","../../node_modules/bootstrap/scss/helpers/_vr.scss","../../node_modules/bootstrap/scss/mixins/_utilities.scss","../../node_modules/bootstrap/scss/utilities/_api.scss","../../node_modules/animate.css/animate.css","transitions.scss","list-types.scss"],"names":[],"mappings":";AACQ;AACA;ACDN;AAAA;AAAA;AAAA;AAAA;ACDF;AAAA;EASI;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAIA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAIA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAIA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAIA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAIA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAIA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAGF;EACA;EAMA;EACA;EACA;EAOA;EC2OI,qBALI;EDpOR;EACA;EAKA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EAGA;EAEA;EACA;EACA;EAEA;EACA;EAMA;EACA;EACA;EAGA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EAIA;EACA;EACA;EAIA;EACA;EACA;EACA;;;AEhHE;EFsHA;EAGA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EAGE;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAIA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAALine truncated
-15
View File
@@ -1,15 +0,0 @@
@charset "UTF-8";@import "@fontsource/Lato/index.css";@import "@fontsource/Alexandria/700.css";
/*!
* Bootstrap v5.3.2 (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-wave{to{mask-position:-200%0}}:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13, 110, 253;--bs-secondary-rgb:108, 117, 125;--bs-success-rgb:25, 135, 84;--bs-info-rgb:13, 202, 240;--bs-warning-rgb:255, 193, 7;--bs-danger-rgb:220, 53, 69;--bs-light-rgb:248, 249, 250;--bs-dark-rgb:33, 37, 41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255, 255, 255;--bs-black-rgb:0, 0, 0;--bs-font-sans-serif:system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace:SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33, 37, 41;--bs-body-bg:#fff;--bs-body-bg-rgb:255, 255, 255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0, 0, 0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33, 37, 41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233, 236, 239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33, 37, 41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248, 249, 250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13, 110, 253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10, 88, 202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222, 226, 230;--bs-body-bg:#212529;--bs-body-bg-rgb:33, 37, 41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255, 255, 255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222, 226, 230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52, 58, 64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222, 226, 230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43, 48, 53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0Line truncated
/*!
* animate.css - https://animate.style/
* Version - 4.1.1
* Licensed under the MIT license - http://opensource.org/licenses/MIT
*
* Copyright (c) 2020 Animate.css
*/
@-webkit-keyframes bounce{0%,20%,53%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0) scaleY(1.1);transform:translate3d(0,-30px,0) scaleY(1.1)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0) scaleY(1.05);transform:translate3d(0,-15px,0) scaleY(1.05)}80%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translate3d(0,0,0) scaleY(.95);transform:translate3d(0,0,0) scaleY(.95)}90%{-webkit-transform:translate3d(0,-4px,0) scaleY(1.02);transform:translate3d(0,-4px,0) scaleY(1.02)}}@keyframes bounce{0%,20%,53%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0) scaleY(1.1);transform:translate3d(0,-30px,0) scaleY(1.1)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0) scaleY(1.05);transform:translate3d(0,-15px,0) scaleY(1.05)}80%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translate3d(0,0,0) scaleY(.95);transform:translate3d(0,0,0) scaleY(.95)}90%{-webkit-transform:translate3d(0,-4px,0) scaleY(1.02);transform:translate3d(0,-4px,0) scaleY(1.02)}}@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@-webkit-keyframes pulse{0%,to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}}@keyframes pulse{0%,to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}}@-webkit-keyframes rubberBand{0%,to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}}@keyframes rubberBand{0%,to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}}@-webkit-keyframes shakeX{0%,to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shakeX{0%,to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@-webkit-keyframes shakeY{0%,to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}20%,40%,60%,80%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}}@keyframes shakeY{0%,to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}20%,40%,60%,80%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}}@-webkit-keyframes headShake{0%,50%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}}@keyframes headShake{0%,50%{-webkit-transform:translateX(0);traLine truncated
+36 -24
View File
@@ -1,21 +1,20 @@
// Fonts.
@import '@fontsource/Lato/index.css';
@import '@fontsource/Alexandria/700.css';
$grid-breakpoints: (
xs: 0,
sm: 601px,
md: 996px,
lg: 1281px,
xl: 1921px,
xxl: 2561px
// Libraries.
@use '@fortawesome/fontawesome-svg-core/styles.css' as fontawesome;
@use 'bootstrap' with (
$grid-breakpoints: (
xs: 0,
sm: 601px,
md: 996px,
lg: 1281px,
xl: 1921px,
xxl: 2561px
)
);
@use 'animate.css';
// Bootstrap & animations.
@import '../../node_modules/bootstrap/scss/bootstrap';
@import '../../node_modules/animate.css/animate';
@import 'transitions';
@import 'list-types';
// Modules.
@use 'transitions';
@use 'lists';
// CSS Variables.
:root {
@@ -33,18 +32,25 @@ html {
body {
display: flex;
flex-direction: column;
position: sticky;
background-color: rgb(6 25 28);
background-image: url('~/assets/images/sky.png');
background-attachment: fixed;
background-blend-mode: multiply;
background-size: cover;
background-repeat: no-repeat;
image-rendering: pixelated;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: white;
font-family: Lato, sans-serif;
font-size: 18px;
height: 100%;
}
@@ -78,6 +84,7 @@ body {
.alex {
font-family: Alexandria, sans-serif;
font-weight: 700;
}
.smooth-glide {
@@ -94,17 +101,21 @@ body {
min-height: 100%;
}
.link {
%link {
color: inherit;
text-decoration: none;
transition: 0.3s ease;
}
.link {
@extend %link;
&:hover {
color: cornflowerblue;
}
&-hi {
@extend .link;
@extend %link;
color: cornflowerblue;
@@ -113,7 +124,7 @@ body {
}
&-force-dark {
@extend .link;
@extend %link;
color: cornflowerblue;
@@ -210,7 +221,7 @@ body {
}
// Dynamic classes.
@include media-breakpoint-up(sm) {
@include bootstrap.media-breakpoint-up(sm) {
#ender-app {
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 {
width: 60%;
}
}
@include media-breakpoint-up(xl) {
@include bootstrap.media-breakpoint-up(xl) {
.dimensions {
width: 40%;
}
}
@include media-breakpoint-up(xxl) {
@include bootstrap.media-breakpoint-up(xxl) {
.dimensions {
width: 30%;
}
-9
View File
@@ -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
View File
@@ -1 +0,0 @@
{"version":3,"sourceRoot":"","sources":["transitions.scss"],"names":[],"mappings":"AACE;EAEE;;AAGF;EAEE;EACA","file":"transitions.css"}
+5 -3
View File
@@ -6,8 +6,10 @@ const props = defineProps({
})
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: ${
config.public.version
}%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
rights reserved.
<sub>
β{{ config.public.version ? config.public.version : '?.?.?' }} ({{
config.public.buildDate ? config.public.buildDate : '1970-01-01'
β{{ version ? version : '?.?.?' }} ({{
buildDate ? buildDate : '1970-01-01'
}})
</sub>
</span>
+16 -3
View File
@@ -11,7 +11,20 @@ const pageStore = usePageStore()
const { pages } = storeToRefs(pageStore)
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>
<template>
@@ -31,8 +44,8 @@ const icons = [aboutIcon, projectIcon, socialIcon]
<LinkButton
:path="page.path"
:name="page.name"
:icon="icons[index]"
alt="Info"
:icon="icons[index].src"
:alt="icons[index].alt"
/>
</li>
</ul>
+7
View 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
View 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
+9 -15
View File
@@ -13,9 +13,6 @@ const { pages } = storeToRefs(pageStore)
const swipe = useSwipe(card, {
passive: true,
onSwipe: (_touch: TouchEvent) => {
console.log(card.value?.offsetWidth, swipe.lengthX.value)
},
onSwipeEnd: (_touch: TouchEvent, _direction: UseSwipeDirection) => {
const currentPage = pages.value.find(
(page) => page.path === route.fullPath,
@@ -25,21 +22,18 @@ const swipe = useSwipe(card, {
if (
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(
toRaw(pages.value)[
currentIndex - 1 < 0
router.push(
toRaw(pages.value)[
swipe.lengthX.value > 0
? (currentIndex + 1) % pages.value.length
: currentIndex - 1 < 0
? pages.value.length - (currentIndex + 1)
: currentIndex - 1
].path,
)
} else {
router.push(
toRaw(pages.value)[(currentIndex + 1) % pages.value.length].path,
)
}
].path,
)
}
},
})
+110 -12
View File
@@ -1,6 +1,10 @@
import eslint from 'vite-plugin-eslint'
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
export default defineNuxtConfig({
app: {
@@ -41,32 +45,126 @@ export default defineNuxtConfig({
},
],
},
css: [
'~/assets/styles/main.min.css',
'@fortawesome/fontawesome-svg-core/styles.css',
],
css: ['~/assets/styles/main.scss'],
plugins: [],
modules: [
'nuxt-font-loader',
'@nuxt/content',
[
'@nuxtjs/eslint-module',
{ fix: true, failOnError: true, lintOnStart: false },
],
'@pinia/nuxt',
'@nuxt/content',
'nuxt-quasar-ui',
['@nuxtjs/eslint-module', { failOnError: false, 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: {
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: {
typeCheck: true,
},
runtimeConfig: {
public: {
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()
}
},
},
},
},
}, */
})
+2711 -671
View File
File diff suppressed because it is too large. Load diff
+13 -13
View File
@@ -17,48 +17,48 @@
"@nuxt/content": "^2.9.0",
"@nuxt/devtools": "latest",
"@nuxt/types": "^2.17.2",
"@nuxtjs/color-mode": "^3.3.2",
"@nuxtjs/eslint-config-typescript": "^12.1.0",
"@nuxtjs/eslint-module": "^4.1.0",
"@nuxtjs/google-fonts": "^3.1.0",
"@nuxtjs/stylelint-module": "^5.1.0",
"@pinia/nuxt": "^0.5.1",
"@quasar/extras": "^1.16.8",
"@typescript-eslint/parser": "^6.10.0",
"caniuse-lite": "^1.0.30001564",
"csso": "^5.0.5",
"eslint": "^8.53.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-nuxt": "^4.0.0",
"eslint-plugin-prettier": "^5.0.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",
"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",
"stylelint": "^15.11.0",
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard-scss": "^11.1.0",
"typescript": "^5.2.2",
"typescript": "^5.3.2",
"vite-plugin-require": "^0.0.3",
"vue": "^3.3.8",
"vue-router": "^4.2.5",
"vue-tsc": "^1.8.22"
},
"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-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2",
"@fortawesome/free-regular-svg-icons": "^6.4.2",
"@fortawesome/free-solid-svg-icons": "^6.4.2",
"@fortawesome/vue-fontawesome": "^3.0.5",
"@quasar/extras": "^1.16.8",
"animate.css": "^4.1.1",
"bootstrap": "^5.3.2",
"caniuse-lite": "^1.0.30001564",
"humps": "^2.0.1",
"pinia": "^2.1.7",
"quasar": "^2.14.0"
"bootstrap": "^5.3.2"
},
"version": "0.1.1"
}
+12
View File
@@ -37,6 +37,8 @@ useHead({
},
],
})
defineRobotMeta()
</script>
<template>
@@ -73,5 +75,15 @@ useHead({
doesn't help with adhering to deadlines at all. However, you can always
check them out!
</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>
</template>
+7 -2
View File
@@ -1,8 +1,11 @@
<script setup lang="ts">
import { useRuntimeConfig } from '#imports'
const config = useRuntimeConfig()
const meta = {
title: 'Enderman',
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',
url: 'https://enderman.ch/',
}
@@ -22,7 +25,7 @@ useSeoMeta({
})
useHead({
title: 'Enderman',
title: config.public.websiteName ? config.public.websiteName : 'Enderman',
htmlAttrs: {
lang: 'en',
},
@@ -34,6 +37,8 @@ useHead({
},
],
})
defineRobotMeta()
</script>
<template>
+2
View File
@@ -64,6 +64,8 @@ useHead({
},
],
})
defineRobotMeta()
</script>
<template>
+2
View File
@@ -84,6 +84,8 @@ useHead({
},
],
})
defineRobotMeta()
</script>
<template>
+1 -4
View File
@@ -1,13 +1,10 @@
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 { fas } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
// Add icon packs.
library.add(far, fab, fas)
library.add(fab)
// Let Nuxt manage CSS.
config.autoAddCss = false
-3
View File
@@ -1,3 +0,0 @@
User-agent: *
Disallow: /images
Sitemap: https://enderman.ch/sitemap.xml
-27
View File
@@ -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>