579 lines
24 KiB
PHP
579 lines
24 KiB
PHP
<?php
|
||
|
||
namespace Database\Seeders;
|
||
|
||
use App\Enums\DietType;
|
||
use App\Enums\FollowStatus;
|
||
use App\Enums\IngredientUnit;
|
||
use App\Enums\MealPostType;
|
||
use App\Enums\MealPostVisibility;
|
||
use App\Enums\NutritionPlanSource;
|
||
use App\Enums\PacePreference;
|
||
use App\Enums\PhysicalActivityLevel;
|
||
use App\Enums\UserRole;
|
||
use App\Enums\UserSex;
|
||
use App\Enums\WeightGoal;
|
||
use App\Enums\WorkoutSource;
|
||
use App\Models\User;
|
||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||
use Illuminate\Database\Seeder;
|
||
use Illuminate\Support\Collection;
|
||
use Illuminate\Support\Facades\DB;
|
||
use LogicException;
|
||
|
||
class DemoContentSeeder extends Seeder
|
||
{
|
||
use WithoutModelEvents;
|
||
|
||
/**
|
||
* Run the database seeds.
|
||
*/
|
||
public function run(): void
|
||
{
|
||
DB::transaction(function (): void {
|
||
$users = $this->createUsers();
|
||
|
||
$this->createMeals($users);
|
||
$this->createSocialGraph($users);
|
||
$this->createProgressHistory($this->demoUser($users));
|
||
});
|
||
}
|
||
|
||
/**
|
||
* @return Collection<int, User>
|
||
*/
|
||
private function createUsers(): Collection
|
||
{
|
||
$users = collect([
|
||
[
|
||
'name' => 'Alex Martin',
|
||
'email' => 'test@example.com',
|
||
'locale' => 'fr',
|
||
'bio' => 'Cuisine simple, course à pied et progression régulière.',
|
||
'account_verified_at' => now(),
|
||
'height' => 178,
|
||
'target_weight' => 68,
|
||
'weight_goal' => WeightGoal::LOSE_WEIGHT,
|
||
'physical_activity_level' => PhysicalActivityLevel::MODERATELY_ACTIVE,
|
||
'pace_preference' => PacePreference::NORMAL,
|
||
'sex' => UserSex::MAN,
|
||
'date_of_birth' => '1994-04-16',
|
||
'terms_accepted_at' => now(),
|
||
],
|
||
[
|
||
'name' => 'Camille Green',
|
||
'email' => 'camille@bowli.test',
|
||
'locale' => 'fr',
|
||
'bio' => 'Recettes végétales colorées et faciles à préparer.',
|
||
'account_verified_at' => now(),
|
||
],
|
||
[
|
||
'name' => 'Noah Kitchen',
|
||
'email' => 'noah@bowli.test',
|
||
'locale' => 'en',
|
||
'bio' => 'High-protein meals without complicated preparation.',
|
||
],
|
||
[
|
||
'name' => 'Lina Fraîcheur',
|
||
'email' => 'lina@bowli.test',
|
||
'locale' => 'fr',
|
||
'bio' => 'Bols frais, produits de saison et cuisine méditerranéenne.',
|
||
'account_verified_at' => now(),
|
||
],
|
||
[
|
||
'name' => 'Sam Fit Food',
|
||
'email' => 'sam@bowli.test',
|
||
'locale' => 'en',
|
||
'bio' => 'Balanced meals for active weeks.',
|
||
],
|
||
[
|
||
'name' => 'Inès Brunch',
|
||
'email' => 'ines@bowli.test',
|
||
'locale' => 'fr',
|
||
'bio' => 'Petits-déjeuners gourmands et brunchs du dimanche.',
|
||
],
|
||
[
|
||
'name' => 'Hugo Maison',
|
||
'email' => 'hugo@bowli.test',
|
||
'locale' => 'fr',
|
||
'bio' => 'Cuisine maison généreuse avec des ingrédients simples.',
|
||
],
|
||
[
|
||
'name' => 'Maya Plant',
|
||
'email' => 'maya@bowli.test',
|
||
'locale' => 'en',
|
||
'bio' => 'Plant-based bowls, soups and snacks.',
|
||
'account_verified_at' => now(),
|
||
],
|
||
[
|
||
'name' => 'Louis Endurance',
|
||
'email' => 'louis@bowli.test',
|
||
'locale' => 'fr',
|
||
'bio' => 'Des repas adaptés aux longues sorties et à la récupération.',
|
||
],
|
||
])->map(
|
||
fn (array $profile): User => $this->createUser($profile)
|
||
);
|
||
|
||
$this->createUser([
|
||
'name' => 'Nouveau profil',
|
||
'email' => 'onboarding@example.com',
|
||
'locale' => 'fr',
|
||
'terms_accepted_at' => now(),
|
||
], withNutritionOnboarding: false);
|
||
|
||
return $users;
|
||
}
|
||
|
||
/**
|
||
* @param array<string, mixed> $profile
|
||
*/
|
||
private function createUser(array $profile, bool $withNutritionOnboarding = true): User
|
||
{
|
||
$onboardingAttributes = $withNutritionOnboarding
|
||
? [
|
||
'height' => 175,
|
||
'target_weight' => 70,
|
||
'date_of_birth' => '1990-01-01',
|
||
'sex' => UserSex::MAN,
|
||
'physical_activity_level' => PhysicalActivityLevel::MODERATELY_ACTIVE,
|
||
'weight_goal' => WeightGoal::MAINTAIN_WEIGHT,
|
||
'pace_preference' => PacePreference::NORMAL,
|
||
'onboarding_completed_at' => now(),
|
||
'nutrition_estimate_accepted_at' => now(),
|
||
]
|
||
: [
|
||
'height' => null,
|
||
'target_weight' => null,
|
||
'date_of_birth' => null,
|
||
'sex' => null,
|
||
'physical_activity_level' => null,
|
||
'weight_goal' => null,
|
||
'pace_preference' => null,
|
||
'onboarding_completed_at' => null,
|
||
'nutrition_estimate_accepted_at' => null,
|
||
];
|
||
|
||
$user = User::query()->create([
|
||
'locale' => 'en',
|
||
'role' => UserRole::USER,
|
||
'email_verified_at' => now(),
|
||
'password' => 'password',
|
||
'avatar_url' => null,
|
||
...$onboardingAttributes,
|
||
...$profile,
|
||
]);
|
||
|
||
if ($withNutritionOnboarding) {
|
||
$this->createNutritionOnboarding($user);
|
||
}
|
||
|
||
return $user;
|
||
}
|
||
|
||
private function createNutritionOnboarding(User $user): void
|
||
{
|
||
$user->weightEntries()->create([
|
||
'weight_kg' => 70,
|
||
'measured_at' => now(),
|
||
]);
|
||
|
||
$user->nutritionPlans()->create([
|
||
'source' => NutritionPlanSource::ONBOARDING,
|
||
'formula_version' => 'mifflin_st_jeor_v1',
|
||
'calories' => 2200,
|
||
'proteins' => 112,
|
||
'carbs' => 286,
|
||
'fats' => 61,
|
||
'resting_metabolism' => 1650,
|
||
'maintenance_calories' => 2200,
|
||
'calorie_adjustment_percent' => 0,
|
||
'calculation_details' => [
|
||
'activityFactor' => 1.55,
|
||
'inputWeightKg' => 70,
|
||
],
|
||
'effective_from' => now(),
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* @param Collection<int, User> $users
|
||
*/
|
||
private function createMeals(Collection $users): void
|
||
{
|
||
$templates = collect($this->mealTemplates());
|
||
$reviewComments = collect([
|
||
'Très bonne idée, je vais essayer cette semaine.',
|
||
'Simple, équilibré et vraiment appétissant.',
|
||
'Les proportions sont parfaites pour mon déjeuner.',
|
||
'Testé hier soir, toute la famille a aimé.',
|
||
'Belle assiette et excellente source d’inspiration.',
|
||
'Parfait après une séance de sport.',
|
||
]);
|
||
|
||
foreach (range(0, 47) as $index) {
|
||
$owner = $users->get($index % $users->count());
|
||
$template = $templates->get($index % $templates->count());
|
||
$eatenAt = now()->subHours(($index * 4) + 1);
|
||
|
||
if (! $owner instanceof User || ! is_array($template)) {
|
||
throw new LogicException('Unable to build the demo meal collection.');
|
||
}
|
||
|
||
$meal = $owner->mealPosts()->create([
|
||
'image_url' => $template['imageUrl'],
|
||
'caption' => $template['caption'],
|
||
'calories' => $template['calories'],
|
||
'proteins' => $template['proteins'],
|
||
'carbs' => $template['carbs'],
|
||
'fats' => $template['fats'],
|
||
'title' => $template['title'],
|
||
'eaten_at' => $eatenAt,
|
||
'visibility' => MealPostVisibility::Public,
|
||
'type' => $template['type'],
|
||
'ai_generated' => $index % 9 === 0,
|
||
'diet_type' => $template['dietType'],
|
||
]);
|
||
|
||
$meal->ingredients()->createMany(
|
||
collect($template['ingredients'])
|
||
->values()
|
||
->map(fn (array $ingredient, int $position): array => [
|
||
...$ingredient,
|
||
'position' => $position + 1,
|
||
])
|
||
->all()
|
||
);
|
||
|
||
$eligibleUsers = $users
|
||
->reject(fn (User $user): bool => $user->is($owner))
|
||
->values();
|
||
$engagedUsers = $eligibleUsers
|
||
->slice($index % $eligibleUsers->count())
|
||
->concat($eligibleUsers->take($index % $eligibleUsers->count()))
|
||
->values();
|
||
|
||
$meal->likedByUsers()->attach(
|
||
$engagedUsers->take(2 + ($index % 5))->pluck('id')->all(),
|
||
[
|
||
'created_at' => $eatenAt->addMinutes(30),
|
||
'updated_at' => $eatenAt->addMinutes(30),
|
||
]
|
||
);
|
||
|
||
$engagedUsers->take(2 + ($index % 2))->each(
|
||
function (User $reviewer, int $reviewerIndex) use ($index, $meal, $reviewComments): void {
|
||
$meal->reviews()->create([
|
||
'rating' => 5 - (($index + $reviewerIndex) % 2),
|
||
'comment' => $reviewComments->get(
|
||
($index + $reviewerIndex) % $reviewComments->count()
|
||
),
|
||
'user_id' => $reviewer->getKey(),
|
||
]);
|
||
}
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @param Collection<int, User> $users
|
||
*/
|
||
private function createSocialGraph(Collection $users): void
|
||
{
|
||
$demoUser = $this->demoUser($users);
|
||
$creators = $users
|
||
->reject(fn (User $user): bool => $user->is($demoUser))
|
||
->values();
|
||
$pivot = [
|
||
'status' => FollowStatus::Accepted->value,
|
||
'created_at' => now()->subDays(10),
|
||
'updated_at' => now()->subDays(10),
|
||
];
|
||
|
||
$demoUser->following()->attach($creators->pluck('id')->all(), $pivot);
|
||
|
||
$creators->take(5)->each(
|
||
fn (User $creator) => $creator->following()->attach($demoUser->getKey(), $pivot)
|
||
);
|
||
|
||
$creators->each(function (User $creator, int $index) use ($creators, $pivot): void {
|
||
$nextCreator = $creators->get(($index + 1) % $creators->count());
|
||
|
||
if ($nextCreator instanceof User) {
|
||
$creator->following()->attach($nextCreator->getKey(), $pivot);
|
||
}
|
||
});
|
||
}
|
||
|
||
private function createProgressHistory(User $demoUser): void
|
||
{
|
||
$demoUser->weightEntries()->delete();
|
||
|
||
foreach (range(11, 0) as $weeksAgo) {
|
||
$demoUser->weightEntries()->create([
|
||
'weight_kg' => round(74.8 - ((11 - $weeksAgo) * 0.28), 2),
|
||
'measured_at' => now()->startOfDay()->subWeeks($weeksAgo),
|
||
]);
|
||
}
|
||
|
||
$demoUser->nutritionPlans()
|
||
->where('is_active', true)
|
||
->update([
|
||
'calories' => 2050,
|
||
'proteins' => 130,
|
||
'carbs' => 235,
|
||
'fats' => 65,
|
||
'maintenance_calories' => 2350,
|
||
'calorie_adjustment_percent' => -0.1277,
|
||
'calculation_details' => [
|
||
'activityFactor' => 1.55,
|
||
'inputWeightKg' => 71.72,
|
||
],
|
||
]);
|
||
|
||
$workouts = collect([
|
||
['title' => 'Course facile', 'type' => 'running', 'duration' => 2700, 'calories' => 390, 'distance' => 7200],
|
||
['title' => 'Renforcement complet', 'type' => 'strength', 'duration' => 3300, 'calories' => 310, 'distance' => 0],
|
||
['title' => 'Sortie vélo', 'type' => 'cycling', 'duration' => 5400, 'calories' => 620, 'distance' => 32000],
|
||
['title' => 'Marche active', 'type' => 'walking', 'duration' => 3600, 'calories' => 260, 'distance' => 6100],
|
||
]);
|
||
|
||
foreach (range(0, 11) as $index) {
|
||
$workout = $workouts->get($index % $workouts->count());
|
||
$source = $index % 4 === 0 ? WorkoutSource::STRAVA : WorkoutSource::MANUAL;
|
||
|
||
if (! is_array($workout)) {
|
||
throw new LogicException('Unable to build the demo workout collection.');
|
||
}
|
||
|
||
$demoUser->workouts()->create([
|
||
'external_id' => $source === WorkoutSource::STRAVA ? "demo-strava-{$index}" : null,
|
||
'source' => $source,
|
||
'type' => $workout['type'],
|
||
'title' => $workout['title'],
|
||
'duration_seconds' => $workout['duration'],
|
||
'calories_burned' => $workout['calories'],
|
||
'distance_meters' => $workout['distance'],
|
||
'started_at' => now()->subDays($index)->setTime(18, 30),
|
||
]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @param Collection<int, User> $users
|
||
*/
|
||
private function demoUser(Collection $users): User
|
||
{
|
||
$demoUser = $users->first(
|
||
fn (User $user): bool => $user->email === 'test@example.com'
|
||
);
|
||
|
||
if (! $demoUser instanceof User) {
|
||
throw new LogicException('The demo user could not be created.');
|
||
}
|
||
|
||
return $demoUser;
|
||
}
|
||
|
||
/**
|
||
* @return list<array<string, mixed>>
|
||
*/
|
||
private function mealTemplates(): array
|
||
{
|
||
return [
|
||
[
|
||
'title' => 'Bowl saumon et avocat',
|
||
'caption' => 'Un déjeuner complet avec du riz, des légumes croquants et une sauce citronnée.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1546069901-ba9599a7e63c?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 620,
|
||
'proteins' => 38,
|
||
'carbs' => 58,
|
||
'fats' => 24,
|
||
'type' => MealPostType::LUNCH,
|
||
'dietType' => DietType::PESCATARIAN,
|
||
'ingredients' => [
|
||
['ingredient' => 'Saumon', 'quantity' => 140, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Riz complet', 'quantity' => 160, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Avocat', 'quantity' => 1, 'unit' => IngredientUnit::PIECE],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Pancakes aux fruits rouges',
|
||
'caption' => 'Des pancakes moelleux accompagnés de fruits rouges et de yaourt.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1528207776546-365bb710ee93?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 480,
|
||
'proteins' => 24,
|
||
'carbs' => 64,
|
||
'fats' => 14,
|
||
'type' => MealPostType::BREAKFAST,
|
||
'dietType' => DietType::VEGETARIAN,
|
||
'ingredients' => [
|
||
['ingredient' => 'Flocons d’avoine', 'quantity' => 80, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Œufs', 'quantity' => 2, 'unit' => IngredientUnit::PIECE],
|
||
['ingredient' => 'Fruits rouges', 'quantity' => 120, 'unit' => IngredientUnit::GRAM],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Poulet rôti et légumes',
|
||
'caption' => 'Une assiette familiale, riche en protéines et pleine de couleurs.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1532550907401-a500c9a57435?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 590,
|
||
'proteins' => 52,
|
||
'carbs' => 46,
|
||
'fats' => 19,
|
||
'type' => MealPostType::DINNER,
|
||
'dietType' => DietType::OMNIVORE,
|
||
'ingredients' => [
|
||
['ingredient' => 'Blanc de poulet', 'quantity' => 180, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Pommes de terre', 'quantity' => 220, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Légumes rôtis', 'quantity' => 180, 'unit' => IngredientUnit::GRAM],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Curry de pois chiches',
|
||
'caption' => 'Un curry végétal doux, crémeux et parfait pour le batch cooking.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1603894584373-5ac82b2ae398?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 540,
|
||
'proteins' => 21,
|
||
'carbs' => 72,
|
||
'fats' => 18,
|
||
'type' => MealPostType::DINNER,
|
||
'dietType' => DietType::VEGAN,
|
||
'ingredients' => [
|
||
['ingredient' => 'Pois chiches', 'quantity' => 180, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Lait de coco', 'quantity' => 120, 'unit' => IngredientUnit::MILLILITER],
|
||
['ingredient' => 'Épinards', 'quantity' => 100, 'unit' => IngredientUnit::GRAM],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Pâtes au pesto maison',
|
||
'caption' => 'Un classique rapide avec tomates cerises, roquette et parmesan.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1473093295043-cdd812d0e601?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 670,
|
||
'proteins' => 25,
|
||
'carbs' => 88,
|
||
'fats' => 24,
|
||
'type' => MealPostType::LUNCH,
|
||
'dietType' => DietType::VEGETARIAN,
|
||
'ingredients' => [
|
||
['ingredient' => 'Pâtes complètes', 'quantity' => 190, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Pesto', 'quantity' => 2, 'unit' => IngredientUnit::TABLESPOON],
|
||
['ingredient' => 'Tomates cerises', 'quantity' => 120, 'unit' => IngredientUnit::GRAM],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Toast avocat et œufs',
|
||
'caption' => 'Le brunch simple qui tient toute la matinée.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1482049016688-2d3e1b311543?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 510,
|
||
'proteins' => 26,
|
||
'carbs' => 42,
|
||
'fats' => 27,
|
||
'type' => MealPostType::BRUNCH,
|
||
'dietType' => DietType::VEGETARIAN,
|
||
'ingredients' => [
|
||
['ingredient' => 'Pain complet', 'quantity' => 2, 'unit' => IngredientUnit::PIECE],
|
||
['ingredient' => 'Avocat', 'quantity' => 1, 'unit' => IngredientUnit::PIECE],
|
||
['ingredient' => 'Œufs', 'quantity' => 2, 'unit' => IngredientUnit::PIECE],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Tacos de poisson',
|
||
'caption' => 'Poisson grillé, chou croquant et sauce au yaourt citronnée.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1551504734-5ee1c4a1479b?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 560,
|
||
'proteins' => 36,
|
||
'carbs' => 61,
|
||
'fats' => 20,
|
||
'type' => MealPostType::DINNER,
|
||
'dietType' => DietType::PESCATARIAN,
|
||
'ingredients' => [
|
||
['ingredient' => 'Poisson blanc', 'quantity' => 160, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Tortillas', 'quantity' => 3, 'unit' => IngredientUnit::PIECE],
|
||
['ingredient' => 'Chou rouge', 'quantity' => 100, 'unit' => IngredientUnit::GRAM],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Buddha bowl au tofu',
|
||
'caption' => 'Tofu croustillant, quinoa, légumes et sauce sésame.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1512621776951-a57141f2eefd?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 575,
|
||
'proteins' => 29,
|
||
'carbs' => 69,
|
||
'fats' => 22,
|
||
'type' => MealPostType::LUNCH,
|
||
'dietType' => DietType::VEGAN,
|
||
'ingredients' => [
|
||
['ingredient' => 'Tofu', 'quantity' => 160, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Quinoa', 'quantity' => 150, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Brocoli', 'quantity' => 140, 'unit' => IngredientUnit::GRAM],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Steak et patate douce',
|
||
'caption' => 'Une assiette protéinée avec patate douce rôtie et haricots verts.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1600891964092-4316c288032e?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 710,
|
||
'proteins' => 49,
|
||
'carbs' => 65,
|
||
'fats' => 28,
|
||
'type' => MealPostType::DINNER,
|
||
'dietType' => DietType::OMNIVORE,
|
||
'ingredients' => [
|
||
['ingredient' => 'Steak de bœuf', 'quantity' => 180, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Patate douce', 'quantity' => 240, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Haricots verts', 'quantity' => 150, 'unit' => IngredientUnit::GRAM],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Overnight oats banane',
|
||
'caption' => 'Préparé la veille avec banane, graines de chia et beurre de cacahuète.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1517673400267-0251440c45dc?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 445,
|
||
'proteins' => 18,
|
||
'carbs' => 62,
|
||
'fats' => 15,
|
||
'type' => MealPostType::BREAKFAST,
|
||
'dietType' => DietType::VEGETARIAN,
|
||
'ingredients' => [
|
||
['ingredient' => 'Flocons d’avoine', 'quantity' => 70, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Banane', 'quantity' => 1, 'unit' => IngredientUnit::PIECE],
|
||
['ingredient' => 'Graines de chia', 'quantity' => 2, 'unit' => IngredientUnit::TEASPOON],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Salade grecque complète',
|
||
'caption' => 'Tomates, concombre, feta, olives et pain pita.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1540420773420-3366772f4999?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 495,
|
||
'proteins' => 19,
|
||
'carbs' => 47,
|
||
'fats' => 26,
|
||
'type' => MealPostType::LUNCH,
|
||
'dietType' => DietType::VEGETARIAN,
|
||
'ingredients' => [
|
||
['ingredient' => 'Tomates', 'quantity' => 180, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Feta', 'quantity' => 80, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Pain pita', 'quantity' => 1, 'unit' => IngredientUnit::PIECE],
|
||
],
|
||
],
|
||
[
|
||
'title' => 'Ramen au poulet',
|
||
'caption' => 'Un bouillon chaud avec nouilles, poulet, œuf et légumes.',
|
||
'imageUrl' => 'https://images.unsplash.com/photo-1569718212165-3a8278d5f624?auto=format&fit=crop&w=1200&q=85',
|
||
'calories' => 640,
|
||
'proteins' => 42,
|
||
'carbs' => 78,
|
||
'fats' => 18,
|
||
'type' => MealPostType::DINNER,
|
||
'dietType' => DietType::OMNIVORE,
|
||
'ingredients' => [
|
||
['ingredient' => 'Nouilles', 'quantity' => 180, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Poulet', 'quantity' => 140, 'unit' => IngredientUnit::GRAM],
|
||
['ingredient' => 'Œuf', 'quantity' => 1, 'unit' => IngredientUnit::PIECE],
|
||
],
|
||
],
|
||
];
|
||
}
|
||
}
|