This commit is contained in:
2023-04-19 14:26:27 +10:00
parent ff93265890
commit f0459b3f6e
4 changed files with 170 additions and 216 deletions

View File

@@ -143,36 +143,6 @@ li {
// margin-bottom: 1rem; // margin-bottom: 1rem;
// } // }
// /* Page Errors */
// .sm-page-error {
// display: flex;
// flex-direction: column;
// .sm-error-number {
// display: flex;
// justify-content: center;
// align-items: center;
// font-size: 30vw;
// font-weight: 600;
// color: #295b7e;
// img {
// height: 25vw;
// margin: 0 0.5rem 0 1rem;
// }
// }
// .sm-error-content {
// text-align: center;
// font-size: 120%;
// h2 {
// margin-top: 0;
// margin-bottom: 0.5rem;
// }
// }
// }
/* SM Dialog */ /* SM Dialog */
.dialog-outer { .dialog-outer {
position: fixed; position: fixed;

View File

@@ -1,32 +1,35 @@
<template> <template>
<div <template v-if="pageError < 300">
:class="['sm-page-outer', { 'sm-no-breadcrumbs': noBreadcrumbs }]" <slot></slot>
:style="styleObject"> </template>
<SMLoader :loading="loading"> <template v-else>
<SMErrorForbidden <SMContainer class="page-error">
v-if="pageError == 403 || !hasPermission()"></SMErrorForbidden> <div class="error-number" v-html="modifiedPageError"></div>
<SMErrorInternal <div class="error-content">
v-if="pageError >= 500 && hasPermission()"></SMErrorInternal> <h2>Ooops!</h2>
<SMErrorNotFound <p v-if="pageError == 403">This page is not for you to view!</p>
v-if="pageError == 404 && hasPermission()"></SMErrorNotFound> <p v-else-if="pageError == 404">
<div v-if="pageError < 300 && hasPermission()" class="sm-page"> The page you are looking for does not exist!
<slot></slot> </p>
<SMContainer v-if="slots.container" <p v-else>
><slot name="container"></slot We are working to fix that what was broken. Please try again
></SMContainer> later!
</p>
<SMButton label="Go Back" @click="handleClick" />
</div> </div>
</SMLoader> </SMContainer>
</div> </template>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useSlots } from "vue"; import { useRouter } from "vue-router";
import { useApplicationStore } from "../store/ApplicationStore";
import { useUserStore } from "../store/UserStore"; import { useUserStore } from "../store/UserStore";
import SMErrorForbidden from "./errors/Forbidden.vue"; import SMButton from "../components/SMButton.vue";
import SMErrorInternal from "./errors/Internal.vue"; import { computed, watch, ref } from "vue";
import SMErrorNotFound from "./errors/NotFound.vue";
import SMContainer from "./SMContainer.vue"; const router = useRouter();
import SMLoader from "./SMLoader.vue"; const applicationStore = useApplicationStore();
const props = defineProps({ const props = defineProps({
pageError: { pageError: {
@@ -44,58 +47,79 @@ const props = defineProps({
default: false, default: false,
required: false, required: false,
}, },
background: {
type: String,
default: "",
required: false,
},
noBreadcrumbs: {
type: Boolean,
default: false,
required: false,
},
}); });
const slots = useSlots(); const pageError = ref(props.pageError);
const userStore = useUserStore();
let styleObject = {};
if (props.background != "") { watch(
styleObject["backgroundImage"] = `url('${props.background}')`; () => props.pageError,
} (newValue) => {
pageError.value = newValue;
}
);
/** /**
* Return if the current user has the props.permission to view this page. * Handle user clicking back/home button
*
* @returns {boolean} If the user has the permission.
*/ */
const hasPermission = (): boolean => { const handleClick = () => {
return ( router.go(-1);
props.permission.length == 0 ||
userStore.permissions.includes(props.permission)
);
}; };
const modifiedPageError = computed(() => {
const errorNumber = pageError.value.toString(); // Convert to string
const middleDigit = errorNumber.charAt(1); // Get the middle digit
if (pageError.value >= 300) {
applicationStore.setDynamicTitle("Server Error");
}
if (middleDigit === "0") {
return errorNumber.replace(
middleDigit,
'<img src="/img/sad-monster.png" />'
); // Replace with image
} else {
return errorNumber; // Use the entire number
}
});
const userStore = useUserStore();
if (
props.permission.length !== 0 &&
userStore.permissions.includes(props.permission) == false &&
pageError.value < 300
) {
pageError.value = 403;
}
</script> </script>
<style lang="scss"> <style lang="scss">
.sm-page-outer { .page-error {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1;
width: 100%;
padding-bottom: calc(map-get($spacer, 5) * 2);
background-position: center;
background-repeat: no-repeat;
background-size: cover;
&.sm-no-breadcrumbs { .error-number {
margin-bottom: 0; display: flex;
justify-content: center;
align-items: center;
font-size: 30vw;
font-weight: 600;
color: #295b7e;
img {
height: 25vw;
margin: 0 0.5rem 0 1rem;
}
} }
.sm-page { .error-content {
display: flex; text-align: center;
flex-direction: column; font-size: 120%;
flex: 1;
h2 {
margin-top: 0;
margin-bottom: 0.5rem;
}
} }
} }
</style> </style>

View File

@@ -1,35 +0,0 @@
<template>
<SMPage no-breadcrumbs>
<div class="sm-page-error sm-error-not-found">
<div class="sm-error-number">
5<img src="/img/sad-monster.png" />0
</div>
<div class="sm-error-content">
<h2>Ooops!</h2>
<p>
We are working to fix that what was broken. Please try again
later!
</p>
<SMButton label="Go Back" @click="handleClick" />
</div>
</div>
</SMPage>
</template>
<script setup lang="ts">
import SMButton from "../SMButton.vue";
import { useRouter } from "vue-router";
import { useApplicationStore } from "../../store/ApplicationStore";
const router = useRouter();
const applicationStore = useApplicationStore();
applicationStore.setDynamicTitle("Server Error");
/**
* Handle user clicking back/home button
*/
const handleClick = () => {
router.go(-1);
};
</script>

View File

@@ -1,9 +1,5 @@
<template> <template>
<SMPage <SMPage :page-error="pageError" permission="admin/userss">
:full="true"
:loading="pageLoading"
class="sm-workshop-view"
:page-error="pageError">
<div <div
class="sm-workshop-image" class="sm-workshop-image"
:style="{ :style="{
@@ -129,6 +125,7 @@ import { SMDate } from "../helpers/datetime";
import { stringToNumber } from "../helpers/string"; import { stringToNumber } from "../helpers/string";
import { useApplicationStore } from "../store/ApplicationStore"; import { useApplicationStore } from "../store/ApplicationStore";
import { mediaGetVariantUrl } from "../helpers/media"; import { mediaGetVariantUrl } from "../helpers/media";
import SMPage from "../components/SMPage.vue";
const applicationStore = useApplicationStore(); const applicationStore = useApplicationStore();
@@ -303,104 +300,102 @@ handleLoad();
</script> </script>
<style lang="scss"> <style lang="scss">
.sm-workshop-view { .sm-workshop-image {
.sm-workshop-image { display: flex;
display: flex; justify-content: center;
justify-content: center; align-items: center;
align-items: center; min-height: map-get($spacer, 5) * 4;
min-height: map-get($spacer, 5) * 4; height: 20vw;
height: 20vw; background-position: center;
background-position: center; background-repeat: no-repeat;
background-repeat: no-repeat; background-size: cover;
background-size: cover; background-color: #eee;
background-color: #eee; transition: background-image 0.2s;
transition: background-image 0.2s;
.sm-workshop-image-loader { .sm-workshop-image-loader {
font-size: 5rem; font-size: 5rem;
color: $secondary-color; color: $secondary-color;
} }
}
.sm-workshop-page {
display: flex;
flex-direction: row;
.sm-workshop-body,
.sm-workshop-info {
line-height: 1.5rem;
} }
.sm-workshop-page { .sm-workshop-body {
display: flex; flex: 1;
flex-direction: row; text-align: left;
}
.sm-workshop-body, .sm-workshop-info {
.sm-workshop-info { width: 18rem;
line-height: 1.5rem; margin-left: 2rem;
h4 {
margin-bottom: 0.25rem;
display: flex;
align-items: center;
height: 1rem;
.icon {
display: inline-block;
width: 1rem;
margin-right: 0.5rem;
text-align: center;
}
} }
.sm-workshop-body { p {
flex: 1; margin: 0;
text-align: left; padding-left: 1.5rem;
font-size: 90%;
} }
.sm-workshop-info { .sm-workshop-registration {
width: 18rem; margin-top: 1.5rem;
margin-left: 2rem; line-height: 1.25rem;
}
h4 { .sm-workshop-registration-none,
margin-bottom: 0.25rem; .sm-workshop-registration-soon,
display: flex; .sm-workshop-registration-message {
align-items: center; border: 1px solid #ffeeba;
height: 1rem; background-color: #fff3cd;
color: #856404;
text-align: center;
font-size: 80%;
padding: 0.5rem;
}
.icon { .sm-workshop-registration-closed,
display: inline-block; .sm-workshop-registration-cancelled {
width: 1rem; border: 1px solid #f5c2c7;
margin-right: 0.5rem; background-color: #f8d7da;
text-align: center; color: #842029;
} text-align: center;
} font-size: 80%;
padding: 0.5rem;
}
p { .sm-workshop-date,
margin: 0; .sm-workshop-location,
padding-left: 1.5rem; .sm-workshop-price,
font-size: 90%; .sm-workshop-ages {
} padding: 0 1rem;
}
.sm-workshop-registration { .sm-workshop-ages p {
margin-top: 1.5rem; margin-top: 0.5rem;
line-height: 1.25rem; margin-left: 1rem;
} padding: 0 0 0 0.5rem;
font-size: 80%;
.sm-workshop-registration-none, border-left: 4px solid $warning-color;
.sm-workshop-registration-soon, line-height: 1.2rem;
.sm-workshop-registration-message {
border: 1px solid #ffeeba;
background-color: #fff3cd;
color: #856404;
text-align: center;
font-size: 80%;
padding: 0.5rem;
}
.sm-workshop-registration-closed,
.sm-workshop-registration-cancelled {
border: 1px solid #f5c2c7;
background-color: #f8d7da;
color: #842029;
text-align: center;
font-size: 80%;
padding: 0.5rem;
}
.sm-workshop-date,
.sm-workshop-location,
.sm-workshop-price,
.sm-workshop-ages {
padding: 0 1rem;
}
.sm-workshop-ages p {
margin-top: 0.5rem;
margin-left: 1rem;
padding: 0 0 0 0.5rem;
font-size: 80%;
border-left: 4px solid $warning-color;
line-height: 1.2rem;
}
} }
} }
} }