Out with Vuetify, in with vanilla Bootstrap

This commit is contained in:
Daniel J. Summers 2021-08-07 14:14:53 -04:00
parent 7e0f98d249
commit 8fbdc858af
24 changed files with 445 additions and 494 deletions

View File

@ -1200,6 +1200,12 @@
"fastq": "^1.6.0" "fastq": "^1.6.0"
} }
}, },
"@popperjs/core": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.3.tgz",
"integrity": "sha512-xDu17cEfh7Kid/d95kB6tZsLOmSWKCZKtprnhVepjsSaCij+lM3mItSJDuuHDMbCWTh8Ejmebwb+KONcCJ0eXQ==",
"dev": true
},
"@soda/friendly-errors-webpack-plugin": { "@soda/friendly-errors-webpack-plugin": {
"version": "1.8.0", "version": "1.8.0",
"resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.0.tgz", "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.0.tgz",
@ -1280,6 +1286,16 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/bootstrap": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.1.0.tgz",
"integrity": "sha512-cR+eQJ/IrgcJZheb7xkKPiPNOa48zkc6fLZ4U9lDNNQp3qiiq3tW1xgrd+VzVJCram/Bnh+DdBsdsPdXKIYClA==",
"dev": true,
"requires": {
"@popperjs/core": "^2.9.2",
"@types/jquery": "*"
}
},
"@types/connect": { "@types/connect": {
"version": "3.4.35", "version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@ -1347,6 +1363,15 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/jquery": {
"version": "3.5.6",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.6.tgz",
"integrity": "sha512-SmgCQRzGPId4MZQKDj9Hqc6kSXFNWZFHpELkyK8AQhf8Zr6HKfCzFv9ZC1Fv3FyQttJZOlap3qYb12h61iZAIg==",
"dev": true,
"requires": {
"@types/sizzle": "*"
}
},
"@types/json-schema": { "@types/json-schema": {
"version": "7.0.8", "version": "7.0.8",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz",
@ -1424,6 +1449,12 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/sizzle": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
"integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
"dev": true
},
"@types/source-list-map": { "@types/source-list-map": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
@ -3403,6 +3434,11 @@
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
"dev": true "dev": true
}, },
"bootstrap": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.0.tgz",
"integrity": "sha512-bs74WNI9BgBo3cEovmdMHikSKoXnDgA6VQjJ7TyTotU6L7d41ZyCEEelPwkYEzsG/Zjv3ie9IE3EMAje0W9Xew=="
},
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -8989,29 +9025,6 @@
"boolbase": "~1.0.0" "boolbase": "~1.0.0"
} }
}, },
"null-loader": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/null-loader/-/null-loader-3.0.0.tgz",
"integrity": "sha512-hf5sNLl8xdRho4UPBOOeoIwT3WhjYcMUQm0zj44EhD6UscMAz72o2udpoDFBgykucdEDGIcd6SXbc/G6zssbzw==",
"dev": true,
"requires": {
"loader-utils": "^1.2.3",
"schema-utils": "^1.0.0"
},
"dependencies": {
"schema-utils": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
"dev": true,
"requires": {
"ajv": "^6.1.0",
"ajv-errors": "^1.0.0",
"ajv-keywords": "^3.1.0"
}
}
}
},
"num2fraction": { "num2fraction": {
"version": "1.2.2", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
@ -10635,15 +10648,6 @@
"picomatch": "^2.2.1" "picomatch": "^2.2.1"
} }
}, },
"rechoir": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
"integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
"dev": true,
"requires": {
"resolve": "^1.1.6"
}
},
"regenerate": { "regenerate": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -10991,11 +10995,6 @@
"inherits": "^2.0.1" "inherits": "^2.0.1"
} }
}, },
"roboto-fontface": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz",
"integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g=="
},
"run-async": { "run-async": {
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
@ -11359,17 +11358,6 @@
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
"dev": true "dev": true
}, },
"shelljs": {
"version": "0.8.4",
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
"integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
"dev": true,
"requires": {
"glob": "^7.0.0",
"interpret": "^1.0.0",
"rechoir": "^0.6.2"
}
},
"signal-exit": { "signal-exit": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
@ -12865,43 +12853,6 @@
"@vue/shared": "3.1.4" "@vue/shared": "3.1.4"
} }
}, },
"vue-cli-plugin-vuetify": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.4.1.tgz",
"integrity": "sha512-ZfhvQ13X41atsCSKdSGiHnSJlhAccv4QIFOZmd8kyq6NktpeeWlvQz/dEKBf6u1AWKmKdwiCDuxS2VNT9fxhOA==",
"dev": true,
"requires": {
"null-loader": "^3.0.0",
"semver": "^7.1.2",
"shelljs": "^0.8.3"
},
"dependencies": {
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
},
"vue-eslint-parser": { "vue-eslint-parser": {
"version": "7.8.0", "version": "7.8.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.8.0.tgz", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.8.0.tgz",
@ -12994,11 +12945,6 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true "dev": true
}, },
"vuetify": {
"version": "3.0.0-alpha.9",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.0.0-alpha.9.tgz",
"integrity": "sha512-F8xwdAp65gUY0kf0lGKMKhYZDAA2j6cqLEc63uqIOq/dZ8R2k3ZSfBMGtt+jOMCt/w28BZ7rx7AuLxPA5oF/pA=="
},
"vuex": { "vuex": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz", "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",

View File

@ -10,17 +10,17 @@
}, },
"dependencies": { "dependencies": {
"@mdi/font": "5.9.55", "@mdi/font": "5.9.55",
"bootstrap": "^5.1.0",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"date-fns": "^2.23.0", "date-fns": "^2.23.0",
"date-fns-tz": "^1.1.4", "date-fns-tz": "^1.1.4",
"marked": "^2.1.3", "marked": "^2.1.3",
"roboto-fontface": "*",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",
"vuetify": "^3.0.0-alpha.0",
"vuex": "^4.0.0-0" "vuex": "^4.0.0-0"
}, },
"devDependencies": { "devDependencies": {
"@types/bootstrap": "^5.1.0",
"@types/marked": "^2.0.4", "@types/marked": "^2.0.4",
"@typescript-eslint/eslint-plugin": "^4.18.0", "@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0", "@typescript-eslint/parser": "^4.18.0",
@ -41,7 +41,6 @@
"eslint-plugin-vue": "^7.0.0", "eslint-plugin-vue": "^7.0.0",
"sass": "~1.32.0", "sass": "~1.32.0",
"sass-loader": "^10.0.0", "sass-loader": "^10.0.0",
"typescript": "~4.1.5", "typescript": "~4.1.5"
"vue-cli-plugin-vuetify": "~2.4.1"
} }
} }

