Skip to content

Commit

Permalink
17673 responsive navbar (bcgov#1400)
Browse files Browse the repository at this point in the history
* add .vscode to gitignore

* make home page layout responsive

* modularize toggle and improve app header

* add HeadlessUI

* add dropdown for app header

* fix landing page tests

* use tailwind theme colors for search button

* revert navbar to original layout

* fix app header image path

* change nuxt version
  • Loading branch information
semmatti authored Oct 5, 2023
1 parent 1a76db2 commit a7cadef
Show file tree
Hide file tree
Showing 15 changed files with 12,908 additions and 9,171 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,6 @@ dist
#firebase hosting
.firebase
.firebaserc

# IDEs
.vscode
56 changes: 30 additions & 26 deletions .nuxt/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,86 +7,90 @@
"module": "ESNext",
"moduleResolution": "Node",
"skipLibCheck": true,
"isolatedModules": true,
"useDefineForClassFields": true,
"strict": true,
"allowJs": true,
"noEmit": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"types": [
"node"
],
"baseUrl": "..",
"paths": {
"~": [
"."
".."
],
"~/*": [
"./*"
"../*"
],
"@": [
"."
".."
],
"@/*": [
"./*"
"../*"
],
"~~": [
"."
".."
],
"~~/*": [
"./*"
"../*"
],
"@@": [
"."
".."
],
"@@/*": [
"./*"
"../*"
],
"assets": [
"assets"
"../assets"
],
"assets/*": [
"assets/*"
"../assets/*"
],
"public": [
"public"
"../public"
],
"public/*": [
"public/*"
"../public/*"
],
"#app": [
"node_modules/nuxt/dist/app"
"../node_modules/nuxt/dist/app"
],
"#app/*": [
"node_modules/nuxt/dist/app/*"
"../node_modules/nuxt/dist/app/*"
],
"vue-demi": [
"node_modules/nuxt/dist/app/compat/vue-demi"
"../node_modules/nuxt/dist/app/compat/vue-demi"
],
"#mdc-imports": [
"./mdc-imports"
],
"pinia": [
"node_modules/pinia/dist/pinia"
"../node_modules/pinia/dist/pinia"
],
"#vue-router": [
".nuxt/vue-router"
"./vue-router"
],
"#imports": [
".nuxt/imports"
"./imports"
],
"#build": [
".nuxt"
"."
],
"#build/*": [
".nuxt/*"
"./*"
],
"#components": [
".nuxt/components"
"./components"
]
}
},
"include": [
"./nuxt.d.ts",
"../**/*"
"../**/*",
".."
],
"exclude": [
"../node_modules",
"../node_modules/nuxt/node_modules",
"../dist",
"../.output"
]
Expand Down
6 changes: 3 additions & 3 deletions __tests__/LandingPage.specs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { beforeEach, describe, it, expect, vitest } from 'vitest'
import LandingPage from '../pages/index.vue'
import { mount } from '@vue/test-utils'
import { DOMWrapper, mount } from '@vue/test-utils'
import { createTestingPinia } from '@pinia/testing'
import { useAuthStore } from '../store/auth'
import flushPromises from 'flush-promises'
Expand Down Expand Up @@ -43,7 +43,7 @@ describe('Welcome Message', () => {
authModule.isAuthenticated = false // simulate not being logged in
await flushPromises()// wait for updates
// At this point, the 'p' element should exist in the DOM.
expect(wrapper.find('p').text()).toBe('Your authorization is missing or has expired. Please login.')
expect(wrapper.findAll('p').filter((node: DOMWrapper<HTMLParagraphElement>) => node.text().match(/Please login/)).length).toBe(1)
// And the 'header' should not.
expect(wrapper.find('header').exists()).toBe(false)
})
Expand All @@ -54,6 +54,6 @@ describe('Welcome Message', () => {
// At this point, the 'header' element should exist in the DOM.
expect(wrapper.find('header').text()).toBe('Welcome to Name X!')
// And the 'p' should not.
expect(wrapper.find('p').exists()).toBe(false)
expect(wrapper.findAll('p').filter((node: DOMWrapper<HTMLParagraphElement>) => node.text().match(/Please login/)).length).toBe(0)
})
})
190 changes: 40 additions & 150 deletions components/AppHeader.vue
Original file line number Diff line number Diff line change
@@ -1,150 +1,53 @@
<template id="app-header">
<nav class="flex h-20 bg-white text-lg font-medium shadow-2xl">
<div class="flex min-w-full">
<div class="image">
<img
src="../public/images/top-nav.png"
alt="Name Examination"
class="h-full"
>
</div>

<div
v-if="authModule.isAuthenticated"
class="mt-6 flex gap-24 text-blue-800"
>
<a
href=""
class="ml-16 text-2xl"
:class="{ 'text-amber-400': selectedLink === SelectedLink.Admin}"
@click="selectedLink = 'admin'"
>Admin</a>

<a
href=""
class="text-2xl"
:class="{ 'text-amber-400': selectedLink === SelectedLink.Examine }"
@click="selectedLink = 'examine'"
>Examine</a>

<nuxt-link to="/SearchPage">
<span
class="text-2xl"
:class="{ 'text-amber-400': selectedLink === SelectedLink.Search }"
@click="selectedLink = 'search'"
>
Search
</span>
<nav class="h-16 border-b border-gray-300">
<div class="flex h-full w-full items-center justify-between">
<div class="hidden h-full 2xl:block">
<nuxt-link to="/HomePage">
<img
src="../public/images/top-nav.png"
class="min-w-8 h-full"
alt="Name Examination"
/>
</nuxt-link>
</div>

