<script>
import { getUserInfo, NUTRITION_NAMES } from '../lib/utils/utils'
import { addNewRecipe } from '../lib/utils/recipes.js'
import RecipePageTemplate from '../lib/components/RecipePageTemplate.svelte'
import AutocompleteSearch from '../lib/components/AutocompleteSearch.svelte'
import NotFound from './NotFound.svelte'
let recipeName = ''
let prepMinutes = ''
let ingredients = []
let tags = []
let nutrition = Array(7).fill(0)
let description = ''
let steps = []
let args = {
recipe: {
Id: 0,
Name: 'Recipe Name',
PrepMinutes: 0,
Description: '',
Ingredients: [],
Nutrition: Array(7).fill(0),
Tags: [],
Steps: [],
},
}
let ingredientSearchBar
let tagSearchBar
let field
let userinfo = getUserInfo()
let onLogin = userinfo == null ? false : true
let inputError = false
let errorMsgs = []
let addRecipeSuccess = false
let addRecipeFail = false
const resetErrors = () => {
inputError = false
errorMsgs = []
}
const checkInputs = () => {
if (recipeName == '') {
errorMsgs.push('Missing recipe name')
}
if (prepMinutes <= 0 || prepMinutes == '') {
errorMsgs.push('Preparation time must be positive')
}
if (description == '') {
errorMsgs.push('Missing description')
}
if (ingredients.length == 0) {
errorMsgs.push('Missing ingredients')
}
if (tags.length == 0) {
errorMsgs.push('Missing tags')
}
if (steps.length == 0) {
errorMsgs.push('Missing steps')
}
if (nutrition === Array(7).fill(0)) {
}
let nSum = 0
if (nutrition.reduce((acc, n) => {
nSum += n
return acc || n < 0
}, false)) {
errorMsgs.push('Nutrition value must be non-negative')
} else if (nSum == 0) {
errorMsgs.push('Missing nutrition values')
}
// now check
if (errorMsgs.length != 0) {
errorMsgs = errorMsgs
inputError = true
return false
}
return true
}
const addRecipe = () => {
console.log('add recipe')
if (checkInputs()) {
console.log(formatRecipe())
addNewRecipe(userinfo.userid, formatRecipe()).then((res) => {
console.log(res.message)
if (res.status != 'failed') {
addRecipeSuccess = true
} else {
addRecipeFail = true
}
})
} else {
console.log('tes')
inputError = true
}
}
const removeFromIngredients = (ing) => {
const index = ingredients.indexOf(ing)
if (index > -1) {
ingredients.splice(index, 1)
}
ingredients = ingredients
}
const removeFromTags = (tag) => {
const index = tags.indexOf(tag)
if (index > -1) {
tags.splice(index, 1)
}
tags = tags
}
const removeFromSteps = (stepNum) => {
const index = stepNum
if (index > -1) {
steps.splice(index, 1)
}
steps = steps
}
const formatRecipe = () => {
return {
Id: 0,
Name: recipeName || 'Recipe Name',
PrepMinutes: prepMinutes || 0,
Description: description || 'Description',
Ingredients: ingredients,
Nutrition: nutrition.length == 0 ? Array(7).fill(0) : nutrition,
Tags: tags,
Steps: steps.map((s) => "'" + s + "'"),
}
}
const updatePreview = () => {
steps.map((s) => {
if (!s) return ''
return s
})
args = {
recipe: formatRecipe(),
}
}
</script>
{#if !onLogin}
<NotFound />
{:else}
<div>
<div
class="flex-col flex-grow pt-10 px-10 bg-base-200"
style="min-height: 85vh"
on:click={() => {
field.stopSuggestion()
updatePreview()
}}
>
<div class="flex my-2 w-full justify-center">
<h1 class="text-5xl font-bold">Add Recipes</h1>
</div>
<div class="flex flex-row justify-center p-5 " style="min-height: 70vh;">
<div
class="form-control w-auto card grid basis-2/5 flex-none bg-base-300 rounded-box items-start"
on:change={updatePreview}
on:click={updatePreview}
>
<div class="label">
<span class="label-text">Recipe Name</span>
</div>
<input
type="text"
placeholder="Type here"
class="input input-bordered w-full max-w-xs"
bind:value={recipeName}
/>
<div class="label">
<span class="label-text">Preparation Time (minutes)</span>
</div>
<input
type="number"
min="0"
placeholder="Type a number"
class="input input-bordered w-full max-w-xs"
bind:value={prepMinutes}
/>
<div class="label">
<span class="label-text">Ingredients</span>
</div>
<AutocompleteSearch
bind:resultArray={ingredients}
bind:searchBar={ingredientSearchBar}
bind:this={field}
/>
{#if ingredients.length > 0}
<ul class="">
{#each ingredients as ing, i}
<div class="badge gap-2 badge-lg">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
class="inline-block w-4 h-4 stroke-current"
on:click={() => removeFromIngredients(ing)}
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/></svg
>
{ing}
</div>
{/each}
</ul>
{/if}
<div class="label">
<span class="label-text">Tags</span>
</div>
<AutocompleteSearch
bind:resultArray={tags}
bind:searchBar={tagSearchBar}
searchIng={false}
bind:this={field}
/>
{#if tags.length > 0}
<ul class="">
{#each tags as tag, i}
<div class="badge badge-lg gap-2">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
class="inline-block w-4 h-4 stroke-current"
on:click={() => removeFromTags(tag)}
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/></svg
>
#{tag}
</div>
{/each}
</ul>
{/if}
<div class="label">
<span class="label-text">Nutrition</span>
</div>
<div class="flex flex-col">
{#each Array(7) as _, i}
<label class="input-group">
<input
type="number"
min="0"
placeholder="0"
class="input input-bordered"
bind:value={nutrition[i]}
/>
<span>{NUTRITION_NAMES[i]}</span>
</label>
{/each}
</div>
<div class="label">
<span class="label-text">Description</span>
</div>
<textarea
placeholder="Type here"
class="textarea textarea-bordered w-full max-w-xs"
bind:value={description}
/>
<div class="label">
<span class="label-text">Steps</span>
</div>
{#each Array(steps.length + 1) as _, i}
<label class="input-group">
<span>{i + 1}</span>
<textarea
placeholder="Type here"
class="textarea textarea-bordered w-full max-w-xs"
bind:value={steps[i]}
/>
<button class="btn h-full" on:click={() => removeFromSteps(i)}>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="#ffffff"
stroke-width="2"
stroke-linecap="butt"
stroke-linejoin="bevel"
><line x1="18" y1="6" x2="6" y2="18" /><line
x1="6"
y1="6"
x2="18"
y2="18"
/></svg
>
</button>
</label>
{/each}
<div class="flex justify-end mt-8">
<button class="btn" on:click={addRecipe}>Add Your Recipe!</button>
</div>
</div>
<div
class="flex-grow ml-4 bg-base-200 rounded-box"
style="pointer-events:none"
>
<RecipePageTemplate bind:recipe={args.recipe} />
</div>
</div>
</div>
</div>
{#if inputError}
<input type="checkbox" id="my-modal" class="modal-toggle" checked />
<div class="modal">
<div class="modal-box align-middle">
<div class="flex mb-2 mt-4 justify-center">
<h3 class="font-bold text-2xl">
Oops! Please make sure your recipe is written properly.
</h3>
</div>
<p class="py-4">
{#each errorMsgs as msg}
{msg} <br />
{/each}
</p>
<div class="modal-action">
<label for="my-modal" class="btn" on:click={resetErrors}>Close</label>
</div>
</div>
</div>
{/if}
{#if addRecipeSuccess}
<input type="checkbox" id="my-modal" class="modal-toggle" checked />
<div class="modal">
<div class="modal-box align-middle">
<div class="flex mb-2 mt-4 justify-center">
<h3 class="font-bold text-2xl">Add Recipe Success!</h3>
</div>
<p class="py-4">
You will be redirected home
</p>
<div class="modal-action">
<label for="my-modal" class="btn" on:click={() => { window.location.href = "#/"; window.location.reload() }}>Close</label>
</div>
</div>
</div>
{:else if addRecipeFail}
<input type="checkbox" id="my-modal" class="modal-toggle" checked />
<div class="modal">
<div class="modal-box align-middle">
<div class="flex mb-2 mt-4 justify-center">
<h3 class="font-bold text-2xl">Add Recipe Fail!</h3>
</div>
<p class="py-4">
Failed to add recipe
</p>
<div class="modal-action">
<label for="my-modal" class="btn" >Close</label>
</div>
</div>
</div>
{/if}
{/if}