Skip to content

Commit 5e2f419

Browse files
authored
Merge pull request #91 from hydroserver2/134-account-form
134 account form
2 parents 3396b83 + d4d9201 commit 5e2f419

File tree

4 files changed

+105
-263
lines changed

4 files changed

+105
-263
lines changed

src/components/account/AccountForm.vue

Lines changed: 79 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,62 @@
33
<slot name="header">
44
<v-card-title>Edit Profile</v-card-title>
55
</slot>
6-
<v-divider class="my-4"></v-divider>
6+
7+
<v-divider class="my-4" />
8+
79
<v-card-text>
810
<v-form
911
ref="myForm"
1012
v-model="valid"
1113
validate-on="blur"
12-
@submit.prevent="updateUser"
14+
@submit.prevent="onSubmit"
1315
>
1416
<v-row>
1517
<v-col cols="12" sm="4">
1618
<v-text-field
1719
v-model="userForm.firstName"
1820
label="First Name *"
1921
:rules="rules.requiredName"
20-
></v-text-field>
22+
/>
2123
</v-col>
2224
<v-col cols="12" sm="4">
2325
<v-text-field
2426
v-model="userForm.middleName"
2527
label="Middle Name"
2628
:rules="rules.name"
27-
></v-text-field>
29+
/>
2830
</v-col>
2931
<v-col cols="12" sm="4">
3032
<v-text-field
3133
v-model="userForm.lastName"
3234
label="Last Name *"
3335
:rules="rules.requiredName"
34-
></v-text-field>
36+
/>
3537
</v-col>
3638

3739
<v-col cols="12" v-if="!userForm.isVerified">
3840
<v-text-field
3941
v-model="userForm.email"
4042
label="Email *"
4143
:rules="rules.email"
42-
></v-text-field>
44+
/>
45+
</v-col>
46+
47+
<v-col v-if="!isEdit" cols="12" md="6">
48+
<v-text-field
49+
type="password"
50+
v-model="userForm.password"
51+
label="Password *"
52+
:rules="rules.password"
53+
/>
54+
</v-col>
55+
<v-col v-if="!isEdit" cols="12" md="6">
56+
<v-text-field
57+
type="password"
58+
v-model="confirmPassword"
59+
label="Confirm Password *"
60+
:rules="rules.passwordMatch(userForm.password)"
61+
/>
4362
</v-col>
4463

4564
<v-col cols="12" sm="6">
@@ -48,7 +67,7 @@
4867
v-maska:[phoneMask]
4968
label="Phone Number"
5069
:rules="rules.phoneNumber"
51-
></v-text-field>
70+
/>
5271
</v-col>
5372

5473
<v-col cols="12" sm="6">
@@ -57,23 +76,19 @@
5776
label="User Type *"
5877
:items="userTypes"
5978
:rules="rules.required"
60-
></v-autocomplete>
79+
/>
6180
</v-col>
6281

6382
<v-col cols="12">
64-
<v-text-field
65-
v-model="userForm.address"
66-
label="Address"
67-
></v-text-field>
83+
<v-text-field v-model="userForm.address" label="Address" />
6884
</v-col>
6985

7086
<v-col>
7187
<v-text-field
7288
v-model="userForm.link"
7389
label="User's Link (URL)"
7490
:rules="userForm.link ? rules.urlFormat : []"
75-
>
76-
</v-text-field>
91+
/>
7792
</v-col>
7893
</v-row>
7994

@@ -82,22 +97,22 @@
8297
hide-details
8398
label="Affiliated with an Organization"
8499
color="primary"
85-
></v-switch>
100+
/>
86101

87102
<v-row v-if="userForm.organization && showOrg">
88103
<v-col cols="12" sm="8">
89104
<v-text-field
90105
v-model="userForm.organization.name"
91106
label="Organization Name *"
92107
:rules="rules.requiredName"
93-
></v-text-field>
108+
/>
94109
</v-col>
95110
<v-col cols="12" sm="4">
96111
<v-text-field
97112
v-model="userForm.organization.code"
98113
label="Organization Code *"
99114
:rules="rules.requiredName"
100-
></v-text-field>
115+
/>
101116
</v-col>
102117
<v-col cols="12" sm="6">
103118
<v-autocomplete
@@ -112,7 +127,7 @@
112127
v-model="userForm.organization.link"
113128
label="Organization Link"
114129
:rules="userForm.organization.link ? rules.urlFormat : []"
115-
></v-text-field>
130+
/>
116131
</v-col>
117132
<v-col cols="12">
118133
<v-textarea
@@ -121,7 +136,7 @@
121136
:rules="
122137
userForm.organization.description ? rules.maxLength(2000) : []
123138
"
124-
></v-textarea>
139+
/>
125140
</v-col>
126141
</v-row>
127142

@@ -134,14 +149,16 @@
134149
</v-alert>
135150
</v-card-text>
136151

137-
<v-divider></v-divider>
152+
<v-divider />
138153

