Merge pull request 'main' (#8) from eatvio/eatvio:main into main

Reviewed-on: apoloz/eatvio#8
This commit is contained in:
apoloz
2023-12-25 11:32:05 +00:00
25 changed files with 1231 additions and 746 deletions

View File

@@ -17,13 +17,25 @@ class Create extends Component
public $grade = 0;
public $isChecked = false;
public function render()
{
return view('livewire.recipe.comment.create');
}
public function toggle()
{
$this->isChecked = !$this->isChecked;
}
public function save()
{
$this->validate([
'body' => 'required|min:3',
'grade' => 'required',
]);
$comment = new RecipeComment();
$comment->grade = $this->grade;
$comment->body = $this->body;
@@ -32,6 +44,9 @@ class Create extends Component
$comment->save();
$this->reset(['body', 'grade']);
$this->toggle();
$this->dispatch('commentAdded')->to('recipe.comment.show');
}
}

View File

@@ -9,10 +9,19 @@ class Show extends Component
{
public Recipe $recipe;
public array $tabpanelState = ['positive' => 'positive', 'negative' => false];
protected $listeners = ['commentAdded' => '$refresh'];
public function render()
{
return view('livewire.recipe.comment.show');
}
public function toggleTabpanelState($tabpanelName)
{
collect($this->tabpanelState)->keys()->map(fn($key) => $key === $tabpanelName
? $this->tabpanelState[$tabpanelName] = $tabpanelName
: $this->tabpanelState[$key] = false, array_keys($this->tabpanelState));
}
}

View File

@@ -17,6 +17,10 @@ class Create extends Component
public $state = 'active';
public $state_ingredient = 'active';
public $state_article = 'active';
public $tags = [];
public $title;
@@ -39,20 +43,21 @@ class Create extends Component
public $ingredients_unit = 'gr';
public $state_row = ['ingredient' => 'true', 'article' => 'false'];
protected $listeners = ['stepRemoved' => '$refresh'];
public function render()
public function toggleStateRow(string $currentRow): void
{
return view('livewire.recipe.create');
collect($this->state_row)->keys()->map(fn($key) => $key === $currentRow
? $this->state_row[$currentRow] = 'true'
: $this->state_row[$key] = 'false');
}
public function addIngredient(): void
{
// dd(
// $this->ingredients_name,
// $this->ingredients_portion,
// $this->ingredients_unit
// );
$this->ingredients[] = [
'name' => $this->ingredients_name,
'portion' => $this->ingredients_portion,
@@ -99,7 +104,7 @@ class Create extends Component
public function parentComponentTagRemoved($tag)
{
$this->tags = collect($this->tags)
->filter(fn ($curTag) => $curTag['name'] !== $tag)
->filter(fn($curTag) => $curTag['name'] !== $tag)
->all();
}
@@ -117,9 +122,21 @@ class Create extends Component
$this->publish();
}
protected function rules()
{
return [
'image' => 'required|image|max:2048',
'state' => 'required|in:active,archived',
'description' => 'required|min:3',
'type' => 'required|min:3',
'video_url' => 'nullable|url|max:2048',
'cooking_time' => 'nullable|numeric',
];
}
public function publish()
{
// dd($this->description);
$this->validate();
$recipe = new Recipe();
@@ -134,7 +151,7 @@ class Create extends Component
$recipe->ingredients = $this->ingredients;
$recipe->save();
$tagsIds = collect($this->tags)->map(fn ($curTag) => $curTag['id']);
$tagsIds = collect($this->tags)->map(fn($curTag) => $curTag['id']);
$recipe->tags()->attach($tagsIds);
$user = Auth::user();
@@ -143,19 +160,6 @@ class Create extends Component
return redirect()->route('recipe.show', $recipe->id);
}
protected function rules()
{
return [
'image' => 'required|image|max:2048',
'state' => 'required|in:active,archived',
'description' => 'required|min:3',
'type' => 'required|min:3',
'video_url' => 'nullable|url|max:2048',
'cooking_time' => 'nullable|numeric',
];
}
private function transformSteps($steps)
{
return collect($steps)->map(
@@ -163,7 +167,7 @@ class Create extends Component
if (gettype($step['image']) === 'string') {
$data['image'] = $step['image'];
} else {
$data['image'] = ! is_null($step['image']) ? $step['image']->store('steps', 'public') : '';
$data['image'] = !is_null($step['image']) ? $step['image']->store('steps', 'public') : '';
}
$data['description'] = $step['description'];
@@ -173,8 +177,11 @@ class Create extends Component
)->toArray();
}
// public function updated($property)
// {
// dd($property, $this->$property);
// }
public function render()
{
return view('livewire.recipe.create');
}
}

View File

@@ -17,6 +17,10 @@ class Edit extends Component
public $state = 'active';
public $state_ingredient = 'active';
public $state_article = 'active';
public $type = 'other';
public $tags;
@@ -39,6 +43,8 @@ class Edit extends Component
public $ingredients_unit = 'gr';
public $state_row = ['ingredient' => 'true', 'article' => 'false'];
protected $listeners = ['stepRemoved' => '$refresh', 'parentComponentTagAdded', 'parentComponentTagRemoved'];
public function mount(Recipe $recipe)
@@ -56,14 +62,15 @@ class Edit extends Component
$this->video_url = $recipe->video_url;
}
public function render()
public function toggleStateRow(string $currentRow): void
{
return view('livewire.recipe.edit');
collect($this->state_row)->keys()->map(fn($key) => $key === $currentRow
? $this->state_row[$currentRow] = 'true'
: $this->state_row[$key] = 'false');
}
public function addIngredient()
{
// $this->ingredients[] = ['name' => '', 'portion' => ''];
$this->ingredients[] = [
'name' => $this->ingredients_name,
'portion' => $this->ingredients_portion,
@@ -115,6 +122,19 @@ class Edit extends Component
$this->recipe->tags()->detach($selectedTags);
}
protected function rules()
{
return [
'image' => 'filled',
'state' => 'required|in:active,archived',
'description' => 'required|min:3',
'type' => 'required|min:3',
'video_url' => 'nullable|url|max:2048',
'cooking_time' => 'nullable|numeric',
];
}
public function draft()
{
$this->state = 'archived';
@@ -150,18 +170,6 @@ class Edit extends Component
return redirect()->route('recipe.show', $recipe->id);
}
protected function rules()
{
return [
'image' => 'filled',
'state' => 'required|in:active,archived',
'description' => 'required|min:3',
'type' => 'required|min:3',
'video_url' => 'nullable|url|max:2048',
'cooking_time' => 'nullable|numeric',
];
}
private function transformSteps($steps)
{
return collect($steps)->
@@ -176,4 +184,11 @@ class Edit extends Component
return $data;
})->toArray();
}
public function render()
{
return view('livewire.recipe.edit');
}
}

View File

@@ -134,12 +134,12 @@ class Plan extends Model implements Viewable
return false;
}
public function scopeByNegative(Builder $query)
public function scopeNegativeComments(Builder $query)
{
return static::comments()->where('grade', '<=', '3');
}
public function scopeByPositive(Builder $query)
public function scopePositiveComments(Builder $query)
{
return static::comments()->where('grade', '>', '3');
}

39
app/Models/Recipe.php Normal file → Executable file
View File

@@ -8,10 +8,15 @@ use Illuminate\Database\Eloquent\Casts\AsCollection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
class Recipe extends Model implements Viewable
{
use HasFactory, InteractsWithViews;
use HasFactory;
use InteractsWithViews;
use HasSlug;
protected $casts = [
'steps' => AsCollection::class,
@@ -23,6 +28,27 @@ class Recipe extends Model implements Viewable
'comments',
];
public function getSlugOptions(): SlugOptions
{
return SlugOptions::create()
->generateSlugsFrom(['title'])
->saveSlugsTo('slug')
// ->slugsShouldBeNoLongerThan(20)
->usingSeparator('_');
// ->usingLanguage('ru')
// ->doNotGenerateSlugsOnUpdate();
}
/**
* Get the route key for the model.
*
* @return string
*/
public function getRouteKeyName()
{
return 'slug';
}
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
@@ -56,6 +82,17 @@ class Recipe extends Model implements Viewable
return $this->hasMany(RecipeLike::class);
}
public function scopeNegativeComments(Builder $query)
{
return static::comments()->where('grade', '<=', '3');
}
public function scopePositiveComments(Builder $query)
{
return static::comments()->where('grade', '>', '3');
}
public function isLiked(): bool
{
$curUser = auth()->user();

1
composer.lock generated
View File

@@ -13868,3 +13868,4 @@
"platform-dev": [],
"plugin-api-version": "2.6.0"
}

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use FakerRestaurant\Provider\en_US\Restaurant;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Tag>
*/
class TagFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
$faker = \Faker\Factory::create();
$this->faker->addProvider(new Restaurant($faker));
return [
'name' => $this->faker->foodName(),
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('recipes', function (Blueprint $table) {
$table->string('slug');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('recipes', function (Blueprint $table) {
$table->dropColumn('slug');
});
}
};

View File

@@ -17,5 +17,6 @@ class DatabaseSeeder extends Seeder
$this->call(RecipeSeeder::class);
$this->call(RecipeAuthor::class);
$this->call(RecipeCommentSeeder::class);
$this->call(RecipeTagSeeder::class);
}
}

View File

@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Database\Seeders;
use App\Models\Recipe;
use Illuminate\Database\Seeder;
use App\Models\Tag;
class RecipeTagSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
if (Recipe::count() > 0) {
$recipes = Recipe::all();
$recipes->each(static function ($recipe): void {
$tags = Tag::factory()->count(5)->create();
$tagsIds = collect($tags)->map(fn($curTag) => $curTag['id']);
$recipe->tags()->attach($tagsIds);
});
}
}
}

View File

