diff --git a/src/JobsJobsJobs/App/src/App.vue b/src/JobsJobsJobs/App/src/App.vue index 90b0321..7b63736 100644 --- a/src/JobsJobsJobs/App/src/App.vue +++ b/src/JobsJobsJobs/App/src/App.vue @@ -10,11 +10,12 @@ diff --git a/src/JobsJobsJobs/App/src/main.ts b/src/JobsJobsJobs/App/src/main.ts index 7ebd125..07664fa 100644 --- a/src/JobsJobsJobs/App/src/main.ts +++ b/src/JobsJobsJobs/App/src/main.ts @@ -3,13 +3,11 @@ import App from "./App.vue" import router from "./router" import store, { key } from "./store" import Icon from "./components/Icon.vue" -import PageTitle from "./components/PageTitle.vue" const app = createApp(App) .use(router) .use(store, key) app.component("Icon", Icon) -app.component("PageTitle", PageTitle) app.mount("#app") diff --git a/src/JobsJobsJobs/App/src/router/index.ts b/src/JobsJobsJobs/App/src/router/index.ts index 1814410..e934cee 100644 --- a/src/JobsJobsJobs/App/src/router/index.ts +++ b/src/JobsJobsJobs/App/src/router/index.ts @@ -3,10 +3,9 @@ import { createWebHistory, RouteLocationNormalized, RouteLocationNormalizedLoaded, - RouteRecordName, RouteRecordRaw } from "vue-router" -import store from "@/store" +import store, { Mutations } from "@/store" import Home from "@/views/Home.vue" import LogOn from "@/views/citizen/LogOn.vue" @@ -29,124 +28,141 @@ const routes: Array = [ { path: "/", name: "Home", - component: Home + component: Home, + meta: { title: "Welcome!" } }, { path: "/how-it-works", name: "HowItWorks", - component: () => import(/* webpackChunkName: "help" */ "../views/HowItWorks.vue") + component: () => import(/* webpackChunkName: "help" */ "../views/HowItWorks.vue"), + meta: { title: "How It Works" } }, { path: "/privacy-policy", name: "PrivacyPolicy", - component: () => import(/* webpackChunkName: "legal" */ "../views/PrivacyPolicy.vue") + component: () => import(/* webpackChunkName: "legal" */ "../views/PrivacyPolicy.vue"), + meta: { title: "Privacy Policy" } }, { path: "/terms-of-service", name: "TermsOfService", - component: () => import(/* webpackChunkName: "legal" */ "../views/TermsOfService.vue") + component: () => import(/* webpackChunkName: "legal" */ "../views/TermsOfService.vue"), + meta: { title: "Terms of Service" } }, // Citizen URLs { path: "/citizen/log-on", name: "LogOn", - component: LogOn + component: LogOn, + meta: { title: "Log On" } }, { path: "/citizen/:abbr/authorized", name: "CitizenAuthorized", - component: () => import(/* webpackChunkName: "dashboard" */ "../views/citizen/Authorized.vue") + component: () => import(/* webpackChunkName: "dashboard" */ "../views/citizen/Authorized.vue"), + meta: { title: "Logging On" } }, { path: "/citizen/dashboard", name: "Dashboard", - component: () => import(/* webpackChunkName: "dashboard" */ "../views/citizen/Dashboard.vue") + component: () => import(/* webpackChunkName: "dashboard" */ "../views/citizen/Dashboard.vue"), + meta: { auth: true, title: "Dashboard" } }, { path: "/citizen/profile", name: "EditProfile", - component: () => import(/* webpackChunkName: "profedit" */ "../views/citizen/EditProfile.vue") + component: () => import(/* webpackChunkName: "profedit" */ "../views/citizen/EditProfile.vue"), + meta: { auth: true, title: "Edit Profile" } }, { path: "/citizen/log-off", name: "LogOff", - component: () => import(/* webpackChunkName: "logoff" */ "../views/citizen/LogOff.vue") + component: () => import(/* webpackChunkName: "logoff" */ "../views/citizen/LogOff.vue"), + meta: { auth: true, title: "Logging Off" } }, // Job Listing URLs { path: "/help-wanted", name: "HelpWanted", - component: () => import(/* webpackChunkName: "joblist" */ "../views/listing/HelpWanted.vue") + component: () => import(/* webpackChunkName: "joblist" */ "../views/listing/HelpWanted.vue"), + meta: { auth: true, title: "Help Wanted" } }, { path: "/listing/:id/edit", name: "EditListing", - component: () => import(/* webpackChunkName: "jobedit" */ "../views/listing/ListingEdit.vue") + component: () => import(/* webpackChunkName: "jobedit" */ "../views/listing/ListingEdit.vue"), + meta: { auth: true, title: "Edit Job Listing" } }, { path: "/listing/:id/expire", name: "ExpireListing", - component: () => import(/* webpackChunkName: "jobedit" */ "../views/listing/ListingExpire.vue") + component: () => import(/* webpackChunkName: "jobedit" */ "../views/listing/ListingExpire.vue"), + meta: { auth: true, title: "Expire Job Listing" } }, { path: "/listing/:id/view", name: "ViewListing", - component: () => import(/* webpackChunkName: "joblist" */ "../views/listing/ListingView.vue") + component: () => import(/* webpackChunkName: "joblist" */ "../views/listing/ListingView.vue"), + meta: { auth: true, title: "Loading Job Listing..." } }, { path: "/listings/mine", name: "MyListings", - component: () => import(/* webpackChunkName: "joblist" */ "../views/listing/MyListings.vue") + component: () => import(/* webpackChunkName: "joblist" */ "../views/listing/MyListings.vue"), + meta: { auth: true, title: "My Job Listings" } }, // Profile URLs { path: "/profile/:id/view", name: "ViewProfile", - component: () => import(/* webpackChunkName: "profview" */ "../views/profile/ProfileView.vue") + component: () => import(/* webpackChunkName: "profview" */ "../views/profile/ProfileView.vue"), + meta: { auth: true, title: "Loading Profile..." } }, { path: "/profile/search", name: "SearchProfiles", - component: () => import(/* webpackChunkName: "profview" */ "../views/profile/ProfileSearch.vue") + component: () => import(/* webpackChunkName: "profview" */ "../views/profile/ProfileSearch.vue"), + meta: { auth: true, title: "Search Profiles" } }, { path: "/profile/seeking", name: "PublicSearchProfiles", - component: () => import(/* webpackChunkName: "seeking" */ "../views/profile/Seeking.vue") + component: () => import(/* webpackChunkName: "seeking" */ "../views/profile/Seeking.vue"), + meta: { auth: false, title: "People Seeking Work" } }, // "So Long" URLs { path: "/so-long/options", name: "DeletionOptions", - component: () => import(/* webpackChunkName: "so-long" */ "../views/so-long/DeletionOptions.vue") + component: () => import(/* webpackChunkName: "so-long" */ "../views/so-long/DeletionOptions.vue"), + meta: { auth: true, title: "Account Deletion Options" } }, { path: "/so-long/success/:abbr", name: "DeletionSuccess", - component: () => import(/* webpackChunkName: "so-long" */ "../views/so-long/DeletionSuccess.vue") + component: () => import(/* webpackChunkName: "so-long" */ "../views/so-long/DeletionSuccess.vue"), + meta: { auth: false, title: "Account Deletion Success" } }, // Success Story URLs { path: "/success-story/list", name: "ListStories", - component: () => import(/* webpackChunkName: "success" */ "../views/success-story/StoryList.vue") + component: () => import(/* webpackChunkName: "success" */ "../views/success-story/StoryList.vue"), + meta: { auth: false, title: "Success Stories" } }, { path: "/success-story/:id/edit", name: "EditStory", - component: () => import(/* webpackChunkName: "succedit" */ "../views/success-story/StoryEdit.vue") + component: () => import(/* webpackChunkName: "succedit" */ "../views/success-story/StoryEdit.vue"), + meta: { auth: false, title: "Edit Success Story" } }, { path: "/success-story/:id/view", name: "ViewStory", - component: () => import(/* webpackChunkName: "success" */ "../views/success-story/StoryView.vue") + component: () => import(/* webpackChunkName: "success" */ "../views/success-story/StoryView.vue"), + meta: { auth: false, title: "Success Story" } } ] -/** The routes that do not require logins */ -const publicRoutes : Array = [ - "Home", "HowItWorks", "PrivacyPolicy", "TermsOfService", "LogOn", "CitizenAuthorized", "PublicSearchProfiles", - "DeletionSuccess" -] const router = createRouter({ history: createWebHistory(process.env.BASE_URL), @@ -158,11 +174,12 @@ const router = createRouter({ }) // eslint-disable-next-line -router.beforeEach((to : RouteLocationNormalized, from : RouteLocationNormalized) =>{ - if (store.state.user === undefined && !publicRoutes.includes(to.name ?? "")) { +router.beforeEach((to : RouteLocationNormalized, from : RouteLocationNormalized) => { + if (store.state.user === undefined && (to.meta.auth || false)) { window.localStorage.setItem(AFTER_LOG_ON_URL, to.fullPath) return "/citizen/log-on" } + store.commit(Mutations.SetTitle, to.meta.title ?? "") }) export default router diff --git a/src/JobsJobsJobs/App/src/store/index.ts b/src/JobsJobsJobs/App/src/store/index.ts index 3750b91..f919533 100644 --- a/src/JobsJobsJobs/App/src/store/index.ts +++ b/src/JobsJobsJobs/App/src/store/index.ts @@ -1,3 +1,4 @@ +import { useTitle } from "@vueuse/core" import { InjectionKey } from "vue" import { createStore, Store, useStore as baseUseStore } from "vuex" import api, { Continent, Instance, LogOnSuccess } from "../api" @@ -6,14 +7,16 @@ import * as Mutations from "./mutations" /** The state tracked by the application */ export interface State { + /** The document's current title */ + pageTitle : string /** The currently logged-on user */ - user: LogOnSuccess | undefined + user : LogOnSuccess | undefined /** The state of the log on process */ - logOnState: string + logOnState : string /** All continents (use `ensureContinents` action) */ - continents: Continent[] + continents : Continent[] /** All instances (use `ensureInstances` action) */ - instances: Instance[] + instances : Instance[] } /** An injection key to identify this state with Vue */ @@ -24,9 +27,13 @@ export function useStore () : Store { return baseUseStore(key) } +/** The application name */ +const appName = "Jobs, Jobs, Jobs" + export default createStore({ state: () : State => { return { + pageTitle: "", user: undefined, logOnState: "Welcome back!", continents: [], @@ -34,6 +41,10 @@ export default createStore({ } }, mutations: { + [Mutations.SetTitle]: (state, title : string) => { + state.pageTitle = title === "" ? appName : `${title} | ${appName}` + useTitle(state.pageTitle) + }, [Mutations.SetUser]: (state, user : LogOnSuccess) => { state.user = user }, [Mutations.ClearUser]: (state) => { state.user = undefined }, [Mutations.SetLogOnState]: (state, message : string) => { state.logOnState = message }, diff --git a/src/JobsJobsJobs/App/src/store/mutations.ts b/src/JobsJobsJobs/App/src/store/mutations.ts index fc58676..43ae9e5 100644 --- a/src/JobsJobsJobs/App/src/store/mutations.ts +++ b/src/JobsJobsJobs/App/src/store/mutations.ts @@ -1,3 +1,6 @@ +/** Set the page title */ +export const SetTitle = "setTitle" + /** Set the logged-on user */ export const SetUser = "setUser" diff --git a/src/JobsJobsJobs/App/src/views/Home.vue b/src/JobsJobsJobs/App/src/views/Home.vue index da66610..7052562 100644 --- a/src/JobsJobsJobs/App/src/views/Home.vue +++ b/src/JobsJobsJobs/App/src/views/Home.vue @@ -1,6 +1,5 @@