View File

@ -1,24 +1,18 @@
<template> <template>
<v-app> <div class="jjj-app">
<v-navigation-drawer app> <app-nav />
<app-nav /> <div class="jjj-main">
</v-navigation-drawer>
<v-app-bar color="secondary" app>
<title-bar /> <title-bar />
</v-app-bar> <main class="container-fluid">
<v-main>
<v-container fluid>
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
<component :is="Component" /> <component :is="Component" />
</transition> </transition>
</router-view> </router-view>
</v-container> </main>
</v-main>
<v-footer app>
<app-footer /> <app-footer />
</v-footer> </div>
</v-app> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -27,6 +21,9 @@ import AppFooter from './components/layout/AppFooter.vue'
import AppNav from './components/layout/AppNav.vue' import AppNav from './components/layout/AppNav.vue'
import TitleBar from './components/layout/TitleBar.vue' import TitleBar from './components/layout/TitleBar.vue'
import 'bootstrap/dist/css/bootstrap.min.css'
import '@mdi/font/css/materialdesignicons.css'
export default defineComponent({ export default defineComponent({
name: 'App', name: 'App',
components: { components: {
@ -51,32 +48,20 @@ export function yesOrNo (cond : boolean) : string {
// Overall app styles // Overall app styles
html html
scroll-behavior: smooth scroll-behavior: smooth
h3 a:link,
font-size: 1.75rem a:visited
h4 text-decoration: none
font-size: 1.5rem a:hover
h1, h2, h3, h4, h5 text-decoration: underline
margin-bottom: .5rem label.jjj-required::after
font-weight: 500 color: red
line-height: 1.2 content: ' *'
p
padding-bottom: 1rem
ul
padding-bottom: 1rem
margin-left: 1.5rem
li
list-style-type: disc
// Styles for this component // Styles for this component
.v-navigation-drawer .jjj-app
background-image: linear-gradient(180deg, darkgreen 0%, green 70%)
height: 100vh
.v-app-bar
height: 3.5rem !important
display: flex display: flex
align-items: center flex-direction: row
justify-content: center .jjj-main
.v-footer flex-grow: 1
flex-direction: row-reverse
// Route transitions // Route transitions
.fade-enter-active, .fade-enter-active,
.fade-leave-active .fade-leave-active

View File

@ -1,16 +1,12 @@
<template> <template>
<v-card> <div class="card">
<v-card-header> <div class="card-body">
<v-card-header-text> <h6 class="card-title">
<v-card-title>
<a href="#" :class="{ 'cp-c': isCollapsed, 'cp-o': !isCollapsed }" @click.prevent="toggle">{{headerText}}</a> <a href="#" :class="{ 'cp-c': isCollapsed, 'cp-o': !isCollapsed }" @click.prevent="toggle">{{headerText}}</a>
</v-card-title> </h6>
</v-card-header-text> <slot v-if="!isCollapsed"></slot>
</v-card-header> </div>
<v-card-text v-if="!isCollapsed"> </div>
<slot></slot>
</v-card-text>
</v-card>
</template> </template>
<script lang="ts"> <script lang="ts">

View File

@ -0,0 +1,22 @@
<template>
<span :class="iconClass"></span>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'Icon',
props: {
icon: {
type: String,
required: true
}
},
setup (props) {
return {
iconClass: `mdi mdi-${props.icon}`
}
}
})
</script>

View File

@ -1,12 +1,19 @@
<template> <template>
<nav class="nav nav-pills"> <div class="row pb-3">
<v-btn rounded="pill" :color="sourceColor" @click="showMarkdown">Markdown</v-btn> &nbsp; <div class="col col-xs-12">
<v-btn rounded="pill" :color="previewColor" @click="showPreview">Preview</v-btn> <nav class="nav nav-pills pb-1">
</nav> <button :class="sourceClass" @click.prevent="showMarkdown">Markdown</button> &nbsp;
<section v-if="preview" class="preview" v-html="previewHtml"> <button :class="previewClass" @click.prevent="showPreview">Preview</button>
</section> </nav>
<textarea v-else :id="id" class="form-control" rows="10" v-text="text" <section v-if="preview" class="preview" v-html="previewHtml">
@input="$emit('update:text', $event.target.value)"></textarea> </section>
<div v-else class="form-floating">
<textarea :id="id" class="form-control md-edit" rows="10" v-text="text"
@input="$emit('update:text', $event.target.value)"></textarea>
<label :for="id">{{label}}</label>
</div>
</div>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -24,6 +31,10 @@ export default defineComponent({
text: { text: {
type: String, type: String,
required: true required: true
},
label: {
type: String,
required: true
} }
}, },
emits: ['update:text'], emits: ['update:text'],
@ -45,19 +56,28 @@ export default defineComponent({
preview.value = true preview.value = true
} }
/** Button classes for the selected button */
const selected = 'btn btn-primary btn-sm rounded-pill'
/** Button classes for the unselected button */
const unselected = 'btn btn-outline-secondary btn-sm rounded-pill'
return { return {
preview, preview,
previewHtml, previewHtml,
showMarkdown, showMarkdown,
showPreview, showPreview,
sourceColor: computed(() => preview.value ? '' : 'primary'), sourceClass: computed(() => preview.value ? unselected : selected),
previewColor: computed(() => preview.value ? 'primary' : '') previewClass: computed(() => preview.value ? selected : unselected)
} }
} }
}) })
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
textarea .md-edit
width: 100% width: 100%
// When wrapping this with Bootstrap's floating label, it shrinks the input down to what a normal one-line input
// would be; this overrides that for the textarea in this component specifically
height: inherit !important
</style> </style>