@@ -21,3 +21,12 @@
.active-icon-heart{
color: #2f80ed;
}
/* Recipe-show like */
.text-blue-400 { color: #2f80ed; }
.text-blue-500 { color: #2f80ed;}
.text-gray-400 { color: #cbd5e0; }
.text-gray-500 { color: #a0aec0; }

View File

@@ -1,8 +1,8 @@
<div class="">
@php
$positivComments = $plan->byPositive();
$positivComments = $plan->positiveComments();
$negativeComments = $plan->byNegative();
$negativeComments = $plan->negativeComments();
$positiveCommmentsCount = $positivComments->count();

View File

@@ -1,24 +1,46 @@
<div class="container px-0 mb-4 --mw-1000 --bg_white --radius fs-4_5">
<div class="d-sm-flex justify-content-between align-items-centerr ps-2 pe-3 pt-2">
<textarea wire:model="body" id="plan-comment-textarea" class="form-control h-100 --no_border --no_resize" placeholder="Введите свой комментарий"></textarea>
<div class="h-100 ps-2 pt-3 pb-4 pb-sm-0 --stars --no_wrap">
<a href="#sg1" wire:click.prevent="$set('grade', 1)">
<svg id="sg1" @class(['yellow-star-filter' => $grade >= 1]) width="24" height="24"><use xlink:href="#StarIcon"></use></svg>
</a>
<a href="#sg2" wire:click.prevent="$set('grade', 2)">
<svg id="sg2" @class(['yellow-star-filter' => $grade >= 2]) width="24" height="24"><use xlink:href="#StarIcon"></use></svg>
</a>
<a href="#sg3" wire:click.prevent="$set('grade', 3)">
<svg id="sg3" @class(['yellow-star-filter' => $grade >= 3]) width="24" height="24"><use xlink:href="#StarIcon"></use></svg>
</a>
<a href="#sg4" wire:click.prevent="$set('grade', 4)">
<svg id="sg4" @class(['yellow-star-filter' => $grade >= 4]) width="24" height="24"><use xlink:href="#StarIcon"></use></svg>
</a>
<a href="#sg5" wire:click.prevent="$set('grade', 5)">
<svg id="sg5" @class(['yellow-star-filter' => $grade >= 5]) width="24" height="24"><use xlink:href="#StarIcon"></use></svg>
</a>
<div>
<form class="reviews__form">
<textarea wire:model="body" id="commentsList" class="textarea textarea-white" placeholder="Введите отзыв"></textarea>
<div class="reviews__form-column">
<div class="reviews__form-rate star-rating">
<input @class(['star-rating__input', 'hidden' => $isChecked]) wire:model="isChecked" wire:click="$set('grade', 5)" type="radio"
name="rate" id="rate-5" value="5" hidden>
<label class="star-rating__label" for="rate-5"></label>
<input @class(['star-rating__input', 'hidden' => $isChecked]) wire:model="isChecked" wire:click="$set('grade',4)" type="radio"
name="rate" id="rate-4" value="4" hidden>
<label class="star-rating__label" for="rate-4"></label>
<input @class(['star-rating__input', 'hidden' => $isChecked]) wire:model="isChecked" wire:click="$set('grade',3)" type="radio"
name="rate" id="rate-3" value="3" hidden>
<label class="star-rating__label" for="rate-3"></label>
<input @class(['star-rating__input', 'hidden' => $isChecked]) wire:model="isChecked" wire:click="$set('grade',2)" type="radio"
name="rate" id="rate-2" value="2" hidden>
<label class="star-rating__label" for="rate-2"></label>
<input @class(['star-rating__input', 'hidden' => $isChecked]) wire:model="isChecked" wire:click="$set('grade',1)" type="radio"
name="rate" id="rate-1" value="1" hidden>
<label class="star-rating__label" for="rate-1"></label>
<input wire:model="isChecked" wire:click="$set('grade',0)" type="radio" name="rate" id="rate-0"
value="1" hidden>
</div>
<button wire:click.prevent="save" type="button" class="btn btn-primary">Оставь отзыв</button>
<a href="#sg1" wire:click.prevent="save" class="ms-3"><svg width="24" height="24"><use xlink:href="#SendPlainIcon"></use></svg></a>
</div>
</div>
</form>
@error('grade')
<div style="color:red;" role="alert">
<strong>{{ $message }}</strong>
</div>
@enderror
@error('body')
<div style="color:red;" role="alert">
<strong>{{ $message }}</strong>
</div>
@enderror
</div>

View File

@@ -1,60 +1,84 @@
<div class="container px-0 mb-4 --mw-1000 reviews">
<div class="h4 mb-4 --f_grey text-uppercase">комментарии</div>
<div class="">
@php
$positivComments = $recipe->comments()->where('grade', '>', '3');
$negativeComments = $recipe->comments()->where('grade', '<=', '3');
$positiveCommmentsCount = $positivComments->count();
$negativeCommentsCount = $negativeComments->count();
@endphp
<ul class="nav nav-tabs mb-3" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="positive-tab" data-bs-toggle="tab" data-bs-target="#positive" type="button" role="tab" aria-controls="positive" aria-selected="true">Положительные<span class="ms-2">{{ $positiveCommmentsCount }}</span></button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="negative-tab" data-bs-toggle="tab" data-bs-target="#negative" type="button" role="tab" aria-controls="negative" aria-selected="false">Негативные<span class="ms-2">{{ $negativeCommentsCount }}</span></button>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade show active" id="positive" role="tabpanel" aria-labelledby="positive-tab">
@foreach($positivComments->get() as $comment)
<div class="d-sm-flex justify-content-between flex-wrap flex-sm-nowrap mb-3 p-3 --bg_white --shadow --radius">
<div class="d-flex align-items-center">
<a href="#" class="d-none d-sm-block"><img src="{{ $comment->author->profile_photo_url }}" width="60px" height="60px" class="--radius_100"></a>
<div class="flex-grow-1 mx-sm-3">
<a href="#" class="--f_bold --f_main">{{ $comment->author->name }}</a>
<small class="d-block mt-1 mb-3 mb-sm-0">{{ $comment->body }}</small>
$positivComments = $recipe->positiveComments();
$negativeComments = $recipe->negativeComments();
$positiveCommmentsCount = $positivComments->count();
$negativeCommentsCount = $negativeComments->count();
@endphp
<div class="reviews__tabs tabs">
<div class="tablist" role="tablist" aria-labelledby="label">
<button wire:click='toggleTabpanelState("positive")' class="tab" role="tab" type="button" id="tab-1"
aria-selected="{{ $tabpanelState['positive'] ? 'true' : 'false' }}"
aria-controls="tabpanel-1">Положительные {{ $positiveCommmentsCount }}</button>
<button wire:click='toggleTabpanelState("negative")' class="tab" role="tab" type="button" id="tab-2" aria-selected="{{$tabpanelState['negative'] ? 'true' : 'false'}}"
aria-controls="tabpanel-2" tabindex="-1">Негативные {{ $negativeCommentsCount }}</button>
</div>
<div @class([
'tabpanel',
'tabpanel--hidden' => $tabpanelState['negative']
]) role="tabpanel" id="tabpanel-1" tabindex="0" aria-labelledby="tab-1">
@foreach ($positivComments->get() as $comment)
<div class="reviews__items">
<div class="review">
<div class="review__thumb">
<img src="{{ $comment->author->profile_photo_url }}" class="cover-image" alt="user">
</div>
</div>
<div class="d-flex d-sm-block align-items-center lh-1">
<div class="d-flex align-items-center">
<svg width="15" height="14" class="mx-2"><use xlink:href="#GoldStar"></use></svg>
<span class="--f_bold --f_light_gold">{{ $comment->grade }}</span>
<div class="review__content">
<div class="review__name">
{{ $comment->author->name }}
</div>
<blockquote class="review__quote">
{{ $comment->body }}
</blockquote>
</div>
<div class="review__info">
<div class="review__rate icon-star">
{{ $comment->grade }}
</div>
<livewire:recipe.comment.upvote :wire:key="$comment->id" :comment="$comment"></liviwire:recipe.comment.upvote>
</div>
@livewire('recipe.comment.upvote', ['comment' => $comment])
</div>
</div>
@endforeach
</div>
<div class="tab-pane fade" id="negative" role="tabpanel" aria-labelledby="negative-tab">
@foreach($negativeComments->get() as $comment)
<div class="d-sm-flex justify-content-between flex-wrap flex-sm-nowrap mb-3 p-3 --bg_white --shadow --radius">
<div class="d-flex align-items-center">
<a href="#" class="d-none d-sm-block"><img src="{{ $comment->author->profile_photo_url }}" width="60px" height="60px" class="--radius_100"></a>
<div class="flex-grow-1 mx-sm-3">
<a href="#" class="--f_bold --f_main">{{ $comment->author->name }}</a>
<small class="d-block mt-1 mb-3 mb-sm-0">{{ $comment->body }}</small>
<div @class([
'tabpanel',
'tabpanel--hidden' => $tabpanelState['positive']
]) role="tabpanel" id="tabpanel-2" tabindex="0" aria-labelledby="tab-1">
@foreach ($negativeComments->get() as $comment)
<div class="reviews__items">
<div class="review">
<div class="review__thumb">
<img src="{{ $comment->author->profile_photo_url }}" class="cover-image" alt="user">
</div>
</div>
<div class="d-flex d-sm-block align-items-center lh-1">
<div class="d-flex align-items-center">
<svg width="15" height="14" class="mx-2"><use xlink:href="#GoldStar"></use></svg>
<span class="--f_bold --f_light_gold">{{ $comment->grade }}</span>
<div class="review__content">
<div class="review__name">
{{ $comment->author->name }}
</div>
<blockquote class="review__quote">
{{ $comment->body }}
</blockquote>
</div>
<div class="review__info">
<div class="review__rate icon-star">
{{ $comment->grade }}
</div>
<livewire:recipe.comment.upvote :wire:key="$comment->id" :comment="$comment"></liviwire:recipe.comment.upvote>
</div>
@livewire('recipe.comment.upvote', ['comment' => $comment])
</div>
</div>
@endforeach
</div>
</div>
</div>

View File

@@ -1,4 +1,4 @@
<div class="d-flex align-items-center ms-3 ms-sm-0 mt-sm-4" data-comment-id={{ $comment->id }}>
<div style="margin-left:20px;" class="" data-comment-id={{ $comment->id }}>
<button wire:click.stop.prevent="downvote" @class(["pt-1", 'text-red-400' => $isDownVoted])>
<svg width="20" height="18" @class(["me-1", "down-vote-filter" => $isDownVoted])><use xlink:href="#DislikeIcon"></use></svg>
</button>

View File

@@ -1,11 +1,11 @@
<section class="py-5 diet" id="main">
<div class="diet__container">
<div class="diet__header">
<div class="diet__header">
<a class="diet__back icon-arrow-short-left" href="{{ route('recipe.index') }}">
<span>Мой блог</span>
<span>Мой блог</span>
</a>
<h1 class="diet__title">{{ __('recipe.adding') }}</h1>
</div>
</div>
<div class="diet__form">
<div class="diet__form-row">
<div class="label">{{ __('recipe.title') }}</div>
@@ -24,53 +24,82 @@
</select>
</div>
<div class="diet__form-row">
<div class="diet__form-columns lg-columns">
<div class="diet__form-column">
<div class="label">{{ __('recipe.picture') }}</div>
<label class="file">
<input wire:model="image" type="file" name="file" class="file__input hidden" hidden="">
@error('image') <span class="error">{{ $message }}</span> @enderror
<div class="diet__form-columns lg-columns">
<div class="diet__form-column">
<div class="label">{{ __('recipe.picture') }}</div>
<label class="file">
<input wire:model="image" type="file" name="file" class="file__input hidden"
hidden="">
@error('image')
<span class="error">{{ $message }}</span>
@enderror
<span class="file__content">
@if(is_null($image))
<span class="file__formats">
<img src="/img/formats-2.svg" alt="formats">
</span>
<span class="file__title">{{ __('recipe.tap_to_select_or_drag_and_drop') }}</span>
@if (is_null($image))
<span class="file__formats">
<img src="/img/formats-2.svg" alt="formats">
</span>
<span class="file__title">{{ __('recipe.tap_to_select_or_drag_and_drop') }}</span>
@else
<p><img src="{{ $image->temporaryUrl() }}" /> </p>
<p><img src="{{ $image->temporaryUrl() }}" /> </p>
@endif
</span>
</label>
</div>
<div class="diet__form-column diet__form-column-lg">
<div class="diet__form-row">
<div class="label">
Тип записи
</span>
</label>
</div>
<div class="diary__stats-tablist" role="tablist" aria-labelledby="label">
<button class="btn" role="tab" type="button" id="tab-1" aria-selected="true" aria-controls="tabpanel-1">Рецепт</button>
<button class="btn" role="tab" type="button" id="tab-2" aria-selected="false" aria-controls="tabpanel-2" tabindex="-1">Cтатья</button>
<div class="diet__form-column diet__form-column-lg">
<div class="diet__form-row">
<div class="label">
Тип записи
</div>
<div class="diary__stats-tablist" role="tablist" aria-labelledby="label">
<button class="btn" role="tab" type="button" id="tab-1"
wire:click="toggleStateRow('ingredient')"
aria-selected="{{ $state_row['ingredient'] }}"
aria-controls="tabpanel-1">Рецепт</button>
<button class="btn" role="tab" type="button" id="tab-2"
wire:click="toggleStateRow('article')" aria-selected="{{ $state_row['article'] }}"
aria-controls="tabpanel-2" tabindex="-1">Cтатья</button>
</div>
</div>
</div>
</div>
</div>
<div class="tabpanel" role="tabpanel" id="tabpanel-1" tabindex="0" aria-labelledby="tab-1">
<div @class([
'tabpanel',
'tabpanel--hidden' => $state_row['ingredient'] !== 'true',
]) role="tabpanel" id="tabpanel-1" tabindex="0"
aria-labelledby="tab-1">
<div class="diet__form-column">
<div class="diet__form-row">
<div class="label">{{ __('recipe.cooking_time') }}</div>
<div class="dropdown" x-data="{ open: false }" >
<button
type="button"
<div class="dropdown" x-data="{ open: false }">
<button type="button"
:class="open ? 'dropdown__button active' : 'dropdown__button'"
x-on:click="open = ! open">
{{ __('recipe.t' . $cooking_time . 'm') }}
</button>
<ul :class="open ? 'dropdown__list visible' : 'dropdown__list'">
<li wire:click="$set('cooking_time','10')" @click="open = !open" :class="$wire.cooking_time =='10'? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t10m') }}</li>
<li wire:click="$set('cooking_time','20')" @click="open = !open" :class="$wire.cooking_time =='20' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t20m') }}</li>
<li wire:click="$set('cooking_time','30')" @click="open = !open" :class="$wire.cooking_time =='30' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t30m') }}</li>
<li wire:click="$set('cooking_time','60')" @click="open = !open" :class="$wire.cooking_time =='60' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t60m') }}</li>
<li wire:click="$set('cooking_time','120')" @click="open = !open" :class="$wire.cooking_time =='120' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t120m') }}</li>
<li wire:click="$set('cooking_time','14400')" @click="open = !open" :class="$wire.cooking_time =='14400' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t14400m') }}</li>
<li wire:click="$set('cooking_time','10')" @click="open = !open"
:class="$wire.cooking_time == '10' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t10m') }}</li>
<li wire:click="$set('cooking_time','20')" @click="open = !open"
:class="$wire.cooking_time == '20' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t20m') }}</li>
<li wire:click="$set('cooking_time','30')" @click="open = !open"
:class="$wire.cooking_time == '30' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t30m') }}</li>
<li wire:click="$set('cooking_time','60')" @click="open = !open"
:class="$wire.cooking_time == '60' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t60m') }}</li>
<li wire:click="$set('cooking_time','120')" @click="open = !open"
:class="$wire.cooking_time == '120' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t120m') }}</li>
<li wire:click="$set('cooking_time','14400')" @click="open = !open"
:class="$wire.cooking_time == '14400' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t14400m') }}</li>
</ul>
</div>
</div>
@@ -81,143 +110,187 @@
<div class="dropdown" x-data="{ open: false }">
<button type="button"
:class="open ? 'dropdown__button active' : 'dropdown__button'"
x-on:click="open = ! open"
>{{ $state == 'active' ? __('recipe.record_state_active') : __('recipe.record_state_not_active') }}
x-on:click="open = ! open">{{ $state_ingredient == 'active' ? __('recipe.record_state_active') : __('recipe.record_state_not_active') }}
</button>
<ul :class="open ? 'dropdown__list visible' : 'dropdown__list'">
<li wire:click="$set('state','active')" @click="open = !open" :class="$wire.state == 'active' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.record_state_active') }}</li>
<li wire:click="$set('state','archived')" @click="open = !open" :class="$wire.state == 'archived' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.record_state_not_active') }}</li>
</ul>
</div>
</div>
</div>
<div class="diet__form-column diet__form-column-xl">
@if(!empty($ingredients))
<div class="content__table diet__form-row">
<div class="content__table-wrapper">
<table class="cabinet__table-content">
<thead>
<tr>
<th>{{ __('recipe.name_of_product')}}</th>
<th>{{ __('recipe.portion')}}</th>
<th>{{ __('recipe.units')}}</th>
</tr>
</thead>
<tbody>
@foreach($ingredients as $ingredient)
<tr>
<td>{{ $ingredient['name'] }}</td>
<td>{{ $ingredient['portion'] }}</td>
<td>{{ __('recipe.' . $ingredient['unit']) }}</td>
</tr>
@endforeach
</tbody>
</table>
<ul :class="open ? 'dropdown__list visible' : 'dropdown__list'">
<li wire:click="$set('state_ingredient','active')" @click="open = !open"
:class="$wire.state_ingredient == 'active' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.record_state_active') }}</li>
<li wire:click="$set('state_ingredient','archived')" @click="open = !open"
:class="$wire.state_ingredient == 'archived' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.record_state_not_active') }}</li>
</ul>
</div>
</div>
</div>
<div class="diet__form-column diet__form-column-xl">
@if (!empty($ingredients))
<div class="content__table diet__form-row">
<div class="content__table-wrapper">
<table class="cabinet__table-content">
<thead>
<tr>
<th>{{ __('recipe.name_of_product') }}</th>
<th>{{ __('recipe.portion') }}</th>
<th>{{ __('recipe.units') }}</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach ($ingredients as $k => $ingredient)
<tr>
<td>{{ $ingredient['name'] }}</td>
<td>{{ $ingredient['portion'] }}</td>
<td>{{ __('recipe.' . $ingredient['unit']) }}</td>
<td>
<button wire:click="removeIngredient({{ $k }})"
type="button"
class="diet__form-add btn btn-primary">-</button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
<div class="diet__form-columns">
<div class="diet__form-column diet__form-column-lg">
<input wire:model="ingredients_name" type="text" name="name"
class="input" placeholder="Введите название продукта">
</div>
<div class="diet__form-column">
<div class="diet__form-adding">
<div class="diet__form-column">
<input wire:model="ingredients_portion" type="num" name="portion"
class="input" placeholder="Порция">
<select wire:model="ingredients_unit" name="unit" class="input">
<option value="gr">гр</option>
<option value="teespoon">ч. ложек</option>
<option value="tablespoon">ст. ложек</option>
<option value="ml">мл</option>
<option value="pcs">шт</option>
<option value="clove">зубчик</option>
<option value="to_taste">по вкусу</option>
</select>
<button wire:click="addIngredient" type="button"
class="btn btn-primary icon-plus"></button>
</div>
<button type="button" class="icon-gear"></button>
</div>
</div>
</div>
</div>
</div>
<div @class([
'tabpanel',
'tabpanel--hidden' => $state_row['article'] !== 'true',
]) role="tabpanel" id="tabpanel-2" tabindex="0"
aria-labelledby="tab-2">
<div class="diet__form-column">
<div class="diet__form-row">
<div class="label">{{ __('recipe.record_state') }}</div>
<div class="dropdown" x-data="{ open: false }">
<button type="button"
:class="open ? 'dropdown__button active' : 'dropdown__button'"
x-on:click="open = ! open">{{ $state_article == 'active' ? __('recipe.record_state_active') : __('recipe.record_state_not_active') }}
</button>
<ul :class="open ? 'dropdown__list visible' : 'dropdown__list'">
<li wire:click="$set('state_article','active')" @click="open = !open"
:class="$wire.state_article == 'active' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.record_state_active') }}</li>
<li wire:click="$set('state_article','archived')" @click="open = !open"
:class="$wire.state_article == 'archived' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.record_state_not_active') }}</li>
</ul>
</div>
</div>
@endif
<div class="diet__form-columns">
<div class="diet__form-column diet__form-column-lg">
<input wire:model="ingredients_name" type="text" name="name" class="input" placeholder="Введите название продукта">
</div>
<div class="diet__form-column">
<div class="diet__form-adding">
<div class="diet__form-column">
<input wire:model="ingredients_portion" type="num" name="portion" class="input" placeholder="Порция">
<select wire:model="ingredients_unit" name="unit" class="input">
<option value="gr">гр</option>
<option value="teespoon">ч. ложек</option>
<option value="tablespoon">ст. ложек</option>
<option value="ml">мл</option>
<option value="pcs">шт</option>
<option value="clove">зубчик</option>
<option value="to_taste">по вкусу</option>
</select>
<button wire:click="addIngredient" type="button" class="btn btn-primary icon-plus"></button>
</div>
<button type="button" class="icon-gear"></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="diet__form-row">
<div class="label">{{ __('recipe.content') }}</div>
<div class="label">{{ __('recipe.content') }}</div>
<div class="wysiwyg" wire:ignore>
<div
class="form-textarea w-full"
x-data="{}"
x-init="ClassicEditor.create($refs.myIdentifierHere,
{
toolbar: {
items: [
'heading', '|',
'bold', 'italic', '|',
'bulletedList', 'numberedList', '|',
'outdent', 'indent', '|',
'blockQuote', 'undo', 'redo'
],
shouldNotGroupWhenFull: true
}
})
.then( function(editor){
editor.model.document.on('change:data', () => {
console.log(editor.getData());
// $dispatch('input', editor.getData())
@this.set('description', editor.getData());
})
})
.catch( error => {
console.error( error );
});"
wire:ignore
wire:key="myIdentifierHere"
x-ref="myIdentifierHere"
<div class="form-textarea w-full" x-data="{}" x-init="ClassicEditor.create($refs.myIdentifierHere, {
toolbar: {
items: [
'heading', '|',
'bold', 'italic', '|',
'bulletedList', 'numberedList', '|',
'outdent', 'indent', '|',
'blockQuote', 'undo', 'redo'
],
shouldNotGroupWhenFull: true
}
})
.then(function(editor) {
editor.model.document.on('change:data', () => {
console.log(editor.getData());
// $dispatch('input', editor.getData())
@this.set('description', editor.getData());
})
})
.catch(error => {
console.error(error);
});" wire:ignore
wire:key="myIdentifierHere" x-ref="myIdentifierHere"
wire:model.live.debounce.9999999ms="description"></div>
</div>
</div>
</div>
@php
$stepsCount = count($steps);
@endphp
@for($i = 0; $i < $stepsCount; $i++)
<div class="diet__form-row">
<div class="label">
{{ __('recipe.step') }} {{ $i + 1 }}
@if($i == 0)
<span>{{ __('recipe.total_steps') }}: {{ $stepsCount }}</span>
@endif
</div>
<div class="diet__form-step">
<label class="file">
<input class="file__input hidden" hidden="" type="file" name="step[{{$i}}][image]" wire:model="steps.{{$i}}.image" id="step[{{$i}}][image]" />
<span class="file__content">
@if ($steps[$i]['image'])
<img src="{{ $steps[$i]['image']->temporaryUrl() }}">
@else
<img src="/img/add-file.svg" width="40" height="40" alt="formats">
@endif
</span>
</label>
<textarea name="desc-step-1" class="textarea" wire:model="steps.{{$i}}.description" id="step[{{$i}}][description]" placeholder="Введите описание шага"></textarea>
<div class="diet__form-column">
<button type="button" wire:click="removeStep({{$i}})" class="diet__form-add btn {{ $i == 0 ? 'btn-gray' : 'btn-primary' }}" @disabled($i == 0)>-</button>
<button type="button" wire:click="addStep" class="diet__form-add btn btn-primary" data-bs-original-title="Добавить шаг">+</button>
@for ($i = 0; $i < $stepsCount; $i++)
<div class="diet__form-row">
<div class="label">
{{ __('recipe.step') }} {{ $i + 1 }}
@if ($i == 0)
<span>{{ __('recipe.total_steps') }}: {{ $stepsCount }}</span>
@endif
</div>
<div class="diet__form-step">
<label class="file">
<input class="file__input hidden" hidden="" type="file"
name="step[{{ $i }}][image]" wire:model="steps.{{ $i }}.image"
id="step[{{ $i }}][image]" />
<span class="file__content">
@if ($steps[$i]['image'])
<img src="{{ $steps[$i]['image']->temporaryUrl() }}">
@else
<img src="/img/add-file.svg" width="40" height="40" alt="formats">
@endif
</span>
</label>
<textarea name="desc-step-1" class="textarea" wire:model="steps.{{ $i }}.description"
id="step[{{ $i }}][description]" placeholder="Введите описание шага"></textarea>
<div class="diet__form-column">
<button type="button" wire:click="removeStep({{ $i }})"
class="diet__form-add btn {{ $i == 0 ? 'btn-gray' : 'btn-primary' }}"
@disabled($i == 0)>-</button>
<button type="button" wire:click="addStep" class="diet__form-add btn btn-primary"
data-bs-original-title="Добавить шаг">+</button>
</div>
</div>
</div>
</div>
</div>
@endfor
<div class="diet__form-row">
<div class="label" data-tags="{{ json_encode($tags) }}">{{ __('recipe.tags') }}</div>
<!--input type="text" name="link" class="input" placeholder="Введите теги через запятую"-->
<livewire:tags-component key="tags-component" />
<div class="label" data-tags="{{ json_encode($tags) }}">{{ __('recipe.tags') }}</div>
<!--input type="text" name="link" class="input" placeholder="Введите теги через запятую"-->
<livewire:tags-component key="tags-component" />
</div>
<div class="diet__form-row">
<div class="label">{{ __('recipe.video_link') }}</div>
<input type="text" name="link" wire:model="video_url" class="input" placeholder="Прикрепите ссылку на YouTube видео">
<div class="label">{{ __('recipe.video_link') }}</div>
<input type="text" name="link" wire:model="video_url" class="input"
placeholder="Прикрепите ссылку на YouTube видео">
</div>
</div>
</div>
</div>
{{-- <div class="container mb-4 py-3 overflow-hidden --bg_white --shadow --radius --mw-1000">
@@ -259,7 +332,7 @@
<div class="mb-4 fs-4_5 --reciept">
<div class="tab-pane fade show active">
@php $lastIngedient = count($ingredients) - 1; @endphp
@foreach($ingredients as $k => $ingredient)
@foreach ($ingredients as $k => $ingredient)
<div class="d-flex align-items-top flex-wrap flex-sm-nowrap mb-4" data-row="{{ $k }}">
<div class="w-100">
<input type="text" wire:model="ingredients.{{$k}}.name" class="form-control fs-4_5 py-3 w-100" placeholder="Введите название продукта...." required="">
@@ -303,9 +376,12 @@
</div> --}}
<div class="diet__container">
<div class="diet__btns">
<button wire:click="draft" class="diet__btn btn btn-gray" type="button">{{ __('recipe.to_drafts') }}</button>
<button wire:click="preview" class="diet__btn btn btn-gray" type="button">{{ __('recipe.preview') }}</button>
<button wire:click="publish" class="diet__btn btn btn-primary" type="submit">{{ __('recipe.publish') }}</button>
<button wire:click="draft" class="diet__btn btn btn-gray"
type="button">{{ __('recipe.to_drafts') }}</button>
<button wire:click="preview" class="diet__btn btn btn-gray"
type="button">{{ __('recipe.preview') }}</button>
<button wire:click="publish" class="diet__btn btn btn-primary"
type="submit">{{ __('recipe.publish') }}</button>
</div>
</div>
@@ -315,4 +391,3 @@
@endforeach
</div>
</section>

View File

@@ -26,197 +26,279 @@
<div class="diet__form-row">
<div class="diet__form-columns lg-columns">
<div class="diet__form-column">
<div class="label">{{ __('recipe.picture') }}</div>
<label class="file">
<input type="file" wire:model="image" name="file" class="file__input hidden" hidden="">
<span class="file__content">
<span class="file__formats">
@if(is_null($image))
<img src="/img/formats-2.svg" alt="formats">
@else
<img src="{{ is_string($image) ? Storage::url($image) : $image->temporaryUrl() }}" />
@endif
</span>
<span class="file__title">
@if(is_null($image))
Нажмите для&nbsp;выбора или&nbsp;перетащите изображание
@endif
</span>
</span>
</label>
@error('image') <span class="error">{{ $message }}</span> @enderror
</div>
<div class="diet__form-column diet__form-column-lg">
<div class="diet__form-row">
<div class="label">
Тип записи
</div>
<div class="diary__stats-tablist" role="tablist" aria-labelledby="label">
<button class="btn" role="tab" type="button" id="tab-1" aria-selected="true" aria-controls="tabpanel-1">{{ __('recipe.self') }}</button>
<button class="btn" role="tab" type="button" id="tab-2" aria-selected="false" aria-controls="tabpanel-2" tabindex="-1">{{ __('recipe.blog_post') }}</button>
</div>
</div>
</div>
<div class="tabpanel" role="tabpanel" id="tabpanel-1" tabindex="0" aria-labelledby="tab-1">
<div class="diet__form-column">
<div class="label">{{ __('recipe.picture') }}</div>
<label class="file">
<input type="file" wire:model="image" name="file" class="file__input hidden"
hidden="">
<span class="file__content">
<span class="file__formats">
@if (is_null($image))
<img src="/img/formats-2.svg" alt="formats">
@else
<img
src="{{ is_string($image) ? Storage::url($image) : $image->temporaryUrl() }}" />
@endif
</span>
<span class="file__title">
@if (is_null($image))
Нажмите для&nbsp;выбора или&nbsp;перетащите изображание
@endif
</span>
</span>
</label>
@error('image')
<span class="error">{{ $message }}</span>
@enderror
</div>
<div class="diet__form-column diet__form-column-lg">
<div class="diet__form-row">
<div class="label">{{ __('recipe.cooking_time') }}</div>
<div class="dropdown" x-data="{ open: false }" >
<button
type="button"
:class="open ? 'dropdown__button active' : 'dropdown__button'"
x-on:click="open = ! open">
{{ __('recipe.t' . $cooking_time . 'm') }}
</button>
<ul :class="open ? 'dropdown__list visible' : 'dropdown__list'">
<li wire:click="$set('cooking_time','10')" @click="open = !open" :class="$wire.cooking_time =='10'? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t10m') }}</li>
<li wire:click="$set('cooking_time','20')" @click="open = !open" :class="$wire.cooking_time =='20' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t20m') }}</li>
<li wire:click="$set('cooking_time','30')" @click="open = !open" :class="$wire.cooking_time =='30' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t30m') }}</li>
<li wire:click="$set('cooking_time','60')" @click="open = !open" :class="$wire.cooking_time =='60' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t60m') }}</li>
<li wire:click="$set('cooking_time','120')" @click="open = !open" :class="$wire.cooking_time =='120' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t120m') }}</li>
<li wire:click="$set('cooking_time','14400')" @click="open = !open" :class="$wire.cooking_time =='14400' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.t14400m') }}</li>
</ul>
<div class="label">
Тип записи
</div>
</div>
</div>
<div class="diet__form-column">
<div class="diet__form-row">
<div class="label">{{ __('recipe.record_state') }}</div>
<div class="dropdown" x-data="{ open: false }">
<button type="button"
:class="open ? 'dropdown__button active' : 'dropdown__button'"
x-on:click="open = ! open"
>{{ $state == 'active' ? __('recipe.record_state_active') : __('recipe.record_state_not_active') }}
</button>
<ul :class="open ? 'dropdown__list visible' : 'dropdown__list'">
<li wire:click="$set('state','active')" @click="open = !open" :class="$wire.state == 'active' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.record_state_active') }}</li>
<li wire:click="$set('state','archived')" @click="open = !open" :class="$wire.state == 'archived' ? 'dropdown__list-item active' : 'dropdown__list-item'">{{ __('recipe.record_state_not_active') }}</li>
</ul>
</div>
</div>
</div>
@php $n = count($ingredients); $lastIngedient = $n-1; @endphp
@if($n == 0)
<div class="diet__form-column diet__form-column-xl">
<div class="diet__form-columns">
<div class="diet__form-column diet__form-column-lg" data-row="0">
<input type="text" wire:model="ingredients.0.name" class="input" placeholder="Введите название продукта...." required="">
</div>
<div class="diet__form-column">
<div class="diet__form-adding">
<div class="diary__stats-tablist" role="tablist" aria-labelledby="label">
<button class="btn" role="tab" type="button" id="tab-1"
wire:click="toggleStateRow('ingredient')"
aria-selected="{{ $state_row['ingredient'] }}"
aria-controls="tabpanel-1">Рецепт</button>
<button class="btn" role="tab" type="button" id="tab-2"
wire:click="toggleStateRow('article')" aria-selected="{{ $state_row['article'] }}"
aria-controls="tabpanel-2" tabindex="-1">Cтатья</button>
</div>
{{-- <div class="diary__stats-tablist" role="tablist" aria-labelledby="label"> --}}
{{-- <button class="btn" role="tab" type="button" id="tab-1" aria-selected="true" aria-controls="tabpanel-1">{{ __('recipe.self') }}</button> --}}
{{-- <button class="btn" role="tab" type="button" id="tab-2" aria-selected="false" aria-controls="tabpanel-2" tabindex="-1">{{ __('recipe.blog_post') }}</button> --}}
{{-- </div> --}}
</div>
</div>
<div @class([
'tabpanel',
'tabpanel--hidden' => $state_row['ingredient'] !== 'true',
]) role="tabpanel" id="tabpanel-1" tabindex="0"
aria-labelledby="tab-1">
<div class="diet__form-column">
<div class="diet__form-row">
<div class="label">{{ __('recipe.cooking_time') }}</div>
<div class="dropdown" x-data="{ open: false }">
<button type="button"
:class="open ? 'dropdown__button active' : 'dropdown__button'"
x-on:click="open = ! open">
{{ __('recipe.t' . $cooking_time . 'm') }}
</button>
<ul :class="open ? 'dropdown__list visible' : 'dropdown__list'">
<li wire:click="$set('cooking_time','10')" @click="open = !open"
:class="$wire.cooking_time == '10' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t10m') }}</li>
<li wire:click="$set('cooking_time','20')" @click="open = !open"
:class="$wire.cooking_time == '20' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t20m') }}</li>
<li wire:click="$set('cooking_time','30')" @click="open = !open"
:class="$wire.cooking_time == '30' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t30m') }}</li>
<li wire:click="$set('cooking_time','60')" @click="open = !open"
:class="$wire.cooking_time == '60' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t60m') }}</li>
<li wire:click="$set('cooking_time','120')" @click="open = !open"
:class="$wire.cooking_time == '120' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t120m') }}</li>
<li wire:click="$set('cooking_time','14400')" @click="open = !open"
:class="$wire.cooking_time == '14400' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.t14400m') }}</li>
</ul>
</div>
</div>
</div>
<div class="diet__form-column">
<div class="diet__form-row">
<div class="label">{{ __('recipe.record_state') }}</div>
<div class="dropdown" x-data="{ open: false }">
<button type="button"
:class="open ? 'dropdown__button active' : 'dropdown__button'"
x-on:click="open = ! open">{{ $state == 'active' ? __('recipe.record_state_active') : __('recipe.record_state_not_active') }}
</button>
<ul :class="open ? 'dropdown__list visible' : 'dropdown__list'">
<li wire:click="$set('state','active')" @click="open = !open"
:class="$wire.state == 'active' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.record_state_active') }}</li>
<li wire:click="$set('state','archived')" @click="open = !open"
:class="$wire.state == 'archived' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.record_state_not_active') }}</li>
</ul>
</div>
</div>
</div>
@php
$n = count($ingredients);
$lastIngedient = $n - 1;
@endphp
@if ($n == 0)
<div class="diet__form-column diet__form-column-xl">
<div class="diet__form-columns">
<div class="diet__form-column diet__form-column-lg" data-row="0">
<input type="text" wire:model="ingredients.0.name" class="input"
placeholder="Введите название продукта...." required="">
</div>
<div class="diet__form-column">
<select wire:model="ingredients.0.unit" name="unit" class="input">
<option value="gr">гр</option>
<option value="teespoon">ч. ложек</option>
<option value="tablespoon">ст. ложек</option>
<option value="ml">мл</option>
<option value="pcs">шт</option>
<option value="clove">зубчик</option>
<option value="to_taste">по вкусу</option>
</select>
</div>
<div class="diet__form-adding">
<div class="diet__form-column">
<select wire:model="ingredients.0.unit" name="unit"
class="input">
<option value="gr">гр</option>
<option value="teespoon">ч. ложек</option>
<option value="tablespoon">ст. ложек</option>
<option value="ml">мл</option>
<option value="pcs">шт</option>
<option value="clove">зубчик</option>
<option value="to_taste">по вкусу</option>
</select>
</div>
<div class="diet__form-column">
<input wire:model="ingredients.0.portion" class="input"
placeholder="Порция" required="" type="number">
<button wire:click="addIngredient" type="button"
class="btn btn-primary icon-plus"></button>
</div>
</div>
</div>
</div>
</div>
@endif
@foreach ($ingredients as $k => $ingredient)
<div class="diet__form-column diet__form-column-xl">
<div class="diet__form-columns">
<div class="diet__form-column diet__form-column-lg"
data-row="{{ $k }}">
<input type="text" wire:model="ingredients.{{ $k }}.name"
class="input" placeholder="Введите название продукта...."
required="">
</div>
<div class="diet__form-column">
<input wire:model="ingredients.0.portion" class="input" placeholder="Порция" required="" type="number">
<button wire:click="addIngredient" type="button" class="btn btn-primary icon-plus"></button>
<div class="diet__form-adding">
<div class="diet__form-column">
<select wire:model="ingredients.{{ $k }}.unit"
name="unit" class="input">
<option value="gr">гр</option>
<option value="teespoon">ч. ложек</option>
<option value="tablespoon">ст. ложек</option>
<option value="ml">мл</option>
<option value="pcs">шт</option>
<option value="clove">зубчик</option>
<option value="to_taste">по вкусу</option>
</select>
</div>
<div class="diet__form-column">
<input wire:model="ingredients.{{ $k }}.portion"
class="input" placeholder="Порция" required=""
type="number">
@if ($k == count($ingredients) - 1)
<button wire:click="addIngredient" type="button"
class="btn btn-primary icon-plus"></button>
@endif
</div>
<button wire:click="removeIngredient({{ $k }})" type="button"
class="btn btn-danger">x</button>
</div>
</div>
</div>
</div>
</div>
@endforeach
</div>
@endif
@foreach($ingredients as $k => $ingredient)
<div class="diet__form-column diet__form-column-xl">
<div class="diet__form-columns">
<div class="diet__form-column diet__form-column-lg" data-row="{{ $k }}">
<input type="text" wire:model="ingredients.{{$k}}.name" class="input" placeholder="Введите название продукта...." required="">
</div>
<div class="diet__form-column">
<div class="diet__form-adding">
<div class="diet__form-column">
<select wire:model="ingredients.{{ $k }}.unit" name="unit" class="input">
<option value="gr">гр</option>
<option value="teespoon">ч. ложек</option>
<option value="tablespoon">ст. ложек</option>
<option value="ml">мл</option>
<option value="pcs">шт</option>
<option value="clove">зубчик</option>
<option value="to_taste">по вкусу</option>
</select>
</div>
<div class="diet__form-column">
<input wire:model="ingredients.{{ $k }}.portion" class="input" placeholder="Порция" required="" type="number">
@if($k == count($ingredients)-1)
<button wire:click="addIngredient" type="button" class="btn btn-primary icon-plus"></button>
@endif
</div>
<button wire:click="removeIngredient({{$k}})" type="button" class="btn btn-danger">x</button>
</div>
</div>
</div>
</div>
@endforeach
</div>
<div class="tabpanel tabpanel--hidden" role="tabpanel" id="tabpanel-2" tabindex="0" aria-labelledby="tab-2">
<div class="diet__form-column">
<div class="diet__form-row">
<div class="label">
Статус
</div>
<div class="dropdown">
<button type="button" class="dropdown__button">
Активна
</button>
<ul class="dropdown__list">
<li data-value="active" class="dropdown__list-item active">Активна</li>
<li data-value="unactive" class="dropdown__list-item">Неактивна</li>
</ul>
<input type="text" name="status" class="dropdown__input hidden" hidden="" value="unactive">
</div>
<div @class([
'tabpanel',
'tabpanel--hidden' => $state_row['article'] !== 'true',
]) role="tabpanel" id="tabpanel-2" tabindex="0"
aria-labelledby="tab-2">
<div class="diet__form-column">
<div class="diet__form-row">
<div class="label">{{ __('recipe.record_state') }}</div>
<div class="dropdown" x-data="{ open: false }">
<button type="button"
:class="open ? 'dropdown__button active' : 'dropdown__button'"
x-on:click="open = ! open">{{ $state_article == 'active' ? __('recipe.record_state_active') : __('recipe.record_state_not_active') }}
</button>
<ul :class="open ? 'dropdown__list visible' : 'dropdown__list'">
<li wire:click="$set('state_article','active')" @click="open = !open"
:class="$wire.state_article == 'active' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.record_state_active') }}</li>
<li wire:click="$set('state_article','archived')" @click="open = !open"
:class="$wire.state_article == 'archived' ? 'dropdown__list-item active' :
'dropdown__list-item'">
{{ __('recipe.record_state_not_active') }}</li>
</ul>
</div>
</div>
</div>
</div>
<div class="tabpanel tabpanel--hidden" role="tabpanel" id="tabpanel-2" tabindex="0"
aria-labelledby="tab-2">
<div class="diet__form-column">
<div class="diet__form-row">
<div class="label">
Статус
</div>
<div class="dropdown">
<button type="button" class="dropdown__button">
Активна
</button>
<ul class="dropdown__list">
<li data-value="active" class="dropdown__list-item active">Активна</li>
<li data-value="unactive" class="dropdown__list-item">Неактивна</li>
</ul>
<input type="text" name="status" class="dropdown__input hidden"
hidden="" value="unactive">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="mb-4 fs-4_5" wire:ignore>
<label for="txtFormatter" class="mb-2">{{ __('recipe.content') }}</label>
<div
class="form-textarea w-full"
x-data="{}"
x-init="ClassicEditor.create($refs.myIdentifierHere,
{
toolbar: {
items: [
'heading', '|',
'bold', 'italic', '|',
'bulletedList', 'numberedList', '|',
'outdent', 'indent', '|',
'blockQuote', 'undo', 'redo'
],
shouldNotGroupWhenFull: true
}
})
.then( function(editor){
editor.model.document.on('change:data', () => {
$dispatch('input', editor.getData())
})
})
.catch( error => {
console.error( error );
});"
wire:ignore
wire:key="myIdentifierHere"
x-ref="myIdentifierHere"
wire:model.live="description">{!! $description !!}</div>
<div class="form-textarea w-full" x-data="{}" x-init="ClassicEditor.create($refs.myIdentifierHere, {
toolbar: {
items: [
'heading', '|',
'bold', 'italic', '|',
'bulletedList', 'numberedList', '|',
'outdent', 'indent', '|',
'blockQuote', 'undo', 'redo'
],
shouldNotGroupWhenFull: true
}
})
.then(function(editor) {
editor.model.document.on('change:data', () => {
$dispatch('input', editor.getData())
})
})
.catch(error => {
console.error(error);
});" wire:ignore
wire:key="myIdentifierHere" x-ref="myIdentifierHere" wire:model.live="description">
{!! $description !!}</div>
</div>
</div>
@php
$stepsCount = count($steps);
@endphp
@for($i = 0; $i < $stepsCount; $i++)
@for ($i = 0; $i < $stepsCount; $i++)
<div class="diet__form-row">
<div class="label">
{{ __('recipe.step') }} {{ $i + 1 }}
@@ -230,8 +312,12 @@
@if (isset($steps[$i]['image']) && is_string($steps[$i]['image']))
<img src="{{ Storage::url($steps[$i]['image']) }}">
@endif
<input type="file" name="step[{{$i}}][image]" wire:model="steps.{{$i}}.image" id="step[{{$i}}][image]" hidden>
@error('steps.'. $i . '.image') <span class="error">{{ $message }}</span> @enderror
<input type="file" name="step[{{ $i }}][image]"
wire:model="steps.{{ $i }}.image"
id="step[{{ $i }}][image]" hidden>
@error('steps.' . $i . '.image')
<span class="error">{{ $message }}</span>
@enderror
@if (!isset($steps[$i]['image']))
<div class="my-3">
<svg width="50" height="50">
@@ -241,10 +327,15 @@
@endif
</span>
</label>
<textarea class="textarea" name="step[{{$i}}][description]" wire:model.defer="steps.{{$i}}.description" autoresize="" placeholder="Введи описание шага" rows="5">{{ $steps[$i]['description'] ?? '' }}</textarea>
<textarea class="textarea" name="step[{{ $i }}][description]"
wire:model.defer="steps.{{ $i }}.description" autoresize="" placeholder="Введи описание шага"
rows="5">{{ $steps[$i]['description'] ?? '' }}</textarea>
<div class="diet__form-column">
<button type="button" wire:click="removeStep({{$i}})" class="diet__form-add btn btn-primary" @disabled($i == 0)>-</button>
<button type="button" wire:click="addStep" class="diet__form-add btn btn-primary" data-bs-toggle="tooltip" data-bs-placement="left" title="" data-bs-original-title="Добавить шаг">+</button>
<button type="button" wire:click="removeStep({{ $i }})"
class="diet__form-add btn btn-primary" @disabled($i == 0)>-</button>
<button type="button" wire:click="addStep" class="diet__form-add btn btn-primary"
data-bs-toggle="tooltip" data-bs-placement="left" title=""
data-bs-original-title="Добавить шаг">+</button>
</div>
</div>
</div>
@@ -259,20 +350,23 @@
<div class="label">
{{ __('recipe.video_link') }}
</div>
<input wire:model="video_url" type="text" class="input" placeholder="Прикрепите ссылку на YouTube видео">
<input wire:model="video_url" type="text" class="input"
placeholder="Прикрепите ссылку на YouTube видео">
</div>
</div>
<div class="diet__btns">
<button wire:click="draft" type="button" class="diet__btn btn btn-gray">{{ __('recipe.to_drafts') }}</button>
<button type="button" wire:click="preview" class="diet__btn btn btn-gray">{{ __('recipe.preview') }}</button>
<button type="button" wire:click="publish" class="diet__btn btn btn-primary">{{ __('recipe.publish') }}</button>
<button wire:click="draft" type="button"
class="diet__btn btn btn-gray">{{ __('recipe.to_drafts') }}</button>
<button type="button" wire:click="preview"
class="diet__btn btn btn-gray">{{ __('recipe.preview') }}</button>
<button type="button" wire:click="publish"
class="diet__btn btn btn-primary">{{ __('recipe.publish') }}</button>
</div>
<div class="container mb-5 p-0 --mw-1000">
@foreach ($errors->all() as $message)
<div class="alert alert-warning">{{ $message }}</div>
@endforeach
</div>
<div class="container mb-5 p-0 --mw-1000">
@foreach ($errors->all() as $message)
<div class="alert alert-warning">{{ $message }}</div>
@endforeach
</div>
</div>
</section>

