Add birthday to registration form

This commit is contained in:
tusooa 2023-01-22 11:15:52 -05:00
parent b1e75c25bd
commit dd97a23ce7
No known key found for this signature in database
GPG Key ID: 7B467EDE43A08224
5 changed files with 70 additions and 3 deletions

View File

@ -60,6 +60,8 @@ const getInstanceConfig = async ({ store }) => {
store.dispatch('setInstanceOption', { name: 'textlimit', value: textlimit }) store.dispatch('setInstanceOption', { name: 'textlimit', value: textlimit })
store.dispatch('setInstanceOption', { name: 'accountApprovalRequired', value: data.approval_required }) store.dispatch('setInstanceOption', { name: 'accountApprovalRequired', value: data.approval_required })
store.dispatch('setInstanceOption', { name: 'birthdayRequired', value: !!data.pleroma.metadata.birthday_required })
store.dispatch('setInstanceOption', { name: 'birthdayMinAge', value: data.pleroma.metadata.birthday_min_age || 0 })
if (vapidPublicKey) { if (vapidPublicKey) {
store.dispatch('setInstanceOption', { name: 'vapidPublicKey', value: vapidPublicKey }) store.dispatch('setInstanceOption', { name: 'vapidPublicKey', value: vapidPublicKey })

View File

@ -3,6 +3,7 @@ import { required, requiredIf, sameAs } from '@vuelidate/validators'
import { mapActions, mapState } from 'vuex' import { mapActions, mapState } from 'vuex'
import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue' import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue'
import localeService from '../../services/locale/locale.service.js' import localeService from '../../services/locale/locale.service.js'
import { DAY } from 'src/services/date_utils/date_utils.js'
const registration = { const registration = {
setup () { return { v$: useVuelidate() } }, setup () { return { v$: useVuelidate() } },
@ -13,6 +14,7 @@ const registration = {
username: '', username: '',
password: '', password: '',
confirm: '', confirm: '',
birthday: '',
reason: '', reason: '',
language: '' language: ''
}, },
@ -32,6 +34,12 @@ const registration = {
required, required,
sameAs: sameAs(this.user.password) sameAs: sameAs(this.user.password)
}, },
birthday: {
required: requiredIf(() => this.birthdayRequired),
maxValue: value => {
return !this.birthdayRequired || new Date(value).getTime() <= this.birthdayMin.getTime()
}
},
reason: { required: requiredIf(() => this.accountApprovalRequired) }, reason: { required: requiredIf(() => this.accountApprovalRequired) },
language: {} language: {}
} }
@ -52,6 +60,21 @@ const registration = {
reasonPlaceholder () { reasonPlaceholder () {
return this.replaceNewlines(this.$t('registration.reason_placeholder')) return this.replaceNewlines(this.$t('registration.reason_placeholder'))
}, },
birthdayMin () {
const minAge = this.birthdayMinAge
const today = new Date()
today.setUTCMilliseconds(0)
today.setUTCSeconds(0)
today.setUTCMinutes(0)
today.setUTCHours(0)
const minDate = new Date()
minDate.setTime(today.getTime() - minAge * DAY)
return minDate
},
birthdayMinFormatted () {
const browserLocale = localeService.internalToBrowserLocale(this.$i18n.locale)
return this.user.birthday && new Date(Date.parse(this.birthdayMin)).toLocaleDateString(browserLocale, { timeZone: 'UTC', day: 'numeric', month: 'long', year: 'numeric' })
},
...mapState({ ...mapState({
registrationOpen: (state) => state.instance.registrationOpen, registrationOpen: (state) => state.instance.registrationOpen,
signedIn: (state) => !!state.users.currentUser, signedIn: (state) => !!state.users.currentUser,
@ -59,7 +82,9 @@ const registration = {
serverValidationErrors: (state) => state.users.signUpErrors, serverValidationErrors: (state) => state.users.signUpErrors,
termsOfService: (state) => state.instance.tos, termsOfService: (state) => state.instance.tos,
accountActivationRequired: (state) => state.instance.accountActivationRequired, accountActivationRequired: (state) => state.instance.accountActivationRequired,
accountApprovalRequired: (state) => state.instance.accountApprovalRequired accountApprovalRequired: (state) => state.instance.accountApprovalRequired,
birthdayRequired: (state) => state.instance.birthdayRequired,
birthdayMinAge: (state) => state.instance.birthdayMinAge
}) })
}, },
methods: { methods: {

View File

@ -167,6 +167,40 @@
</ul> </ul>
</div> </div>
<div
class="form-group"
:class="{ 'form-group--error': v$.user.birthday.$error }"
>
<label
class="form--label"
for="sign-up-birthday"
>
{{ birthdayRequired ? $t('registration.birthday') : $t('registration.birthday_optional') }}
</label>
<input
id="sign-up-birthday"
v-model="user.birthday"
:disabled="isPending"
class="form-control"
type="date"
max="birthdayMin"
:aria-required="birthdayRequired"
>
</div>
<div
v-if="v$.user.birthday.$dirty"
class="form-error"
>
<ul>
<li v-if="v$.user.birthday.required.$invalid">
<span>{{ $t('registration.validations.birthday_required') }}</span>
</li>
<li v-if="v$.user.birthday.maxValue.$invalid">
<span>{{ $tc('registration.validations.birthday_min_age', { date: birthdayMinFormatted }) }}</span>
</li>
</ul>
</div>
<div <div
class="form-group" class="form-group"
:class="{ 'form-group--error': v$.user.language.$error }" :class="{ 'form-group--error': v$.user.language.$error }"

View File

@ -312,9 +312,13 @@
"email_required": "cannot be left blank", "email_required": "cannot be left blank",
"password_required": "cannot be left blank", "password_required": "cannot be left blank",
"password_confirmation_required": "cannot be left blank", "password_confirmation_required": "cannot be left blank",
"password_confirmation_match": "should be the same as password" "password_confirmation_match": "should be the same as password",
"birthday_required": "cannot be left blank",
"birthday_min_age": "must be on or before {date}"
}, },
"email_language": "In which language do you want to receive emails from the server?" "email_language": "In which language do you want to receive emails from the server?",
"birthday": "Birthday:",
"birthday_optional": "Birthday (optional):"
}, },
"remote_user_resolver": { "remote_user_resolver": {
"remote_user_resolver": "Remote user resolver", "remote_user_resolver": "Remote user resolver",

View File

@ -107,6 +107,8 @@ const defaultState = {
restrictedNicknames: [], restrictedNicknames: [],
safeDM: true, safeDM: true,
knownDomains: [], knownDomains: [],
birthdayRequired: false,
birthdayMinAge: 0,
// Feature-set, apparently, not everything here is reported... // Feature-set, apparently, not everything here is reported...
shoutAvailable: false, shoutAvailable: false,