forked from eatvio/eatvio-infra
Merge pull request 'main' (#2) from eatvio/eatvio:main into main
Reviewed-on: apoloz/eatvio#2
This commit is contained in:
@@ -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 }}
|
||||
|
||||
@@ -2,3 +2,5 @@
|
||||
```
|
||||
The main Eatvio web project
|
||||
```
|
||||
|
||||
see [eatvio-infra](http://gitea.office.local:3000/eatvio/eatvio-infra)
|
||||
|
||||
@@ -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,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
40
app/Livewire/Plan/Accordion.php
Normal file
40
app/Livewire/Plan/Accordion.php
Normal 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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
28
database/factories/PlanCommentFactory.php
Executable file
28
database/factories/PlanCommentFactory.php
Executable 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(),
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
38
database/seeders/PlanCommentSeeder.php
Executable file
38
database/seeders/PlanCommentSeeder.php
Executable 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();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
72
database/seeders/RecipeSeeder.php
Normal file
72
database/seeders/RecipeSeeder.php
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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 />
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -145,3 +145,4 @@ $isDiary = Str::of($curUrl)->test('/\/diary/');
|
||||
<x-toaster-hub />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
99
resources/views/livewire/plan/accordion.blade.php
Normal file
99
resources/views/livewire/plan/accordion.blade.php
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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))
|
||||
Нажмите для выбора или перетащите изображание
|
||||
@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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
105
tests/Feature/Recipe/EditTest.php
Normal file
105
tests/Feature/Recipe/EditTest.php
Normal 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');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user