mirror of https://github.com/kcal-app/kcal.git
Complete initial food picker component
This commit is contained in:
parent
6dccf05f2d
commit
5877d24f64
|
|
@ -71,16 +71,8 @@ class RecipeController extends Controller
|
|||
*/
|
||||
public function edit(Recipe $recipe): View
|
||||
{
|
||||
$foods = Food::all(['id', 'name', 'detail'])->sortBy('name')->collect()
|
||||
->map(function ($food) {
|
||||
return [
|
||||
'value' => $food->id,
|
||||
'label' => "{$food->name}" . ($food->detail ? ", {$food->detail}" : ""),
|
||||
];
|
||||
});
|
||||
return view('recipes.edit')
|
||||
->with('recipe', $recipe)
|
||||
->with('foods', $foods)
|
||||
->with('food_units', new Collection([
|
||||
['value' => 'tsp', 'label' => 'tsp.'],
|
||||
['value' => 'tbsp', 'label' => 'tbsp.'],
|
||||
|
|
|
|||
|
|
@ -7,7 +7,17 @@ use Livewire\Component;
|
|||
|
||||
class FoodPicker extends Component
|
||||
{
|
||||
public string $term = '';
|
||||
public ?string $term = NULL;
|
||||
public int $index;
|
||||
public ?int $defaultId = NULL;
|
||||
public ?string $defaultName = NULL;
|
||||
|
||||
/**
|
||||
* Set the default term on mount.
|
||||
*/
|
||||
public function mount() {
|
||||
$this->term = $this->defaultName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
|
|
@ -21,6 +31,7 @@ class FoodPicker extends Component
|
|||
} else {
|
||||
$foods = [];
|
||||
}
|
||||
return view('livewire.food-picker')->with('foods', $foods);
|
||||
return view('livewire.food-picker')
|
||||
->with('foods', $foods);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31425,6 +31425,12 @@ select {
|
|||
animation: bounce 1s infinite;
|
||||
}
|
||||
|
||||
/* See: https://ryangjchandler.co.uk/articles/hiding-elements-until-alpine-is-ready-with-x-cloak */
|
||||
|
||||
[x-cloak] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.sm\:container {
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -21338,8 +21338,8 @@ window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
|||
/*! no static exports found */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
__webpack_require__(/*! /Users/wellc/PhpstormProjects/prndb/resources/js/app.js */"./resources/js/app.js");
|
||||
module.exports = __webpack_require__(/*! /Users/wellc/PhpstormProjects/prndb/resources/css/app.css */"./resources/css/app.css");
|
||||
__webpack_require__(/*! /home/chris/PhpstormProjects/pfnj/resources/js/app.js */"./resources/js/app.js");
|
||||
module.exports = __webpack_require__(/*! /home/chris/PhpstormProjects/pfnj/resources/css/app.css */"./resources/css/app.css");
|
||||
|
||||
|
||||
/***/ })
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* @license
|
||||
* Lodash <https://lodash.com/>
|
||||
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
||||
* Released under MIT license <https://lodash.com/license>
|
||||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||||
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||
*/
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
|
||||
/* See: https://ryangjchandler.co.uk/articles/hiding-elements-until-alpine-is-ready-with-x-cloak */
|
||||
[x-cloak] {
|
||||
display: none !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,46 @@
|
|||
<div x-data="{isTyped: false}">
|
||||
<div x-data="{searching: false}">
|
||||
<div>
|
||||
<div>
|
||||
<x-inputs.input type="hidden"
|
||||
name="foods[{{ $index }}]"
|
||||
:value="$defaultId"
|
||||
x-ref="foods{{ $index }}"/>
|
||||
<x-inputs.input type="text"
|
||||
name="food"
|
||||
placeholder="{{__('Search ...')}}"
|
||||
x-on:input.debounce.400ms="isTyped = ($event.target.value != '')"
|
||||
x-on:focusout="isTyped = false; $event.target.value = ''"
|
||||
name="foods_name[{{ $index }}]"
|
||||
:value="$defaultName"
|
||||
placeholder="Search..."
|
||||
autocomplete="off"
|
||||
wire:model.debounce.500ms="term"
|
||||
aria-label="Search input" />
|
||||
x-on:input.debounce.400ms="searching = ($event.target.value != '')"
|
||||
x-on:focusout.debounce.200ms="searching = false;"
|
||||
x-ref="foods_name{{ $index }}" />
|
||||
</div>
|
||||
<div x-show="isTyped" x-cloak>
|
||||
<div class="absolute border-2 border-gray-500 border-b-0 bg-white">
|
||||
<div x-show="searching" x-cloak>
|
||||
<div class="absolute border-2 border-gray-500 border-b-0 bg-white"
|
||||
x-on:click="selected = $event.target; if (selected.dataset.id) { $refs.foods_name{{ $index }}.value = selected.dataset.value; $refs.foods{{ $index }}.value = selected.dataset.id; searching = false; }">
|
||||
@forelse($foods as $food)
|
||||
<div class="p-1 border-b-2 border-gray-500 hover:bg-yellow-300 cursor-pointer">
|
||||
<div class="text">
|
||||
{{ $food->name }}@if($food->detail), <span class="text-gray-500">{{ $food->detail }}</span>@endif
|
||||
</div>
|
||||
@if($food->brand)
|
||||
<div class="text-sm text-gray-600">
|
||||
{{ $food->brand }}
|
||||
<div class="p-1 border-b-2 border-gray-500 hover:bg-yellow-300 cursor-pointer"
|
||||
wire:key="{{ $food->id }}"
|
||||
data-id="{{ $food->id }}"
|
||||
data-value="{{ $food->name }}">
|
||||
<div class="pointer-events-none">
|
||||
<div>
|
||||
{{ $food->name }}@if($food->detail), <span class="text-gray-500">{{ $food->detail }}</span>@endif
|
||||
</div>
|
||||
@if($food->brand)
|
||||
<div class="text-sm text-gray-600">
|
||||
{{ $food->brand }}
|
||||
</div>
|
||||
@endif
|
||||
<div class="text-sm">
|
||||
Serving size {{ \App\Support\Number::fractionStringFromFloat($food->serving_size) }}
|
||||
{{ $food->serving_unit }}
|
||||
({{ $food->serving_weight }}g)
|
||||
</div>
|
||||
@endif
|
||||
<div class="text-sm">
|
||||
Serving size {{ \App\Support\Number::fractionStringFromFloat($food->serving_size) }}
|
||||
{{ $food->serving_unit }}
|
||||
({{ $food->serving_weight }}g)
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="border-b-2 border-gray-500" x-cloak>
|
||||
<div class="p-1 border-b-2 border-gray-500" x-cloak>
|
||||
No results found.
|
||||
</div>
|
||||
@endforelse
|
||||
|
|
|
|||
|
|
@ -70,10 +70,11 @@
|
|||
$amount = \App\Support\Number::fractionStringFromFloat($foodAmount->amount);
|
||||
$unit = $foodAmount->unit;
|
||||
$food_id = $foodAmount->food->id;
|
||||
$food_name = $foodAmount->food->name;
|
||||
$detail = $foodAmount->detail;
|
||||
} else {
|
||||
$foodAmount = new \App\Models\FoodAmount();
|
||||
$amount = $food_id = $unit = $detail = null;
|
||||
$amount = $food_id = $food_name = $unit = $detail = null;
|
||||
}
|
||||
@endphp
|
||||
<div class="flex flex-row space-x-4 mb-4">
|
||||
|
|
@ -86,12 +87,9 @@
|
|||
:selectedValue="old('foods_unit.' . $i, $unit)">
|
||||
<option value=""></option>
|
||||
</x-inputs.select>
|
||||
{{-- <x-inputs.select name="foods[]"--}}
|
||||
{{-- :options="$foods"--}}
|
||||
{{-- :selectedValue="old('foods.' . $i, $food_id)">--}}
|
||||
{{-- <option value=""></option>--}}
|
||||
{{-- </x-inputs.select>--}}
|
||||
<livewire:food-picker>
|
||||
<livewire:food-picker :index="$i"
|
||||
:default-id="old('foods.' . $i, $food_id)"
|
||||
:default-name="old('foods_name.' . $i, $food_name)">
|
||||
<x-inputs.input type="text"
|
||||
class="block"
|
||||
name="foods_detail[]"
|
||||
|
|
|
|||
Loading…
Reference in New Issue