View File

@ -1,8 +1,10 @@
<template> <template>
<p> <footer>
Jobs, Jobs, Jobs v{{appVersion}} &bull; <router-link to="/privacy-policy">Privacy Policy</router-link> <p class="text-muted">
&bull; <router-link to="/terms-of-service">Terms of Service</router-link> Jobs, Jobs, Jobs v{{appVersion}} &bull; <router-link to="/privacy-policy">Privacy Policy</router-link>
</p> &bull; <router-link to="/terms-of-service">Terms of Service</router-link>
</p>
</footer>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -24,15 +26,12 @@ export default defineComponent({
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
footer
display: flex
flex-direction: row-reverse
p p
padding-top: 2rem padding-top: 2rem
color: rgba(0, 0, 0, .4) padding-right: .5rem
font-style: italic font-style: italic
font-size: .8rem font-size: .8rem
a:link,
a:visited
color: rgba(0, 0, 0, .4)
text-decoration: none
a:hover
text-decoration: underline
</style> </style>

View File

@ -1,21 +1,21 @@
<template> <template>
<aside> <aside class="collapse show p-3">
<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>&nbsp;</p> <p>&nbsp;</p>
<nav> <nav>
<template v-if="isLoggedOn"> <template v-if="isLoggedOn">
<router-link to="/citizen/dashboard"><v-icon icon="mdi-view-dashboard-variant" />Dashboard</router-link> <router-link to="/citizen/dashboard"><icon icon="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"><icon icon="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"><icon icon="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"><icon icon="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"><icon icon="logout-variant" /> Log Off</router-link>
</template> </template>
<template v-else> <template v-else>
<router-link to="/"><v-icon icon="mdi-home" /> Home</router-link> <router-link to="/"><icon icon="home" /> Home</router-link>
<router-link to="/profile/seeking"><v-icon icon="mdi-view-list-outline" /> Job Seekers</router-link> <router-link to="/profile/seeking"><icon icon="view-list-outline" /> Job Seekers</router-link>
<router-link to="/citizen/log-on"><v-icon icon="mdi-login-variant" /> Log On</router-link> <router-link to="/citizen/log-on"><icon icon="login-variant" /> Log On</router-link>
</template> </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"><icon icon="help-circle-outline" /> How It Works</router-link>
</nav> </nav>
</aside> </aside>
</template> </template>
@ -39,13 +39,18 @@ export default defineComponent({
<style lang="sass" scoped> <style lang="sass" scoped>
aside aside
background-image: linear-gradient(180deg, darkgreen 0%, green 70%)
color: white color: white
margin: 1rem
font-size: 1.2rem font-size: 1.2rem
height: 100vh
width: 250px
min-width: 250px
position: sticky
top: 0
a:link, a:visited a:link, a:visited
text-decoration: none text-decoration: none
color: white color: white
font-weight: 500 // font-weight: 500
.home-link .home-link
font-size: 1.2rem font-size: 1.2rem
text-align: center text-align: center

View File

@ -1,5 +1,10 @@
<template> <template>
<p>(...and Jobs &ndash; <audio-clip clip="pelosi-jobs">Let's Vote for Jobs!</audio-clip>)</p> <nav class="navbar navbar-light bg-light">
<span></span>
<span class="navbar-text">
(...and Jobs &ndash; <audio-clip clip="pelosi-jobs">Let's Vote for Jobs!</audio-clip>)
</span>
</nav>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -15,9 +20,8 @@ export default defineComponent({
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
p span
width: 100%
text-align: right
font-style: italic font-style: italic
padding: 0 .5rem 0 0 padding-right: 1rem
// padding: 0 .5rem 0 0
</style> </style>

View File

@ -1,56 +1,62 @@
<template> <template>
<form> <form class="container">
<v-container> <div class="row">
<v-row> <div class="col col-xs-12 col-sm-6 col-md-4 col-lg-3">
<v-col cols="12" sm="6" md="4" lg="3"> <div class="form-floating">
<label for="continentId" class="jjj-label">Continent</label> <select id="continentId" class="form-select" :value="criteria.continentId"
<select id="continentId" class="form-control form-control-sm" @change="updateValue('continentId', $event.target.value)">
:value="criteria.continentId" @change="updateValue('continentId', $event.target.value)">
<option value="">&ndash; Any &ndash;</option> <option value="">&ndash; Any &ndash;</option>
<option v-for="c in continents" :key="c.id" :value="c.id">{{c.name}}</option> <option v-for="c in continents" :key="c.id" :value="c.id">{{c.name}}</option>
</select> </select>
</v-col> <label for="continentId">Continent</label>
<v-col cols="12" sm="6" md="4" lg="3"> </div>
<label for="region" class="jjj-label">Region</label> </div>
<div class="col col-xs-12 col-sm-6 col-md-4 col-lg-3">
<div class="form-floating">
<input type="text" id="region" class="form-control form-control-sm" placeholder="(free-form text)" <input type="text" id="region" class="form-control form-control-sm" placeholder="(free-form text)"
:value="criteria.region" @input="updateValue('region', $event.target.value)"> :value="criteria.region" @input="updateValue('region', $event.target.value)">
</v-col> <label for="region">Region</label>
<v-col cols="12" sm="6" offset-md="2" lg="3" offset-lg="0"> </div>
<label class="jjj-label">Seeking Remote Work?</label><br> <div class="form-text">(free-form text)</div>
<div class="form-check form-check-inline"> </div>
<input type="radio" id="remoteNull" name="remoteWork" class="form-check-input" <div class="col col-xs-12 col-sm-6 col-offset-md-2 col-lg-3 col-offset-lg-0">
:checked="criteria.remoteWork === ''" @click="updateValue('remoteWork', '')"> <label class="jjj-label">Seeking Remote Work?</label><br>
<label for="remoteNull" class="form-check-label">No Selection</label> <div class="form-check form-check-inline">
</div> <input type="radio" id="remoteNull" name="remoteWork" class="form-check-input"
<div class="form-check form-check-inline"> :checked="criteria.remoteWork === ''" @click="updateValue('remoteWork', '')">
<input type="radio" id="remoteYes" name="remoteWork" class="form-check-input" <label for="remoteNull" class="form-check-label">No Selection</label>
:checked="criteria.remoteWork === 'yes'" @click="updateValue('remoteWork', 'yes')"> </div>
<label for="remoteYes" class="form-check-label">Yes</label> <div class="form-check form-check-inline">
</div> <input type="radio" id="remoteYes" name="remoteWork" class="form-check-input"
<div class="form-check form-check-inline"> :checked="criteria.remoteWork === 'yes'" @click="updateValue('remoteWork', 'yes')">
<input type="radio" id="remoteNo" name="remoteWork" class="form-check-input" <label for="remoteYes" class="form-check-label">Yes</label>
:checked="criteria.remoteWork === 'no'" @click="updateValue('remoteWork', 'no')"> </div>
<label for="remoteNo" class="form-check-label">No</label> <div class="form-check form-check-inline">
</div> <input type="radio" id="remoteNo" name="remoteWork" class="form-check-input"
</v-col> :checked="criteria.remoteWork === 'no'" @click="updateValue('remoteWork', 'no')">
<v-col cols="12" sm="6" lg="3"> <label for="remoteNo" class="form-check-label">No</label>
<label for="skillSearch" class="jjj-label">Skill</label> </div>
</div>
<div class="col col-xs-12 col-sm-6 col-lg-3">
<div class="form-floating">
<input type="text" id="skillSearch" class="form-control form-control-sm" placeholder="(free-form text)" <input type="text" id="skillSearch" class="form-control form-control-sm" placeholder="(free-form text)"
:value="criteria.skill" @input="updateValue('skill', $event.target.value)"> :value="criteria.skill" @input="updateValue('skill', $event.target.value)">
</v-col> <label for="skillSearch">Skill</label>
</v-row> </div>
<v-row> <div class="form-text">(free-form text)</div>
<v-col cols="12"> </div>
<br> </div>
<v-btn type="submit" color="primary" variant="outlined" @click.prevent="$emit('search')">Search</v-btn> <div class="row">
</v-col> <div class="col col-xs-12">
</v-row> <br>
</v-container> <button type="submit" class="btn btn-outline-primary" @click.prevent="$emit('search')">Search</button>
</div>
</div>
</form> </form>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, onMounted } from 'vue' import { computed, defineComponent, onMounted, ref, Ref } from 'vue'
import { PublicSearch } from '@/api' import { PublicSearch } from '@/api'
import { useStore } from '@/store' import { useStore } from '@/store'
@ -67,7 +73,7 @@ export default defineComponent({
const store = useStore() const store = useStore()
/** The initial search criteria passed; this is what we'll update and emit when data changes */ /** The initial search criteria passed; this is what we'll update and emit when data changes */
const criteria : PublicSearch = { ...props.modelValue as PublicSearch } const criteria : Ref<PublicSearch> = ref({ ...props.modelValue as PublicSearch })
/** Make sure we have continents */ /** Make sure we have continents */
onMounted(async () => await store.dispatch('ensureContinents')) onMounted(async () => await store.dispatch('ensureContinents'))
@ -75,7 +81,10 @@ export default defineComponent({
return { return {
criteria, criteria,
continents: computed(() => store.state.continents), continents: computed(() => store.state.continents),
updateValue: (key : string, value : string) => emit('update:modelValue', { ...criteria, [key]: value }) updateValue: (key : string, value : string) => {
criteria.value = { ...criteria.value, [key]: value }
emit('update:modelValue', criteria.value)
}
} }
} }
}) })

View File

@ -1,56 +1,62 @@
<template> <template>
<form> <form class="container">
<v-container> <div class="row">
<v-row> <div class="col col-xs-12 col-sm-6 col-md-4 col-lg-3">
<v-col cols="12" sm="6" md="4" lg="3"> <div class="form-floating">
<label for="continentId" class="jjj-label">Continent</label> <select id="continentId" class="form-select"
<select id="continentId" class="form-control form-control-sm"
:value="criteria.continentId" @change="updateValue('continentId', $event.target.value)"> :value="criteria.continentId" @change="updateValue('continentId', $event.target.value)">
<option value="">&ndash; Any &ndash;</option> <option value="">&ndash; Any &ndash;</option>
<option v-for="c in continents" :key="c.id" :value="c.id">{{c.name}}</option> <option v-for="c in continents" :key="c.id" :value="c.id">{{c.name}}</option>
</select> </select>
</v-col> <label for="continentId">Continent</label>
<v-col cols="12" sm="6" offset-md="2" lg="3" offset-lg="0"> </div>
<label class="jjj-label">Seeking Remote Work?</label><br> </div>
<div class="form-check form-check-inline"> <div class="col col-xs-12 col-sm-6 col-offset-md-2 col-lg-3 col-offset-lg-0">
<input type="radio" id="remoteNull" name="remoteWork" class="form-check-input" <label class="jjj-label">Seeking Remote Work?</label><br>
:checked="criteria.remoteWork === ''" @click="updateValue('remoteWork', '')"> <div class="form-check form-check-inline">
<label for="remoteNull" class="form-check-label">No Selection</label> <input type="radio" id="remoteNull" name="remoteWork" class="form-check-input"
</div> :checked="criteria.remoteWork === ''" @click="updateValue('remoteWork', '')">
<div class="form-check form-check-inline"> <label for="remoteNull" class="form-check-label">No Selection</label>
<input type="radio" id="remoteYes" name="remoteWork" class="form-check-input" </div>
:checked="criteria.remoteWork === 'yes'" @click="updateValue('remoteWork', 'yes')"> <div class="form-check form-check-inline">
<label for="remoteYes" class="form-check-label">Yes</label> <input type="radio" id="remoteYes" name="remoteWork" class="form-check-input"
</div> :checked="criteria.remoteWork === 'yes'" @click="updateValue('remoteWork', 'yes')">
<div class="form-check form-check-inline"> <label for="remoteYes" class="form-check-label">Yes</label>
<input type="radio" id="remoteNo" name="remoteWork" class="form-check-input" </div>
:checked="criteria.remoteWork === 'no'" @click="updateValue('remoteWork', 'no')"> <div class="form-check form-check-inline">
<label for="remoteNo" class="form-check-label">No</label> <input type="radio" id="remoteNo" name="remoteWork" class="form-check-input"
</div> :checked="criteria.remoteWork === 'no'" @click="updateValue('remoteWork', 'no')">
</v-col> <label for="remoteNo" class="form-check-label">No</label>
<v-col cols="12" sm="6" lg="3"> </div>
<label for="skillSearch" class="jjj-label">Skill</label> </div>
<input type="text" id="skillSearch" class="form-control form-control-sm" placeholder="(free-form text)" <div class="col col-xs-12 col-sm-6 col-lg-3">
<div class="form-floating">
<input type="text" id="skillSearch" class="form-control" placeholder="(free-form text)"
:value="criteria.skill" @input="updateValue('skill', $event.target.value)"> :value="criteria.skill" @input="updateValue('skill', $event.target.value)">
</v-col> <label for="skillSearch" class="jjj-label">Skill</label>
<v-col cols="12" sm="6" lg="3"> </div>
<label for="bioSearch" class="jjj-label">Bio / Experience</label> <div class="form-text">(free-form text)</div>
<input type="text" id="bioSearch" class="form-control form-control-sm" placeholder="(free-form text)" </div>
<div class="col col-xs-12 col-sm-6 col-lg-3">
<div class="form-floating">
<input type="text" id="bioSearch" class="form-control" placeholder="(free-form text)"
:value="criteria.bioExperience" @input="updateValue('bioExperience', $event.target.value)"> :value="criteria.bioExperience" @input="updateValue('bioExperience', $event.target.value)">
</v-col> <label for="bioSearch" class="jjj-label">Bio / Experience</label>
</v-row> </div>
<v-row> <div class="form-text">(free-form text)</div>
<v-col cols="12"> </div>
<br> </div>
<v-btn type="submit" color="primary" variant="outlined" @click.prevent="$emit('search')">Search</v-btn> <div class="row">
</v-col> <div class="col col-xs-12">
</v-row> <br>
</v-container> <button type="submit" class="btn btn-outline-primary" @click.prevent="$emit('search')">Search</button>
</div>
</div>
</form> </form>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, onMounted } from 'vue' import { computed, defineComponent, onMounted, Ref, ref } from 'vue'
import { ProfileSearch } from '@/api' import { ProfileSearch } from '@/api'
import { useStore } from '@/store' import { useStore } from '@/store'
@ -67,7 +73,7 @@ export default defineComponent({
const store = useStore() const store = useStore()
/** The initial search criteria passed; this is what we'll update and emit when data changes */ /** The initial search criteria passed; this is what we'll update and emit when data changes */
const criteria : ProfileSearch = { ...props.modelValue as ProfileSearch } const criteria : Ref<ProfileSearch> = ref({ ...props.modelValue as ProfileSearch })
/** Make sure we have continents */ /** Make sure we have continents */
onMounted(async () => await store.dispatch('ensureContinents')) onMounted(async () => await store.dispatch('ensureContinents'))
@ -75,7 +81,10 @@ export default defineComponent({
return { return {
criteria, criteria,
continents: computed(() => store.state.continents), continents: computed(() => store.state.continents),
updateValue: (key : string, value : string) => emit('update:modelValue', { ...criteria, [key]: value }) updateValue: (key : string, value : string) => {
criteria.value = { ...criteria.value, [key]: value }
emit('update:modelValue', criteria.value)
}
} }
} }
}) })

View File

@ -1,26 +1,33 @@
<template> <template>
<v-row> <div class="row pb-3">
<v-col cols="2" md="1"> <div class="col col-xs-2 col-md-1 align-self-center">
<br> <button class="btn btn-sm btn-outline-danger rounded-pill" title="Delete" @click.prevent="$emit('remove')">
<v-btn color="danger" variant="outlined" title="Delete" @click="$emit('remove')">&minus;</v-btn> &nbsp;&minus;&nbsp;
</v-col> </button>
<v-col cols="10" md="6"> </div>
<label :for="`skillDesc${skill.id}`" class="jjj-label">Skill</label> <div class="col col-xs-10 col-md-6">
<input type="text" :id="`skillDesc${skill.id}`" maxlength="100" <div class="form-floating">
placeholder="A skill (language, design technique, process, etc.)" <input type="text" :id="`skillDesc${skill.id}`" class="form-control" maxlength="100"
:value="skill.description" @input="updateValue('description', $event.target.value)"> placeholder="A skill (language, design technique, process, etc.)"
</v-col> :value="skill.description" @input="updateValue('description', $event.target.value)">
<v-col cols="12" md="5"> <label :for="`skillDesc${skill.id}`" class="jjj-label">Skill</label>
<label :for="`skillNotes${skill.id}`" class="jjj-label">Notes</label> </div>
<input type="text" :id="`skillNotes${skill.id}`" maxlength="100" <div class="form-text">A skill (language, design technique, process, etc.)</div>
placeholder="A further description of the skill (100 characters max)" </div>
:value="skill.notes" @input="updateValue('notes', $event.target.value)"> <div class="col col-xs-12 col-md-5">
</v-col> <div class="form-floating">
</v-row> <input type="text" :id="`skillNotes${skill.id}`" class="form-control" maxlength="100"
placeholder="A further description of the skill (100 characters max)"
:value="skill.notes" @input="updateValue('notes', $event.target.value)">
<label :for="`skillNotes${skill.id}`" class="jjj-label">Notes</label>
</div>
<div class="form-text">A further description of the skill (100 characters max)</div>
</div>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent, Ref, ref } from 'vue'
import { Skill } from '@/api' import { Skill } from '@/api'
export default defineComponent({ export default defineComponent({
@ -34,11 +41,14 @@ export default defineComponent({
emits: ['remove', 'update:modelValue'], emits: ['remove', 'update:modelValue'],
setup (props, { emit }) { setup (props, { emit }) {
/** The skill being edited */ /** The skill being edited */
const skill : Skill = { ...props.modelValue as Skill } const skill : Ref<Skill> = ref({ ...props.modelValue as Skill })
return { return {
skill, skill,
updateValue: (key : string, value : string) => emit('update:modelValue', { ...skill, [key]: value }) updateValue: (key : string, value : string) => {
skill.value = { ...skill.value, [key]: value }
emit('update:modelValue', skill.value)
}
} }
} }
}) })

View File

@ -1,15 +1,15 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import vuetify from './plugins/vuetify'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
import store, { key } from './store' import store, { key } from './store'
import Icon from './components/Icon.vue'
import PageTitle from './components/PageTitle.vue' import PageTitle from './components/PageTitle.vue'
const app = createApp(App) const app = createApp(App)
.use(router) .use(router)
.use(store, key) .use(store, key)
.use(vuetify)
app.component('Icon', Icon)
app.component('PageTitle', PageTitle) app.component('PageTitle', PageTitle)
app.mount('#app') app.mount('#app')

View File

@ -1,48 +0,0 @@
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/lib/styles/main.sass'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/lib/components'
import * as directives from 'vuetify/lib/directives'
const jjjTheme = {
dark: false,
colors: {
background: '#ffffff',
surface: '#ffffff',
primary: '#007bff',
'primary-darken-1': '#3700b3',
secondary: '#f7f7f7',
'secondary-darken-1': '#018786',
error: '#b00020',
info: '#2196f3',
success: '#4caf50',
warning: '#fb8c00'
},
variables: {
'border-color': '#000000',
'border-opacity': 0.12,
'high-emphasis-opacity': 0.87,
'medium-emphasis-opacity': 0.60,
'disabled-opacity': 0.38,
'activated-opacity': 0.12,
'hover-opacity': 0.04,
'focus-opacity': 0.12,
'selected-opacity': 0.08,
'dragged-opacity': 0.08,
'pressed-opacity': 0.16,
'kbd-background-color': '#212529',
'kbd-color': '#FFFFFF',
'code-background-color': '#C2C2C2'
}
}
export default createVuetify({
components,
directives,
theme: {
defaultTheme: 'jjjTheme',
themes: {
jjjTheme
}
}
})

View File

@ -1,6 +1,7 @@
<template> <template>
<article> <article>
<page-title title="Welcome!" /> <page-title title="Welcome!" />
<p>&nbsp;</p>
<p> <p>
Welcome to Jobs, Jobs, Jobs (AKA No Agenda Careers), where citizens of Gitmo Nation can assist one another in Welcome to Jobs, Jobs, Jobs (AKA No Agenda Careers), where citizens of Gitmo Nation can assist one another in
finding employment. This will enable them to continue providing value-for-value to Adam and John, as they continue finding employment. This will enable them to continue providing value-for-value to Adam and John, as they continue

View File

@ -1,6 +1,7 @@
<template> <template>
<article> <article>
<page-title title="Logging on..." /> <page-title title="Logging on..." />
<p>&nbsp;</p>
<p v-html="message"></p> <p v-html="message"></p>
</article> </article>
</template> </template>

View File

@ -1,19 +1,15 @@
<template> <template>
<article> <article class="container">
<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">
<v-row class="spaced"> <div class="row row-cols-1 row-cols-md-2">
<v-col cols="12" md="6"> <div class="col">
<v-card elevation="6"> <div class="card h-100">
<v-card-header> <h5 class="card-header">Your Profile</h5>
<v-card-header-text> <div class="card-body">
<v-card-title>Your Profile</v-card-title> <h6 class="card-subtitle mb-3 text-muted">Last updated <full-date :date="profile.lastUpdatedOn" /></h6>
<v-card-subtitle>Last updated <full-date-time :date="profile.lastUpdatedOn" /></v-card-subtitle> <p v-if="profile" class="card-text">
</v-card-header-text>
</v-card-header>
<v-card-text>
<div v-if="profile">
Your profile currently lists {{profile.skills.length}} Your profile currently lists {{profile.skills.length}}
skill<template v-if="profile.skills.length !== 1">s</template>. skill<template v-if="profile.skills.length !== 1">s</template>.
<span v-if="profile.seekingEmployment"> <span v-if="profile.seekingEmployment">
@ -21,51 +17,48 @@
Your profile indicates that you are seeking employment. Once you find it, 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> <router-link to="/success-story/add">tell your fellow citizens about it!</router-link>
</span> </span>
</div> </p>
<div v-else> <p v-else class="card-text">
You do not have an employment profile established; click below (or &ldquo;Edit Profile&rdquo; in the You do not have an employment profile established; click below (or &ldquo;Edit Profile&rdquo; in the
menu) to get started! menu) to get started!
</div> </p>
</v-card-text> </div>
<v-card-actions> <div class="card-footer">
<template v-if="profile"> <template v-if="profile">
<v-btn v-if="profile" @click="viewProfile">View Profile</v-btn> <button class="btn btn-outline-secondary" @click="viewProfile">View Profile</button> &nbsp; &nbsp;
<v-btn @click="editProfile">Edit Profile</v-btn> <button class="btn btn-outline-secondary" @click="editProfile">Edit Profile</button>
</template> </template>
<v-btn v-else @click="editProfile">Create Profile</v-btn> <button v-else class="btn btn-primary" @click="editProfile">Create Profile</button>
</v-card-actions> </div>
</v-card> </div>
</v-col> </div>
<v-col cols="12" md="6"> <div class="col">
<v-card elevation="6"> <div class="card h-100">
<v-card-header> <h5 class="card-header">Other Citizens</h5>
<v-card-header-text> <div class="card-body">
<v-card-title>Other Citizens</v-card-title> <h6 class="card-subtitle mb-3 text-muted">
<v-card-subtitle> <template v-if="profileCount === 0">No</template><template v-else>{{profileCount}} Total</template>
<template v-if="profileCount === 0">No</template><template v-else>{{profileCount}} Total</template> Employment Profile<template v-if="profileCount !== 1">s</template>
Employment Profile<template v-if="profileCount !== 1">s</template> </h6>
</v-card-subtitle> <p v-if="profileCount === 1 && profile" class="card-text">
</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; It looks like, for now, it&rsquo;s just you&hellip;
</div> </p>
<div v-else-if="profileCount > 0"> <p v-else-if="profileCount > 0" class="card-text">
Take a look around and see if you can help them find work! Take a look around and see if you can help them find work!
</div> </p>
<div v-else> <p v-else class="card-text">
You can click below, but you will not find anything&hellip; You can click below, but you will not find anything&hellip;
</div> </p>
</v-card-text> </div>
<v-card-actions> <div class="card-footer">
<v-btn @click="searchProfiles">Search Profiles</v-btn> <button class="btn btn-outline-secondary" @click="searchProfiles">Search Profiles</button>
</v-card-actions> </div>
</v-card> </div>
</v-col> </div>
</v-row> </div>
</load-data> </load-data>
<p class="spaced"> <p>&nbsp;</p>
<p>
To see how this application works, check out &ldquo;How It Works&rdquo; in the sidebar (last updated June To see how this application works, check out &ldquo;How It Works&rdquo; in the sidebar (last updated June
14<sup>th</sup>, 2021). 14<sup>th</sup>, 2021).
</p> </p>
@ -77,14 +70,15 @@ import { 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 { useStore } from '@/store' import { useStore } from '@/store'
import FullDateTime from '@/components/FullDateTime.vue'
import FullDate from '@/components/FullDate.vue'
import LoadData from '@/components/LoadData.vue' import LoadData from '@/components/LoadData.vue'
export default defineComponent({ export default defineComponent({
name: 'Dashboard', name: 'Dashboard',
components: { components: {
LoadData, FullDate,
FullDateTime LoadData
}, },
setup () { setup () {
const store = useStore() const store = useStore()
@ -126,8 +120,3 @@ export default defineComponent({
} }
}) })
</script> </script>
<style lang="sass" scoped>
.spaced
margin-top: 1rem
</style>

View File

@ -4,104 +4,103 @@
<h3>Employment Profile</h3> <h3>Employment Profile</h3>
<load-data :load="retrieveData"> <load-data :load="retrieveData">
<form> <form>
<v-container> <div class="row pb-3">
<v-row> <div class="col col-xs-12 col-sm-10 col-md-8 col-lg-6">
<v-col cols="12" sm="10" md="8" lg="6"> <div class="form-floating">
<label for="realName">Real Name</label> <input type="text" id="realName" class="form-control" v-model="profile.realName" maxlength="255"
<input type="text" id="realName" v-model="profile.realName" maxlength="255"
placeholder="Leave blank to use your NAS display name"> placeholder="Leave blank to use your NAS display name">
</v-col> <label for="realName">Real Name</label>
</v-row> </div>
<v-row> <div class="form-text">Leave blank to use your NAS display name</div>
<v-col> </div>
<label> </div>
<input type="checkbox" v-model="profile.seekingEmployment"> <div class="row pb-3">
I am currently seeking employment <div class="col col-xs-12">
</label> <div class="form-check">
<em v-if="profile?.seekingEmployment">&nbsp; &nbsp; If you have found employment, consider <input type="checkbox" class="form-check-input" v-model="profile.seekingEmployment">
<router-link to="/success-story/add">telling your fellow citizens about it</router-link> <label class="form-check-label">I am currently seeking employment</label>
</em> </div>
</v-col> <p v-if="profile?.seekingEmployment">
</v-row> <em>If you have found employment, consider <router-link to="/success-story/add">telling your fellow
<v-row> citizens about it!</router-link></em>
<v-col cols="12" sm="6" md="4"> </p>
<label for="continentId" class="jjj-required">Continent</label> </div>
<select id="continentId"> </div>
<option v-for="c in continents" :key="c.id" :value="c.id" <div class="row pb-3">
:selected="c.id === profile?.continentId ? 'selected' : null">{{c.name}}</option> <div class="col col-xs-12 col-sm-6 col-md-4">
<div class="form-floating">
<select id="continentId" class="form-select" :value="profile.continentId">
<option v-for="c in continents" :key="c.id" :value="c.id">{{c.name}}</option>
</select> </select>
</v-col> <label for="continentId" class="jjj-required">Continent</label>
<v-col cols="12" sm="6" md="8"> </div>
<label for="region" class="jjj-required">Region</label> </div>
<input type="text" id="region" v-model="profile.region" maxlength="255" <div class="col col-xs-12 col-sm-6 col-md-8">
<div class="form-floating">
<input type="text" id="region" class="form-control" v-model="profile.region" maxlength="255"
placeholder="Country, state, geographic area, etc."> placeholder="Country, state, geographic area, etc.">
</v-col> <label for="region" class="jjj-required">Region</label>
</v-row> </div>
<v-row> <div class="form-text">Country, state, geographic area, etc.</div>
<v-col> </div>
<label for="bio" class="jjj-required">Professional Biography</label> </div>
<markdown-editor id="bio" v-model:text="profile.biography" /> <markdown-editor id="bio" label="Professional Biography" v-model:text="profile.biography" />
</v-col> <div class="row pb-3">
</v-row> <div class="col col-xs-12 col-offset-md-2 col-md-4">
<v-row> <div class="form-check">
<v-col cols="12" sm="12" offset-md="2" md="4"> <input type="checkbox" id="isRemote" class="form-check-input" v-model="profile.remoteWork">
<label> <label class="form-check-label" for="isRemote">I am looking for remote work</label>
<input type="checkbox" v-model="profile.remoteWork"> </div>
I am looking for remote work </div>
</label> <div class="col col-xs-12 col-md-4">
</v-col> <div class="form-check">
<v-col cols="12" sm="12" md="4"> <input type="checkbox" id="isFullTime" class="form-check-input" v-model="profile.fullTime">
<label> <label class="form-check-label" for="isFullTime">I am looking for full-time work</label>
<input type="checkbox" v-model="profile.fullTime"> </div>
I am looking for full-time work </div>
</label> </div>
</v-col> <hr>
</v-row> <h4 class="pb-2">
<hr> Skills &nbsp;
<h4> <button class="btn btn-sm btn-outline-primary rounded-pill" @click.prevent="addSkill">Add a Skill</button>
Skills &nbsp; </h4>
<v-btn color="primary" variant="outlined" @click="addSkill">Add a Skill</v-btn> <profile-skill-edit v-for="(skill, idx) in profile.skills" :key="skill.id" v-model="profile.skills[idx]"
</h4> @remove="removeSkill(skill.id)" />
<profile-skill-edit v-for="(skill, idx) in profile.skills" :key="skill.id" v-model="profile.skills[idx]" <hr>
@remove="removeSkill(skill.id)" /> <h4>Experience</h4>
<hr> <p>
<h4>Experience</h4> This application does not have a place to individually list your chronological job history; however, you can
<p> use this area to list prior jobs, their dates, and anything else you want to include that&rsquo;s not
This application does not have a place to individually list your chronological job history; however, you can already a part of your Professional Biography above.
use this area to list prior jobs, their dates, and anything else you want to include that&rsquo;s not </p>
already a part of your Professional Biography above. <markdown-editor id="experience" label="Experience" v-model:text="profile.experience" />
</p> <div class="row pb-3">
<v-row> <div class="col col-xs-12">
<v-col> <div class="form-check">
<markdown-editor id="experience" v-model:text="profile.experience" /> <input type="checkbox" id="isPublic" class="form-check-input" v-model="profile.isPublic">
</v-col> <label class="form-check-label" for="isPublic">
</v-row>
<v-row>
<v-col>
<label>
<input type="checkbox" v-model="profile.isPublic">
Allow my profile to be searched publicly (outside NA Social) Allow my profile to be searched publicly (outside NA Social)
</label> </label>
</v-col> </div>
</v-row> </div>
<v-row> </div>
<v-col> <div class="row pt-3">
<br> <div class="col col-xs-12">
<v-btn text color="primary">Save</v-btn> <button class="btn btn-primary">Save</button>
</v-col> <template v-if="!isNew">
</v-row> &nbsp; &nbsp;
</v-container> <button class="btn btn-outline-secondary" @click.prevent="viewProfile">
<icon icon="file-account-outline" />&nbsp; View Your User Profile
</button>
</template>
</div>
</div>
</form> </form>
<p v-if="!isNew">
<br>
<v-btn color="primary" @click="viewProfile">
<v-icon icon="mdi-file-account-outline" />&nbsp; View Your User Profile
</v-btn>
</p>
</load-data> </load-data>
<p> <hr>
<br>If you want to delete your profile, or your entire account, <router-link to="/so-long/options">see your <p class="text-muted fst-italic">
deletion options here</router-link>. (If you want to delete your profile, or your entire account, <router-link to="/so-long/options">see your deletion
options here</router-link>.)
</p> </p>
</article> </article>
</template> </template>

View File

@ -1,7 +1,8 @@
<template> <template>
<article> <article>
<page-title title="Logging off..." /> <page-title title="Logging off..." />
<p>Logging off&hellip;</p> <p>&nbsp;</p>
<p class="fst-italic">Logging off&hellip;</p>
</article> </article>
</template> </template>

View File

@ -1,5 +1,8 @@
<template> <template>
<p><em>Sending you over to No Agenda Social to log on; see you back in just a second&hellip;</em></p> <article>
<p>&nbsp;</p>
<p class="fst-italic">Sending you over to No Agenda Social to log on; see you back in just a second&hellip;</p>
</article>
</template> </template>
<script lang="ts"> <script lang="ts">

View File

@ -26,7 +26,7 @@
<template v-if="user.citizenId === it.citizen.id"> <template v-if="user.citizenId === it.citizen.id">
<br><br> <br><br>
<v-btn color="primary" @click="editProfile"><v-icon icon="mdi-pencil" />&nbsp; Edit Your Profile</v-btn> <button class="btn btn-primary" @click="editProfile"><icon icon="pencil" />&nbsp; Edit Your Profile</button>
</template> </template>
</load-data> </load-data>
</article> </article>

View File

@ -12,7 +12,7 @@
use if you want to clear out your profile and start again (and remove the current one from others&rsquo; view). use if you want to clear out your profile and start again (and remove the current one from others&rsquo; view).
</p> </p>
<p class="text-center"> <p class="text-center">
<v-btn color="error" @click="deleteProfile">Delete Your Profile</v-btn> <button class="btn btn-danger" @click.prevent="deleteProfile">Delete Your Profile</button>
</p> </p>
<hr> <hr>
@ -32,7 +32,7 @@
</em> </em>
</p> </p>
<p class="text-center"> <p class="text-center">
<v-btn color="error" @click="deleteAccount">Delete Your Entire Account</v-btn> <button class="btn btn-danger" @click.prevent="deleteAccount">Delete Your Entire Account</button>
</p> </p>
</article> </article>
</template> </template>

View File

@ -39,14 +39,15 @@
import { defineComponent, ref, Ref } from 'vue' import { defineComponent, ref, Ref } from 'vue'
import api, { LogOnSuccess, StoryEntry } from '@/api' import api, { LogOnSuccess, StoryEntry } from '@/api'
import { useStore } from '@/store' import { useStore } from '@/store'
import FullDate from '@/components/FullDate.vue' import FullDate from '@/components/FullDate.vue'
import LoadData from '@/components/LoadData.vue' import LoadData from '@/components/LoadData.vue'
export default defineComponent({ export default defineComponent({
name: 'StoryList', name: 'StoryList',
components: { components: {
LoadData, FullDate,
FullDate LoadData
}, },
setup () { setup () {
const store = useStore() const store = useStore()