mirror of https://github.com/kcal-app/kcal.git
Add "manual" journal entry option
This commit is contained in:
parent
089b2edab2
commit
d1c66924ea
|
@ -80,6 +80,23 @@ class JournalEntryController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a journal entry from nutrients directly.
|
||||||
|
*/
|
||||||
|
public function createFromNutrients(): View
|
||||||
|
{
|
||||||
|
return view('journal-entries.create-from-nutrients')
|
||||||
|
->with('meals', JournalEntry::$meals)
|
||||||
|
->with('units', [
|
||||||
|
['value' => 'tsp', 'label' => 'tsp.'],
|
||||||
|
['value' => 'tbsp', 'label' => 'tbsp.'],
|
||||||
|
['value' => 'cup', 'label' => 'cup'],
|
||||||
|
['value' => 'oz', 'label' => 'oz'],
|
||||||
|
['value' => 'g', 'label' => 'grams'],
|
||||||
|
['value' => 'servings', 'label' => 'servings'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a newly created resource in storage.
|
* Store a newly created resource in storage.
|
||||||
*/
|
*/
|
||||||
|
@ -158,6 +175,32 @@ class JournalEntryController extends Controller
|
||||||
return redirect()->route('journal-entries.index');
|
return redirect()->route('journal-entries.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store an entry from nutrients.
|
||||||
|
*/
|
||||||
|
public function storeFromNutrients(Request $request): RedirectResponse {
|
||||||
|
$attributes = $request->validate([
|
||||||
|
'date' => ['required', 'date'],
|
||||||
|
'meal' => ['required', 'string', new InArray(array_column(JournalEntry::$meals, 'value'))],
|
||||||
|
'summary' => ['required', 'string'],
|
||||||
|
'calories' => ['nullable', 'required_without_all:fat,cholesterol,sodium,carbohydrates,protein', 'numeric'],
|
||||||
|
'fat' => ['nullable', 'required_without_all:calories,cholesterol,sodium,carbohydrates,protein', 'numeric'],
|
||||||
|
'cholesterol' => ['nullable', 'required_without_all:calories,fat,sodium,carbohydrates,protein', 'numeric'],
|
||||||
|
'sodium' => ['nullable', 'required_without_all:calories,fat,cholesterol,carbohydrates,protein', 'numeric'],
|
||||||
|
'carbohydrates' => ['nullable', 'required_without_all:calories,fat,cholesterol,sodium,protein', 'numeric'],
|
||||||
|
'protein' => ['nullable', 'required_without_all:calories,fat,cholesterol,sodium,carbohydrates', 'numeric'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$entry = JournalEntry::make(array_filter($attributes))
|
||||||
|
->user()->associate(Auth::user());
|
||||||
|
$entry->save();
|
||||||
|
session()->flash('message', "Journal entry added!");
|
||||||
|
return redirect()->route(
|
||||||
|
'journal-entries.index',
|
||||||
|
['date' => $entry->date->format('Y-m-d')]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm removal of the specified resource.
|
* Confirm removal of the specified resource.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
<x-app-layout>
|
||||||
|
<x-slot name="header">
|
||||||
|
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||||
|
{{ __('Add Nutrient Journal Entry') }}
|
||||||
|
</h2>
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
<div class="py-12">
|
||||||
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
|
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
||||||
|
<div class="p-6 bg-white border-b border-gray-200">
|
||||||
|
<form method="POST" action="{{ route('journal-entries.store.from-nutrients') }}">
|
||||||
|
@csrf
|
||||||
|
<div class="flex mb-4 space-x-4">
|
||||||
|
<!-- Date -->
|
||||||
|
<div>
|
||||||
|
<x-inputs.label for="date" value="Date"/>
|
||||||
|
|
||||||
|
<x-inputs.input name="date"
|
||||||
|
type="date"
|
||||||
|
class="block mt-1"
|
||||||
|
:value="old('date', \Illuminate\Support\Carbon::now()->toDateString())"
|
||||||
|
required />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Meal -->
|
||||||
|
<div>
|
||||||
|
<x-inputs.label for="meal" value="Meal"/>
|
||||||
|
|
||||||
|
<x-inputs.select name="meal"
|
||||||
|
class="block mt-1"
|
||||||
|
:options="$meals"
|
||||||
|
:selectedValue="old('meal')"
|
||||||
|
required>
|
||||||
|
<option value=""></option>
|
||||||
|
</x-inputs.select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Summary -->
|
||||||
|
<div class="flex-auto">
|
||||||
|
<x-inputs.label for="summary" value="Summary"/>
|
||||||
|
|
||||||
|
<x-inputs.input name="summary"
|
||||||
|
type="text"
|
||||||
|
class="block mt-1 w-full"
|
||||||
|
:value="old('summary')"
|
||||||
|
required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-auto">
|
||||||
|
@foreach (\App\Support\Nutrients::$all as $nutrient)
|
||||||
|
<!-- {{ ucfirst($nutrient) }} -->
|
||||||
|
<div>
|
||||||
|
<x-inputs.label for="{{ $nutrient }}"
|
||||||
|
:value="ucfirst($nutrient) . ' (g)'"/>
|
||||||
|
|
||||||
|
<x-inputs.input id="{{ $nutrient }}"
|
||||||
|
class="block w-5/6 mt-1"
|
||||||
|
type="number"
|
||||||
|
step="any"
|
||||||
|
name="{{ $nutrient }}"
|
||||||
|
:value="old($nutrient)"/>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-end mt-4">
|
||||||
|
<x-inputs.button class="ml-3">Add Entry</x-inputs.button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-app-layout>
|
|
@ -1,7 +1,7 @@
|
||||||
<x-app-layout>
|
<x-app-layout>
|
||||||
<x-slot name="header">
|
<x-slot name="header">
|
||||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||||
{{ __('Add Journal Entry') }}
|
{{ __('Add Journal Entries') }}
|
||||||
</h2>
|
</h2>
|
||||||
</x-slot>
|
</x-slot>
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,9 @@
|
||||||
<x-dropdown-link :href="route('journal-entries.create')">
|
<x-dropdown-link :href="route('journal-entries.create')">
|
||||||
{{ __('Add Entries') }}
|
{{ __('Add Entries') }}
|
||||||
</x-dropdown-link>
|
</x-dropdown-link>
|
||||||
|
<x-dropdown-link :href="route('journal-entries.create.from-nutrients')">
|
||||||
|
{{ __('Add Nutrient Entry') }}
|
||||||
|
</x-dropdown-link>
|
||||||
</x-slot>
|
</x-slot>
|
||||||
</x-dropdown>
|
</x-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -25,18 +25,21 @@ Route::get('/dashboard', function () {
|
||||||
return view('dashboard');
|
return view('dashboard');
|
||||||
})->middleware(['auth'])->name('dashboard');
|
})->middleware(['auth'])->name('dashboard');
|
||||||
|
|
||||||
|
// Foods.
|
||||||
Route::resource('foods', FoodController::class)->middleware(['auth']);
|
Route::resource('foods', FoodController::class)->middleware(['auth']);
|
||||||
Route::get('/foods/{food}/delete', [FoodController::class, 'delete'])
|
Route::get('/foods/{food}/delete', [FoodController::class, 'delete'])->middleware(['auth'])->name('foods.delete');
|
||||||
->middleware(['auth'])
|
|
||||||
->name('foods.delete');
|
|
||||||
Route::resource('recipes', RecipeController::class)->middleware(['auth']);
|
|
||||||
Route::resource('journal-entries', JournalEntryController::class)->middleware(['auth']);
|
|
||||||
Route::get('/journal-entries/{journalEntry}/delete', [JournalEntryController::class, 'delete'])
|
|
||||||
->middleware(['auth'])
|
|
||||||
->name('journal-entries.delete');
|
|
||||||
|
|
||||||
Route::get('/ingredient-picker/search', [IngredientPickerController::class, 'search'])
|
// Recipes.
|
||||||
->middleware(['auth'])
|
Route::resource('recipes', RecipeController::class)->middleware(['auth']);
|
||||||
->name('ingredient-picker.search');
|
|
||||||
|
// Journal entries.
|
||||||
|
Route::get('/journal-entries/create-from-nutrients', [JournalEntryController::class, 'createFromNutrients'])->middleware(['auth'])->name('journal-entries.create.from-nutrients');
|
||||||
|
Route::post('/journal-entries/create-from-nutrients', [JournalEntryController::class, 'storeFromNutrients'])->middleware(['auth'])->name('journal-entries.store.from-nutrients');
|
||||||
|
Route::resource('journal-entries', JournalEntryController::class)->middleware(['auth']);
|
||||||
|
Route::get('/journal-entries/{journalEntry}/delete', [JournalEntryController::class, 'delete'])->middleware(['auth'])->name('journal-entries.delete');
|
||||||
|
|
||||||
|
// Custom.
|
||||||
|
// TODO: Change this to a custom JSON API endpoint.
|
||||||
|
Route::get('/ingredient-picker/search', [IngredientPickerController::class, 'search'])->middleware(['auth'])->name('ingredient-picker.search');
|
||||||
|
|
||||||
require __DIR__.'/auth.php';
|
require __DIR__.'/auth.php';
|
||||||
|
|
Loading…
Reference in New Issue