139154
<v-card-actions>
140-
<v-spacer></v-spacer>
141-
<v-btn-cancel v-if="hasCancelButton" @click="emit('close')"
142-
>Cancel</v-btn-cancel
143-
>
144-
<v-btn-primary type="submit">Save</v-btn-primary>
155+
<v-spacer />
156+
<v-btn-cancel v-if="hasCancelButton" @click="emit('close')">
157+
Cancel
158+
</v-btn-cancel>
159+
<v-btn-primary type="submit">
160+
{{ isEdit ? 'Save' : 'Create User' }}
161+
</v-btn-primary>
145162
</v-card-actions>
146163
</v-form>
147164
</v-card-text>
@@ -161,21 +178,28 @@ import router from '@/router/router'
161178
import { Snackbar } from '@/utils/notifications'
162179
import { api } from '@/services/api'
163180
import { storeToRefs } from 'pinia'
181+
import { useAuthStore } from '@/store/authentication'
164182
165-
defineProps({
183+
const props = defineProps({
166184
hasCancelButton: { type: Boolean, required: false, default: true },
185+
isEdit: Boolean,
167186
})
168187
188+
const { setTokens } = useAuthStore()
169189
const { setUser } = useUserStore()
170190
const { user } = storeToRefs(useUserStore())
171-
let userForm = reactive<User>(JSON.parse(JSON.stringify(user.value)))
191+
192+
let userForm = reactive<User>(
193+
props.isEdit ? JSON.parse(JSON.stringify(user.value)) : new User()
194+
)
172195
173196
const phoneMask = { mask: '(###) ###-####' }
174197
const valid = ref(false)
175198
const myForm = ref<VForm>()
176199
const showOrg = ref(!!userForm.organization)
177200
const hadOrgInitially = ref<boolean>(!!userForm.organization)
178201
const tempOrganization = ref<Organization | null>(null)
202+
const confirmPassword = ref('')
179203
180204
watch(showOrg, (newVal) => {
181205
if (newVal) {
@@ -195,26 +219,41 @@ watch(showOrg, (newVal) => {
195219
196220
const emit = defineEmits(['close'])
197221
198-
const updateUser = async () => {
199-
await myForm.value?.validate()
200-
if (!valid.value) return
222+
async function createUser() {
223+
try {
224+
const data = await api.createUser(userForm)
225+
setUser(data.user)
226+
setTokens(data.access, data.refresh)
227+
Snackbar.success('Account created.')
228+
await router.push({ name: 'VerifyEmail' })
229+
} catch (error) {
230+
console.error('Error creating user', error)
231+
if ((error as Error).message === '409') {
232+
Snackbar.warn('A user with this email already exists.')
233+
}
234+
}
235+
}
201236
237+
const updateUser = async () => {
202238
try {
203239
userForm = await api.updateUser(userForm, user.value)
204-
if (userForm !== undefined) {
205-
setUser(userForm)
206-
}
240+
if (userForm !== undefined) setUser(userForm)
207241
} catch (error) {
208242
console.error('Error updating user', error)
209243
}
210-
211-
if (!user.value?.isVerified) {
212-
await router.push({ name: 'VerifyEmail' })
213-
} else {
214-
Snackbar.success('Your changes have been saved.')
215-
}
244+
if (!user.value?.isVerified) await router.push({ name: 'VerifyEmail' })
245+
else Snackbar.success('Your changes have been saved.')
216246
emit('close')
217247
}
218248
219-
onMounted(async () => await myForm.value?.validate())
249+
const onSubmit = async () => {
250+
await myForm.value?.validate()
251+
if (!valid.value) return
252+
if (props.isEdit) updateUser()
253+
else createUser()
254+
}
255+
256+
onMounted(async () => {
257+
if (props.isEdit) await myForm.value?.validate()
258+
})
220259
</script>

src/pages/account/CompleteProfile.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<template>
22
<v-container>
3-
<AccountForm v-if="loaded" :has-cancel-button="false">
3+
<AccountForm
4+
v-if="loaded"
5+
:has-cancel-button="false"
6+
:is-edit="true"
7+
@close="navigateToSites()"
8+
>
49
<template v-slot:header>
510
<v-card-title align="center" class="mb-2 signup-title">
611
Successfully authenticated!
@@ -21,12 +26,17 @@ import { useUserStore } from '@/store/user'
2126
import { storeToRefs } from 'pinia'
2227
import { onMounted, ref } from 'vue'
2328
import { useRoute } from 'vue-router'
29+
import router from '@/router/router'
2430
2531
const route = useRoute()
2632
const { user } = storeToRefs(useUserStore())
2733
const { setTokens } = useAuthStore()
2834
const loaded = ref(false)
2935
36+
const navigateToSites = async () => {
37+
await router.push({ name: 'Sites' })
38+
}
39+
3040
onMounted(async () => {
3141
const accessToken = (route.query.t as string) || ''
3242
const refreshToken = (route.query.rt as string) || ''

src/pages/account/Profile.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</v-container>
1111

1212
<v-dialog v-model="openForm" width="40rem">
13-
<AccountForm @close="openForm = false" />
13+
<AccountForm @close="openForm = false" :is-edit="true" />
1414
</v-dialog>
1515

1616
<v-dialog v-model="openDelete" width="40rem">

0 commit comments

Comments
 (0)