remove vue components
This commit is contained in:
0
resources/js/bootstrap.js
vendored
0
resources/js/bootstrap.js
vendored
File diff suppressed because one or more lines are too long
@@ -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");
|
||||
@@ -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;
|
||||
@@ -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,
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -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;
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -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 });
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user