admin panel created
This commit is contained in:
parent
2c5dcebc84
commit
30f124a429
100
app/Console/Commands/CreateModelAndMigrationCommand.php
Normal file
100
app/Console/Commands/CreateModelAndMigrationCommand.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CreateModelAndMigrationCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'module:create {name}
|
||||
{--momi=}
|
||||
{--create_model=}
|
||||
{--create_migration=}
|
||||
{--add_migration=}
|
||||
';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if ($this->option('momi')) {
|
||||
$this->input->setOption('create_model', $this->option('momi'));
|
||||
$this->input->setOption('create_migration', $this->option('momi'));
|
||||
}
|
||||
if ($this->option('create_model')) {
|
||||
$this->createModel();
|
||||
}
|
||||
if ($this->option('create_migration')) {
|
||||
$this->createMigration();
|
||||
}
|
||||
if ($this->option('add_migration')) {
|
||||
$this->addMigration();
|
||||
}
|
||||
}
|
||||
|
||||
private function createModel()
|
||||
{
|
||||
try
|
||||
{
|
||||
$path = trim($this->argument('name'));
|
||||
$model = Str::singular(class_basename($this->option('create_model')));
|
||||
$this->call('make:model', [
|
||||
'name' => 'App\\Modules\\' . $path . '\\Models\\' . $model
|
||||
]);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$e->getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function createMigration()
|
||||
{
|
||||
$path = trim($this->argument('name'));
|
||||
$table = Str::plural(Str::snake(class_basename($this->option('create_migration'))));
|
||||
try
|
||||
{
|
||||
$this->call('make:migration', [
|
||||
'name' => 'create_' . $table . '_table',
|
||||
'--create' => $table,
|
||||
'--path' => 'app/Modules/' . $path . '/Database/Migrations'
|
||||
]);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private function addMigration()
|
||||
{
|
||||
$path = trim($this->argument('name'));
|
||||
$table = $this->option('add_migration');
|
||||
try
|
||||
{
|
||||
$this->call('make:migration', [
|
||||
'name' => $table,
|
||||
'--path' => 'app/Modules/' . $path . '/Database/Migrations'
|
||||
]);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
389
app/Console/Commands/CreateModuleCommand.php
Normal file
389
app/Console/Commands/CreateModuleCommand.php
Normal file
@ -0,0 +1,389 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CreateModuleCommand extends Command
|
||||
{
|
||||
protected $files;
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'make:module {name}
|
||||
{--all : Create ready module}
|
||||
';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Module creation command';
|
||||
|
||||
/**
|
||||
* Create a new command instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Filesystem $files)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if ($this->option('all'))
|
||||
{
|
||||
$directory = $this->getDirectory($this->argument('name'));
|
||||
if ($this->files->isDirectory($directory))
|
||||
{
|
||||
$this->error('Module already exists!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->createProviders();
|
||||
$this->createConfig();
|
||||
|
||||
$this->createModel();
|
||||
$this->createMigration();
|
||||
|
||||
$this->createController();
|
||||
$this->createView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getDirectory($directory)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $directory);
|
||||
}
|
||||
|
||||
private function createModel()
|
||||
{
|
||||
try
|
||||
{
|
||||
$model = Str::singular(class_basename($this->argument('name')));
|
||||
$this->call('make:model', [
|
||||
'name' => 'App\\Modules\\' . trim($this->argument('name')) . '\\Models\\' . $model
|
||||
]);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$e->getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function createView()
|
||||
{
|
||||
$directoryName = Str::singular(Str::studly(class_basename($this->argument('name'))));
|
||||
$path = $this->getViewsPath($this->argument('name'));
|
||||
if ($this->alreadyExists($path))
|
||||
{
|
||||
$this->error('View already exists!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->makeDirectory($path);
|
||||
|
||||
$stub = $this->files->get(base_path('resources/stubs/view.stub'));
|
||||
$this->files->put($path, $stub);
|
||||
$this->info('Views created');
|
||||
|
||||
//livewire
|
||||
$path = $this->getLivewireViewsPath($this->argument('name'));
|
||||
$this->makeDirectory($path);
|
||||
$this->info('Views - livewire folder created');
|
||||
|
||||
//components
|
||||
$path = $this->getComponentsViewsPath($this->argument('name'));
|
||||
$this->makeDirectory($path);
|
||||
$this->info('Views - components folder created');
|
||||
}
|
||||
}
|
||||
|
||||
private function getViewsPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Views/index.blade.php';
|
||||
}
|
||||
|
||||
private function getLivewireViewsPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Views/livewire/example.php';
|
||||
}
|
||||
|
||||
private function getComponentsViewsPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Views/components/example.php';
|
||||
}
|
||||
|
||||
private function createConfig()
|
||||
{
|
||||
$directoryName = Str::singular(Str::studly(class_basename($this->argument('name'))));
|
||||
$path = $this->getConfigPath($this->argument('name'));
|
||||
if ($this->alreadyExists($path))
|
||||
{
|
||||
$this->error('Config already exists!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->makeDirectory($path);
|
||||
|
||||
$stub = $this->files->get(base_path('resources/stubs/config.stub'));
|
||||
$this->files->put($path, $stub);
|
||||
$this->info('Config created');
|
||||
}
|
||||
}
|
||||
|
||||
private function getConfigPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Config/config.php';
|
||||
}
|
||||
|
||||
private function createProviders()
|
||||
{
|
||||
//Create ModuleServiceProvider
|
||||
$directoryName = Str::singular(Str::studly(class_basename($this->argument('name'))));
|
||||
$path = $this->getModuleServiceProviderPath($this->argument('name'));
|
||||
if ($this->alreadyExists($path))
|
||||
{
|
||||
$this->error('ModuleServiceProvider already exists!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->makeDirectory($path);
|
||||
$stub = $this->files->get(base_path('resources/stubs/module_service_provider.stub'));
|
||||
$stub = str_replace(
|
||||
[
|
||||
'TeamplateDirectoryName',
|
||||
],
|
||||
[
|
||||
$directoryName
|
||||
],
|
||||
$stub
|
||||
);
|
||||
|
||||
$this->files->put($path, $stub);
|
||||
$this->info('ModuleServiceProvider created');
|
||||
}
|
||||
|
||||
//Create RouteServiceProvider
|
||||
$path = $this->getRouteServiceProviderPath($this->argument('name'));
|
||||
if ($this->alreadyExists($path))
|
||||
{
|
||||
$this->error('RouteServiceProvider already exists!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->makeDirectory($path);
|
||||
$stub = $this->files->get(base_path('resources/stubs/route_service_provider.stub'));
|
||||
$stub = str_replace(
|
||||
[
|
||||
'TeamplateDirectoryName',
|
||||
],
|
||||
[
|
||||
$directoryName
|
||||
],
|
||||
$stub
|
||||
);
|
||||
|
||||
$this->files->put($path, $stub);
|
||||
$this->info('RouteServiceProvider created');
|
||||
}
|
||||
}
|
||||
|
||||
private function getModuleServiceProviderPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Providers/ModuleServiceProvider.php';
|
||||
}
|
||||
|
||||
private function getRouteServiceProviderPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Providers/RouteServiceProvider.php';
|
||||
}
|
||||
|
||||
private function createController()
|
||||
{
|
||||
$controller = Str::studly(class_basename($this->argument('name')));
|
||||
$modelName = Str::singular(Str::studly(class_basename($this->argument('name'))));
|
||||
|
||||
$path = $this->getControllerPath($this->argument('name'));
|
||||
|
||||
if ($this->alreadyExists($path))
|
||||
{
|
||||
$this->error('Controller already exists!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->makeDirectory($path);
|
||||
|
||||
$stub = $this->files->get(base_path('resources/stubs/controller.model.stub'));
|
||||
|
||||
$stub = str_replace(
|
||||
[
|
||||
'TeamplateNamespace',
|
||||
'TeamplateFullModelClass',
|
||||
'TeamplateClass',
|
||||
'TeamplateDirectoryName'
|
||||
],
|
||||
[
|
||||
'Modules\\' . trim($this->argument('name')) . '\\Http\\Controllers',
|
||||
'Modules\\' . trim($this->argument('name')) . '\\Models\\' . $modelName,
|
||||
$controller . 'Controller',
|
||||
lcfirst($controller)
|
||||
|
||||
],
|
||||
$stub
|
||||
);
|
||||
|
||||
$this->files->put($path, $stub);
|
||||
$this->info('Controller created');
|
||||
|
||||
//Livewire Http
|
||||
$path = $this->getLivewireHttpPath($this->argument('name'));
|
||||
$this->makeDirectory($path);
|
||||
$this->info('Http - Livewire folder created');
|
||||
|
||||
//Components Http
|
||||
$path = $this->getComponentsHttpPath($this->argument('name'));
|
||||
$this->makeDirectory($path);
|
||||
$this->info('Http - Components folder created');
|
||||
|
||||
//Policies Http
|
||||
$path = $this->getPoliciesHttpPath($this->argument('name'));
|
||||
$this->makeDirectory($path);
|
||||
$this->info('Http - Policies folder created');
|
||||
|
||||
//Requests Http
|
||||
$path = $this->getRequestsHttpPath($this->argument('name'));
|
||||
$this->makeDirectory($path);
|
||||
$this->info('Http - Requests folder created');
|
||||
|
||||
//Routes create
|
||||
$this->createRoutes($controller, $modelName);
|
||||
}
|
||||
}
|
||||
|
||||
private function getLivewireHttpPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Http/Livewire/example.php';
|
||||
}
|
||||
|
||||
private function getComponentsHttpPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Http/Components/example.php';
|
||||
}
|
||||
|
||||
private function getPoliciesHttpPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Http/Policies/example.php';
|
||||
}
|
||||
|
||||
private function getRequestsHttpPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' . str_replace('\\', '/', $argument) . '/Http/Requests/example.php';
|
||||
}
|
||||
|
||||
private function createRoutes($controller, $modelName)
|
||||
{
|
||||
$routePath = $this->getRoutesPath($this->argument('name'));
|
||||
|
||||
if ($this->alreadyExists($routePath))
|
||||
{
|
||||
$this->error('Routes already exists!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->makeDirectory($routePath);
|
||||
|
||||
$stub = $this->files->get(base_path('resources/stubs/routes.web.stub'));
|
||||
|
||||
$stub = str_replace(
|
||||
[
|
||||
'TeamplateDirectoryName',
|
||||
'TeamplateRoutePrefix',
|
||||
'TeamplateClass'
|
||||
],
|
||||
[
|
||||
$controller,
|
||||
lcfirst($modelName),
|
||||
$controller . 'Controller'
|
||||
],
|
||||
$stub
|
||||
);
|
||||
|
||||
$this->files->put($routePath, $stub);
|
||||
$this->info('Routes created successfully');
|
||||
}
|
||||
}
|
||||
|
||||
private function alreadyExists($valuePath)
|
||||
{
|
||||
return $this->files->exists($valuePath);
|
||||
}
|
||||
|
||||
private function getRoutesPath($argument)
|
||||
{
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' .
|
||||
str_replace('\\', '/', $argument) .
|
||||
'/Routes/web.php';
|
||||
}
|
||||
|
||||
private function getControllerPath($argument)
|
||||
{
|
||||
$controller = Str::studly(class_basename($argument));
|
||||
return $this->laravel['path'] .
|
||||
'/Modules/' .
|
||||
str_replace('\\', '/', $argument) .
|
||||
'/Http/Controllers/' .
|
||||
$controller .
|
||||
'Controller.php';
|
||||
}
|
||||
|
||||
private function makeDirectory($path)
|
||||
{
|
||||
$this->files->makeDirectory(dirname($path), 0777, true, true);
|
||||
//$this->files->makeDirectory(dirname($path));
|
||||
}
|
||||
|
||||
private function createMigration()
|
||||
{
|
||||
$name = trim($this->argument('name'));
|
||||
$table = Str::plural(Str::snake(class_basename($this->argument('name'))));
|
||||
try
|
||||
{
|
||||
$this->call('make:migration', [
|
||||
'name' => 'create_' . $table . '_table',
|
||||
'--create' => $table,
|
||||
'--path' => 'app/Modules/' . $name . '/Database/Migrations'
|
||||
]);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
5
app/Modules/Admin/Config/config.php
Normal file
5
app/Modules/Admin/Config/config.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
];
|
||||
@ -0,0 +1,27 @@
|
||||
<?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('admins', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
});*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('admins');
|
||||
}
|
||||
};
|
||||
68
app/Modules/Admin/Http/Controllers/AdminController.php
Normal file
68
app/Modules/Admin/Http/Controllers/AdminController.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\Http\Controllers;
|
||||
|
||||
use Modules\Admin\Models\Admin;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\User\UserRole;
|
||||
use App\Models\User\Role;
|
||||
use App\Models\User;
|
||||
|
||||
class AdminController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (!$this->superAdminExists())
|
||||
{
|
||||
return $this->goToSuperAdminCreator();
|
||||
}
|
||||
return view('admin::index');
|
||||
}
|
||||
|
||||
public function superAdminExists()
|
||||
{
|
||||
$count = UserRole::where('role_id', Role::SUPER_ADMIN)->count();
|
||||
if ($count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function goToSuperAdminCreator()
|
||||
{
|
||||
return view('admin::setAdmin.index', [
|
||||
'users' => User::orderBy('name')->get()
|
||||
]);
|
||||
}
|
||||
|
||||
public function setSuperAdmin(Request $request)
|
||||
{
|
||||
if (!$this->superAdminExists())
|
||||
{
|
||||
$userId = false;
|
||||
$user = User::where('email', $request->email)->orWhere('phone', $request->phone);
|
||||
if ($user->count() == 1)
|
||||
{
|
||||
$user = $user->first();
|
||||
$userId = $user->id;
|
||||
}
|
||||
elseif ($user->count() > 1)
|
||||
{
|
||||
return to_route('admin.index');
|
||||
}
|
||||
else
|
||||
{
|
||||
$user = User::create($request->all());
|
||||
$userId = $user->id;
|
||||
$user->setForcedPassword();
|
||||
}
|
||||
UserRole::create([
|
||||
'user_id' => $userId,
|
||||
'role_id' => Role::SUPER_ADMIN
|
||||
]);
|
||||
}
|
||||
return to_route('admin.index');
|
||||
}
|
||||
}
|
||||
83
app/Modules/Admin/Http/Controllers/AdminPostsController.php
Normal file
83
app/Modules/Admin/Http/Controllers/AdminPostsController.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\Http\Controllers;
|
||||
|
||||
use Modules\Post\Models\Post;
|
||||
use Modules\Post\Models\PostCategory;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class AdminPostsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$posts = Post::orderBy('id', 'desc')->get();
|
||||
return view('admin::posts.index', [
|
||||
'posts' => $posts
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('admin::posts.create', [
|
||||
'categories' => PostCategory::cases()
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'required',
|
||||
'category' => 'required',
|
||||
'short_text' => 'max:500',
|
||||
'text' => 'required',
|
||||
'imageFile' => 'required|mimes:jpg,bmp,png'
|
||||
]);
|
||||
$path = $request->file('imageFile')->store('posts', ['disk' => 'public']);
|
||||
$request['image'] = $path;
|
||||
$post = Post::create(
|
||||
$request->only(['name', 'short_text', 'text', 'category', 'image'])
|
||||
);
|
||||
return to_route('admin.posts');
|
||||
}
|
||||
|
||||
public function edit(Post $post)
|
||||
{
|
||||
return view('admin::posts.edit', [
|
||||
'categories' => PostCategory::cases(),
|
||||
'post' => $post
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Request $request, Post $post)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'required',
|
||||
'category' => 'required',
|
||||
'short_text' => 'max:500',
|
||||
'text' => 'required',
|
||||
]);
|
||||
|
||||
if ($request->file('imageFile'))
|
||||
{
|
||||
$path = $request->file('imageFile')->store('posts', ['disk' => 'public']);
|
||||
$request['image'] = $path;
|
||||
}
|
||||
else
|
||||
{
|
||||
$reuqest['image'] = $post->image;
|
||||
}
|
||||
$post = $post->update(
|
||||
$request->only(['name', 'short_text', 'text', 'category', 'image'])
|
||||
);
|
||||
return to_route('admin.posts');
|
||||
}
|
||||
|
||||
public function delete(Post $post)
|
||||
{
|
||||
$post->delete();
|
||||
return to_route('admin.posts');
|
||||
}
|
||||
}
|
||||
25
app/Modules/Admin/Http/Livewire/AdminMenu.php
Normal file
25
app/Modules/Admin/Http/Livewire/AdminMenu.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\Http\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
|
||||
use App\Models\User\UserRole;
|
||||
use App\Models\User\Role;
|
||||
|
||||
class AdminMenu extends Component
|
||||
{
|
||||
public $userId;
|
||||
public function mount()
|
||||
{
|
||||
$this->userId = auth()->user()->id;
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
return view('admin::menu.index', [
|
||||
'userRoles' => UserRole::where('user_id', $this->userId)->pluck('role_id')->toArray(),
|
||||
'roles' => Role::class
|
||||
]);
|
||||
}
|
||||
}
|
||||
27
app/Modules/Admin/Http/Livewire/Posts.php
Normal file
27
app/Modules/Admin/Http/Livewire/Posts.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\Http\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
use Modules\Post\Models\Post;
|
||||
class Posts extends Component
|
||||
{
|
||||
public $userId;
|
||||
public function mount()
|
||||
{
|
||||
$this->userId = auth()->user()->id;
|
||||
}
|
||||
|
||||
public function open($id)
|
||||
{
|
||||
$this->dispatch('showPostCardInModal', id: $id);
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
$posts = Post::all();
|
||||
return view('admin::posts.list', [
|
||||
'posts' => $posts
|
||||
]);
|
||||
}
|
||||
}
|
||||
11
app/Modules/Admin/Models/Admin.php
Normal file
11
app/Modules/Admin/Models/Admin.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Admin\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Admin extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
||||
72
app/Modules/Admin/Providers/ModuleServiceProvider.php
Normal file
72
app/Modules/Admin/Providers/ModuleServiceProvider.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Livewire\Livewire;
|
||||
|
||||
class ModuleServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected string $moduleName = 'Admin';
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
}
|
||||
|
||||
public function boot()
|
||||
{
|
||||
$this->registerViews();
|
||||
$this->registerLivewireViews();
|
||||
$this->registerMigrations();
|
||||
$this->registerConfig();
|
||||
$this->registerComponent();
|
||||
$this->registerLivewire();
|
||||
}
|
||||
|
||||
protected function registerViews()
|
||||
{
|
||||
$moduleViewsPath = __DIR__ . '/../Views';
|
||||
$this->loadViewsFrom(
|
||||
$moduleViewsPath,
|
||||
strtolower($this->moduleName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerLivewireViews()
|
||||
{
|
||||
$moduleViewsPath = __DIR__ . '/../Views/livewire';
|
||||
$this->loadViewsFrom(
|
||||
$moduleViewsPath,
|
||||
strtolower($this->moduleName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerMigrations()
|
||||
{
|
||||
$this->loadMigrationsFrom(
|
||||
app_path('Modules/' . $this->moduleName . '/Database/Migrations')
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerConfig()
|
||||
{
|
||||
$path = app_path('Modules/' . $this->moduleName . '/Config/config.php');
|
||||
$this->mergeConfigFrom(
|
||||
$path,
|
||||
strtolower($this->moduleName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerLivewire()
|
||||
{
|
||||
Livewire::component('admin.menu', \Modules\Admin\Http\Livewire\AdminMenu::class);
|
||||
Livewire::component('admin.posts', \Modules\Admin\Http\Livewire\Posts::class);
|
||||
}
|
||||
|
||||
protected function registerComponent()
|
||||
{
|
||||
//Blade::component('<name>', \Modules\<NAME>\Http\Components\<NAME>::class);
|
||||
}
|
||||
}
|
||||
24
app/Modules/Admin/Providers/RouteServiceProvider.php
Normal file
24
app/Modules/Admin/Providers/RouteServiceProvider.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
public function map()
|
||||
{
|
||||
$this->registerWebRoutes();
|
||||
}
|
||||
|
||||
protected function registerWebRoutes()
|
||||
{
|
||||
//Add Web Routes with web Guard
|
||||
Route::middleware('web')
|
||||
//Set Default Controllers Namespace
|
||||
->namespace('Modules\\Admin\\Http\\Controllers')
|
||||
->group(app_path('Modules/Admin/Routes/web.php'));
|
||||
}
|
||||
}
|
||||
26
app/Modules/Admin/Routes/web.php
Normal file
26
app/Modules/Admin/Routes/web.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\Admin\Http\Controllers\AdminController;
|
||||
|
||||
Route::middleware(['auth'])->group(function ()
|
||||
{
|
||||
|
||||
Route::get('/admin', [AdminController::class, 'index']);
|
||||
|
||||
Route::middleware(['hasAccess'])->group(function ()
|
||||
{
|
||||
/** Routes that need to be protected - Маршруты которые нужно защитить */
|
||||
});
|
||||
Route::post('/admin/set', [Modules\Admin\Http\Controllers\AdminController::class, 'setSuperAdmin'])->name('admin.setSuperAdmin');
|
||||
|
||||
|
||||
Route::get('/admin', [Modules\Admin\Http\Controllers\AdminController::class, 'index'])->name('admin.index');
|
||||
Route::get('/admin/posts', [Modules\Admin\Http\Controllers\AdminPostsController::class, 'index'])->name('admin.posts');
|
||||
Route::get('/admin/posts/create', [Modules\Admin\Http\Controllers\AdminPostsController::class, 'create'])->name('admin.posts.create');
|
||||
Route::post('/admin/posts/store', [Modules\Admin\Http\Controllers\AdminPostsController::class, 'store'])->name('admin.posts.store');
|
||||
Route::get('/admin/post/{post}/edit', [Modules\Admin\Http\Controllers\AdminPostsController::class, 'edit'])->name('admin.posts.edit');
|
||||
Route::post('/admin/post/{post}/update', [Modules\Admin\Http\Controllers\AdminPostsController::class, 'update'])->name('admin.posts.update');
|
||||
Route::post('/admin/post/{post}/delete', [Modules\Admin\Http\Controllers\AdminPostsController::class, 'delete'])->name('admin.posts.delete');
|
||||
|
||||
});
|
||||
4
app/Modules/Admin/Views/index.blade.php
Normal file
4
app/Modules/Admin/Views/index.blade.php
Normal file
@ -0,0 +1,4 @@
|
||||
@extends('layouts.admin')
|
||||
@section('content')
|
||||
<h1>Дашборд</h1>
|
||||
@endsection
|
||||
44
app/Modules/Admin/Views/menu/index.blade.php
Normal file
44
app/Modules/Admin/Views/menu/index.blade.php
Normal file
@ -0,0 +1,44 @@
|
||||
<div>
|
||||
@if (in_array($roles::SUPER_ADMIN, $userRoles))
|
||||
<ul class="nav flex flex-md-column ">
|
||||
<li>
|
||||
<h6 class="dropdown-header text-uppercase">Основное</h6>
|
||||
</li>
|
||||
<li class="nav-item text-center m-2"><a
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
href="{{ route('admin.posts') }}">Новости</a>
|
||||
</li>
|
||||
<li class="nav-item text-center m-2"><a
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
href="#">Объекты</a></li>
|
||||
<li>
|
||||
<h6 class="dropdown-header text-uppercase">Пользователи</h6>
|
||||
</li>
|
||||
<li class="nav-item text-center m-2"><a
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
href="#">Роли</a></li>
|
||||
<li class="nav-item text-center m-2"><a
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
href="#">Список</a>
|
||||
</li>
|
||||
<li>
|
||||
<h6 class="dropdown-header text-uppercase">Справочники</h6>
|
||||
</li>
|
||||
<li class="nav-item text-center m-2"><a
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
href="#">Города</a></li>
|
||||
<li class="nav-item text-center m-2"><a
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active" href="#">ЖК</a>
|
||||
</li>
|
||||
<li>
|
||||
<h6 class="dropdown-header text-uppercase">Агентства</h6>
|
||||
</li>
|
||||
<li class="nav-item text-center m-2"><a
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
href="#">Организации</a></li>
|
||||
<li class="nav-item text-center m-2"><a
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
href="#">Вознаграждения</a></li>
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
53
app/Modules/Admin/Views/posts/create.blade.php
Normal file
53
app/Modules/Admin/Views/posts/create.blade.php
Normal file
@ -0,0 +1,53 @@
|
||||
@extends('layouts.admin')
|
||||
@section('content')
|
||||
<link rel="stylesheet" type="text/css" href="https://unpkg.com/trix@2.0.8/dist/trix.css">
|
||||
<script type="text/javascript" src="https://unpkg.com/trix@2.0.8/dist/trix.umd.min.js"></script>
|
||||
|
||||
<h4 class="fw-bold">Добавить новость</h4>
|
||||
<form action="{{ route('admin.posts.store') }}" method="post" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label for="titleFormControlTextarea" class="form-label">Заголовок</label>
|
||||
<textarea class="form-control" id="titleFormControlTextarea1" name="name" rows="2"></textarea>
|
||||
@error('name')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 mb-3">
|
||||
<label for="categoryFormControlSelect" class="form-label">Категория</label>
|
||||
<select class="form-select" id="categoryFormControlSelect" name="category" aria-label="">
|
||||
@foreach ($categories as $category)
|
||||
<option value="{{ $category->value }}">{{ __($category->name) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('category')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col-6 mb-3">
|
||||
<label for="formFile" class="form-label">Заставка новости</label>
|
||||
<input class="form-control" type="file" id="formFile" name="imageFile">
|
||||
@error('imageFile')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="shortTextFormControlTextarea" class="form-label">Анонс</label>
|
||||
<textarea class="form-control" id="shortTextFormControlTextarea1" name="short_text" rows="3"></textarea>
|
||||
@error('short_text')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="shortTextFormControlTextarea" class="form-label">Основной текст</label>
|
||||
<textarea class="form-control d-none" id="textFormControlTextarea" name="text" rows="15"></textarea>
|
||||
<trix-editor input="textFormControlTextarea" class="overflow-auto" style="height:300px"></trix-editor>
|
||||
@error('text')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||||
</form>
|
||||
@endsection
|
||||
54
app/Modules/Admin/Views/posts/edit.blade.php
Normal file
54
app/Modules/Admin/Views/posts/edit.blade.php
Normal file
@ -0,0 +1,54 @@
|
||||
@extends('layouts.admin')
|
||||
@section('content')
|
||||
<link rel="stylesheet" type="text/css" href="https://unpkg.com/trix@2.0.8/dist/trix.css">
|
||||
<script type="text/javascript" src="https://unpkg.com/trix@2.0.8/dist/trix.umd.min.js"></script>
|
||||
|
||||
<h4 class="fw-bold">Добавить новость</h4>
|
||||
<form action="{{ route('admin.posts.update', ['post' => $post]) }}" method="post" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label for="titleFormControlTextarea" class="form-label">Заголовок</label>
|
||||
<textarea class="form-control" id="titleFormControlTextarea1" name="name" rows="2">{{ $post->name }}</textarea>
|
||||
@error('name')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col mb-3">
|
||||
<label for="categoryFormControlSelect" class="form-label">Категория</label>
|
||||
<select class="form-select" id="categoryFormControlSelect" name="category" aria-label="">
|
||||
@foreach ($categories as $category)
|
||||
<option value="{{ $category->value }}" {{ $post->category == $category->value ? 'selected' : '' }}>
|
||||
{{ __($category->name) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('category')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col mb-3">
|
||||
<label for="formFile" class="form-label">Заставка новости</label>
|
||||
<input class="form-control" type="file" id="formFile" name="imageFile">
|
||||
@error('imageFile')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="shortTextFormControlTextarea" class="form-label">Анонс</label>
|
||||
<textarea class="form-control" id="shortTextFormControlTextarea1" name="short_text" rows="3">{{ $post->short_text }}</textarea>
|
||||
@error('short_text')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="shortTextFormControlTextarea" class="form-label">Основной текст</label>
|
||||
<textarea class="form-control d-none" id="textFormControlTextarea" name="text" rows="15">{{ $post->text }}</textarea>
|
||||
<trix-editor input="textFormControlTextarea" class="overflow-auto" style="height:300px"></trix-editor>
|
||||
@error('text')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||||
</form>
|
||||
@endsection
|
||||
14
app/Modules/Admin/Views/posts/index.blade.php
Normal file
14
app/Modules/Admin/Views/posts/index.blade.php
Normal file
@ -0,0 +1,14 @@
|
||||
@extends('layouts.admin')
|
||||
@section('content')
|
||||
<form class="d-flex mb-3" method="GET" action="{{ route('company.agents.table') }}">
|
||||
|
||||
|
||||
<div class="ms-auto p-2">
|
||||
<a type="button" class="btn btn-primary py-2 px-3 fs-5" href="{{ route('admin.posts.create') }}">
|
||||
<i class="bi bi-postcard"></i>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@livewire('admin.posts')
|
||||
@endsection
|
||||
53
app/Modules/Admin/Views/posts/list.blade.php
Normal file
53
app/Modules/Admin/Views/posts/list.blade.php
Normal file
@ -0,0 +1,53 @@
|
||||
<div>
|
||||
@if ($posts->count() == 0)
|
||||
<div class="text-center py-5">Нет данных для отображения</div>
|
||||
@else
|
||||
<div class="fs-5 bg-light p-0 m-0 border border-1 rounded-4">
|
||||
<table class="table m-0">
|
||||
<thead>
|
||||
<tr scope="col">
|
||||
<th>ID
|
||||
<th>Название
|
||||
<th>Дата создания
|
||||
<th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class=" ">
|
||||
@foreach ($posts as $post)
|
||||
<tr scope="row">
|
||||
<td class="fw-semibold fs-5 align-middle">
|
||||
{{ $post->id }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{{ $post->name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $post->created_at->diffForHumans() }}
|
||||
</td>
|
||||
<td>
|
||||
<div class="dropdown" style="">
|
||||
<button class="btn btn-light" type="button" id="dropdownMenuButton"
|
||||
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="bi bi-three-dots-vertical"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
<a class="dropdown-item" wire:click="open({{ $post->id }})"
|
||||
target="_blank">Открыть</a>
|
||||
<a class="dropdown-item"
|
||||
href="{{ route('admin.posts.edit', ['post' => $post]) }}">Редактировать</a>
|
||||
<form method="post"
|
||||
action="{{ route('admin.posts.delete', ['post' => $post]) }}">
|
||||
@csrf
|
||||
<button class="dropdown-item" type="submit">Удалить</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
@livewire('post.card')
|
||||
</div>
|
||||
29
app/Modules/Admin/Views/setAdmin/index.blade.php
Normal file
29
app/Modules/Admin/Views/setAdmin/index.blade.php
Normal file
@ -0,0 +1,29 @@
|
||||
@extends('layouts.admin')
|
||||
@section('content')
|
||||
<h1>Установить глобального администратора</h1>
|
||||
<form action="{{ route('admin.setSuperAdmin') }}" method="post">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label for="titleFormControlTextarea" class="form-label">ФИО</label>
|
||||
<input type="text" class="form-control" id="titleFormControlTextarea1" name="name" rows="2">
|
||||
@error('name')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="titleFormControlTextarea" class="form-label">Email</label>
|
||||
<input type="text" class="form-control" id="titleFormControlTextarea1" name="email" rows="2">
|
||||
@error('name')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="titleFormControlTextarea" class="form-label">Телефон</label>
|
||||
<input type="text" class="form-control" id="titleFormControlTextarea1" name="phone" rows="2">
|
||||
@error('name')
|
||||
<div class="text-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Создать администратора</button>
|
||||
</form>
|
||||
@endsection
|
||||
5
app/Modules/Post/Config/config.php
Normal file
5
app/Modules/Post/Config/config.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
];
|
||||
@ -0,0 +1,33 @@
|
||||
<?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('posts', function (Blueprint $table)
|
||||
{
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->text('short_text');
|
||||
$table->text('text');
|
||||
$table->string('image');
|
||||
$table->enum('category', ['News', 'Projects', 'Credits', 'Sale'])->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('news');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,30 @@
|
||||
<?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('post_cities', function (Blueprint $table)
|
||||
{
|
||||
$table->id();
|
||||
$table->foreignId('post_id')->references('id')->on('posts')->onDelete('cascade');
|
||||
$table->foreignId('city_id')->references('id')->on('cities')->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('news');
|
||||
}
|
||||
};
|
||||
20
app/Modules/Post/Http/Controllers/PostController.php
Normal file
20
app/Modules/Post/Http/Controllers/PostController.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Post\Http\Controllers;
|
||||
|
||||
use Modules\Post\Models\Post;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PostController extends Controller
|
||||
{
|
||||
public function open(Post $post)
|
||||
{
|
||||
return view('post::list.card', [
|
||||
'post' => $post
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
51
app/Modules/Post/Http/Livewire/PostCard.php
Normal file
51
app/Modules/Post/Http/Livewire/PostCard.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Post\Http\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\On;
|
||||
use Modules\Post\Models\Post;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
class PostCard extends Component
|
||||
{
|
||||
public $id;
|
||||
public function mount($id = false)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
#[On('showPostCardInModal')]
|
||||
public function open($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
$this->id = null;
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
if ($this->id)
|
||||
{
|
||||
$post = Post::find($this->id);
|
||||
if (Storage::disk('public')->exists($post->image))
|
||||
{
|
||||
$post->image = Storage::url($post->image);
|
||||
}
|
||||
else
|
||||
{
|
||||
$post->image = false;
|
||||
}
|
||||
return view('post::list.card', [
|
||||
'post' => $post
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return view('post::list.card', [
|
||||
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
app/Modules/Post/Http/Livewire/PostsList.php
Normal file
30
app/Modules/Post/Http/Livewire/PostsList.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Post\Http\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
use Modules\Post\Models\Post;
|
||||
|
||||
class PostsList extends Component
|
||||
{
|
||||
public $count;
|
||||
public $filter;
|
||||
public function mount()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function open($id)
|
||||
{
|
||||
$this->dispatch('showPostCardInModal', id: $id);
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
$posts = Post::all();
|
||||
return view('post::list.cards', [
|
||||
'posts' => $posts
|
||||
]);
|
||||
}
|
||||
}
|
||||
18
app/Modules/Post/Models/Post.php
Normal file
18
app/Modules/Post/Models/Post.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Post\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
class Post extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'short_text',
|
||||
'text',
|
||||
'category',
|
||||
'image'
|
||||
];
|
||||
}
|
||||
9
app/Modules/Post/Models/PostCategory.php
Normal file
9
app/Modules/Post/Models/PostCategory.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Modules\Post\Models;
|
||||
enum PostCategory: string
|
||||
{
|
||||
case News = "News";
|
||||
case Projects = "Projects";
|
||||
case Credits = "Credits";
|
||||
case Sale = 'Sale';
|
||||
}
|
||||
73
app/Modules/Post/Providers/ModuleServiceProvider.php
Normal file
73
app/Modules/Post/Providers/ModuleServiceProvider.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Post\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Livewire\Livewire;
|
||||
|
||||
class ModuleServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected string $moduleName = 'Post';
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
}
|
||||
|
||||
public function boot()
|
||||
{
|
||||
$this->registerViews();
|
||||
$this->registerLivewireViews();
|
||||
$this->registerMigrations();
|
||||
$this->registerConfig();
|
||||
$this->registerComponent();
|
||||
$this->registerLivewire();
|
||||
}
|
||||
|
||||
protected function registerViews()
|
||||
{
|
||||
$moduleViewsPath = __DIR__ . '/../Views';
|
||||
$this->loadViewsFrom(
|
||||
$moduleViewsPath,
|
||||
strtolower($this->moduleName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerLivewireViews()
|
||||
{
|
||||
$moduleViewsPath = __DIR__ . '/../Views/livewire';
|
||||
$this->loadViewsFrom(
|
||||
$moduleViewsPath,
|
||||
strtolower($this->moduleName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerMigrations()
|
||||
{
|
||||
$this->loadMigrationsFrom(
|
||||
app_path('Modules/' . $this->moduleName . '/Database/Migrations')
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerConfig()
|
||||
{
|
||||
$path = app_path('Modules/' . $this->moduleName . '/Config/config.php');
|
||||
$this->mergeConfigFrom(
|
||||
$path,
|
||||
strtolower($this->moduleName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerLivewire()
|
||||
{
|
||||
Livewire::component('posts.list', \Modules\Post\Http\Livewire\PostsList::class);
|
||||
Livewire::component('post.card', \Modules\Post\Http\Livewire\PostCard::class);
|
||||
|
||||
}
|
||||
|
||||
protected function registerComponent()
|
||||
{
|
||||
//Blade::component('<name>', \Modules\<NAME>\Http\Components\<NAME>::class);
|
||||
}
|
||||
}
|
||||
24
app/Modules/Post/Providers/RouteServiceProvider.php
Normal file
24
app/Modules/Post/Providers/RouteServiceProvider.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Post\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
public function map()
|
||||
{
|
||||
$this->registerWebRoutes();
|
||||
}
|
||||
|
||||
protected function registerWebRoutes()
|
||||
{
|
||||
//Add Web Routes with web Guard
|
||||
Route::middleware('web')
|
||||
//Set Default Controllers Namespace
|
||||
->namespace('Modules\\Post\\Http\\Controllers')
|
||||
->group(app_path('Modules/Post/Routes/web.php'));
|
||||
}
|
||||
}
|
||||
11
app/Modules/Post/Routes/web.php
Normal file
11
app/Modules/Post/Routes/web.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::middleware(['auth'])->group(function ()
|
||||
{
|
||||
|
||||
Route::get('/post/{post}', [Modules\Post\Http\Controllers\PostController::class, 'open'])->name('post.open');
|
||||
|
||||
|
||||
});
|
||||
4
app/Modules/Post/Views/index.blade.php
Normal file
4
app/Modules/Post/Views/index.blade.php
Normal file
@ -0,0 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@section('content')
|
||||
<h1> Example views </h1>
|
||||
@endsection
|
||||
31
app/Modules/Post/Views/list/card.blade.php
Normal file
31
app/Modules/Post/Views/list/card.blade.php
Normal file
@ -0,0 +1,31 @@
|
||||
<div>
|
||||
@isset($post)
|
||||
<div class="modal fade show d-block bg-dark" style="--bs-bg-opacity: .5;" id="postCardModal" data-bs-backdrop="static"
|
||||
data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-fullscreen-lg-down">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"
|
||||
wire:click="close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@if ($post->image)
|
||||
<div class="w-100"
|
||||
style="
|
||||
height:250px;
|
||||
background-image:url('{{ $post->image }}');
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover; ">
|
||||
</div>
|
||||
@endif
|
||||
<h1 class="mt-3">{{ $post->name }}</h1>
|
||||
<p>
|
||||
{!! $post->text !!}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endisset
|
||||
</div>
|
||||
28
app/Modules/Post/Views/list/cards.blade.php
Normal file
28
app/Modules/Post/Views/list/cards.blade.php
Normal file
@ -0,0 +1,28 @@
|
||||
<div class="d-lg-flex row g-3">
|
||||
@foreach ($posts as $post)
|
||||
<div class="col-4 m-0 p-2" style="">
|
||||
<div class="flex-fill placeholder-glow bg-white card">
|
||||
<div class="row g-0 h-100">
|
||||
<div class="col-md-6">
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<span
|
||||
class="badge bg-body-secondary text-dark border-secondary bg-opacity-75 fs-6 rounded-pill">{{ __($post->category) }}</span>
|
||||
</div>
|
||||
<h3 class="card-title fs-4">{{ $post->name }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 bg-secondary bg-opacity-50 rounded-end"
|
||||
style="height:200px;background-image:url('{{ url('/storage/' . $post->image) }}')">
|
||||
<a href="#" class="btn btn-light btn-lg rounded-4 position-absolute bottom-0 end-0 m-3"
|
||||
wire:click="open({{ $post->id }})">
|
||||
<i class="bi bi-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
@livewire('post.card')
|
||||
</div>
|
||||
@ -5,22 +5,40 @@
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
|
||||
//$this->app->register('\\Modules\\Post\\Providers\\ModuleServiceProvider');
|
||||
|
||||
//Поиск модулей
|
||||
$modulesBasePath = app_path('Modules');
|
||||
foreach (File::directories($modulesBasePath) as $moduleDirectory)
|
||||
{
|
||||
//
|
||||
//Получить имя модуля из имени каталога
|
||||
$moduleName = basename($moduleDirectory);
|
||||
$providerClassName = '\\Modules\\' . $moduleName . '\\Providers\\ModuleServiceProvider';
|
||||
if (class_exists($providerClassName))
|
||||
{
|
||||
//Зарегистрировать поставщика услуг модуля, если он существует
|
||||
$this->app->register($providerClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
{
|
||||
Paginator::useBootstrapFive();
|
||||
Paginator::useBootstrapFour();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,10 @@
|
||||
"name": "laravel/laravel",
|
||||
"type": "project",
|
||||
"description": "The skeleton application for the Laravel framework.",
|
||||
"keywords": ["laravel", "framework"],
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"framework"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
@ -27,7 +30,8 @@
|
||||
"psr-4": {
|
||||
"App\\": "app/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
"Database\\Seeders\\": "database/seeders/",
|
||||
"Modules\\": "app/Modules/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
@ -66,4 +70,4 @@
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
}
|
||||
}
|
||||
691
composer.lock
generated
691
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -28,32 +28,32 @@
|
||||
|
|
||||
*/
|
||||
|
||||
'disks' => [
|
||||
'disks' => [
|
||||
|
||||
'local' => [
|
||||
'local' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app'),
|
||||
'throw' => false,
|
||||
'root' => storage_path('app'),
|
||||
'throw' => false,
|
||||
],
|
||||
|
||||
'public' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/public'),
|
||||
'url' => env('APP_URL').'/storage',
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/public'),
|
||||
'url' => env('APP_URL') . '/storage/app',
|
||||
'visibility' => 'public',
|
||||
'throw' => false,
|
||||
'throw' => false,
|
||||
],
|
||||
|
||||
's3' => [
|
||||
'driver' => 's3',
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION'),
|
||||
'bucket' => env('AWS_BUCKET'),
|
||||
'url' => env('AWS_URL'),
|
||||
'endpoint' => env('AWS_ENDPOINT'),
|
||||
's3' => [
|
||||
'driver' => 's3',
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION'),
|
||||
'bucket' => env('AWS_BUCKET'),
|
||||
'url' => env('AWS_URL'),
|
||||
'endpoint' => env('AWS_ENDPOINT'),
|
||||
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
|
||||
'throw' => false,
|
||||
'throw' => false,
|
||||
],
|
||||
|
||||
],
|
||||
@ -69,9 +69,9 @@
|
||||
|
|
||||
*/
|
||||
|
||||
'links' => [
|
||||
'links' => [
|
||||
public_path('storage') => storage_path('app/public'),
|
||||
public_path('lk') => storage_path('public'),
|
||||
public_path('lk') => storage_path('public'),
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@ -32,5 +32,9 @@
|
||||
"SoleProperty name": "ФИО полностью",
|
||||
"contract status new": "Новый",
|
||||
"Agent was created": "Создана новая учетная запись агента",
|
||||
"Your account was attached as agent": "Ваша учетная запись была привязана в качестве агента в"
|
||||
"Your account was attached as agent": "Ваша учетная запись была привязана в качестве агента в",
|
||||
"Credits": "Ипотека",
|
||||
"News": "Новости",
|
||||
"Projects": "Проекты",
|
||||
"Sale": "Акции"
|
||||
}
|
||||
25
package-lock.json
generated
25
package-lock.json
generated
@ -4,7 +4,9 @@
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "lk.zachem.info",
|
||||
"dependencies": {
|
||||
"@editorjs/editorjs": "^2.30.8",
|
||||
"bootstrap": "^5.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -16,6 +18,11 @@
|
||||
"vite": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@editorjs/editorjs": {
|
||||
"version": "2.30.8",
|
||||
"resolved": "https://registry.npmjs.org/@editorjs/editorjs/-/editorjs-2.30.8.tgz",
|
||||
"integrity": "sha512-ClFuxI1qZTfXPJTacQfsJtOUP6bKoIe6BQNdAvGsDTDVwMnZEzoaSOwvUpdZEE56xppVfQueNK/1MElV9SJKHg=="
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
|
||||
@ -888,9 +895,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
|
||||
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
|
||||
"version": "1.8.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
|
||||
"integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
@ -1165,9 +1172,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.7",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
||||
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -1328,9 +1335,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.4.10",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz",
|
||||
"integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==",
|
||||
"version": "5.4.17",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.17.tgz",
|
||||
"integrity": "sha512-5+VqZryDj4wgCs55o9Lp+p8GE78TLVg0lasCH5xFZ4jacZjtqZa6JUw9/p0WeAojaOfncSM6v77InkFPGnvPvg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.21.3",
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
"vite": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@editorjs/editorjs": "^2.30.8",
|
||||
"bootstrap": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
||||
1
public/lk
Symbolic link
1
public/lk
Symbolic link
@ -0,0 +1 @@
|
||||
/home/thekindbull/Рабочий стол/laravel_projects/gitea_alfa/lk.zachem.info/storage/public
|
||||
@ -1 +1 @@
|
||||
import './bootstrap';
|
||||
import './bootstrap'
|
||||
5
resources/stubs/config.stub
Normal file
5
resources/stubs/config.stub
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
];
|
||||
17
resources/stubs/controller.model.stub
Normal file
17
resources/stubs/controller.model.stub
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace TeamplateNamespace;
|
||||
|
||||
use TeamplateFullModelClass;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TeamplateClass extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('TeamplateDirectoryName::index');
|
||||
}
|
||||
}
|
||||
68
resources/stubs/module_service_provider.stub
Normal file
68
resources/stubs/module_service_provider.stub
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\TeamplateDirectoryName\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Livewire\Livewire;
|
||||
|
||||
class ModuleServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected String $moduleName = 'TeamplateDirectoryName';
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
}
|
||||
|
||||
public function boot()
|
||||
{
|
||||
$this->registerViews();
|
||||
$this->registerLivewireViews();
|
||||
$this->registerMigrations();
|
||||
$this->registerConfig();
|
||||
$this->registerComponent();
|
||||
$this->registerLivewire();
|
||||
}
|
||||
|
||||
protected function registerViews()
|
||||
{
|
||||
$moduleViewsPath = __DIR__.'/../Views';
|
||||
$this->loadViewsFrom(
|
||||
$moduleViewsPath, strtolower($this->moduleName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerLivewireViews()
|
||||
{
|
||||
$moduleViewsPath = __DIR__.'/../Views/livewire';
|
||||
$this->loadViewsFrom(
|
||||
$moduleViewsPath, strtolower($this->moduleName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerMigrations()
|
||||
{
|
||||
$this->loadMigrationsFrom(
|
||||
app_path('Modules/'.$this->moduleName.'/Database/Migrations')
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerConfig()
|
||||
{
|
||||
$path = app_path('Modules/'.$this->moduleName.'/Config/config.php');
|
||||
$this->mergeConfigFrom(
|
||||
$path, strtolower($this->moduleName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function registerLivewire()
|
||||
{
|
||||
//Livewire::component('<name>', \Modules\<NAME>\Http\Livewire\<NAME>::class);
|
||||
}
|
||||
|
||||
protected function registerComponent()
|
||||
{
|
||||
//Blade::component('<name>', \Modules\<NAME>\Http\Components\<NAME>::class);
|
||||
}
|
||||
}
|
||||
24
resources/stubs/route_service_provider.stub
Normal file
24
resources/stubs/route_service_provider.stub
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\TeamplateDirectoryName\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
public function map()
|
||||
{
|
||||
$this->registerWebRoutes();
|
||||
}
|
||||
|
||||
protected function registerWebRoutes()
|
||||
{
|
||||
//Add Web Routes with web Guard
|
||||
Route::middleware('web')
|
||||
//Set Default Controllers Namespace
|
||||
->namespace('Modules\\TeamplateDirectoryName\\Http\\Controllers')
|
||||
->group(app_path('Modules/TeamplateDirectoryName/Routes/web.php'));
|
||||
}
|
||||
}
|
||||
13
resources/stubs/routes.web.stub
Normal file
13
resources/stubs/routes.web.stub
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\TeamplateDirectoryName\Http\Controllers\TeamplateClass;
|
||||
|
||||
Route::middleware(['auth'])->group(function() {
|
||||
|
||||
Route::get('/TeamplateRoutePrefix', [TeamplateClass::class, 'index']);
|
||||
|
||||
Route::middleware(['hasAccess'])->group(function() {
|
||||
/** Routes that need to be protected - Маршруты которые нужно защитить */
|
||||
});
|
||||
});
|
||||
4
resources/stubs/view.stub
Normal file
4
resources/stubs/view.stub
Normal file
@ -0,0 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@section('content')
|
||||
<h1> Example views </h1>
|
||||
@endsection
|
||||
103
resources/views/layouts/admin.blade.php
Normal file
103
resources/views/layouts/admin.blade.php
Normal file
@ -0,0 +1,103 @@
|
||||
<!doctype html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- CSRF Token -->
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
<title>{{ config('app.name', 'Laravel') }}</title>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="dns-prefetch" href="//fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
@vite(['resources/sass/app.scss', 'resources/js/app.js', 'resources/css/app.css'])
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<nav class="navbar navbar-expand-md bg-body-tertiary shadow-sm">
|
||||
<div class="container">
|
||||
<a class="navbar-brand">
|
||||
<img src={{ url('/images/logo.png') }} alt="Bootstrap" width="70">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
|
||||
aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<!-- Left Side Of Navbar -->
|
||||
<ul class="navbar-nav me-auto">
|
||||
|
||||
</ul>
|
||||
|
||||
<!-- Right Side Of Navbar -->
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<!-- Authentication Links -->
|
||||
@guest
|
||||
@if (Route::has('login'))
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if (Route::has('register'))
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
|
||||
</li>
|
||||
@endif
|
||||
@else
|
||||
<li class="nav-item dropdown">
|
||||
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button"
|
||||
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
|
||||
<img src="../../images/icons/user.png" class="img-fluid align-middle"
|
||||
style="height: 40px;">
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
|
||||
<a class="dropdown-item" href="/profile">
|
||||
Профиль
|
||||
</a>
|
||||
<a class="dropdown-item" href="{{ route('logout') }}"
|
||||
onclick="event.preventDefault();
|
||||
document.getElementById('logout-form').submit();">
|
||||
Выйти
|
||||
</a>
|
||||
|
||||
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
|
||||
@csrf
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
@endguest
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="py-4">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col col-sm-2" id="leftPanel">
|
||||
@livewire('admin.menu')
|
||||
</div>
|
||||
<div class="col-10 px-0 px-md-4">
|
||||
@foreach ($errors->all() as $error)
|
||||
{{ $error }}
|
||||
@endforeach
|
||||
@yield('content')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,45 +1 @@
|
||||
<livewire:mainMenu />
|
||||
<!--
|
||||
<ul class="nav flex flex-md-column ">
|
||||
<li class="nav-item text-center m-2">
|
||||
<a href="{{ route('home') }}" class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
aria-current="page">
|
||||
<i class="bi bi-columns-gap"></i> <span class="d-none d-lg-inline text-truncate">Главная</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item text-center m-2">
|
||||
<a href="{{ route('clients.table') }}"
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active" aria-current="page">
|
||||
<i class="bi bi-person"></i> <span class="d-none d-lg-inline">Клиенты</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item text-center m-2">
|
||||
<a href="/projects" class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
aria-current="page">
|
||||
<i class="bi bi-book"></i> <span class="d-none d-lg-inline">Проекты</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item text-center m-2">
|
||||
<a href="/news" class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active"
|
||||
aria-current="page">
|
||||
<i class="bi bi-layers"></i> <span class="d-none d-lg-inline">Новости</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item text-center m-2">
|
||||
<a href="{{ route('company.agents.table') }}"
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active" aria-current="page">
|
||||
<i class="bi bi-people"></i> <span class="d-none d-lg-inline">Агенты</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item text-center m-2">
|
||||
<a href="{{ route('company.details') }}"
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active" aria-current="page">
|
||||
<i class="bi bi-gear"></i> <span class="d-none d-lg-inline">Настройки</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
-->
|
||||
@livewire('mainMenu')
|
||||
|
||||
@ -51,6 +51,15 @@ class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active" ar
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if (in_array($roles::SUPER_ADMIN, $userRoles))
|
||||
<li class="nav-item text-center m-2">
|
||||
<a href="{{ route('admin.index') }}"
|
||||
class="nav-link d-flex align-items-center gap-2 fs-5 border rounded-4 active" aria-current="page">
|
||||
<i class="bi bi-gear11"></i> <span class="d-none d-lg-inline">Админка</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
@ -45,65 +45,7 @@ class="list-group-item list-group-item-action p-3 bg-white rounded border border
|
||||
<div class="fs-5 fw-bold">Новости</div>
|
||||
<div class="ms-auto p-2">Смотреть все</div>
|
||||
</div>
|
||||
<div class="d-lg-flex">
|
||||
<div class="flex-fill card mb-3 placeholder-glow m-2 bg-white" style="min-height:200px; max-width: 540px;">
|
||||
<div class="row g-0 h-100">
|
||||
<div class="col-md-6">
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<span
|
||||
class="badge bg-body-secondary text-dark border-secondary bg-opacity-75 fs-6 rounded-pill">Акция</span>
|
||||
</div>
|
||||
<h3 class="card-title fs-4">Скидка 30% на апартаменты</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 bg-secondary bg-opacity-50 rounded-end"
|
||||
style="height:200px;background-image:url('https://img3.sibdom.ru/images/photo_crop_282_212/houses/photo_main/97/97be/97be2371dd0bba9c4605c3ea6f06e213.jpg')">
|
||||
<a href="#" class="btn btn-light btn-lg rounded-4 position-absolute bottom-0 end-0 m-3">
|
||||
<i class="bi bi-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-fill card mb-3 placeholder-glow m-2 bg-white" style="min-height:200px; max-width: 540px;">
|
||||
<div class="row g-0 h-100">
|
||||
<div class="col-md-6">
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<span
|
||||
class="badge bg-body-secondary text-dark border-secondary bg-opacity-75 fs-6 rounded-pill">Акция</span>
|
||||
</div>
|
||||
<h3 class="card-title fs-4">Скидка 30% на апартаменты</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 bg-secondary bg-opacity-50 rounded-end"
|
||||
style="height:200px;background-image:url('https://img3.sibdom.ru/images/photo_crop_282_212/houses/photo_main/97/97be/97be2371dd0bba9c4605c3ea6f06e213.jpg')">
|
||||
<a href="#" class="btn btn-light btn-lg rounded-4 position-absolute bottom-0 end-0 m-3">
|
||||
<i class="bi bi-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-fill card mb-3 placeholder-glow m-2 bg-white" style="min-height:200px; max-width: 540px;">
|
||||
<div class="row g-0 h-100">
|
||||
<div class="col-md-6">
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<span
|
||||
class="badge bg-body-secondary text-dark border-secondary bg-opacity-75 fs-6 rounded-pill">Акция</span>
|
||||
</div>
|
||||
<h3 class="card-title fs-4">Скидка 30% на апартаменты</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 bg-secondary bg-opacity-50 rounded-end"
|
||||
style="height:200px;background-image:url('https://img3.sibdom.ru/images/photo_crop_282_212/houses/photo_main/97/97be/97be2371dd0bba9c4605c3ea6f06e213.jpg')">
|
||||
<a href="#" class="btn btn-light btn-lg rounded-4 position-absolute bottom-0 end-0 m-3">
|
||||
<i class="bi bi-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@livewire(name: 'posts.list')
|
||||
</div>
|
||||
<div class="mt-3 col-12">
|
||||
<div class="d-flex">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user