mirror of
https://github.com/taogaetz/chefbible.git
synced 2025-12-06 11:47:24 -05:00
added categories for dish and ingredient
This commit is contained in:
parent
f241b06336
commit
1c0ce2d741
@ -0,0 +1,21 @@
|
|||||||
|
-- RedefineTables
|
||||||
|
PRAGMA defer_foreign_keys=ON;
|
||||||
|
PRAGMA foreign_keys=OFF;
|
||||||
|
CREATE TABLE "new_Recipe" (
|
||||||
|
"id" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"description" TEXT,
|
||||||
|
"instructions" TEXT,
|
||||||
|
"photoUrl" TEXT,
|
||||||
|
"time" TEXT NOT NULL DEFAULT 'Medium',
|
||||||
|
"station" TEXT NOT NULL DEFAULT 'Pans',
|
||||||
|
"type" TEXT NOT NULL DEFAULT 'Dish',
|
||||||
|
"hidden" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" DATETIME NOT NULL
|
||||||
|
);
|
||||||
|
INSERT INTO "new_Recipe" ("createdAt", "description", "hidden", "id", "instructions", "name", "photoUrl", "station", "time", "updatedAt") SELECT "createdAt", "description", "hidden", "id", "instructions", "name", "photoUrl", "station", "time", "updatedAt" FROM "Recipe";
|
||||||
|
DROP TABLE "Recipe";
|
||||||
|
ALTER TABLE "new_Recipe" RENAME TO "Recipe";
|
||||||
|
PRAGMA foreign_keys=ON;
|
||||||
|
PRAGMA defer_foreign_keys=OFF;
|
||||||
@ -25,6 +25,7 @@ model Recipe {
|
|||||||
photoUrl String?
|
photoUrl String?
|
||||||
time String @default("Medium") // Quick, Medium, Long
|
time String @default("Medium") // Quick, Medium, Long
|
||||||
station String @default("Pans") // Garde Manger, Pans, Grill
|
station String @default("Pans") // Garde Manger, Pans, Grill
|
||||||
|
type String @default("Dish") // Ingredient or Dish
|
||||||
hidden Boolean @default(false) // Hidden from non-chefs
|
hidden Boolean @default(false) // Hidden from non-chefs
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|||||||
29
src/routes/dishes/+page.server.ts
Normal file
29
src/routes/dishes/+page.server.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
import prisma from '$lib/server/prisma';
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async ({ locals }) => {
|
||||||
|
// Get dish recipes only
|
||||||
|
// If not authenticated, filter out hidden recipes
|
||||||
|
const recipes = await prisma.recipe.findMany({
|
||||||
|
where: {
|
||||||
|
type: 'Dish',
|
||||||
|
...(locals.authenticated ? {} : { hidden: false })
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
ingredients: {
|
||||||
|
include: {
|
||||||
|
ingredient: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
createdAt: 'desc'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
recipes,
|
||||||
|
authenticated: locals.authenticated,
|
||||||
|
hasAccess: locals.hasAccess
|
||||||
|
};
|
||||||
|
};
|
||||||
33
src/routes/dishes/+page.svelte
Normal file
33
src/routes/dishes/+page.svelte
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { PageProps } from './$types';
|
||||||
|
import RecipeCard from '$lib/components/RecipeCard.svelte';
|
||||||
|
|
||||||
|
let { data }: PageProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Dishes - Chef Bible</title>
|
||||||
|
<meta name="description" content="Dish recipes" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<main class="m-0 min-h-screen bg-gradient-to-br from-base-200 to-base-300 p-0">
|
||||||
|
<section class="mx-auto max-w-7xl p-10 lg:p-6">
|
||||||
|
<div class="mb-4">
|
||||||
|
<h1 class="text-sm text-base-content/60">
|
||||||
|
<a href="/" class="hover:underline">Home</a> / Dishes
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||||
|
{#each data.recipes as recipe}
|
||||||
|
<RecipeCard {recipe} authenticated={data.authenticated} />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if data.recipes.length === 0}
|
||||||
|
<div class="mt-12 text-center">
|
||||||
|
<p class="text-base-content/60">No dish recipes found.</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
29
src/routes/ingredients/+page.server.ts
Normal file
29
src/routes/ingredients/+page.server.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
import prisma from '$lib/server/prisma';
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async ({ locals }) => {
|
||||||
|
// Get ingredient recipes only
|
||||||
|
// If not authenticated, filter out hidden recipes
|
||||||
|
const recipes = await prisma.recipe.findMany({
|
||||||
|
where: {
|
||||||
|
type: 'Ingredient',
|
||||||
|
...(locals.authenticated ? {} : { hidden: false })
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
ingredients: {
|
||||||
|
include: {
|
||||||
|
ingredient: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
createdAt: 'desc'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
recipes,
|
||||||
|
authenticated: locals.authenticated,
|
||||||
|
hasAccess: locals.hasAccess
|
||||||
|
};
|
||||||
|
};
|
||||||
33
src/routes/ingredients/+page.svelte
Normal file
33
src/routes/ingredients/+page.svelte
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { PageProps } from './$types';
|
||||||
|
import RecipeCard from '$lib/components/RecipeCard.svelte';
|
||||||
|
|
||||||
|
let { data }: PageProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Ingredients - Chef Bible</title>
|
||||||
|
<meta name="description" content="Ingredient recipes" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<main class="m-0 min-h-screen bg-gradient-to-br from-base-200 to-base-300 p-0">
|
||||||
|
<section class="mx-auto max-w-7xl p-10 lg:p-6">
|
||||||
|
<div class="mb-4">
|
||||||
|
<h1 class="text-sm text-base-content/60">
|
||||||
|
<a href="/" class="hover:underline">Home</a> / Ingredients
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||||
|
{#each data.recipes as recipe}
|
||||||
|
<RecipeCard {recipe} authenticated={data.authenticated} />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if data.recipes.length === 0}
|
||||||
|
<div class="mt-12 text-center">
|
||||||
|
<p class="text-base-content/60">No ingredient recipes found.</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
@ -24,6 +24,7 @@ export const POST: RequestHandler = async ({ request, params }) => {
|
|||||||
const instructions = (formData.get('instructions') as string | null)?.trim() || null;
|
const instructions = (formData.get('instructions') as string | null)?.trim() || null;
|
||||||
const time = ((formData.get('time') as string | null)?.trim() || 'Medium') as string;
|
const time = ((formData.get('time') as string | null)?.trim() || 'Medium') as string;
|
||||||
const station = ((formData.get('station') as string | null)?.trim() || 'Pans') as string;
|
const station = ((formData.get('station') as string | null)?.trim() || 'Pans') as string;
|
||||||
|
const type = ((formData.get('type') as string | null)?.trim() || 'Dish') as string;
|
||||||
const hidden = formData.get('hidden') === 'on'; // Checkbox returns 'on' when checked
|
const hidden = formData.get('hidden') === 'on'; // Checkbox returns 'on' when checked
|
||||||
const photo = formData.get('photo') as File | null;
|
const photo = formData.get('photo') as File | null;
|
||||||
const parsedIngredientsRaw = formData.get('parsedIngredients') as string | null;
|
const parsedIngredientsRaw = formData.get('parsedIngredients') as string | null;
|
||||||
@ -101,6 +102,7 @@ export const POST: RequestHandler = async ({ request, params }) => {
|
|||||||
photoUrl: photoUrl || existingRecipe.photoUrl, // Keep existing photo if no new one uploaded
|
photoUrl: photoUrl || existingRecipe.photoUrl, // Keep existing photo if no new one uploaded
|
||||||
time,
|
time,
|
||||||
station,
|
station,
|
||||||
|
type,
|
||||||
hidden
|
hidden
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -24,6 +24,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
|||||||
const instructions = (formData.get('instructions') as string | null)?.trim() || null;
|
const instructions = (formData.get('instructions') as string | null)?.trim() || null;
|
||||||
const time = ((formData.get('time') as string | null)?.trim() || 'Medium') as string;
|
const time = ((formData.get('time') as string | null)?.trim() || 'Medium') as string;
|
||||||
const station = ((formData.get('station') as string | null)?.trim() || 'Pans') as string;
|
const station = ((formData.get('station') as string | null)?.trim() || 'Pans') as string;
|
||||||
|
const type = ((formData.get('type') as string | null)?.trim() || 'Dish') as string;
|
||||||
const hidden = formData.get('hidden') === 'on'; // Checkbox returns 'on' when checked
|
const hidden = formData.get('hidden') === 'on'; // Checkbox returns 'on' when checked
|
||||||
const photo = formData.get('photo') as File | null;
|
const photo = formData.get('photo') as File | null;
|
||||||
const parsedIngredientsRaw = formData.get('parsedIngredients') as string | null;
|
const parsedIngredientsRaw = formData.get('parsedIngredients') as string | null;
|
||||||
@ -91,6 +92,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
|||||||
photoUrl,
|
photoUrl,
|
||||||
time,
|
time,
|
||||||
station,
|
station,
|
||||||
|
type,
|
||||||
hidden
|
hidden
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user