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

Reviewed-on: apoloz/eatvio#2
This commit is contained in:
apoloz
2023-12-15 14:49:30 +00:00
31 changed files with 1247 additions and 1081 deletions

View File

@@ -12,7 +12,7 @@ jobs:
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- run: echo "The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}

View File

@@ -2,3 +2,5 @@
```
The main Eatvio web project
```
see [eatvio-infra](http://gitea.office.local:3000/eatvio/eatvio-infra)

View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
use App\Models\Plan;
use App\Models\User;
use Illuminate\Http\Request;
use App\Models\PlanComment;
class PlanController extends Controller
{
@@ -65,16 +66,16 @@ class PlanController extends Controller
// $options1 = $this->unserializeOptions($plan->packet1_options);
// $options2 = $this->unserializeOptions($plan->packet2_options);
// $options3 = $this->unserializeOptions($plan->packet2_options);
$options1 = $plan->packet1_options;
$options2 = $plan->packet2_options;
$options3 = $plan->packet2_options;
// $options1 = $plan->packet1_options;
// $options2 = $plan->packet2_options;
// $options3 = $plan->packet2_options;
return view('plan/show',
[
'plan' => $plan,
'options1' => $options1,
'options2' => $options2,
'options3' => $options3
// 'options1' => $options1,
// 'options2' => $options2,
// 'options3' => $options3,
]
);
}

View File

@@ -0,0 +1,40 @@
<?php
namespace App\Livewire\Plan;
use App\Models\Plan;
use Livewire\Component;
class Accordion extends Component
{
public Plan $plan;
public $accordionState = ['options1' => false, 'options2' => false, 'options3' => false];
public $options1;
public $options2;
public $options3;
public function mount(Plan $plan): void
{
$this->plan = $plan;
$this->options1 = $plan->packet1_options;
$this->options2 = $plan->packet2_options;
$this->options3 = $plan->packet3_options;
}
public function render()
{
return view('livewire.plan.accordion');
}
public function toggleAccordionState($optionName)
{
$this->accordionState[$optionName] = !$this->accordionState[$optionName];
// 1. Если у нас 1 true все остальные делать false(чтобы закрывать остальные вкладки у которых не true)
// a. у нас есть ключ у которого будет true
// b. проходим по всем ключам accordionState и все кроме true делаем false
array_map(fn($key) => $key === $optionName ?: $this->accordionState[$key] = false, array_keys($this->accordionState));
}
}

View File

@@ -6,6 +6,7 @@ use Livewire\Component;
use App\Models\Plan;
use App\Models\PlanComment;
use App\Models\User;
use Livewire\Attributes\Validate;
class Create extends Component
{
@@ -21,6 +22,11 @@ class Create extends Component
public function save()
{
$this->validate([
'body' => 'required|min:10',
'grade' => 'required',
]);
$comment = new PlanComment();
$comment->grade = $this->grade;
$comment->body = $this->body;

View File

@@ -8,6 +8,7 @@ use App\Models\Plan;
class Show extends Component
{
public Plan $plan;
public array $tabpanelState = ['positive' => 'positive', 'negative' => false];
protected $listeners = ['commentAdded' => '$refresh'];
@@ -15,4 +16,9 @@ class Show extends Component
{
return view('livewire.plan.comment.show');
}
public function toggleTabpanelState($tabpanelName)
{
array_map(fn($key) => $key === $tabpanelName ? $this->tabpanelState[$tabpanelName] = $tabpanelName : $this->tabpanelState[$key] = false, array_keys($this->tabpanelState));
}
}

View File

@@ -24,6 +24,9 @@ class Edit extends Component
public $description = "";
public $steps = [['image' => '', 'description' => '']];
public $ingredients = [['name' => '', 'portion' => '']];
public $ingredients_name = "";
public $ingredients_portion = "";
public $ingredients_unit = "gr";
protected $listeners = ['stepRemoved' => '$refresh', 'parentComponentTagAdded', 'parentComponentTagRemoved'];
@@ -86,9 +89,15 @@ class Edit extends Component
public function removeStep($i)
{
if (is_array($this->steps)) {
$steps = $this->steps;
}
else {
$steps = $this->steps->toArray();
}
$searchKey = $i - 1;
$newSteps = array_filter(
$this->steps,
$steps,
function ($key) use ($searchKey) {
return $key != $searchKey;
},
@@ -141,7 +150,6 @@ class Edit extends Component
public function publish()
{
dd($this->steps);
$this->validate();
$recipe = $this->recipe;

View File

@@ -1,16 +1,17 @@
<?php
namespace App\Models;
use Laracasts\Presenter\PresentableTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Model;
use App\Models\PlanLike;
use App\Presenters\PlanPresenter;
use Illuminate\Database\Eloquent\Casts\Attribute;
use CyrildeWit\EloquentViewable\InteractsWithViews;
use CyrildeWit\EloquentViewable\Contracts\Viewable;
use CyrildeWit\EloquentViewable\InteractsWithViews;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Laracasts\Presenter\PresentableTrait;
class Plan extends Model implements Viewable
{
@@ -18,7 +19,6 @@ class Plan extends Model implements Viewable
use InteractsWithViews;
use PresentableTrait;
protected $withCount = [
'likes',
'comments'
@@ -31,10 +31,8 @@ class Plan extends Model implements Viewable
'packet3_options' => 'array',
];
protected $presenter = PlanPresenter::class;
public function author()
{
return $this->belongsToMany(User::class, 'plan_author', 'plan_id', 'user_id');
@@ -63,12 +61,12 @@ class Plan extends Model implements Viewable
{
$result = [];
for ($i = 1; $i <= $this->packets_count; $i++) {
$key = "packet" . $i . "_options";
$key = 'packet' . $i . '_options';
// $data = $this->unserializeOptionsObj($this->$key);
$data = $this->$key;
if (!is_null($data)) {
$result = array_merge($result, data_get($data, "items", []));
$result = array_merge($result, data_get($data, 'items', []));
}
}
@@ -81,7 +79,7 @@ class Plan extends Model implements Viewable
$data = $this->type;
return new Attribute(
get: fn () => array_keys($data),
get: fn() => array_keys($data),
);
}
@@ -89,18 +87,18 @@ class Plan extends Model implements Viewable
{
$result = 0;
for ($i = 1; $i <= $this->packets_count; $i++) {
$key = "packet" . $i . "_options";
$key = 'packet' . $i . '_options';
// dd($this->$key);
// $data = $this->unserializeOptionsObj($this->$key);
$data = $this->$key;
if (!is_null($data)) {
$curPrice = (int)data_get($data, "price", 0);
$result = $curPrice > $result ? $curPrice : $result ;
$curPrice = (int) data_get($data, 'price', 0);
$result = $curPrice > $result ? $curPrice : $result;
}
}
return new Attribute(
get: fn () => $result,
get: fn() => $result,
);
}
@@ -128,4 +126,14 @@ class Plan extends Model implements Viewable
}
return json_decode(stripslashes($str), true);
}
public function scopeByNegative(Builder $query)
{
return static::comments()->where('grade', '<=', '3');
}
public function scopeByPositive(Builder $query)
{
return static::comments()->where('grade', '>', '3');
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\User;
use App\Models\Plan;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\PlanComment>
*/
class PlanCommentFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'grade' => $this->faker->randomDigit(),
'body' => $this->faker->text(),
];
}
}

View File

@@ -16,6 +16,7 @@ class DatabaseSeeder extends Seeder
{
$this->call(PlanSeeder::class);
$this->call(UserSeeder::class);
$this->call(RecipeSeeder::class);
// \App\Models\User::factory(10)->create();
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Database\Seeders;
use App\Models\Plan;
use App\Models\PlanComment;
use App\Models\User;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class PlanCommentSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
if (User::count() > 0 && Plan::count() > 0) {
$comments = PlanComment::factory()->count(5)->make();
$comments->each(function ($comment) {
$comment->author()->associate(
User::inRandomOrder()
->first()
->id
);
$comment->plan()->associate(
Plan::inRandomOrder()
->first()
->id
);
$comment->saveOrFail();
});
}
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace Database\Seeders;
use Illuminate\Support\Facades\Storage;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Recipe;
use App\Models\RecipeComment;
use App\Models\RecipeAuthor;
use App\Models\User;
use Faker\Factory as FakerFactory;
use DB;
class RecipeSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$faker = FakerFactory::create();
$images = [];
for ($i = 0; $i < 10; $i++) {
$recipe = new Recipe();
$recipe->image = $this->downloadRandomImage();
$recipe->state = 'active';
$recipe->type = $faker->randomElement(['first_meals', 'second_meals', 'salads', 'snacks', 'drinks', 'other']);
$recipe->title = $faker->sentence(5);
$recipe->video_url = $faker->url;
$recipe->cooking_time = $faker->randomElement([10,20,30,60,120,14400]);
$recipe->description = $faker->text(200);
$recipe->steps = [
['image' => $this->downloadRandomImage(), 'description' => $faker->text(100)],
['image' => $this->downloadRandomImage(), 'description' => $faker->text(100)],
['image' => $this->downloadRandomImage(), 'description' => $faker->text(100)]
];
$recipe->ingredients = [
['name' => $faker->word, 'portion' => $faker->numberBetween(1, 20), 'unit' => $faker->randomElement(['teespoon', 'tablespoon', 'ml', 'pcs', 'clove', 'to_taste'])],
['name' => $faker->word, 'portion' => $faker->numberBetween(1, 20), 'unit' => $faker->randomElement(['teespoon', 'tablespoon', 'ml', 'pcs', 'clove', 'to_taste'])],
['name' => $faker->word, 'portion' => $faker->numberBetween(1, 20), 'unit' => $faker->randomElement(['teespoon', 'tablespoon', 'ml', 'pcs', 'clove', 'to_taste'])],
];
$recipe->save();
for ($j = 0; $j < 10; $j++) {
$comment = new RecipeComment();
$comment->user_id = User::inRandomOrder()->first()->id;
$comment->recipe_id = $recipe->id;
$comment->grade = $faker->randomElement([1,2,3,4,5]);
$comment->body = $faker->text(100);
$comment->save();
}
User::inRandomOrder()->first()->author_of_recipe()->attach($recipe->id);
}
}
public function downloadRandomImage(): string
{
$faker = FakerFactory::create();
$url = $faker->imageUrl(640, 480, 'food', true);
$contents = file_get_contents($url);
$dir_path = storage_path('app/public/recipe');
$path = 'recipe/' . uniqid() . '.jpg';
if (!file_exists( $dir_path)) {
mkdir( $dir_path, 0777, true);
}
file_put_contents(storage_path('app/public/' . $path), $contents);
return $path;
}
}

View File

@@ -1,4 +1,7 @@
<x-guest-layout>
@push('css_head')
<script src="https://cdn.tailwindcss.com"></script>
@endpush
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />

View File

@@ -1,4 +1,7 @@
<x-guest-layout>
@push('css_head')
<script src="https://cdn.tailwindcss.com"></script>
@endpush
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />

View File

@@ -1,4 +1,8 @@
<x-guest-layout>
@push('css_head')
<script src="https://cdn.tailwindcss.com"></script>
@endpush
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />

View File

@@ -1,4 +1,7 @@
<x-guest-layout>
@push('css_head')
<script src="https://cdn.tailwindcss.com"></script>
@endpush
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />

View File

@@ -1,4 +1,7 @@
<x-guest-layout>
@push('css_head')
<script src="https://cdn.tailwindcss.com"></script>
@endpush
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />

View File

@@ -1,4 +1,7 @@
<x-guest-layout>
@push('css_head')
<script src="https://cdn.tailwindcss.com"></script>
@endpush
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />

View File

@@ -1,4 +1,7 @@
<x-guest-layout>
@push('css_head')
<script src="https://cdn.tailwindcss.com"></script>
@endpush
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />

View File

@@ -145,3 +145,4 @@ $isDiary = Str::of($curUrl)->test('/\/diary/');
<x-toaster-hub />
</body>
</html>

View File

@@ -16,6 +16,7 @@
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
<script src="{{ mix('js/app.js') }}" defer></script>
@stack('css_head')
<!-- Styles -->
@livewireStyles
</head>

View File

@@ -0,0 +1,99 @@
<div class="settings__price" data-spollers data-one-spoller>
<div class="settings__price-item">
<button type="button" @class([
'settings__price-btn',
'_active' => $accordionState['options1'],
]) wire:click='toggleAccordionState("options1","options2", "options3")' data-spoller>
<strong>
{{ $options1['price'] ?? '0' }} ₽
</strong>
{{ $options1['short'] ?? '' }}
</button>
<div class="settings__price-body" @style(['display: none' => !$accordionState['options1'], 'display: block' => $accordionState['options1']])>
<div class="settings__price-desc">
{{ $options1['description'] ?? '' }}
</div>
@isset($options1['items'])
@foreach ($options1['items'] as $item)
<ul class="settings__price-list">
<li>
{{ $item }}
<span class="settings__price-icon icon-check-square"></span>
{{-- <span class="settings__price-icon">-</span> --}}
</li>
</ul>
@endforeach
@endisset
<button type="button" class="settings__price-bid btn btn-green">Заказать за
{{ $options1['price'] ?? '0' }}₽</button>
</div>
</div>
@if ($plan->packets_count == 3)
<div class="settings__price-item">
<button type="button" @class([
'settings__price-btn',
'_active' => $accordionState['options2'],
]) wire:click='toggleAccordionState("options2")' data-spoller>
<strong>
{{ $options2['price'] ?? '0' }} ₽
</strong>
{{ $options2['short'] ?? '' }}
</button>
<div class="settings__price-body" @style(['display: none' => !$accordionState['options2'], 'display: block' => $accordionState['options2']])>
<div class="settings__price-desc">
{{ $options2['description'] ?? '' }}
</div>
@isset($options2['items'])
@foreach ($options2['items'] as $item)
<ul class="settings__price-list">
<li>
{{ $item }}
<span class="settings__price-icon icon-check-square"></span>
{{-- <span class="settings__price-icon">-</span> --}}
</li>
</ul>
@endforeach
@endisset
<button type="button" class="settings__price-bid btn btn-green">Заказать за
{{ $options2['price'] ?? '0' }}
₽</button>
</div>
</div>
<div class="settings__price-item">
<button type="button" @class([
'settings__price-btn',
'_active' => $accordionState['options3'],
]) wire:click='toggleAccordionState("options3")'
data-spoller>
<strong>
{{ $options3['price'] ?? '0' }} ₽
</strong>
{{ $options3['short'] ?? '' }}
</button>
<div class="settings__price-body" @style(['display: none' => !$accordionState['options3'], 'display: block' => $accordionState['options3']])>
<div class="settings__price-desc">
{{ $options3['description'] ?? '' }}
</div>
@isset($options3['items'])
@foreach ($options3['items'] as $item)
<ul class="settings__price-list">
<li>
{{ $item }}
<span class="settings__price-icon icon-check-square"></span>
{{-- <span class="settings__price-icon">-</span> --}}
</li>
</ul>
@endforeach
@endisset
<button type="button" class="settings__price-bid btn btn-green">Заказать за
{{ $options3['price'] ?? '0' }}
₽</button>
</div>
</div>
@endif
</div>

View File

@@ -1,24 +1,18 @@
<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>
<a href="#sg1" wire:click.prevent="save" class="ms-3"><svg width="24" height="24"><use xlink:href="#SendPlainIcon"></use></svg></a>
<form class="reviews__form">
<textarea wire:model="body" class="textarea textarea-white" placeholder="Введите отзыв"></textarea>
<div class="reviews__form-column">
<div class="reviews__form-rate star-rating">
<input wire:click="$set('grade', 5)" 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 wire:click="$set('grade',4)" 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 wire:click="$set('grade',3)" 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 wire:click="$set('grade',2)" 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 wire:click="$set('grade',1)" 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 wire:click.prevent="save" type="button" class="btn btn-primary">Оставь отзыв</button>
</div>
</div>
</form>

View File

@@ -1,59 +1,89 @@
<div class="container px-0 mb-4 --mw-1000 reviews">
@php
$positivComments = $plan->comments()->where('grade', '>', '3');
$negativeComments = $plan->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 = $plan->byPositive();
$negativeComments = $plan->byNegative();
$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__programm">
{{ $plan->name }}
</div>
<div class="review__rate icon-star">
{{ $comment->grade }}
</div>
{{-- @livewire('plan.comment.upvote', ['comment' => $comment]) --}}
</div>
@livewire('plan.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-1" 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__programm">
{{ $plan->name }}
</div>
<div class="review__rate icon-star">
{{ $comment->grade }}
</div>
{{-- @livewire('plan.comment.upvote', ['comment' => $comment]) --}}
</div>
@livewire('plan.comment.upvote', ['comment' => $comment])
</div>
</div>
@endforeach
</div>
</div>
</div>

View File

@@ -373,8 +373,6 @@
</div>
</div>
</form>
<div class="diet__services">
<div class="diet__services-caption">
<div class="diet__services-title title">
@@ -652,8 +650,8 @@
@endisset
<div class="row">
<div class="col-12 col-md-10 mb-3">
<input class="input" wire:model="input_items_3" type="text"
class="form-control py-3 w-100"
<input class="input" wire:model="input_items_3"
type="text" class="form-control py-3 w-100"
placeholder="Содержание услуги" required=""></input>
</div>
<div class="col-12 col-md-2 mb-3">
@@ -689,20 +687,7 @@
class="diet__btn btn btn-primary">Опубликовать</button>
</div>
</div>
@endif
<div class="container p-0 --mw-1000">
<div class="row gx-3 gx-lg-4 gy-3 gy-lg-4">
<div class="col">
<a wire:click="addToDrafts" href="#" class="btn btn-lg btn-secondary btn-block w-100 --f_bolder --no_wrap">В ЧЕРНОВИК</a>
</div>
<div class="col">
<a wire:click="showPreview" href="#" class="btn btn-lg btn-secondary btn-block w-100 --f_bolder --no_wrap">ПРЕВЬЮ</a>
</div>
<div class="col">
<button wire:click.prevent="publish" class="btn btn-lg btn-primary btn-block w-100 --f_bolder --no_wrap" type="submit">ОПУБЛИКОВАТЬ</button>
</div>
</div>
</div>
</section>

View File

@@ -25,180 +25,141 @@
</div>
<div class="diet__form-row">
<div class="diet__form-columns lg-columns">
<div class="diet__form-columns lg-columns">
<div class="diet__form-column">
<div class="label">{{ __('recipe.picture') }}</div>
<label class="file">
<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">
<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">
</span>
<span class="file__title">
@if(is_null($image))
Нажмите для&nbsp;выбора или&nbsp;перетащите изображание
@endif
</span>
</span>
</span>
</label>
@error('image') <span class="error">{{ $message }}</span> @enderror
</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 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 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>
<div class="tabpanel" 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>
<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>
<div class="tabpanel" 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>
@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="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 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>
@endif
@foreach($ingredients as $k => $ingredient)
<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>
<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>
@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>
@endforeach
</div>
{{-- <div class="tabpanel" role="tabpanel" id="tabpanel-1" tabindex="0" aria-labelledby="tab-1">
<div class="diet__form-column">
<div class="diet__form-row">
<div class="label">
Время приготавления
</div>
<div class="dropdown">
<button type="button" class="dropdown__button">
1 час
</button>
<ul class="dropdown__list">
<li data-value="1" class="dropdown__list-item active">1 час</li>
<li data-value="30" class="dropdown__list-item">30 минут</li>
</ul>
<input type="text" name="time" class="dropdown__input hidden" hidden="" value="1">
</div>
</div>
</div>
<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 class="diet__form-column diet__form-column-xl">
<div class="diet__form-columns">
<div class="diet__form-column diet__form-column-lg">
<input type="text" name="product" class="input" placeholder="Введите название продукта">
</div>
<div class="diet__form-column">
<div class="diet__form-adding">
<div class="diet__form-column">
<input type="num" name="ccal" class="input" placeholder="Порция">
<button 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" role="tabpanel" id="tabpanel-2" tabindex="0" aria-labelledby="tab-2">
<div class="diet__form-column">
<div class="diet__form-row">
@@ -219,194 +180,94 @@
</div>
</div>
</div>
</div>
</div>
<div class="diet__form">
<div class="row fs-4_5">
<div class="col-12 col-sm-12 col-xl-4 my-4 dnd_file">
<label for="form-image">{{ __('recipe.picture') }}</label>
<div class="form__item mt-3 p-3 --radius --bordered text-center --f_grey">
<input wire:model="image" type="file" name="form-image" id="form-image">
@error('image') <span class="error">{{ $message }}</span> @enderror
<label for="form-image" class="file-label">
@if(is_null($image))
<p><svg width="88" height="88"><use xlink:href="#dndFileIcon"></use></svg></p>
<div class="px-3">{{ __('recipe.tap_to_select_or_drag_and_drop') }}</div>
<div id="file-name"></div>
@else
<p>
<img src="{{ is_string($image) ? Storage::url($image) : $image->temporaryUrl() }}" />
</p>
@endif
</label>
<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>
</div>
<div class="col-12 col-sm-7 col-md-8 my-4 d-flex flex-column justify-content-between">
<div class="mb-4">
<label>{{ __('recipe.record_type') }}</label>
<ul class="mt-3 nav nav-pills flex-nowrap w-100 --bordered --radius --tabs_blue overflow-x-xs-scroll" role="radiogroup">
<li class="nav-item" role="presentation">
<label class="btn btn-lg nav-link py-3 --radius active">{{ __('recipe.self') }}</label>
</li>
<li class="nav-item" role="presentation">
<a href="{{ route('blog_post.create') }}" class="btn btn-lg nav-link py-3">{{ __('recipe.blog_post') }}</a>
</li>
</ul>
</div>
<div class="row">
<div class="col-12 col-sm-6 d-flex flex-column --reciept">
<label>{{ __('recipe.cooking_time') }}</label>
<select wire:model="cooking_time" class="form-select mt-3 ps-4 pe-5 py-3 --f_bold">
<option value="10" selected>{{ __('recipe.t10m') }}</option>
<option value="20" selected>{{ __('recipe.t20m') }}</option>
<option value="30" selected>{{ __('recipe.t30m') }}</option>
<option value="60">{{ __('recipe.t60m') }}</option>
<option value="120">{{ __('recipe.t120m') }}</option>
<option value="14400">{{ __('recipe.t14400m') }}</option>
</select>
@php
$stepsCount = count($steps);
@endphp
@for($i = 0; $i < $stepsCount; $i++)
<div class="diet__form-row">
<div class="label">
{{ __('recipe.step') }} {{ $i + 1 }}
<span>
{{ __('recipe.total_steps') }}: {{ $stepsCount }}
</span>
</div>
<div class="col-12 col-sm-6 d-flex flex-column mt-3 mt-sm-0">
<label>{{ __('recipe.record_state') }}</label>
<select wire:model="state" class="form-select mt-3 ps-4 pe-5 py-3 --f_bold">
<option value="active">{{ __('recipe.record_state_active') }}</option>
<option value="archived">{{ __('recipe.record_state_not_active') }}</option>
</select>
</div>
</div>
</div>
</div>
<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)
<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="">
</div>
<div class="d-flex w-md-80 align-items-baseline">
<div class="flex-grow-1 ms-sm-3 mt-3 mt-sm-0">
<input wire:model="ingredients.{{ $k }}.portion" class="form-control fs-4_5 py-3" placeholder="Порция" required="" type="number">
</div>
<div class="ms-4 me-2 mt-3 mt-sm-0">
<select name="unit" wire:model="ingredients.{{ $k }}.unit" class="form-select ps-4 pe-5 py-3 --f_bold">
<option value="gr">{{ __('recipe.gr') }}</option>
<option value="teespoon">{{ __('recipe.teespoon') }}</option>
<option value="tablespoon">{{ __('recipe.tablespoon') }}</option>
<option value="ml">{{ __('recipe.ml') }}</option>
<option value="pcs">{{ __('recipe.pcs') }}</option>
<option value="clove">{{ __('recipe.clove') }}</option>
<option value="to_taste">{{ __('recipe.to_taste') }}</option>
</select>
</div>
<div class="flex-grow-1 ms-sm-3 mt-3 mt-sm-0">
<button wire:click="removeIngredient({{$k}})" type="button" class="btn btn-outline-danger">x</button>
</div>
</div>
</div>
@endforeach
<div class="d-flex justify-content-end mt-2" data-row="0">
<button type="button" wire:click="addIngredient" class="btn btn-lg btn-primary btn-block py-4 fs-2 lh-0 --radius">+</button>
</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.debounce.9999999ms="description">{!! $description !!}</div>
</div>
@php
$stepsCount = count($steps);
@endphp
@for($i = 0; $i < $stepsCount; $i++)
<div class="mb-4 fs-4_5 --reciept">
<div class="d-flex justify-content-between mb-2">
<div>{{ __('recipe.step') }} {{ $i + 1 }}</div>
@if($i == 0)
<div>{{ __('recipe.total_steps') }}: {{ $stepsCount }}</div>
@endif
</div>
<div class="row flex-md-nowrap">
<div class="col-12 col-sm-3 mb-3 mb-sm-0 pe-2 dnd_file">
<label class="form__item w-100 p-3 --radius --bordered text-center --f_grey --upload_image" style="background:url()">
@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]">
@error('steps.'. $i . '.image') <span class="error">{{ $message }}</span> @enderror
@if (!isset($steps[$i]['image']))
<div class="my-3">
<svg width="50" height="50">
<use xlink:href="#dndFileIcon"></use>
</svg>
</div>
@endif
<div class="diet__form-step">
<label class="file">
<span class="file__content">
@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
@if (!isset($steps[$i]['image']))
<div class="my-3">
<svg width="50" height="50">
<use xlink:href="#dndFileIcon"></use>
</svg>
</div>
@endif
</span>
</label>
</div>
<div class="col-sm-7 col-lg-8 mb-3 mb-sm-0 px-sm-2 flex-grow-1">
<div class="d-flex align-items-center form-control --textarea py-3 w-100 h-100" onclick="this.children[0].focus()">
<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>
</div>
</div>
<div class="col d-flex flex-sm-column ps-sm-2 justify-content-between">
<button type="button" wire:click="removeStep({{$i}})" class="btn btn-lg {{ $i == 0 ? "btn-secondary" : "btn-primary" }} btn-block w-100 me-3 me-sm-0 py-4 fs-2 lh-0 --radius" @disabled($i == 0)>-</button>
<button type="button" wire:click="addStep" class="btn btn-lg btn-primary btn-block w-100 py-4 fs-2 lh-0 --radius" data-bs-toggle="tooltip" data-bs-placement="left" title="" data-bs-original-title="Добавить шаг">+</button>
</div>
</div>
@endfor
<div class="diet__form-row">
<div class="label" data-tags="{{ json_encode($tags) }}">
{{ __('recipe.tags') }}
</div>
<livewire:tags-component :parentComponent="$recipe" />
</div>
@endfor
<div class="mb-4 fs-4_5">
<div class="mb-2" data-tags="{{ json_encode($tags) }}">{{ __('recipe.tags') }}</div>
<livewire:tags-component :parentComponent="$recipe" />
</div>
<div class="mb-4 fs-4_5">
<div class="mb-2">{{ __('recipe.video_link') }}</div>
<input wire:model="video_url" type="text" class="form-control fs-4_5 py-3 w-100" placeholder="Прикрипите ссылку на YouTube видео" />
</div>
</div>
</div>
<div class="container mb-5 p-0 --mw-1000">
<div class="row gx-3 gx-lg-4 gy-3 gy-lg-4">
<div class="col">
<button wire:click="draft" class="btn btn-lg btn-secondary btn-block w-100 --f_bolder --no_wrap">{{ __('recipe.to_drafts') }}</button>
</div>
<div class="col">
<button wire:click="preview" class="btn btn-lg btn-secondary btn-block w-100 --f_bolder --no_wrap">{{ __('recipe.preview') }}</button>
</div>
<div class="col">
<button wire:click="publish" class="btn btn-lg btn-primary btn-block w-100 --f_bolder --no_wrap" type="submit">{{ __('recipe.publish') }}</button>
<div class="diet__form-row">
<div class="label">
{{ __('recipe.video_link') }}
</div>
<input wire:model="video_url" type="text" class="input" placeholder="Прикрепите ссылку на YouTube видео">
</div>
</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>
</div>
<div class="container mb-5 p-0 --mw-1000">
@foreach ($errors->all() as $message)
<div class="alert alert-warning">{{ $message }}</div>

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>
{{ $isIconOnly ? "Нравится" : "" }}
<svg width="24" height="21" class="me-1"><use xlink:href="#HeartPath"></use></svg>
{{ $isIconOnly ? "Нравится" : "" }}
</button>

View File

@@ -1,102 +1,146 @@
<section class="py-5" id="main">
<div class="container d-block d-sm-flex justify-content-between align-items-end align-items-lg-center mb-4 p-0 --mw-1000" wire:key="search">
<div class="d-block d-lg-flex align-items-center col-12 col-sm-9 me-lg-2 mb-1 mb-sm-0 p-0 pe-sm-2">
<div class="h4 me-md-3 mb-3 mb-lg-0 --f_grey text-uppercase">Популярные блюда</div>
<div class="d-flex align-items-center -search flex-grow-1">
<span class="btn --search_icon">
<svg width="20" height="20">
<use xlink:href="#SearchIcon"></use>
</svg>
</span>
<input class="form-control" name="search" wire:model.live.debounce.500ms="search" type="search" placeholder="Поиск рецепта" />
<main class="page">
<section class="content">
<div class="content__container">
<div class="content__header">
<div class="content__header-title title">
ПОПУЛЯРНЫЕ БЛЮДА
</div>
<form action="#" class="content__header-search search">
<div class="search__box">
<button class="search__btn icon-search"></button>
<input type="text" name="search" class="search__input search__input-white" placeholder="Поиск записи">
</div>
<button class="search__send btn btn-primary btn-sm">найти рецепт</button>
</form>
</div>
</div>
<div class="col-12 col-sm px-0 flex-grow-1">
<button type="submit" class="btn btn-lg btn-primary btn-block w-100 ps-4 pe-sm-4 --f_bold text-uppercase --no_wrap --radius">Найти рецепт</button>
</div>
</div>
<div id="recordsList" class="container p-0 --mw-1000" wire:key="recipe-result">
<div class="row justify-content-between flex-lg-nowrap">
<div class="col-12 col-lg-9 me-lg-2 mb-4 mb-lg-0 p-0 pe-lg-2" >
<div class="row gx-3">
<div class="content__body">
<div class="content__main">
<div class="content__grid">
@foreach($recipes as $recipe)
<div class="col-md-6 mb-3">
<div class="h-100 --bg_white --shadow --radius --no_wrap overflow-hidden">
<div class="post_img position-relative">
<a href="{{ route("recipe.show", $recipe) }}"><img src="{{ Storage::url($recipe->image) }}" class="w-100" /></a>
@if(Str::length($recipe->video_url) > 1)
<a href="{{ $recipe->video_url }}">
<div class="post_v_l --top_r --round_icon">
<svg width="18" height="14">
<use xlink:href="#YouTubeIcon"></use>
</svg>
</div>
</a>
@endif
</div>
<div class="mt-2 px-3 py-2">
<div class="d-flex justify-content-between align-items-center mb-3">
<div class="d-flex align-items-center --f_bold">
<svg width="22" height="22" class="me-1">
<use xlink:href="#KdjIcon"></use>
</svg>
139.9 ккал
</div>
<div class="d-flex align-items-center --f_bold">
<svg width="22" height="22" class="me-1">
<use xlink:href="#TimeBlack"></use>
</svg>
{{ $recipe->cooking_time }}
</div>
<div class="d-flex align-items-center --f_bold">
<svg width="22" height="26" class="me-1">
<use xlink:href="#Footprints"></use>
</svg>
{{ $recipe->steps->count() }} этапов
</div>
</div>
<div class="mb-2 f-4_5 --f_bold --no_wrap_normal">{{ $recipe->title }}</div>
<small class="d-block --no_wrap_normal">{!! $recipe->description !!}</small>
<div class="mt-1 text-center --pointer">
<svg width="14" height="8" class="--sblue">
<use xlink:href="#ArrBottomBlue"></use>
</svg>
</div>
</div>
<div class="dish">
<div class="dish__image">
@php
$image = $recipe->image
@endphp
<a href="{{ route('recipe.show', $recipe) }}">
@if(is_null($image))
<img src="/img/formats-2.svg" alt="formats">
@else
<img src="{{ is_string($image) ? Storage::url($image) : $image->temporaryUrl() }}" class="cover-image" alt="recipe"/>
@endif
</a>
<a href="{{ $recipe->video_url }}" class="dish__video icon-youtube"></a>
</div>
<div class="dish__stats">
<div class="dish__stat icon-pie">
139.9 ккал
</div>
<div class="dish__stat icon-clock">
{{ __('recipe.t' . $recipe->cooking_time . 'm') }}
</div>
<div class="dish__stat icon-foots">
{{ __('recipe.total_steps') }}: {{ $recipe->steps->count() }}
</div>
</div>
@endforeach
</div>
{{ $recipes->links() }}
</div>
@php
$colorClasses = [
'btn-primary',
'btn-green',
'btn-yellow',
'btn-red',
'btn-rose',
'btn-seaweed',
'btn-purple'
];
<div class="dish__desc" data-spollers>
<div class="dish__desc-caption">
{{ $recipe->title }}
</div>
<div class="dish__desc-visible">
{{ substr(strip_tags($recipe->description), 0, 200); }}
</div>
<button type="button" data-spoller class="dish__desc-btn icon-down"></button>
<div class="dish__desc-more">
$colorsMaxIndex = count($colorClasses) - 1;
$i = 0;
@endphp
<div class="col-12 col-lg px-0 flex-grow-1 text-lg-end">
@if(!is_null($rawTypes))
@foreach($rawTypes as $keyType => $type)
<div class="--tags mb-3">
<div class="mb-2 --f_bold"> {{ __('recipe.' . $keyType) }} </div>
@foreach($type as $tagName => $tagsCount)
<a href="?tag={{ $tagName }}" data-idx="{{ $i . ":" . $colorsMaxIndex }}" style="font-weight: {{$tagsCount * 200}};" class="btn {{ $colorClasses[$i] }} btn-sm border-0 --radius">{{ Str::of($tagName)->split('/-/')[1] }} <sup>{{ $tagsCount }}</sup></a>
@php $i = ($colorsMaxIndex > $i) ? $i+1 : 0; @endphp
@endforeach
</div>
</div>
</div>
@endforeach
@endif
</div>
</div>
</div>
</section>
</div>
</div>
<aside class="content__side content__side-sm">
<div class="content__recipes">
<div class="content__recipes-caption">Рецепты первых блюд</div>
<div class="content__recipes-items">
<a href="#" class="content__recipe content__recipe-blue">Кулеш</a>
<a href="#" class="content__recipe content__recipe-blue">Лагман</a>
<a href="#" class="content__recipe content__recipe-blue">Борщи</a>
<a href="#" class="content__recipe content__recipe-blue">Ботвинья</a>
<a href="#" class="content__recipe content__recipe-blue">Капустняк</a>
<a href="#" class="content__recipe content__recipe-blue">Бульоны</a>
</div>
</div>
<div class="content__recipes">
<div class="content__recipes-caption">Рецепты вторых блюд</div>
<div class="content__recipes-items">
<a href="#" class="content__recipe content__recipe-green">Кулеш</a>
<a href="#" class="content__recipe content__recipe-green">Лагман</a>
<a href="#" class="content__recipe content__recipe-green">Борщи</a>
<a href="#" class="content__recipe content__recipe-green">Ботвинья</a>
<a href="#" class="content__recipe content__recipe-green">Капустняк</a>
<a href="#" class="content__recipe content__recipe-green">Бульоны</a>
</div>
</div>
<div class="content__recipes">
<div class="content__recipes-caption">Рецепты заготовок</div>
<div class="content__recipes-items">
<a href="#" class="content__recipe content__recipe-yellow">Кулеш</a>
<a href="#" class="content__recipe content__recipe-yellow">Лагман</a>
<a href="#" class="content__recipe content__recipe-yellow">Борщи</a>
<a href="#" class="content__recipe content__recipe-yellow">Ботвинья</a>
<a href="#" class="content__recipe content__recipe-yellow">Капустняк</a>
<a href="#" class="content__recipe content__recipe-yellow">Бульоны</a>
</div>
</div>
<div class="content__recipes">
<div class="content__recipes-caption">Рецепты закусок</div>
<div class="content__recipes-items">
<a href="#" class="content__recipe content__recipe-orange">Кулеш</a>
<a href="#" class="content__recipe content__recipe-orange">Лагман</a>
<a href="#" class="content__recipe content__recipe-orange">Борщи</a>
<a href="#" class="content__recipe content__recipe-orange">Ботвинья</a>
<a href="#" class="content__recipe content__recipe-orange">Капустняк</a>
<a href="#" class="content__recipe content__recipe-orange">Бульоны</a>
</div>
</div>
<div class="content__recipes">
<div class="content__recipes-caption">Рецепты изделий из теста</div>
<div class="content__recipes-items">
<a href="#" class="content__recipe content__recipe-rose">Кулеш</a>
<a href="#" class="content__recipe content__recipe-rose">Лагман</a>
<a href="#" class="content__recipe content__recipe-rose">Борщи</a>
<a href="#" class="content__recipe content__recipe-rose">Ботвинья</a>
<a href="#" class="content__recipe content__recipe-rose">Капустняк</a>
<a href="#" class="content__recipe content__recipe-rose">Бульоны</a>
</div>
</div>
<div class="content__recipes">
<div class="content__recipes-caption">Рецепты маринада</div>
<div class="content__recipes-items">
<a href="#" class="content__recipe content__recipe-seaweed">Кулеш</a>
<a href="#" class="content__recipe content__recipe-seaweed">Лагман</a>
<a href="#" class="content__recipe content__recipe-seaweed">Борщи</a>
<a href="#" class="content__recipe content__recipe-seaweed">Ботвинья</a>
<a href="#" class="content__recipe content__recipe-seaweed">Капустняк</a>
<a href="#" class="content__recipe content__recipe-seaweed">Бульоны</a>
</div>
</div>
<div class="content__recipes">
<div class="content__recipes-caption">Рецепты напитков</div>
<div class="content__recipes-items">
<a href="#" class="content__recipe content__recipe-purple">Кулеш</a>
<a href="#" class="content__recipe content__recipe-purple">Лагман</a>
<a href="#" class="content__recipe content__recipe-purple">Борщи</a>
<a href="#" class="content__recipe content__recipe-purple">Ботвинья</a>
<a href="#" class="content__recipe content__recipe-purple">Капустняк</a>
<a href="#" class="content__recipe content__recipe-purple">Бульоны</a>
</div>
</div>
</aside>
</div>
</div>
</section>
</main>
</section>

View File

@@ -6,151 +6,121 @@
$authorPhoto = $plan->present()->getAuthorPhoto;
$image = Storage::url($plan->image);
$planViewsCount = views($plan)->unique()->count();
$planViewsCount = views($plan)
->unique()
->count();
@endphp
@section('main_section')
<section class="py-5" id="main">
<div class="container d-flex justify-content-between align-items-center mb-4 ps-4 pe-3 py-3 --bg_white --shadow --radius --mw-1000">
<a href="{{ route('plan.index', ['author' => $author->id]) }}" class="d-flex align-items-center --f_bold --f_main"><svg width="17" height="16" class="me-2"><use xlink:href="#GoBack"></use></svg><span class="d-none d-md-inline">Планы питания консультанта</span></a>
<div class="d-flex align-items-center">
<div class="d-none d-md-flex me-3 align-items-center">
<a href={{ route("profile.show", ['user' => $author]) }} class="me-2 text-nowrap --f_bold --f_main">
<span class="me-2 text-nowrap --f_bold">{{ $author->name }}</span>
<img src="{{ $authorPhoto }}" width="42px" height="42px" class="--radius_100" style="height: 42px;">
<section class="page" id="main">
<section class="settings">
<div class="settings__container container-sm">
<div class="settings__header">
<a href="" class="settings__back icon-arrow-short-left">
<span>Планы питания консультанта</span>
</a>
</div>
<a href="#" class="btn btn-lg btn-primary btn-block w-100 ps-4 pe-sm-4 --f_bold" target="_blank" style="max-width: 180px;">
<svg width="20" height="20" class="me-3"><use xlink:href="#WhiteChat"></use></svg>НАПИСАТЬ</a>
</div>
</div>
<div class="container mb-5 --mw-1000">
<div class="row justify-content-between flex-lg-nowrap">
<div class="col-lg-7 me-lg-4 mb-4 mb-lg-0 px-3 pt-3 pb-4 --bg_white --shadow --radius">
<div class="d-flex justify-content-between align-items-center mb-2 --f_bold">
<div class="h5 mb-0 --f_bold">{{ $plan->name }}</div>
<div class="d-flex align-items-center">
<svg width="20" height="14" class="me-2"><use xlink:href="#Eye_Black"></use></svg><span class="me-3 fs-5">{{ $planViewsCount }}</span>
<svg width="16" height="14" class="me-2"><use xlink:href="#Heart_Black"></use></svg>@livewire('plan.like-count', ['plan' => $plan])
<svg width="14" height="14" class="me-2"><use xlink:href="#CommentIcon"></use></svg><span class="me-3 fs-5">{{ $plan->comments_count }}</span>
</div>
</div>
<img src="{{ $image }}" class="w-100">
<div class="d-md-flex justify-content-between align-items-center my-3 px-3 py-1 bg_lightest_blue --radius">
<table class="table table-sm-block --no_border me-5 mb-0 fs-4_5"><tbody>
<tr>
<td class="text-start ps-0 p-1">Время прохождения плана:</td>
<td class="text-start p-1 --f_bold">{{ $plan->duration }} дней</td>
</tr>
<tr>
<td class="text-start ps-0 p-1">Проходят план:</td>
<td class="text-start p-1 --f_bold">2 пользователя</td>
</tr>
</tbody></table>
{{-- <a href="#" class="d-none d-md-inline"><svg width="24" height="21" class="me-1"><use xlink:href="#HeartPath"></use></svg></a> --}}
</div>
<div class="fs-4_5">{!! $plan->details !!}</div>
<div class="d-flex mt-4 align-items-center justify-content-between --f_bold">
<a href="#plan-comment-textarea" class="d-flex align-items-center --f_main"><small>
<svg width="21" height="20" class="me-1"><use xlink:href="#ActionComment"></use></svg>
Комментировать
</small></a>
@livewire('plan.like', ['plan' => $plan])
<a href="#" class="d-flex align-items-center --f_main"><small>
<svg width="21" height="22" class="me-1"><use xlink:href="#Share"></use></svg>
<span class="d-none d-sm-inline">Поделится</span>
</small></a>
</div>
</div>
<div class="col px-0 flex-grow-1">
<div class="accordion" id="collapsedPlans">
<div class="accordion-item mb-3 --bg_white --shadow --radius overflow-hidden">
<div class="accordion-header" id="headingOne">
<div class="accordion-button d-flex align-items-center fs-4" type="button" data-bs-toggle="collapse" data-bs-target="#collapsedPlan1" aria-expanded="true" aria-controls="collapsedPlan1">
<div class="me-3 --f_bold">{{ $options1['price'] ?? '0' }} ₽</div>
<div>{{ $options1['short'] ?? ''}}</div>
</div>
</div>
<div id="collapsedPlan1" class="accordion-collapse collapse show" aria-labelledby="collapsedPlan1" data-bs-parent="#collapsedPlans">
<div class="accordion-body fs-4_5">
<p>{{ $options1['description'] ?? '' }}</p>
@isset($options1['items'])
<ul class="checks -reverse --sber">
@foreach($options1['items'] as $item)
<li>{{ $item }}</li>
@endforeach
</ul>
@endisset
<a href="#" class="btn btn-lg btn-success btn-block w-100 py-2 fs-4 --f_bolder">Заказать за {{ $options1['price'] ?? '0' }} ₽</a>
</div>
</div>
</div>
@if($plan->packets_count == 3)
<div class="accordion-item mb-3 --bg_white --shadow --radius overflow-hidden">
<div class="accordion-header" id="headingOne">
<div class="accordion-button collapsed d-flex align-items-center fs-4" type="button" data-bs-toggle="collapse" data-bs-target="#collapsedPlan2" aria-expanded="true" aria-controls="collapsedPlan2">
<div class="me-3 --f_bold">{{ $options2['price'] ?? '0' }} ₽</div>
<div>{{ $options2['short'] ?? '' }}</div>
</div>
</div>
<div id="collapsedPlan2" class="accordion-collapse collapse" aria-labelledby="collapsedPlan2" data-bs-parent="#collapsedPlans">
<div class="accordion-body fs-4_5">
<p>{{ $options2['description'] ?? '' }}</p>
@isset($options2['items'])
<ul class="checks -reverse --sber">
@foreach($options2['items'] as $item)
<li>{{ $item }}</li>
@endforeach
</ul>
@endisset
<a href="#" class="btn btn-lg btn-success btn-block w-100 py-2 fs-4 --f_bolder">Заказать за {{ $options2['price'] ?? '0' }} ₽</a>
</div>
</div>
</div>
<div class="accordion-item --bg_white --shadow --radius overflow-hidden">
<div class="accordion-header" id="headingOne">
<div class="accordion-button collapsed d-flex align-items-center fs-4" type="button" data-bs-toggle="collapse" data-bs-target="#collapsedPlan3" aria-expanded="true" aria-controls="collapsedPlan3">
<div class="me-3 --f_bold">{{ $options3['price'] ?? '0' }} ₽</div>
<div>{{ $options3['short'] ?? '' }}</div>
</div>
</div>
<div id="collapsedPlan3" class="accordion-collapse collapse" aria-labelledby="collapsedPlan3" data-bs-parent="#collapsedPlans">
<div class="accordion-body fs-4_5">
<p>{{ $options3['description'] ?? '' }}</p>
@isset($options3['items'])
<ul class="checks -reverse --sber">
@foreach($options3['items'] as $item)
<li>{{ $item }}</li>
@endforeach
</ul>
@endisset
<a href="#" class="btn btn-lg btn-success btn-block w-100 py-2 fs-4 --f_bolder">Заказать за {{ $options3['price'] ?? '0' }} ₽</a>
</div>
</div>
</div>
@endif
</div>
</div>
</div>
</div>
<div class="settings__actions">
<div class="settings__action setting__person">
<div class="settings__person-content">
<a href="{{ route('profile.show', ['user' => $author]) }}" class="setting__person-name">
{{ $author->name }}
</a>
</div>
<a href="" class="settings__person-thumb">
<img src="{{ $authorPhoto }}" alt="thumb">
</a>
</div>
<a href="" class="settings__action btn btn-md btn-primary icon-message-square">
<span>Написать</span>
</a>
</div>
</div>
<div class="container px-0 mb-4 --mw-1000">
<div class="h4 mb-4 --f_grey">ОТЗЫВЫ</div>
</div>
@livewire('plan.comment.show', ['plan' => $plan])
@livewire('plan.comment.create', ['plan' => $plan, 'user' => Auth::user()])
</section>
<div class="settings__plans">
<div class="settings__plans-body">
<div class="settings__plans-announcement announcement">
<div class="announcement__header">
<div class="announcement__header-title title">
{{ $plan->name }}
</div>
<div class="announcement__header-stats">
<div class="announcement__header-stat icon-eye-fill">{{ $planViewsCount }}</div>
<div class="announcement__header-stat icon-heart-fill">@livewire('plan.like-count', ['plan' => $plan])</div>
<div class="announcement__header-stat icon-message-square">{{ $plan->comments_count }}
</div>
</div>
</div>
<div class="announcement__image">
<img src="{{ $image }}" class="cover-image" alt="announcement">
</div>
<div class="announcement__details">
<div class="announcement__details-rows">
<div class="announcement__details-row">
<div class="announcement__details-caption">
Время прохождения плана:
</div>
<div class="announcement__details-value">
{{ $plan->duration }} дней
</div>
</div>
<div class="announcement__details-row">
<div class="announcement__details-caption">
Проходят план:
</div>
<div class="announcement__details-value">
2 пользователя
</div>
</div>
</div>
<button type="button" class="announcement__details-btn icon-heart"></button>
</div>
<p class="announcement__desc">
{{ $plan->details }}
</p>
{{-- @livewire('plan.like', ['plan' => $plan]) --}}
<div class="announcement__footer">
<button type="button"
class="announcement__footer-action icon-message-square">Комментировать</button>
<button type="button" class="announcement__footer-action icon-heart">Нравится</button>
<button type="button" class="announcement__footer-action icon-share">Поделится</button>
</div>
</div>
</div>
@livewire('plan.accordion', ['plan' => $plan])
</div>
</div>
</section>
<section class="reviews">
<div class="reviews__container">
<h2 class="reviews__title title">
ОТЗЫВЫ
</h2>
@livewire('plan.comment.show', ['plan' => $plan])
@livewire('plan.comment.create', ['plan' => $plan, 'user' => Auth::user()])
</div>
</section>
</section>
@endsection
@push('jq_scripts')
<script src="/js/bootstrap.min.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
{{-- <script src="js/app.min.js"></script> --}}
<script src="/js/bootstrap.min.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
@endpush

View File

@@ -1,432 +1,276 @@
@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">
<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>
{{--
<li>Калории: 139.9 ккал</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/{{ $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>
{{--
<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">
ПОШАГОВЫЙ ФОТО РЕЦЕПТ - КУРИНЫЕ РУЛЕТИКИ С СЫРОМ
</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">
<div class="steps__item-image">
<img src="img/price_step_1.jpg" class="cover-image" alt="step">
</div>
<div class="steps__item-text">
Режем куриную грудку тонкими ломтиками.
</div>
</li>
<li class="steps__item">
<div class="steps__item-image">
<img src="img/price_step_2.jpg" class="cover-image" alt="step">
</div>
<div class="steps__item-text">
<p>
{{--<li class="steps__item">
<div class="steps__item-image">
<img src="img/price_step_1.jpg" class="cover-image" alt="step">
</div>
<div class="steps__item-text">
Режем куриную грудку тонкими ломтиками.
</div>
</li>
<li class="steps__item">
<div class="steps__item-image">
<img src="img/price_step_2.jpg" class="cover-image" alt="step">
</div>
<div class="steps__item-text">
<p>
На край каждого кусочка филе кладем 1 ст. л. тертого сыра и порезанную зелень.
</p>
<p>
</p>
<p>
Формируем рулетик из куриного филе с сыром и зеленью, подворачивая с боков, чтобы сыр при приготовлении не вытек. Скрепляем края половинками зубочисток.
</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">
</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 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 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>
</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>
<section class="py-5" id="main">
<div class="container d-flex justify-content-between align-items-center flex-nowrap mb-4 px-4 py-3 --bg_white --shadow --radius --mw-1000 --f_bold --f_main overflow-x-xs-scroll">
<a href="{{ route('recipe.index') }}" class="d-flex w-2/5 align-items-center --f_bold">
<svg width="17" height="16" class="me-2">
<use xlink:href="#GoBack"></use>
</svg>
<span class="d-none d-md-inline --f_main">Рецепты</span>
</a>
<div class="d-flex align-items-center fs-6">
<svg width="20" height="14" class="me-2">
<use xlink:href="#Eye_Black"></use>
</svg>
<span class="me-4">{{ $recipeViewsCount }}</span>
<svg width="16" height="14" class="me-2">
<use xlink:href="#Heart_Black"></use>
</svg>
<span class="me-4">@livewire('recipe.like-count', ['recipe' => $recipe])</span>
<svg width="14" height="14" class="me-2">
<use xlink:href="#Comment_Black"></use>
</svg>
<span>{{ $recipe->comments_count }}</span>
</div>
<div class="d-none d-md-flex w-2/5 ps-3 justify-content-end align-items-center">
<span class="me-2 text-end">{{ $author['name'] }}</span>
<img src="/storage/{{ $author->profile_photo_path }}" width="42px" height="42px" class="--radius_100">
</div>
</div>
<div class="container mb-5 p-0 --mw-1000">
<div class="--bg_white --shadow --radius --no_wrap">
<div class="row m-0 p-3 position-relative">
<div class="col-12 col-md-5 mb-2 mb-md-0 ps-0 pe-0 pe-md-3">
<img src="/storage/{{ $recipe->image }}" class="w-full --radius">
</div>
<div class="col-12 col-md-7 pe-0 d-flex flex-column justify-content-between">
<div>
<div class="mb-3 fs-18 --f_bold --no_wrap_normal">{{ $recipe->title }}</div>
<div class="d-flex align-items-center fs-6 --f_bolder">
<svg width="22" height="22" class="me-2">
<use xlink:href="#TimeBlack"></use>
</svg><span class="me-4">{{ __('recipe.t' . $recipe->cooking_time . "m") }}</span>
<svg width="22" height="26" class="me-2">
<use xlink:href="#Footprints"></use>
</svg><span>{{ $recipe->steps->count() }} этапов</span>
</div>
<div class="mt-3 lh-sm --no_wrap_normal">
<small>
{!! $recipe->description !!}
</small>
</div>
</div>
<div class="mt-3 fs-14 --f_bolder">
@if (strlen(trim($recipe->video_url)) > 4)
<a href="{{ $recipe->video_url }}" class="d-inline-flex align-items-center" target="_blank">
<span class="--f_main">Посмотреть рецепт на YouTube</span>
<svg width="18" height="14" class="ms-2">
<use xlink:href="#YouTubeIcon"></use>
</svg>
</a>
@endif
</div>
</div>
<ul class="navbar-nav --abs --dotted --r w-auto mt-2 me-2 mt-md-3 me-md-3 p-0" style="--bs-scroll-height:100px;">
<li class="nav-item dropdown">
<a id="dLabel" class="nav-link py-0 dropdown-toggle-js" href="#" data-bs-toggle="dropdown" aria-expanded="false" role="button">
<svg width="18" height="4">
<use xlink:href="#Dots"></use>
</svg>
</a>
<ul class="dropdown-menu" aria-labelledby="navbarScrollingDropdown">
<li><a class="dropdown-item" href="{{ route('recipe.edit', $recipe->id) }}">Edit</a></li>
<li><a class="dropdown-item" href="#">Другое действие</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="#">Что-то еще</a></li>
</ul>
</li>
</ul>
</div>
<div class="row m-0 mt-2 p-3 bg_lightest_blue-v2">
<div class="col-12 col-md-5 fs-14">
<div class="h6 mb-2 mb-md-3 --f_bold --f_grey text-uppercase">продукты:</div>
<ul class="m-0 ps-4 list-disc">
@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="col-12 col-md-3 mt-3 mt-md-0 fs-14">
<div class="h6 mb-2 mb-md-3 --f_bold --f_grey text-uppercase">Теги:</div>
<div class="fs-6 --tags --m_large --no_wrap_normal">
@foreach($recipe->tags->unique() as $curTag)
<a href="{{ $curTag->recipe_index_url }}" class="btn badge --radius --bg-blue --f_bold --f_main">{{ $curTag->name }}</a>
@endforeach
</div>
</div>
</div>
<div class="d-flex p-4 align-items-center justify-content-between justify-content-sm-center --f_bold">
<a href="#commentsList" class="d-flex align-items-center me-4 me-sm-5 --f_main">
<small>
<svg width="21" height="20" class="me-1">
<use xlink:href="#ActionComment"></use>
</svg>
Комментировать
</small>
</a>
@livewire('recipe.like', ['recipe' => $recipe])
<a href="#" class="d-flex align-items-center --f_main">
<small>
<svg width="21" height="22" class="me-1">
<use xlink:href="#Share"></use>
</svg>
<span class="d-none d-sm-inline">Поделится</span>
</small>
</a>
</div>
</div>
</div>
<div class="container px-0 mb-5 --mw-1000">
<div class="h4 --f_grey text-uppercase">Пошаговый фото рецепт - {{ $recipe->title }}</div>
<div class="--step_boxes">
@foreach($recipe->steps as $step)
<div class="row align-items-center m-0 my-3 p-3 --bg_white --shadow --radius --step_box">
<div class="col-12 col-md-5 mb-2 mb-md-0 ps-0 pe-0 pe-md-3">
@if(isset($step['image']) && is_string($step['image']) && strlen($step["image"]) > 4)
<img src="/storage/{{ $step['image'] }}" class="w-100 --radius">
@endif
</div>
<div class="col-12 col-md-7 ps-0 ps-md-3 pe-0 d-flex flex-column justify-content-between">
<small>
{!! $step['description'] !!}
</small>
</div>
</div>
@endforeach
</div>
</div>
<div id="commentsList" class="container p-0 --mw-1000">
@livewire('recipe.comment.show', ['recipe' => $recipe])
</div>
<div class="container px-0 mb-4 --mw-1000 --bg_white --radius fs-4_5">
@livewire('recipe.comment.create', ['recipe' => $recipe, 'user' => Auth::user()])
</div>
</section>
@endsection
@push('jq_scripts')
<script src="/js/bootstrap.min.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
@endpush
@endsection
@push('jq_scripts')
<script src="/js/bootstrap.min.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
@endpush

View File

@@ -0,0 +1,105 @@
<?php
namespace Tests\Feature\Plan;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use App\Models\Recipe;
use App\Models\User;
use App\Livewire\Recipe\Edit;
use Tests\TestCase;
use Faker\Generator as Faker;
class RecipeEditTest extends TestCase
{
use RefreshDatabase;
public function can_update_recipe()
{
Storage::fake('public');
$faker = Factory::create('ru_RU');
$user = User::factory()->create();
$recipe = Recipe::factory()->create([
'steps' => [],
'ingredients' => [],
]);
$tag1 = Tag::factory()->create();
$tag2 = Tag::factory()->create();
$title = $faker->sentence(3);
$description = $faker->paragraph(2);
$cooking_time = $faker->numberBetween(10, 120);
$type = $faker->randomElement(['Main Dish', 'Dessert', 'Appetizer']);
$video_url = $faker->url;
$image = UploadedFile::fake()->image('new_image.jpg');
$ingredients_names = [$faker->word, $faker->word, $faker->word];
$ingredients_portions = [$faker->numberBetween(1, 500), $faker->numberBetween(1, 500), $faker->numberBetween(1, 500)];
$ingredient_units = [$faker->randomElement(['gr', 'ml', 'pcs']), $faker->randomElement(['gr', 'ml', 'pcs']), $faker->randomElement(['gr', 'ml', 'pcs'])];
Livewire::actingAs($user)
->test('recipe.edit', ['recipe' => $recipe])
->set('title', $title)
->set('description', $description)
->set('cooking_time', $cooking_time)
->set('type', $type)
->set('video_url', $video_url)
->set('image', $image)
->set('tags', [$tag1->id, $tag2->id])
->call('addIngredient')
->set('ingredients_name.0', $ingredients_names[0])
->set('ingredients_portion.0', $ingredients_portions[0])
->set('ingredients_unit.0', $ingredient_units[0])
->call('addIngredient')
->set('ingredients_name.1', $ingredients_names[1])
->set('ingredients_portion.1', $ingredients_portions[1])
->set('ingredients_unit.1', $ingredient_units[1])
->call('addIngredient')
->set('ingredients_name.2', $ingredients_names[2])
->set('ingredients_portion.2', $ingredients_portions[2])
->set('ingredients_unit.2', $ingredient_units[2])
->call('addStep')
->set('steps.0.description', $faker->paragraph)
->set('steps.0.image', UploadedFile::fake()->image('new_step_image0.jpg'))
->call('addStep')
->set('steps.1.description', $faker->paragraph)
->set('steps.1.image', UploadedFile::fake()->image('new_step_image1.jpg'))
->call('addStep')
->set('steps.2.description', $faker->paragraph)
->set('steps.2.image', UploadedFile::fake()->image('new_step_image2.jpg'))
->call('publish');
$this->assertDatabaseHas('recipes', [
'title' => $title,
'description' => $description,
'cooking_time' => $cooking_time,
'type' => $type,
'video_url' => $video_url,
'image' => $image,
'ingredients_name.0' => $ingredients_names[0],
'ingredients_portion.0' => $ingredients_portions[0],
'ingredients_unit.0' => $ingredient_units[0],
'ingredients_name.1' => $ingredients_names[1],
'ingredients_portion.1' => $ingredients_portions[1],
'ingredients_unit.1' => $ingredient_units[1],
'ingredients_name.2' => $ingredients_names[2],
'ingredients_portion.2' => $ingredients_portions[2],
'ingredients_unit.2' => $ingredient_units[2],
]);
$this->assertDatabaseHas('tags', [
'id' => $tag1->id,
]);
$this->assertDatabaseHas('tags', [
'id' => $tag2->id,
]);
Storage::disk('public')->assertExists('recipes/new_image.jpg');
Storage::disk('public')->assertExists('steps/new_step_image0.jpg');
Storage::disk('public')->assertExists('steps/new_step_image1.jpg');
Storage::disk('public')->assertExists('steps/new_step_image2.jpg');
}
}