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"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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">
|
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> </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>
|
|
@ -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',
|
|
@ -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">
|
||||
import { defineComponent } from 'vue'
|
||||
import AudioClip from '../components/shared/AudioClip.vue'
|
||||
import AudioClip from '../components/AudioClip.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Home',
|
||||
|
|
|
@ -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 “Edit Profile” in the menu to get
|
||||
started!
|
||||
</p>
|
||||
</template>
|
||||
<hr>
|
||||
<p>
|
||||
There <template v-if="profileCount === 1">is</template><template v-else>are</template>
|
||||
<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 “Edit Profile” 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’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>
|
||||
<hr>
|
||||
<p>
|
||||
<p class="spaced">
|
||||
To see how this application works, check out “How It Works” 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>
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"webpack-env"
|
||||
|
|
Loading…
Reference in New Issue
Block a user