<div
v-if="authModule.isAuthenticated"
class="ml-auto flex"
class="ml-3 flex gap-10 text-bcgov-blue5"
>
<form class="flex items-center">
<label
for="allowWordClassificationModal"
class="sr-only"
>NR Number Lookup</label>
<div class="relative w-full">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg-icon
type="mdi"
:path="path"
class="h-6"
/>
</div>
<input
id="allowWordClassificationModal"
type="text"
class="w-72 h-13 bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-blue-500
focus:border-blue-500 block pl-10 p-2.5 dark:bg-gray-700 dark:border-gray-600
dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 text-lg"
placeholder="NR Number Lookup"
required
>
</div>
<button
type="submit"
class="bcgovblue-btn p-2.5 ml-3 h-12 transition ease-in-out delay-120
hover:scale-115 duration-300 px-4 py-2 text-white border
rounded-lg focus:ring-4 focus:outline-none
focus:ring-amber-300 dark:bg-amber-200 dark:hover:bg-amber-400 dark:focus:ring-amber-200"
>
<svg-icon
type="mdi"
:path="path"
/>
Submit
</button>
</form>

<span class="mx-10 mt-7 underline">Stats</span>

<label
for="classifyWords"
class="relative mt-2 inline-flex cursor-pointer items-center"
>
<input
id="classifyWords"
type="checkbox"
value=""
class="peer sr-only"
>
<div
class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300
dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full
peer-checked:after:border-white after:content-[''] after:absolute after:left-[2px] after:top-[25px]
after:bg-white after:border-gray-300
after:border after:rounded-full after:h-5 after:w-5 after:transition-all
dark:border-gray-600 peer-checked:bg-blue-600"
/>
<span class="ml-3 font-medium text-gray-500 dark:text-gray-300">Classify Words</span>
</label>
<AppHeaderNavLink text="Admin" :route="NavbarLink.Admin" />
<AppHeaderNavLink text="Examine Names" :route="NavbarLink.Examine" />
<AppHeaderNavLink text="Search" :route="NavbarLink.Search" />
</div>

<label
for="priorityQueue"
class="relative mt-2 inline-flex cursor-pointer items-center ml-5"
>
<input
id="priorityQueue"
type="checkbox"
value=""
class="peer sr-only"
>
<div
class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300
dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full
peer-checked:after:border-white after:content-[''] after:absolute after:left-[2px] after:top-[25px]
after:bg-white after:border-gray-300
after:border after:rounded-full after:h-5 after:w-5 after:transition-all
dark:border-gray-600 peer-checked:bg-blue-600"
/>
<span class="ml-3 font-medium text-gray-500 dark:text-gray-300">Priority Queue</span>
</label>
<div v-if="authModule.isAuthenticated" class="ml-auto flex items-center">
<SearchInput />

<span class="mx-10 mt-7 flex text-gray-800">{{ KeycloakService.getUserInfo().fullName }}</span>
<nuxt-link to="/stats" class="mx-3 text-sm text-blue-800 underline">
<a>Stats</a>
</nuxt-link>

<div class="divider" />
<div class="flex space-x-2 px-3">
<ToggleSwitch label="Classify Words" storeFieldName="classifyWords" />
<ToggleSwitch label="Priority Queue" storeFieldName="priorityQueue" />
</div>

<div class="mx-10 mt-7 text-blue-800">
<a
id="logout-button"
href="#"
@click="logout()"
>Log Out</a>
<div class="flex flex-col px-3 border-l-2 border-gray-300">
<span class="text-sm">{{
KeycloakService.getUserInfo().fullName
}}</span>
<a class="text-sm text-blue-800" href="#" @click="logout">Log Out</a>
</div>
</div>

<div
v-if="!authModule.isAuthenticated"
class="mx-10 ml-auto mt-7 flex text-blue-800"
>
<a
href="#"
@click="login()"
>Login</a>
<div v-if="!authModule.isAuthenticated" class="mx-5">
<button
class="inline-flex w-full items-center justify-between rounded-md border-2 border-gray-300 px-1.5 py-1 font-medium hover:bg-gray-300 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
@click="login"
>
Login
<svg-icon type="mdi" viewBox="0 -2 24 24" :path="mdiLogin" />
</button>
</div>
</div>
</nav>
Expand All @@ -153,20 +56,17 @@
<script setup>
import '@jamescoyle/vue-icon'
import { ref } from 'vue'
import { mdiMagnify } from '@mdi/js'
import { mdiLogin, mdiMagnify } from '@mdi/js'
import { useAuthStore } from '../store/auth'
import KeycloakService from '../public/keycloak/keycloak'
import { SelectedLink } from '../enums/dropdownEnums'
import { useRuntimeConfig } from '#imports'
import { NavbarLink } from '../enums/dropdownEnums'
/* eslint-disable require-jsdoc */
const authModule = useAuthStore()
const config = useRuntimeConfig()
const path = mdiMagnify
const selectedLink = ref('/')
async function login () {
async function login() {
// If the user is already authenticated, do nothing
if (authModule.isAuthenticated) return
Expand All @@ -188,7 +88,7 @@ async function login () {
}
}
async function logout () {
async function logout() {
// If the user is already logged out, do nothing
if (!authModule.isAuthenticated) return
Expand All @@ -202,13 +102,3 @@ async function logout () {
}
}
</script>
<style lang ='scss' scoped>
@import '../assets/theme.scss';
.bcgovblue-btn {
background-color: $BCgovBlue5;
&:hover {
background-color: $BCgovGold5;
}
}
</style>
Loading

0 comments on commit a7cadef

Please sign in to comment.