forked from eatvio/eatvio-infra
Merge branch 'main' of ssh://gitea.office.local:222/alex_chevski/eatvio into alex_chevski-main
This commit is contained in:
@@ -15,7 +15,6 @@ class PlanController extends Controller
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
/* dd($request->get('author')); */
|
||||
if ($request->has('author')) {
|
||||
$author = $request->get('author');
|
||||
$user = User::find($author);
|
||||
|
||||
@@ -21,9 +21,10 @@ class Accordion extends Component
|
||||
{
|
||||
$this->plan = $plan;
|
||||
// dd($this->unserializeOptions($plan->packet3_options));
|
||||
$this->options1 = $this->unserializeOptions($plan->packet1_options);
|
||||
$this->options2 = $this->unserializeOptions($plan->packet2_options);
|
||||
$this->options3 = $this->unserializeOptions($plan->packet3_options);
|
||||
|
||||
$this->options1 = $plan->packet1_options;
|
||||
$this->options2 = $plan->packet2_options;
|
||||
$this->options3 = $plan->packet3_options;
|
||||
}
|
||||
|
||||
public function render()
|
||||
|
||||
@@ -26,7 +26,7 @@ class Create extends Component
|
||||
|
||||
public function toggle()
|
||||
{
|
||||
$this->isChecked = ! $this->isChecked;
|
||||
$this->isChecked = !$this->isChecked;
|
||||
}
|
||||
|
||||
public function save()
|
||||
@@ -39,10 +39,12 @@ class Create extends Component
|
||||
$comment = new PlanComment();
|
||||
$comment->grade = $this->grade;
|
||||
$comment->body = $this->body;
|
||||
|
||||
$comment->plan_id = $this->plan->id;
|
||||
$comment->user_id = $this->user->id;
|
||||
$comment->save();
|
||||
$this->reset(['body']);
|
||||
|
||||
$this->reset(['grade', 'body']);
|
||||
|
||||
$this->toggle();
|
||||
|
||||
|
||||
@@ -12,17 +12,12 @@ class Create extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public $name = '';
|
||||
|
||||
public $name = "";
|
||||
public $image = null;
|
||||
|
||||
public $duration = '7';
|
||||
|
||||
public $state = 'draft';
|
||||
|
||||
public $type = [];
|
||||
|
||||
public $details = '';
|
||||
public $duration = "7";
|
||||
public $state = "draft";
|
||||
public $type = ['fit' => false, 'slim' => false, 'behavior' => false, 'wellness' => false];
|
||||
public $details = "";
|
||||
|
||||
public $packets_count = 1;
|
||||
|
||||
@@ -48,6 +43,36 @@ class Create extends Component
|
||||
|
||||
public $isVisibleState = false;
|
||||
|
||||
protected function rules()
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|min:3',
|
||||
'image' => 'required|image|max:2048',
|
||||
'duration' => 'required|numeric|min:7',
|
||||
'state' => 'required|in:draft,active,unactive',
|
||||
'type' => ['required', 'array:slim,fit,wellness,behavior', 'min:1'],
|
||||
'details' => 'required|min:3',
|
||||
'packets_count' => 'required|in:1,3',
|
||||
'packet1_options.short' => 'required|string|min:3',
|
||||
'packet1_options.price' => 'required|numeric|min:1',
|
||||
'packet1_options.description' => 'required|string|min:3',
|
||||
'packet1_options.items' => 'required|array|min:1',
|
||||
];
|
||||
|
||||
if($this->packets_count === 3) {
|
||||
$rules['packet2_options.short'] = 'required|string|min:3';
|
||||
$rules['packet2_options.price'] = 'required|numeric|min:1';
|
||||
$rules['packet2_options.description'] = 'required|string|min:3';
|
||||
$rules['packet2_options.items'] = 'required|array|min:1';
|
||||
$rules['packet3_options.short'] = 'required|string|min:3';
|
||||
$rules['packet3_options.price'] = 'required|numeric|min:1';
|
||||
$rules['packet3_options.description'] = 'required|string|min:3';
|
||||
$rules['packet3_options.items'] = 'required|array|min:1';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.plan.create');
|
||||
@@ -103,15 +128,18 @@ class Create extends Component
|
||||
$plan->state = $this->state;
|
||||
$plan->details = $this->details;
|
||||
$plan->packets_count = $this->packets_count;
|
||||
$plan->type = json_encode($this->type);
|
||||
$plan->packet1_options = json_encode($this->packet1_options);
|
||||
$plan->packet2_options = json_encode($this->packet2_options);
|
||||
$plan->packet3_options = json_encode($this->packet3_options);
|
||||
$plan->type = $this->type;
|
||||
$plan->packet1_options = $this->packet1_options;
|
||||
$plan->packet2_options = $this->packet2_options;
|
||||
$plan->packet3_options = $this->packet3_options;
|
||||
|
||||
$plan->saveOrFail();
|
||||
|
||||
|
||||
$user = Auth::user();
|
||||
$user->author_of_plans()->attach($plan->id);
|
||||
|
||||
return redirect()->route('plan.show', $plan->id);
|
||||
return redirect()->route('plan.show', $plan->slug);
|
||||
}
|
||||
|
||||
public function addToDrafts()
|
||||
@@ -125,34 +153,4 @@ class Create extends Component
|
||||
$this->state = 'unactive';
|
||||
$this->publish();
|
||||
}
|
||||
|
||||
protected function rules()
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|min:3',
|
||||
'image' => 'required|image|max:2048',
|
||||
'duration' => 'required|numeric|min:7',
|
||||
'state' => 'required|in:draft,active,inactive',
|
||||
'type' => ['required', 'array:slim,fit,wellness,behavior', 'min:1'],
|
||||
'details' => 'required|min:3',
|
||||
'packets_count' => 'required|in:1,3',
|
||||
'packet1_options.short' => 'required|string|min:3',
|
||||
'packet1_options.price' => 'required|numeric|min:1',
|
||||
'packet1_options.description' => 'required|string|min:3',
|
||||
'packet1_options.items' => 'required|array|min:1',
|
||||
];
|
||||
|
||||
if ($this->packets_count === 3) {
|
||||
$rules['packet2_options.short'] = 'required|string|min:3';
|
||||
$rules['packet2_options.price'] = 'required|numeric|min:1';
|
||||
$rules['packet2_options.description'] = 'required|string|min:3';
|
||||
$rules['packet2_options.items'] = 'required|array|min:1';
|
||||
$rules['packet3_options.short'] = 'required|string|min:3';
|
||||
$rules['packet3_options.price'] = 'required|numeric|min:1';
|
||||
$rules['packet3_options.description'] = 'required|string|min:3';
|
||||
$rules['packet3_options.items'] = 'required|array|min:1';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
|
||||
190
app/Livewire/Plan/Edit.php
Normal file
190
app/Livewire/Plan/Edit.php
Normal file
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Plan;
|
||||
|
||||
use App\Models\Plan;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
|
||||
class Edit extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public Plan $plan;
|
||||
public $name = '';
|
||||
public $image = null;
|
||||
public $duration = '7';
|
||||
public $state = 'draft';
|
||||
public $type = ['fit' => false, 'slim' => false, 'behavior' => false, 'wellness' => false];
|
||||
public $details = '';
|
||||
public $packets_count = 1;
|
||||
public $packet1_options = [];
|
||||
public $packet2_options = [];
|
||||
public $packet3_options = [];
|
||||
public $packet1_options_input = [];
|
||||
public $packet2_options_input = [];
|
||||
public $packet3_options_input = [];
|
||||
public $input_items_1 = '';
|
||||
public $input_items_2 = '';
|
||||
public $input_items_3 = '';
|
||||
public $isVisibleDuration = false;
|
||||
public $isVisibleState = false;
|
||||
|
||||
public function mount(Plan $plan)
|
||||
{
|
||||
$this->plan = $plan;
|
||||
|
||||
$this->name = $plan->name;
|
||||
$this->image = $plan->image;
|
||||
$this->duration = $plan->duration;
|
||||
$this->state = $plan->state;
|
||||
$this->type = $plan->type;
|
||||
$this->details = $plan->details;
|
||||
$this->packets_count = $plan->packets_count;
|
||||
|
||||
$this->packet1_options_input['short'] = $plan->packet1_options['short'];
|
||||
$this->packet1_options_input['price'] = $plan->packet1_options['price'];
|
||||
$this->packet1_options_input['description'] = $plan->packet1_options['description'];
|
||||
// $this->input_items_1 = $plan->packet1_options['items'];
|
||||
|
||||
$this->packet1_options['short'] = $plan->packet1_options['short'];
|
||||
$this->packet1_options['price'] = $plan->packet1_options['price'];
|
||||
$this->packet1_options['description'] = $plan->packet1_options['description'];
|
||||
$this->packet1_options['items'] = $plan->packet1_options['items'];
|
||||
|
||||
if ($plan->packets_count === 3) {
|
||||
|
||||
$this->packet2_options_input['short'] = $plan->packet2_options['short'];
|
||||
$this->packet2_options_input['price'] = $plan->packet2_options['price'];
|
||||
$this->packet2_options_input['description'] = $plan->packet2_options['description'];
|
||||
// $this->input_items_2 = $plan->packet1_options['items'];
|
||||
|
||||
$this->packet2_options['short'] = $plan->packet2_options['short'];
|
||||
$this->packet2_options['price'] = $plan->packet2_options['price'];
|
||||
$this->packet2_options['description'] = $plan->packet2_options['description'];
|
||||
$this->packet2_options['items'] = $plan->packet2_options['items'];
|
||||
|
||||
$this->packet3_options_input['short'] = $plan->packet2_options['short'];
|
||||
$this->packet3_options_input['price'] = $plan->packet2_options['price'];
|
||||
$this->packet3_options_input['description'] = $plan->packet2_options['description'];
|
||||
// $this->input_items_3 = $plan->packet1_options['items'];
|
||||
|
||||
$this->packet3_options['short'] = $plan->packet2_options['short'];
|
||||
$this->packet3_options['price'] = $plan->packet2_options['price'];
|
||||
$this->packet3_options['description'] = $plan->packet2_options['description'];
|
||||
$this->packet3_options['items'] = $plan->packet3_options['items'];
|
||||
}
|
||||
|
||||
// likes_count
|
||||
// commentsCount
|
||||
}
|
||||
|
||||
protected function rules()
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|min:3',
|
||||
// 'image' => 'image|max:2048',
|
||||
'duration' => 'required|numeric|min:7',
|
||||
'state' => 'required|in:draft,active,unactive',
|
||||
'type' => ['required', 'array:slim,fit,wellness,behavior', 'min:1'],
|
||||
'details' => 'required|min:3',
|
||||
'packets_count' => 'required|in:1,3',
|
||||
'packet1_options.short' => 'required|string|min:3',
|
||||
'packet1_options.price' => 'required|numeric|min:1',
|
||||
'packet1_options.description' => 'required|string|min:3',
|
||||
'packet1_options.items' => 'required|array|min:1',
|
||||
];
|
||||
|
||||
if ($this->packets_count === 3) {
|
||||
$rules['packet2_options.short'] = 'required|string|min:3';
|
||||
$rules['packet2_options.price'] = 'required|numeric|min:1';
|
||||
$rules['packet2_options.description'] = 'required|string|min:3';
|
||||
$rules['packet2_options.items'] = 'required|array|min:1';
|
||||
$rules['packet3_options.short'] = 'required|string|min:3';
|
||||
$rules['packet3_options.price'] = 'required|numeric|min:1';
|
||||
$rules['packet3_options.description'] = 'required|string|min:3';
|
||||
$rules['packet3_options.items'] = 'required|array|min:1';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function showListDuration()
|
||||
{
|
||||
$this->isVisibleDuration = !$this->isVisibleDuration;
|
||||
}
|
||||
|
||||
public function showListState()
|
||||
{
|
||||
$this->isVisibleState = !$this->isVisibleState;
|
||||
}
|
||||
|
||||
public function toggleDuration($duration)
|
||||
{
|
||||
$this->duration = $duration;
|
||||
$this->isVisibleDuration = false;
|
||||
}
|
||||
|
||||
public function toggleState($state)
|
||||
{
|
||||
$this->state = $state;
|
||||
$this->isVisibleState = false;
|
||||
}
|
||||
|
||||
public function addPacketOption($options_type, $options_type_input)
|
||||
{
|
||||
$this->$options_type['short'] = $this->$options_type_input['short'];
|
||||
$this->$options_type['price'] = $this->$options_type_input['price'];
|
||||
$this->$options_type['description'] = $this->$options_type_input['description'];
|
||||
|
||||
$this->$options_type['items'][] = $this->input_items_1;
|
||||
$this->$options_type['items'][] = $this->input_items_2;
|
||||
$this->$options_type['items'][] = $this->input_items_3;
|
||||
|
||||
// delete empty value in items
|
||||
$this->$options_type['items'] = array_filter($this->$options_type['items'], fn($item) => !empty($item));
|
||||
$this->reset('input_items_1');
|
||||
$this->reset('input_items_2');
|
||||
$this->reset('input_items_3');
|
||||
}
|
||||
|
||||
public function publish()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$this->plan->name = $this->name;
|
||||
$this->plan->image = !is_string($this->image) ? $this->image->store('plans', 'public') : $this->image;
|
||||
$this->plan->duration = $this->duration;
|
||||
$this->plan->state = $this->state;
|
||||
$this->plan->details = $this->details;
|
||||
$this->plan->packets_count = $this->packets_count;
|
||||
$this->plan->type = $this->type;
|
||||
$this->plan->packet1_options = $this->packet1_options;
|
||||
$this->plan->packet2_options = $this->packet2_options;
|
||||
$this->plan->packet3_options = $this->packet3_options;
|
||||
|
||||
$this->plan->update();
|
||||
|
||||
// $user = Auth::user();
|
||||
// $user->author_of_plans()->attach($plan->id);
|
||||
|
||||
return redirect()->route('plan.show', $this->plan->slug);
|
||||
}
|
||||
|
||||
public function addToDrafts()
|
||||
{
|
||||
$this->state = 'draft';
|
||||
$this->publish();
|
||||
}
|
||||
|
||||
public function showPreview()
|
||||
{
|
||||
$this->state = 'unactive';
|
||||
$this->publish();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.plan.edit');
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,37 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Laracasts\Presenter\PresentableTrait;
|
||||
use Spatie\Sluggable\HasSlug;
|
||||
use Spatie\Sluggable\SlugOptions;
|
||||
|
||||
class Plan extends Model implements Viewable
|
||||
{
|
||||
use HasFactory;
|
||||
use HasSlug;
|
||||
use InteractsWithViews;
|
||||
use PresentableTrait;
|
||||
|
||||
public function getSlugOptions(): SlugOptions
|
||||
{
|
||||
return SlugOptions::create()
|
||||
->generateSlugsFrom(['name'] )
|
||||
->saveSlugsTo('slug')
|
||||
// ->slugsShouldBeNoLongerThan(20)
|
||||
->usingSeparator('_');
|
||||
// ->usingLanguage('ru')
|
||||
// ->doNotGenerateSlugsOnUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the route key for the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteKeyName()
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
|
||||
protected $withCount = [
|
||||
'likes',
|
||||
'comments',
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"pusher/pusher-php-server": "^7.2",
|
||||
"sentry/sentry-laravel": "^3.7",
|
||||
"spatie/laravel-query-builder": "^5.0",
|
||||
"spatie/laravel-sluggable": "^3.5",
|
||||
"wire-elements/modal": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
1044
composer.lock
generated
1044
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,8 @@ class PlanFactory extends Factory
|
||||
'wellness' => $this->faker->boolean(),
|
||||
];
|
||||
|
||||
$wrongTypeBody = json_encode($typeBody);
|
||||
|
||||
$packetsOptions = [
|
||||
'items' => [$this->faker->fruitName(), $this->faker->meatName(), $this->faker->sauceName()],
|
||||
'price' => $this->faker->randomNumber(),
|
||||
@@ -45,8 +47,9 @@ class PlanFactory extends Factory
|
||||
'name' => $this->faker->foodName(),
|
||||
// 'image' => UploadedFile::fake()->image('plans/Photo_C.png'),
|
||||
'image' => $fileLocalPath,
|
||||
'duration' => $this->faker->randomElement([7, 14, 21]),
|
||||
'state' => $this->faker->randomElement(['active', 'draft', 'archived']),
|
||||
'duration' => $this->faker->randomElement([7, 14,21]),
|
||||
'state' => $this->faker->randomElement(['active', 'draft', 'unactive']),
|
||||
//'type' => $this->faker->randomElement([$typeBody, $wrongTypeBody]),
|
||||
'type' => $typeBody,
|
||||
'details' => $this->faker->text(),
|
||||
'packets_count' => $this->faker->randomElement([1, 3]),
|
||||
|
||||
28
database/migrations/2023_12_20_105039_add_slug_to_plan.php
Normal file
28
database/migrations/2023_12_20_105039_add_slug_to_plan.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('plans', function (Blueprint $table) {
|
||||
$table->string('slug');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('plans', function (Blueprint $table) {
|
||||
$table->dropColumn('slug');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -15,6 +15,8 @@ class DatabaseSeeder extends Seeder
|
||||
{
|
||||
$this->call(PlanSeeder::class);
|
||||
$this->call(UserSeeder::class);
|
||||
$this->call(PlanAuthor::class);
|
||||
$this->call(PlanCommentSeeder::class);
|
||||
// $this->call(RecipeSeeder::class);
|
||||
// \App\Models\User::factory(10)->create();
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
<input @class(['star-rating__input', 'hidden' => $isChecked]) wire:model="isChecked" wire:click="$set('grade',1)" type="radio"
|
||||
name="rate" id="rate-1" value="1" hidden>
|
||||
<label class="star-rating__label" for="rate-1"></label>
|
||||
<input wire:model="isChecked" wire:click="$set('grade',0)" type="radio" name="rate" id="rate-0" value="1" hidden>
|
||||
</div>
|
||||
<button wire:click="save" type="button" class="btn btn-primary">Оставь отзыв</button>
|
||||
<button wire:click.prevent="save" type="button" class="btn btn-primary">Оставь отзыв</button>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="container px-0 mb-4 --mw-1000 reviews">
|
||||
<div class="">
|
||||
@php
|
||||
$positivComments = $plan->byPositive();
|
||||
|
||||
|
||||
493
resources/views/livewire/plan/edit.blade.php
Normal file
493
resources/views/livewire/plan/edit.blade.php
Normal file
@@ -0,0 +1,493 @@
|
||||
<section class="diet" id="main">
|
||||
<div class="diet__container">
|
||||
<div class="diet__header">
|
||||
<button class="diet__back icon-arrow-short-left">
|
||||
<span>Мои планы</span>
|
||||
</button>
|
||||
<h1 class="diet__title">
|
||||
Мои планы
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="diet__form">
|
||||
<div class="diet__form-row">
|
||||
<div class="label">
|
||||
Название
|
||||
</div>
|
||||
<input wire:model="name" type="text" name="name" class="input" value="{{ $name }}"
|
||||
placeholder="Введите название плана">
|
||||
</div>
|
||||
|
||||
<div class="diet__form-row">
|
||||
<div class="diet__form-columns ">
|
||||
<div class="diet__form-column">
|
||||
<div class="label">
|
||||
Изображение
|
||||
</div>
|
||||
<label class="file">
|
||||
<input wire:model="image" type="file" name="file" class="file__input hidden"
|
||||
hidden="">
|
||||
@error('image')
|
||||
<span class="error">{{ $message }}</span>
|
||||
@enderror
|
||||
|
||||
@if (is_null($image))
|
||||
<span class="file__content">
|
||||
<span class="file__formats">
|
||||
<img src="/img/formats-2.svg" alt="formats">
|
||||
</span>
|
||||
<span class="file__title">
|
||||
Нажмите для выбора или перетащите изображание
|
||||
</span>
|
||||
</span>
|
||||
@else
|
||||
{{-- @php dd($image) @endphp --}}
|
||||
<span class="file__content">
|
||||
<span class="file__formats">
|
||||
<img src="{{ is_string($image) ? Storage::url($image) : $image->temporaryUrl() }}" alt="formats">
|
||||
</span>
|
||||
</span>
|
||||
@endif
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="diet__form-column">
|
||||
<div class="diet__form-row">
|
||||
<div class="label">
|
||||
Длительность плана питания
|
||||
</div>
|
||||
<div class="dropdown">
|
||||
<button @class(['dropdown__button', 'active' => $isVisibleDuration]) wire:click="showListDuration" wire:model="duration"
|
||||
type="button">
|
||||
{{ $duration }} дней
|
||||
</button>
|
||||
|
||||
<ul @class(['dropdown__list', 'visible' => $isVisibleDuration])>
|
||||
<li wire:click="toggleDuration('7')" @class(['dropdown__list-item', 'active' => $duration === '7']) data-value="7">7
|
||||
дней</li>
|
||||
<li wire:click="toggleDuration('8')" @class(['dropdown__list-item', 'active' => $duration === '8']) data-value="8">8
|
||||
дней</li>
|
||||
<li wire:click="toggleDuration('100')" @class(['dropdown__list-item', 'active' => $duration === '100'])
|
||||
data-value="100 ">100 дней</li>
|
||||
</ul>
|
||||
<input type="text" name="action" class="dropdown__input hidden" hidden
|
||||
value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="diet__form-row">
|
||||
<div class="diet__form-checkboxes">
|
||||
<label class="checkbox-btn">
|
||||
<input wire:model="type.slim" type="checkbox" name="slim"
|
||||
class="checkbox-btn__input hidden" hidden>
|
||||
<span class="checkbox-btn__content">
|
||||
<svg width="40" height="60">
|
||||
<use xlink:href="#SlimBig"></use>
|
||||
</svg>
|
||||
Slim
|
||||
</span>
|
||||
</label>
|
||||
<label class="checkbox-btn">
|
||||
<input wire:model="type.fit" type="checkbox" name="fit"
|
||||
class="checkbox-btn__input hidden" hidden>
|
||||
<span class="checkbox-btn__content">
|
||||
<svg width="40" height="60">
|
||||
<use xlink:href="#FitBig"></use>
|
||||
</svg>
|
||||
Fit
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="diet__form-column">
|
||||
<div class="diet__form-row">
|
||||
<div class="label">
|
||||
Статус
|
||||
</div>
|
||||
<div class="dropdown">
|
||||
<button @class(['dropdown__button', 'active' => $isVisibleState]) wire:click="showListState" type="button">
|
||||
{{ $state === 'active' ? 'Активна' : 'Неактивна' }}
|
||||
</button>
|
||||
<ul @class(['dropdown__list', 'visible' => $isVisibleState])>
|
||||
<li wire:click="toggleState('active')" @class(['dropdown__list-item', 'active' => $state === 'active'])>
|
||||
Активна</li>
|
||||
<li wire:click="toggleState('unactive')" @class(['dropdown__list-item', 'active' => $state === 'unactive'])>Неактивна
|
||||
</li>
|
||||
</ul>
|
||||
<input type="text" name="status" class="dropdown__input hidden" hidden
|
||||
value="unactive">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="diet__form-row">
|
||||
<div class="diet__form-checkboxes">
|
||||
<label class="checkbox-btn">
|
||||
<input wire:model="type.wellness" type="checkbox" name="wellness"
|
||||
class="checkbox-btn__input hidden" hidden>
|
||||
<span class="checkbox-btn__content">
|
||||
<svg width="40" height="60">
|
||||
<use xlink:href="#WellnessBig"></use>
|
||||
</svg>
|
||||
Wellness
|
||||
</span>
|
||||
</label>
|
||||
<label class="checkbox-btn">
|
||||
<input wire:model="type.behavior" type="checkbox" name="behavior"
|
||||
class="checkbox-btn__input hidden" hidden>
|
||||
<span class="checkbox-btn__content">
|
||||
<svg width="40" height="60">
|
||||
<use xlink:href="#BehaviorBig"></use>
|
||||
</svg>
|
||||
Behavior
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div wire:ignore class="diet__form-row">
|
||||
<div class="label">
|
||||
Описание
|
||||
</div>
|
||||
<!-- <label for="details" class="mb-3">Описание </label> -->
|
||||
<div class="wysiwyg">
|
||||
<div class="wysiwyg__caption">
|
||||
<textarea class="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:key="myIdentifierHere"
|
||||
x-ref="myIdentifierHere" wire:model="details"></textarea>
|
||||
<!-- x-ref="myIdentifierHere" wire:model="details"></textarea> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="diet__services">
|
||||
<div class="diet__services-caption">
|
||||
<div class="diet__services-title title">
|
||||
ОКАЗАНИЕ УСЛУГ
|
||||
</div>
|
||||
<div class="diary__stats-tablist" role="tablist" aria-labelledby="label">
|
||||
<button wire:click="$set('packets_count', 1)"
|
||||
class="btn {{ $packets_count === 1 ? 'active' : '' }}" role="tab" type="button"
|
||||
id="tab-1" aria-selected="{{ $packets_count === 1 ? 'true' : 'false' }}"
|
||||
aria-controls="tabpanel-1">1 пакет</button>
|
||||
<button wire:click="$set('packets_count', 3)"
|
||||
class="btn {{ $packets_count === 3 ? 'active' : '' }}" role="tab" type="button"
|
||||
id="tab-2" aria-selected="{{ $packets_count === 3 ? 'true' : 'false' }}"
|
||||
aria-controls="tabpanel-2" tabindex="-1">3 пакета</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($packets_count === 1)
|
||||
<div class="diet__services-body">
|
||||
<div class="tabpanel" role="tabpanel" id="tabpanel-1" tabindex="0" aria-labelledby="tab-1">
|
||||
<div class="diet__services-form">
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Краткое описание
|
||||
</div>
|
||||
<input wire:model="packet1_options_input.short" type="text" name="desc"
|
||||
class="input" placeholder="Введите краткое описание">
|
||||
</div>
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Цена
|
||||
|
||||
<span>
|
||||
1 вариант
|
||||
</span>
|
||||
</div>
|
||||
<input wire:model="packet1_options_input.price" type="num" name="price"
|
||||
class="input" placeholder="Введите цену варианта">
|
||||
</div>
|
||||
</div>
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Описание услуги:
|
||||
</div>
|
||||
<textarea wire:model="packet1_options_input.description" name="service" placeholder="Описание услуги"
|
||||
class="textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Содержание услуги
|
||||
</div>
|
||||
@isset($packet1_options['items'])
|
||||
<ul>
|
||||
@foreach ($packet1_options['items'] as $item)
|
||||
<li>
|
||||
<td>{{ $item }}</td>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endisset
|
||||
|
||||
<div class="diet__form-row">
|
||||
<input wire:model="input_items_1" type="text" name="name"
|
||||
class="input" placeholder="Содержание услуги" required="">
|
||||
</div>
|
||||
|
||||
|
||||
<button wire:click="addPacketOption('packet1_options', 'packet1_options_input')"
|
||||
type="button" class="btn btn-primary icon-plus"></button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($packets_count === 3)
|
||||
<div class="diet__services-body">
|
||||
<div class="tabpanel" role="tabpanel" id="tabpanel-1" tabindex="0" aria-labelledby="tab-1">
|
||||
<div class="diet__services-form">
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Краткое описание
|
||||
</div>
|
||||
<input wire:model="packet1_options_input.short" type="text" name="desc"
|
||||
class="input" placeholder="Введите краткое описание">
|
||||
</div>
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Цена
|
||||
|
||||
<span>
|
||||
1 вариант
|
||||
</span>
|
||||
</div>
|
||||
<input wire:model="packet1_options_input.price" type="num" name="price"
|
||||
class="input" placeholder="Введите цену варианта">
|
||||
</div>
|
||||
</div>
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Описание услуги:
|
||||
</div>
|
||||
<textarea wire:model="packet1_options_input.description" name="service" placeholder="Описание услуги"
|
||||
class="textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Содержание услуги
|
||||
</div>
|
||||
@isset($packet1_options['items'])
|
||||
<ul>
|
||||
@foreach ($packet1_options['items'] as $item)
|
||||
<li>
|
||||
<td>{{ $item }}</td>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endisset
|
||||
|
||||
<div class="diet__form-row">
|
||||
<input wire:model="input_items_1" type="text" name="name"
|
||||
class="input" placeholder="Содержание услуги" required="">
|
||||
</div>
|
||||
|
||||
|
||||
<button wire:click="addPacketOption('packet1_options', 'packet1_options_input')"
|
||||
type="button" class="btn btn-primary icon-plus"></button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="diet__services-body">
|
||||
<div class="tabpanel" role="tabpanel" id="tabpanel-1" tabindex="0" aria-labelledby="tab-1">
|
||||
<div class="diet__services-form">
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Краткое описание
|
||||
</div>
|
||||
<input wire:model="packet2_options_input.short" type="text" name="desc"
|
||||
class="input" placeholder="Введите краткое описание">
|
||||
</div>
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Цена
|
||||
|
||||
<span>
|
||||
2 вариант
|
||||
</span>
|
||||
</div>
|
||||
<input wire:model="packet2_options_input.price" type="num" name="price"
|
||||
class="input" placeholder="Введите цену варианта">
|
||||
</div>
|
||||
</div>
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Описание услуги:
|
||||
</div>
|
||||
<textarea wire:model="packet2_options_input.description" name="service" placeholder="Описание услуги"
|
||||
class="textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Содержание услуги
|
||||
</div>
|
||||
@isset($packet2_options['items'])
|
||||
<ul>
|
||||
@foreach ($packet2_options['items'] as $item)
|
||||
<li>
|
||||
<td>{{ $item }}</td>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endisset
|
||||
|
||||
<div class="diet__form-row">
|
||||
<input wire:model="input_items_2" type="text" name="name"
|
||||
class="input" placeholder="Содержание услуги" required="">
|
||||
</div>
|
||||
|
||||
|
||||
<button wire:click="addPacketOption('packet2_options', 'packet2_options_input')"
|
||||
type="button" class="btn btn-primary icon-plus"></button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="diet__services-body">
|
||||
<div class="tabpanel" role="tabpanel" id="tabpanel-1" tabindex="0" aria-labelledby="tab-1">
|
||||
<div class="diet__services-form">
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Краткое описание
|
||||
</div>
|
||||
<input wire:model="packet3_options_input.short" type="text" name="desc"
|
||||
class="input" placeholder="Введите краткое описание">
|
||||
</div>
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Цена
|
||||
|
||||
<span>
|
||||
3 вариант
|
||||
</span>
|
||||
</div>
|
||||
<input wire:model="packet3_options_input.price" type="num" name="price"
|
||||
class="input" placeholder="Введите цену варианта">
|
||||
</div>
|
||||
</div>
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Описание услуги:
|
||||
</div>
|
||||
<textarea wire:model="packet3_options_input.description" name="service" placeholder="Описание услуги"
|
||||
class="textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="diet__services-row">
|
||||
<div class="diet__services-column">
|
||||
<div class="label">
|
||||
Содержание услуги
|
||||
</div>
|
||||
@isset($packet3_options['items'])
|
||||
<ul class="mb-3">
|
||||
@foreach ($packet3_options['items'] as $item)
|
||||
<li>
|
||||
<td>{{ $item }}</td>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endisset
|
||||
|
||||
<div class="diet__form-row">
|
||||
<input wire:model="input_items_3" type="text" name="name"
|
||||
class="input" placeholder="Содержание услуги" required="">
|
||||
</div>
|
||||
|
||||
|
||||
<button wire:click="addPacketOption('packet3_options', 'packet3_options_input')"
|
||||
type="button" class="btn btn-primary icon-plus"></button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@if ($errors)
|
||||
<div class="">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $message)
|
||||
<li> {{ $message }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<div class="diet__btns">
|
||||
<button wire:click="addToDrafts" type="button" class="diet__btn btn btn-gray">В
|
||||
черновик</button>
|
||||
<button wire:click="showPreview"type="button" class="diet__btn btn btn-gray">Превью</button>
|
||||
<button wire:click.prevent="publish" type="button"
|
||||
class="diet__btn btn btn-primary">Опубликовать</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,9 +1,13 @@
|
||||
@extends('layouts/eatvio')
|
||||
|
||||
@section('main_section')
|
||||
@livewire('plan.create')
|
||||
@isset($plan)
|
||||
@livewire('plan.edit', ['plan' => $plan]);
|
||||
@else
|
||||
@livewire('plan.create')
|
||||
@endisset
|
||||
@endsection
|
||||
@push('css_head')
|
||||
{{-- <script src="/js/build/ckeditor.js" defer></script> --}}
|
||||
<script src="/js/ckeditor.js"></script>
|
||||
@endpush
|
||||
|
||||
|
||||
@@ -86,6 +86,35 @@
|
||||
{{ $plan->details }}
|
||||
</p>
|
||||
|
||||
|
||||
<div class="person__checklist">
|
||||
|
||||
|
||||
@if ($plan->type['slim'] === true)
|
||||
<svg width="40" height="60">
|
||||
<use xlink:href="#SlimBig"></use>
|
||||
</svg>
|
||||
@endif
|
||||
|
||||
@if ($plan->type['fit'] === true)
|
||||
<svg width="40" height="60">
|
||||
<use xlink:href="#FitBig"></use>
|
||||
</svg>
|
||||
@endif
|
||||
|
||||
@if ($plan->type['wellness'] === true)
|
||||
<svg width="40" height="60">
|
||||
<use xlink:href="#WellnessBig"></use>
|
||||
</svg>
|
||||
@endif
|
||||
|
||||
@if ($plan->type['behavior'] === true)
|
||||
<svg width="40" height="60">
|
||||
<use xlink:href="#BehaviorBig"></use>
|
||||
</svg>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="announcement__footer">
|
||||
<button type="button"
|
||||
class="announcement__footer-action icon-message-square">Комментировать</button>
|
||||
@@ -117,7 +146,7 @@
|
||||
@endsection
|
||||
|
||||
{{-- @push('jq_scripts') --}}
|
||||
{{-- <script src="js/app.min.js"></script> --}}
|
||||
{{-- <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 --}}
|
||||
|
||||
@@ -88,8 +88,8 @@ Route::group(
|
||||
Route::resource('calendar', CalendarController::class);
|
||||
Route::resource('user_detailz', UserDetailzController::class);
|
||||
Route::resource('user', UserController::class)->only('show');
|
||||
Route::resource('finance', FinanceController::class)->only(['index', 'show']);
|
||||
Route::resource('plan', PlanController::class)->only(['create', 'show', 'index']);
|
||||
Route::resource('finance', FinanceController::class)->only(['index','show']);
|
||||
Route::resource('plan', PlanController::class)->only(['create', 'show', 'index', 'edit']);
|
||||
Route::resource('diet', DietController::class)->only(['create', 'show', 'index', 'edit']);
|
||||
Route::resource('consultants', ConsultantController::class)->only(['index']);
|
||||
Route::resource('recipe', RecipeController::class)->only(['create', 'show', 'index', 'edit']);
|
||||
|
||||
@@ -31,17 +31,18 @@ class CreateTest extends TestCase
|
||||
|
||||
$this->user = User::factory()->create(['is_consultant' => true]);
|
||||
$this->plan = Plan::factory()->make();
|
||||
|
||||
$this->refreshApplicationWithLocale('en');
|
||||
}
|
||||
|
||||
public function test_show_form_create_plan()
|
||||
{
|
||||
$response = $this
|
||||
->actingAs($this->user)
|
||||
->get('/plan/create');
|
||||
->get(route('plan.create'));
|
||||
|
||||
$response
|
||||
->assertStatus(302);
|
||||
// ->assertRedirect(route('home'));
|
||||
$response->assertSuccessful();
|
||||
// ->assertRedirect(route('home'));
|
||||
}
|
||||
|
||||
public function test_publish_new_plan_success(): void
|
||||
@@ -49,6 +50,7 @@ class CreateTest extends TestCase
|
||||
$this->actingAs($this->user);
|
||||
|
||||
// $this->assertEquals($this->plan->count(), $count = Plan::count());
|
||||
$planCountAtStart = Plan::count();
|
||||
|
||||
Livewire::test(Create::class)
|
||||
->set('name', $this->plan->name)
|
||||
@@ -71,11 +73,18 @@ class CreateTest extends TestCase
|
||||
->set('packet3_options', $this->plan->packet3_options)
|
||||
->assertSet('packet3_options', $this->plan->packet3_options)
|
||||
->call('publish')
|
||||
->assertStatus(200)
|
||||
->assertHasNoErrors(['name', 'image', 'duration', 'details']);
|
||||
->assertSuccessful()
|
||||
->assertHasNoErrors(['name', 'image', 'duration', 'details', 'packets_count', 'packet1_options', 'packet2_options', 'packet3_options']);
|
||||
|
||||
Storage::disk('public')->assertExists($this->plan->image);
|
||||
|
||||
$this->assertEquals($planCountAtStart + 1, Plan::count());
|
||||
|
||||
$response = $this->actingAs($this->user)->get(route('plan.index'));
|
||||
|
||||
$response->assertSuccessful();
|
||||
|
||||
|
||||
// $this->assertEquals($count + 1, Plan::count());
|
||||
}
|
||||
|
||||
@@ -83,7 +92,10 @@ class CreateTest extends TestCase
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$id = $this->plan->count();
|
||||
$planCountAtStart = Plan::count();
|
||||
|
||||
// $planLastId = $this->plan->latest()->first()->id;
|
||||
// $expectedRedirectRoute = route('plan.show', ['plan' => $planLastId + 1]);
|
||||
|
||||
Livewire::test(Create::class)
|
||||
->set('name', $this->plan->name)
|
||||
@@ -106,17 +118,20 @@ class CreateTest extends TestCase
|
||||
->set('packet3_options', $this->plan->packet3_options)
|
||||
->assertSet('packet3_options', $this->plan->packet3_options)
|
||||
->call('addToDrafts')
|
||||
->assertStatus(200)
|
||||
->assertRedirect('plan/'.$id + 1)
|
||||
->assertRedirect()
|
||||
->assertHasNoErrors(['name', 'image', 'duration', 'details']);
|
||||
|
||||
Storage::disk('public')->assertExists($this->plan->image);
|
||||
|
||||
$this->assertEquals($planCountAtStart + 1, Plan::count());
|
||||
}
|
||||
|
||||
public function test_to_preview_new_plan_success(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$planCountAtStart = Plan::count();
|
||||
|
||||
Livewire::test(Create::class)
|
||||
->set('name', $this->plan->name)
|
||||
->assertSet('name', $this->plan->name)
|
||||
@@ -138,16 +153,20 @@ class CreateTest extends TestCase
|
||||
->set('packet3_options', $this->plan->packet3_options)
|
||||
->assertSet('packet3_options', $this->plan->packet3_options)
|
||||
->call('showPreview')
|
||||
->assertStatus(200)
|
||||
->assertSuccessful()
|
||||
->assertHasNoErrors(['name', 'image', 'duration', 'details']);
|
||||
|
||||
Storage::disk('public')->assertExists($this->plan->image);
|
||||
|
||||
$this->assertEquals($planCountAtStart + 1, Plan::count());
|
||||
}
|
||||
|
||||
public function test_set_empty_data(): void
|
||||
{
|
||||
$this->actingAs($this->user);
|
||||
|
||||
$planCountAtStart = Plan::count();
|
||||
|
||||
Livewire::test(Create::class)
|
||||
->set('name', null)
|
||||
->set('image', null)
|
||||
@@ -161,5 +180,7 @@ class CreateTest extends TestCase
|
||||
->set('packet3_options', null)
|
||||
->call('publish')
|
||||
->assertHasErrors(['name', 'image', 'duration', 'details']);
|
||||
|
||||
$this->assertEquals($planCountAtStart, Plan::count());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,19 +32,17 @@ class ShowTest extends TestCase
|
||||
$this->image = UploadedFile::fake()->image('plan.png');
|
||||
|
||||
$this->user = User::factory()->create(['is_consultant' => true]);
|
||||
$this->plan = Plan::factory()->create();
|
||||
|
||||
$this->plan = Plan::inRandomOrder()->first();
|
||||
$this->refreshApplicationWithLocale('en');
|
||||
}
|
||||
|
||||
public function test_show_form_success()
|
||||
{
|
||||
$response = $this->actingAs($this->user)
|
||||
->get('/plan/'.$this->plan->id);
|
||||
->get(route('plan.show', ['plan' => $this->plan->id]));
|
||||
|
||||
$response
|
||||
->assertStatus(302);
|
||||
// ->assertRedirect(route('home'));
|
||||
// ->assertRedirect('https://dev2.eatvio.com/ru');
|
||||
->assertOk();
|
||||
}
|
||||
|
||||
// When appear role for user
|
||||
|
||||
Reference in New Issue
Block a user