Added seeder
This commit is contained in:
137
Seasoned.Backend/Data/DbInitializer.cs
Normal file
137
Seasoned.Backend/Data/DbInitializer.cs
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
using Seasoned.Backend.Models;
|
||||||
|
using Seasoned.Backend.Data;
|
||||||
|
using Pgvector;
|
||||||
|
|
||||||
|
namespace Seasoned.Backend.Data
|
||||||
|
{
|
||||||
|
public static class DbInitializer
|
||||||
|
{
|
||||||
|
public static void Initialize(ApplicationDbContext context)
|
||||||
|
{
|
||||||
|
context.Database.EnsureCreated();
|
||||||
|
|
||||||
|
if (context.Recipes.Any()) return;
|
||||||
|
|
||||||
|
string testUserId = "0c55c0ed-8080-482d-8ebd-1054cdc3b672";
|
||||||
|
|
||||||
|
var dummyEmbedding = new Vector(new float[768]);
|
||||||
|
|
||||||
|
var recipes = new List<Recipe>
|
||||||
|
{
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Miso-Glazed Smashed Burger",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1550547660-d9450f859349?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "1/2 lb Ground Beef", "1 tbsp White Miso", "Brioche Bun", "Pickled Ginger" },
|
||||||
|
Instructions = new List<string> { "Mix miso into beef.", "Smash thin on high heat.", "Sear until crispy." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-1),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Heirloom Tomato Galette",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1595126731003-7337def8d5ee?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Puff Pastry", "Heirloom Tomatoes", "Ricotta", "Thyme" },
|
||||||
|
Instructions = new List<string> { "Spread ricotta on pastry.", "Layer tomatoes.", "Bake at 200°C until golden." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-2),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Whipped Feta & Hot Honey Toast",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1525351484163-7529414344d8?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Sourdough", "Feta Cheese", "Greek Yogurt", "Hot Honey" },
|
||||||
|
Instructions = new List<string> { "Whip feta and yogurt.", "Toast sourdough.", "Spread and drizzle honey." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-3),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Thai Basil Pesto Pasta",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1473093226795-af9932fe5856?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Linguine", "Thai Basil", "Cashews", "Garlic", "Chili Flakes", "Olive Oil" },
|
||||||
|
Instructions = new List<string> { "Blend basil, cashews, and garlic into a paste.", "Toss with hot pasta.", "Garnish with chili flakes and fresh basil." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-4),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Smoked Gouda & Broccolini Soup",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1547592166-23ac45744acd?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Broccolini", "Smoked Gouda", "Heavy Cream", "Vegetable Broth", "Nutmeg" },
|
||||||
|
Instructions = new List<string> { "Simmer broccolini in broth until tender.", "Blend until smooth.", "Whisk in cream and grated gouda until melted." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-5),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Charred Octopus with Romesco",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1551024506-0bccd828d307?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Octopus Tentacles", "Roasted Red Peppers", "Almonds", "Sherry Vinegar", "Smoked Paprika" },
|
||||||
|
Instructions = new List<string> { "Blanch octopus then grill over high heat.", "Process peppers, nuts, and vinegar for romesco.", "Serve charred over a bed of sauce." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-6),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Truffle Honey Fried Chicken",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1562967914-608f82629710?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Chicken Thighs", "Buttermilk", "Flour", "Truffle Oil", "Wildflower Honey" },
|
||||||
|
Instructions = new List<string> { "Marinate chicken in buttermilk.", "Dredge and deep fry until 75°C internal.", "Drizzle with truffle-infused honey immediately." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-7),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Burrata with Roasted Grapes",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1604908176997-125f25cc6f3d?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Burrata Cheese", "Red Grapes", "Balsamic Glaze", "Fresh Mint", "Sourdough" },
|
||||||
|
Instructions = new List<string> { "Roast grapes at 200°C until they burst.", "Place burrata in the center of the plate.", "Top with warm grapes and balsamic drizzle." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-8),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Black Garlic Shoyu Ramen",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1569718212165-3a8278d5f624?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Ramen Noodles", "Pork Belly", "Black Garlic Oil", "Soft Boiled Egg", "Nori" },
|
||||||
|
Instructions = new List<string> { "Slow roast pork belly until tender.", "Prepare shoyu broth with black garlic oil.", "Assemble with noodles and traditional toppings." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-9),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Espresso Rubbed Skirt Steak",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1546241072-48010ad28c2c?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Skirt Steak", "Fine Coffee Grounds", "Brown Sugar", "Ancho Chili Powder", "Cumin" },
|
||||||
|
Instructions = new List<string> { "Mix coffee and spices for the rub.", "Coat steak and let sit for 30 minutes.", "Sear on a cast iron skillet for 3 minutes per side." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-10),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
},
|
||||||
|
new Recipe
|
||||||
|
{
|
||||||
|
Title = "Matcha White Chocolate Blondies",
|
||||||
|
UserId = testUserId,
|
||||||
|
ImageUrl = "https://images.unsplash.com/photo-1515037893149-de7f840978e2?q=80&w=800",
|
||||||
|
Ingredients = new List<string> { "Matcha Powder", "White Chocolate Chips", "Butter", "Flour", "Sea Salt" },
|
||||||
|
Instructions = new List<string> { "Melt butter and whisk with sugar and matcha.", "Fold in flour and chocolate chips.", "Bake at 175°C for 25 minutes until edges set." },
|
||||||
|
CreatedAt = DateTime.UtcNow.AddDays(-11),
|
||||||
|
Embedding = dummyEmbedding
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
context.Recipes.AddRange(recipes);
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -91,28 +91,5 @@ const printRecipe = () => {
|
|||||||
window.print()
|
window.print()
|
||||||
}
|
}
|
||||||
|
|
||||||
// mock output
|
|
||||||
/*const recipe = ref({
|
|
||||||
title: "Bakery-Style Lemon Blueberry Muffins",
|
|
||||||
ingredients: [
|
|
||||||
"2 cups all-purpose flour",
|
|
||||||
"1/2 cup granulated sugar",
|
|
||||||
"2 tsp baking powder",
|
|
||||||
"1/2 tsp salt",
|
|
||||||
"1/2 cup unsalted butter, melted",
|
|
||||||
"2 large eggs",
|
|
||||||
"1/2 cup whole milk",
|
|
||||||
"1 tbsp fresh lemon zest",
|
|
||||||
"2 tbsp fresh lemon juice",
|
|
||||||
"1 1/2 cups fresh blueberries"
|
|
||||||
],
|
|
||||||
instructions: [
|
|
||||||
"Preheat your oven to 375°F (190°C) and line a muffin tin with paper liners.",
|
|
||||||
"In a large bowl, whisk together the flour, sugar, baking powder, and salt.",
|
|
||||||
"In a separate bowl, whisk the melted butter, eggs, milk, lemon zest, and lemon juice.",
|
|
||||||
"Pour the wet ingredients into the dry and stir gently until just combined; do not overmix or the muffins will be tough.",
|
|
||||||
"Toss the blueberries in a teaspoon of flour, then gently fold them into the batter.",
|
|
||||||
"Divide the batter evenly into the muffin cups and bake for 18-20 minutes until golden."
|
|
||||||
]
|
|
||||||
}) */
|
|
||||||
</script>
|
</script>
|
||||||
@@ -122,10 +122,14 @@
|
|||||||
width="160"
|
width="160"
|
||||||
height="160"
|
height="160"
|
||||||
:class="[
|
:class="[
|
||||||
'rounded-lg d-flex align-center justify-center cursor-pointer position-relative overflow-hidden',
|
'rounded-lg d-flex align-center justify-center position-relative overflow-hidden',
|
||||||
{ 'image-drop-zone': isEditing }
|
{
|
||||||
|
'image-drop-zone': isEditing,
|
||||||
|
'cursor-pointer': isEditing
|
||||||
|
}
|
||||||
]"
|
]"
|
||||||
@click="isEditing ? $refs.fileInput.click() : null"
|
:style="{ pointerEvents: isEditing ? 'auto' : 'none' }"
|
||||||
|
@click="isEditing ? $refs.fileInput.click() : null"
|
||||||
:elevation="isHovering && isEditing ? 4 : 1"
|
:elevation="isHovering && isEditing ? 4 : 1"
|
||||||
>
|
>
|
||||||
<v-img
|
<v-img
|
||||||
@@ -163,10 +167,10 @@
|
|||||||
|
|
||||||
<v-divider class="mb-8 separator"></v-divider>
|
<v-divider class="mb-8 separator"></v-divider>
|
||||||
|
|
||||||
<v-row class="px-md-4">
|
<v-row class="mt-10" density="compact">
|
||||||
<v-col cols="12" md="5">
|
<v-col cols="12" md="5" class="pe-md-10">
|
||||||
<h3 class="section-header mb-4">
|
<h3 class="section-header justify-center mb-6">
|
||||||
<v-icon icon="mdi-basket-outline" class="mr-2" size="small"></v-icon>
|
<v-icon icon="mdi-spoon-sugar" class="mr-2" size="small"></v-icon>
|
||||||
Ingredients
|
Ingredients
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
@@ -182,20 +186,20 @@
|
|||||||
:persistent-placeholder="true"
|
:persistent-placeholder="true"
|
||||||
></v-textarea>
|
></v-textarea>
|
||||||
|
|
||||||
<v-list v-else class="ingredients-list bg-transparent">
|
<div v-else class="ingredients-container">
|
||||||
<v-list-item
|
<div
|
||||||
v-for="(ing, index) in (Array.isArray(selectedRecipe.ingredients) ? selectedRecipe.ingredients : selectedRecipe.ingredients?.split('\n') || [])"
|
v-for="(ing, index) in (Array.isArray(selectedRecipe.ingredients) ? selectedRecipe.ingredients : selectedRecipe.ingredients?.split('\n') || [])"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="ingredient-item px-0"
|
class="ingredient-item"
|
||||||
>
|
>
|
||||||
• {{ ing }}
|
{{ ing }}
|
||||||
</v-list-item>
|
</div>
|
||||||
</v-list>
|
</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="12" md="7">
|
<v-col cols="12" md="7" class="ps-md-10">
|
||||||
<h3 class="section-header mb-4">
|
<h3 class="section-header justify-center mb-6">
|
||||||
<v-icon icon="mdi-chef-hat" class="mr-2" size="small"></v-icon>
|
<v-icon icon="mdi-pot-steam-outline" class="mr-2" size="small"></v-icon>
|
||||||
Instructions
|
Instructions
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
@@ -214,10 +218,10 @@
|
|||||||
<div v-else
|
<div v-else
|
||||||
v-for="(step, index) in (Array.isArray(selectedRecipe.instructions) ? selectedRecipe.instructions : selectedRecipe.instructions?.split('\n') || [])"
|
v-for="(step, index) in (Array.isArray(selectedRecipe.instructions) ? selectedRecipe.instructions : selectedRecipe.instructions?.split('\n') || [])"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="instruction-step mb-4"
|
class="instruction-step mb-8"
|
||||||
>
|
>
|
||||||
<span class="step-number">{{ index + 1 }}</span>
|
<span class="step-number">{{ index + 1 }}.</span>
|
||||||
<p>{{ step }}</p>
|
<p class="step-text">{{ step }}</p>
|
||||||
</div>
|
</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
@@ -237,8 +241,77 @@ import { ref, onMounted, computed, watch } from 'vue'
|
|||||||
import '@/assets/css/gallery.css'
|
import '@/assets/css/gallery.css'
|
||||||
import '@/assets/css/app-theme.css'
|
import '@/assets/css/app-theme.css'
|
||||||
|
|
||||||
const recipes = ref([])
|
const mockRecipes = [
|
||||||
const loading = ref(true)
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "Miso-Glazed Smashed Burger",
|
||||||
|
imageUrl: "https://picsum.photos/id/42/800/600",
|
||||||
|
ingredients: ["1/2 lb Ground Beef", "1 tbsp White Miso", "Brioche Bun", "Pickled Ginger"],
|
||||||
|
instructions: ["Mix miso into beef.", "Smash thin on high heat.", "Sear until crispy."],
|
||||||
|
createdAt: "2026-03-18T10:00:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: "Zesty Yuzu Raspberry Bowl",
|
||||||
|
imageUrl: "https://picsum.photos/id/429/800/600",
|
||||||
|
ingredients: ["1 cup Oats", "2 tbsp Yuzu Juice", "Fresh Raspberries", "Honey"],
|
||||||
|
instructions: ["Soak oats overnight.", "Stir in yuzu.", "Top with berries."],
|
||||||
|
createdAt: "2026-03-17T08:30:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: "Caribbean Curry Chickpeas",
|
||||||
|
imageUrl: "https://picsum.photos/id/493/800/600",
|
||||||
|
ingredients: ["1 can Chickpeas", "Coconut Milk", "Curry Powder", "Sweet Potato"],
|
||||||
|
instructions: ["Sauté potatoes.", "Add chickpeas and spices.", "Simmer in coconut milk."],
|
||||||
|
createdAt: "2026-03-16T12:45:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: "Tallow-Crisped Truffle Fries",
|
||||||
|
imageUrl: "https://picsum.photos/id/517/800/600",
|
||||||
|
ingredients: ["Russet Potatoes", "Beef Tallow", "Truffle Salt", "Parsley"],
|
||||||
|
instructions: ["Double fry in tallow.", "Toss with truffle salt.", "Garnish with parsley."],
|
||||||
|
createdAt: "2026-03-15T16:20:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
title: "Smoked Gouda & Broccolini Soup",
|
||||||
|
imageUrl: "https://picsum.photos/id/488/800/600",
|
||||||
|
ingredients: ["Broccolini", "Smoked Gouda", "Heavy Cream", "Vegetable Broth"],
|
||||||
|
instructions: ["Simmer broccolini in broth.", "Blend until smooth.", "Melt in cheese."],
|
||||||
|
createdAt: "2026-03-14T11:10:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
title: "Heirloom Tomato Galette",
|
||||||
|
imageUrl: "https://picsum.photos/id/447/800/600",
|
||||||
|
ingredients: ["Puff Pastry", "Heirloom Tomatoes", "Ricotta", "Thyme"],
|
||||||
|
instructions: ["Spread ricotta on pastry.", "Layer tomatoes.", "Bake at 200°C until golden."],
|
||||||
|
createdAt: "2026-03-13T09:00:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
title: "Thai Basil Pesto Pasta",
|
||||||
|
imageUrl: "https://picsum.photos/id/102/800/600",
|
||||||
|
ingredients: ["Linguine", "Thai Basil", "Cashews", "Garlic", "Chili Flakes"],
|
||||||
|
instructions: ["Blend basil, cashews, and garlic.", "Toss with hot pasta.", "Add chili for heat."],
|
||||||
|
createdAt: "2026-03-12T19:30:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
title: "Whipped Feta & Hot Honey Toast",
|
||||||
|
imageUrl: "https://picsum.photos/id/311/800/600",
|
||||||
|
ingredients: ["Sourdough", "Feta Cheese", "Greek Yogurt", "Hot Honey"],
|
||||||
|
instructions: ["Whip feta and yogurt.", "Toast sourdough.", "Spread and drizzle honey."],
|
||||||
|
createdAt: "2026-03-11T07:45:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
//const recipes = ref([])
|
||||||
|
const recipes = ref(mockRecipes)
|
||||||
|
const loading = ref(false)
|
||||||
|
//const loading = ref(true)
|
||||||
const showDetails = ref(false)
|
const showDetails = ref(false)
|
||||||
const selectedRecipe = ref(null)
|
const selectedRecipe = ref(null)
|
||||||
const isEditing = ref(false)
|
const isEditing = ref(false)
|
||||||
@@ -249,7 +322,8 @@ const isSearching = ref(false)
|
|||||||
let debounceTimeout = null
|
let debounceTimeout = null
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await fetchRecipes()
|
//await fetchRecipes()
|
||||||
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
const fetchRecipes = async () => {
|
const fetchRecipes = async () => {
|
||||||
@@ -376,4 +450,6 @@ watch(searchQuery, (newVal) => {
|
|||||||
performSearch()
|
performSearch()
|
||||||
}, 600)
|
}, 600)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
Reference in New Issue
Block a user