Raw blog finished
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
const config = useAppConfig()
|
||||
const meta = {
|
||||
title: 'Page not found',
|
||||
description:
|
||||
'The page you are looking for does not exist. It might have been removed, had its name changed, or is temporarily unavailable.',
|
||||
image: `${config.url}/images/logo.png`,
|
||||
url: config.url,
|
||||
}
|
||||
|
||||
let slug = useRoute().params.slug
|
||||
|
||||
if (Array.isArray(slug)) slug = slug.join('/')
|
||||
|
||||
const error = {
|
||||
http_code: 200,
|
||||
title: config.title,
|
||||
url: config.url + '/' + slug,
|
||||
locale: config.locale || 'en',
|
||||
data: {
|
||||
path: '/error.vue',
|
||||
content: {
|
||||
title: 'Page not found!',
|
||||
description:
|
||||
"The page you are looking for does not exist. However, no 404 error has occurred, as you're browsing through a web application loaded into memory and HTTP error codes make no sense here.",
|
||||
},
|
||||
},
|
||||
slug: useRoute().params.slug,
|
||||
build: config.build,
|
||||
hint: 'Use the navigation bar to get back to the main page.',
|
||||
}
|
||||
const errorString = JSON.stringify(error, null, 2)
|
||||
const buffer = ref('')
|
||||
|
||||
const startTime = Date.now()
|
||||
const dt = 20
|
||||
|
||||
let i = 0
|
||||
|
||||
function type() {
|
||||
if (Date.now() > startTime + dt * i) buffer.value += errorString[i++]
|
||||
if (i < errorString.length) requestAnimationFrame(type)
|
||||
}
|
||||
|
||||
onMounted(() => setTimeout(type, 1500))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<h3 class="alex">Page not found!</h3>
|
||||
<pre class="pre-wrap">{{ buffer }}<span class="blinker">▊</span></pre>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.blinker {
|
||||
animation: blinker 1s steps(2, start) infinite;
|
||||
}
|
||||
|
||||
@keyframes blinker {
|
||||
from {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
to {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
logo: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
sectionLogo: {
|
||||
type: null as unknown as PropType<string | null>,
|
||||
default: null,
|
||||
required: false,
|
||||
},
|
||||
thumbnail: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
alt: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const sentence = computed(() => {
|
||||
return props.description.split('.')[0] + '...'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full h-full flex flex-col justify-end text-white relative">
|
||||
<img
|
||||
:src="thumbnail"
|
||||
:alt="alt"
|
||||
class="w-full h-full object-cover absolute top-0 left-0"
|
||||
/>
|
||||
<div class="absolute top-0 left-0 p-5">
|
||||
<img :src="logo" alt="Logo" class="w-[100] h-[100]" />
|
||||
</div>
|
||||
<div v-if="sectionLogo" class="absolute top-0 right-0 p-5">
|
||||
<img :src="sectionLogo" alt="Logo" class="w-[100] h-[100]" />
|
||||
</div>
|
||||
|
||||
<div class="mb-5 px-5" style="text-shadow: black 1px 1px 10px">
|
||||
<h1 class="m-0 text-[60px]">{{ title }}</h1>
|
||||
<strong class="min-h-[90px] m-0 text-[24px]" style="font-family: Lato">{{
|
||||
sentence
|
||||
}}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user