aboutsummaryrefslogtreecommitdiff
path: root/front-end/src/bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'front-end/src/bootstrap')
-rw-r--r--front-end/src/bootstrap/Environment.vue44
-rw-r--r--front-end/src/bootstrap/components/ConfirmPrompt.vue6
-rw-r--r--front-end/src/bootstrap/components/Footer.vue2
-rw-r--r--front-end/src/bootstrap/components/Header.vue26
-rw-r--r--front-end/src/bootstrap/index.ts71
-rw-r--r--front-end/src/bootstrap/style/modals.scss4
6 files changed, 50 insertions, 103 deletions
diff --git a/front-end/src/bootstrap/Environment.vue b/front-end/src/bootstrap/Environment.vue
index f575529..618ee62 100644
--- a/front-end/src/bootstrap/Environment.vue
+++ b/front-end/src/bootstrap/Environment.vue
@@ -1,7 +1,4 @@
<template>
- <head>
- <title>{{ metaTile }}</title>
- </head>
<div id="env-entry" ref="content" class="absolute top-0 left-0 w-full min-h-screen env-bg">
<div class="absolute flex w-full">
<notifications
@@ -20,7 +17,7 @@
/>
</div>
- <site-header ref="header" :site-title="siteTitle" :routes="routes" >
+ <site-header ref="header" :routes="routes" @logout="emit('logout')" >
<template #site_logo>
<!-- Use the global site-logo if enabled -->
<site-logo />
@@ -53,54 +50,37 @@
import { computed } from 'vue'
import { RouteLocation, useRouter } from 'vue-router'
import { filter, map, without, find, includes } from 'lodash-es'
-import { useEnvSize, useScrollOnRouteChange, useSession, useTitle } from '@vnuge/vnlib.browser'
+import { storeToRefs } from 'pinia'
+import { useEnvSize } from '@vnuge/vnlib.browser'
+import { useStore } from '../store'
import CookieWarning from './components/CookieWarning.vue'
import PasswordPrompt from './components/PasswordPrompt.vue'
import siteHeader from './components/Header.vue'
import siteFooter from './components/Footer.vue'
import ConfirmPrompt from './components/ConfirmPrompt.vue'
-import { headerRoutes, authRoutes, siteTitle, showCookieWarning } from './index'
-const { loggedIn } = useSession();
+const emit = defineEmits(['logout'])
+const store = useStore()
+const { showCookieWarning, currentRoutes } = storeToRefs(store)
const { getRoutes } = useRouter();
-const { title } = useTitle(siteTitle.value);
//Use the env size to calculate the header and footer heights for us
const { header, footer, content, headerHeight, footerHeight } = useEnvSize(true)
-//setup autoscroll
-useScrollOnRouteChange();
-
-//Compute meta title from the default site title and the page title
-const metaTile = computed(() => title.value ? `${title.value} | ${siteTitle.value}` : siteTitle.value)
-
const routes = computed<RouteLocation[]>(() => {
// Get routes that are defined above but only if they are defined in the router
// This is a computed property because loggedin is a reactive property
- const routeNames = loggedIn.value ? authRoutes.value : headerRoutes.value
- const routes = filter(getRoutes(), (pageName) => includes(routeNames, pageName.name))
+ const routes = filter(getRoutes(), (pageName) => includes(currentRoutes.value, pageName.name))
- const activeRoutes = map(routeNames, route => find(routes, { name: route }))
+ const activeRoutes = map(currentRoutes.value, route => find(routes, { name: route }))
return without<RouteLocation>(activeRoutes, undefined)
})
-
//Forces the page content to be exactly the height of the viewport - header and footer sizes
-const bodyStyle = computed(() => {
- return { 'min-height': `calc(100vh - ${headerHeight.value + footerHeight.value}px)` }
-})
+const bodyStyle = computed(() => ({ 'min-height': `calc(100vh - ${headerHeight.value + footerHeight.value}px)` }))
+const generalToastStyle = computed(() => ({ top: `${headerHeight.value + 5}px` }))
+const formToastStyle = computed(() => ({ top: `${headerHeight.value}px` }))
-const generalToastStyle = computed(() => {
- return { top: `${headerHeight.value + 5}px` }
-})
-
-const formToastStyle = computed(() => {
- return { top: `${headerHeight.value}px` }
-})
</script>
-
-<style>
-
-</style>
diff --git a/front-end/src/bootstrap/components/ConfirmPrompt.vue b/front-end/src/bootstrap/components/ConfirmPrompt.vue
index 78317e0..c67bcfc 100644
--- a/front-end/src/bootstrap/components/ConfirmPrompt.vue
+++ b/front-end/src/bootstrap/components/ConfirmPrompt.vue
@@ -5,7 +5,7 @@
<div class="modal-content-container">
<DialogPanel>
<DialogTitle class="modal-title">
- {{ title }}
+ {{ message.title ?? 'Confirm' }}
</DialogTitle>
<DialogDescription class="modal-description">
@@ -55,9 +55,7 @@ const message = ref({})
onClickOutside(dialog, () => isRevealed.value ? cancel() : null)
//Set message on reveal
-onReveal(m => message.value = m);
-
-const title = computed(() => defaultTo(message.value.title, 'Confirm'))
+onReveal(m => message.value = defaultTo(m, {}));
const style = computed(() => {
return {
diff --git a/front-end/src/bootstrap/components/Footer.vue b/front-end/src/bootstrap/components/Footer.vue
index 6af6936..7c306c9 100644
--- a/front-end/src/bootstrap/components/Footer.vue
+++ b/front-end/src/bootstrap/components/Footer.vue
@@ -17,7 +17,7 @@
<p class="nav-title">
Built with
</p>
- <a class="footer-link" href="https://www.vaughnnugent.com/resources/software/modules">VNLib HTTP v1.0.1</a>
+ <a class="footer-link" href="https://www.vaughnnugent.com/resources/software/modules">VNLib HTTP v0.1.0</a>
<a class="footer-link" href="https://tailwindcss.com/">Tailwindcss</a>
<a class="footer-link" href="https://vuejs.org/">Vuejs v3</a>
<a class="footer-link" href="https://fontawesome.com/">Font Awesome</a>
diff --git a/front-end/src/bootstrap/components/Header.vue b/front-end/src/bootstrap/components/Header.vue
index 8ea2240..43a805b 100644
--- a/front-end/src/bootstrap/components/Header.vue
+++ b/front-end/src/bootstrap/components/Header.vue
@@ -78,18 +78,21 @@
import { debounce, find } from 'lodash-es'
import { useElementSize, onClickOutside, useElementHover } from '@vueuse/core'
import { computed, ref, toRefs } from 'vue'
-import { useSession, useUser, useEnvSize, apiCall } from '@vnuge/vnlib.browser'
+import { useEnvSize } from '@vnuge/vnlib.browser'
import { RouteLocation, useRouter } from 'vue-router';
+import { storeToRefs } from 'pinia';
+import { useStore } from '../../store';
+const emit = defineEmits(['logout'])
const props = defineProps<{
- siteTitle: string,
routes: RouteLocation[]
}>()
-const { siteTitle, routes } = toRefs(props)
+const { routes } = toRefs(props)
+
+const store = useStore();
+const { loggedIn, siteTitle } = storeToRefs(store);
-const { loggedIn } = useSession()
-const { userName, logout } = useUser()
const { headerHeight } = useEnvSize()
//Get the router for navigation
@@ -105,7 +108,7 @@ const dropMenuSize = useElementSize(userDrop)
const sideMenuSize = useElementSize(sideMenu)
const userMenuHovered = useElementHover(userMenu)
-const uname = computed(() => userName.value || 'Visitor')
+const uname = computed(() => (store as any).userName || 'Visitor')
const sideMenuStyle = computed(() => {
// Side menu should be the exact height of the page and under the header,
// So menu height is the height of the page minus the height of the header
@@ -148,15 +151,8 @@ const gotoRoute = (route : string) =>{
}
const OnLogout = () =>{
- apiCall(async ({ toaster }) => {
- await logout()
- toaster.general.success({
- id: 'logout-success',
- title: 'Success',
- text: 'You have been logged out',
- duration: 5000
- })
- })
+ //Emit logout event
+ emit('logout')
}
</script> \ No newline at end of file
diff --git a/front-end/src/bootstrap/index.ts b/front-end/src/bootstrap/index.ts
index ead41e1..343def6 100644
--- a/front-end/src/bootstrap/index.ts
+++ b/front-end/src/bootstrap/index.ts
@@ -1,47 +1,25 @@
import App from '../App.vue'
import Notifications, { notify } from '@kyvg/vue3-notification'
import { configureNotifier } from '@vnuge/vnlib.browser'
-import { createApp as vueCreateApp, ref } from "vue";
+import { CreateAppFunction, createApp as vueCreateApp } from "vue";
import { useDark } from "@vueuse/core";
+import { createPinia, type Pinia } from "pinia";
//Font awesome support
import { Library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faBars, faLightbulb, faTimes } from '@fortawesome/free-solid-svg-icons'
-
-//Required global state elements for app components
-export const headerRoutes = ref<string[]>([]);
-export const authRoutes = ref<string[]>([]);
-export const siteTitle = ref<string>("");
-export const showCookieWarning = ref<boolean>(false);
-
-
export interface AppConfig {
/**
- * Routes to be displayed in the header when the user is not logged in
- */
- headerRoutes: string[];
-
- /**
- * Routes to be displayed in the header when the user is logged in
- */
- authRoutes: string[];
-
- /**
- * The title of the site, used in the title bar
- */
- siteTitle: string;
-
- /**
* Enables dark mode support
*/
- useDarkMode: boolean;
+ useDarkMode?: boolean;
/**
* The element to mount the app to
*/
- mountElement: string;
+ mountElement: string | Element;
/**
* library instance for adding required icons
@@ -49,16 +27,19 @@ export interface AppConfig {
faLibrary: Library;
/**
- * If true, the cookie warning will not be displayed
+ * Called when the app is created for you to add custom elements
+ * and configure the app
+ * @param app The app instance
+ * @param store The pinia store instance
*/
- hideCookieWarning?: boolean;
+ onCreate(app: any, piniaStore: Pinia): void;
/**
- * Called when the app is created for you to add custom elements
- * and configure the app
+ * Allows the user to override the createApp function
* @param app The app instance
+ * @returns The app instance
*/
- onCreate: (app: any) => void;
+ createApp?: CreateAppFunction<Element>
}
/**
@@ -66,13 +47,12 @@ export interface AppConfig {
* @param config The configuration for the app
* @returns The app instance
*/
-export const createVnApp = (config: AppConfig, createApp?: (app: any) => any) => {
- headerRoutes.value = config.headerRoutes;
- authRoutes.value = config.authRoutes;
- siteTitle.value = config.siteTitle;
+export const createVnApp = (config: AppConfig) => {
+
+ const store = createPinia();
//Allow the user to override the createApp function
- createApp = createApp || vueCreateApp;
+ config.createApp ??= vueCreateApp;
//Enable dark mode support
if (config.useDarkMode) {
@@ -83,25 +63,18 @@ export const createVnApp = (config: AppConfig, createApp?: (app: any) => any) =>
});
}
- if (!config.hideCookieWarning) {
- //Configure the cookie warning to be displayed cookies are not enabled
- showCookieWarning.value = navigator?.cookieEnabled === false;
- }
-
//Add required icons to library
config.faLibrary.add(faBars, faLightbulb, faTimes);
//create the vue app
- const app = createApp(App)
-
- //Add the library to the app
- app.component('fa-icon', FontAwesomeIcon)
-
- //Add the notification and router to the app
- app.use(Notifications);
+ const app = config.createApp(App)
+
+ app.use(Notifications) //Add the notification component to the app
+ .use(store) //Add pinia to the app
+ .component('fa-icon', FontAwesomeIcon) //Add the font awesome icon component to the app
//Call the onCreate callback
- config.onCreate(app);
+ config.onCreate(app, store);
//Mount the app
app.mount(config.mountElement);
diff --git a/front-end/src/bootstrap/style/modals.scss b/front-end/src/bootstrap/style/modals.scss
index 254b8e1..b868406 100644
--- a/front-end/src/bootstrap/style/modals.scss
+++ b/front-end/src/bootstrap/style/modals.scss
@@ -3,8 +3,8 @@
@apply fixed z-50 flex w-full px-6;
.modal-content-container {
- @apply w-full max-w-md p-5 m-auto rounded-md shadow-2xl mt-44;
- @apply bg-white border border-transparent dark:bg-dark-600 dark:border-primary-500 dark:text-white;
+ @apply w-full max-w-md p-5 m-auto rounded shadow-2xl mt-44;
+ @apply bg-white border border-transparent dark:bg-dark-700 dark:border-dark-300 dark:text-white;
.modal-title {
@apply text-xl font-bold;