Changes
This commit is contained in:
Generated
+4
@@ -179,6 +179,10 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/robots-txt" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/robots-txt" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/temporary-directory" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/temporary-directory" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dom-crawler" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dom-crawler" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/predis/predis" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/yepsua/filament-range-field" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/tomatophp/console-helpers" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/tomatophp/filament-icons" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
|||||||
Generated
+15
@@ -190,6 +190,21 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/spatie/laravel-sitemap" />
|
<path value="$PROJECT_DIR$/vendor/spatie/laravel-sitemap" />
|
||||||
<path value="$PROJECT_DIR$/vendor/spatie/browsershot" />
|
<path value="$PROJECT_DIR$/vendor/spatie/browsershot" />
|
||||||
<path value="$PROJECT_DIR$/vendor/spatie/crawler" />
|
<path value="$PROJECT_DIR$/vendor/spatie/crawler" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/spatie/laravel-signal-aware-command" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/spatie/db-dumper" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/spatie/laravel-backup" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/calebporzio/sushi" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/shuvroroy/filament-spatie-laravel-backup" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/askerakbar/checkpoint" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/filament/spatie-laravel-settings-plugin" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpstan/phpdoc-parser" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/spatie/laravel-settings" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/predis/predis" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/yepsua/filament-range-field" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/tomatophp/filament-icons" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/tomatophp/console-helpers" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.1" />
|
<component name="PhpProjectSharedConfiguration" php_language_level="8.1" />
|
||||||
|
|||||||
@@ -0,0 +1,214 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\SlideResource\Pages;
|
||||||
|
use App\Models\Event;
|
||||||
|
use App\Models\Page;
|
||||||
|
use App\Models\Post;
|
||||||
|
use App\Models\Slide;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Components\ColorPicker;
|
||||||
|
use Filament\Forms\Components\DateTimePicker;
|
||||||
|
use Filament\Forms\Components\FileUpload;
|
||||||
|
use Filament\Forms\Components\Toggle;
|
||||||
|
use Filament\Forms\Components\ToggleButtons;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
|
class SlideResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = Slide::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
Forms\Components\Section::make('Быстрая настройка слайда')->schema([
|
||||||
|
Forms\Components\Grid::make()->schema([
|
||||||
|
Forms\Components\Select::make('model_select')
|
||||||
|
->name('')
|
||||||
|
->label('Выбор типа данных')
|
||||||
|
->options([
|
||||||
|
'Post' => 'Новость',
|
||||||
|
'Page' => 'Страница',
|
||||||
|
'Event' => 'Мероприятие',
|
||||||
|
'Custom' => 'Кастомная ссылка',
|
||||||
|
])
|
||||||
|
->afterStateUpdated(function (string $operation, string|null $state, Forms\Set $set, Forms\Get $get) {
|
||||||
|
if ($get('model_select') === 'Custom') {
|
||||||
|
$set('model', null);
|
||||||
|
$set('title', null);
|
||||||
|
$set('content', null);
|
||||||
|
$set('link', null);
|
||||||
|
};
|
||||||
|
})->live(onBlur: true),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('model')
|
||||||
|
->label('Поиск данных')
|
||||||
|
->name('')
|
||||||
|
->live(onBlur: true)
|
||||||
|
->searchable()
|
||||||
|
->live(onBlur: true)
|
||||||
|
->afterStateUpdated(function (string $operation, string|null $state, Forms\Set $set, Forms\Get $get) {
|
||||||
|
if ($get('model_select') === 'Post') {
|
||||||
|
$post = Post::find($state);
|
||||||
|
$set('title', $post->title);
|
||||||
|
$relativeUrl = parse_url(route('client.post.show', $post->slug), PHP_URL_PATH);
|
||||||
|
$set('link', $relativeUrl);
|
||||||
|
};
|
||||||
|
if ($get('model_select') === 'Page') {
|
||||||
|
$page = Page::find($state);
|
||||||
|
$set('title', $page->title);
|
||||||
|
$set('link', $page->path);
|
||||||
|
};
|
||||||
|
if ($get('model_select') === 'Event') {
|
||||||
|
$event = Event::find($state);
|
||||||
|
$set('title', $event->title);
|
||||||
|
$relativeUrl = parse_url(route('client.event.show', $event->slug), PHP_URL_PATH);
|
||||||
|
$set('link', $relativeUrl);
|
||||||
|
};
|
||||||
|
|
||||||
|
})
|
||||||
|
->options(function (Forms\Get $get) {
|
||||||
|
if ($get('model_select') === 'Post') {
|
||||||
|
return Post::where('status', '=', 'published')->pluck('title', 'id');
|
||||||
|
};
|
||||||
|
if ($get('model_select') === 'Page') {
|
||||||
|
return Page::where('title', '!=', null)->pluck('title', 'id');
|
||||||
|
};
|
||||||
|
if ($get('model_select') === 'Event') {
|
||||||
|
return Event::all()->pluck('title', 'id');
|
||||||
|
};
|
||||||
|
if ($get('model_select') === 'Custom') {
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
Forms\Components\Section::make('Слайдер')->schema([
|
||||||
|
|
||||||
|
Forms\Components\Section::make('Информация слайда')->schema([
|
||||||
|
Forms\Components\TextInput::make('title')
|
||||||
|
->label('Заголовок слайда'),
|
||||||
|
Forms\Components\Textarea::make('content')
|
||||||
|
->label('Текст слайда'),
|
||||||
|
Forms\Components\Grid::make()->schema([
|
||||||
|
ColorPicker::make('color_theme')
|
||||||
|
->label('Цвет текста')
|
||||||
|
->default('#ffffff')
|
||||||
|
->required(),
|
||||||
|
Forms\Components\ToggleButtons::make('settings.text_position')
|
||||||
|
->options([
|
||||||
|
'left' => 'Текст слева',
|
||||||
|
'center' => 'Текст по середине',
|
||||||
|
'right' => 'Текст справа'
|
||||||
|
])
|
||||||
|
->inline()->default('left')->grouped()
|
||||||
|
->label('Позиция текста на слайде'),
|
||||||
|
]),
|
||||||
|
Forms\Components\Grid::make()->schema([
|
||||||
|
Toggle::make('active_button')
|
||||||
|
->label('Использовать кнопку для ссылки (Ссылка будет открываться при нажатии на слайд)')
|
||||||
|
->inline(false)
|
||||||
|
->default(true) // Проверяем, есть ли текст в link_text
|
||||||
|
->live()
|
||||||
|
->afterStateHydrated(function (Toggle $component, $state, $get) {
|
||||||
|
if ($state === null && !empty($get('settings.link_text'))) {
|
||||||
|
$component->state(true); // Устанавливаем значение по умолчанию
|
||||||
|
}
|
||||||
|
})
|
||||||
|
->dehydrated(false),
|
||||||
|
Forms\Components\TextInput::make('settings.link_text')
|
||||||
|
->default('Читать')
|
||||||
|
->label('Текст кнопки')
|
||||||
|
->disabled(fn (Forms\Get $get) => !$get('active_button'))
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
Forms\Components\Section::make('Изображение')->schema([
|
||||||
|
FileUpload::make('image.url')
|
||||||
|
->label('Изображение')
|
||||||
|
->image()
|
||||||
|
->optimize('webp')
|
||||||
|
->resize(50)
|
||||||
|
->disk('public')
|
||||||
|
->directory('images')
|
||||||
|
->imageEditor()
|
||||||
|
->required(),
|
||||||
|
ToggleButtons::make('image.shading')->inline()->grouped()->label('Уровень затемнения изображения')->options([
|
||||||
|
'1' => 'Без затемнения',
|
||||||
|
'0.7' => 'Слабое затемнение',
|
||||||
|
'0.5' => 'Среднее затемнение',
|
||||||
|
'0.3' => 'Сильное затемнение',
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
Forms\Components\Section::make('Общая часть')->schema([
|
||||||
|
Forms\Components\Grid::make()->schema([
|
||||||
|
DateTimePicker::make('start_time')
|
||||||
|
->label('Слайд начинается с')
|
||||||
|
->native()
|
||||||
|
->displayFormat('d/m/Y')
|
||||||
|
->default(Carbon::now())
|
||||||
|
->maxDate(Carbon::now()->addWeeks(2)),
|
||||||
|
DateTimePicker::make('end_time')
|
||||||
|
->label('Слайд действует до')
|
||||||
|
->native()
|
||||||
|
->displayFormat('d/m/Y')
|
||||||
|
->default(Carbon::now()->addWeeks(2))
|
||||||
|
->minDate(Carbon::now())
|
||||||
|
->maxDate(Carbon::now()->addMonth()),
|
||||||
|
]),
|
||||||
|
Forms\Components\TextInput::make('link')
|
||||||
|
->label('Ссылка кнопки')
|
||||||
|
->required(),
|
||||||
|
]),
|
||||||
|
|
||||||
|
Toggle::make('is_active')->default(true)->label('Активный слайдер')->inline(false),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->reorderable('sort')
|
||||||
|
->defaultSort('sort')
|
||||||
|
->columns([
|
||||||
|
Tables\Columns\TextColumn::make('title'),
|
||||||
|
Tables\Columns\ToggleColumn::make('is_active')
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
//
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListSlides::route('/'),
|
||||||
|
'create' => Pages\CreateSlide::route('/create'),
|
||||||
|
'edit' => Pages\EditSlide::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\SlideResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\SlideResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateSlide extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = SlideResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeCreate(array $data): array
|
||||||
|
{
|
||||||
|
unset($data['model_select'], $data['model']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\SlideResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\SlideResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditSlide extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = SlideResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeSave(array $data): array
|
||||||
|
{
|
||||||
|
unset($data['model_select'], $data['model']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\SlideResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\SlideResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListSlides extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = SlideResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\SliderResource\Pages;
|
||||||
|
use App\Filament\Resources\SliderResource\RelationManagers;
|
||||||
|
use App\Models\Slider;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Forms\Components\Toggle;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class SliderResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = Slider::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
Forms\Components\Section::make()->schema([
|
||||||
|
Forms\Components\TextInput::make('title')
|
||||||
|
->label('Заголовок слайдера'),
|
||||||
|
Toggle::make('is_active')->default(true)->label('Активный слайдер')->inline(false),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
//
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
//
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListSliders::route('/'),
|
||||||
|
'create' => Pages\CreateSlider::route('/create'),
|
||||||
|
'edit' => Pages\EditSlider::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\SliderResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\SliderResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateSlider extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = SliderResource::class;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\SliderResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\SliderResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditSlider extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = SliderResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\SliderResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\SliderResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListSliders extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = SliderResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,21 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class Slide extends Model
|
class Slide extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $guarded = false;
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'settings' => 'array',
|
||||||
|
'image' => 'array',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function slider(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Slider::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
class Slider extends Model
|
class Slider extends Model
|
||||||
{
|
{
|
||||||
@@ -11,13 +12,10 @@ class Slider extends Model
|
|||||||
|
|
||||||
protected $guarded = false;
|
protected $guarded = false;
|
||||||
|
|
||||||
protected $casts = [
|
|
||||||
'settings' => 'array',
|
|
||||||
'image' => 'array',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function slidable()
|
public function slides(): HasMany
|
||||||
{
|
{
|
||||||
return $this->morphTo();
|
return $this->hasMany(Slide::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?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::create('sliders', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('title');
|
||||||
|
$table->boolean('is_active');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('sliders');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?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::create('slides', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('title');
|
||||||
|
$table->text('content');
|
||||||
|
$table->string('image');
|
||||||
|
$table->string('link');
|
||||||
|
$table->string('link_text');
|
||||||
|
$table->string('color_theme');
|
||||||
|
$table->boolean('is_active')->default(true);
|
||||||
|
$table->integer('sort')->nullable();
|
||||||
|
$table->foreignId('slider_id')->references('id')->on('sliders')->onDelete('cascade');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('slides');
|
||||||
|
}
|
||||||
|
};
|
||||||
Generated
+18
-1
@@ -26,7 +26,8 @@
|
|||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"preline": "^1.9.0",
|
"preline": "^1.9.0",
|
||||||
"slugify": "^1.6.6",
|
"slugify": "^1.6.6",
|
||||||
"vue3-yandex-smartcaptcha": "^1.0.0"
|
"vue3-yandex-smartcaptcha": "^1.0.0",
|
||||||
|
"vuex": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@inertiajs/vue3": "^1.0.0",
|
"@inertiajs/vue3": "^1.0.0",
|
||||||
@@ -1037,6 +1038,11 @@
|
|||||||
"@vue/shared": "3.5.11"
|
"@vue/shared": "3.5.11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@vue/devtools-api": {
|
||||||
|
"version": "6.6.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
|
||||||
|
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
|
||||||
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.5.11",
|
"version": "3.5.11",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.11.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.11.tgz",
|
||||||
@@ -6218,6 +6224,17 @@
|
|||||||
"vue": "^3.3.8"
|
"vue": "^3.3.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vuex": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-api": "^6.0.0-beta.11"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
|||||||
+2
-1
@@ -45,7 +45,8 @@
|
|||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"preline": "^1.9.0",
|
"preline": "^1.9.0",
|
||||||
"slugify": "^1.6.6",
|
"slugify": "^1.6.6",
|
||||||
"vue3-yandex-smartcaptcha": "^1.0.0"
|
"vue3-yandex-smartcaptcha": "^1.0.0",
|
||||||
|
"vuex": "^4.1.0"
|
||||||
},
|
},
|
||||||
"name": "ntspi-reborn",
|
"name": "ntspi-reborn",
|
||||||
"description": "<p align=\"center\"><a href=\"https://laravel.com\" target=\"_blank\"><img src=\"https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg\" width=\"400\" alt=\"Laravel Logo\"></a></p>",
|
"description": "<p align=\"center\"><a href=\"https://laravel.com\" target=\"_blank\"><img src=\"https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg\" width=\"400\" alt=\"Laravel Logo\"></a></p>",
|
||||||
|
|||||||
@@ -69,6 +69,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapActions } from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'slider',
|
name: 'slider',
|
||||||
props: {
|
props: {
|
||||||
@@ -82,7 +84,6 @@ export default {
|
|||||||
currentIndex: 0,
|
currentIndex: 0,
|
||||||
intervalId: null,
|
intervalId: null,
|
||||||
slideDuration: 5000,
|
slideDuration: 5000,
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -90,12 +91,13 @@ export default {
|
|||||||
return this.slidersCarousel && this.slidersCarousel.data ? this.slidersCarousel.data.length : 0;
|
return this.slidersCarousel && this.slidersCarousel.data ? this.slidersCarousel.data.length : 0;
|
||||||
},
|
},
|
||||||
progressBarStep() {
|
progressBarStep() {
|
||||||
const slides = this.totalSlides
|
const slides = this.totalSlides;
|
||||||
const step = 100 / slides
|
const step = 100 / slides;
|
||||||
return (this.currentIndex + 1) * step
|
return (this.currentIndex + 1) * step;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
...mapActions(['updateLastSlider']),
|
||||||
next() {
|
next() {
|
||||||
if (this.totalSlides > 0) {
|
if (this.totalSlides > 0) {
|
||||||
this.currentIndex = (this.currentIndex + 1) % this.totalSlides;
|
this.currentIndex = (this.currentIndex + 1) % this.totalSlides;
|
||||||
@@ -109,8 +111,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
startTimer() {
|
startTimer() {
|
||||||
this.stopTimer(); // Останавливаем предыдущий таймер, если он есть
|
this.stopTimer();
|
||||||
this.intervalId = setInterval(this.next, this.slideDuration); // Запускаем новый таймер
|
this.intervalId = setInterval(this.next, this.slideDuration);
|
||||||
},
|
},
|
||||||
stopTimer() {
|
stopTimer() {
|
||||||
clearInterval(this.intervalId);
|
clearInterval(this.intervalId);
|
||||||
@@ -121,7 +123,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$emit('slider-mounted', this.$refs.sliderRef);
|
// Передаем данные в Vuex после монтирования компонента
|
||||||
|
this.updateLastSlider({
|
||||||
|
url: this.$page.props.ziggy.location,
|
||||||
|
bottom: this.$refs.sliderRef.getBoundingClientRect().bottom, // Получаем актуальное значение bottom
|
||||||
|
});
|
||||||
this.startTimer();
|
this.startTimer();
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
|
|||||||
@@ -47,7 +47,6 @@
|
|||||||
|
|
||||||
<MobileNavbar v-if="sections" :sections="sections" />
|
<MobileNavbar v-if="sections" :sections="sections" />
|
||||||
|
|
||||||
|
|
||||||
<SearchModal open_id="open-search-modal" />
|
<SearchModal open_id="open-search-modal" />
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
@@ -55,14 +54,13 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
import {Link} from "@inertiajs/vue3";
|
import {Link} from "@inertiajs/vue3";
|
||||||
import axios from "axios";
|
|
||||||
import ClientGlobalSearch from "@/Components/ClientGlobalSearch.vue";
|
import ClientGlobalSearch from "@/Components/ClientGlobalSearch.vue";
|
||||||
import * as isvek from "bvi"
|
import * as isvek from "bvi"
|
||||||
import BaseIcon from "@/Components/BaseComponents/BaseIcon.vue";
|
import BaseIcon from "@/Components/BaseComponents/BaseIcon.vue";
|
||||||
import MobileNavbar from "@/Navbars/MobileNavbar.vue";
|
import MobileNavbar from "@/Navbars/MobileNavbar.vue";
|
||||||
import SearchModal from "@/Components/Modals/SearchModal.vue";
|
import SearchModal from "@/Components/Modals/SearchModal.vue";
|
||||||
import DesktopNavBar from "@/Navbars/DesktopNavBar.vue";
|
import DesktopNavBar from "@/Navbars/DesktopNavBar.vue";
|
||||||
|
import {mapGetters} from "vuex";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -87,7 +85,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
scrollPosition: 0,
|
scrollPosition: 0,
|
||||||
headerFilter: false,
|
headerFilter: false,
|
||||||
underSliderHeader: this.sliderRef,
|
underSliderHeader: true,
|
||||||
bvi: null,
|
bvi: null,
|
||||||
isActiveBvi: null,
|
isActiveBvi: null,
|
||||||
logos: {
|
logos: {
|
||||||
@@ -96,36 +94,23 @@ export default {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
isSameRoute(route) {
|
isSameRoute(route) {
|
||||||
if (route === this.$page.props.ziggy.location) {
|
if (route === this.$page.props.ziggy.location) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentLocation = this.$page.props.ziggy.location;
|
const currentLocation = this.$page.props.ziggy.location;
|
||||||
const currentUrl = this.$page.props.ziggy.url + '/' + route;
|
const currentUrl = this.$page.props.ziggy.url + '/' + route;
|
||||||
|
return currentLocation === currentUrl;
|
||||||
if (currentLocation === currentUrl) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
hasActivePage(section) {
|
hasActivePage(section) {
|
||||||
// Проверяем, есть ли активная страница в секции или подсекции
|
|
||||||
// if (!section || !section.pages) return false; // Проверка на наличие section и pages
|
|
||||||
|
|
||||||
if (section.pages) {
|
if (section.pages) {
|
||||||
return section.pages.some(page => this.isSameRoute(page.path));
|
return section.pages.some(page => this.isSameRoute(page.path));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section.subSections) {
|
if (section.subSections) {
|
||||||
return section.subSections.some(subSection => this.hasActivePage(subSection));
|
return section.subSections.some(subSection => this.hasActivePage(subSection));
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
iniBvi() {
|
iniBvi() {
|
||||||
if (this.getCookie('bvi_panelActive') === null) {
|
if (this.getCookie('bvi_panelActive') === null) {
|
||||||
this.bvi = new isvek.Bvi({
|
this.bvi = new isvek.Bvi({
|
||||||
@@ -138,43 +123,43 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleScroll() {
|
handleScroll() {
|
||||||
if (typeof this.sliderRef === 'object') {
|
if (this.lastSlider) {
|
||||||
const mainSlider = this.sliderRef;
|
const slider = this.lastSlider;
|
||||||
this.underSliderHeader = mainSlider.getBoundingClientRect().bottom < 50
|
this.scrollPosition = window.pageYOffset;
|
||||||
this.scrollPosition = window.pageYOffset
|
if (this.isSameRoute(slider.url)) {
|
||||||
this.headerFilter = this.scrollPosition > 90
|
this.underSliderHeader = slider.bottom < this.scrollPosition;
|
||||||
|
}
|
||||||
|
this.headerFilter = this.scrollPosition > 90;
|
||||||
} else {
|
} else {
|
||||||
this.headerFilter = true
|
this.headerFilter = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
lastSlider(newVal) {
|
||||||
|
if (this.isSameRoute(newVal?.url)) {
|
||||||
|
this.underSliderHeader = newVal.bottom < 0; // Пример логики
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
window.addEventListener('scroll', this.handleScroll)
|
window.addEventListener('scroll', this.handleScroll);
|
||||||
|
|
||||||
|
|
||||||
if (this.getCookie('bvi_panelActive') === null) {
|
if (this.getCookie('bvi_panelActive') === null) {
|
||||||
this.iniBvi()
|
this.iniBvi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
window.removeEventListener('scroll', this.handleScroll)
|
window.removeEventListener('scroll', this.handleScroll);
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapGetters(['lastSlider']),
|
||||||
currentLogo() {
|
currentLogo() {
|
||||||
return this.underSliderHeader ? this.logos.alternate : this.logos.default;
|
return this.underSliderHeader ? this.logos.alternate : this.logos.default;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppHead :seo="seo" />
|
<AppHead :seo="seo" />
|
||||||
|
|
||||||
<MainPageNavBar :sections="$page.props.navigation" :slider-ref="sliderRef" />
|
<MainPageNavBar :sections="$page.props.navigation" />
|
||||||
<ClientMainSlider @slider-mounted="setSliderRef" :slidersCarousel="sliders" />
|
<ClientMainSlider :slidersCarousel="sliders" />
|
||||||
|
|
||||||
<section class="max-w-screen-xl w-full mx-auto px-4 py-3 pb-10">
|
<section class="max-w-screen-xl w-full mx-auto px-4 py-3 pb-10">
|
||||||
<h2 class="text-brand-primary my-6 md:mb-[50px] md:mt-[80px] text-2xl font-semibold tracking-tight text-black lg:text-[32px] lg:leading-tight bvi-show">Последние новости</h2>
|
<h2 class="text-brand-primary my-6 md:mb-[50px] md:mt-[80px] text-2xl font-semibold tracking-tight text-black lg:text-[32px] lg:leading-tight bvi-show">Последние новости</h2>
|
||||||
@@ -195,11 +195,6 @@ export default {
|
|||||||
return LevelEducational
|
return LevelEducational
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
sliderRef: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
posts: {
|
posts: {
|
||||||
@@ -240,9 +235,6 @@ export default {
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
Cookies,
|
Cookies,
|
||||||
setSliderRef(ref) {
|
|
||||||
this.sliderRef = ref;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
|
|||||||
import {linksReform} from "@/mixins/LinksReform.js";
|
import {linksReform} from "@/mixins/LinksReform.js";
|
||||||
import YSmartCaptcha from 'vue3-yandex-smartcaptcha'
|
import YSmartCaptcha from 'vue3-yandex-smartcaptcha'
|
||||||
import cookieMixin from "@/mixins/cookieMixin.js";
|
import cookieMixin from "@/mixins/cookieMixin.js";
|
||||||
|
import store from '@/store/index.js';
|
||||||
|
|
||||||
|
|
||||||
// const appName = import.meta.env.VITE_APP_NAME || 'НТГСПИ';
|
// const appName = import.meta.env.VITE_APP_NAME || 'НТГСПИ';
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ createInertiaApp({
|
|||||||
setup({ el, App, props, plugin }) {
|
setup({ el, App, props, plugin }) {
|
||||||
return createSSRApp({ render: () => h(App, props) })
|
return createSSRApp({ render: () => h(App, props) })
|
||||||
.use(plugin)
|
.use(plugin)
|
||||||
|
.use(store)
|
||||||
.mixin(linksReform)
|
.mixin(linksReform)
|
||||||
.mixin(cookieMixin)
|
.mixin(cookieMixin)
|
||||||
.use(ZiggyVue)
|
.use(ZiggyVue)
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { createStore } from 'vuex';
|
||||||
|
|
||||||
|
export default createStore({
|
||||||
|
state: {
|
||||||
|
lastSlider: null, // Состояние для отслеживания положения слайдера
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
setLastSlider(state, value) {
|
||||||
|
state.lastSlider = value; // Мутация для изменения состояния
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
updateLastSlider({ commit }, value) {
|
||||||
|
commit('setLastSlider', value); // Действие для обновления состояния
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
lastSlider: (state) => state.lastSlider, // Геттер для получения состояния
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user