randomize moved to API
This commit is contained in:
		@@ -1 +0,0 @@
 | 
			
		||||
{"terminal": "nvimterm"}
 | 
			
		||||
@@ -2,10 +2,11 @@ import { json, type RequestHandler } from '@sveltejs/kit';
 | 
			
		||||
import type { BriefRecipeType } from '../../../../types/types';
 | 
			
		||||
import { Recipe } from '../../../../models/Recipe'
 | 
			
		||||
import { dbConnect, dbDisconnect } from '../../../../utils/db';
 | 
			
		||||
import { rand_array } from '$lib/js/randomize';
 | 
			
		||||
 | 
			
		||||
export const GET: RequestHandler = async ({params}) => {
 | 
			
		||||
  await dbConnect();
 | 
			
		||||
  let found_brief = (await Recipe.find({}, 'name short_name tags category icon description season').lean()) as BriefRecipeType[];
 | 
			
		||||
  let found_brief = rand_array(await Recipe.find({}, 'name short_name tags category icon description season').lean()) as BriefRecipeType[];
 | 
			
		||||
  await dbDisconnect();
 | 
			
		||||
  return json(JSON.parse(JSON.stringify(found_brief)));
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,11 @@ import { json, type RequestHandler } from '@sveltejs/kit';
 | 
			
		||||
import { Recipe } from '../../../../../models/Recipe';
 | 
			
		||||
import { dbConnect, dbDisconnect } from '../../../../../utils/db';
 | 
			
		||||
import type {BriefRecipeType} from '../../../../../types/types';
 | 
			
		||||
import { rand_array } from '$lib/js/randomize';
 | 
			
		||||
 | 
			
		||||
export const GET: RequestHandler = async ({params}) => {
 | 
			
		||||
  await dbConnect();
 | 
			
		||||
  let recipes = (await Recipe.find({category: params.category}, 'name short_name images tags category icon description season').lean()) as BriefRecipeType[];
 | 
			
		||||
  let recipes = rand_array(await Recipe.find({category: params.category}, 'name short_name images tags category icon description season').lean()) as BriefRecipeType[];
 | 
			
		||||
  await dbDisconnect();
 | 
			
		||||
 | 
			
		||||
  recipes = JSON.parse(JSON.stringify(recipes));
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,11 @@ import { json, type RequestHandler } from '@sveltejs/kit';
 | 
			
		||||
import { Recipe } from '../../../../../models/Recipe';
 | 
			
		||||
import { dbConnect, dbDisconnect } from '../../../../../utils/db';
 | 
			
		||||
import type {BriefRecipeType} from '../../../../../types/types';
 | 
			
		||||
import { rand_array } from '$lib/js/randomize';
 | 
			
		||||
 | 
			
		||||
export const GET: RequestHandler = async ({params}) => {
 | 
			
		||||
  await dbConnect();
 | 
			
		||||
  let recipes = (await Recipe.find({icon: params.icon}, 'name short_name images tags category icon description season').lean()) as BriefRecipeType[];
 | 
			
		||||
  let recipes = rand_array(await Recipe.find({icon: params.icon}, 'name short_name images tags category icon description season').lean()) as BriefRecipeType[];
 | 
			
		||||
  await dbDisconnect();
 | 
			
		||||
 | 
			
		||||
  recipes = JSON.parse(JSON.stringify(recipes));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,12 @@
 | 
			
		||||
import type {rand_array} from '$lib/js/randomize';
 | 
			
		||||
import { json, type RequestHandler } from '@sveltejs/kit';
 | 
			
		||||
import { Recipe } from '../../../../../models/Recipe'
 | 
			
		||||
import { dbConnect, dbDisconnect } from '../../../../../utils/db';
 | 
			
		||||
import { rand_array } from '$lib/js/randomize';
 | 
			
		||||
 | 
			
		||||
export const GET: RequestHandler = async ({params}) => {
 | 
			
		||||
  await dbConnect();
 | 
			
		||||
  let found_in_season = (await Recipe.find({season: params.month}, 'name short_name images tags category icon description season').lean());
 | 
			
		||||
  let found_in_season = rand_array(await Recipe.find({season: params.month}, 'name short_name images tags category icon description season').lean());
 | 
			
		||||
  await dbDisconnect();
 | 
			
		||||
  found_in_season = JSON.parse(JSON.stringify(found_in_season));
 | 
			
		||||
  return json(found_in_season);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,11 @@ import { json, type RequestHandler } from '@sveltejs/kit';
 | 
			
		||||
import { Recipe } from '../../../../../models/Recipe';
 | 
			
		||||
import { dbConnect, dbDisconnect } from '../../../../../utils/db';
 | 
			
		||||
import type {BriefRecipeType} from '../../../../../types/types';
 | 
			
		||||
import { rand_array } from '$lib/js/randomize';
 | 
			
		||||
 | 
			
		||||
export const GET: RequestHandler = async ({params}) => {
 | 
			
		||||
  await dbConnect();
 | 
			
		||||
  let recipes = (await Recipe.find({tags: params.tag}, 'name short_name images tags category icon description season').lean()) as BriefRecipeType[];
 | 
			
		||||
  let recipes = rand_array(await Recipe.find({tags: params.tag}, 'name short_name images tags category icon description season').lean()) as BriefRecipeType[];
 | 
			
		||||
  await dbDisconnect();
 | 
			
		||||
 | 
			
		||||
  recipes = JSON.parse(JSON.stringify(recipes));
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    	export let data: PageData;
 | 
			
		||||
    	export let current_month = new Date().getMonth() + 1
 | 
			
		||||
	const all_categories = [ ...new Set (data.all_brief.map(item => item.category))];
 | 
			
		||||
	import { rand_array } from '$lib/js/randomize';
 | 
			
		||||
	const categories = ["Hauptspeise", "Nudel", "Brot", "Dessert", "Suppe", "Beilage", "Salat", "Kuchen", "Sauce", "Zutat", "Aufstrich", "Guetzli"]
 | 
			
		||||
</script>
 | 
			
		||||
<style>
 | 
			
		||||
h1{
 | 
			
		||||
@@ -21,16 +21,16 @@ h1{
 | 
			
		||||
<h1>Rezepte</h1>
 | 
			
		||||
<section>
 | 
			
		||||
<MediaScroller title="In Saison:">
 | 
			
		||||
{#each rand_array(data.season) as recipe}
 | 
			
		||||
{#each data.season as recipe}
 | 
			
		||||
	<Card {recipe} {current_month} search=""></Card>
 | 
			
		||||
{/each}
 | 
			
		||||
</MediaScroller>
 | 
			
		||||
</section>
 | 
			
		||||
<Search></Search>
 | 
			
		||||
 | 
			
		||||
{#each all_categories as category}
 | 
			
		||||
{#each categories as category}
 | 
			
		||||
	<MediaScroller title={category}>
 | 
			
		||||
	{#each rand_array(data.all_brief.filter(recipe => recipe.category == category)) as recipe}
 | 
			
		||||
	{#each data.all_brief.filter(recipe => recipe.category == category) as recipe}
 | 
			
		||||
		<Card {recipe} {current_month}></Card>
 | 
			
		||||
	{/each}
 | 
			
		||||
	</MediaScroller>
 | 
			
		||||
 
 | 
			
		||||
@@ -85,7 +85,7 @@
 | 
			
		||||
		console.log(img_local)
 | 
			
		||||
        	const data = {
 | 
			
		||||
			image: img_local,
 | 
			
		||||
			filename: short_name + '.webp',
 | 
			
		||||
			name: short_name,
 | 
			
		||||
			bearer: password,
 | 
			
		||||
		}
 | 
			
		||||
        	await fetch(`/api/img/add`, {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,41 +1,46 @@
 | 
			
		||||
<script lang=ts>
 | 
			
		||||
    let fileInput;
 | 
			
		||||
    let files;
 | 
			
		||||
    let temp
 | 
			
		||||
    let image : String;
 | 
			
		||||
    let base64
 | 
			
		||||
let src_full = ''
 | 
			
		||||
let src_thumbnail = ''
 | 
			
		||||
let src_placeholder = ''
 | 
			
		||||
let alt = 'Random Image'
 | 
			
		||||
let API = '/api/img/test1'
 | 
			
		||||
import { onMount } from 'svelte';
 | 
			
		||||
import Card from '$lib/components/Card.svelte';
 | 
			
		||||
 | 
			
		||||
    export function store_img_base64(image) {
 | 
			
		||||
        const reader = new FileReader();
 | 
			
		||||
        reader.readAsDataURL(image);
 | 
			
		||||
        reader.onload = e => {
 | 
			
		||||
            base64 = e.target.result.split(',')[1];
 | 
			
		||||
	    //base64 = temp.split(',')[1]
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
onMount(async () => {
 | 
			
		||||
    loadPlaceholder()
 | 
			
		||||
    loadImage()
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
export async function loadImage() {
 | 
			
		||||
    const res = await fetch(API)
 | 
			
		||||
    let image = await res.json()
 | 
			
		||||
    image = JSON.parse(image.img)
 | 
			
		||||
    src_placeholder = "data:image/webp;base64, " + image.image
 | 
			
		||||
    const img_el = document.querySelector("#img")
 | 
			
		||||
    img_el?.classList.toggle("blur")
 | 
			
		||||
    src_thumbnail = "data:image/webp;base64, " + image.thumbnail
 | 
			
		||||
  }
 | 
			
		||||
export async function loadPlaceholder() {
 | 
			
		||||
    const url = '/api/img/placeholder/test1'
 | 
			
		||||
    const res = await fetch(url)
 | 
			
		||||
    let image = await res.json()
 | 
			
		||||
    image = JSON.parse(image.img)
 | 
			
		||||
    src_placeholder = "data:image/webp;base64, " + image.placeholder
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    export async function upload(){
 | 
			
		||||
    	console.log("uploading...")
 | 
			
		||||
        const data = {
 | 
			
		||||
		image: base64,
 | 
			
		||||
		filename: "test.webp"
 | 
			
		||||
	}
 | 
			
		||||
        await fetch(`/api/img/add`, {
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            headers: {
 | 
			
		||||
                'Content-Type': 'application/json',
 | 
			
		||||
                Accept: 'application/json'
 | 
			
		||||
            },
 | 
			
		||||
            body: JSON.stringify(data)
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<input id="file-to-upload" type="file" accept=".png,.jpg,.webp" bind:files bind:this={fileInput} on:change={() => store_img_base64(files[0])}/>
 | 
			
		||||
<button class="upload-btn" on:click="{upload}">Upload</button>
 | 
			
		||||
<button on:click={console.log(base64)}></button>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
img{
 | 
			
		||||
	width: 300px;
 | 
			
		||||
	height: 300px;
 | 
			
		||||
	object-fit: cover;
 | 
			
		||||
	transition: 300ms;
 | 
			
		||||
}
 | 
			
		||||
.blur{
 | 
			
		||||
	filter: blur(8px);
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
<img id=img src={src_placeholder} class=blur {alt}/>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,249 +0,0 @@
 | 
			
		||||
<form action="/api/img/add" method="post" enctype="multipart/form-data">
 | 
			
		||||
  <input type="file" name="image" placeholder="avatar" />
 | 
			
		||||
  <input type="text" name="filename" placeholder=filename />
 | 
			
		||||
  <button type="submit">upload</button>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import Check from '$lib/assets/icons/Check.svelte';
 | 
			
		||||
	import SeasonSelect from '$lib/components/SeasonSelect.svelte';
 | 
			
		||||
	import '$lib/css/action_button.css'
 | 
			
		||||
 | 
			
		||||
    	export let data: PageData;
 | 
			
		||||
	let preamble = ""
 | 
			
		||||
	let addendum = ""
 | 
			
		||||
 | 
			
		||||
	import { season } from '$lib/js/season_store';
 | 
			
		||||
	season.update(() => [])
 | 
			
		||||
	let season_local
 | 
			
		||||
	season.subscribe((s) => {
 | 
			
		||||
		season_local = s
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	export let card_data ={
 | 
			
		||||
		icon: "",
 | 
			
		||||
		category: "",
 | 
			
		||||
		name: "",
 | 
			
		||||
		description: "",
 | 
			
		||||
		tags: [],
 | 
			
		||||
	}
 | 
			
		||||
	export let add_info ={
 | 
			
		||||
		preparation: "",
 | 
			
		||||
		fermentation: {
 | 
			
		||||
			bulk: "",
 | 
			
		||||
			final: "",
 | 
			
		||||
		},
 | 
			
		||||
		baking: {
 | 
			
		||||
			length: "",
 | 
			
		||||
			temperature: "",
 | 
			
		||||
			mode: "",
 | 
			
		||||
		},
 | 
			
		||||
		total_time: "",
 | 
			
		||||
		cooking: "",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	let images = []
 | 
			
		||||
	export let portions = ""
 | 
			
		||||
 | 
			
		||||
	let short_name = ""
 | 
			
		||||
	let password
 | 
			
		||||
	let datecreated =  new Date()
 | 
			
		||||
	let datemodified = datecreated
 | 
			
		||||
 | 
			
		||||
    	import type { PageData } from './$types';
 | 
			
		||||
	import CardAdd from '$lib/components/CardAdd.svelte';
 | 
			
		||||
 | 
			
		||||
	import CreateIngredientList from '$lib/components/CreateIngredientList.svelte';
 | 
			
		||||
	export let ingredients = []
 | 
			
		||||
 | 
			
		||||
	import CreateStepList from '$lib/components/CreateStepList.svelte';
 | 
			
		||||
	export let instructions = []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	function get_season(){
 | 
			
		||||
		let season = []
 | 
			
		||||
		const el = document.getElementById("labels");
 | 
			
		||||
		for(var i = 0; i < el.children.length; i++){
 | 
			
		||||
			if(el.children[i].children[0].children[0].checked){
 | 
			
		||||
				season.push(i+1)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return season
 | 
			
		||||
	}
 | 
			
		||||
	function write_season(season){
 | 
			
		||||
		const el = document.getElementById("labels");
 | 
			
		||||
		for(var i = 0; i < season.length; i++){
 | 
			
		||||
			el.children[i].children[0].children[0].checked = true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	async function doPost () {
 | 
			
		||||
		console.log(add_info.total_time)
 | 
			
		||||
		const res = await fetch('/api/add', {
 | 
			
		||||
			method: 'POST',
 | 
			
		||||
			body: JSON.stringify({
 | 
			
		||||
				recipe: {
 | 
			
		||||
					...card_data,
 | 
			
		||||
					...add_info,
 | 
			
		||||
					images: {mediapath: short_name + '.webp', alt: "", caption: ""}, // TODO
 | 
			
		||||
					season: season_local,
 | 
			
		||||
					short_name,
 | 
			
		||||
					portions,
 | 
			
		||||
					datecreated,
 | 
			
		||||
					datemodified,
 | 
			
		||||
					instructions,
 | 
			
		||||
					ingredients,
 | 
			
		||||
					preamble,
 | 
			
		||||
					addendum,
 | 
			
		||||
				},
 | 
			
		||||
			headers: {
 | 
			
		||||
       				'content-type': 'application/json',
 | 
			
		||||
				bearer: password,
 | 
			
		||||
     				}
 | 
			
		||||
			})
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
input{
 | 
			
		||||
	display: block;
 | 
			
		||||
	border: unset;
 | 
			
		||||
	margin: 1rem auto;
 | 
			
		||||
	padding: 0.5em 1em;
 | 
			
		||||
	border-radius: 1000px;
 | 
			
		||||
	background-color: var(--nord4);
 | 
			
		||||
	font-size: 1.1rem;
 | 
			
		||||
	transition: 100ms;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
input:hover,
 | 
			
		||||
input:focus-visible
 | 
			
		||||
{
 | 
			
		||||
	scale: 1.05 1.05;
 | 
			
		||||
}
 | 
			
		||||
.list_wrapper{
 | 
			
		||||
	margin-inline: auto;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: row;
 | 
			
		||||
	max-width: 1000px;
 | 
			
		||||
	gap: 2rem;
 | 
			
		||||
	justify-content: center;
 | 
			
		||||
}
 | 
			
		||||
@media screen and (max-width: 700px){
 | 
			
		||||
	.list_wrapper{
 | 
			
		||||
		flex-direction: column;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
input[type=password]{
 | 
			
		||||
	box-sizing: border-box;
 | 
			
		||||
	font-size: 1.5rem;
 | 
			
		||||
	padding-block: 0.5em;
 | 
			
		||||
	display: inline;
 | 
			
		||||
	width: 100%;
 | 
			
		||||
}
 | 
			
		||||
.submit_wrapper{
 | 
			
		||||
	position: relative;
 | 
			
		||||
	margin-inline: auto;
 | 
			
		||||
	width: max(300px, 50vw)
 | 
			
		||||
}
 | 
			
		||||
.submit_wrapper button{
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	right:-1em;
 | 
			
		||||
	bottom: -0.5em;
 | 
			
		||||
}
 | 
			
		||||
.submit_wrapper h2{
 | 
			
		||||
	margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
h1{
 | 
			
		||||
	text-align: center;
 | 
			
		||||
	margin-bottom: 2rem;
 | 
			
		||||
}
 | 
			
		||||
.title_container{
 | 
			
		||||
	max-width: 1000px;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	flex-direction: column;
 | 
			
		||||
	margin-inline: auto;
 | 
			
		||||
}
 | 
			
		||||
.title{
 | 
			
		||||
	position: relative;
 | 
			
		||||
	width: min(800px, 80vw);
 | 
			
		||||
	margin-block: 2rem;
 | 
			
		||||
	margin-inline: auto;
 | 
			
		||||
	background-color: var(--nord6);
 | 
			
		||||
	padding: 1rem 2rem;
 | 
			
		||||
}
 | 
			
		||||
.title p{
 | 
			
		||||
	border: 2px solid var(--nord1);
 | 
			
		||||
	border-radius: 10000px;
 | 
			
		||||
	padding: 0.5em 1em;
 | 
			
		||||
	font-size: 1.1rem;
 | 
			
		||||
	transition: 200ms;
 | 
			
		||||
}
 | 
			
		||||
.title p:hover,
 | 
			
		||||
.title p:focus-within{
 | 
			
		||||
	scale: 1.02 1.02;
 | 
			
		||||
}
 | 
			
		||||
.addendum{
 | 
			
		||||
	font-size: 1.1rem;
 | 
			
		||||
	max-width: 90%;
 | 
			
		||||
	margin-inline: auto;
 | 
			
		||||
	border: 2px solid var(--nord1);
 | 
			
		||||
	border-radius: 45px;
 | 
			
		||||
	padding: 1em 1em;
 | 
			
		||||
	transition: 100ms;
 | 
			
		||||
}
 | 
			
		||||
.addendum:hover,
 | 
			
		||||
.addendum:focus-within
 | 
			
		||||
{
 | 
			
		||||
	scale: 1.02 1.02;
 | 
			
		||||
}
 | 
			
		||||
.addendum_wrapper{
 | 
			
		||||
	max-width: 1000px;
 | 
			
		||||
	margin-inline: auto;
 | 
			
		||||
}
 | 
			
		||||
h3{
 | 
			
		||||
	text-align: center;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
<h1>Rezept erstellen</h1>
 | 
			
		||||
<form action="/api/img/add" method="post" enctype="multipart/form-data">
 | 
			
		||||
<CardAdd {card_data}></CardAdd>
 | 
			
		||||
 | 
			
		||||
<h3>Kurzname (für URL):</h3>
 | 
			
		||||
<input bind:value={short_name} placeholder="Kurzname"/>
 | 
			
		||||
 | 
			
		||||
<div class=title_container>
 | 
			
		||||
<div class=title>
 | 
			
		||||
<h4>Eine etwas längere Beschreibung:</h4>
 | 
			
		||||
<p bind:innerText={preamble} contenteditable></p>
 | 
			
		||||
<div class=tags>
 | 
			
		||||
<h4>Saison:</h4>
 | 
			
		||||
<SeasonSelect></SeasonSelect>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
</div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<div class=list_wrapper>
 | 
			
		||||
<div>
 | 
			
		||||
<CreateIngredientList {ingredients} {portions}></CreateIngredientList>
 | 
			
		||||
</div>
 | 
			
		||||
<div>
 | 
			
		||||
<CreateStepList {instructions} {add_info}></CreateStepList>
 | 
			
		||||
</div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<div class=addendum_wrapper>
 | 
			
		||||
<h3>Nachtrag:</h3>
 | 
			
		||||
<div class=addendum bind:innerText={addendum} contenteditable></div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<div class=submit_wrapper>
 | 
			
		||||
<h2>Neues Rezept hinzufügen:</h2>
 | 
			
		||||
<input type="password" placeholder=Passwort bind:value={password}>
 | 
			
		||||
<button type=submit class=action_button on:click={doPost}><Check fill=white width=2rem height=2rem></Check></button>
 | 
			
		||||
</form>
 | 
			
		||||
</div>
 | 
			
		||||
		Reference in New Issue
	
	Block a user