remove vue components

This commit is contained in:
2023-11-27 10:34:39 +10:00
committed by GitHub
parent 0772010119
commit 3ef4075aa7
11 changed files with 0 additions and 1016 deletions

View File

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +0,0 @@
import Router from "@/router";
import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
import { createApp } from "vue";
import App from "./views/App.vue";
import "uno.css";
import "../css/app.scss";
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
createApp(App).use(pinia).use(Router).mount("#app");

View File

@@ -1,619 +0,0 @@
import { useUserStore } from "@/store/UserStore";
import { createRouter, createWebHistory } from "vue-router";
import { api } from "../helpers/api";
import { useApplicationStore } from "../store/ApplicationStore";
import { updateSEOTags } from "../helpers/seo";
export const routes = [
{
path: "/",
name: "home",
meta: {
title: "Home",
description:
"STEMMechanics, a family-run company based in Cairns, Queensland, creates fantastic STEM-focused programs and activities that are both entertaining and educational.",
},
component: () => import("@/views/Home.vue"),
},
{
path: "/blog",
name: "blog",
meta: {
title: "Blog",
},
component: () => import(/* webpackPrefetch: true */ "@/views/Blog.vue"),
},
{
path: "/article",
redirect: "/blog",
children: [
{
path: ":slug",
name: "article",
component: () => import("@/views/Article.vue"),
},
],
},
{
path: "/workshops",
name: "workshops",
meta: {
title: "Workshops",
},
component: () =>
import(/* webpackPreload: true */ "@/views/Workshops.vue"),
},
{
path: "/event",
redirect: "/workshops",
children: [
{
path: ":id",
name: "event",
component: () => import("@/views/Event.vue"),
},
],
},
{
path: "/verify-email",
name: "verify-email",
meta: {
title: "Verify Email",
},
component: () => import("@/views/EmailVerify.vue"),
},
{
path: "/resend-verify-email",
name: "resend-verify-email",
meta: {
title: "Resend Verification Email",
},
component: () => import("@/views/ResendEmailVerify.vue"),
},
{
path: "/reset-password",
name: "reset-password",
meta: {
title: "Reset Password",
},
component: () => import("@/views/ResetPassword.vue"),
},
{
path: "/privacy",
name: "privacy",
meta: {
title: "Privacy Policy",
},
component: () => import("@/views/Privacy.vue"),
},
{
path: "/rules",
name: "rules",
meta: {
title: "Rules",
},
component: () => import("@/views/Rules.vue"),
},
{
path: "/community",
name: "community",
meta: {
title: "Community",
},
component: () => import("@/views/Community.vue"),
},
{
path: "/minecraft",
children: [
{
path: "",
name: "minecraft",
meta: {
title: "Minecraft",
},
component: () => import("@/views/Minecraft.vue"),
},
{
path: "curve",
name: "minecraft-curve",
meta: {
title: "Minecraft Curve",
},
component: () => import("@/views/MinecraftCurve.vue"),
},
],
},
{
path: "/login",
name: "login",
meta: {
title: "Login",
middleware: "guest",
},
component: () =>
import(/* webpackPrefetch: true */ "@/views/Login.vue"),
},
{
path: "/logout",
name: "logout",
meta: {
title: "Logout",
},
component: () => import("@/views/Logout.vue"),
},
{
path: "/contact",
name: "contact",
meta: {
title: "Contact",
},
component: () =>
import(/* webpackPrefetch: true */ "@/views/Contact.vue"),
},
{
path: "/conduct",
redirect: { name: "code-of-conduct" },
},
{
path: "/code-of-conduct",
name: "code-of-conduct",
meta: {
title: "Code of Conduct",
},
component: () => import("@/views/CodeOfConduct.vue"),
},
{
path: "/terms",
redirect: { name: "terms-and-conditions" },
},
{
path: "/terms-and-conditions",
name: "terms-and-conditions",
meta: {
title: "Terms and Conditions",
},
component: () => import("@/views/TermsAndConditions.vue"),
},
{
path: "/register",
name: "register",
meta: {
title: "Register",
},
component: () =>
import(/* webpackPrefetch: true */ "@/views/Register.vue"),
},
{
path: "/dashboard",
children: [
{
path: "",
name: "dashboard",
meta: {
title: "Dashboard",
middleware: "authenticated",
},
component: () =>
import(
/* webpackPrefetch: true */ "@/views/dashboard/Dashboard.vue"
),
},
{
path: "analytics",
children: [
{
path: "",
name: "dashboard-analytics-list",
meta: {
title: "Analytics",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/AnalyticsList.vue"),
},
{
path: ":id",
name: "dashboard-analytics-item",
meta: {
title: "Analytics Session",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/AnalyticsItem.vue"),
},
],
},
{
path: "articles",
children: [
{
path: "",
name: "dashboard-article-list",
meta: {
title: "Articles",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/ArticleList.vue"),
},
{
path: "create",
name: "dashboard-article-create",
meta: {
title: "Create Article",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/ArticleEdit.vue"),
},
{
path: ":id",
name: "dashboard-article-edit",
meta: {
title: "Edit Article",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/ArticleEdit.vue"),
},
],
},
{
path: "events",
children: [
{
path: "",
name: "dashboard-event-list",
meta: {
title: "Events",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/EventList.vue"),
},
{
path: "create",
name: "dashboard-event-create",
meta: {
title: "Create Event",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/EventEdit.vue"),
},
{
path: ":id",
name: "dashboard-event-edit",
meta: {
title: "Event",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/EventEdit.vue"),
},
],
},
{
path: "details",
name: "dashboard-account-details",
meta: {
title: "Account Details",
middleware: "authenticated",
},
component: () => import("@/views/dashboard/UserEdit.vue"),
},
{
path: "users",
children: [
{
path: "",
name: "dashboard-user-list",
meta: {
title: "Users",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/UserList.vue"),
},
{
path: "create",
name: "dashboard-user-create",
meta: {
title: "Create User",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/UserEdit.vue"),
},
{
path: ":id",
name: "dashboard-user-edit",
meta: {
title: "Edit User",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/UserEdit.vue"),
},
],
},
{
path: "media",
children: [
{
path: "",
name: "dashboard-media-list",
meta: {
title: "Media",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/MediaList.vue"),
},
{
path: "create",
name: "dashboard-media-create",
meta: {
title: "Upload Media",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/MediaEdit.vue"),
},
{
path: ":id",
name: "dashboard-media-edit",
meta: {
title: "Edit Media",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/MediaEdit.vue"),
},
],
},
{
path: "shortlinks",
children: [
{
path: "",
name: "dashboard-shortlink-list",
meta: {
title: "Shortlink",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/ShortlinkList.vue"),
},
{
path: "create",
name: "dashboard-shortlink-create",
meta: {
title: "Create Shortlink",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/ShortlinkEdit.vue"),
},
{
path: ":id",
name: "dashboard-shortlink-edit",
meta: {
title: "Edit Shortlink",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/ShortlinkEdit.vue"),
},
],
},
{
path: "discord-bot-logs",
name: "dashboard-discord-bot-logs",
meta: {
title: "Discord Bot Logs",
middleware: "authenticated",
},
component: () => import("@/views/dashboard/DiscordBotLogs.vue"),
},
],
},
{
path: "/forgot-password",
name: "forgot-password",
meta: {
title: "Forgot Password",
},
component: () => import("@/views/ForgotPassword.vue"),
},
{
path: "/file/:id",
name: "file",
meta: {
title: "File",
},
component: () => import("@/views/File.vue"),
},
{
path: "/cart",
name: "cart",
meta: {
title: "Cart",
},
component: () => import("@/views/Cart.vue"),
},
{
path: "/:catchAll(.*)",
name: "not-found",
meta: {
title: "Page not found",
hideInEditor: true,
},
component: () => import("@/views/404.vue"),
},
];
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior() {
return { top: 0 };
},
});
// export let activeRoutes = [];
router.beforeEach(async (to, from, next) => {
const userStore = useUserStore();
const applicationStore = useApplicationStore();
applicationStore.hydrated = false;
applicationStore.clearDynamicTitle();
if (applicationStore.pageLoaderTimeout !== 0) {
window.clearTimeout(applicationStore.pageLoaderTimeout);
applicationStore.pageLoaderTimeout = window.setTimeout(() => {
const pageLoadingElem = document.getElementById("sm-page-loading");
if (pageLoadingElem !== null) {
pageLoadingElem.style.display = "flex";
}
}, 0);
}
if (to.meta.middleware == "authenticated") {
if (userStore.id) {
api.get({
url: "/me",
})
.then((res) => {
userStore.setUserDetails(res.data.user);
})
.catch((err) => {
console.log(err);
if (err.status == 401) {
userStore.clearUser();
window.location.href = `/login?redirect=${to.fullPath}`;
}
});
}
if (!userStore.id) {
next({
name: "login",
query: { redirect: encodeURIComponent(to.fullPath) },
});
return;
}
}
api.post({
url: "/analytics",
body: {
type: "pageview",
path: to.fullPath,
},
}).catch(() => {
/* empty */
});
next();
});
router.afterEach((to, from) => {
const applicationStore = useApplicationStore();
if (from.name !== undefined) {
document.body.classList.remove(`page-${from.name}`);
}
document.body.classList.add(`page-${to.name}`);
window.setTimeout(() => {
const getMetaValue = (tag, defaultValue = "") => {
const getMeta = (obj, tag) => {
const tagHierarchy = tag.split(".");
const nearestWithMeta = obj.matched
.slice()
.reverse()
.reduce(
(acc, r) => acc || (r.meta && r.meta[tagHierarchy[0]]),
null,
);
if (nearestWithMeta) {
let result = nearestWithMeta;
for (let i = 1; i < tagHierarchy.length; i++) {
result = result[tagHierarchy[i]];
if (!result) break;
}
if (result !== undefined) return result;
}
return null;
};
const nearestMeta = getMeta(to, tag);
if (nearestMeta == null) {
const previousMeta = getMeta(from, tag);
if (previousMeta == null) {
return defaultValue;
}
return previousMeta;
}
return nearestMeta;
};
updateSEOTags({
title: getMetaValue("title"),
description: getMetaValue("description"),
keywords: getMetaValue("keywords", []),
robots: {
index: getMetaValue(
"robots.index",
!to.meta.middleware
? true
: to.meta.middleware != "authenticated",
),
follow: getMetaValue(
"robots.follow",
!to.meta.middleware
? true
: to.meta.middleware != "authenticated",
),
},
url: getMetaValue("url", to.path),
image: getMetaValue("image", ""),
});
}, 10);
window.setTimeout(() => {
const autofocusElement = document.querySelector("[autofocus]");
if (autofocusElement) {
autofocusElement.focus();
}
const hash = window.location.hash;
if (hash) {
const target = document.querySelector(hash);
if (target) {
target.scrollIntoView();
}
}
}, 10);
if (applicationStore.pageLoaderTimeout !== 0) {
window.clearTimeout(applicationStore.pageLoaderTimeout);
applicationStore.pageLoaderTimeout = 0;
}
const pageLoadingElem = document.getElementById("sm-page-loading");
if (pageLoadingElem !== null) {
pageLoadingElem.style.display = "none";
}
applicationStore.hydrated = true;
});
export default router;

View File

@@ -1,94 +0,0 @@
import { defineStore } from "pinia";
type ApplicationStoreEventKeyUpCallback = (event: KeyboardEvent) => boolean;
type ApplicationStoreEventKeyPressCallback = (event: KeyboardEvent) => boolean;
export interface ApplicationStore {
hydrated: boolean;
unavailable: boolean;
dynamicTitle: string;
eventKeyUpStack: ApplicationStoreEventKeyUpCallback[];
eventKeyPressStack: ApplicationStoreEventKeyPressCallback[];
pageLoaderTimeout: number;
_addedListener: boolean;
}
export const useApplicationStore = defineStore({
id: "application",
state: (): ApplicationStore => ({
hydrated: false,
unavailable: false,
dynamicTitle: "",
eventKeyUpStack: [],
eventKeyPressStack: [],
pageLoaderTimeout: 0,
_addedListener: false,
}),
actions: {
async setDynamicTitle(title: string) {
this.$state.dynamicTitle = title;
document.title = `STEMMechanics | ${title}`;
},
clearDynamicTitle() {
this.$state.dynamicTitle = "";
},
addKeyUpListener(callback: ApplicationStoreEventKeyUpCallback) {
this.eventKeyUpStack.push(callback);
if (!this._addedListener) {
document.addEventListener("keyup", (event: KeyboardEvent) => {
this.eventKeyUpStack.every(
(item: ApplicationStoreEventKeyUpCallback) => {
const result = item(event);
if (result) {
return false;
}
return true;
},
);
});
}
},
removeKeyUpListener(callback: ApplicationStoreEventKeyUpCallback) {
this.eventKeyUpStack = this.eventKeyUpStack.filter(
(item: ApplicationStoreEventKeyUpCallback) => item !== callback,
);
},
addKeyPressListener(callback: ApplicationStoreEventKeyPressCallback) {
this.eventKeyPressStack.push(callback);
if (!this._addedListener) {
document.addEventListener(
"keypress",
(event: KeyboardEvent) => {
this.eventKeyPressStack.every(
(item: ApplicationStoreEventKeyPressCallback) => {
const result = item(event);
if (result) {
return false;
}
return true;
},
);
},
);
}
},
removeKeyPressListener(
callback: ApplicationStoreEventKeyPressCallback,
) {
this.eventKeyPressStack = this.eventKeyPressStack.filter(
(item: ApplicationStoreEventKeyPressCallback) =>
item !== callback,
);
},
},
});

View File

@@ -1,61 +0,0 @@
import { DefineStoreOptions, defineStore } from "pinia";
interface CacheItem {
url: string;
data: unknown;
}
export const useCacheStore = defineStore({
id: "cache",
state: () => ({
cache: [] as CacheItem[],
}),
actions: {
// Method to retrieve cached JSON data based on a URL
getCacheByUrl(url: string) {
const cachedItem = this.cache.find((item) => item.url === url);
return cachedItem ? cachedItem.data : null;
},
// Method to update the cache with new data and check for modifications
updateCache(url: string, newData: unknown): boolean {
const index = this.cache.findIndex((item) => item.url === url);
if (index !== -1) {
// If the URL is already in the cache, check for modifications
const existingData = this.cache[index].data;
if (JSON.stringify(existingData) === JSON.stringify(newData)) {
// Data is not modified, return false
return false;
} else {
// Data is modified, update the cache
this.cache[index].data = newData;
return true;
}
} else {
// If the URL is not in the cache, add it
this.cache.push({ url, data: newData });
return true;
}
},
// Method to clear the cache for a specific URL
clearCacheByUrl(url: string) {
const index = this.cache.findIndex((item) => item.url === url);
if (index !== -1) {
this.cache.splice(index, 1);
}
},
// Method to clear the entire cache
clearCache() {
this.cache = [];
},
},
persist: true,
} as DefineStoreOptions<string, unknown, unknown, unknown> & {
persist?: boolean;
});

View File

@@ -1,83 +0,0 @@
import { defineStore } from "pinia";
export interface ToastOptions {
id?: number;
title?: string;
content: string;
type?: string;
loader?: boolean;
}
export interface ToastItem {
id: number;
title: string;
content: string;
type: string;
loader: boolean;
}
export interface ToastStore {
toasts: ToastItem[];
}
export const defaultToastItem: ToastItem = {
id: 0,
title: "",
content: "",
type: "primary",
loader: false,
};
export const useToastStore = defineStore({
id: "toasts",
state: (): ToastStore => ({
toasts: [],
}),
actions: {
addToast(toast: ToastOptions): number {
while (
!toast.id ||
toast.id == 0 ||
this.toasts.find((item: ToastItem) => item.id === toast.id)
) {
toast.id =
Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1;
}
toast.title = toast.title || defaultToastItem.title;
toast.type = toast.type || defaultToastItem.type;
this.toasts.push(toast);
return toast.id;
},
clearToast(id: number): void {
this.toasts = this.toasts.filter(
(item: ToastItem) => item.id !== id
);
},
updateToast(id: number, updatedFields: Partial<ToastOptions>): void {
const toastToUpdate = this.toasts.find(
(item: ToastItem) => item.id === id
);
if (toastToUpdate) {
toastToUpdate.title =
updatedFields.title || toastToUpdate.title;
toastToUpdate.content =
updatedFields.content || toastToUpdate.content;
toastToUpdate.type = updatedFields.type || toastToUpdate.type;
if (
Object.prototype.hasOwnProperty.call(
updatedFields,
"loader"
)
) {
toastToUpdate.loader = updatedFields.loader;
}
}
},
},
});

View File

@@ -1,72 +0,0 @@
import { defineStore, DefineStoreOptions } from "pinia";
export interface UserDetails {
id: string;
username: string;
first_name: string;
last_name: string;
display_name: string;
email: string;
phone: string;
permissions: string[];
}
export interface UserState {
id: string;
token: string;
username: string;
firstName: string;
lastName: string;
displayName: string;
email: string;
phone: string;
permissions: string[];
}
export const useUserStore = defineStore({
id: "user",
state: (): UserState => {
return {
id: "",
token: "",
username: "",
firstName: "",
lastName: "",
displayName: "",
email: "",
phone: "",
permissions: [],
};
},
actions: {
async setUserDetails(user: UserDetails) {
this.$state.id = user.id;
this.$state.username = user.username;
this.$state.firstName = user.first_name;
this.$state.lastName = user.last_name;
this.$state.displayName = user.display_name;
this.$state.email = user.email;
this.$state.phone = user.phone;
this.$state.permissions = user.permissions || [];
},
async setUserToken(token: string) {
this.$state.token = token;
},
clearUser() {
this.$state.id = null;
this.$state.token = null;
this.$state.username = null;
this.$state.firstName = null;
this.$state.lastName = null;
this.$state.displayName = null;
this.$state.email = null;
this.$state.phone = null;
this.$state.permissions = [];
},
},
persist: true,
} as DefineStoreOptions<string, unknown, unknown, unknown> & { persist?: boolean });

View File

@@ -1,33 +0,0 @@
import { expect, describe, it } from "vitest";
import { SMDate } from "../helpers/datetime";
describe("format()", () => {
it("should return an empty string when the first argument is not a Date object", () => {
const result = new SMDate("not a date").format("yyyy-MM-dd");
expect(result).toEqual("");
});
it("should format the date correctly", () => {
const date = new Date("2022-02-19T12:34:56");
const result = new SMDate(date).format("yyyy-MM-dd HH:mm:ss");
expect(result).toEqual("2022-02-19 12:34:56");
});
it("should handle single-digit month and day", () => {
const date = new Date("2022-01-01T00:00:00");
const result = new SMDate(date).format("yy-M-d");
expect(result).toEqual("22-1-1");
});
it("should handle day of week and month name abbreviations", () => {
const date = new Date("2022-03-22T00:00:00");
const result = new SMDate(date).format("EEE, MMM dd, yyyy");
expect(result).toEqual("Tue, Mar 22, 2022");
});
it("should handle 12-hour clock with am/pm", () => {
const date = new Date("2022-01-01T12:34:56");
const result = new SMDate(date).format("hh:mm:ss aa");
expect(result).toEqual("12:34:56 pm");
});
});

View File

@@ -1,14 +0,0 @@
import { expect, describe, it } from "vitest";
import { toTitleCase } from "../helpers/string";
describe("toTitleCase()", () => {
it("should return a converted title case string", () => {
const result = toTitleCase("titlecase");
expect(result).toEqual("Titlecase");
});
it("should return a converted title case string and spaces", () => {
const result = toTitleCase("titlecase_and_more");
expect(result).toEqual("Titlecase And More");
});
});

View File

@@ -1,28 +0,0 @@
import { expect, describe, it } from "vitest";
import { Email } from "../helpers/validate";
describe("Email()", () => {
it("should return valid=false when an invalid email address is passed to the validate function", async () => {
const v = Email();
const result = await v.validate("invalid email");
expect(result.valid).toBe(false);
});
it("should return valid=false when an invalid email address is passed to the validate function", async () => {
const v = Email();
const result = await v.validate("fake@outlook");
expect(result.valid).toBe(false);
});
it("should return valid=true when an valid email address is passed to the validate function", async () => {
const v = Email();
const result = await v.validate("fake@outlook.com");
expect(result.valid).toBe(true);
});
it("should return valid=true when an valid email address is passed to the validate function", async () => {
const v = Email();
const result = await v.validate("fake@outlook.com.au");
expect(result.valid).toBe(true);
});
});