#179-suspensions #188
@@ -1,18 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import Button from '@/components/ui/button/Button.vue';
|
||||
import Checkbox from '@/components/ui/checkbox/Checkbox.vue';
|
||||
import { useForm, Field as VeeField } from 'vee-validate';
|
||||
import {
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form'
|
||||
Field,
|
||||
FieldContent,
|
||||
FieldDescription,
|
||||
FieldGroup,
|
||||
FieldLabel,
|
||||
} from '@/components/ui/field'
|
||||
import FieldError from '@/components/ui/field/FieldError.vue';
|
||||
import Input from '@/components/ui/input/Input.vue';
|
||||
import Textarea from '@/components/ui/textarea/Textarea.vue';
|
||||
import { toTypedSchema } from '@vee-validate/zod';
|
||||
import { Form } from 'vee-validate';
|
||||
import { nextTick, onMounted, ref, watch } from 'vue';
|
||||
import * as z from 'zod';
|
||||
import DateInput from '../form/DateInput.vue';
|
||||
@@ -65,6 +65,15 @@ const emit = defineEmits(['submit']);
|
||||
|
||||
const initialValues = ref<Record<string, unknown> | null>(null);
|
||||
|
||||
const { handleSubmit, resetForm, values } = useForm({
|
||||
validationSchema: formSchema,
|
||||
validateOnMount: false,
|
||||
});
|
||||
|
||||
const submitForm = handleSubmit(async (val) => {
|
||||
await onSubmit(val);
|
||||
});
|
||||
|
||||
async function onSubmit(val: any) {
|
||||
emit('submit', val);
|
||||
}
|
||||
@@ -80,6 +89,9 @@ onMounted(async () => {
|
||||
initialValues.value = { ...fallbackInitials };
|
||||
}
|
||||
|
||||
// apply the initial values to the vee-validate form
|
||||
resetForm({ values: initialValues.value });
|
||||
|
||||
// CoCbox.value.innerHTML = await getCoC()
|
||||
CoCString.value = await getCoC();
|
||||
})
|
||||
@@ -103,7 +115,7 @@ function enforceExternalLinks() {
|
||||
}
|
||||
|
||||
watch(() => showCoC.value, async () => {
|
||||
if (showCoC) {
|
||||
if (showCoC.value) {
|
||||
await nextTick(); // wait for v-html to update
|
||||
enforceExternalLinks();
|
||||
}
|
||||
@@ -126,215 +138,214 @@ function convertToAge(dob: string) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Form v-if="initialValues" :validation-schema="formSchema" :initial-values="initialValues" @submit="onSubmit"
|
||||
class="space-y-6">
|
||||
<form v-if="initialValues" @submit.prevent="submitForm" class="space-y-6">
|
||||
<!-- Age -->
|
||||
<FormField name="dob" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>What is your date of birth?</FormLabel>
|
||||
<FormControl>
|
||||
<template class="flex items-center gap-10">
|
||||
<DateInput :model-value="(value as string) ?? ''" :disabled="readOnly" @update:model-value="handleChange" />
|
||||
<p v-if="props.readOnly" class="text-muted-foreground">Age: {{ convertToAge(value) }}</p>
|
||||
</template>
|
||||
</FormControl>
|
||||
<VeeField name="dob" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>What is your date of birth?</FieldLabel>
|
||||
<FieldContent>
|
||||
<div class="flex items-center gap-10">
|
||||
<DateInput :model-value="(field.value as string) ?? ''" :disabled="readOnly" @update:model-value="field.onChange" />
|
||||
<p v-if="props.readOnly" class="text-muted-foreground">Age: {{ convertToAge(field.value) }}</p>
|
||||
</div>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Name -->
|
||||
<FormField name="name" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>What name will you be going by within the community?</FormLabel>
|
||||
<FormDescription>This name must be consistent across platforms.</FormDescription>
|
||||
<FormControl>
|
||||
<Input :model-value="value" @update:model-value="handleChange" :disabled="readOnly" />
|
||||
</FormControl>
|
||||
<VeeField name="name" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>What name will you be going by within the community?</FieldLabel>
|
||||
<FieldDescription>This name must be consistent across platforms.</FieldDescription>
|
||||
<FieldContent>
|
||||
<Input :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Playtime -->
|
||||
<FormField name="playtime" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>How long have you played Arma 3 for (in hours)?</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="number" :model-value="value" @update:model-value="handleChange" :disabled="readOnly" />
|
||||
</FormControl>
|
||||
<VeeField name="playtime" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>How long have you played Arma 3 for (in hours)?</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input type="number" :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Hobbies -->
|
||||
<FormField name="hobbies" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>What hobbies do you like to participate in outside of gaming?</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea rows="4" class="resize-none" :model-value="value" @update:model-value="handleChange"
|
||||
<VeeField name="hobbies" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>What hobbies do you like to participate in outside of gaming?</FieldLabel>
|
||||
<FieldContent>
|
||||
<Textarea rows="4" class="resize-none" :model-value="field.value" @update:model-value="field.onChange"
|
||||
:disabled="readOnly" />
|
||||
</FormControl>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Military (boolean) -->
|
||||
<FormField name="military" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>Have you ever served in the military?</FormLabel>
|
||||
<FormControl>
|
||||
<VeeField name="military" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>Have you ever served in the military?</FieldLabel>
|
||||
<FieldContent>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox :model-value="value" @update:model-value="handleChange" :disabled="readOnly" />
|
||||
<Checkbox :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
|
||||
<span>Yes (checked) / No (unchecked)</span>
|
||||
</div>
|
||||
</FormControl>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Other communities (freeform) -->
|
||||
<FormField name="communities" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>Are you a part of any other communities? If so, which ones? If none, type "No"</FormLabel>
|
||||
<FormControl>
|
||||
<Input :model-value="value" @update:model-value="handleChange" :disabled="readOnly" />
|
||||
</FormControl>
|
||||
<VeeField name="communities" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>Are you a part of any other communities? If so, which ones? If none, type "No"</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Why join -->
|
||||
<FormField name="joinReason" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>Why do you want to join our community?</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea rows="4" class="resize-none" :model-value="value" @update:model-value="handleChange"
|
||||
<VeeField name="joinReason" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>Why do you want to join our community?</FieldLabel>
|
||||
<FieldContent>
|
||||
<Textarea rows="4" class="resize-none" :model-value="field.value" @update:model-value="field.onChange"
|
||||
:disabled="readOnly" />
|
||||
</FormControl>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Attraction to milsim -->
|
||||
<FormField name="milsimAttraction" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>What attracts you to the Arma 3 milsim playstyle?</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea rows="4" class="resize-none" :model-value="value" @update:model-value="handleChange"
|
||||
<VeeField name="milsimAttraction" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>What attracts you to the Arma 3 milsim playstyle?</FieldLabel>
|
||||
<FieldContent>
|
||||
<Textarea rows="4" class="resize-none" :model-value="field.value" @update:model-value="field.onChange"
|
||||
:disabled="readOnly" />
|
||||
</FormControl>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Referral (freeform) -->
|
||||
<FormField name="referral" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>Where did you hear about us? (If another member, who?)</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="e.g., Reddit / Member: Alice" :model-value="value" @update:model-value="handleChange"
|
||||
<VeeField name="referral" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>Where did you hear about us? (If another member, who?)</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input placeholder="e.g., Reddit / Member: Alice" :model-value="field.value" @update:model-value="field.onChange"
|
||||
:disabled="readOnly" />
|
||||
</FormControl>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Steam profile -->
|
||||
<FormField name="steamProfile" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>Steam profile link</FormLabel>
|
||||
<FormDescription>
|
||||
<VeeField name="steamProfile" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>Steam profile link</FieldLabel>
|
||||
<FieldDescription>
|
||||
Format: <code>https://steamcommunity.com/id/USER/</code> or
|
||||
<code>https://steamcommunity.com/profiles/STEAMID64/</code>
|
||||
</FormDescription>
|
||||
<FormControl>
|
||||
<Input type="url" placeholder="https://steamcommunity.com/profiles/7656119..." :model-value="value"
|
||||
@update:model-value="handleChange" :disabled="readOnly" />
|
||||
</FormControl>
|
||||
</FieldDescription>
|
||||
<FieldContent>
|
||||
<Input type="url" placeholder="https://steamcommunity.com/profiles/7656119..." :model-value="field.value"
|
||||
@update:model-value="field.onChange" :disabled="readOnly" />
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Timezone -->
|
||||
<FormField name="timezone" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>What time zone are you in?</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="e.g., AEST, EST, UTC+10" :model-value="value" @update:model-value="handleChange"
|
||||
<VeeField name="timezone" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>What time zone are you in?</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input placeholder="e.g., AEST, EST, UTC+10" :model-value="field.value" @update:model-value="field.onChange"
|
||||
:disabled="readOnly" />
|
||||
</FormControl>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Attendance (boolean) -->
|
||||
<FormField name="canAttendSaturday" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>Are you able to attend weekly operations Saturdays @ 7pm CST?</FormLabel>
|
||||
<FormControl>
|
||||
<VeeField name="canAttendSaturday" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>Are you able to attend weekly operations Saturdays @ 7pm CST?</FieldLabel>
|
||||
<FieldContent>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox :model-value="value ?? false" @update:model-value="handleChange" :disabled="readOnly" />
|
||||
<Checkbox :model-value="field.value ?? false" @update:model-value="field.onChange" :disabled="readOnly" />
|
||||
<span>Yes (checked) / No (unchecked)</span>
|
||||
</div>
|
||||
</FormControl>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Interests / Playstyle (freeform) -->
|
||||
<FormField name="interests" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>Which playstyles interest you?</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="e.g., Rifleman; Medic; Pilot" :model-value="value" @update:model-value="handleChange"
|
||||
<VeeField name="interests" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>Which playstyles interest you?</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input placeholder="e.g., Rifleman; Medic; Pilot" :model-value="field.value" @update:model-value="field.onChange"
|
||||
:disabled="readOnly" />
|
||||
</FormControl>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<!-- Code of Conduct (boolean, field name kept as-is) -->
|
||||
<FormField name="acknowledgeRules" v-slot="{ value, handleChange }">
|
||||
<FormItem>
|
||||
<FormLabel>Community Code of Conduct</FormLabel>
|
||||
<FormControl>
|
||||
<VeeField name="acknowledgeRules" v-slot="{ field, errors }">
|
||||
<Field>
|
||||
<FieldLabel>Community Code of Conduct</FieldLabel>
|
||||
<FieldContent>
|
||||
<div class="flex items-center gap-2">
|
||||
<Checkbox :model-value="value" @update:model-value="handleChange" :disabled="readOnly" />
|
||||
<Checkbox :model-value="field.value" @update:model-value="field.onChange" :disabled="readOnly" />
|
||||
<span>By checking this box, you accept the <Button variant="link" class="p-0 h-min"
|
||||
@click.prevent.stop="showCoC = true">Code of
|
||||
Conduct</Button>.</span>
|
||||
</div>
|
||||
</FormControl>
|
||||
</FieldContent>
|
||||
<div class="h-4">
|
||||
<FormMessage class="text-destructive" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</Field>
|
||||
</VeeField>
|
||||
|
||||
<div class="pt-2" v-if="!readOnly">
|
||||
<Button type="submit" :disabled="readOnly">Submit Application</Button>
|
||||
@@ -351,5 +362,5 @@ function convertToAge(dob: string) {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
</Form>
|
||||
</form>
|
||||
</template>
|
||||
Reference in New Issue
Block a user