Format dates/revise dashboard
Also added version and rearranged shared components into just components and layout components
This commit is contained in:
parent
b0ae93cc07
commit
b27e7a8055
10
src/JobsJobsJobs/App/package-lock.json
generated
10
src/JobsJobsJobs/App/package-lock.json
generated
|
@ -4853,6 +4853,16 @@
|
||||||
"assert-plus": "^1.0.0"
|
"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": {
|
"debug": {
|
||||||
"version": "4.3.2",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "jobs-jobs-jobs",
|
"name": "jobs-jobs-jobs",
|
||||||
"version": "1.0.1",
|
"version": "1.9.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vue-cli-service serve",
|
||||||
|
@ -11,6 +11,8 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/font": "5.9.55",
|
"@mdi/font": "5.9.55",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
|
"date-fns": "^2.23.0",
|
||||||
|
"date-fns-tz": "^1.1.4",
|
||||||
"marked": "^2.1.3",
|
"marked": "^2.1.3",
|
||||||
"roboto-fontface": "*",
|
"roboto-fontface": "*",
|
||||||
"vue": "^3.0.0",
|
"vue": "^3.0.0",
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import AppFooter from './components/shared/AppFooter.vue'
|
import AppFooter from './components/layout/AppFooter.vue'
|
||||||
import AppNav from './components/shared/AppNav.vue'
|
import AppNav from './components/layout/AppNav.vue'
|
||||||
import TitleBar from './components/shared/TitleBar.vue'
|
import TitleBar from './components/layout/TitleBar.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'App',
|
name: 'App',
|
||||||
|
|
|
@ -11,10 +11,10 @@ export interface Citizen {
|
||||||
realName : string | undefined
|
realName : string | undefined
|
||||||
/** The URL for the user's Mastodon profile */
|
/** The URL for the user's Mastodon profile */
|
||||||
profileUrl : string
|
profileUrl : string
|
||||||
/** When the user joined Jobs, Jobs, Jobs */
|
/** When the user joined Jobs, Jobs, Jobs (date) */
|
||||||
joinedOn : number
|
joinedOn : string
|
||||||
/** When the user last logged in */
|
/** When the user last logged in (date) */
|
||||||
lastSeenOn : number
|
lastSeenOn : string
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A continent */
|
/** A continent */
|
||||||
|
@ -63,8 +63,8 @@ export interface Profile {
|
||||||
fullTime : boolean
|
fullTime : boolean
|
||||||
/** The citizen's professional biography */
|
/** The citizen's professional biography */
|
||||||
biography : string
|
biography : string
|
||||||
/** When the citizen last updated their profile */
|
/** When the citizen last updated their profile (date) */
|
||||||
lastUpdatedOn : number
|
lastUpdatedOn : string
|
||||||
/** The citizen's experience (topical / chronological) */
|
/** The citizen's experience (topical / chronological) */
|
||||||
experience : string | undefined
|
experience : string | undefined
|
||||||
/** Skills this citizen possesses */
|
/** Skills this citizen possesses */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<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>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
27
src/JobsJobsJobs/App/src/components/FullDateTime.vue
Normal file
27
src/JobsJobsJobs/App/src/components/FullDateTime.vue
Normal 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>
|
38
src/JobsJobsJobs/App/src/components/layout/AppFooter.vue
Normal file
38
src/JobsJobsJobs/App/src/components/layout/AppFooter.vue
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<template>
|
||||||
|
<p>
|
||||||
|
Jobs, Jobs, Jobs v{{appVersion}} • <router-link to="/privacy-policy">Privacy Policy</router-link>
|
||||||
|
• <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>
|
|
@ -3,18 +3,18 @@
|
||||||
<p class="home-link"><router-link to="/">Jobs, Jobs, Jobs</router-link></p>
|
<p class="home-link"><router-link to="/">Jobs, Jobs, Jobs</router-link></p>
|
||||||
<p> </p>
|
<p> </p>
|
||||||
<nav>
|
<nav>
|
||||||
<template v-if="!isLoggedOn">
|
<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>
|
|
||||||
<router-link to="/citizen/dashboard"><v-icon icon="mdi-view-dashboard-variant" />Dashboard</router-link>
|
<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="/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="/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="/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>
|
<router-link to="/citizen/log-off"><v-icon icon="mdi-logout-variant" /> Log Off</router-link>
|
||||||
</template>
|
</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>
|
<router-link to="/how-it-works"><v-icon icon="mdi-help-circle-outline" /> How It Works</router-link>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import AudioClip from './AudioClip.vue'
|
import AudioClip from '../AudioClip.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'TitleBar',
|
name: 'TitleBar',
|
|
@ -1,19 +0,0 @@
|
||||||
<template>
|
|
||||||
<p>Jobs, Jobs, Jobs [version] • <router-link to="/privacy-policy">Privacy Policy</router-link>
|
|
||||||
• <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>
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import AudioClip from '../components/shared/AudioClip.vue'
|
import AudioClip from '../components/AudioClip.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
|
|
|
@ -3,33 +3,69 @@
|
||||||
<page-title title="Dashboard" />
|
<page-title title="Dashboard" />
|
||||||
<h3>Welcome, {{user.name}}</h3>
|
<h3>Welcome, {{user.name}}</h3>
|
||||||
<load-data :load="retrieveData">
|
<load-data :load="retrieveData">
|
||||||
<template v-if="profile">
|
<v-row class="spaced">
|
||||||
<p>
|
<v-col cols="12" md="6">
|
||||||
Your employment profile was last updated {{profile.lastUpdatedOn}}. Your profile currently lists
|
<v-card elevation="6">
|
||||||
{{profile.skills.length}} skill<span v-if="profile.skills.length !== 1">s</span>.
|
<v-card-header>
|
||||||
</p>
|
<v-card-header-text>
|
||||||
<p><router-link :to="'/profile/view/' + user.citizenId">View Your Employment Profile</router-link></p>
|
<v-card-title>Your Profile</v-card-title>
|
||||||
<p v-if="profile.seekingEmployment">
|
<v-card-subtitle>Last updated <full-date-time :date="profile.lastUpdatedOn" /></v-card-subtitle>
|
||||||
Your profile indicates that you are seeking employment. Once you find it,
|
</v-card-header-text>
|
||||||
<router-link to="/success-story/add">tell your fellow citizens about it!</router-link>
|
</v-card-header>
|
||||||
</p>
|
<v-card-text>
|
||||||
</template>
|
<div v-if="profile">
|
||||||
<template v-else>
|
Your profile currently lists {{profile.skills.length}}
|
||||||
<p>
|
skill<template v-if="profile.skills.length !== 1">s</template>.
|
||||||
You do not have an employment profile established; click “Edit Profile” in the menu to get
|
<span v-if="profile.seekingEmployment">
|
||||||
started!
|
<br><br>
|
||||||
</p>
|
Your profile indicates that you are seeking employment. Once you find it,
|
||||||
</template>
|
<router-link to="/success-story/add">tell your fellow citizens about it!</router-link>
|
||||||
<hr>
|
</span>
|
||||||
<p>
|
</div>
|
||||||
There <template v-if="profileCount === 1">is</template><template v-else>are</template>
|
<div v-else>
|
||||||
<template v-if="profileCount === 0">no</template><template v-else>{{profileCount}}</template>
|
You do not have an employment profile established; click below (or “Edit Profile” in the menu)
|
||||||
employment profile<template v-if="profileCount !== 1">s</template> from citizens of Gitmo Nation.
|
to get started!
|
||||||
<template v-if="profileCount > 0">Take a look around and see if you can help them find work!</template>
|
</div>
|
||||||
</p>
|
</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’s just you…
|
||||||
|
</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…
|
||||||
|
</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>
|
</load-data>
|
||||||
<hr>
|
<p class="spaced">
|
||||||
<p>
|
|
||||||
To see how this application works, check out “How It Works” in the sidebar (last updated June
|
To see how this application works, check out “How It Works” in the sidebar (last updated June
|
||||||
14<sup>th</sup>, 2021).
|
14<sup>th</sup>, 2021).
|
||||||
</p>
|
</p>
|
||||||
|
@ -40,13 +76,19 @@
|
||||||
import { defineComponent, Ref, ref } from 'vue'
|
import { defineComponent, Ref, ref } from 'vue'
|
||||||
import api, { LogOnSuccess, Profile } from '../../api'
|
import api, { LogOnSuccess, Profile } from '../../api'
|
||||||
import { useStore } from '../../store'
|
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({
|
export default defineComponent({
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
components: { LoadData },
|
components: {
|
||||||
|
LoadData,
|
||||||
|
FullDateTime
|
||||||
|
},
|
||||||
setup () {
|
setup () {
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
/** The currently logged-in user */
|
/** The currently logged-in user */
|
||||||
const user = store.state.user as LogOnSuccess
|
const user = store.state.user as LogOnSuccess
|
||||||
|
@ -76,8 +118,16 @@ export default defineComponent({
|
||||||
retrieveData,
|
retrieveData,
|
||||||
user,
|
user,
|
||||||
profile,
|
profile,
|
||||||
profileCount
|
profileCount,
|
||||||
|
viewProfile: () => router.push(`/profile/view/${user.citizenId}`),
|
||||||
|
editProfile: () => router.push('/citizen/profile'),
|
||||||
|
searchProfiles: () => router.push('/profile/search')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="sass" scoped>
|
||||||
|
.spaced
|
||||||
|
margin-top: 1rem
|
||||||
|
</style>
|
||||||
|
|
|
@ -113,7 +113,7 @@ import { computed, defineComponent, Ref, ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import api, { LogOnSuccess, Profile } from '../../api'
|
import api, { LogOnSuccess, Profile } from '../../api'
|
||||||
import MarkdownEditor from '../../components/MarkdownEditor.vue'
|
import MarkdownEditor from '../../components/MarkdownEditor.vue'
|
||||||
import LoadData from '../../components/shared/LoadData.vue'
|
import LoadData from '../../components/LoadData.vue'
|
||||||
import { useStore } from '../../store'
|
import { useStore } from '../../store'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
import { computed, defineComponent, ref, Ref } from 'vue'
|
import { computed, defineComponent, ref, Ref } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import marked from 'marked'
|
import marked from 'marked'
|
||||||
import LoadData from '../../components/shared/LoadData.vue'
|
import LoadData from '../../components/LoadData.vue'
|
||||||
import { useStore } from '../../store'
|
import { useStore } from '../../store'
|
||||||
import api, { LogOnSuccess, markedOptions, ProfileForView } from '../../api'
|
import api, { LogOnSuccess, markedOptions, ProfileForView } from '../../api'
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"types": [
|
"types": [
|
||||||
"webpack-env"
|
"webpack-env"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user