89 lines
2.6 KiB
Vue
89 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
import { useForm } from "vee-validate";
|
|
import { toTypedSchema } from "@vee-validate/yup";
|
|
import * as yup from "yup";
|
|
import "@/assets/form.css";
|
|
|
|
import { pb } from "../pocketbase.ts";
|
|
import MultiSelectField from "../components/MultiSelectField.vue";
|
|
import { onMounted, ref } from "vue";
|
|
|
|
const { meta, errors, handleSubmit, defineField, resetForm } = useForm({
|
|
validationSchema: toTypedSchema(
|
|
yup.object({
|
|
name: yup.string().required("This field is required."),
|
|
tags: yup.string().required("This field is required."),
|
|
price_range: yup.string().required("This field is required."),
|
|
})
|
|
),
|
|
});
|
|
|
|
const onSubmit = handleSubmit((values) => {
|
|
pb.collection("restaurants").create(values);
|
|
resetForm();
|
|
});
|
|
|
|
const tagsModel = ref<string[]>([]);
|
|
|
|
const [name, nameAttrs] = defineField("name");
|
|
const [tags, tagsAttrs] = defineField("tags");
|
|
const [price, priceAttrs] = defineField("price_range");
|
|
|
|
onMounted(async () => {
|
|
const tags = await pb.collection("tags").getFullList();
|
|
tagsModel.value = tags.map((record) => record.name);
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<form
|
|
class="flex flex-col place-content-center items-center h-full"
|
|
@submit.prevent="onSubmit"
|
|
>
|
|
<div class="flex flex-row flex-nowrap">
|
|
<div class="mx-5 my-4 w-full">
|
|
<label class="form-label"> Name </label>
|
|
<input
|
|
:class="errors.name === undefined ? 'form-field' : 'form-field-error'"
|
|
v-model="name"
|
|
v-bind="nameAttrs"
|
|
type="text"
|
|
/>
|
|
<label class="text-red-500">{{ errors.name }}</label>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-row flex-nowrap">
|
|
<div class="mx-5 my-4 w-full">
|
|
<label class="form-label"> Tags </label>
|
|
<MultiSelectField :model="tags" :options="tagsModel" />
|
|
<input
|
|
:class="
|
|
errors.cuisine_type === undefined
|
|
? 'form-field'
|
|
: 'form-field-error'
|
|
"
|
|
v-model="cuisine"
|
|
v-bind="cuisineAttrs"
|
|
type="text"
|
|
/>
|
|
<label class="text-red-500">{{ errors.cuisine_type }}</label>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-row flex-nowrap w-1/2 place-content-center">
|
|
<div class="mx-5 my-4">
|
|
<label class="form-label"> Price </label>
|
|
<input
|
|
:class="
|
|
errors.price_range === undefined ? 'form-field' : 'form-field-error'
|
|
"
|
|
v-model="price"
|
|
v-bind="priceAttrs"
|
|
type="text"
|
|
/>
|
|
<label class="text-red-500">{{ errors.price_range }}</label>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-outline">Create</button>
|
|
</form>
|
|
</template>
|