Add/Edit request works

No longer a modal (#20)
This commit is contained in:
Daniel J. Summers 2018-08-17 20:59:57 -05:00
parent c0dd6b5dd6
commit d3aff4a110
8 changed files with 135 additions and 85 deletions

View File

@ -26,7 +26,7 @@ module Error =
/// Handle 404s from the API, sending known URL paths to the Vue app so that they can be handled there /// Handle 404s from the API, sending known URL paths to the Vue app so that they can be handled there
let notFound : HttpHandler = let notFound : HttpHandler =
fun next ctx -> fun next ctx ->
[ "/answered"; "/journal"; "/snoozed"; "/user" ] [ "/answered"; "/journal"; "/legal"; "/request"; "/snoozed"; "/user" ]
|> List.filter ctx.Request.Path.Value.StartsWith |> List.filter ctx.Request.Path.Value.StartsWith
|> List.length |> List.length
|> function |> function

View File

@ -61,8 +61,17 @@ a[role="button"] {
border-radius: .5rem; border-radius: .5rem;
background-color: whitesmoke; background-color: whitesmoke;
} }
a[role="button"] {
padding: .25rem;
}
button.primary,
a[role="button"].primary {
background-color: white;
border-width: 3px;
}
button:hover, button:hover,
a[role="button"]:hover { a[role="button"]:hover {
cursor: pointer;
background-color: #050; background-color: #050;
color: white; color: white;
text-decoration: none; text-decoration: none;
@ -132,4 +141,7 @@ a:hover {
margin-left: 1rem; margin-left: 1rem;
margin-right: 1rem; margin-right: 1rem;
} }
.material-icons {
vertical-align: middle;
}
</style> </style>

View File

@ -31,7 +31,7 @@ export default {
* Add a new prayer request * Add a new prayer request
* @param {string} requestText The text of the request to be added * @param {string} requestText The text of the request to be added
*/ */
addRequest: requestText => http.post('request', { requestText }), addRequest: requestText => http.post('request', { requestText, recurType: 'immediate' }),
/** /**
* Get all answered requests, along with the text they had when it was answered * Get all answered requests, along with the text they had when it was answered

View File

@ -3,7 +3,10 @@ article.mpj-main-content-wide(role='main')
page-title(:title='title') page-title(:title='title')
p(v-if='isLoadingJournal') Loading your prayer journal... p(v-if='isLoadingJournal') Loading your prayer journal...
template(v-else) template(v-else)
new-request router-link(:to="{ name: 'EditRequest', params: { id: 'new' } }"
role='button')
md-icon(icon='add_box')
| &nbsp; Add a New Request
br br
.mpj-journal(v-if='journal.length > 0') .mpj-journal(v-if='journal.length > 0')
request-card(v-for='request in journal' request-card(v-for='request in journal'
@ -13,8 +16,6 @@ article.mpj-main-content-wide(role='main')
:toast='toast') :toast='toast')
p.text-center(v-else): em. p.text-center(v-else): em.
No requests found; click the &ldquo;Add a New Request&rdquo; button to add one No requests found; click the &ldquo;Add a New Request&rdquo; button to add one
edit-request(:events='eventBus'
:toast='toast')
notes-edit(:events='eventBus' notes-edit(:events='eventBus'
:toast='toast') :toast='toast')
snooze-request(:events='eventBus' snooze-request(:events='eventBus'
@ -27,8 +28,6 @@ article.mpj-main-content-wide(role='main')
import Vue from 'vue' import Vue from 'vue'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import EditRequest from './request/EditRequest'
import NewRequest from './request/NewRequest'
import NotesEdit from './request/NotesEdit' import NotesEdit from './request/NotesEdit'
import RequestCard from './request/RequestCard' import RequestCard from './request/RequestCard'
import SnoozeRequest from './request/SnoozeRequest' import SnoozeRequest from './request/SnoozeRequest'
@ -38,8 +37,6 @@ import actions from '@/store/action-types'
export default { export default {
name: 'journal', name: 'journal',
components: { components: {
EditRequest,
NewRequest,
NotesEdit, NotesEdit,
RequestCard, RequestCard,
SnoozeRequest SnoozeRequest

View File

@ -1,46 +1,62 @@
<template lang="pug"> <template lang="pug">
b-modal(v-model='editVisible' article.mpj-main-content(role='main')
header-bg-variant='mpj' page-title(:title='title')
header-text-variant='light' form.mpj-edit-request-form
size='lg' label(for='request_text') Prayer Request
title='Edit Prayer Request' br
@edit='openDialog()' textarea#request_text(v-model='form.requestText'
@shows='focusRequestText') :rows='10'
b-form @blur='trimText()'
b-form-group(label='Prayer Request' autofocus)
label-for='request_text') br
b-textarea#request_text(ref='toFocus' template(v-if='!isNew')
v-model='form.requestText' label Also Mark As
:rows='10' br
@blur='trimText()') input(type='radio'
b-form-group(label='Also Mark As') id='status_updated'
b-radio-group(v-model='form.status' value='Updated'
buttons) v-model='form.status')
b-radio(value='Updated') Updated label(for='status_updated')= ' Updated'
b-radio(value='Prayed') Prayed input(type='radio'
b-radio(value='Answered') Answered id='status_prayed'
div.w-100.text-right(slot='modal-footer') value='Prayed'
b-btn(variant='primary' v-model='form.status')
@click='saveRequest()') Save label(for='status_prayed')= ' Prayed'
input(type='radio'
id='status_answered'
value='Answered'
v-model='form.status')
label(for='status_answered')= ' Answered'
br(v-else)
div.mpj-edit-request-form.mpj-text-right
button(@click.stop='saveRequest()').primary
md-icon(icon='save')
= ' Save'
| &nbsp; &nbsp; | &nbsp; &nbsp;
b-btn(variant='outline-secondary' button(@click.stop='goBack()')
@click='closeDialog()') Cancel md-icon(icon='arrow_back')
= ' Cancel'
</template> </template>
<script> <script>
'use strict' 'use strict'
import { mapState } from 'vuex'
import actions from '@/store/action-types' import actions from '@/store/action-types'
export default { export default {
name: 'edit-request', name: 'edit-request',
props: { props: {
toast: { required: true }, id: {
events: { required: true } type: String,
required: true
}
}, },
data () { data () {
return { return {
editVisible: false, title: 'Edit Prayer Request',
isNew: false,
form: { form: {
requestId: '', requestId: '',
requestText: '', requestText: '',
@ -48,42 +64,70 @@ export default {
} }
} }
}, },
created () { computed: {
this.events.$on('edit', this.openDialog) toast () {
return this.$parent.$refs.toast
},
...mapState(['journal'])
}, },
methods: { async mounted () {
closeDialog () { if (this.id === 'new') {
this.title = 'Add Prayer Request'
this.isNew = true
this.form.requestId = '' this.form.requestId = ''
this.form.requestText = '' this.form.requestText = ''
this.form.status = 'Created'
} else {
this.title = 'Edit Prayer Request'
this.isNew = false
if (this.journal.length === 0) {
await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress)
}
const req = this.journal.filter(r => r.requestId === this.id)[0]
this.form.requestId = this.id
this.form.requestText = req.text
this.form.status = 'Updated' this.form.status = 'Updated'
this.editVisible = false }
}, },
focusRequestText (e) { methods: {
this.$refs.toFocus.focus() goBack () {
}, this.$router.go(-1)
openDialog (request) {
this.form.requestId = request.requestId
this.form.requestText = request.text
this.editVisible = true
this.focusRequestText(null)
}, },
trimText () { trimText () {
this.form.requestText = this.form.requestText.trim() this.form.requestText = this.form.requestText.trim()
}, },
async saveRequest () { async saveRequest () {
await this.$store.dispatch(actions.UPDATE_REQUEST, { if (this.isNew) {
progress: this.$Progress, await this.$store.dispatch(actions.ADD_REQUEST, {
requestId: this.form.requestId, progress: this.$Progress,
updateText: this.form.requestText, requestText: this.form.requestText
status: this.form.status })
}) this.toast.showToast('New prayer request added', { theme: 'success' })
if (this.form.status === 'Answered') {
this.toast.showToast('Request updated and removed from active journal', { theme: 'success' })
} else { } else {
this.toast.showToast('Request updated', { theme: 'success' }) await this.$store.dispatch(actions.UPDATE_REQUEST, {
progress: this.$Progress,
requestId: this.form.requestId,
updateText: this.form.requestText,
status: this.form.status
})
if (this.form.status === 'Answered') {
this.toast.showToast('Request updated and removed from active journal', { theme: 'success' })
} else {
this.toast.showToast('Request updated', { theme: 'success' })
}
} }
this.closeDialog() this.goBack()
} }
} }
} }
</script> </script>
<style>
.mpj-edit-request-form {
max-width: 40rem;
margin: auto;
}
#request_text {
width: 100%;
}
</style>

View File

@ -1,10 +1,10 @@
<template lang="pug"> <template lang="pug">
.mpj-request-card .mpj-request-card
header.mpj-card-header.mpj-bg(role='toolbar'). header.mpj-card-header(role='toolbar').
#[button.pray(@click='markPrayed()' title='Pray' size='sm'): md-icon(icon='done')] #[button.primary(@click='markPrayed()' title='Pray'): md-icon(icon='done')]
#[button(@click.stop='showEdit()' title='Edit' size='sm'): md-icon(icon='edit')] #[button(@click.stop='showEdit()' title='Edit'): md-icon(icon='edit')]
#[button(@click.stop='showNotes()' title='Add Notes' size='sm'): md-icon(icon='comment')] #[button(@click.stop='showNotes()' title='Add Notes'): md-icon(icon='comment')]
#[button(@click.stop='snooze()' title='Snooze Request' size='sm'): md-icon(icon='schedule')] #[button(@click.stop='snooze()' title='Snooze Request'): md-icon(icon='schedule')]
div div
p.card-text.mpj-request-text p.card-text.mpj-request-text
| {{ request.text }} | {{ request.text }}
@ -42,10 +42,7 @@ export default {
this.toast.showToast('Request marked as prayed', { theme: 'success' }) this.toast.showToast('Request marked as prayed', { theme: 'success' })
}, },
showEdit () { showEdit () {
this.events.$emit('edit', this.request) this.$router.push({ name: 'EditRequest', params: { id: this.request.requestId } })
},
showFull () {
this.events.$emit('full', this.request.requestId)
}, },
showNotes () { showNotes () {
this.events.$emit('notes', this.request) this.events.$emit('notes', this.request)
@ -73,22 +70,15 @@ export default {
display: flex; display: flex;
flex-flow: row; flex-flow: row;
justify-content: center; justify-content: center;
background-image: -webkit-gradient(linear, left top, left bottom, from(lightgray), to(whitesmoke));
background-image: -webkit-linear-gradient(top, lightgray, whitesmoke);
background-image: -moz-linear-gradient(top, lightgray, whitesmoke);
background-image: linear-gradient(to bottom, lightgray, whitesmoke);
} }
.mpj-card-header button { .mpj-card-header button {
background-color: rgba(255, 255, 255, .75);
border-radius: .25rem;
margin: .25rem; margin: .25rem;
border: solid #050 1px;
font-size: .8rem; font-size: .8rem;
} }
.mpj-card-header button:hover {
cursor: pointer;
background-color: white;
color: #050;
}
.mpj-card-header button.pray {
background-color: white;
}
.mpj-request-card .card-text { .mpj-request-card .card-text {
margin-left: 1rem; margin-left: 1rem;
margin-right: 1rem; margin-right: 1rem;

View File

@ -3,6 +3,7 @@ import Router from 'vue-router'
import Answered from '@/components/Answered' import Answered from '@/components/Answered'
import AnsweredDetail from '@/components/AnsweredDetail' import AnsweredDetail from '@/components/AnsweredDetail'
import EditRequest from '@/components/request/EditRequest'
import Home from '@/components/Home' import Home from '@/components/Home'
import Journal from '@/components/Journal' import Journal from '@/components/Journal'
import LogOn from '@/components/user/LogOn' import LogOn from '@/components/user/LogOn'
@ -46,6 +47,12 @@ export default new Router({
name: 'TermsOfService', name: 'TermsOfService',
component: TermsOfService component: TermsOfService
}, },
{
path: '/request/:id/edit',
name: 'EditRequest',
component: EditRequest,
props: true
},
{ {
path: '/snoozed', path: '/snoozed',
name: 'Snoozed', name: 'Snoozed',

View File

@ -9,7 +9,7 @@ import actions from './action-types'
Vue.use(Vuex) Vue.use(Vuex)
this.auth0 = new AuthService() const auth0 = new AuthService()
const logError = function (error) { const logError = function (error) {
if (error.response) { if (error.response) {
@ -34,11 +34,11 @@ export default new Vuex.Store({
state: { state: {
user: JSON.parse(localStorage.getItem('user_profile') || '{}'), user: JSON.parse(localStorage.getItem('user_profile') || '{}'),
isAuthenticated: (() => { isAuthenticated: (() => {
this.auth0.scheduleRenewal() auth0.scheduleRenewal()
if (this.auth0.isAuthenticated()) { if (auth0.isAuthenticated()) {
api.setBearer(localStorage.getItem('id_token')) api.setBearer(localStorage.getItem('id_token'))
} }
return this.auth0.isAuthenticated() return auth0.isAuthenticated()
})(), })(),
journal: {}, journal: {},
isLoadingJournal: false isLoadingJournal: false