Format dates/revise dashboard

Also added version and rearranged shared components into just components and layout components
This commit is contained in:
Daniel J. Summers 2021-07-25 22:21:53 -04:00
parent b0ae93cc07
commit b27e7a8055
16 changed files with 178 additions and 69 deletions

View File

@ -4853,6 +4853,16 @@
"assert-plus": "^1.0.0"
}
},
"date-fns": {
"version": "2.23.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.23.0.tgz",
"integrity": "sha512-5ycpauovVyAk0kXNZz6ZoB9AYMZB4DObse7P3BPWmyEjXNORTI8EJ6X0uaSAq4sCHzM1uajzrkr6HnsLQpxGXA=="
},
"date-fns-tz": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.1.4.tgz",
"integrity": "sha512-lQ+FF7xUxxRuRqIY7H/lagnT3PhhSnnvtGHzjE5WZKwRyLU7glJfLys05SZ7zHlEr6RXWiqkmgWq4nCkcElR+g=="
},
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",

View File

@ -1,6 +1,6 @@
{
"name": "jobs-jobs-jobs",
"version": "1.0.1",
"version": "1.9.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@ -11,6 +11,8 @@
"dependencies": {
"@mdi/font": "5.9.55",
"core-js": "^3.6.5",
"date-fns": "^2.23.0",
"date-fns-tz": "^1.1.4",
"marked": "^2.1.3",
"roboto-fontface": "*",
"vue": "^3.0.0",

View File

@ -23,9 +23,9 @@
<script lang="ts">
import { defineComponent } from 'vue'
import AppFooter from './components/shared/AppFooter.vue'
import AppNav from './components/shared/AppNav.vue'
import TitleBar from './components/shared/TitleBar.vue'
import AppFooter from './components/layout/AppFooter.vue'
import AppNav from './components/layout/AppNav.vue'
import TitleBar from './components/layout/TitleBar.vue'
export default defineComponent({
name: 'App',

View File

@ -11,10 +11,10 @@ export interface Citizen {
realName : string | undefined
/** The URL for the user's Mastodon profile */
profileUrl : string
/** When the user joined Jobs, Jobs, Jobs */
joinedOn : number
/** When the user last logged in */
lastSeenOn : number
/** When the user joined Jobs, Jobs, Jobs (date) */
joinedOn : string
/** When the user last logged in (date) */
lastSeenOn : string
}
/** A continent */
@ -63,8 +63,8 @@ export interface Profile {
fullTime : boolean
/** The citizen's professional biography */
biography : string
/** When the citizen last updated their profile */
lastUpdatedOn : number
/** When the citizen last updated their profile (date) */
lastUpdatedOn : string
/** The citizen's experience (topical / chronological) */
experience : string | undefined
/** Skills this citizen possesses */

View File

@ -1,5 +1,5 @@
<template>
<span @click.prevent="playFile"><slot></slot></span><audio :id="clip"><source :src="clipSource"></audio>
<span @click="playFile"><slot></slot><audio :id="clip"><source :src="clipSource"></audio></span>
</template>
<script lang="ts">

View File

@ -0,0 +1,27 @@
<template>
<template v-if="true">{{formatted}}</template>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { format, parseJSON } from 'date-fns'
import { utcToZonedTime } from 'date-fns-tz'
export default defineComponent({
name: 'FullDateTime',
props: {
date: {
type: String,
required: true
}
},
setup (props) {
return {
formatted: format(
utcToZonedTime(
parseJSON(props.date), Intl.DateTimeFormat().resolvedOptions().timeZone),
'PPPppp')
}
}
})
</script>

View File

@ -0,0 +1,38 @@
<template>
<p>
Jobs, Jobs, Jobs v{{appVersion}} &bull; <router-link to="/privacy-policy">Privacy Policy</router-link>
&bull; <router-link to="/terms-of-service">Terms of Service</router-link>
</p>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { version } from '../../../package.json'
export default defineComponent({
name: 'AppFooter',
setup () {
let appVersion : string = version
while (appVersion.endsWith('.0')) {
appVersion = appVersion.substring(0, appVersion.length - 2)
}
return {
appVersion
}
}
})
</script>
<style lang="sass" scoped>
p
padding-top: 2rem
color: rgba(0, 0, 0, .4)
font-style: italic
font-size: .8rem
a:link,
a:visited
color: rgba(0, 0, 0, .4)
text-decoration: none
a:hover
text-decoration: underline
</style>

View File

@ -3,18 +3,18 @@
<p class="home-link"><router-link to="/">Jobs, Jobs, Jobs</router-link></p>
<p>&nbsp;</p>
<nav>
<template v-if="!isLoggedOn">
<router-link to="/"><v-icon icon="mdi-home" /> Home</router-link>
<router-link to="/profile/seeking"><v-icon icon="mdi-view-list-outline" /> Job Seekers</router-link>
<a :href="authUrl"><v-icon icon="mdi-login-variant" /> Log On</a>
</template>
<template v-else>
<template v-if="isLoggedOn">
<router-link to="/citizen/dashboard"><v-icon icon="mdi-view-dashboard-variant" />Dashboard</router-link>
<router-link to="/citizen/profile"><v-icon icon="mdi-pencil" /> Edit Your Profile</router-link>
<router-link to="/profile/search"><v-icon icon="mdi-view-list-outline" /> View Profiles</router-link>
<router-link to="/success-story/list"><v-icon icon="mdi-thumb-up" /> Success Stories</router-link>
<router-link to="/citizen/log-off"><v-icon icon="mdi-logout-variant" /> Log Off</router-link>
</template>
<template v-else>
<router-link to="/"><v-icon icon="mdi-home" /> Home</router-link>
<router-link to="/profile/seeking"><v-icon icon="mdi-view-list-outline" /> Job Seekers</router-link>
<a :href="authUrl"><v-icon icon="mdi-login-variant" /> Log On</a>
</template>
<router-link to="/how-it-works"><v-icon icon="mdi-help-circle-outline" /> How It Works</router-link>
</nav>
</aside>

View File

@ -4,7 +4,7 @@
<script lang="ts">
import { defineComponent } from 'vue'
import AudioClip from './AudioClip.vue'
import AudioClip from '../AudioClip.vue'
export default defineComponent({
name: 'TitleBar',

View File

@ -1,19 +0,0 @@
<template>
<p>Jobs, Jobs, Jobs [version] &bull; <router-link to="/privacy-policy">Privacy Policy</router-link>
&bull; <router-link to="/terms-of-service">Terms of Service</router-link>
</p>
</template>
<style lang="sass" scoped>
p
padding-top: 2rem
color: rgba(0, 0, 0, .4)
font-style: italic
font-size: .8rem
a:link,
a:visited
color: rgba(0, 0, 0, .4)
text-decoration: none
a:hover
text-decoration: underline
</style>

View File

@ -16,7 +16,7 @@
<script lang="ts">
import { defineComponent } from 'vue'
import AudioClip from '../components/shared/AudioClip.vue'
import AudioClip from '../components/AudioClip.vue'
export default defineComponent({
name: 'Home',

View File

@ -3,33 +3,69 @@
<page-title title="Dashboard" />
<h3>Welcome, {{user.name}}</h3>
<load-data :load="retrieveData">
<template v-if="profile">
<p>
Your employment profile was last updated {{profile.lastUpdatedOn}}. Your profile currently lists
{{profile.skills.length}} skill<span v-if="profile.skills.length !== 1">s</span>.
</p>
<p><router-link :to="'/profile/view/' + user.citizenId">View Your Employment Profile</router-link></p>
<p v-if="profile.seekingEmployment">
Your profile indicates that you are seeking employment. Once you find it,
<router-link to="/success-story/add">tell your fellow citizens about it!</router-link>
</p>
</template>
<template v-else>
<p>
You do not have an employment profile established; click &ldquo;Edit Profile&rdquo; in the menu to get
started!
</p>
</template>
<hr>
<p>
There <template v-if="profileCount === 1">is</template><template v-else>are</template>&nbsp;
<template v-if="profileCount === 0">no</template><template v-else>{{profileCount}}</template>
employment profile<template v-if="profileCount !== 1">s</template> from citizens of Gitmo Nation.
<template v-if="profileCount > 0">Take a look around and see if you can help them find work!</template>
</p>
<v-row class="spaced">
<v-col cols="12" md="6">
<v-card elevation="6">
<v-card-header>
<v-card-header-text>
<v-card-title>Your Profile</v-card-title>
<v-card-subtitle>Last updated <full-date-time :date="profile.lastUpdatedOn" /></v-card-subtitle>
</v-card-header-text>
</v-card-header>
<v-card-text>
<div v-if="profile">
Your profile currently lists {{profile.skills.length}}
skill<template v-if="profile.skills.length !== 1">s</template>.
<span v-if="profile.seekingEmployment">
<br><br>
Your profile indicates that you are seeking employment. Once you find it,
<router-link to="/success-story/add">tell your fellow citizens about it!</router-link>
</span>
</div>
<div v-else>
You do not have an employment profile established; click below (or &ldquo;Edit Profile&rdquo; in the menu)
to get started!
</div>
</v-card-text>
<v-card-actions>
<template v-if="profile">
<v-btn v-if="profile" @click="viewProfile">View Profile</v-btn>
<v-btn @click="editProfile">Edit Profile</v-btn>
</template>
<v-btn v-else @click="editProfile">Create Profile</v-btn>
</v-card-actions>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card elevation="6">
<v-card-header>
<v-card-header-text>
<v-card-title>Other Citizens</v-card-title>
<v-card-subtitle>
<template v-if="profileCount === 0">No</template><template v-else>{{profileCount}} Total</template>
Employment Profile<template v-if="profileCount !== 1">s</template>
</v-card-subtitle>
</v-card-header-text>
</v-card-header>
<v-card-text>
<div v-if="profileCount === 1 && profile">
It looks like, for now, it&rsquo;s just you&hellip;
</div>
<div v-else-if="profileCount > 0">
Take a look around and see if you can help them find work!
</div>
<div v-else>
You can click below, but you will not find anything&hellip;
</div>
</v-card-text>
<v-card-actions>
<v-btn @click="searchProfiles">Search Profiles</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</load-data>
<hr>
<p>
<p class="spaced">
To see how this application works, check out &ldquo;How It Works&rdquo; in the sidebar (last updated June
14<sup>th</sup>, 2021).
</p>
@ -40,13 +76,19 @@
import { defineComponent, Ref, ref } from 'vue'
import api, { LogOnSuccess, Profile } from '../../api'
import { useStore } from '../../store'
import LoadData from '../../components/shared/LoadData.vue'
import FullDateTime from '../../components/FullDateTime.vue'
import LoadData from '../../components/LoadData.vue'
import { useRouter } from 'vue-router'
export default defineComponent({
name: 'Dashboard',
components: { LoadData },
components: {
LoadData,
FullDateTime
},
setup () {
const store = useStore()
const router = useRouter()
/** The currently logged-in user */
const user = store.state.user as LogOnSuccess
@ -76,8 +118,16 @@ export default defineComponent({
retrieveData,
user,
profile,
profileCount
profileCount,
viewProfile: () => router.push(`/profile/view/${user.citizenId}`),
editProfile: () => router.push('/citizen/profile'),
searchProfiles: () => router.push('/profile/search')
}
}
})
</script>
<style lang="sass" scoped>
.spaced
margin-top: 1rem
</style>

View File

@ -113,7 +113,7 @@ import { computed, defineComponent, Ref, ref } from 'vue'
import { useRouter } from 'vue-router'
import api, { LogOnSuccess, Profile } from '../../api'
import MarkdownEditor from '../../components/MarkdownEditor.vue'
import LoadData from '../../components/shared/LoadData.vue'
import LoadData from '../../components/LoadData.vue'
import { useStore } from '../../store'
export default defineComponent({

View File

@ -36,7 +36,7 @@
import { computed, defineComponent, ref, Ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import marked from 'marked'
import LoadData from '../../components/shared/LoadData.vue'
import LoadData from '../../components/LoadData.vue'
import { useStore } from '../../store'
import api, { LogOnSuccess, markedOptions, ProfileForView } from '../../api'

View File

@ -10,6 +10,7 @@
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"resolveJsonModule": true,
"baseUrl": ".",
"types": [
"webpack-env"