commit: dd97a23ce70fc564d3142eb9d218ff1a929107b1
parent b1e75c25bd50180e715afde70c6e659e7509a3f3
Author: tusooa <tusooa@kazv.moe>
Date: Sun, 22 Jan 2023 11:15:52 -0500
Add birthday to registration form
Diffstat:
5 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
@@ -60,6 +60,8 @@ const getInstanceConfig = async ({ store }) => {
store.dispatch('setInstanceOption', { name: 'textlimit', value: textlimit })
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) {
store.dispatch('setInstanceOption', { name: 'vapidPublicKey', value: vapidPublicKey })
diff --git a/src/components/registration/registration.js b/src/components/registration/registration.js
@@ -3,6 +3,7 @@ import { required, requiredIf, sameAs } from '@vuelidate/validators'
import { mapActions, mapState } from 'vuex'
import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue'
import localeService from '../../services/locale/locale.service.js'
+import { DAY } from 'src/services/date_utils/date_utils.js'
const registration = {
setup () { return { v$: useVuelidate() } },
@@ -13,6 +14,7 @@ const registration = {
username: '',
password: '',
confirm: '',
+ birthday: '',
reason: '',
language: ''
},
@@ -32,6 +34,12 @@ const registration = {
required,
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) },
language: {}
}
@@ -52,6 +60,21 @@ const registration = {
reasonPlaceholder () {
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({
registrationOpen: (state) => state.instance.registrationOpen,
signedIn: (state) => !!state.users.currentUser,
@@ -59,7 +82,9 @@ const registration = {
serverValidationErrors: (state) => state.users.signUpErrors,
termsOfService: (state) => state.instance.tos,
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: {
diff --git a/src/components/registration/registration.vue b/src/components/registration/registration.vue
@@ -169,6 +169,40 @@
<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
+ class="form-group"
:class="{ 'form-group--error': v$.user.language.$error }"
>
<interface-language-switcher
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -312,9 +312,13 @@
"email_required": "cannot be left blank",
"password_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",
diff --git a/src/modules/instance.js b/src/modules/instance.js
@@ -107,6 +107,8 @@ const defaultState = {
restrictedNicknames: [],
safeDM: true,
knownDomains: [],
+ birthdayRequired: false,
+ birthdayMinAge: 0,
// Feature-set, apparently, not everything here is reported...
shoutAvailable: false,