<template> <div class="error-page"> <div class="error-page-content"> <div class="row justify-content-center pt-16"> <v-img :src="YodaFireLogo" max-width="200"></v-img> </div> <div class="row justify-content-center"> <h2 class="white--text error-title">Are you lost, traveler?</h2> </div> <div class="row justify-content-center pb-16"> <p class="col-md-6 white--text pt-2 mx-2"> Please contact your team admin or <router-link to="/contact-us">contact us</router-link> for help. </p> </div> <div class="suggestions-container" v-if="pageSuggestions.length > 0"> <h3>Some of these related links might get you back on track:</h3> <div class="d-flex flex-column pa-4"> <a v-for="(result, idx) in pageSuggestions.slice(0, 5)" :key="idx" class="py-2" :href="result.ref" > {{ result.title }} </a> </div> </div> </div> </div> </template> <script> import YodaFireLogo from "@/assets/images/Yoda_Fire.webp"; import Search from "@/api/search.js"; import { routesByPath } from "@/router/routes.js"; const MAX_SUGGESTIONS = 3; export default { name: "ErrorComponent", components: {}, data() { return { YodaFireLogo, pageSuggestions: [], }; }, mounted() { const searchApi = new Search(); // parse out the address bar path into tokens const pathSearchTokens = decodeURI(this.$route.fullPath) .replaceAll("/", " ") .trim() .split(" "); // try increasing edit distances to find potential matches for (let editDistance = 0; editDistance < 4; editDistance++) { const tokens = pathSearchTokens.map((t) => `${t}~${editDistance}`); // run search const results = searchApi.search(tokens.join(" ")); // assemble suggestions this.addSuggestions(results); if (this.pageSuggestions.length >= MAX_SUGGESTIONS) { break; } } }, methods: { /** * Adds the search results from `searchResults` to pageSuggestions, * without adding duplicates */ addSuggestions(searchResults) { // early exit if (searchResults.length === 0) { return; } // get current keys (ref) const refs = this.pageSuggestions.map((suggestion) => suggestion.ref); // add each non-duplicate ref for (const searchResult of searchResults) { if (!refs[searchResult.ref]) { const details = routesByPath[searchResult.ref]; this.pageSuggestions.push( Object.assign(searchResult, { title: details.meta?.title, }) ); } } }, }, }; </script> <style lang="scss" scoped> .error-page { height: 100%; padding-top: 16px; padding-bottom: 16px; background-image: url(@/assets/images/tech-bg.webp); background-attachment: fixed; background-size: cover; background-repeat: no-repeat; background-color: $bottom-bg; .error-title { font-size: 48px; line-height: 48px; text-transform: none; } .suggestions-container { h3 { color: white; text-transform: none; } } } </style>