diff --git a/src/app/App.vue b/src/app/App.vue index b9faf7c..dba0e1b 100644 --- a/src/app/App.vue +++ b/src/app/App.vue @@ -1,14 +1,20 @@ - + + + + diff --git a/src/app/components/CheckBox.vue b/src/app/components/CheckBox.vue index c917e62..9b87745 100644 --- a/src/app/components/CheckBox.vue +++ b/src/app/components/CheckBox.vue @@ -1,6 +1,6 @@ - + {{label}} @@ -40,12 +40,6 @@ export default defineComponent({ diff --git a/src/app/components/modals/MovieModal.vue b/src/app/components/modals/MovieModal.vue new file mode 100644 index 0000000..f9f2734 --- /dev/null +++ b/src/app/components/modals/MovieModal.vue @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + {{ movie.title }} + ({{ releaseYear }}) + + + {{ releaseDate }} + {{ runtime }} + + + {{movie?.overview}} + + + Request + + + + + + + + Overview + {{ movie?.overview }} + + + Request + + + + + + + + + + + diff --git a/src/app/components/modals/index.ts b/src/app/components/modals/index.ts new file mode 100644 index 0000000..12479b4 --- /dev/null +++ b/src/app/components/modals/index.ts @@ -0,0 +1,22 @@ +/** + * Modal names to export + */ +const enum Modal { + +} + +/** + * Modal export type + */ +type ModalTypes = { [K in keyof typeof Modal]: any } + +/** + * Modals to export + */ +export const modals: ModalTypes = { +} + +/** + * Export the list of modal names + */ +export default Modal; diff --git a/src/app/index.ts b/src/app/index.ts index a87b799..cdb22f3 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -7,6 +7,7 @@ import "./styles/index.css"; let app = createApp(App); app.use(router); app.use(store); + app.mount("#app"); /** diff --git a/src/app/routes/index.ts b/src/app/routes/index.ts index aaebd00..b2f27ce 100644 --- a/src/app/routes/index.ts +++ b/src/app/routes/index.ts @@ -5,7 +5,9 @@ import store, { Action } from "../store"; * Check if the user is a guest; redirect otherwise */ function requiresGuest(to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) { + if (store.getters.isAuthenticated) { + console.log("Checking guest..."); next({ name: "Home" }); return; } @@ -53,8 +55,25 @@ const routes: RouteRecordRaw[] = [ { path: "/", name: "Home", - component: () => import("../views/Home.vue"), - beforeEnter: requiresAuth + component: { + beforeRouteEnter(to, from, next) { + next({ name: "Search" }); + } + } + }, + { + path: "/search", + name: "Search", + component: () => import("../views/Search.vue"), + beforeEnter: requiresAuth, + children: [ + { + path: ":movieId", + name: "Lookup", + component: () => import("../components/modals/MovieModal.vue"), + props: true + } + ] }, { path: "/login", diff --git a/src/app/store/actions.ts b/src/app/store/actions.ts index 191bc19..c62dc96 100644 --- a/src/app/store/actions.ts +++ b/src/app/store/actions.ts @@ -62,8 +62,8 @@ export const actions: Actions { @@ -77,7 +77,7 @@ export const actions: Actionswindow).modalShow = (name: Modal) => { + store.commit(Mutation.ModalShow, name); +} + +(window).modalHide = () => { + store.commit(Mutation.ModalHide, undefined); +} diff --git a/src/app/store/mutations.ts b/src/app/store/mutations.ts index 958fef2..cd91026 100644 --- a/src/app/store/mutations.ts +++ b/src/app/store/mutations.ts @@ -1,3 +1,4 @@ +import Modal from "@app/components/modals"; import jwtDecode from "jwt-decode"; import { MutationTree } from "vuex"; import { IState } from "./state"; @@ -6,28 +7,50 @@ import { IState } from "./state"; * All available mutation types */ export enum Mutation { - ForgetUser = "FORGET_USER", - LoadUser = "LOAD_USER", - StoreUser = "STORE_USER" + + LockScroll = "LOCK_SCROLL", + + UserForget = "USER_FORGET", + UserLoad = "USER_LOAD", + UserStore = "USER_STORE", + } /** * Type declarations for each mutation */ export type MutationsTypes = { - [Mutation.ForgetUser]: (state: S) => void, - [Mutation.LoadUser] : (state: S, token: string) => boolean, - [Mutation.StoreUser] : (state: S, remember: boolean) => void, + [Mutation.UserForget]: (state: S) => void, + [Mutation.UserLoad] : (state: S, token: string) => boolean, + [Mutation.UserStore] : (state: S, remember: boolean) => void, + [Mutation.LockScroll]: (state: S, lock: boolean) => void, } /** * The auth mutations */ export const mutations: MutationsTypes & MutationTree = { + + [Mutation.LockScroll](state: IState, lock: boolean) { + if (lock) { + // document.body.style.position = "fixed"; + // document.body.style.top = `-${window.scrollY}px`; + document.body.style.paddingRight = `${window.innerWidth - document.body.clientWidth}px`; + document.body.style.overflow = "hidden"; + } else { + // const scrollY = document.body.style.top; + // document.body.style.position = ""; + // document.body.style.top = ""; + document.body.style.paddingRight = ""; + document.body.style.overflow = ""; + // window.scrollTo(0, parseInt(scrollY || '0') * -1); + } + }, + /** * Log the user out and remove the token from storage */ - [Mutation.ForgetUser](state: IState) { + [Mutation.UserForget](state: IState) { state.user = null; sessionStorage.removeItem("jwt"); localStorage.removeItem("jwt"); @@ -36,7 +59,7 @@ export const mutations: MutationsTypes & MutationTree = { /** * Try loading a user from the provided token */ - [Mutation.LoadUser](state: IState, token: string) { + [Mutation.UserLoad](state: IState, token: string) { try { let user: any = jwtDecode(token); state.user = { @@ -54,7 +77,7 @@ export const mutations: MutationsTypes & MutationTree = { /** * Store the user to remember them */ - [Mutation.StoreUser](state: IState, remember: boolean) { + [Mutation.UserStore](state: IState, remember: boolean) { if (state.user == null) { sessionStorage.removeItem("jwt"); localStorage.removeItem("jwt"); diff --git a/src/app/store/state.ts b/src/app/store/state.ts index 524c37f..4a45d4c 100644 --- a/src/app/store/state.ts +++ b/src/app/store/state.ts @@ -1,15 +1,21 @@ import { IUser } from "./schema"; +import type Modals from "../components/modals"; +import Modal from "../components/modals"; /** * The state definition */ export interface IState { - user: IUser | null, + user : IUser | null, + modalName : Modal | null, + modalVisible: boolean } /** * The state implementation */ export const state: IState = { - user: null + user: null, + modalName: null, + modalVisible: false, }; diff --git a/src/app/styles/index.css b/src/app/styles/index.css index 3c5f02e..26dab05 100644 --- a/src/app/styles/index.css +++ b/src/app/styles/index.css @@ -6,3 +6,22 @@ html, body { @apply h-full; } + +.fade-enter-active, .fade-leave-active { + transition: opacity 0.15s; +} +.fade-enter-from, .fade-leave-to { + opacity: 0; +} + +.slide-enter-active, .slide-leave-active { + transform: none; + opacity: 1.0; + transition: opacity 0.15s ease-in-out, transform 0.5s cubic-bezier(0.0, 0.0, 0.2, 1); +} + +.slide-enter-from, .slide-leave-to { + opacity: 0; + transition: opacity 0.15s ease-in-out, transform 0.5s cubic-bezier(0.4, 0.0, 1, 1); + transform: translateY(10%); +} diff --git a/src/app/views/Home.vue b/src/app/views/Search.vue similarity index 66% rename from src/app/views/Home.vue rename to src/app/views/Search.vue index 44303a2..2e9be19 100644 --- a/src/app/views/Home.vue +++ b/src/app/views/Search.vue @@ -7,25 +7,25 @@ - - - - - - - - + + + + + + + - + +
{{movie?.overview}}
{{ movie?.overview }}