View File

@@ -1,4 +1,4 @@
<button wire:click="like" class="d-flex align-items-center me-4 me-sm-5 inline-flex space-x-2 d-flex align-items-center {{ $recipe->isLiked() ? 'text-blue-400 hover:text-blue-500' : 'text-gray-400 hover:text-gray-500' }} focus:outline-none focus:ring-0">
<svg width="24" height="21" class="me-1"><use xlink:href="#HeartPath"></use></svg>
<button wire:click="like" class="{{ $recipe->isLiked() ? 'text-blue-400 hover:text-blue-500' : 'text-gray-400 hover:text-gray-500' }} focus:outline-none focus:ring-0">
<svg width="24" height="21" class=""><use xlink:href="#HeartPath"></use></svg>
{{ $isIconOnly ? "Нравится" : "" }}
</button>

View File

@@ -1,147 +1,172 @@
@extends('layouts/eatvio')
@section('page_title', 'Recipe ' . $recipe->title)
@php
$recipeViewsCount = views($recipe)->unique()->count();
@endphp
@section('main_section')
<section class="content">
<div class="content__container container-sm">
<div class="content__heading">
<a href="{{ route('recipe.index') }}" class="content__heading-back icon-arrow-short-left">
<span>Рецепты</span>
</a>
<div class="content__heading-stats">
<div class="content__heading-stat icon-eye-fill">
<strong>{{ $recipeViewsCount }}</strong>
</div>
<div class="content__heading-stat icon-heart-fill">
<strong>@livewire('recipe.like-count', ['recipe' => $recipe])</strong>
</div>
<div class="content__heading-stat icon-message-square">
<strong>{{ $recipe->comments_count }}</strong>
</div>
</div>
<div class="content__person">
<div class="content__person-name">
{{ $author['name'] }}
</div>
<div class="content__person-thumb">
@empty($author->profile_photo_path)
<img src="{{ $author->profile_photo_url }}" alt="thumb">
@else
<img src="/storage/{{ $author->profile_photo_path }}" alt="thumb">
@endempty
</div>
</div>
</div>
</div>
</section>
<section class="recipe">
<div class="recipe__container container-sm">
<div class="recipe__content">
<div class="recipe__header">
<div class="recipe__image" style="height: 100%;">
<img src="/storage/{{ $recipe->image }}" class="cover-image" alt="recipe">
</div>
<div class="recipe__body">
<div class="recipe__caption">
<h1 class="recipe__title">
{{ $recipe->title }}
</h1>
<button type="button" class="recipe__action icon-dotts"></button>
</div>
<div class="recipe__stats">
<div class="recipe__stat icon-clock">{{ __('recipe.t' . $recipe->cooking_time . "m") }}</div>
<div class="recipe__stat icon-foots">{{ $recipe->steps->count() }} этапов</div>
</div>
<p class="recipe__desc">{!! $recipe->description !!}</p>
@if (strlen(trim($recipe->video_url)) > 4)
<a target="_blank" rel="noopener noreferrer" href="{{ $recipe->video_url }}" class="recipe__link icon-youtube">Посмотреть рецепт на YouTube</a>
@endif
</div>
</div>
<div class="recipe__info">
<div class="recipe__info-column">
<div class="recipe__info-caption">
ПРОДУКТЫ:
</div>
<ul class="recipe__info-list marked">
@foreach($recipe->ingredients as $ingredient)
@php
$localizedUnit = (isset($ingredient['unit']) && mb_strlen($ingredient['unit']) > 1)
? $ingredient['unit']
: 'gr';
@endphp
@if(mb_strlen($ingredient['name']) > 1)
<li>{{ $ingredient['name'] }} - {{ $ingredient['portion'] }} {{ __('recipe.' . $localizedUnit ) }}</li>
@endif
@endforeach
</ul>
</div>
<div class="recipe__info-column">
<div class="recipe__info-caption">
ЦЕННОСТЬ:
</div>
<ul class="recipe__info-list">
<li>WIP</li>
{{--
@section('page_title', 'Recipe ' . $recipe->title)
@php
$recipeViewsCount = views($recipe)
->unique()
->count();
@endphp
@section('main_section')
<section class="content">
<div class="content__container container-sm">
<div class="content__heading">
<a href="{{ route('recipe.index') }}" class="content__heading-back icon-arrow-short-left">
<span>Рецепты</span>
</a>
<div class="content__heading-stats">
<div class="content__heading-stat icon-eye-fill">
<strong>{{ $recipeViewsCount }}</strong>
</div>
<div class="content__heading-stat icon-heart-fill">
<strong>@livewire('recipe.like-count', ['recipe' => $recipe])</strong>
</div>
<div class="content__heading-stat icon-message-square">
<strong>{{ $recipe->comments_count }}</strong>
</div>
</div>
<div class="content__person">
<div class="content__person-name">
{{ $author['name'] }}
</div>
<div class="content__person-thumb">
@empty($author->profile_photo_path)
<img src="{{ $author->profile_photo_url }}" alt="thumb">
@else
<img src="/storage/{{ $author->profile_photo_path }}" alt="thumb">
@endempty
</div>
</div>
</div>
</div>
</section>
<section class="recipe">
<div class="recipe__container container-sm">
<div class="recipe__content">
<div class="recipe__header">
<div class="recipe__image" style="height: 100%;">
<img src="{{ Storage::url($recipe->image) }}" class="cover-image" alt="recipe">
</div>
<div class="recipe__body">
<div class="recipe__caption">
<h1 class="recipe__title">
{{ $recipe->title }}
</h1>
<div class="announcement__actions">
<button x-data="{ open: false }" x-on:click="open = ! open" type="button"
class="announcement__actions-btn icon-more-horizontal"></button>
<ul class="announcement__actions-list">
<li class="announcement__actions-item">
<a href="{{route('recipe.edit', ['recipe' => $recipe->id], false)}}" class="announcement__action">Редактировать</a>
</li>
<li class="announcement__actions-item">
<button type="button" class="announcement__action">О рекламодателе</button>
</li>
<li class="announcement__actions-item">
<button type="button" class="announcement__action">Не интересно</button>
</li>
<li class="announcement__actions-item">
<button type="button" class="announcement__action">Пожаловаться</button>
</li>
{{-- <li class="announcement__actions-item"> --}}
{{-- <div class="announcement__actions-id">ID: 2jkfk45JG</div> --}}
{{-- </li> --}}
</ul>
</div>
</div>
<div class="recipe__stats">
<div class="recipe__stat icon-clock">{{ __('recipe.t' . $recipe->cooking_time . 'm') }}</div>
<div class="recipe__stat icon-foots">{{ $recipe->steps->count() }} этапов</div>
</div>
<p class="recipe__desc">{!! $recipe->description !!}</p>
@if (strlen(trim($recipe->video_url)) > 4)
<a target="_blank" rel="noopener noreferrer" href="{{ $recipe->video_url }}"
class="recipe__link icon-youtube">Посмотреть рецепт на YouTube</a>
@endif
</div>
</div>
<div class="recipe__info">
<div class="recipe__info-column">
<div class="recipe__info-caption">
ПРОДУКТЫ:
</div>
<ul class="recipe__info-list marked">
@foreach ($recipe->ingredients as $ingredient)
@php
$localizedUnit = isset($ingredient['unit']) && mb_strlen($ingredient['unit']) > 1 ? $ingredient['unit'] : 'gr';
@endphp
@if (mb_strlen($ingredient['name']) > 1)
<li>{{ $ingredient['name'] }} - {{ $ingredient['portion'] }}
{{ __('recipe.' . $localizedUnit) }}</li>
@endif
@endforeach
</ul>
</div>
<div class="recipe__info-column">
<div class="recipe__info-caption">
ЦЕННОСТЬ:
</div>
<ul class="recipe__info-list">
<li>WIP</li>
{{--
<li>Калории: 139.9 ккал</li>
<li>Белки: 20.4 гр</li>
<li>Жиры: 5.7 гр</li>
<li>Углеводы: 1.8 гр</li>
--}}
</ul>
</div>
<div class="recipe__info-column">
<div class="recipe__info-caption">
ЦЕННОСТЬ:
</div>
<div class="recipe__info-tags">
@foreach($recipe->tags->unique() as $curTag)
<a href="{{ $curTag->recipe_index_url }}" class="recipe__info-tag">{{ $curTag->name }}</a>
@endforeach
</div>
</div>
</div>
<div class="recipe__footer">
<a href="#commentsList" class="recipe__footer-action icon-message-square">
<span>Комментировать</span>
</a>
@livewire('recipe.like', ['recipe' => $recipe])
{{--<button class="recipe__footer-action icon-heart">
<span>Нравится</span>
</button>--}}
<button class="recipe__footer-action icon-share">
<span>Поделится</span>
</button>
</div>
</div>
</div>
</section>
<section class="steps">
<div class="steps__container container-sm">
<h2 class="steps__title title">
ПОШАГОВЫЙ ФОТО РЕЦЕПТ - {{ $recipe->title }}
</h2>
<ol class="steps__list">
@foreach($recipe->steps as $step)
</ul>
</div>
<div class="recipe__info-column">
<div class="recipe__info-caption">
ЦЕННОСТЬ:
</div>
<div class="recipe__info-tags">
@foreach ($recipe->tags->unique() as $curTag)
<a href="{{ $curTag->recipe_index_url }}" class="recipe__info-tag">{{ $curTag->name }}</a>
@endforeach
</div>
</div>
</div>
<div class="recipe__footer">
<a href="#commentsList" class="recipe__footer-action icon-message-square">
<span>Комментировать</span>
</a>
@livewire('recipe.like', ['recipe' => $recipe])
{{-- <button class="recipe__footer-action icon-heart"> --}}
{{-- <span>Нравится</span> --}}
{{-- </button> --}}
<button class="recipe__footer-action icon-share">
<span>Поделится</span>
</button>
</div>
</div>
</div>
</section>
<section class="steps">
<div class="steps__container container-sm">
<h2 class="steps__title title">
ПОШАГОВЫЙ ФОТО РЕЦЕПТ - {{ $recipe->title }}
</h2>
<ol class="steps__list">
@foreach ($recipe->steps as $step)
<li class="steps__item">
<div class="steps__item-image">
@if (isset($step['image']) && is_string($step['image']) && strlen($step['image']) > 4)
<img src="/storage/{{ $step['image'] }}" class="cover-image" alt="step">
@endif
</div>
<div class="steps__item-text">
<small>
{!! $step['description'] !!}
</small>
</div>
</li>
@endforeach
<li class="steps__item">
<div class="steps__item-image">
@if(isset($step['image']) && is_string($step['image']) && strlen($step["image"]) > 4)
<img src="/storage/{{ $step['image'] }}" class="cover-image" alt="step">
@endif
</div>
<div class="steps__item-text">
<small>
{!! $step['description'] !!}
</small>
</div>
</li>
@endforeach
{{--<li class="steps__item">
{{-- <li class="steps__item">
<div class="steps__item-image">
<img src="img/price_step_1.jpg" class="cover-image" alt="step">
</div>
@@ -162,115 +187,26 @@
</p>
</div>
</li> --}}
</ol>
</div>
</section>
<section class="reviews">
<div class="reviews__container container-sm">
<h2 class="reviews__title title">
Отзывы
</h2>
<div class="reviews__tabs tabs">
<div class="tablist" role="tablist" aria-labelledby="label">
<button class="tab" role="tab" type="button" id="tab-1" aria-selected="true" aria-controls="tabpanel-1">Положительные 2</button>
<button class="tab" role="tab" type="button" id="tab-2" aria-selected="false" aria-controls="tabpanel-2" tabindex="-1">Негативные 1</button>
</div>
<div class="tabpanel" role="tabpanel" id="tabpanel-1" tabindex="0" aria-labelledby="tab-1">
<div class="reviews__items">
<div class="review">
<div class="review__thumb">
<img src="img/user.png" class="cover-image" alt="user">
</div>
<div class="review__content">
<div class="review__name">
Артём
</div>
<blockquote class="review__quote">
После данного плана питания стал чувствовать себя куда лучше! Обязательно продолжу работать с Дмитрием!
</blockquote>
</div>
<div class="review__info">
<div class="review__programm">
Лёгкий
</div>
<div class="review__rate icon-star">
5.0
</div>
</div>
</div>
<div class="review">
<div class="review__thumb">
<img src="img/user.png" class="cover-image" alt="user">
</div>
<div class="review__content">
<div class="review__name">
Артём
</div>
<blockquote class="review__quote">
После данного плана питания стал чувствовать себя куда лучше! Обязательно продолжу работать с Дмитрием!
</blockquote>
</div>
<div class="review__info">
<div class="review__programm">
Лёгкий
</div>
<div class="review__rate icon-star">
5.0
</div>
</div>
</div>
</div>
</div>
<div class="tabpanel" role="tabpanel" id="tabpanel-2" tabindex="0" aria-labelledby="tab-2">
<div class="reviews__items">
<div class="review">
<div class="review__thumb">
<img src="img/user.png" class="cover-image" alt="user">
</div>
<div class="review__content">
<div class="review__name">
Артём
</div>
<blockquote class="review__quote">
Курить план – это плохо! Гласит лозунг и кричит Минздрав. Ну, конечно …Ничем не хуже водки, а водку везде продают и ничего.. ... Говорят, некоторые годами курят план и живут нормальной жизнью…Ну, если они считают это нормальной жизнью, то пусть и дальше существуют…Я не хочу…Я теперь спрашиваю себя – а зачем мне жить, что б просто курить траву?..Теперь мне плохо и траву курить, Проклятый мир! Даже год не покурил… Мне нужно что-то получше.. почище….ярче!!!
</blockquote>
</div>
<div class="review__info">
<div class="review__programm">
Лёгкий
</div>
<div class="review__rate icon-star">
5.0
</div>
</div>
</div>
</div>
</div>
</div>
<form action="" class="reviews__form">
<textarea class="textarea textarea-white" placeholder="Введите отзыв"></textarea>
<div class="reviews__form-column">
<div class="reviews__form-rate star-rating">
<input type="radio" name="rate" id="rate-5" value="5" class="star-rating__input hidden" hidden>
<label class="star-rating__label" for="rate-5"></label>
<input type="radio" name="rate" id="rate-4" value="4" class="star-rating__input hidden" hidden>
<label class="star-rating__label" for="rate-4"></label>
<input type="radio" name="rate" id="rate-3" value="3" class="star-rating__input hidden" hidden>
<label class="star-rating__label" for="rate-3"></label>
<input type="radio" name="rate" id="rate-2" value="2" class="star-rating__input hidden" hidden>
<label class="star-rating__label" for="rate-2"></label>
<input type="radio" name="rate" id="rate-1" value="1" class="star-rating__input hidden" hidden>
<label class="star-rating__label" for="rate-1"></label>
</div>
<button type="button" class="btn btn-primary">Оставить отзыв</button>
</div>
</form>
</div>
</section>
</ol>
</div>
</section>
<section class="reviews">
<div class="reviews__container">
<h2 class="reviews__title title">
ОТЗЫВЫ
</h2>
@livewire('recipe.comment.show', ['recipe' => $recipe])
@livewire('recipe.comment.create', ['recipe' => $recipe, 'user' => Auth::user()])
</div>
@endsection
@push('jq_scripts')
<script src="/js/bootstrap.min.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
@endpush
</section>
@endsection
{{-- @push('jq_scripts') --}}
{{-- <script src="/js/bootstrap.min.js"></script> --}}
{{-- <script src="/js/bootstrap.bundle.min.js"></script> --}}
{{-- @endpush --}}

View File

@@ -196,3 +196,4 @@ final class CreateTest extends TestCase
self::assertEquals($count, Recipe::count());
}
}

View File

@@ -1,41 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests\Feature\Recipe;
use App\Models\Recipe;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
/**
* @internal
*/
final class EditFormTest extends TestCase
{
use RefreshDatabase;
protected User $user;
private Recipe $recipe;
public function setUp(): void
{
$this->refreshApplicationWithLocale('en');
$this->user = User::factory()->create(['is_consultant' => true]);
$this->recipe = Recipe::inRandomOrder()->first();
}
public function test_edit_page_recipe_success(): void
{
$response = $this
->actingAs($this->user)
->get(route('recipe.edit', $this->recipe, false));
$response->assertSuccessful();
}
}

View File

@@ -0,0 +1,192 @@
<?php declare(strict_types=1);
namespace Tests\Feature\Recipe;
use App\Livewire\Recipe\Edit;
use App\Models\Recipe;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use Livewire\Livewire;
use Tests\TestCase;
/**
* @internal
*/
final class EditTest extends TestCase
{
use RefreshDatabase;
protected User $user;
private Recipe $recipe;
public function setUp(): void
{
$this->refreshApplicationWithLocale('en');
$this->user = User::factory()->create(['is_consultant' => true]);
$this->recipe = Recipe::inRandomOrder()->first();
}
public function test_edit_page_recipe_success(): void
{
$response = $this
->actingAs($this->user)
->get(route('recipe.edit', $this->recipe, false));
$response->assertSuccessful();
}
public function testUpdateRecipePublishSuccess(): void
{
$this->actingAs($this->user);
$recipe = $this->recipe = Recipe::factory()->make();
$recipeUpdate = Livewire::test(Edit::class, [
'recipe' => $this->recipe,
])
->set('title', $recipe->title)
->assertSet('title', $recipe->title)
->set('image', $recipe->image)
->set('state', $recipe->state)
->assertSet('state', $recipe->state)
->set('cooking_time', $recipe->cooking_time)
->assertSet('cooking_time', $recipe->cooking_time)
->set('ingredients', $recipe->ingredients)
->assertSet('ingredients', $recipe->ingredients)
->set('type', $recipe->type)
->assertSet('type', $recipe->type)
->set('description', $recipe->description)
->assertSet('description', $recipe->description)
->set('video_url', $recipe->video_url)
->assertSet('video_url', $recipe->video_url)
->call('publish')
->assertSuccessful()
->assertHasNoErrors(['title', 'image', 'state', 'cooking_time', 'ingredients', 'type', 'description', 'steps', 'video_url']);
Storage::disk('public')->assertExists($this->recipe->image);
// check data after update recipe
self::assertEquals($recipe->title, $recipeUpdate->title);
self::assertEquals($recipe->image, $recipeUpdate->image);
self::assertEquals($recipe->state, $recipeUpdate->state);
self::assertEquals($recipe->cooking_time, $recipeUpdate->cooking_time);
self::assertEquals($recipe->ingredients, $recipeUpdate->ingredients);
self::assertEquals($recipe->type, $recipeUpdate->type);
self::assertEquals($recipe->description, $recipeUpdate->description);
self::assertEquals($recipe->video_url, $recipeUpdate->video_url);
}
public function testUpdateRecipeDraftSuccess(): void
{
$this->actingAs($this->user);
$recipe = $this->recipe = Recipe::factory()->make();
$recipeUpdate = Livewire::test(Edit::class, [
'recipe' => $this->recipe,
])
->set('title', $recipe->title)
->assertSet('title', $recipe->title)
->set('image', $recipe->image)
->set('state', $recipe->state)
->assertSet('state', $recipe->state)
->set('cooking_time', $recipe->cooking_time)
->assertSet('cooking_time', $recipe->cooking_time)
->set('ingredients', $recipe->ingredients)
->assertSet('ingredients', $recipe->ingredients)
->set('type', $recipe->type)
->assertSet('type', $recipe->type)
->set('description', $recipe->description)
->assertSet('description', $recipe->description)
->set('video_url', $recipe->video_url)
->assertSet('video_url', $recipe->video_url)
->call('draft')
->assertSuccessful()
->assertHasNoErrors(['title', 'image', 'state', 'cooking_time', 'ingredients', 'type', 'description', 'steps', 'video_url']);
Storage::disk('public')->assertExists($this->recipe->image);
// check data after update recipe
self::assertEquals($recipe->title, $recipeUpdate->title);
self::assertEquals($recipe->image, $recipeUpdate->image);
self::assertEquals('archived', $recipeUpdate->state);
self::assertEquals($recipe->cooking_time, $recipeUpdate->cooking_time);
self::assertEquals($recipe->ingredients, $recipeUpdate->ingredients);
self::assertEquals($recipe->type, $recipeUpdate->type);
self::assertEquals($recipe->description, $recipeUpdate->description);
self::assertEquals($recipe->video_url, $recipeUpdate->video_url);
}
public function testUpdateRecipePreviewSuccess(): void
{
$this->actingAs($this->user);
$recipe = $this->recipe = Recipe::factory()->make();
$recipeUpdate = Livewire::test(Edit::class, [
'recipe' => $this->recipe,
])
->set('title', $recipe->title)
->assertSet('title', $recipe->title)
->set('image', $recipe->image)
->set('state', $recipe->state)
->assertSet('state', $recipe->state)
->set('cooking_time', $recipe->cooking_time)
->assertSet('cooking_time', $recipe->cooking_time)
->set('ingredients', $recipe->ingredients)
->assertSet('ingredients', $recipe->ingredients)
->set('type', $recipe->type)
->assertSet('type', $recipe->type)
->set('description', $recipe->description)
->assertSet('description', $recipe->description)
->set('video_url', $recipe->video_url)
->assertSet('video_url', $recipe->video_url)
->call('preview')
->assertSuccessful()
->assertHasNoErrors(['title', 'image', 'state', 'cooking_time', 'ingredients', 'type', 'description', 'steps', 'video_url']);
Storage::disk('public')->assertExists($this->recipe->image);
// check data after update recipe
self::assertEquals($recipe->title, $recipeUpdate->title);
self::assertEquals($recipe->image, $recipeUpdate->image);
self::assertEquals('archived', $recipeUpdate->state);
self::assertEquals($recipe->cooking_time, $recipeUpdate->cooking_time);
self::assertEquals($recipe->ingredients, $recipeUpdate->ingredients);
self::assertEquals($recipe->type, $recipeUpdate->type);
self::assertEquals($recipe->description, $recipeUpdate->description);
self::assertEquals($recipe->video_url, $recipeUpdate->video_url);
}
public function testNothingChange(): void
{
$this->actingAs($this->user);
$recipeUpdate = Livewire::test(Edit::class, [
'recipe' => $this->recipe,
])
->call('publish')
->assertSuccessful()
->assertHasNoErrors(['title', 'image', 'state', 'cooking_time', 'ingredients', 'type', 'description', 'steps', 'video_url']);
Storage::disk('public')->assertExists($this->recipe->image);
// check data after update recipe
self::assertEquals($this->recipe->title, $recipeUpdate->title);
self::assertEquals($this->recipe->image, $recipeUpdate->image);
self::assertEquals($this->recipe->state, $recipeUpdate->state);
self::assertEquals($this->recipe->cooking_time, $recipeUpdate->cooking_time);
self::assertEquals($this->recipe->ingredients, $recipeUpdate->ingredients);
self::assertEquals($this->recipe->type, $recipeUpdate->type);
self::assertEquals($this->recipe->description, $recipeUpdate->description);
self::assertEquals($this->recipe->video_url, $recipeUpdate->video_url);
}
}

View File

@@ -33,3 +33,4 @@ class IndexTest extends TestCase
->assertOk();
}
}

View File

@@ -32,3 +32,4 @@ class ShowTest extends TestCase
->assertOk();
}
}