| <script setup> |
| import { ref } from 'vue' |
|
|
| const emit = defineEmits(['save', 'cancel']) |
|
|
| const newRecipe = ref({ |
| name: '', |
| description: '', |
| ingredients: [], |
| instructions: '', |
| tags: [] |
| }) |
|
|
| const currentIngredient = ref('') |
| const currentTag = ref('') |
|
|
| function addIngredient() { |
| if (currentIngredient.value.trim()) { |
| newRecipe.value.ingredients.push(currentIngredient.value.trim()) |
| currentIngredient.value = '' |
| } |
| } |
|
|
| function addTag() { |
| if (currentTag.value.trim()) { |
| newRecipe.value.tags.push(currentTag.value.trim()) |
| currentTag.value = '' |
| } |
| } |
|
|
| function saveRecipe() { |
| emit('save', newRecipe.value) |
| } |
| </script> |
|
|
| <template> |
| <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> |
| <div class="bg-white p-6 rounded-lg shadow-lg w-full max-w-md"> |
| <h3 class="text-lg font-semibold mb-4">Add New Recipe</h3> |
| |
| <form @submit.prevent="saveRecipe"> |
| <div class="space-y-4"> |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Name</label> |
| <input v-model="newRecipe.name" type="text" class="w-full px-3 py-2 border rounded-md" required> |
| </div> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Description</label> |
| <textarea v-model="newRecipe.description" rows="2" class="w-full px-3 py-2 border rounded-md"></textarea> |
| </div> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Ingredients</label> |
| <div class="flex"> |
| <input |
| v-model="currentIngredient" |
| type="text" |
| class="flex-grow px-3 py-2 border rounded-l-md" |
| placeholder="Add ingredient" |
| @keydown.enter.prevent="addIngredient" |
| > |
| <button |
| type="button" |
| @click="addIngredient" |
| class="px-3 py-2 bg-indigo-600 text-white rounded-r-md" |
| > |
| Add |
| </button> |
| </div> |
| <ul class="mt-2"> |
| <li v-for="(ingredient, index) in newRecipe.ingredients" :key="index" class="flex items-center"> |
| <span>{{ ingredient }}</span> |
| <button |
| type="button" |
| @click="newRecipe.ingredients.splice(index, 1)" |
| class="ml-2 text-red-500" |
| > |
| <i data-feather="x"></i> |
| </button> |
| </li> |
| </ul> |
| </div> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Instructions</label> |
| <textarea v-model="newRecipe.instructions" rows="4" class="w-full px-3 py-2 border rounded-md" required></textarea> |
| </div> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Tags</label> |
| <div class="flex"> |
| <input |
| v-model="currentTag" |
| type="text" |
| class="flex-grow px-3 py-2 border rounded-l-md" |
| placeholder="Add tag" |
| @keydown.enter.prevent="addTag" |
| > |
| <button |
| type="button" |
| @click="addTag" |
| class="px-3 py-2 bg-indigo-600 text-white rounded-r-md" |
| > |
| Add |
| </button> |
| </div> |
| <div class="mt-2 flex flex-wrap gap-2"> |
| <span |
| v-for="(tag, index) in newRecipe.tags" |
| :key="index" |
| class="flex items-center bg-indigo-100 text-indigo-800 px-2 py-1 rounded text-sm" |
| > |
| {{ tag }} |
| <button |
| type="button" |
| @click="newRecipe.tags.splice(index, 1)" |
| class="ml-1 text-indigo-600 hover:text-indigo-800" |
| > |
| <i data-feather="x" class="w-3 h-3"></i> |
| </button> |
| </span> |
| </div> |
| </div> |
| </div> |
| |
| <div class="mt-6 flex justify-end space-x-3"> |
| <button type="button" @click="emit('cancel')" class="btn-secondary"> |
| Cancel |
| </button> |
| <button type="submit" class="btn-primary"> |
| Save Recipe |
| </button> |
| </div> |
| </form> |
| </div> |
| </div> |
| </template> |