PronounsPage/components/NameSubmitForm.vue

187 lines
6.7 KiB
Vue

<script setup lang="ts">
import useConfig from '~/composables/useConfig.ts';
import useDialogue from '~/composables/useDialogue.ts';
import type { Name } from '~/src/classes.ts';
const config = useConfig();
type NameForm = Pick<Name, 'name' | 'origin' | 'meaning' | 'usage' | 'legally' | 'pros' | 'cons' | 'notablePeople' | 'links' | 'namedays' | 'namedaysComment' | 'base'>;
const form = ref<NameForm>({
name: '',
origin: '',
meaning: '',
usage: '',
legally: '',
pros: [],
cons: [],
notablePeople: [],
links: [],
namedays: [],
namedaysComment: '',
base: null,
});
const submitting = ref(false);
const afterSubmit = ref(false);
const dialogue = useDialogue();
const submit = async () => {
submitting.value = true;
try {
await dialogue.postWithAlertOnError('/api/names/submit', form.value);
afterSubmit.value = true;
form.value = {
name: '',
origin: '',
meaning: '',
usage: '',
legally: '',
pros: [],
cons: [],
notablePeople: [],
links: [],
namedays: [],
namedaysComment: '',
base: null,
};
} finally {
submitting.value = false;
}
};
const edit = (name: Name) => {
form.value = {
name: name.name,
origin: name.origin,
meaning: name.meaning,
usage: name.usage,
legally: name.legally,
pros: name.pros,
cons: name.cons,
notablePeople: name.notablePeople,
links: name.links,
namedays: name.namedays,
namedaysComment: name.namedaysComment,
base: name.id,
};
afterSubmit.value = false;
focus();
};
const section = useTemplateRef<HTMLElement>('section');
const focus = () => {
section.value?.scrollIntoView();
};
defineExpose({ edit, focus });
</script>
<template>
<section v-if="$user()" ref="section" class="px-md-3 scroll-mt-7">
<div v-if="afterSubmit" class="alert alert-success text-center">
<p>
<T>nouns.submit.thanks</T>
</p>
<p>
<button type="button" class="btn btn-success" @click="afterSubmit = false">
<Icon v="plus" />
<T>nouns.submit.another</T>
</button>
</p>
</div>
<form v-else @submit.prevent="submit">
<div class="row">
<div class="col-12 col-lg-6">
<div class="form-group">
<label><strong><T>names.name</T><T>quotation.colon</T></strong></label>
<input v-model="form.name" class="form-control" required>
</div>
<div class="form-group">
<label><strong><T>names.origin</T><T>quotation.colon</T></strong></label>
<input v-model="form.origin" class="form-control">
</div>
<div class="form-group">
<label><strong><T>names.meaning</T><T>quotation.colon</T></strong></label>
<input v-model="form.meaning" class="form-control">
</div>
<div class="form-group">
<label><strong><T>names.usage</T><T>quotation.colon</T></strong></label>
<input v-model="form.usage" class="form-control">
</div>
<div v-if="config.names.legally" class="form-group">
<label><strong><T>names.legally</T><T>quotation.colon</T></strong></label>
<input v-model="form.legally" class="form-control">
</div>
<template v-if="config.names.namedays">
<div class="form-group">
<label><strong><T>names.namedays</T><T>quotation.colon</T></strong></label>
<ListInput v-slot="s" v-model="form.namedays">
<DayMonth v-model="s.val" @update:model-value="s.update(s.val)" />
</ListInput>
</div>
<div class="form-group">
<label><strong><T>names.namedaysComment</T><T>quotation.colon</T></strong></label>
<input v-model="form.namedaysComment" class="form-control">
</div>
</template>
</div>
<div class="col-12 col-lg-6">
<div class="form-group">
<label><strong><T>names.pros</T><T>quotation.colon</T></strong></label>
<ListInput v-model="form.pros" :maxlength="128" />
</div>
<div class="form-group">
<label><strong><T>names.cons</T><T>quotation.colon</T></strong></label>
<ListInput v-model="form.cons" :maxlength="128" />
</div>
<div class="form-group">
<label><strong><T>names.notablePeople</T><T>quotation.colon</T></strong></label>
<ListInput v-model="form.notablePeople" :maxlength="128" />
</div>
<div class="form-group">
<label><strong><T>names.links</T><T>quotation.colon</T></strong></label>
<ListInput v-slot="s" v-model="form.links" :maxlength="128">
<input v-model="s.val" type="url" class="form-control" required @keyup="s.update(s.val)">
</ListInput>
</div>
</div>
</div>
<div v-if="form.base" class="alert alert-info">
<Icon v="info-circle" />
<T>nouns.editing</T>
<button type="button" class="btn btn-sm float-end" @click="form.base = null">
<Icon v="times" />
</button>
</div>
<button type="submit" class="btn btn-primary w-100" :disabled="submitting">
<template v-if="submitting">
<Icon v="circle-notch fa-spin" />
</template>
<template v-else>
<Icon v="plus" />
<T>nouns.submit.actionLong</T>
</template>
</button>
<p class="small text-muted mt-1">
<T>nouns.submit.moderation</T>
</p>
</form>
</section>
<section v-else class="text-center">
<div class="alert alert-info">
<T>crud.loginRequired</T>
</div>
</section>
</template>