first
This commit is contained in:
8
app/modules/event/EventModule.php
Normal file
8
app/modules/event/EventModule.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace app\modules\event;
|
||||
|
||||
class EventModule extends \kernel\app_modules\event\EventModule
|
||||
{
|
||||
|
||||
}
|
8
app/modules/event/controllers/EventController.php
Normal file
8
app/modules/event/controllers/EventController.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace app\modules\event\controllers;
|
||||
|
||||
class EventController extends \kernel\app_modules\event\controllers\EventController
|
||||
{
|
||||
|
||||
}
|
12
app/modules/event/manifest.json
Normal file
12
app/modules/event/manifest.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "Мероприятия",
|
||||
"version": "0.1",
|
||||
"author": "ITGuild",
|
||||
"slug": "event",
|
||||
"type": "entity",
|
||||
"description": "Мероприятия module",
|
||||
"module_class": "app\\modules\\event\\EventModule",
|
||||
"module_class_file": "{APP}/modules/event/EventModule.php",
|
||||
"routs": "routs/event.php",
|
||||
"migration_path": "migrations"
|
||||
}
|
2
app/modules/event/routs/event.php
Normal file
2
app/modules/event/routs/event.php
Normal file
@ -0,0 +1,2 @@
|
||||
<?php
|
||||
include KERNEL_APP_MODULES_DIR . "/event/routs/event.php";
|
8
app/modules/gestalt_profile/Gestalt_profileModule.php
Normal file
8
app/modules/gestalt_profile/Gestalt_profileModule.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace app\modules\gestalt_profile;
|
||||
|
||||
class Gestalt_profileModule extends \kernel\app_modules\gestalt_profile\Gestalt_profileModule
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace app\modules\gestalt_profile\controllers;
|
||||
|
||||
class Gestalt_profileController extends \kernel\app_modules\gestalt_profile\controllers\Gestalt_profileController
|
||||
{
|
||||
|
||||
}
|
11
app/modules/gestalt_profile/manifest.json
Normal file
11
app/modules/gestalt_profile/manifest.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "Профили психологов",
|
||||
"version": "0.1",
|
||||
"author": "kavalar",
|
||||
"slug": "gestalt_profile",
|
||||
"description": "Профили психологов module",
|
||||
"module_class": "app\\modules\\gestalt_profile\\Gestalt_profileModule",
|
||||
"module_class_file": "{APP}/modules/gestalt_profile/Gestalt_profileModule.php",
|
||||
"routs": "routs/gestalt_profile.php",
|
||||
"migration_path": "migrations"
|
||||
}
|
2
app/modules/gestalt_profile/routs/gestalt_profile.php
Normal file
2
app/modules/gestalt_profile/routs/gestalt_profile.php
Normal file
@ -0,0 +1,2 @@
|
||||
<?php
|
||||
include KERNEL_APP_MODULES_DIR . "/gestalt_profile/routs/gestalt_profile.php";
|
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace app\modules\gestalt_profile_relationship;
|
||||
|
||||
class Gestalt_profile_relationshipModule extends \kernel\app_modules\gestalt_profile_relationship\Gestalt_profile_relationshipModule
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace app\modules\gestalt_profile_relationship\controllers;
|
||||
|
||||
class GestaltProfileRelationshipController extends \kernel\app_modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController
|
||||
{
|
||||
|
||||
}
|
13
app/modules/gestalt_profile_relationship/manifest.json
Normal file
13
app/modules/gestalt_profile_relationship/manifest.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "Профили психологов (связь)",
|
||||
"version": "0.1",
|
||||
"author": "kavalar",
|
||||
"type": "additional_property",
|
||||
"slug": "gestalt_profile_relationship",
|
||||
"description": "Профили психологов (связь) module",
|
||||
"module_class": "app\\modules\\gestalt_profile_relationship\\Gestalt_profile_relationshipModule",
|
||||
"module_class_file": "{APP}/modules/gestalt_profile_relationship/Gestalt_profile_relationshipModule.php",
|
||||
"routs": "routs/gestalt_profile_relationship.php",
|
||||
"migration_path": "migrations",
|
||||
"dependence": "gestalt_profile"
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<?php
|
||||
include KERNEL_APP_MODULES_DIR . "/gestalt_profile_relationship/routs/gestalt_profile_relationship.php";
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\custom;
|
||||
|
||||
class CustomTheme extends \kernel\app_themes\custom\CustomTheme
|
||||
{
|
||||
|
||||
}
|
8
app/themes/custom/GestaltTheme.php
Normal file
8
app/themes/custom/GestaltTheme.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\custom;
|
||||
|
||||
class GestaltTheme extends \kernel\app_themes\custom\GestaltTheme
|
||||
{
|
||||
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
* @var string $title
|
||||
* @var \kernel\CgView $view
|
||||
*/
|
||||
$assets = new \app\themes\custom\assets\CustomThemesAssets($resources);
|
||||
$assets = new \app\themes\custom\assets\GestaltThemesAssets($resources);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
8
app/themes/gestalt/GestaltTheme.php
Normal file
8
app/themes/gestalt/GestaltTheme.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\gestalt;
|
||||
|
||||
class GestaltTheme extends \kernel\app_themes\gestalt\GestaltTheme
|
||||
{
|
||||
|
||||
}
|
18
app/themes/gestalt/assets/GestaltThemesAssets.php
Normal file
18
app/themes/gestalt/assets/GestaltThemesAssets.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\gestalt\assets;
|
||||
|
||||
use kernel\Assets;
|
||||
|
||||
class GestaltThemesAssets extends Assets
|
||||
{
|
||||
protected function createCSS(): void
|
||||
{
|
||||
$this->registerCSS(slug: "main", resource: "/out/_next/static/css/af2a5715f5fb28bf.css");
|
||||
}
|
||||
|
||||
protected function createJS(): void
|
||||
{
|
||||
$this->registerJS(slug: "webpack", resource: "/js/scripts.js");
|
||||
}
|
||||
}
|
46
app/themes/gestalt/controllers/EventController.php
Normal file
46
app/themes/gestalt/controllers/EventController.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\gestalt\controllers;
|
||||
|
||||
use kernel\app_modules\event\models\Event;
|
||||
use kernel\Controller;
|
||||
use kernel\EloquentDataProvider;
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\helpers\Url;
|
||||
use kernel\Request;
|
||||
|
||||
class EventController extends Controller
|
||||
{
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = APP_DIR . "/themes/gestalt/views/event/";
|
||||
$this->cgView->layout = "main.php";
|
||||
$this->cgView->layoutPath = APP_DIR . "/themes/gestalt/views/layout/";
|
||||
$this->cgView->addVarToLayout("resources", "/resources/themes/gestalt");
|
||||
}
|
||||
|
||||
public function actionIndex(): void
|
||||
{
|
||||
$request = new Request();
|
||||
$dataProvider = (new EloquentDataProvider(Event::query()));
|
||||
$dataProvider->setSort([
|
||||
'id' => 'desc'
|
||||
]);
|
||||
|
||||
$page = $request->get('page', 1); // или request('page', 1) для HTTP-запросов
|
||||
$events = $dataProvider->getManualPaginated($page, 2);
|
||||
|
||||
$pagination = $dataProvider->getPaginationLinks($events['meta']);
|
||||
// Debug::dd($pagination);
|
||||
$this->cgView->render("index.php", ['events' => $events, 'pagination' => $pagination]);
|
||||
}
|
||||
|
||||
public function actionView(int $id): void
|
||||
{
|
||||
$event = Event::with('contacts')->where('id', $id)->first();
|
||||
|
||||
$this->cgView->render("view.php", ['event' => $event]);
|
||||
}
|
||||
|
||||
}
|
28
app/themes/gestalt/controllers/MainController.php
Normal file
28
app/themes/gestalt/controllers/MainController.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\gestalt\controllers;
|
||||
|
||||
use kernel\Controller;
|
||||
|
||||
class MainController extends Controller
|
||||
{
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = APP_DIR . "/themes/gestalt/views/main/";
|
||||
$this->cgView->layout = "main.php";
|
||||
$this->cgView->layoutPath = APP_DIR . "/themes/gestalt/views/layout/";
|
||||
$this->cgView->addVarToLayout("resources", "/resources/themes/gestalt");
|
||||
}
|
||||
|
||||
public function actionIndex(): void
|
||||
{
|
||||
$this->cgView->render("index.php");
|
||||
}
|
||||
|
||||
public function actionAbout(): void
|
||||
{
|
||||
$this->cgView->render("about.php");
|
||||
}
|
||||
}
|
46
app/themes/gestalt/controllers/PsychologistController.php
Normal file
46
app/themes/gestalt/controllers/PsychologistController.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\gestalt\controllers;
|
||||
|
||||
use kernel\app_modules\gestalt_profile\models\Gestalt_profile;
|
||||
use kernel\Controller;
|
||||
use kernel\EloquentDataProvider;
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\Request;
|
||||
|
||||
class PsychologistController extends Controller
|
||||
{
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = APP_DIR . "/themes/gestalt/views/psychologist/";
|
||||
$this->cgView->layout = "main.php";
|
||||
$this->cgView->layoutPath = APP_DIR . "/themes/gestalt/views/layout/";
|
||||
$this->cgView->addVarToLayout("resources", "/resources/themes/gestalt");
|
||||
}
|
||||
|
||||
public function actionIndex(): void
|
||||
{
|
||||
$request = new Request();
|
||||
$dataProvider = (new EloquentDataProvider(Gestalt_profile::query()));
|
||||
$dataProvider->setSort([
|
||||
'id' => 'desc'
|
||||
]);
|
||||
|
||||
$page = $request->get('page', 1); // или request('page', 1) для HTTP-запросов
|
||||
$psychologists = $dataProvider->getManualPaginated($page, 8);
|
||||
|
||||
$pagination = $dataProvider->getPaginationLinks($psychologists['meta']);
|
||||
|
||||
$this->cgView->render("index.php", ['psychologists' => $psychologists, 'pagination' => $pagination]);
|
||||
}
|
||||
|
||||
public function actionView(int $id): void
|
||||
{
|
||||
$profile = Gestalt_profile::where('id', $id)->first();
|
||||
|
||||
$this->cgView->render("view.php", ['profile' => $profile]);
|
||||
}
|
||||
|
||||
}
|
15
app/themes/gestalt/manifest.json
Normal file
15
app/themes/gestalt/manifest.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "Gestalt",
|
||||
"version": "0.1",
|
||||
"author": "ItGuild",
|
||||
"slug": "gestalt",
|
||||
"type": "theme",
|
||||
"description": "Gestalt theme",
|
||||
"preview": "preview.jpg",
|
||||
"resource": "/resources/themes/gestalt",
|
||||
"resource_path": "{RESOURCES}/themes/gestalt",
|
||||
"theme_class": "app\\themes\\gestalt\\GestaltTheme",
|
||||
"theme_class_file": "{APP}/themes/gestalt/GestaltTheme.php",
|
||||
"routs": "routs/gestalt.php",
|
||||
"dependence": "photo,tag"
|
||||
}
|
16
app/themes/gestalt/routs/gestalt.php
Normal file
16
app/themes/gestalt/routs/gestalt.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
use kernel\App;
|
||||
|
||||
|
||||
App::$collector->get('/', [\app\themes\gestalt\controllers\MainController::class, 'actionIndex']);
|
||||
App::$collector->get('/about', [\app\themes\custom\controllers\MainController::class, 'actionAbout']);
|
||||
App::$collector->get('/events', [\app\themes\gestalt\controllers\EventController::class, 'actionIndex']);
|
||||
App::$collector->get('/event/{id}', [\app\themes\gestalt\controllers\EventController::class, 'actionView']);
|
||||
App::$collector->get('/psychologist/{id}', [\app\themes\gestalt\controllers\PsychologistController::class, 'actionView']);
|
||||
App::$collector->get('/psychologists', [\app\themes\gestalt\controllers\PsychologistController::class, 'actionIndex']);
|
||||
//App::$collector->get('/page/{page_number}', [\app\modules\tag\controllers\TagController::class, 'actionIndex']);
|
||||
//App::$collector->get('/create', [\app\modules\tag\controllers\TagController::class, 'actionCreate']);
|
||||
|
||||
|
||||
|
23
app/themes/gestalt/views/event/_main_events_list.php
Normal file
23
app/themes/gestalt/views/event/_main_events_list.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $events
|
||||
*/
|
||||
$relation = new \kernel\EntityRelation();
|
||||
?>
|
||||
|
||||
<div class="flex justify-around flex-wrap gap-y-[10px]">
|
||||
<?php foreach ($events as $event): ?>
|
||||
<?php /** @var \kernel\app_modules\event\models\Event $event */ ?>
|
||||
<a class="border-[1px] border-white rounded-[6px] bg-darkGrey px-[13.5px] pt-[12px] pb-[35px] text-black" href="event/<?= $event->id ?>">
|
||||
<span class="flex w-[288px] h-[177px] bg-white">
|
||||
<?= $relation->getAdditionalPropertyByEntityId('event', $event->id, 'photo', ['cover' => true]) ?>
|
||||
</span>
|
||||
<h5 class="max-w-[267px] font-[500] text-[16px] leading-[18px] mt-[30px] mb-[8px] line-clamp-3 text-ellipsis">
|
||||
<?= $event->title ?>
|
||||
</h5>
|
||||
<p class="max-w-[267px] text-[15px] leading-[17px] line-clamp-3 text-ellipsis">
|
||||
<?= $event->description ?>
|
||||
</p>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
147
app/themes/gestalt/views/event/index.php
Normal file
147
app/themes/gestalt/views/event/index.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* @var string $resources ;
|
||||
* @var array $pagination ;
|
||||
* @var \kernel\CgView $view
|
||||
* @var array $events
|
||||
*/
|
||||
|
||||
$view->setTitle("IT Guild Micro Framework");
|
||||
$view->setMeta([
|
||||
'description' => 'Default IT Guild Micro Framework theme'
|
||||
]);
|
||||
|
||||
$relation = new \kernel\EntityRelation();
|
||||
?>
|
||||
|
||||
<main>
|
||||
<nav class="max-w-[1083px] px-[25px] mx-auto">
|
||||
<ol class="flex flex-wrap text-middleGrey font-[350] my-[50px]">
|
||||
<li><a href="/">главная</a></li>
|
||||
<li><a href="/events"><span class="mx-[2px]">/</span>мероприятия сообщества</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<div class="flex flex-col gap-[31px] items-center mb-[50px] px-[25px]"><h1
|
||||
class="text-[35px] text-center md:text-[40px] uppercase">Мероприятия сообщества</h1>
|
||||
<p class="text-[17px] md:text-[19px] max-w-[832px] text-center">это добровольное самоорганизующееся сообщество
|
||||
специалистов г. Донецка и Донецкого края в области психологического консультирования и гештальт-терапии.</p>
|
||||
</div>
|
||||
<div class="flex flex-col max-w-[1083px] px-[25px] m-auto">
|
||||
<div class="flex flex-col gap-[30px] items-center md:flex-row md:gap-[84px] mb-[30px]">
|
||||
<div class="undefined px-[36px] py-[7px] bg-white max-w-[225px] min-w-[180px] min-h-[39px] justify-center items-center w-fit cursor-pointer border-blue border-[1px] flex gap-[10px] rounded-[10px]">
|
||||
<p class="text-blue font-[700] text-[16px]">Все мероприятия</p><img alt="chevronDown" loading="lazy"
|
||||
width="11" height="8"
|
||||
decoding="async" data-nimg="1"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/chevronDown.svg"/>
|
||||
</div>
|
||||
<label class="flex items-center text-[14px] text-lightGrey gap-[12px]"><input
|
||||
class="w-[16px] h-[16px] border-white" type="checkbox"/>только мероприятия Донецкого
|
||||
сообщества</label></div>
|
||||
<div class="flex flex-wrap gap-x-[12px] gap-y-[30px] mb-[80px] justify-evenly lg:justify-between">
|
||||
<?php foreach ($events['data'] as $event): ?>
|
||||
<?php /* @var \kernel\app_modules\event\models\Event $event */ ?>
|
||||
<a class="border-[1px] border-white rounded-[6px] bg-darkGrey px-[13.5px] pt-[12px] pb-[35px] text-black"
|
||||
href="/event/<?= $event->id ?>">
|
||||
<span class="flex w-[288px] h-[177px] bg-white">
|
||||
<?= $relation->getAdditionalPropertyByEntityId('event', $event->id, 'photo', ['cover' => true]) ?>
|
||||
</span>
|
||||
<h5 class="max-w-[267px] font-[500] text-[16px] leading-[18px] mt-[30px] mb-[8px] line-clamp-3 text-ellipsis">
|
||||
<?= $event->title ?>
|
||||
</h5>
|
||||
<p class="max-w-[267px] text-[15px] leading-[17px] line-clamp-3 text-ellipsis">
|
||||
<?= $event->description ?>
|
||||
</p>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="mb-[100px] flex justify-between flex-col gap-[50px] md:flex-row">
|
||||
<div class="flex">
|
||||
<button class="mr-[30px]" disabled="">
|
||||
<a href="<?= $pagination['previous'] ?>">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11"
|
||||
decoding="async" data-nimg="1"
|
||||
class="rotate-[90deg] relative top-[-2px]"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/chevronDown.svg"/>
|
||||
</a>
|
||||
</button>
|
||||
<div class="flex gap-[12px] items-center">
|
||||
<?php if ($pagination['previous']): ?>
|
||||
<button class="text-[17px]">
|
||||
<a href="<?= $pagination['previous'] ?>">
|
||||
<?= $pagination['meta']['current_page'] - 1 ?>
|
||||
</a>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<button class="text-blue font-[700] text-[17px]"><?= $pagination['meta']['current_page'] ?></button>
|
||||
<?php if ($pagination['next']): ?>
|
||||
<button class="text-[17px]">
|
||||
<a href="<?= $pagination['next'] ?>">
|
||||
<?= $pagination['meta']['current_page'] + 1 ?>
|
||||
</a>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if ($pagination['meta']['current_page'] <= $pagination['meta']['last_page']
|
||||
&& $pagination['meta']['current_page'] > 4): ?>
|
||||
<span>...</span>
|
||||
<button class="text-[17px]"><?= $pagination['meta']['last_page'] ?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<button class=" flex items-center text-[15px] font-[700] ml-auto md:ml-[26px] gap-[11px]">
|
||||
<a href="<?= $pagination['next'] ?>">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="rotate-[-90deg] relative top-[-2px]" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/chevronDown.svg"/>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<button class="flex items-center justify-center whitespace-nowrap rounded-[6px] font-[400] text-[16px] text-blue border-[1px] border-blue max-h-[39px] px-[25px] py-[10px] undefined">
|
||||
Показать все мероприятия
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[80px]">
|
||||
<div class="hidden lg:flex bg-blue rounded-[25px] relative max-w-[1033px] w-full m-auto pt-[59.5px] pb-[59.5px] h-[234px] text-center justify-center items-center">
|
||||
<p class="text-white text-[32px] max-w-[671px] font-[700]">Через собственное развитие мы развиваем и
|
||||
популяризируем гештальт-подход</p><img alt="palm" loading="lazy" width="217" height="254"
|
||||
decoding="async" data-nimg="1"
|
||||
class=" absolute right-0 top-[-20px]" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/palm.svg"/></div>
|
||||
<div class="flex-col w-full max-w-[1083px] px-[25px] flex gap-[53px] items-end m-auto md:flex-row">
|
||||
<div class="flex justify-center md:justify-start md:max-w-[645px] flex-wrap gap-x-[15px] gap-y-[12px]">
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">конференции</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">акредитации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">общие сборы</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">протоколы сборов</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">новости сайта</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">календарь событий</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">сайт мги</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">вопросы и ответы</span></div>
|
||||
</div>
|
||||
<div class="flex gap-[19px] m-auto">
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">Книги</span></div>
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">лекции</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
172
app/themes/gestalt/views/event/view.php
Normal file
172
app/themes/gestalt/views/event/view.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?php
|
||||
/**
|
||||
* @var \kernel\app_modules\event\models\Event $event
|
||||
* @var string $resources ;
|
||||
*/
|
||||
|
||||
$entityRelation = new \kernel\EntityRelation();
|
||||
$profiles = $entityRelation->callModuleMethod('gestalt_profile_relationship', 'getItemsObject', ['entity' => 'event', 'entity_id' => $event->id]);
|
||||
?>
|
||||
|
||||
<main>
|
||||
<nav class="max-w-[1083px] px-[25px] mx-auto">
|
||||
<ol class="flex flex-wrap text-middleGrey font-[350] my-[50px]">
|
||||
<li><a href="/">главная</a></li>
|
||||
<li><a href="/events"><span class="mx-[2px]">/</span>мероприятия сообщества</a></li>
|
||||
<li><a href="/event/<?= $event->id ?>"><span class="mx-[2px]">/</span><?= $event->title ?></a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<div class="bg-blue rounded-[6px] max-w-[1033px] mx-[25px] px-[30px] lg:mx-auto mb-[30px] py-[45px] lg:px-[100px]">
|
||||
<p class="text-white text-[40px] text-center uppercase leading-[48px]">
|
||||
<?= $event->title ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col m-auto max-w-[1083px] px-[25px] gap-[50px] mb-[80px]">
|
||||
<div class="flex gap-[10px] flex-wrap lg:gap-[23px] justify-between lg:justify-start">
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[16px] text-lightBlack border-[1px] rounded-[6px] py-[10px] px-[28px] gap-[10px] items-center">
|
||||
<span class="">
|
||||
<?= $event->type ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[16px] text-lightBlack border-[1px] rounded-[6px] py-[10px] px-[28px] gap-[10px] items-center">
|
||||
<img alt="clock" loading="lazy" width="18" height="18" decoding="async" data-nimg="1"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/clock.svg"/>
|
||||
<span class="">
|
||||
<?= $event->hours_count ?> ч.
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[16px] text-lightBlack border-[1px] rounded-[6px] py-[10px] px-[28px] gap-[10px] items-center">
|
||||
<img alt="date" loading="lazy" width="18" height="18" decoding="async" data-nimg="1"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/date.svg"/>
|
||||
<span class="">
|
||||
<?= $event->dateStartFormated . " - " . $event->dateEndFormated ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[16px] text-lightBlack border-[1px] rounded-[6px] py-[10px] px-[28px] gap-[10px] items-center">
|
||||
<img alt="location" loading="lazy" width="18" height="18" decoding="async" data-nimg="1"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/location.svg"/>
|
||||
<span class="">
|
||||
<?= $event->place ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center flex-wrap lg:flex-nowrap lg:justify-between gap-[18px]">
|
||||
<?php foreach ($profiles as $profile): ?>
|
||||
<a class=" backdrop-blur-custom border-[1px] border-white rounded-[15px] bg-darkWhite text-black w-fit shadow-custom px-[9px] pt-[11px] pb-[25px] max-w-[370px] w-full sm:max-w-[280px]"
|
||||
href="/psychologist/<?= $profile->profile->id ?>">
|
||||
<img alt="image" loading="lazy" width="260" height="181" decoding="async"
|
||||
data-nimg="1" class="w-full" style="color:transparent;width:100%;height:200px;object-fit:cover;"
|
||||
src="<?= $profile->profile->photo ?? '' ?>"/>
|
||||
<div class="px-[13px]">
|
||||
<h5 class="text-[18px] max-w-full sm:max-w-[190px] font-[400] leading-[20px] max-w-[190px] mt-[16px] mb-[20px]">
|
||||
<?= $profile->profile->fio ?? '' ?>
|
||||
</h5>
|
||||
<span class="text-lightGrey">Работает с темами
|
||||
<p class="text-black text-[13px] leading-[15px] line-clamp-3 text-ellipsis max-w-[220px] mb-[16px] max-w-full sm:max-w-[220px]"></p>
|
||||
</span>
|
||||
<div class="flex gap-[5px] max-w-[220px] flex-wrap items-center max-w-full sm:max-w-[220px]">
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[13px] px-[9.5px] rounded-[6px] border-[0.5px] text-blue font-[400] min-h-[28px] max-h-[28px] h-full">
|
||||
<span class="">Терапевт</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[13px] px-[9.5px] rounded-[6px] border-[0.5px] text-blue font-[400] min-h-[28px] max-h-[28px] h-full">
|
||||
<span class="">Супервизор</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[13px] px-[9.5px] rounded-[6px] border-[0.5px] text-blue font-[400] min-h-[28px] max-h-[28px] h-full">
|
||||
<span class="">Тренер</span>
|
||||
</div>
|
||||
<div class="bg-bgGrey rounded-[6px] w-[28px] h-[28px] flex justify-center items-center"><span
|
||||
class="text-white text-[13px] font-[400] max-h-[15px] flex items-center relative top-[1px]"><span
|
||||
class="relative top-[-0.5px]">+</span>3</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="flex-wrap xl:flex-nowrap flex gap-[21px]">
|
||||
<div class="order-2 xl:order-1 items-center xl:items-start flex py-[30px] flex-col border-white border-[1px] rounded-[6px] w-full xl:min-w-[780px] min-h-[200px] px-[32px] justify-center gap-[12px]">
|
||||
<h4 class="text-black text-[26px] text-center md:text-start uppercase">
|
||||
формат мероприятия
|
||||
</h4>
|
||||
<p class="text-black text-[15px] max-w-[640px]">
|
||||
<?= !empty($event->event_format) ? $event->event_format : "Не указан" ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="order-1 xl:order-2 justify-evenly flex xl:flex-col bg-white rounded-[12px] pt-[25px] pb-[10px] xl:pt-[47px] xl:pb-[34px] w-full xl:pl-[32px] gap-[23px] relative">
|
||||
<div class="flex-col flex text-[18px]">
|
||||
<?php foreach ($event->contacts as $contact): ?>
|
||||
<span><?= $contact->title ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<!-- <div class="flex-col flex text-[15px]">-->
|
||||
<!-- <span>Luchayapochta@mail.ru</span>-->
|
||||
<!-- <span>Luchayapochta@mail.ru</span>-->
|
||||
<!-- </div>-->
|
||||
<div class="absolute bg-white w-[47px] h-[47px] flex rounded-full items-center justify-center top-[-20px]">
|
||||
<a class="flex justify-center items-center w-[41px] h-[41px] bg-blue rounded-full" href=""><img
|
||||
alt="logo_tg" loading="lazy" width="1" height="1" decoding="async" data-nimg="1"
|
||||
class="w-auto h-auto" style="color:transparent" src="<?= $resources ?>/out/images/logo_tg.svg"/> </a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[30px] max-w-[910px] font-[300]">
|
||||
<h3 class="uppercase text-black text-[26px]">
|
||||
содержание
|
||||
</h3>
|
||||
<p class="text-[15px] leading-[24px]">
|
||||
<?= $event->description ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php if (!empty($event->additional_info)): ?>
|
||||
<div class="flex flex-col gap-[30px] max-w-[910px] font-[300]">
|
||||
<h3 class="uppercase text-black text-[26px]">
|
||||
Дополнительная информация
|
||||
</h3>
|
||||
<p class="text-[15px] leading-[24px] ">
|
||||
<?= $event->additional_info ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[80px]">
|
||||
<div class="hidden lg:flex bg-blue rounded-[25px] relative max-w-[1033px] w-full m-auto pt-[59.5px] pb-[59.5px] h-[234px] text-center justify-center items-center">
|
||||
<p class="text-white text-[32px] max-w-[671px] font-[700]">Через собственное развитие мы развиваем и
|
||||
популяризируем гештальт-подход</p><img alt="palm" loading="lazy" width="217" height="254"
|
||||
decoding="async" data-nimg="1"
|
||||
class=" absolute right-0 top-[-20px]" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/palm.svg"/></div>
|
||||
<div class="flex-col w-full max-w-[1083px] px-[25px] flex gap-[53px] items-end m-auto md:flex-row">
|
||||
<div class="flex justify-center md:justify-start md:max-w-[645px] flex-wrap gap-x-[15px] gap-y-[12px]">
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">конференции</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">акредитации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">общие сборы</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">протоколы сборов</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">новости сайта</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">календарь событий</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">сайт мги</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">вопросы и ответы</span></div>
|
||||
</div>
|
||||
<div class="flex gap-[19px] m-auto">
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent" src="<?= $resources ?>/out/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">Книги</span></div>
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent" src="<?= $resources ?>/out/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">лекции</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
114
app/themes/gestalt/views/layout/main.php
Normal file
114
app/themes/gestalt/views/layout/main.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* @var string $content
|
||||
* @var string $resources
|
||||
* @var string $title
|
||||
* @var \kernel\CgView $view
|
||||
*/
|
||||
$assets = new \app\themes\gestalt\assets\GestaltThemesAssets($resources);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
|
||||
<?php $assets->getCSSAsSTR(); ?>
|
||||
<meta name="description" content=""/>
|
||||
<meta name="author" content=""/>
|
||||
<title><?= $title ?></title>
|
||||
<?= $view->getMeta() ?>
|
||||
<link rel="icon" type="image/x-icon" href="<?= $resources ?>/assets/favicon.ico"/>
|
||||
<!-- Font Awesome icons (free version)-->
|
||||
<script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>
|
||||
<!-- Google fonts-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic" rel="stylesheet"
|
||||
type="text/css"/>
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800"
|
||||
rel="stylesheet" type="text/css"/>
|
||||
<!-- Core theme CSS (includes Bootstrap)-->
|
||||
</head>
|
||||
<body>
|
||||
<!-- Navigation-->
|
||||
<header class="flex pt-8 px-[25px] m-auto justify-between items-center max-w-[1083px] relative">
|
||||
<div class="sm:hidden max-w-[95px] w-full"><img alt="burger" loading="lazy" width="23" height="17" decoding="async"
|
||||
data-nimg="1" class="cursor-pointer sm:hidden"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/burger.svg"/></div>
|
||||
<div class="hidden w-full justify-between mt-[10px] gap-[19px] text-[15px] text-dark font-[350] sm:flex sm:max-w-[145px] sm:mt-0 md:gap-[96px]">
|
||||
<a href="/events">События</a><a href="/participants">Участники</a></div>
|
||||
<a class=" " href="/"><img alt="logo" loading="lazy" width="150" height="48" decoding="async" data-nimg="1"
|
||||
style="color:transparent" src="<?= $resources ?>/out/logo.svg"/></a>
|
||||
<div class="flex gap-[13px] sm:gap-[19px]"><a
|
||||
class="flex justify-center items-center w-[41px] h-[41px] bg-blue rounded-full" href=""><img alt="logo_tg"
|
||||
loading="lazy"
|
||||
width="1"
|
||||
height="1"
|
||||
decoding="async"
|
||||
data-nimg="1"
|
||||
class="w-auto h-auto"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/logo_tg.svg"/>
|
||||
</a><a class="flex justify-center items-center w-[41px] h-[41px] bg-blue rounded-full" href=""><img alt="logo_vk"
|
||||
loading="lazy"
|
||||
width="1"
|
||||
height="1"
|
||||
decoding="async"
|
||||
data-nimg="1"
|
||||
class="w-auto h-auto"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/logo_vk.svg"/>
|
||||
</a></div>
|
||||
</header>
|
||||
|
||||
<?= $content ?>
|
||||
|
||||
<!-- Footer-->
|
||||
<footer class="flex flex-col items-center mt-[20px] md:flex-row md:mt-[80px] max-w-[1083px] px-[25px] justify-between pb-8 m-auto">
|
||||
<a href="/public"><img alt="logo" loading="lazy" width="150" height="48" decoding="async" data-nimg="1"
|
||||
style="color:transparent" src="<?= $resources ?>/out/logo.svg"/></a>
|
||||
<div class="max-w-[500px] mt-[40px] md:mt-0 w-full justify-between md:w-fit gap-[25px] lg:gap-[96px] flex text-[15px] text-dark items-center font-[350]">
|
||||
<div class="flex gap-[28px]"><a href="/events">События</a><a href="/participants">Участники</a></div>
|
||||
<div class="flex gap-[28px] md:hidden"><a
|
||||
class="flex justify-center items-center w-[41px] h-[41px] bg-blue rounded-full" href=""><img
|
||||
alt="logo_tg" loading="lazy" width="1" height="1" decoding="async" data-nimg="1" class="w-auto h-auto"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/logo_tg.svg"/> </a><a
|
||||
class="flex justify-center items-center w-[41px] h-[41px] bg-blue rounded-full" href=""><img
|
||||
alt="logo_vk" loading="lazy" width="1" height="1" decoding="async" data-nimg="1" class="w-auto h-auto"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/logo_vk.svg"/> </a></div>
|
||||
</div>
|
||||
<div class="max-w-[500px] w-full justify-between mt-[70px] md:mt-0 md:w-fit flex gap-[25px]"><img alt="oop"
|
||||
loading="lazy"
|
||||
width="83"
|
||||
height="21"
|
||||
decoding="async"
|
||||
data-nimg="1"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/oppgp.svg"/><img
|
||||
alt="pmg" loading="lazy" width="96" height="27" decoding="async" data-nimg="1" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/pmg.svg"/></div>
|
||||
<div class="max-w-[500px] w-full justify-center hidden md:w-fit md:flex gap-[29px]"><a
|
||||
class="flex justify-center items-center w-[41px] h-[41px] bg-blue rounded-full" href=""><img alt="logo_tg"
|
||||
loading="lazy"
|
||||
width="1"
|
||||
height="1"
|
||||
decoding="async"
|
||||
data-nimg="1"
|
||||
class="w-auto h-auto"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/logo_tg.svg"/>
|
||||
</a><a class="flex justify-center items-center w-[41px] h-[41px] bg-blue rounded-full" href=""><img alt="logo_vk"
|
||||
loading="lazy"
|
||||
width="1"
|
||||
height="1"
|
||||
decoding="async"
|
||||
data-nimg="1"
|
||||
class="w-auto h-auto"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/logo_vk.svg"/>
|
||||
</a></div>
|
||||
</footer>
|
||||
<!-- Bootstrap core JS-->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<!-- Core theme JS-->
|
||||
<?php $assets->getJSAsStr(); ?>
|
||||
</body>
|
||||
</html>
|
36
app/themes/gestalt/views/main/about.php
Normal file
36
app/themes/gestalt/views/main/about.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* @var string $resources;
|
||||
* @var \kernel\CgView $view
|
||||
*/
|
||||
|
||||
$view->setTitle("Старт Bootstrap");
|
||||
$view->setMeta([
|
||||
'description' => 'Дефолтная bootstrap тема'
|
||||
]);
|
||||
?>
|
||||
<!-- Page Header-->
|
||||
<header class="masthead" style="background-image: url('<?= $resources ?>/assets/img/about-bg.jpeg')">
|
||||
<div class="container position-relative px-4 px-lg-5">
|
||||
<div class="row gx-4 gx-lg-5 justify-content-center">
|
||||
<div class="col-md-10 col-lg-8 col-xl-7">
|
||||
<div class="page-heading">
|
||||
<h1>About Me</h1>
|
||||
<span class="subheading">This is what I do.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- Main Content-->
|
||||
<main class="mb-4">
|
||||
<div class="container px-4 px-lg-5">
|
||||
<div class="row gx-4 gx-lg-5 justify-content-center">
|
||||
<div class="col-md-10 col-lg-8 col-xl-7">
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Saepe nostrum ullam eveniet pariatur voluptates odit, fuga atque ea nobis sit soluta odio, adipisci quas excepturi maxime quae totam ducimus consectetur?</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eius praesentium recusandae illo eaque architecto error, repellendus iusto reprehenderit, doloribus, minus sunt. Numquam at quae voluptatum in officia voluptas voluptatibus, minus!</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut consequuntur magnam, excepturi aliquid ex itaque esse est vero natus quae optio aperiam soluta voluptatibus corporis atque iste neque sit tempora!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
151
app/themes/gestalt/views/main/index.php
Normal file
151
app/themes/gestalt/views/main/index.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
/**
|
||||
* @var string $resources;
|
||||
* @var \kernel\CgView $view
|
||||
*/
|
||||
|
||||
$view->setTitle("IT Guild Micro Framework");
|
||||
$view->setMeta([
|
||||
'description' => 'Default IT Guild Micro Framework theme'
|
||||
]);
|
||||
$last4 = \kernel\app_modules\gestalt_profile\services\Gestalt_profileService::getLast4();
|
||||
?>
|
||||
<style>
|
||||
.circle-image {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
</style>
|
||||
<main class="pt-[60px] sm:pt-[100px] flex flex-col">
|
||||
<div class="flex flex-col container m-auto text-center text-dark gap-[31px]"><h1
|
||||
class="text-[35px] sm:text-[40px] uppercase">Донецкое гештальт сообщество</h1>
|
||||
<p class="text-[17px] text-dark sm:text-[19px] max-w-[832px] mx-auto">это добровольное самоорганизующееся
|
||||
сообщество специалистов г. Донецка и Донецкого края в области психологического консультирования и
|
||||
гештальт-терапии.</p></div>
|
||||
<div class="mt-[50px] w-full flex-col flex lg:flex-row justify-center sm:mt-[100px] gap-y-[30px] sm:gap-[14px] max-w-[1083px] px-[25px] mx-auto">
|
||||
<div class="relative bg-blue border-[1px] border-white rounded-[25px] px-[25px] pb-[10px] md:pb-[0] md:pr-[48px] md:pl-[0] md:min-w-[650px] min-h-[480px] w-full font-[400]">
|
||||
<img alt="intro" loading="lazy" width="1" height="1" decoding="async" data-nimg="1"
|
||||
class="w-[262px] h-[262px] sm:w-auto sm:h-auto scale-x-flip right-0 md:left-0 md:scale-x-100 absolute"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/intro.svg"/>
|
||||
<h3 class="text-white text-[38px] text-start mt-[214px] md:text-end leading-[41px]"><span
|
||||
class="bg-darkBlue px-[12px] py-[3px] rounded-[18px]">Цель</span> нашего<br/>объединения:</h3>
|
||||
<p class="md:ml-auto text-[16px] mt-[50px] text-start text-white md:text-[18px] leading-[20px] max-w-[400px] font-[700]">
|
||||
взаимное обогащение профессиональными знаниями, идеями и опытом на конференциях и семинарах, в учебных
|
||||
программах и на интенсивах, на специализациях и в супервизорских группах.</p></div>
|
||||
<div class="flex-col md:flex-row min-w-full lg:min-w-min lg:flex-col flex gap-[12px] max-w-[368px]">
|
||||
<div class="flex px-[20px] items-center bg-blue rounded-[25px] min-h-[234px] lg:px-[68px] py-[60px] relative">
|
||||
<p class="text-white font-[500] leading-[23px] text-[20px]">Через собственное развитие мы развиваем и
|
||||
популяризируем гештальт-подход</p><img alt="palm" loading="lazy" width="1" height="1"
|
||||
decoding="async" data-nimg="1"
|
||||
class="w-auto h-auto absolute right-3 bottom-0"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/palm.svg"/></div>
|
||||
<div class="flex justify-center sm:justify-normal px-[20px] flex-col items-center rounded-[25px] min-h-[234px] lg:px-[68px] pt-[40px] border-[4px] border-white relative">
|
||||
<div class="w-full lg:left-[-20px] flex relative justify-center md:justify-normal">
|
||||
<img alt="avatar" loading="lazy" width="101" height="100" decoding="async" data-nimg="1" class="right-[-85px] md:right-0 relative circle-image" style="color:transparent" src="<?= $last4[0]['photo'] ?? $resources . '/out/images/avatar.png' ?>"/>
|
||||
<img alt="avatar" loading="lazy" width="101" height="100" decoding="async" data-nimg="1" class="right-[-30px] md:right-[55px] z-2 relative circle-image" style="color:transparent" src="<?= $last4[1]['photo'] ?? $resources . '/out/images/avatar.png' ?>"/>
|
||||
<img alt="avatar" loading="lazy" width="101" height="100" decoding="async" data-nimg="1" class="right-[30px] md:right-[105px] z-3 relative circle-image" style="color:transparent" src="<?= \kernel\helpers\Files::isImageByExtension($last4[2]['photo']) ? $last4[2]['photo'] : $resources . '/out/images/user_no_photo.png' ?>"/>
|
||||
<img alt="avatar" loading="lazy" width="101" height="100" decoding="async" data-nimg="1" class="right-[85px] md:right-[155px] z-4 relative circle-image" style="color:transparent" src="<?= $last4[3]['photo'] ?? $resources . '/out/images/avatar.png' ?>"/>
|
||||
</div>
|
||||
<p class="text-blue font-[900] text-[26px]">+ <?= \kernel\app_modules\gestalt_profile\services\Gestalt_profileService::getCount() - 4 ?> учасников</p></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-[50px] flex-col sm:flex-row flex gap-[64px] justify-center container mx-auto">
|
||||
<div class="flex-col flex gap-[35px] items-center"><img alt="oppgp" loading="lazy" width="140" height="37"
|
||||
decoding="async" data-nimg="1" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/oppgp.svg"/>
|
||||
<p class="text-grey max-w-[300px] text-[16px] leading-[17px] text-center font-[700]">Донецкое
|
||||
гештальт-сообщество является частью Всероссийского общества психологов практикующих гештальт-подход (ОПП
|
||||
ГП). </p></div>
|
||||
<div class="flex-col flex gap-[19px] items-center"><img alt="oppgp" loading="lazy" width="177" height="53"
|
||||
decoding="async" data-nimg="1" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/pmg.svg"/>
|
||||
<p class="text-grey max-w-[507px] text-[16px] leading-[17px] text-center font-[700]">В своей работе мы
|
||||
придерживаемся стандартов программы «Московский Гештальт Институт», а также стандартов Европейской
|
||||
Ассоциации Гештальт Терапии, Этического Кодекса Гештальт Терапевта и принципов гуманизма.</p></div>
|
||||
</div>
|
||||
<div class="flex flex-col mt-[100px]">
|
||||
<div class="flex flex-col gap-[10px] md:flex-row items-center lg: max-w-[1083px] px-[25px] mx-auto justify-between w-full mb-[50px]">
|
||||
<div class="order-2 md:order-1 max-w-[225px] min-w-[180px] min-h-[39px] justify-center items-center w-fit cursor-pointer border-blue border-[1px] flex gap-[10px] rounded-[10px]">
|
||||
<p class="text-blue font-[700] text-[16px]">Конференции</p><img alt="chevronDown" loading="lazy"
|
||||
width="11" height="8" decoding="async"
|
||||
data-nimg="1" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/chevronDown.svg"/></div>
|
||||
<h3 class="mb-[50px] md:mb-0 order-1 md:order-2 text-blac text-center text-[26px] uppercase">Мероприятия
|
||||
сообщества</h3>
|
||||
<button class="flex items-center justify-center whitespace-nowrap rounded-[6px] font-[400] bg-blue text-[16px] text-white max-h-[39px] px-[25px] py-[10px] hidden md:flex order-3">
|
||||
<a href="/events">Все мероприятия</a>
|
||||
</button>
|
||||
</div>
|
||||
<?php \app\themes\gestalt\widgets\MainEventsList::create()->run(); ?>
|
||||
</div>
|
||||
<button class="flex items-center justify-center whitespace-nowrap rounded-[6px] font-[400] bg-blue text-[16px] text-white max-h-[39px] px-[25px] py-[10px] min-w-[315px] mt-[50px] m-auto md:hidden">
|
||||
<a href="/events">Все мероприятия</a>
|
||||
</button>
|
||||
<div class="flex flex-col mt-[90px] mb-[80px] gap-[56px]">
|
||||
<div class="flex flex-col md:flex-row items-center px-[25px] max-w-[1083px] mx-auto justify-between w-full">
|
||||
<div class="order-2 md:order-1 max-w-[225px] min-w-[180px] min-h-[39px] justify-center items-center w-fit cursor-pointer border-blue border-[1px] flex gap-[10px] rounded-[10px]">
|
||||
<p class="text-blue font-[700] text-[16px]">Тренер</p><img alt="chevronDown" loading="lazy" width="11"
|
||||
height="8" decoding="async" data-nimg="1"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/chevronDown.svg"/></div>
|
||||
<div class="flex mb-[50px] order-1 md:order-2 md:mb-0"><img alt="arrow" loading="lazy" width="11"
|
||||
height="11" decoding="async" data-nimg="1"
|
||||
class="rotate-[90deg] relative top-[-2px]"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/chevronDown.svg"/>
|
||||
<h3 class=" text-black text-center text-[26px] uppercase mx-[23px]">наше сообщество</h3><img alt="arrow"
|
||||
loading="lazy"
|
||||
width="11"
|
||||
height="11"
|
||||
decoding="async"
|
||||
data-nimg="1"
|
||||
class="rotate-[-90deg] relative top-[-2px]"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/chevronDown.svg"/>
|
||||
</div>
|
||||
<button class="flex items-center justify-center whitespace-nowrap rounded-[6px] font-[400] bg-blue text-[16px] text-white max-h-[39px] px-[25px] py-[10px] hidden md:order-3 md:flex">
|
||||
<a href="/psychologists">Все участники</a>
|
||||
</button>
|
||||
</div>
|
||||
<?php \app\themes\gestalt\widgets\MainPsychologistsList::create(['count' => 5])->run(); ?>
|
||||
<button class="flex items-center justify-center whitespace-nowrap rounded-[6px] font-[400] bg-blue text-[16px] text-white max-h-[39px] px-[25px] py-[10px] min-w-[315px] mt-[50px] m-auto md:hidden">
|
||||
Все участники
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-col w-full max-w-[1083px] px-[25px] flex gap-[53px] items-end m-auto md:flex-row">
|
||||
<div class="flex justify-center md:justify-start md:max-w-[645px] flex-wrap gap-x-[15px] gap-y-[12px]">
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">конференции</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">акредитации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">общие сборы</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">протоколы сборов</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">новости сайта</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">календарь событий</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">сайт мги</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">вопросы и ответы</span></div>
|
||||
</div>
|
||||
<div class="flex gap-[19px] m-auto">
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent" src="<?= $resources ?>/out/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">Книги</span></div>
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent" src="<?= $resources ?>/out/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">лекции</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $psychologists
|
||||
*/
|
||||
?>
|
||||
|
||||
<div class="flex m-auto justify-center gap-[16px] w-full px-[25px] flex-wrap">
|
||||
<?php foreach ($psychologists as $psychologist): ?>
|
||||
<?php /** @var \kernel\app_modules\gestalt_profile\models\Gestalt_profile $psychologist */ ?>
|
||||
<a class=" backdrop-blur-custom border-[1px] border-white rounded-[15px] bg-darkWhite text-black w-fit shadow-custom px-[9px] pt-[11px] pb-[25px] max-w-[370px] w-full sm:max-w-[280px]"
|
||||
href="/psychologist/<?= $psychologist->id ?>">
|
||||
<img alt="image" loading="lazy" width="260" height="181" decoding="async"
|
||||
data-nimg="1" class="w-full" style="width: 100%; height: 200px; object-fit: cover;color:transparent"
|
||||
src="<?= $psychologist->photo ?? '' ?>"/>
|
||||
<div class="px-[13px]">
|
||||
<h5 class="text-[18px] max-w-full sm:max-w-[190px] font-[400] leading-[20px] max-w-[190px] mt-[16px] mb-[20px]">
|
||||
<?= $psychologist->fio ?? '' ?>
|
||||
</h5>
|
||||
<span class="text-lightGrey">
|
||||
Работает с темами
|
||||
<p class="text-black text-[13px] leading-[15px] line-clamp-3 text-ellipsis max-w-[220px] mb-[16px] max-w-full sm:max-w-[220px]">
|
||||
<?= !empty($psychologist->specialization) ? $psychologist->specialization : 'Нет данных' ?>
|
||||
</p>
|
||||
</span>
|
||||
<div class="flex gap-[5px] max-w-[220px] flex-wrap items-center max-w-full sm:max-w-[220px]">
|
||||
<?php foreach ($psychologist->communityStatusArr as $item): ?>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[13px] px-[9.5px] rounded-[6px] border-[0.5px] text-blue font-[400] min-h-[28px] max-h-[28px] h-full">
|
||||
<span class="">
|
||||
<?= $item ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php if (count($psychologist->communityStatusArr) > 3): ?>
|
||||
<div class="bg-bgGrey rounded-[6px] w-[28px] h-[28px] flex justify-center items-center"><span
|
||||
class="text-white text-[13px] font-[400] max-h-[15px] flex items-center relative top-[1px]"><span
|
||||
class="relative top-[-0.5px]">+</span>3</span></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* @var array $columns
|
||||
*/
|
||||
|
||||
echo '<div class="flex text-[15px] leading-[25px] gap-0 lg:gap-[63px] flex-col lg:flex-row ">';
|
||||
foreach ($columns as $column) {
|
||||
echo '<ul class="list-disc list-inside">';
|
||||
foreach ($column as $item) {
|
||||
echo '<li>' . htmlspecialchars($item) . '</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
echo '</div>';
|
154
app/themes/gestalt/views/psychologist/index.php
Normal file
154
app/themes/gestalt/views/psychologist/index.php
Normal file
@ -0,0 +1,154 @@
|
||||
<?php
|
||||
/**
|
||||
* @var string $resources ;
|
||||
* @var array $psychologists
|
||||
* @var array $pagination ;
|
||||
*/
|
||||
?>
|
||||
|
||||
<main>
|
||||
<nav class="max-w-[1083px] px-[25px] mx-auto">
|
||||
<ol class="flex flex-wrap text-middleGrey font-[350] my-[50px]">
|
||||
<li><a href="/">главная</a></li>
|
||||
<li><a href="/psychologists"><span class="mx-[2px]">/</span>участники</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<div class="flex flex-col gap-[31px] items-center mb-[50px] px-[25px]"><h1
|
||||
class="text-[35px] sm:text-[40px] text-center uppercase">участники сообщества</h1>
|
||||
<p class="text-[19px] sm:text-[19px] max-w-[832px] text-center">это добровольное самоорганизующееся сообщество
|
||||
специалистов г. Донецка и Донецкого края в области психологического консультирования и гештальт-терапии.</p>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[50px] px-[25px]">
|
||||
<div class="flex flex-wrap gap-[10px] justify-center md:justify-start md:gap-[28px] max-w-[1032px] m-auto w-full">
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] max-w-[140px] w-full rounded-[6px] border-[1px] text-[16px] text-blue">
|
||||
<span class="">Терапевт</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] max-w-[140px] w-full rounded-[6px] border-[1px] text-[16px] text-blue">
|
||||
<span class="">Супервизор</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] max-w-[140px] w-full rounded-[6px] border-[1px] text-[16px] text-blue">
|
||||
<span class="">Тренер</span></div>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-x-[16px] gap-y-[30px] justify-center max-w-[1350px] m-auto">
|
||||
<?php foreach ($psychologists['data'] as $psychologist): ?>
|
||||
<?php /** @var \kernel\app_modules\gestalt_profile\models\Gestalt_profile $psychologist */ ?>
|
||||
<a class="backdrop-blur-custom border-[1px] border-white rounded-[15px] bg-darkWhite text-black w-fit shadow-custom px-[9px] pt-[11px] pb-[25px] max-w-[370px] w-full sm:max-w-[280px]"
|
||||
href="/participants/<?= $psychologist->id ?>">
|
||||
<img alt="image" loading="lazy" width="260" height="181" decoding="async"
|
||||
data-nimg="1" class="w-full"
|
||||
style="width: 100%; height: 200px; object-fit: cover;color:transparent"
|
||||
src="<?= !empty(\kernel\helpers\Files::isImageByExtension($psychologist->photo)) ? $psychologist->photo : $resources . '/out/images/user_no_photo.png' ?>"/>
|
||||
<div class="px-[13px]">
|
||||
<h5 class="text-[18px] max-w-full sm:max-w-[190px] font-[400] leading-[20px] max-w-[190px] mt-[16px] mb-[20px]">
|
||||
<?= $psychologist->fio ?>
|
||||
</h5>
|
||||
<span class="text-lightGrey">
|
||||
Работает с темами
|
||||
<p class="text-black text-[13px] leading-[15px] line-clamp-3 text-ellipsis max-w-[220px] mb-[16px] max-w-full sm:max-w-[220px]">
|
||||
<?= !empty(trim($psychologist->description_of_professional_activity)) ? $psychologist->description_of_professional_activity : 'Нет данных' ?>
|
||||
</p>
|
||||
</span>
|
||||
<div class="flex gap-[5px] max-w-[220px] flex-wrap items-center max-w-full sm:max-w-[220px]">
|
||||
<?php foreach ($psychologist->communityStatusArr as $item): ?>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[13px] px-[9.5px] rounded-[6px] border-[0.5px] text-blue font-[400] min-h-[28px] max-h-[28px] h-full">
|
||||
<span class="">
|
||||
<?= $item ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php if (count($psychologist->communityStatusArr) > 3): ?>
|
||||
<div class="bg-bgGrey rounded-[6px] w-[28px] h-[28px] flex justify-center items-center"><span
|
||||
class="text-white text-[13px] font-[400] max-h-[15px] flex items-center relative top-[1px]"><span
|
||||
class="relative top-[-0.5px]">+</span>3</span></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="flex-col md:flex-row gap-[50px] max-w-[1033px] m-auto w-full mb-[100px] flex justify-between">
|
||||
<div class="flex">
|
||||
<button class="mr-[30px]" disabled="">
|
||||
<a href="<?= $pagination['previous'] ?>">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11"
|
||||
decoding="async" data-nimg="1"
|
||||
class="rotate-[90deg] relative top-[-2px]"
|
||||
style="color:transparent" src="<?= $resources ?>/out/images/chevronDown.svg"/>
|
||||
</a>
|
||||
</button>
|
||||
<div class="flex gap-[12px] items-center">
|
||||
<?php if ($pagination['previous']): ?>
|
||||
<button class="text-[17px]">
|
||||
<a href="<?= $pagination['previous'] ?>">
|
||||
<?= $pagination['meta']['current_page'] - 1 ?>
|
||||
</a>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<button class="text-blue font-[700] text-[17px]"><?= $pagination['meta']['current_page'] ?></button>
|
||||
<?php if ($pagination['next']): ?>
|
||||
<button class="text-[17px]">
|
||||
<a href="<?= $pagination['next'] ?>">
|
||||
<?= $pagination['meta']['current_page'] + 1 ?>
|
||||
</a>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if ($pagination['meta']['current_page'] <= $pagination['meta']['last_page']
|
||||
&& $pagination['meta']['current_page'] > 4): ?>
|
||||
<span>...</span>
|
||||
<button class="text-[17px]"><?= $pagination['meta']['last_page'] ?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<button class=" flex items-center text-[15px] font-[700] ml-auto md:ml-[26px] gap-[11px]">
|
||||
<a href="<?= $pagination['next'] ?>">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="rotate-[-90deg] relative top-[-2px]" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/chevronDown.svg"/>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<button class="flex items-center justify-center whitespace-nowrap rounded-[6px] font-[400] bg-blue text-[16px] text-white max-h-[39px] px-[25px] py-[10px] undefined">
|
||||
Показать всех участников
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[80px]">
|
||||
<div class="hidden lg:flex bg-blue rounded-[25px] relative max-w-[1033px] w-full m-auto pt-[59.5px] pb-[59.5px] h-[234px] text-center justify-center items-center">
|
||||
<p class="text-white text-[32px] max-w-[671px] font-[700]">Через собственное развитие мы развиваем и
|
||||
популяризируем гештальт-подход</p><img alt="palm" loading="lazy" width="217" height="254"
|
||||
decoding="async" data-nimg="1"
|
||||
class=" absolute right-0 top-[-20px]"
|
||||
style="color:transparent" src="/images/palm.svg"/></div>
|
||||
<div class="flex-col w-full max-w-[1083px] px-[25px] flex gap-[53px] items-end m-auto md:flex-row">
|
||||
<div class="flex justify-center md:justify-start md:max-w-[645px] flex-wrap gap-x-[15px] gap-y-[12px]">
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">конференции</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">акредитации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">общие сборы</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">протоколы сборов</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">новости сайта</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">календарь событий</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">сайт мги</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">вопросы и ответы</span></div>
|
||||
</div>
|
||||
<div class="flex gap-[19px] m-auto">
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent" src="/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">Книги</span></div>
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent" src="/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">лекции</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
110
app/themes/gestalt/views/psychologist/view.php
Normal file
110
app/themes/gestalt/views/psychologist/view.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* @var \kernel\app_modules\gestalt_profile\models\Gestalt_profile $profile
|
||||
* @var string $resources ;
|
||||
*/
|
||||
?>
|
||||
|
||||
<main>
|
||||
<nav class="max-w-[1083px] px-[25px] mx-auto">
|
||||
<ol class="flex flex-wrap text-middleGrey font-[350] my-[50px]">
|
||||
<li><a href="/">главная</a></li>
|
||||
<li><a href="/psychologists"><span class="mx-[2px]">/</span>участники</a></li>
|
||||
<li><a href="/psychologist/<?= $profile->id ?>"><span class="mx-[2px]">/</span><?= $profile->fio ?? '' ?> </a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<div class=" flex flex-wrap justify-center gap-[35px] px-[25px] max-w-[1083px] m-auto">
|
||||
<div class="bg-white p-[15px] w-fit rounded-[6px] mr-auto"><img alt="human" loading="lazy" width="335"
|
||||
height="355" decoding="async" data-nimg="1"
|
||||
class=""
|
||||
style="color:transparent"
|
||||
src="<?= $profile->photo ?? $resources . '/out/images/mok_human.svg' ?>"/>
|
||||
</div>
|
||||
<div class="flex flex-col w-full lg:w-auto">
|
||||
<h2
|
||||
class="uppercase lg:text-start lg:max-w-[390px] text-[40px] leading-[48px]">
|
||||
<?= $profile->fio ?>
|
||||
</h2>
|
||||
<div class="flex gap-[17px] mt-[8px] mb-[25px]">
|
||||
<img alt="location" loading="lazy" width="18" height="22"
|
||||
decoding="async" data-nimg="1"
|
||||
style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/location.svg"/>
|
||||
<span class="text-lightBlack text-[18px]">
|
||||
<?= $profile->city ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[8px] mb-[70px] lg:mb-[23px]"><span class="text-blue text-[16px]">Статус в сообществе:</span>
|
||||
<div class="flex gap-[13px]">
|
||||
<?php foreach ($profile->communityStatusArr as $item): ?>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit text-[14px] px-[9.5px] rounded-[6px] border-[0.5px] text-blue font-[400] max-w-[114px] w-full min-h-[34px] h-full">
|
||||
<span class=""><?= $item ?></span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-[35px] pb-[10px] pt-[35px] sm:py-[47.5px] sm:px-[53px] gap-[20px] sm:gap-[52px] bg-white text-[20px] flex flex-col sm:flex-row rounded-[12px] relative">
|
||||
<div class="flex gap-[13px]"><img alt="phone" loading="lazy" width="18" height="18" decoding="async"
|
||||
data-nimg="1" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/phone.svg"/><span><?= $profile->phone ?? '' ?></span></div>
|
||||
<div class="flex gap-[13px]"><img alt="phone" loading="lazy" width="18" height="18" decoding="async"
|
||||
data-nimg="1" style="color:transparent" src="<?= $resources ?>/out/images/mail.svg"/><span><?= $profile->email ?? '' ?></span>
|
||||
</div>
|
||||
<div class="flex absolute top-[-20px] min-w-[47px] h-[47px] bg-white items-center justify-center rounded-full sm:right-[-25px] sm:top-[38px]">
|
||||
<a class="flex justify-center items-center w-[41px] h-[41px] bg-blue rounded-full" href=""><img
|
||||
alt="logo_tg" loading="lazy" width="1" height="1" decoding="async" data-nimg="1"
|
||||
class="w-auto h-auto" style="color:transparent" src="<?= $resources ?>/out/images/logo_tg.svg"/> </a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col rounded-[6px] border-[1px] border-white max-w-[1032px] mx-[25px] lg:mx-auto pt-[41px] px-[34px] pb-[30px] gap-[12px] mb-[50px] mt-[36px]">
|
||||
<h3 class="uppercase text-[26px]">Специализация</h3>
|
||||
<?php \app\themes\gestalt\widgets\SpecializationListWidget::create(['items' => $profile->specializationArr])->run(); ?>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[30px] mx-[25px] lg:max-w-[910px] lg:mx-auto mb-[100px] ">
|
||||
<h3 class="uppercase text-black text-[26px]">Описание профессиональной деятельности</h3>
|
||||
<?= $profile->description_of_professional_activity ?? '' ?>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[80px]">
|
||||
<div class="hidden lg:flex bg-blue rounded-[25px] relative max-w-[1033px] w-full m-auto pt-[59.5px] pb-[59.5px] h-[234px] text-center justify-center items-center">
|
||||
<p class="text-white text-[32px] max-w-[671px] font-[700]">Через собственное развитие мы развиваем и
|
||||
популяризируем гештальт-подход</p><img alt="palm" loading="lazy" width="217" height="254"
|
||||
decoding="async" data-nimg="1"
|
||||
class=" absolute right-0 top-[-20px]" style="color:transparent"
|
||||
src="<?= $resources ?>/out/images/palm.svg"/></div>
|
||||
<div class="flex-col w-full max-w-[1083px] px-[25px] flex gap-[53px] items-end m-auto md:flex-row">
|
||||
<div class="flex justify-center md:justify-start md:max-w-[645px] flex-wrap gap-x-[15px] gap-y-[12px]">
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">конференции</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">акредитации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">открытые сертификации</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">общие сборы</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">протоколы сборов</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">новости сайта</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">календарь событий</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">сайт мги</span></div>
|
||||
<div class="flex items-center justify-center font-[400] border-blue w-fit px-[10px] py-[6.5px] rounded-[6px] border-[1px] text-[16px] text-blue font-[700]">
|
||||
<span class="">вопросы и ответы</span></div>
|
||||
</div>
|
||||
<div class="flex gap-[19px] m-auto">
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent" src="<?= $resources ?>/out/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">Книги</span></div>
|
||||
<div class="flex border-[4px] border-white rounded-[6px] items-center w-[160px] h-[120px] justify-center relative">
|
||||
<img alt="arrow" loading="lazy" width="11" height="11" decoding="async" data-nimg="1"
|
||||
class="absolute top-[-18px]" style="color:transparent" src="<?= $resources ?>/out/images/chevronDown.svg"/><span
|
||||
class="text-[26px] text-black uppercase">лекции</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
24
app/themes/gestalt/widgets/MainEventsList.php
Normal file
24
app/themes/gestalt/widgets/MainEventsList.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\gestalt\widgets;
|
||||
|
||||
use kernel\app_modules\event\models\Event;
|
||||
use kernel\Widget;
|
||||
|
||||
class MainEventsList extends Widget
|
||||
{
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = APP_DIR . "/themes/gestalt/views/event/";
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$events = Event::query()->limit(5)->get();
|
||||
|
||||
$this->cgView->render('_main_events_list.php', ['events' => $events]);
|
||||
}
|
||||
|
||||
}
|
29
app/themes/gestalt/widgets/MainPsychologistsList.php
Normal file
29
app/themes/gestalt/widgets/MainPsychologistsList.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\gestalt\widgets;
|
||||
|
||||
use kernel\app_modules\gestalt_profile\models\Gestalt_profile;
|
||||
use kernel\Widget;
|
||||
|
||||
/**
|
||||
* @property array $data
|
||||
*/
|
||||
class MainPsychologistsList extends Widget
|
||||
{
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = APP_DIR . "/themes/gestalt/views/psychologist/";
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$count = $this->data['count'];
|
||||
|
||||
$psychologists = Gestalt_profile::where("show_on_main", 1)->limit($count)->get();
|
||||
|
||||
$this->cgView->render('_main_psychologists_list.php', ['psychologists' => $psychologists]);
|
||||
}
|
||||
|
||||
}
|
32
app/themes/gestalt/widgets/SpecializationListWidget.php
Normal file
32
app/themes/gestalt/widgets/SpecializationListWidget.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace app\themes\gestalt\widgets;
|
||||
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\Widget;
|
||||
|
||||
/**
|
||||
* @property array $data
|
||||
*/
|
||||
class SpecializationListWidget extends Widget
|
||||
{
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = APP_DIR . "/themes/gestalt/views/psychologist/";
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$totalItems = count($this->data['items']);
|
||||
$itemsPerColumn = ceil($totalItems / 3);
|
||||
// Разбиваем массив на три части
|
||||
if (empty($this->data['items'])){
|
||||
return;
|
||||
}
|
||||
$columns = array_chunk($this->data['items'], $itemsPerColumn);
|
||||
|
||||
$this->cgView->render('_specialization_list.php', ['columns' => $columns]);
|
||||
}
|
||||
|
||||
}
|
482
kernel/EloquentDataProvider.php
Normal file
482
kernel/EloquentDataProvider.php
Normal file
@ -0,0 +1,482 @@
|
||||
<?php
|
||||
|
||||
namespace kernel;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class EloquentDataProvider
|
||||
{
|
||||
protected Builder $query;
|
||||
protected int $perPage = 15;
|
||||
protected array $filters = [];
|
||||
protected array $sort = [];
|
||||
protected array $with = [];
|
||||
protected array $withCount = [];
|
||||
protected array $search = [];
|
||||
protected array $allowedFilters = [];
|
||||
protected array $allowedSorts = [];
|
||||
protected array $allowedSearch = [];
|
||||
protected array $defaultSort = [];
|
||||
protected array $beforeQueryCallbacks = [];
|
||||
protected array $afterQueryCallbacks = [];
|
||||
|
||||
protected array $paginationTemplates = [];
|
||||
|
||||
public function __construct(Builder $query)
|
||||
{
|
||||
$this->query = $query;
|
||||
}
|
||||
|
||||
public function setPerPage(int $perPage): self
|
||||
{
|
||||
$this->perPage = max(1, $perPage);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFilters(array $filters): self
|
||||
{
|
||||
$this->filters = $filters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSort(array $sort): self
|
||||
{
|
||||
$this->sort = $sort;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function with(array $relations): self
|
||||
{
|
||||
$this->with = $relations;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withCount(array $relations): self
|
||||
{
|
||||
$this->withCount = $relations;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSearch(array $search): self
|
||||
{
|
||||
$this->search = $search;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function allowFilters(array $filters): self
|
||||
{
|
||||
$this->allowedFilters = $filters;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function allowSorts(array $sorts): self
|
||||
{
|
||||
$this->allowedSorts = $sorts;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function allowSearch(array $fields): self
|
||||
{
|
||||
$this->allowedSearch = $fields;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDefaultSort(array $sort): self
|
||||
{
|
||||
$this->defaultSort = $sort;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function beforeQuery(callable $callback): self
|
||||
{
|
||||
$this->beforeQueryCallbacks[] = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function afterQuery(callable $callback): self
|
||||
{
|
||||
$this->afterQueryCallbacks[] = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function applyFilters(): void
|
||||
{
|
||||
foreach ($this->filters as $field => $value) {
|
||||
if (!$this->isFilterAllowed($field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$this->applyArrayFilter($field, $value);
|
||||
} elseif (Str::contains($field, '.')) {
|
||||
$this->applyRelationFilter($field, $value);
|
||||
} elseif ($value !== null && $value !== '') {
|
||||
$this->query->where($field, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyArrayFilter(string $field, array $value): void
|
||||
{
|
||||
$operator = strtolower($value[0] ?? null);
|
||||
$operand = $value[1] ?? null;
|
||||
|
||||
switch ($operator) {
|
||||
case 'in':
|
||||
$this->query->whereIn($field, (array)$operand);
|
||||
break;
|
||||
case 'not in':
|
||||
$this->query->whereNotIn($field, (array)$operand);
|
||||
break;
|
||||
case 'between':
|
||||
$this->query->whereBetween($field, (array)$operand);
|
||||
break;
|
||||
case 'not between':
|
||||
$this->query->whereNotBetween($field, (array)$operand);
|
||||
break;
|
||||
case 'null':
|
||||
$this->query->whereNull($field);
|
||||
break;
|
||||
case 'not null':
|
||||
$this->query->whereNotNull($field);
|
||||
break;
|
||||
case 'like':
|
||||
$this->query->where($field, 'like', "%{$operand}%");
|
||||
break;
|
||||
case '>':
|
||||
case '<':
|
||||
case '>=':
|
||||
case '<=':
|
||||
case '!=':
|
||||
$this->query->where($field, $operator, $operand);
|
||||
break;
|
||||
default:
|
||||
$this->query->whereIn($field, $value);
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyRelationFilter(string $field, $value): void
|
||||
{
|
||||
[$relation, $column] = explode('.', $field, 2);
|
||||
|
||||
$this->query->whereHas($relation, function ($query) use ($column, $value) {
|
||||
if (is_array($value)) {
|
||||
$query->whereIn($column, $value);
|
||||
} else {
|
||||
$query->where($column, $value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function applySort(): void
|
||||
{
|
||||
if (empty($this->sort) && !empty($this->defaultSort)) {
|
||||
$this->sort = $this->defaultSort;
|
||||
}
|
||||
|
||||
foreach ($this->sort as $field => $direction) {
|
||||
if (!$this->isSortAllowed($field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$direction = strtolower($direction) === 'desc' ? 'desc' : 'asc';
|
||||
|
||||
if (Str::contains($field, '.')) {
|
||||
$this->applyRelationSort($field, $direction);
|
||||
} else {
|
||||
$this->query->orderBy($field, $direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyRelationSort(string $field, string $direction): void
|
||||
{
|
||||
[$relation, $column] = explode('.', $field, 2);
|
||||
|
||||
$this->query->with([$relation => function ($query) use ($column, $direction) {
|
||||
$query->orderBy($column, $direction);
|
||||
}]);
|
||||
}
|
||||
|
||||
protected function applySearch(): void
|
||||
{
|
||||
if (empty($this->search) || empty($this->allowedSearch)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$searchTerm = Arr::get($this->search, 'term', '');
|
||||
if (empty($searchTerm)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->query->where(function ($query) use ($searchTerm) {
|
||||
foreach ($this->allowedSearch as $field) {
|
||||
if (Str::contains($field, '.')) {
|
||||
[$relation, $column] = explode('.', $field, 2);
|
||||
$query->orWhereHas($relation, function ($q) use ($column, $searchTerm) {
|
||||
$q->where($column, 'like', "%{$searchTerm}%");
|
||||
});
|
||||
} else {
|
||||
$query->orWhere($field, 'like', "%{$searchTerm}%");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function applyRelations(): void
|
||||
{
|
||||
if (!empty($this->with)) {
|
||||
$this->query->with($this->with);
|
||||
}
|
||||
|
||||
if (!empty($this->withCount)) {
|
||||
$this->query->withCount($this->withCount);
|
||||
}
|
||||
}
|
||||
|
||||
protected function isFilterAllowed(string $field): bool
|
||||
{
|
||||
if (empty($this->allowedFilters)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$baseField = Str::before($field, '.');
|
||||
|
||||
return in_array($field, $this->allowedFilters) ||
|
||||
in_array($baseField, $this->allowedFilters);
|
||||
}
|
||||
|
||||
protected function isSortAllowed(string $field): bool
|
||||
{
|
||||
if (empty($this->allowedSorts)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$baseField = Str::before($field, '.');
|
||||
|
||||
return in_array($field, $this->allowedSorts) ||
|
||||
in_array($baseField, $this->allowedSorts);
|
||||
}
|
||||
|
||||
protected function executeCallbacks(array $callbacks): void
|
||||
{
|
||||
foreach ($callbacks as $callback) {
|
||||
call_user_func($callback, $this->query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение данных с ручной пагинацией
|
||||
*/
|
||||
public function getManualPaginated(int $page = 1, int $perPage = null): array
|
||||
{
|
||||
$perPage = $perPage ?? $this->perPage;
|
||||
|
||||
$this->applyRelations();
|
||||
$this->applyFilters();
|
||||
$this->applySearch();
|
||||
$this->applySort();
|
||||
|
||||
$total = $this->query->count();
|
||||
$results = $this->query
|
||||
->offset(($page - 1) * $perPage)
|
||||
->limit($perPage)
|
||||
->get();
|
||||
|
||||
return [
|
||||
'data' => $results,
|
||||
'meta' => [
|
||||
'total' => $total,
|
||||
'per_page' => $perPage,
|
||||
'current_page' => $page,
|
||||
'last_page' => ceil($total / $perPage),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function getAll(): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
$this->executeCallbacks($this->beforeQueryCallbacks);
|
||||
|
||||
$this->applyRelations();
|
||||
$this->applyFilters();
|
||||
$this->applySearch();
|
||||
$this->applySort();
|
||||
|
||||
$result = $this->query->get();
|
||||
|
||||
$this->executeCallbacks($this->afterQueryCallbacks);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getFirst(): ?\Illuminate\Database\Eloquent\Model
|
||||
{
|
||||
$this->executeCallbacks($this->beforeQueryCallbacks);
|
||||
|
||||
$this->applyRelations();
|
||||
$this->applyFilters();
|
||||
$this->applySearch();
|
||||
$this->applySort();
|
||||
|
||||
$result = $this->query->first();
|
||||
|
||||
$this->executeCallbacks($this->afterQueryCallbacks);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерирует массив с основными ссылками пагинации
|
||||
*
|
||||
* @param array $meta Мета-информация из getManualPaginated()
|
||||
* @param string|null $baseUrl Базовый URL (если null - определит автоматически)
|
||||
* @return array
|
||||
*/
|
||||
public function getPaginationLinks(array $meta, ?string $baseUrl = null): array
|
||||
{
|
||||
$currentPage = $meta['current_page'];
|
||||
$lastPage = $meta['last_page'];
|
||||
|
||||
// Определяем базовый URL
|
||||
$baseUrl = $this->normalizeBaseUrl($baseUrl);
|
||||
|
||||
$links = [
|
||||
'first' => null,
|
||||
'previous' => null,
|
||||
'current' => $this->buildPageUrl($baseUrl, $currentPage),
|
||||
'next' => null,
|
||||
'last' => null,
|
||||
];
|
||||
|
||||
// Первая страница (если не на первой)
|
||||
if ($currentPage > 1) {
|
||||
$links['first'] = $this->buildPageUrl($baseUrl, 1);
|
||||
}
|
||||
|
||||
// Предыдущая страница
|
||||
if ($currentPage > 1) {
|
||||
$links['previous'] = $this->buildPageUrl($baseUrl, $currentPage - 1);
|
||||
}
|
||||
|
||||
// Следующая страница
|
||||
if ($currentPage < $lastPage) {
|
||||
$links['next'] = $this->buildPageUrl($baseUrl, $currentPage + 1);
|
||||
}
|
||||
|
||||
// Последняя страница (если не на последней)
|
||||
if ($currentPage < $lastPage) {
|
||||
$links['last'] = $this->buildPageUrl($baseUrl, $lastPage);
|
||||
}
|
||||
|
||||
// Дополнительная мета-информация
|
||||
$links['meta'] = [
|
||||
'current_page' => $currentPage,
|
||||
'last_page' => $lastPage,
|
||||
'per_page' => $meta['per_page'],
|
||||
'total' => $meta['total']
|
||||
];
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Нормализует базовый URL
|
||||
*/
|
||||
protected function normalizeBaseUrl(?string $url): string
|
||||
{
|
||||
if ($url !== null) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (function_exists('url')) {
|
||||
// Laravel
|
||||
return url()->current();
|
||||
}
|
||||
|
||||
// Чистый PHP
|
||||
$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || ($_SERVER['SERVER_PORT'] ?? null) == 443) ? 'https://' : 'http://';
|
||||
|
||||
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
|
||||
$uri = $_SERVER['REQUEST_URI'] ?? '/';
|
||||
|
||||
// Удаляем параметр page если он есть
|
||||
$uri = preg_replace('/([?&])page=[^&]*(&|$)/', '$1', $uri);
|
||||
|
||||
return $protocol . $host . rtrim($uri, '?&');
|
||||
}
|
||||
|
||||
/**
|
||||
* Строит URL для конкретной страницы
|
||||
*/
|
||||
protected function buildPageUrl(string $baseUrl, int $page): string
|
||||
{
|
||||
if ($page <= 1) {
|
||||
return $baseUrl; // Первая страница без параметра
|
||||
}
|
||||
|
||||
$separator = strpos($baseUrl, '?') === false ? '?' : '&';
|
||||
return $baseUrl . $separator . 'page=' . $page;
|
||||
}
|
||||
|
||||
public function renderPaginationLinks(array $meta, string $url, int $showPages = 5): string
|
||||
{
|
||||
$currentPage = $meta['current_page'];
|
||||
$lastPage = $meta['last_page'];
|
||||
|
||||
// Определяем диапазон страниц для отображения
|
||||
$startPage = max(1, $currentPage - floor($showPages / 2));
|
||||
$endPage = min($lastPage, $startPage + $showPages - 1);
|
||||
|
||||
$html = '<div class="pagination">';
|
||||
|
||||
// Кнопка "Назад"
|
||||
if ($currentPage > 1) {
|
||||
$html .= '<a href="' . $this->buildPageUrl($url, $currentPage - 1) . '" class="page-link prev">« Назад</a>';
|
||||
}
|
||||
|
||||
// Первая страница
|
||||
if ($startPage > 1) {
|
||||
$html .= '<a href="' . $this->buildPageUrl($url, 1) . '" class="page-link">1</a>';
|
||||
if ($startPage > 2) {
|
||||
$html .= '<span class="page-dots">...</span>';
|
||||
}
|
||||
}
|
||||
|
||||
// Основные страницы
|
||||
for ($i = $startPage; $i <= $endPage; $i++) {
|
||||
$activeClass = $i == $currentPage ? ' active' : '';
|
||||
$html .= '<a href="' . $this->buildPageUrl($url, $i) . '" class="page-link' . $activeClass . '">' . $i . '</a>';
|
||||
}
|
||||
|
||||
// Последняя страница
|
||||
if ($endPage < $lastPage) {
|
||||
if ($endPage < $lastPage - 1) {
|
||||
$html .= '<span class="page-dots">...</span>';
|
||||
}
|
||||
$html .= '<a href="' . $this->buildPageUrl($url, $lastPage) . '" class="page-link">' . $lastPage . '</a>';
|
||||
}
|
||||
|
||||
// Кнопка "Вперед"
|
||||
if ($currentPage < $lastPage) {
|
||||
$html .= '<a href="' . $this->buildPageUrl($url, $currentPage + 1) . '" class="page-link next">Вперед »</a>';
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function setPaginationTemplate(array $tpl)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function getQuery(): Builder
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
}
|
@ -209,11 +209,11 @@ class EntityRelation
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getAdditionalPropertyByEntityId(string $entity, string $entity_id, string $additionalPropertySlug): string
|
||||
public function getAdditionalPropertyByEntityId(string $entity, string $entity_id, string $additionalPropertySlug, array $params = []): string
|
||||
{
|
||||
$moduleClass = $this->getAdditionalPropertyClassBySlug($additionalPropertySlug);
|
||||
if ($moduleClass and method_exists($moduleClass, "getItem")) {
|
||||
return $moduleClass->getItem($entity, $entity_id);
|
||||
return $moduleClass->getItem($entity, $entity_id, $params);
|
||||
}
|
||||
|
||||
return "";
|
||||
@ -276,4 +276,20 @@ class EntityRelation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function callModuleMethod(string $slug, string $method, array $params)
|
||||
{
|
||||
$module = $this->moduleService->getModuleInfoBySlug($slug);
|
||||
if (isset($module['module_class'])) {
|
||||
$moduleClass = new $module['module_class']();
|
||||
if (method_exists($moduleClass, $method)) {
|
||||
|
||||
return call_user_func_array([$moduleClass, $method], $params);
|
||||
} else {
|
||||
echo "Метод $method не существует";
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -132,6 +132,18 @@ class Request
|
||||
return $_GET[$param] ?? $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $param
|
||||
* @return mixed
|
||||
*/
|
||||
public function except(string $param): mixed
|
||||
{
|
||||
$params = $this->get();
|
||||
unset($param);
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Возвращает POST - параметр.
|
||||
|
@ -63,15 +63,6 @@ $assets = new \kernel\admin_themes\default\DefaultAdminThemeAssets($resources)
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/admin/logout">Выход</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">About</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Portfolio</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
63
kernel/app_modules/event/EventModule.php
Normal file
63
kernel/app_modules/event/EventModule.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\event;
|
||||
|
||||
use kernel\app_modules\event\models\Event;
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\Module;
|
||||
use kernel\modules\menu\service\MenuService;
|
||||
use kernel\services\MigrationService;
|
||||
|
||||
class EventModule extends Module
|
||||
{
|
||||
|
||||
public MenuService $menuService;
|
||||
public MigrationService $migrationService;
|
||||
public function __construct()
|
||||
{
|
||||
$this->menuService = new MenuService();
|
||||
$this->migrationService = new MigrationService();
|
||||
}
|
||||
|
||||
public function init(): void
|
||||
{
|
||||
$this->migrationService->runAtPath("{KERNEL_APP_MODULES}/event/migrations");
|
||||
|
||||
$this->menuService->createItem([
|
||||
"label" => "Мероприятия",
|
||||
"url" => "/admin/event",
|
||||
"slug" => "event",
|
||||
]);
|
||||
|
||||
$this->menuService->createItem([
|
||||
"label" => "Список",
|
||||
"url" => "/admin/event",
|
||||
"slug" => "event_list",
|
||||
"parent_slug" => "event",
|
||||
]);
|
||||
$this->menuService->createItem([
|
||||
"label" => "Создать",
|
||||
"url" => "/admin/event/create",
|
||||
"slug" => "event_create",
|
||||
"parent_slug" => "event",
|
||||
]);
|
||||
$this->menuService->createItem([
|
||||
"label" => "Контакты",
|
||||
"url" => "/admin/event-contacts",
|
||||
"slug" => "event_contacts",
|
||||
"parent_slug" => "event",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deactivate(): void
|
||||
{
|
||||
$this->migrationService->rollbackAtPath("{KERNEL_APP_MODULES}/event/migrations");
|
||||
$this->menuService->removeItemBySlug("event_contacts");
|
||||
$this->menuService->removeItemBySlug("event_create");
|
||||
$this->menuService->removeItemBySlug("event_list");
|
||||
$this->menuService->removeItemBySlug("event");
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\event\controllers;
|
||||
|
||||
use Exception;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
use kernel\AdminController;
|
||||
use kernel\app_modules\event\models\forms\CreateEventContactForm;
|
||||
use kernel\app_modules\event\models\EventContact;
|
||||
use kernel\app_modules\event\services\EventContactService;
|
||||
use kernel\helpers\Debug;
|
||||
|
||||
class EventContactController extends AdminController
|
||||
{
|
||||
private EventContactService $eventService;
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = KERNEL_APP_MODULES_DIR . "/event/views/eventcontact/";
|
||||
$this->eventService = new EventContactService();
|
||||
}
|
||||
|
||||
public function actionCreate(): void
|
||||
{
|
||||
$this->cgView->render("form.php");
|
||||
}
|
||||
|
||||
#[NoReturn] public function actionAdd(): void
|
||||
{
|
||||
$eventForm = new CreateEventContactForm();
|
||||
$eventForm->load($_REQUEST);
|
||||
if ($eventForm->validate()){
|
||||
$event = $this->eventService->create($eventForm);
|
||||
if ($event){
|
||||
$this->redirect("/admin/event-contacts/view/" . $event->id);
|
||||
}
|
||||
}
|
||||
$this->redirect("/admin/event-contacts/create");
|
||||
}
|
||||
|
||||
public function actionIndex($page_number = 1): void
|
||||
{
|
||||
$this->cgView->render("index.php", ['page_number' => $page_number]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionView($id): void
|
||||
{
|
||||
$event = EventContact::find($id);
|
||||
|
||||
if (!$event){
|
||||
throw new Exception(message: "The event contact not found");
|
||||
}
|
||||
$this->cgView->render("view.php", ['event' => $event]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionUpdate($id): void
|
||||
{
|
||||
$model = EventContact::find($id);
|
||||
if (!$model){
|
||||
throw new Exception(message: "The event contact not found");
|
||||
}
|
||||
|
||||
$this->cgView->render("form.php", ['model' => $model]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionEdit($id): void
|
||||
{
|
||||
$event = EventContact::find($id);
|
||||
if (!$event){
|
||||
throw new Exception(message: "The event not found");
|
||||
}
|
||||
$eventForm = new CreateEventContactForm();
|
||||
$eventService = new EventContactService();
|
||||
$eventForm->load($_REQUEST);
|
||||
if ($eventForm->validate()) {
|
||||
$event = $eventService->update($eventForm, $event);
|
||||
if ($event) {
|
||||
$this->redirect("/admin/event-contacts/view/" . $event->id);
|
||||
}
|
||||
}
|
||||
$this->redirect("/admin/event-contacts/update/" . $id);
|
||||
}
|
||||
|
||||
#[NoReturn] public function actionDelete($id): void
|
||||
{
|
||||
$event = EventContact::find($id)->first();
|
||||
$event->delete();
|
||||
$this->redirect("/admin/event-contacts/");
|
||||
}
|
||||
}
|
109
kernel/app_modules/event/controllers/EventController.php
Normal file
109
kernel/app_modules/event/controllers/EventController.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\event\controllers;
|
||||
|
||||
use Exception;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
use kernel\AdminController;
|
||||
use kernel\app_modules\event\models\forms\CreateEventForm;
|
||||
use kernel\app_modules\event\models\Event;
|
||||
use kernel\app_modules\event\services\EventService;
|
||||
use kernel\EntityRelation;
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\Request;
|
||||
|
||||
class EventController extends AdminController
|
||||
{
|
||||
private EventService $eventService;
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = KERNEL_APP_MODULES_DIR . "/event/views/";
|
||||
$this->eventService = new EventService();
|
||||
}
|
||||
|
||||
public function actionCreate(): void
|
||||
{
|
||||
$this->cgView->render("form.php");
|
||||
}
|
||||
|
||||
#[NoReturn] public function actionAdd(): void
|
||||
{
|
||||
$eventForm = new CreateEventForm();
|
||||
$eventForm->load($_REQUEST);
|
||||
if ($eventForm->validate()){
|
||||
$event = $this->eventService->create($eventForm);
|
||||
|
||||
$entityRelation = new EntityRelation();
|
||||
$entityRelation->saveEntityRelation(entity: "event", model: $event, request: new Request());
|
||||
|
||||
if ($event){
|
||||
$this->redirect("/admin/event/view/" . $event->id);
|
||||
}
|
||||
}
|
||||
$this->redirect("/admin/event/create");
|
||||
}
|
||||
|
||||
public function actionIndex($page_number = 1): void
|
||||
{
|
||||
$this->cgView->render("index.php", ['page_number' => $page_number]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionView($id): void
|
||||
{
|
||||
$event = Event::find($id);
|
||||
|
||||
if (!$event){
|
||||
throw new Exception(message: "The event not found");
|
||||
}
|
||||
$this->cgView->render("view.php", ['event' => $event]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionUpdate($id): void
|
||||
{
|
||||
$model = Event::find($id);
|
||||
if (!$model){
|
||||
throw new Exception(message: "The event not found");
|
||||
}
|
||||
|
||||
$this->cgView->render("form.php", ['model' => $model]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionEdit($id): void
|
||||
{
|
||||
$event = Event::find($id);
|
||||
if (!$event){
|
||||
throw new Exception(message: "The event not found");
|
||||
}
|
||||
$eventForm = new CreateEventForm();
|
||||
$eventService = new EventService();
|
||||
$eventForm->load($_REQUEST);
|
||||
if ($eventForm->validate()) {
|
||||
$event = $eventService->update($eventForm, $event);
|
||||
|
||||
$entityRelation = new EntityRelation();
|
||||
$entityRelation->saveEntityRelation(entity: "event", model: $event, request: new Request());
|
||||
|
||||
if ($event) {
|
||||
$this->redirect("/admin/event/view/" . $event->id);
|
||||
}
|
||||
}
|
||||
$this->redirect("/admin/event/update/" . $id);
|
||||
}
|
||||
|
||||
#[NoReturn] public function actionDelete($id): void
|
||||
{
|
||||
$event = Event::find($id)->first();
|
||||
$event->delete();
|
||||
$this->redirect("/admin/event/");
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<?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
|
||||
{
|
||||
\kernel\App::$db->schema->create('event', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title', 255)->nullable(false);
|
||||
$table->string('type', 255)->nullable(false);
|
||||
$table->integer('hours_count')->nullable(false);
|
||||
$table->dateTime('date_start')->nullable(false);
|
||||
$table->dateTime('date_end')->nullable(true);
|
||||
$table->string('place')->nullable(false);
|
||||
$table->text('event_format')->nullable(true);
|
||||
$table->text('description')->nullable(false);
|
||||
$table->text('additional_info')->nullable(true);
|
||||
$table->integer('status')->nullable(true)->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
\kernel\App::$db->schema->create('event_contact', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title', 255)->nullable(false);
|
||||
$table->string('type', 255)->nullable(false);
|
||||
$table->integer('event_id')->nullable(false);
|
||||
$table->integer('status')->nullable(true)->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
\kernel\App::$db->schema->dropIfExists('event_contact');
|
||||
\kernel\App::$db->schema->dropIfExists('event');
|
||||
}
|
||||
};
|
110
kernel/app_modules/event/models/Event.php
Normal file
110
kernel/app_modules/event/models/Event.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\event\models;
|
||||
|
||||
use DateTime;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use kernel\helpers\Debug;
|
||||
|
||||
// Добавить @property
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $status
|
||||
* @property int $hours_count
|
||||
* @property string $title
|
||||
* @property string $type
|
||||
* @property string $date_start
|
||||
* @property string $dateStartFormated
|
||||
* @property string $dateStartFormatedToForm
|
||||
* @property string $dateEndFormatedToForm
|
||||
* @property string $dateEndFormated
|
||||
* @property string $date_end
|
||||
* @property string $place
|
||||
* @property string $event_format
|
||||
* @property string $description
|
||||
* @property string $additional_info
|
||||
*/
|
||||
class Event extends Model
|
||||
{
|
||||
const DISABLE_STATUS = 0;
|
||||
const ACTIVE_STATUS = 1;
|
||||
|
||||
protected $table = 'event';
|
||||
|
||||
protected $fillable = ['title', 'type', 'hours_count', 'date_start', 'date_end', 'place', 'event_format', 'description', 'additional_info', 'status'];
|
||||
|
||||
public static function labels(): array
|
||||
{
|
||||
return [
|
||||
'title' => 'Название',
|
||||
'type' => 'Тип',
|
||||
'hours_count' => 'Количество часов',
|
||||
'date_start' => 'Дата начала',
|
||||
'date_end' => 'Дата окончания',
|
||||
'place' => 'Место',
|
||||
'event_format' => 'Формат',
|
||||
'description' => 'Описание',
|
||||
'additional_info' => 'Дополнительная информация',
|
||||
'status' => 'Статус',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getStatus(): array
|
||||
{
|
||||
return [
|
||||
self::DISABLE_STATUS => "Не активный",
|
||||
self::ACTIVE_STATUS => "Активный",
|
||||
];
|
||||
}
|
||||
|
||||
public function contacts(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(EventContact::class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getDateStartFormatedAttribute(): string
|
||||
{
|
||||
$startDate = new DateTime($this->date_start);
|
||||
|
||||
return $startDate->format("d-m-Y");
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getDateStartFormatedToFormAttribute(): string
|
||||
{
|
||||
$startDate = new DateTime($this->date_start);
|
||||
|
||||
return $startDate->format("Y-m-d");
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getDateEndFormatedAttribute(): string
|
||||
{
|
||||
$endDate = new DateTime($this->date_end);
|
||||
|
||||
return $endDate->format("d-m-Y");
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getDateEndFormatedToFormAttribute(): string
|
||||
{
|
||||
$endDate = new DateTime($this->date_end);
|
||||
|
||||
return $endDate->format("Y-m-d");
|
||||
}
|
||||
|
||||
|
||||
}
|
61
kernel/app_modules/event/models/EventContact.php
Normal file
61
kernel/app_modules/event/models/EventContact.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\event\models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
// Добавить @property
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $status
|
||||
* @property int $event_id
|
||||
* @property string $title
|
||||
* @property string $type
|
||||
*/
|
||||
class EventContact extends Model
|
||||
{
|
||||
const DISABLE_STATUS = 0;
|
||||
const ACTIVE_STATUS = 1;
|
||||
|
||||
const TYPE_EMAIL = 'email';
|
||||
const TYPE_PHONE = 'phone';
|
||||
const TYPE_TG = 'tg';
|
||||
|
||||
protected $table = 'event_contact';
|
||||
|
||||
protected $fillable = ['title', 'type', 'event_id', 'status']; // Заполнить массив. Пример: ['label', 'slug', 'status']
|
||||
|
||||
public static function labels(): array
|
||||
{
|
||||
return [
|
||||
'title' => 'Название',
|
||||
'type' => 'Тип',
|
||||
'event_id' => 'Мероприятие',
|
||||
'status' => 'Статус',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getStatus(): array
|
||||
{
|
||||
return [
|
||||
self::DISABLE_STATUS => "Не активный",
|
||||
self::ACTIVE_STATUS => "Активный",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getTypes(): array
|
||||
{
|
||||
return [
|
||||
self::TYPE_EMAIL => "Email",
|
||||
self::TYPE_PHONE => "Телефон",
|
||||
self::TYPE_TG => "Телеграм",
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\event\models\forms;
|
||||
|
||||
use kernel\FormModel;
|
||||
|
||||
class CreateEventContactForm extends FormModel
|
||||
{
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
// Заполнить массив правил
|
||||
// Пример:
|
||||
// return [
|
||||
// 'label' => 'required|min-str-len:5|max-str-len:30',
|
||||
// 'entity' => 'required',
|
||||
// 'slug' => '',
|
||||
// 'status' => ''
|
||||
// ];
|
||||
return [
|
||||
'title' => 'required|min-str-len:5|max-str-len:30',
|
||||
'type' => 'required|min-str-len:5|max-str-len:30',
|
||||
'event_id' => 'required|integer',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
34
kernel/app_modules/event/models/forms/CreateEventForm.php
Normal file
34
kernel/app_modules/event/models/forms/CreateEventForm.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\event\models\forms;
|
||||
|
||||
use kernel\FormModel;
|
||||
|
||||
class CreateEventForm extends FormModel
|
||||
{
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
// Заполнить массив правил
|
||||
// Пример:
|
||||
// return [
|
||||
// 'label' => 'required|min-str-len:5|max-str-len:30',
|
||||
// 'entity' => 'required',
|
||||
// 'slug' => '',
|
||||
// 'status' => ''
|
||||
// ];
|
||||
return [
|
||||
'title' => 'required|min-str-len:5|max-str-len:30',
|
||||
'type' => 'required|min-str-len:5|max-str-len:30',
|
||||
'hours_count' => 'required',
|
||||
'date_start' => 'date',
|
||||
'date_end' => 'date',
|
||||
'place' => 'required|min-str-len:5|max-str-len:30',
|
||||
'event_format' => '',
|
||||
'description' => 'required|min-str-len:5',
|
||||
'additional_info' => '',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
35
kernel/app_modules/event/routs/event.php
Normal file
35
kernel/app_modules/event/routs/event.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use kernel\App;
|
||||
use kernel\CgRouteCollector;
|
||||
use Phroute\Phroute\RouteCollector;
|
||||
|
||||
App::$collector->group(["prefix" => "admin"], function (CgRouteCollector $router) {
|
||||
App::$collector->group(["before" => "auth"], function (RouteCollector $router) {
|
||||
App::$collector->group(["prefix" => "event"], function (CGRouteCollector $router) {
|
||||
App::$collector->get('/', [\app\modules\event\controllers\EventController::class, 'actionIndex']);
|
||||
App::$collector->get('/page/{page_number}', [\app\modules\event\controllers\EventController::class, 'actionIndex']);
|
||||
App::$collector->get('/create', [\app\modules\event\controllers\EventController::class, 'actionCreate']);
|
||||
App::$collector->post("/", [\app\modules\event\controllers\EventController::class, 'actionAdd']);
|
||||
App::$collector->get('/view/{id}', [\app\modules\event\controllers\EventController::class, 'actionView']);
|
||||
App::$collector->any('/update/{id}', [\app\modules\event\controllers\EventController::class, 'actionUpdate']);
|
||||
App::$collector->any("/edit/{id}", [\app\modules\event\controllers\EventController::class, 'actionEdit']);
|
||||
App::$collector->get('/delete/{id}', [\app\modules\event\controllers\EventController::class, 'actionDelete']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
App::$collector->group(["prefix" => "admin"], function (CgRouteCollector $router) {
|
||||
App::$collector->group(["before" => "auth"], function (RouteCollector $router) {
|
||||
App::$collector->group(["prefix" => "event-contacts"], function (CGRouteCollector $router) {
|
||||
App::$collector->get('/', [\kernel\app_modules\event\controllers\EventContactController::class, 'actionIndex']);
|
||||
App::$collector->get('/page/{page_number}', [\kernel\app_modules\event\controllers\EventContactController::class, 'actionIndex']);
|
||||
App::$collector->get('/create', [\kernel\app_modules\event\controllers\EventContactController::class, 'actionCreate']);
|
||||
App::$collector->post("/", [\kernel\app_modules\event\controllers\EventContactController::class, 'actionAdd']);
|
||||
App::$collector->get('/view/{id}', [\kernel\app_modules\event\controllers\EventContactController::class, 'actionView']);
|
||||
App::$collector->any('/update/{id}', [\kernel\app_modules\event\controllers\EventContactController::class, 'actionUpdate']);
|
||||
App::$collector->any("/edit/{id}", [\kernel\app_modules\event\controllers\EventContactController::class, 'actionEdit']);
|
||||
App::$collector->get('/delete/{id}', [\kernel\app_modules\event\controllers\EventContactController::class, 'actionDelete']);
|
||||
});
|
||||
});
|
||||
});
|
41
kernel/app_modules/event/services/EventContactService.php
Normal file
41
kernel/app_modules/event/services/EventContactService.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\event\services;
|
||||
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\app_modules\event\models\EventContact;
|
||||
use kernel\FormModel;
|
||||
|
||||
class EventContactService
|
||||
{
|
||||
public function create(FormModel $form_model): false|EventContact
|
||||
{
|
||||
$model = new EventContact();
|
||||
// Пример заполнения:
|
||||
$model->title = $form_model->getItem('title');
|
||||
$model->type = $form_model->getItem('type');
|
||||
$model->event_id = $form_model->getItem('event_id');
|
||||
$model->status = $form_model->getItem('status');
|
||||
|
||||
if ($model->save()){
|
||||
return $model;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function update(FormModel $form_model, EventContact $event): false|EventContact
|
||||
{
|
||||
// Пример обновления:
|
||||
$event->title = $form_model->getItem('title');
|
||||
$event->type = $form_model->getItem('type');
|
||||
$event->event_id = $form_model->getItem('event_id');
|
||||
$event->status = $form_model->getItem('status');
|
||||
|
||||
if ($event->save()){
|
||||
return $event;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
58
kernel/app_modules/event/services/EventService.php
Normal file
58
kernel/app_modules/event/services/EventService.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\event\services;
|
||||
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\app_modules\event\models\Event;
|
||||
use kernel\FormModel;
|
||||
|
||||
class EventService
|
||||
{
|
||||
public function create(FormModel $form_model): false|Event
|
||||
{
|
||||
$model = new Event();
|
||||
$model->title = $form_model->getItem('title');
|
||||
$model->type = $form_model->getItem('type');
|
||||
$model->hours_count = $form_model->getItem('hours_count');
|
||||
$model->date_start = $form_model->getItem('date_start');
|
||||
$model->date_end = $form_model->getItem('date_end');
|
||||
$model->place = $form_model->getItem('place');
|
||||
$model->event_format = $form_model->getItem('event_format');
|
||||
$model->description = $form_model->getItem('description');
|
||||
$model->additional_info = $form_model->getItem('additional_info');
|
||||
$model->status = $form_model->getItem('status');
|
||||
|
||||
if ($model->save()){
|
||||
return $model;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function update(FormModel $form_model, Event $event): false|Event
|
||||
{
|
||||
$event->title = $form_model->getItem('title');
|
||||
$event->type = $form_model->getItem('type');
|
||||
$event->hours_count = $form_model->getItem('hours_count');
|
||||
$event->date_start = $form_model->getItem('date_start');
|
||||
$event->date_end = $form_model->getItem('date_end');
|
||||
$event->place = $form_model->getItem('place');
|
||||
$event->event_format = $form_model->getItem('event_format');
|
||||
$event->description = $form_model->getItem('description');
|
||||
$event->additional_info = $form_model->getItem('additional_info');
|
||||
$event->status = $form_model->getItem('status');
|
||||
|
||||
if ($event->save()){
|
||||
return $event;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getList(): array
|
||||
{
|
||||
return Event::select('id', 'title')->get()
|
||||
->pluck('title', 'id')
|
||||
->toArray();
|
||||
}
|
||||
}
|
71
kernel/app_modules/event/views/eventcontact/form.php
Normal file
71
kernel/app_modules/event/views/eventcontact/form.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* @var EventContact $model
|
||||
*/
|
||||
|
||||
use kernel\app_modules\event\models\EventContact;
|
||||
|
||||
$form = new \itguild\forms\ActiveForm();
|
||||
$form->beginForm(isset($model) ? "/admin/event-contacts/edit/" . $model->id : "/admin/event-contacts", 'multipart/form-data');
|
||||
|
||||
// Пример формы:
|
||||
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextInput::class, 'title', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Контакт',
|
||||
'value' => $model->title ?? ''
|
||||
])
|
||||
->setLabel("Контакт")
|
||||
->render();
|
||||
|
||||
$form->field(class: \itguild\forms\inputs\Select::class, name: "type", params: [
|
||||
'class' => "form-control",
|
||||
'value' => $model->type ?? ''
|
||||
])
|
||||
->setLabel("Тип контакта")
|
||||
->setOptions(EventContact::getTypes())
|
||||
->render();
|
||||
|
||||
$form->field(class: \itguild\forms\inputs\Select::class, name: "event_id", params: [
|
||||
'class' => "form-control",
|
||||
'value' => $model->event_id ?? ''
|
||||
])
|
||||
->setLabel("Мероприятие")
|
||||
->setOptions(\kernel\app_modules\event\services\EventService::getList())
|
||||
->render();
|
||||
|
||||
$form->field(class: \itguild\forms\inputs\Select::class, name: "status", params: [
|
||||
'class' => "form-control",
|
||||
'value' => $model->status ?? ''
|
||||
])
|
||||
->setLabel("Статус")
|
||||
->setOptions(EventContact::getStatus())
|
||||
->render();
|
||||
|
||||
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-submit", params: [
|
||||
'class' => "btn btn-primary ",
|
||||
'value' => 'Отправить',
|
||||
'typeInput' => 'submit'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-reset", params: [
|
||||
'class' => "btn btn-warning",
|
||||
'value' => 'Сбросить',
|
||||
'typeInput' => 'reset'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$form->endForm();
|
89
kernel/app_modules/event/views/eventcontact/index.php
Normal file
89
kernel/app_modules/event/views/eventcontact/index.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $event
|
||||
* @var int $page_number
|
||||
* @var \kernel\CgView $view
|
||||
*/
|
||||
|
||||
use kernel\app_modules\event\models\EventContact;
|
||||
use Itguild\EloquentTable\EloquentDataProvider;
|
||||
use Itguild\EloquentTable\ListEloquentTable;
|
||||
use kernel\widgets\IconBtn\IconBtnCreateWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnDeleteWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnEditWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnViewWidget;
|
||||
|
||||
$view->setTitle("Список event contacts");
|
||||
$view->setMeta([
|
||||
'description' => 'Список event contacts системы'
|
||||
]);
|
||||
|
||||
//Для использования таблицы с моделью, необходимо создать таблицу в базе данных
|
||||
$table = new ListEloquentTable(new EloquentDataProvider(EventContact::class, [
|
||||
'currentPage' => $page_number,
|
||||
'perPage' => 8,
|
||||
'params' => ["class" => "table table-bordered", "border" => "2"],
|
||||
'baseUrl' => "/admin/event-contacts"
|
||||
]));
|
||||
|
||||
|
||||
//$table = new \Itguild\Tables\ListJsonTable(json_encode(
|
||||
// [
|
||||
// 'meta' => [
|
||||
// 'total' => 0,
|
||||
// 'totalWithFilters' => 0,
|
||||
// 'columns' => [
|
||||
// 'title',
|
||||
// 'slug',
|
||||
// 'status',
|
||||
// ],
|
||||
// 'perPage' => 5,
|
||||
// 'currentPage' => 1,
|
||||
// 'baseUrl' => '/admin/some',
|
||||
// 'params' => [
|
||||
// 'class' => 'table table-bordered',
|
||||
// 'border' => 2
|
||||
// ]
|
||||
// ],
|
||||
// 'filters' => [],
|
||||
// 'data' => [],
|
||||
// ]
|
||||
//));
|
||||
|
||||
// Пример фильтра
|
||||
$table->columns([
|
||||
'title' => [
|
||||
'filter' => [
|
||||
'class' => \Itguild\Tables\Filter\InputTextFilter::class,
|
||||
'value' => $get['title'] ?? ''
|
||||
]
|
||||
],
|
||||
'event_id' => [
|
||||
'value' => function ($data) {
|
||||
$model = \kernel\app_modules\event\models\Event::find($data);
|
||||
return $model->title ?? '';
|
||||
}
|
||||
],
|
||||
'status' => [
|
||||
'value' => function ($data) {
|
||||
return EventContact::getStatus()[$data];
|
||||
}
|
||||
]
|
||||
]);
|
||||
|
||||
$table->beforePrint(function () {
|
||||
return IconBtnCreateWidget::create(['url' => '/admin/event-contacts/create'])->run();
|
||||
});
|
||||
|
||||
$table->addAction(function($row) {
|
||||
return IconBtnViewWidget::create(['url' => '/admin/event-contacts/view/' . $row['id']])->run();
|
||||
});
|
||||
$table->addAction(function($row) {
|
||||
return IconBtnEditWidget::create(['url' => '/admin/event-contacts/update/' . $row['id']])->run();
|
||||
});
|
||||
$table->addAction(function($row) {
|
||||
return IconBtnDeleteWidget::create(['url' => '/admin/event-contacts/delete/' . $row['id']])->run();
|
||||
});
|
||||
$table->create();
|
||||
$table->render();
|
40
kernel/app_modules/event/views/eventcontact/view.php
Normal file
40
kernel/app_modules/event/views/eventcontact/view.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $event
|
||||
*/
|
||||
|
||||
use Itguild\EloquentTable\ViewEloquentTable;
|
||||
use Itguild\EloquentTable\ViewJsonTableEloquentModel;
|
||||
use kernel\app_modules\event\models\EventContact;
|
||||
use kernel\widgets\IconBtn\IconBtnDeleteWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnEditWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnListWidget;
|
||||
|
||||
$table = new ViewEloquentTable(new ViewJsonTableEloquentModel($event, [
|
||||
'params' => ["class" => "table table-bordered", "border" => "2"],
|
||||
'baseUrl' => "/admin/event-contacts",
|
||||
]));
|
||||
$table->beforePrint(function () use ($event) {
|
||||
$btn = IconBtnListWidget::create(['url' => '/admin/event-contacts'])->run();
|
||||
$btn .= IconBtnEditWidget::create(['url' => '/admin/event-contacts/update/' . $event->id])->run();
|
||||
$btn .= IconBtnDeleteWidget::create(['url' => '/admin/event-contacts/delete/' . $event->id])->run();
|
||||
return $btn;
|
||||
});
|
||||
|
||||
$table->rows([
|
||||
'event_id' => [
|
||||
'value' => function ($data) {
|
||||
$model = \kernel\app_modules\event\models\Event::find($data);
|
||||
return $model->title ?? '';
|
||||
}
|
||||
],
|
||||
'status' => [
|
||||
'value' => function ($data) {
|
||||
return EventContact::getStatus()[$data];
|
||||
}
|
||||
]
|
||||
]);
|
||||
|
||||
$table->create();
|
||||
$table->render();
|
136
kernel/app_modules/event/views/form.php
Normal file
136
kernel/app_modules/event/views/form.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* @var Event $model
|
||||
*/
|
||||
|
||||
use kernel\app_modules\event\models\Event;
|
||||
|
||||
$form = new \itguild\forms\ActiveForm();
|
||||
$form->beginForm(isset($model) ? "/admin/event/edit/" . $model->id : "/admin/event", 'multipart/form-data');
|
||||
|
||||
// Пример формы:
|
||||
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextInput::class, 'title', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Название',
|
||||
'value' => $model->title ?? ''
|
||||
])
|
||||
->setLabel("Название мероприятие")
|
||||
->render();
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextInput::class, 'type', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Тип',
|
||||
'value' => $model->type ?? ''
|
||||
])
|
||||
->setLabel("Тип мероприятие")
|
||||
->render();
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextInput::class, 'hours_count', [
|
||||
'class' => "form-control",
|
||||
'type' => 'number',
|
||||
'placeholder' => 'Кол-во часов',
|
||||
'value' => $model->hours_count ?? ''
|
||||
])
|
||||
->setLabel("Кол-во часов")
|
||||
->render();
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextInput::class, 'date_start', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Дата начала',
|
||||
'type' => 'date',
|
||||
'value' => $model->dateStartFormatedToForm ?? ''
|
||||
])
|
||||
->setLabel("Дата начала")
|
||||
->render();
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextInput::class, 'date_end', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Дата окончания',
|
||||
'type' => 'date',
|
||||
'value' => $model->dateEndFormatedToForm ?? ''
|
||||
])
|
||||
->setLabel("Дата окончания")
|
||||
->render();
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextInput::class, 'place', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Место',
|
||||
'value' => $model->place ?? ''
|
||||
])
|
||||
->setLabel("Место провежения")
|
||||
->render();
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextArea::class, 'event_format', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Формат',
|
||||
'value' => $model->event_format ?? ''
|
||||
])
|
||||
->setLabel("Формат мероприятия")
|
||||
->render();
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextArea::class, 'description', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Описание',
|
||||
'value' => $model->description ?? ''
|
||||
])
|
||||
->setLabel("Описание")
|
||||
->render();
|
||||
|
||||
$form->field(\itguild\forms\inputs\TextArea::class, 'additional_info', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Дополнительная информация',
|
||||
'value' => $model->additional_info ?? ''
|
||||
])
|
||||
->setLabel("Дополнительная информация")
|
||||
->render();
|
||||
|
||||
$form->field(class: \itguild\forms\inputs\Select::class, name: "status", params: [
|
||||
'class' => "form-control",
|
||||
'value' => $model->status ?? ''
|
||||
])
|
||||
->setLabel("Статус")
|
||||
->setOptions(Event::getStatus())
|
||||
->render();
|
||||
|
||||
$entityRelations = new \kernel\EntityRelation();
|
||||
if (!isset($model)) {
|
||||
$model = new Event();
|
||||
}
|
||||
$entityRelations->renderEntityAdditionalPropertyFormBySlug("event", $model);
|
||||
|
||||
//$form->field(class: \itguild\forms\inputs\Select::class, name: "user_id", params: [
|
||||
// 'class' => "form-control",
|
||||
// 'value' => $model->user_id ?? ''
|
||||
//])
|
||||
// ->setLabel("Пользователи")
|
||||
// ->setOptions(\kernel\modules\user\service\UserService::createUsernameArr())
|
||||
// ->render();
|
||||
|
||||
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-submit", params: [
|
||||
'class' => "btn btn-primary ",
|
||||
'value' => 'Отправить',
|
||||
'typeInput' => 'submit'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-reset", params: [
|
||||
'class' => "btn btn-warning",
|
||||
'value' => 'Сбросить',
|
||||
'typeInput' => 'reset'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$form->endForm();
|
107
kernel/app_modules/event/views/index.php
Normal file
107
kernel/app_modules/event/views/index.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $event
|
||||
* @var int $page_number
|
||||
* @var \kernel\CgView $view
|
||||
*/
|
||||
|
||||
use kernel\app_modules\event\models\Event;
|
||||
use Itguild\EloquentTable\EloquentDataProvider;
|
||||
use Itguild\EloquentTable\ListEloquentTable;
|
||||
use kernel\widgets\IconBtn\IconBtnCreateWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnDeleteWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnEditWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnViewWidget;
|
||||
|
||||
$view->setTitle("Список event");
|
||||
$view->setMeta([
|
||||
'description' => 'Список event системы'
|
||||
]);
|
||||
|
||||
$fillable = ['title', 'date_start', 'status', 'photo'];
|
||||
|
||||
//Для использования таблицы с моделью, необходимо создать таблицу в базе данных
|
||||
$table = new ListEloquentTable(new EloquentDataProvider(Event::class, [
|
||||
'currentPage' => $page_number,
|
||||
'perPage' => 8,
|
||||
'params' => ["class" => "table table-bordered", "border" => "2"],
|
||||
'baseUrl' => "/admin/event",
|
||||
'fillable' => $fillable
|
||||
]));
|
||||
|
||||
$entityRelation = new \kernel\EntityRelation();
|
||||
$additionals = $entityRelation->getEntityRelationsBySlug("event");
|
||||
|
||||
foreach ($additionals as $additional) {
|
||||
if (in_array($additional, $fillable)){
|
||||
$table->addColumn($additional, $additional, function ($id) use ($entityRelation, $additional) {
|
||||
return $entityRelation->getAdditionalPropertyByEntityId("event", $id, $additional);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//$table = new \Itguild\Tables\ListJsonTable(json_encode(
|
||||
// [
|
||||
// 'meta' => [
|
||||
// 'total' => 0,
|
||||
// 'totalWithFilters' => 0,
|
||||
// 'columns' => [
|
||||
// 'title',
|
||||
// 'slug',
|
||||
// 'status',
|
||||
// ],
|
||||
// 'perPage' => 5,
|
||||
// 'currentPage' => 1,
|
||||
// 'baseUrl' => '/admin/some',
|
||||
// 'params' => [
|
||||
// 'class' => 'table table-bordered',
|
||||
// 'border' => 2
|
||||
// ]
|
||||
// ],
|
||||
// 'filters' => [],
|
||||
// 'data' => [],
|
||||
// ]
|
||||
//));
|
||||
|
||||
// Пример фильтра
|
||||
$table->columns([
|
||||
'title' => [
|
||||
'filter' => [
|
||||
'class' => \Itguild\Tables\Filter\InputTextFilter::class,
|
||||
'value' => $get['title'] ?? ''
|
||||
]
|
||||
],
|
||||
'date_start' => [
|
||||
'format' => 'date:d-m-Y',
|
||||
],
|
||||
'date_end' => [
|
||||
'format' => 'date:d-m-Y',
|
||||
],
|
||||
'status' => [
|
||||
'value' => function ($data) {
|
||||
return Event::getStatus()[$data];
|
||||
}
|
||||
]
|
||||
]);
|
||||
|
||||
$table->addColumn("Контакты", "event_contacts", function ($data){
|
||||
$event = Event::with('contacts')->find($data);
|
||||
return $event->contacts->pluck('title')->implode(', ');
|
||||
});
|
||||
|
||||
$table->beforePrint(function () {
|
||||
return IconBtnCreateWidget::create(['url' => '/admin/event/create'])->run();
|
||||
});
|
||||
|
||||
$table->addAction(function($row) {
|
||||
return IconBtnViewWidget::create(['url' => '/admin/event/view/' . $row['id']])->run();
|
||||
});
|
||||
$table->addAction(function($row) {
|
||||
return IconBtnEditWidget::create(['url' => '/admin/event/update/' . $row['id']])->run();
|
||||
});
|
||||
$table->addAction(function($row) {
|
||||
return IconBtnDeleteWidget::create(['url' => '/admin/event/delete/' . $row['id']])->run();
|
||||
});
|
||||
$table->create();
|
||||
$table->render();
|
50
kernel/app_modules/event/views/view.php
Normal file
50
kernel/app_modules/event/views/view.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $event
|
||||
*/
|
||||
|
||||
use Itguild\EloquentTable\ViewEloquentTable;
|
||||
use Itguild\EloquentTable\ViewJsonTableEloquentModel;
|
||||
use kernel\app_modules\event\models\Event;
|
||||
use kernel\widgets\IconBtn\IconBtnDeleteWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnEditWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnListWidget;
|
||||
|
||||
$table = new ViewEloquentTable(new ViewJsonTableEloquentModel($event, [
|
||||
'params' => ["class" => "table table-bordered", "border" => "2"],
|
||||
'baseUrl' => "/admin/event",
|
||||
]));
|
||||
|
||||
$entityRelation = new \kernel\EntityRelation();
|
||||
$additionals = $entityRelation->getEntityAdditionalProperty("event", $event);
|
||||
|
||||
foreach ($additionals as $key => $additional) {
|
||||
$table->addRow($key, function () use ($additional) {
|
||||
return $additional;
|
||||
}, ['after' => 'additional_info']);
|
||||
}
|
||||
|
||||
$table->rows([
|
||||
'date_start' => [
|
||||
'format' => 'date:d-m-Y',
|
||||
],
|
||||
'date_end' => [
|
||||
'format' => 'date:d-m-Y',
|
||||
],
|
||||
'status' => [
|
||||
'value' => function ($data) {
|
||||
return Event::getStatus()[$data];
|
||||
}
|
||||
]
|
||||
]);
|
||||
|
||||
$table->beforePrint(function () use ($event) {
|
||||
$btn = IconBtnListWidget::create(['url' => '/admin/event'])->run();
|
||||
$btn .= IconBtnEditWidget::create(['url' => '/admin/event/update/' . $event->id])->run();
|
||||
$btn .= IconBtnDeleteWidget::create(['url' => '/admin/event/delete/' . $event->id])->run();
|
||||
return $btn;
|
||||
});
|
||||
|
||||
$table->create();
|
||||
$table->render();
|
43
kernel/app_modules/gestalt_profile/Gestalt_profileModule.php
Normal file
43
kernel/app_modules/gestalt_profile/Gestalt_profileModule.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile;
|
||||
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\Module;
|
||||
use kernel\modules\menu\service\MenuService;
|
||||
use kernel\services\MigrationService;
|
||||
|
||||
class Gestalt_profileModule extends Module
|
||||
{
|
||||
|
||||
public MenuService $menuService;
|
||||
public MigrationService $migrationService;
|
||||
public function __construct()
|
||||
{
|
||||
$this->menuService = new MenuService();
|
||||
$this->migrationService = new MigrationService();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function init(): void
|
||||
{
|
||||
$this->migrationService->runAtPath("{KERNEL_APP_MODULES}/gestalt_profile/migrations");
|
||||
|
||||
$this->menuService->createItem([
|
||||
"label" => "Профили психологов",
|
||||
"url" => "/admin/gestalt_profile",
|
||||
"slug" => "gestalt_profile",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deactivate(): void
|
||||
{
|
||||
$this->migrationService->rollbackAtPath("{KERNEL_APP_MODULES}/gestalt_profile/migrations");
|
||||
$this->menuService->removeItemBySlug("gestalt_profile");
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile\controllers;
|
||||
|
||||
use kernel\app_modules\gestalt_profile\models\Gestalt_profile;
|
||||
use kernel\modules\post\models\Post;
|
||||
use kernel\RestController;
|
||||
|
||||
class GestaltProfileRestController extends RestController
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->model = new Gestalt_profile();
|
||||
}
|
||||
|
||||
protected function expand(): array
|
||||
{
|
||||
return ["user"];
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile\controllers;
|
||||
|
||||
use Exception;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
use kernel\AdminController;
|
||||
use kernel\app_modules\gestalt_profile\models\forms\CreateGestalt_profileForm;
|
||||
use kernel\app_modules\gestalt_profile\models\Gestalt_profile;
|
||||
use kernel\app_modules\gestalt_profile\services\Gestalt_profileService;
|
||||
use kernel\helpers\Debug;
|
||||
|
||||
class Gestalt_profileController extends AdminController
|
||||
{
|
||||
private Gestalt_profileService $gestalt_profileService;
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = KERNEL_APP_MODULES_DIR . "/gestalt_profile/views/";
|
||||
$this->gestalt_profileService = new Gestalt_profileService();
|
||||
}
|
||||
|
||||
public function actionCreate(): void
|
||||
{
|
||||
$this->cgView->render("form.php");
|
||||
}
|
||||
|
||||
#[NoReturn] public function actionAdd(): void
|
||||
{
|
||||
$gestalt_profileForm = new CreateGestalt_profileForm();
|
||||
$gestalt_profileForm->load($_REQUEST);
|
||||
if ($gestalt_profileForm->validate()){
|
||||
$gestalt_profile = $this->gestalt_profileService->create($gestalt_profileForm);
|
||||
if ($gestalt_profile){
|
||||
$this->redirect("/admin/gestalt_profile/view/" . $gestalt_profile->id);
|
||||
}
|
||||
}
|
||||
$this->redirect("/admin/gestalt_profile/create");
|
||||
}
|
||||
|
||||
public function actionIndex($page_number = 1): void
|
||||
{
|
||||
$this->cgView->render("index.php", ['page_number' => $page_number]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionView($id): void
|
||||
{
|
||||
$gestalt_profile = Gestalt_profile::find($id);
|
||||
|
||||
if (!$gestalt_profile){
|
||||
throw new Exception(message: "The gestalt_profile not found");
|
||||
}
|
||||
$this->cgView->render("view.php", ['gestalt_profile' => $gestalt_profile]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionUpdate($id): void
|
||||
{
|
||||
$model = Gestalt_profile::find($id);
|
||||
if (!$model){
|
||||
throw new Exception(message: "The gestalt_profile not found");
|
||||
}
|
||||
|
||||
$this->cgView->render("form.php", ['model' => $model]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionEdit($id): void
|
||||
{
|
||||
$gestalt_profile = Gestalt_profile::find($id);
|
||||
if (!$gestalt_profile){
|
||||
throw new Exception(message: "The gestalt_profile not found");
|
||||
}
|
||||
$gestalt_profileForm = new CreateGestalt_profileForm();
|
||||
$gestalt_profileService = new Gestalt_profileService();
|
||||
$gestalt_profileForm->load($gestalt_profile->toArray());
|
||||
$gestalt_profileForm->load($_REQUEST);
|
||||
if ($gestalt_profileForm->validate()) {
|
||||
$gestalt_profile = $gestalt_profileService->update($gestalt_profileForm, $gestalt_profile);
|
||||
if ($gestalt_profile) {
|
||||
$this->redirect("/admin/gestalt_profile/view/" . $gestalt_profile->id);
|
||||
}
|
||||
}
|
||||
$this->redirect("/admin/gestalt_profile/update/" . $id);
|
||||
}
|
||||
|
||||
#[NoReturn] public function actionDelete($id): void
|
||||
{
|
||||
$gestalt_profile = Gestalt_profile::find($id)->first();
|
||||
$gestalt_profile->delete();
|
||||
$this->redirect("/admin/gestalt_profile/");
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
<?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
|
||||
{
|
||||
\kernel\App::$db->schema->create('gestalt_profile', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->integer('user_id')->nullable();
|
||||
$table->string('fio', 255)->nullable(false);
|
||||
$table->string('phone', 255)->nullable(false);
|
||||
$table->string('email', 255)->nullable(false);
|
||||
$table->string('city', 255);
|
||||
$table->string('photo', 255);
|
||||
$table->text('community_status')->nullable(true);
|
||||
$table->text('specialization')->nullable(true);
|
||||
$table->text('description_of_professional_activity')->nullable(true);
|
||||
$table->text('past_events')->nullable(true);
|
||||
$table->text('upcoming_events')->nullable(true);
|
||||
$table->text('under_curation_events')->nullable(true);
|
||||
$table->integer('status')->default(1);
|
||||
$table->integer('show_on_main')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
\kernel\App::$db->schema->dropIfExists('gestalt_profile');
|
||||
}
|
||||
};
|
118
kernel/app_modules/gestalt_profile/models/Gestalt_profile.php
Normal file
118
kernel/app_modules/gestalt_profile/models/Gestalt_profile.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile\models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use kernel\app_modules\gestalt_profile_relationship\models\GestaltProfileRelationship;
|
||||
|
||||
// Добавить @property
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $status
|
||||
* @property int $show_on_main
|
||||
* @property int $user_id
|
||||
* @property string $fio
|
||||
* @property string $phone
|
||||
* @property string $email
|
||||
* @property string $city
|
||||
* @property string $photo
|
||||
* @property string $community_status
|
||||
* @property string $specialization
|
||||
* @property string $description_of_professional_activity
|
||||
* @property string $past_events
|
||||
* @property string $upcoming_events
|
||||
* @property string $under_curation_events
|
||||
* @property array $communityStatusArr
|
||||
* @property array $specializationArr
|
||||
*/
|
||||
class Gestalt_profile extends Model
|
||||
{
|
||||
const DISABLE_STATUS = 0;
|
||||
const ACTIVE_STATUS = 1;
|
||||
|
||||
const DONT_SHOW_ON_MAIN = 0;
|
||||
|
||||
const SHOW_ON_MAIN = 1;
|
||||
|
||||
protected $table = 'gestalt_profile';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'fio',
|
||||
'phone',
|
||||
'email',
|
||||
'city',
|
||||
'photo',
|
||||
'community_status',
|
||||
'specialization',
|
||||
'description_of_professional_activity',
|
||||
'past_events',
|
||||
'upcoming_events',
|
||||
'under_curation_events',
|
||||
'status',
|
||||
'show_on_main',
|
||||
];
|
||||
|
||||
public static function labels(): array
|
||||
{
|
||||
return [
|
||||
'user_id' => 'Пользователь',
|
||||
'fio' => 'ФИО',
|
||||
'phone' => 'Телефон',
|
||||
'email' => 'Почта',
|
||||
'city' => 'Город',
|
||||
'photo' => 'Фото',
|
||||
'community_status' => 'Статус в сообществе',
|
||||
'specialization' => 'Специализация',
|
||||
'description_of_professional_activity' => 'Описание профессиональной деятельности',
|
||||
'past_events' => 'Прошедшие мероприятия',
|
||||
'upcoming_events' => 'Будущие мероприятия',
|
||||
'under_curation_events' => 'Под руководством специалиста',
|
||||
'status' => 'Статус',
|
||||
'show_on_main' => 'Показать на главной',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getStatus(): array
|
||||
{
|
||||
return [
|
||||
self::DISABLE_STATUS => "Не активный",
|
||||
self::ACTIVE_STATUS => "Активный",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getShowOnMain(): array
|
||||
{
|
||||
return [
|
||||
self::DONT_SHOW_ON_MAIN => "Не показывать",
|
||||
self::SHOW_ON_MAIN => "Показывать",
|
||||
];
|
||||
}
|
||||
|
||||
public function relationships(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(GestaltProfileRelationship::class, 'gestalt_profile_id');
|
||||
}
|
||||
|
||||
public function getCommunityStatusArrAttribute(): array
|
||||
{
|
||||
return array_filter(explode(", ", $this->community_status));
|
||||
}
|
||||
|
||||
public function getSpecializationArrAttribute(): array
|
||||
{
|
||||
return array_filter(explode(", ", $this->specialization));
|
||||
}
|
||||
|
||||
public static function getCountProfiles()
|
||||
{
|
||||
return self::count();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile\models\forms;
|
||||
|
||||
use kernel\FormModel;
|
||||
|
||||
class CreateGestalt_profileForm extends FormModel
|
||||
{
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
// Заполнить массив правил
|
||||
// Пример:
|
||||
// return [
|
||||
// 'label' => 'required|min-str-len:5|max-str-len:30',
|
||||
// 'entity' => 'required',
|
||||
// 'slug' => '',
|
||||
// 'status' => ''
|
||||
// ];
|
||||
return [
|
||||
'user_id' => 'integer',
|
||||
'fio' => 'required|min-str-len:5|max-str-len:80',
|
||||
'phone' => 'required|min-str-len:5|max-str-len:30',
|
||||
'email' => 'required|min-str-len:5|max-str-len:30',
|
||||
'city' => 'required|min-str-len:3|max-str-len:30',
|
||||
'photo' => '',
|
||||
'community_status' => '',
|
||||
'specialization' => '',
|
||||
'description_of_professional_activity' => '',
|
||||
'past_events' => '',
|
||||
'upcoming_events' => '',
|
||||
'under_curation_events' => '',
|
||||
'status' => 'integer',
|
||||
'show_on_main' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
25
kernel/app_modules/gestalt_profile/routs/gestalt_profile.php
Normal file
25
kernel/app_modules/gestalt_profile/routs/gestalt_profile.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use kernel\App;
|
||||
use kernel\CgRouteCollector;
|
||||
use Phroute\Phroute\RouteCollector;
|
||||
|
||||
App::$collector->group(["prefix" => "admin"], function (CgRouteCollector $router) {
|
||||
App::$collector->group(["before" => "auth"], function (RouteCollector $router) {
|
||||
App::$collector->group(["prefix" => "gestalt_profile"], function (CGRouteCollector $router) {
|
||||
App::$collector->get('/', [\app\modules\gestalt_profile\controllers\Gestalt_profileController::class, 'actionIndex']);
|
||||
App::$collector->get('/page/{page_number}', [\app\modules\gestalt_profile\controllers\Gestalt_profileController::class, 'actionIndex']);
|
||||
App::$collector->get('/create', [\app\modules\gestalt_profile\controllers\Gestalt_profileController::class, 'actionCreate']);
|
||||
App::$collector->post("/", [\app\modules\gestalt_profile\controllers\Gestalt_profileController::class, 'actionAdd']);
|
||||
App::$collector->get('/view/{id}', [\app\modules\gestalt_profile\controllers\Gestalt_profileController::class, 'actionView']);
|
||||
App::$collector->any('/update/{id}', [\app\modules\gestalt_profile\controllers\Gestalt_profileController::class, 'actionUpdate']);
|
||||
App::$collector->any("/edit/{id}", [\app\modules\gestalt_profile\controllers\Gestalt_profileController::class, 'actionEdit']);
|
||||
App::$collector->get('/delete/{id}', [\app\modules\gestalt_profile\controllers\Gestalt_profileController::class, 'actionDelete']);
|
||||
});
|
||||
});
|
||||
});
|
||||
App::$collector->group(["prefix" => "api"], function (CgRouteCollector $router){
|
||||
App::$collector->group(['before' => 'bearer'], function (CgRouteCollector $router){
|
||||
$router->rest("gestalt_profile", [\kernel\app_modules\gestalt_profile\controllers\GestaltProfileRestController::class]);
|
||||
});
|
||||
});
|
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile\services;
|
||||
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\app_modules\gestalt_profile\models\Gestalt_profile;
|
||||
use kernel\FormModel;
|
||||
|
||||
class Gestalt_profileService
|
||||
{
|
||||
protected Gestalt_profile $model;
|
||||
public function __construct()
|
||||
{
|
||||
$this->model = new Gestalt_profile();
|
||||
}
|
||||
|
||||
public function create(FormModel $form_model): false|Gestalt_profile
|
||||
{
|
||||
$model = new Gestalt_profile();
|
||||
// Пример заполнения:
|
||||
$model->user_id = $form_model->getItem('user_id');
|
||||
$model->fio = $form_model->getItem('fio');
|
||||
$model->phone = $form_model->getItem('phone');
|
||||
$model->email = $form_model->getItem('email');
|
||||
$model->city = $form_model->getItem('city');
|
||||
$model->photo = $form_model->getItem('photo');
|
||||
$model->community_status = $form_model->getItem('community_status');
|
||||
$model->specialization = $form_model->getItem('specialization');
|
||||
$model->description_of_professional_activity = $form_model->getItem('description_of_professional_activity');
|
||||
$model->past_events = $form_model->getItem('past_events');
|
||||
$model->upcoming_events = $form_model->getItem('upcoming_events');
|
||||
$model->under_curation_events = $form_model->getItem('under_curation_events');
|
||||
$model->status = $form_model->getItem('status');
|
||||
$model->show_on_main = $form_model->getItem('show_on_main');
|
||||
|
||||
if ($model->save()){
|
||||
return $model;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function update(FormModel $form_model, Gestalt_profile $gestalt_profile): false|Gestalt_profile
|
||||
{
|
||||
// Пример обновления:
|
||||
$gestalt_profile->user_id = $form_model->getItem('user_id');
|
||||
$gestalt_profile->fio = $form_model->getItem('fio');
|
||||
$gestalt_profile->phone = $form_model->getItem('phone');
|
||||
$gestalt_profile->email = $form_model->getItem('email');
|
||||
$gestalt_profile->city = $form_model->getItem('city');
|
||||
$gestalt_profile->photo = $form_model->getItem('photo');
|
||||
$gestalt_profile->community_status = $form_model->getItem('community_status');
|
||||
$gestalt_profile->specialization = $form_model->getItem('specialization');
|
||||
$gestalt_profile->description_of_professional_activity = $form_model->getItem('description_of_professional_activity');
|
||||
$gestalt_profile->past_events = $form_model->getItem('past_events');
|
||||
$gestalt_profile->upcoming_events = $form_model->getItem('upcoming_events');
|
||||
$gestalt_profile->under_curation_events = $form_model->getItem('under_curation_events');
|
||||
$gestalt_profile->status = $form_model->getItem('status');
|
||||
$gestalt_profile->show_on_main = $form_model->getItem('show_on_main');
|
||||
|
||||
if ($gestalt_profile->save()){
|
||||
return $gestalt_profile;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getCount()
|
||||
{
|
||||
return Gestalt_profile::count();
|
||||
}
|
||||
|
||||
public static function getLast4(): array
|
||||
{
|
||||
return Gestalt_profile::query()->limit(4)->orderBy('id', 'desc')->get()->toArray();
|
||||
}
|
||||
}
|
55
kernel/app_modules/gestalt_profile/views/form.php
Normal file
55
kernel/app_modules/gestalt_profile/views/form.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* @var Gestalt_profile $model
|
||||
*/
|
||||
|
||||
use kernel\app_modules\gestalt_profile\models\Gestalt_profile;
|
||||
|
||||
$form = new \itguild\forms\ActiveForm();
|
||||
$form->beginForm(isset($model) ? "/admin/gestalt_profile/edit/" . $model->id : "/admin/gestalt_profile", 'multipart/form-data');
|
||||
|
||||
// Пример формы:
|
||||
|
||||
/*
|
||||
$form->field(\itguild\forms\inputs\TextInput::class, 'title', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Заголовок поста',
|
||||
'value' => $model->title ?? ''
|
||||
])
|
||||
->setLabel("Заголовок")
|
||||
->render();
|
||||
*/
|
||||
$form->field(class: \itguild\forms\inputs\Select::class, name: "show_on_main", params: [
|
||||
'class' => "form-control",
|
||||
'value' => $model->show_on_main ?? ''
|
||||
])
|
||||
->setLabel("Показать на главной")
|
||||
->setOptions(Gestalt_profile::getShowOnMain())
|
||||
->render();
|
||||
|
||||
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-submit", params: [
|
||||
'class' => "btn btn-primary ",
|
||||
'value' => 'Отправить',
|
||||
'typeInput' => 'submit'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-reset", params: [
|
||||
'class' => "btn btn-warning",
|
||||
'value' => 'Сбросить',
|
||||
'typeInput' => 'reset'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$form->endForm();
|
90
kernel/app_modules/gestalt_profile/views/index.php
Normal file
90
kernel/app_modules/gestalt_profile/views/index.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $gestalt_profile
|
||||
* @var int $page_number
|
||||
* @var \kernel\CgView $view
|
||||
*/
|
||||
|
||||
use kernel\app_modules\gestalt_profile\models\Gestalt_profile;
|
||||
use Itguild\EloquentTable\EloquentDataProvider;
|
||||
use Itguild\EloquentTable\ListEloquentTable;
|
||||
use kernel\widgets\IconBtn\IconBtnCreateWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnDeleteWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnEditWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnViewWidget;
|
||||
|
||||
$get = (new \kernel\Request())->get();
|
||||
|
||||
$view->setTitle("Список gestalt_profile");
|
||||
$view->setMeta([
|
||||
'description' => 'Список gestalt_profile системы'
|
||||
]);
|
||||
|
||||
//Для использования таблицы с моделью, необходимо создать таблицу в базе данных
|
||||
$table = new ListEloquentTable(new EloquentDataProvider(Gestalt_profile::class, [
|
||||
'currentPage' => $page_number,
|
||||
'perPage' => 8,
|
||||
'params' => ["class" => "table table-bordered", "border" => "2"],
|
||||
'baseUrl' => "/admin/gestalt_profile",
|
||||
'searchPrefix' => "",
|
||||
'searchParams' => $get,
|
||||
'fillable' => ['fio', 'photo', 'phone', 'email', 'city']
|
||||
]));
|
||||
|
||||
|
||||
//$table = new \Itguild\Tables\ListJsonTable(json_encode(
|
||||
// [
|
||||
// 'meta' => [
|
||||
// 'total' => 0,
|
||||
// 'totalWithFilters' => 0,
|
||||
// 'columns' => [
|
||||
// 'title',
|
||||
// 'slug',
|
||||
// 'status',
|
||||
// ],
|
||||
// 'perPage' => 5,
|
||||
// 'currentPage' => 1,
|
||||
// 'baseUrl' => '/admin/some',
|
||||
// 'params' => [
|
||||
// 'class' => 'table table-bordered',
|
||||
// 'border' => 2
|
||||
// ]
|
||||
// ],
|
||||
// 'filters' => [],
|
||||
// 'data' => [],
|
||||
// ]
|
||||
//));
|
||||
|
||||
// Пример фильтра
|
||||
//$table->columns([
|
||||
// 'title' => [
|
||||
// 'filter' => [
|
||||
// 'class' => \Itguild\Tables\Filter\InputTextFilter::class,
|
||||
// 'value' => $get['title'] ?? ''
|
||||
// ]
|
||||
// ],
|
||||
//]);
|
||||
|
||||
$table->columns([
|
||||
"photo" => [
|
||||
"value" => function ($cell) {
|
||||
return \kernel\helpers\Html::img($cell, ['width' => '200px']);
|
||||
}]
|
||||
]);
|
||||
|
||||
$table->beforePrint(function () {
|
||||
return IconBtnCreateWidget::create(['url' => '/admin/gestalt_profile/create'])->run();
|
||||
});
|
||||
|
||||
$table->addAction(function ($row) {
|
||||
return IconBtnViewWidget::create(['url' => '/admin/gestalt_profile/view/' . $row['id']])->run();
|
||||
});
|
||||
$table->addAction(function ($row) {
|
||||
return IconBtnEditWidget::create(['url' => '/admin/gestalt_profile/update/' . $row['id']])->run();
|
||||
});
|
||||
$table->addAction(function ($row) {
|
||||
return IconBtnDeleteWidget::create(['url' => '/admin/gestalt_profile/delete/' . $row['id']])->run();
|
||||
});
|
||||
$table->create();
|
||||
$table->render();
|
32
kernel/app_modules/gestalt_profile/views/view.php
Normal file
32
kernel/app_modules/gestalt_profile/views/view.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $gestalt_profile
|
||||
*/
|
||||
|
||||
use Itguild\EloquentTable\ViewEloquentTable;
|
||||
use Itguild\EloquentTable\ViewJsonTableEloquentModel;
|
||||
use kernel\widgets\IconBtn\IconBtnDeleteWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnEditWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnListWidget;
|
||||
|
||||
$table = new ViewEloquentTable(new ViewJsonTableEloquentModel($gestalt_profile, [
|
||||
'params' => ["class" => "table table-bordered", "border" => "2"],
|
||||
'baseUrl' => "/admin/gestalt_profile",
|
||||
]));
|
||||
$table->beforePrint(function () use ($gestalt_profile) {
|
||||
$btn = IconBtnListWidget::create(['url' => '/admin/gestalt_profile'])->run();
|
||||
$btn .= IconBtnEditWidget::create(['url' => '/admin/gestalt_profile/update/' . $gestalt_profile->id])->run();
|
||||
$btn .= IconBtnDeleteWidget::create(['url' => '/admin/gestalt_profile/delete/' . $gestalt_profile->id])->run();
|
||||
return $btn;
|
||||
});
|
||||
|
||||
$table->rows([
|
||||
'photo' => function ($data) {
|
||||
return \kernel\helpers\Html::img($data, ['width' => '200px']);
|
||||
|
||||
},
|
||||
]);
|
||||
|
||||
$table->create();
|
||||
$table->render();
|
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile_relationship;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use itguild\forms\builders\SelectBuilder;
|
||||
use kernel\app_modules\gestalt_profile_relationship\models\GestaltProfileRelationship;
|
||||
use kernel\app_modules\gestalt_profile_relationship\services\GestaltProfileRelationshipService;
|
||||
use kernel\app_modules\tag\models\Tag;
|
||||
use kernel\app_modules\tag\service\TagEntityService;
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\Module;
|
||||
use kernel\modules\menu\service\MenuService;
|
||||
use kernel\modules\option\service\OptionService;
|
||||
use kernel\Request;
|
||||
use kernel\services\MigrationService;
|
||||
|
||||
class Gestalt_profile_relationshipModule extends Module
|
||||
{
|
||||
|
||||
public MenuService $menuService;
|
||||
|
||||
public MigrationService $migrationService;
|
||||
public function __construct()
|
||||
{
|
||||
$this->menuService = new MenuService();
|
||||
$this->migrationService = new MigrationService();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function init(): void
|
||||
{
|
||||
$this->migrationService->runAtPath("{KERNEL_APP_MODULES}/gestalt_profile_relationship/migrations");
|
||||
|
||||
$this->menuService->createItem([
|
||||
"label" => "Профили психологов (связь)",
|
||||
"url" => "/admin/gestalt_profile_relationship",
|
||||
"slug" => "gestalt_profile_relationship",
|
||||
]);
|
||||
|
||||
$this->menuService->createItem([
|
||||
"label" => "Профили психологов",
|
||||
"url" => "/admin/settings/gestalt_profile_relationship",
|
||||
"slug" => "gestalt_profile_relationship_settings",
|
||||
"parent_slug" => "settings"
|
||||
]);
|
||||
|
||||
OptionService::createFromParams("entity_gestalt_profile_relationship_list", "{}", "Список тегов");
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deactivate(): void
|
||||
{
|
||||
$this->menuService->removeItemBySlug("gestalt_profile_relationship");
|
||||
$this->menuService->removeItemBySlug("gestalt_profile_relationship_settings");
|
||||
$this->migrationService->rollbackAtPath("{KERNEL_APP_MODULES}/gestalt_profile_relationship/migrations");
|
||||
OptionService::removeOptionByKey("entity_gestalt_profile_relationship_list");
|
||||
}
|
||||
|
||||
public function formInputs(string $entity, Model $model = null): void
|
||||
{
|
||||
if (isset($model->id)) {
|
||||
$value = GestaltProfileRelationshipService::getProfileByEntity($entity, $model->id);
|
||||
}
|
||||
|
||||
$input = SelectBuilder::build("gestalt_profiles[]", [
|
||||
'class' => 'form-control',
|
||||
'placeholder' => 'Психологи',
|
||||
'value' => $value ?? '',
|
||||
'multiple' => "multiple",
|
||||
'options' => GestaltProfileRelationshipService::getProfilesList()
|
||||
]);
|
||||
$input->setLabel("Психологи");
|
||||
$input->create()->render();
|
||||
}
|
||||
|
||||
public function saveInputs(string $entity, Model $model, Request $request): void
|
||||
{
|
||||
GestaltProfileRelationship::where("entity", $entity)->where("entity_id", $model->id)->delete();
|
||||
|
||||
$profiles = $request->post("gestalt_profiles");
|
||||
if (is_array($profiles)) {
|
||||
foreach ($profiles as $profile) {
|
||||
$gpr = new GestaltProfileRelationship();
|
||||
$gpr->entity = $entity;
|
||||
$gpr->entity_id = $model->id;
|
||||
$gpr->gestalt_profile_id = $profile;
|
||||
$gpr->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getItems(string $entity, Model $model): array|string
|
||||
{
|
||||
$profiles = GestaltProfileRelationship::where("entity", $entity)->where("entity_id", $model->id)->with("profile")->get();
|
||||
return $profiles->pluck('profile.fio')->filter()->implode(', ');
|
||||
}
|
||||
|
||||
public function getItem(string $entity, string $entity_id): string
|
||||
{
|
||||
$profiles = GestaltProfileRelationship::where("entity", $entity)->where("entity_id", $entity_id)->with("profile")->get();
|
||||
return $profiles->pluck('profile.fio')->filter()->implode(', ');
|
||||
}
|
||||
|
||||
public function getItemsObject(string $entity, string $entity_id)
|
||||
{
|
||||
return GestaltProfileRelationship::where("entity", $entity)->where("entity_id", $entity_id)->with("profile")->get();
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile_relationship\controllers;
|
||||
|
||||
use Exception;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
use kernel\AdminController;
|
||||
use kernel\app_modules\gestalt_profile_relationship\models\forms\CreateGestaltProfileRelationshipForm;
|
||||
use kernel\app_modules\gestalt_profile_relationship\models\GestaltProfileRelationship;
|
||||
use kernel\app_modules\gestalt_profile_relationship\services\GestaltProfileRelationshipService;
|
||||
use kernel\EntityRelation;
|
||||
use kernel\Flash;
|
||||
use kernel\Request;
|
||||
|
||||
class GestaltProfileRelationshipController extends AdminController
|
||||
{
|
||||
private GestaltProfileRelationshipService $gestalt_profile_relationshipService;
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
$this->cgView->viewPath = KERNEL_APP_MODULES_DIR . "/gestalt_profile_relationship/views/";
|
||||
$this->gestalt_profile_relationshipService = new GestaltProfileRelationshipService();
|
||||
}
|
||||
|
||||
public function actionCreate(): void
|
||||
{
|
||||
$this->cgView->render("form.php");
|
||||
}
|
||||
|
||||
#[NoReturn] public function actionAdd(): void
|
||||
{
|
||||
$gestalt_profile_relationshipForm = new CreateGestaltProfileRelationshipForm();
|
||||
$gestalt_profile_relationshipForm->load($_REQUEST);
|
||||
if ($gestalt_profile_relationshipForm->validate()){
|
||||
$gestalt_profile_relationship = $this->gestalt_profile_relationshipService->create($gestalt_profile_relationshipForm);
|
||||
if ($gestalt_profile_relationship){
|
||||
$this->redirect("/admin/gestalt_profile_relationship/view/" . $gestalt_profile_relationship->id);
|
||||
}
|
||||
}
|
||||
$this->redirect("/admin/gestalt_profile_relationship/create");
|
||||
}
|
||||
|
||||
public function actionIndex($page_number = 1): void
|
||||
{
|
||||
$this->cgView->render("index.php", ['page_number' => $page_number]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionView($id): void
|
||||
{
|
||||
$gestalt_profile_relationship = GestaltProfileRelationship::find($id);
|
||||
|
||||
if (!$gestalt_profile_relationship){
|
||||
throw new Exception(message: "The gestalt_profile_relationship not found");
|
||||
}
|
||||
$this->cgView->render("view.php", ['gestalt_profile_relationship' => $gestalt_profile_relationship]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionUpdate($id): void
|
||||
{
|
||||
$model = GestaltProfileRelationship::find($id);
|
||||
if (!$model){
|
||||
throw new Exception(message: "The gestalt_profile_relationship not found");
|
||||
}
|
||||
|
||||
$this->cgView->render("form.php", ['model' => $model]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function actionEdit($id): void
|
||||
{
|
||||
$gestalt_profile_relationship = GestaltProfileRelationship::find($id);
|
||||
if (!$gestalt_profile_relationship){
|
||||
throw new Exception(message: "The gestalt_profile_relationship not found");
|
||||
}
|
||||
$gestalt_profile_relationshipForm = new CreateGestaltProfileRelationshipForm();
|
||||
$gestalt_profile_relationshipService = new GestaltProfileRelationshipService();
|
||||
$gestalt_profile_relationshipForm->load($_REQUEST);
|
||||
if ($gestalt_profile_relationshipForm->validate()) {
|
||||
$gestalt_profile_relationship = $gestalt_profile_relationshipService->update($gestalt_profile_relationshipForm, $gestalt_profile_relationship);
|
||||
if ($gestalt_profile_relationship) {
|
||||
$this->redirect("/admin/gestalt_profile_relationship/view/" . $gestalt_profile_relationship->id);
|
||||
}
|
||||
}
|
||||
$this->redirect("/admin/gestalt_profile_relationship/update/" . $id);
|
||||
}
|
||||
|
||||
#[NoReturn] public function actionDelete($id): void
|
||||
{
|
||||
$gestalt_profile_relationship = GestaltProfileRelationship::find($id)->first();
|
||||
$gestalt_profile_relationship->delete();
|
||||
$this->redirect("/admin/gestalt_profile_relationship/");
|
||||
}
|
||||
|
||||
public function actionSettings(): void
|
||||
{
|
||||
$this->cgView->render('settingsForm.php');
|
||||
}
|
||||
|
||||
#[NoReturn] public function actionSaveSettings(): void
|
||||
{
|
||||
$request = new Request();
|
||||
$entities = $request->post('entity');
|
||||
EntityRelation::configurationEntitiesByProperty($entities, 'gestalt_profile_relationship');
|
||||
|
||||
Flash::setMessage("success", "Настройка прошла успешно");
|
||||
$this->redirect("/admin/settings/gestalt_profile_relationship", 302);
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
\kernel\App::$db->schema->create('gestalt_profile_relationship', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->integer('gestalt_profile_id')->nullable(false);
|
||||
$table->string('entity', 255)->nullable(false);
|
||||
$table->integer('entity_id')->nullable(false);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
\kernel\App::$db->schema->dropIfExists('gestalt_profile_relationship');
|
||||
}
|
||||
};
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile_relationship\models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use kernel\app_modules\gestalt_profile\models\Gestalt_profile;
|
||||
|
||||
// Добавить @property
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $gestalt_profile_id
|
||||
* @property int $entity_id
|
||||
* @property string $entity
|
||||
*/
|
||||
class GestaltProfileRelationship extends Model
|
||||
{
|
||||
const DISABLE_STATUS = 0;
|
||||
const ACTIVE_STATUS = 1;
|
||||
|
||||
protected $table = 'gestalt_profile_relationship';
|
||||
|
||||
protected $fillable = ['gestalt_profile_id', 'entity', 'entity_id'];
|
||||
|
||||
public static function labels(): array
|
||||
{
|
||||
// Заполнить массив
|
||||
// Пример: [
|
||||
// 'label' => 'Заголовок',
|
||||
// 'entity' => 'Сущность',
|
||||
// 'slug' => 'Slug',
|
||||
// 'status' => 'Статус',
|
||||
// ]
|
||||
|
||||
return [
|
||||
'gestalt_profile_id' => 'Профиль',
|
||||
'entity' => 'Сущность',
|
||||
'entity_id' => 'ID сущности',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getStatus(): array
|
||||
{
|
||||
return [
|
||||
self::DISABLE_STATUS => "Не активный",
|
||||
self::ACTIVE_STATUS => "Активный",
|
||||
];
|
||||
}
|
||||
|
||||
public function profile(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Gestalt_profile::class, 'gestalt_profile_id');
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile_relationship\models\forms;
|
||||
|
||||
use kernel\FormModel;
|
||||
|
||||
class CreateGestaltProfileRelationshipForm extends FormModel
|
||||
{
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
// Заполнить массив правил
|
||||
// Пример:
|
||||
// return [
|
||||
// 'label' => 'required|min-str-len:5|max-str-len:30',
|
||||
// 'entity' => 'required',
|
||||
// 'slug' => '',
|
||||
// 'status' => ''
|
||||
// ];
|
||||
return [
|
||||
'gestalt_profile_id' => 'required|integer',
|
||||
'entity' => 'required|min-str-len:5|max-str-len:30',
|
||||
'entity_id' => 'required|integer',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use kernel\App;
|
||||
use kernel\CgRouteCollector;
|
||||
use Phroute\Phroute\RouteCollector;
|
||||
|
||||
App::$collector->group(["prefix" => "admin"], function (CgRouteCollector $router) {
|
||||
App::$collector->group(["before" => "auth"], function (RouteCollector $router) {
|
||||
App::$collector->group(["prefix" => "gestalt_profile_relationship"], function (CGRouteCollector $router) {
|
||||
App::$collector->get('/', [\app\modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionIndex']);
|
||||
App::$collector->get('/page/{page_number}', [\app\modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionIndex']);
|
||||
App::$collector->get('/create', [\app\modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionCreate']);
|
||||
App::$collector->post("/", [\app\modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionAdd']);
|
||||
App::$collector->get('/view/{id}', [\app\modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionView']);
|
||||
App::$collector->any('/update/{id}', [\app\modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionUpdate']);
|
||||
App::$collector->any("/edit/{id}", [\app\modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionEdit']);
|
||||
App::$collector->get('/delete/{id}', [\app\modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionDelete']);
|
||||
});
|
||||
App::$collector->group(["prefix" => "settings"], function (CGRouteCollector $router) {
|
||||
App::$collector->get('/gestalt_profile_relationship', [\kernel\app_modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionSettings']);
|
||||
App::$collector->post('/gestalt_profile_relationship/update', [\kernel\app_modules\gestalt_profile_relationship\controllers\GestaltProfileRelationshipController::class, 'actionSaveSettings']);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_modules\gestalt_profile_relationship\services;
|
||||
|
||||
use kernel\app_modules\gestalt_profile\models\Gestalt_profile;
|
||||
use kernel\helpers\Debug;
|
||||
use kernel\app_modules\gestalt_profile_relationship\models\GestaltProfileRelationship;
|
||||
use kernel\FormModel;
|
||||
|
||||
class GestaltProfileRelationshipService
|
||||
{
|
||||
public function create(FormModel $form_model): false|GestaltProfileRelationship
|
||||
{
|
||||
$model = new GestaltProfileRelationship();
|
||||
$model->gestalt_profile_id = $form_model->getItem('gestalt_profile_id');
|
||||
$model->entity = $form_model->getItem('entity');
|
||||
$model->entity_id = $form_model->getItem('entity_id');
|
||||
|
||||
if ($model->save()){
|
||||
return $model;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function update(FormModel $form_model, GestaltProfileRelationship $gestalt_profile_relationship): false|GestaltProfileRelationship
|
||||
{
|
||||
$gestalt_profile_relationship->gestalt_profile_id = $form_model->getItem('gestalt_profile_id');
|
||||
$gestalt_profile_relationship->entity = $form_model->getItem('entity');
|
||||
$gestalt_profile_relationship->entity_id = $form_model->getItem('entity_id');
|
||||
|
||||
if ($gestalt_profile_relationship->save()){
|
||||
return $gestalt_profile_relationship;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getProfileByEntity(string $entity, int $entity_id): array
|
||||
{
|
||||
$profiles = GestaltProfileRelationship::with('profile')->where("entity_id", $entity_id)->where("entity", $entity)->get();
|
||||
$value = [];
|
||||
foreach ($profiles as $profile) {
|
||||
$value[$profile->gestalt_profile_id] = $profile->profile->fio;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function getProfilesList(): array
|
||||
{
|
||||
return Gestalt_profile::pluck('fio', 'id')->all();
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* @var GestaltProfileRelationship $model
|
||||
*/
|
||||
|
||||
use kernel\app_modules\gestalt_profile_relationship\models\GestaltProfileRelationship;
|
||||
|
||||
$form = new \itguild\forms\ActiveForm();
|
||||
$form->beginForm(isset($model) ? "/admin/gestalt_profile_relationship/edit/" . $model->id : "/admin/gestalt_profile_relationship", 'multipart/form-data');
|
||||
|
||||
// Пример формы:
|
||||
|
||||
/*
|
||||
$form->field(\itguild\forms\inputs\TextInput::class, 'title', [
|
||||
'class' => "form-control",
|
||||
'placeholder' => 'Заголовок поста',
|
||||
'value' => $model->title ?? ''
|
||||
])
|
||||
->setLabel("Заголовок")
|
||||
->render();
|
||||
|
||||
$form->field(class: \itguild\forms\inputs\Select::class, name: "user_id", params: [
|
||||
'class' => "form-control",
|
||||
'value' => $model->user_id ?? ''
|
||||
])
|
||||
->setLabel("Пользователи")
|
||||
->setOptions(\kernel\modules\user\service\UserService::createUsernameArr())
|
||||
->render();
|
||||
*/
|
||||
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-submit", params: [
|
||||
'class' => "btn btn-primary ",
|
||||
'value' => 'Отправить',
|
||||
'typeInput' => 'submit'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-reset", params: [
|
||||
'class' => "btn btn-warning",
|
||||
'value' => 'Сбросить',
|
||||
'typeInput' => 'reset'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$form->endForm();
|
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $gestalt_profile_relationship
|
||||
* @var int $page_number
|
||||
* @var \kernel\CgView $view
|
||||
*/
|
||||
|
||||
use kernel\app_modules\gestalt_profile_relationship\models\GestaltProfileRelationship;
|
||||
use Itguild\EloquentTable\EloquentDataProvider;
|
||||
use Itguild\EloquentTable\ListEloquentTable;
|
||||
use kernel\widgets\IconBtn\IconBtnCreateWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnDeleteWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnEditWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnViewWidget;
|
||||
|
||||
$view->setTitle("Список gestalt_profile_relationship");
|
||||
$view->setMeta([
|
||||
'description' => 'Список gestalt_profile_relationship системы'
|
||||
]);
|
||||
|
||||
//Для использования таблицы с моделью, необходимо создать таблицу в базе данных
|
||||
$table = new ListEloquentTable(new EloquentDataProvider(GestaltProfileRelationship::class, [
|
||||
'currentPage' => $page_number,
|
||||
'perPage' => 8,
|
||||
'params' => ["class" => "table table-bordered", "border" => "2"],
|
||||
'baseUrl' => "/admin/gestalt_profile_relationship"
|
||||
]));
|
||||
|
||||
|
||||
//$table = new \Itguild\Tables\ListJsonTable(json_encode(
|
||||
// [
|
||||
// 'meta' => [
|
||||
// 'total' => 0,
|
||||
// 'totalWithFilters' => 0,
|
||||
// 'columns' => [
|
||||
// 'title',
|
||||
// 'slug',
|
||||
// 'status',
|
||||
// ],
|
||||
// 'perPage' => 5,
|
||||
// 'currentPage' => 1,
|
||||
// 'baseUrl' => '/admin/some',
|
||||
// 'params' => [
|
||||
// 'class' => 'table table-bordered',
|
||||
// 'border' => 2
|
||||
// ]
|
||||
// ],
|
||||
// 'filters' => [],
|
||||
// 'data' => [],
|
||||
// ]
|
||||
//));
|
||||
|
||||
// Пример фильтра
|
||||
$table->columns([
|
||||
'gestalt_profile_id' => [
|
||||
'value' => function ($data) {
|
||||
return \kernel\app_modules\gestalt_profile\models\Gestalt_profile::find($data)->fio ?? '';
|
||||
}
|
||||
],
|
||||
]);
|
||||
|
||||
//$table->beforePrint(function () {
|
||||
// return IconBtnCreateWidget::create(['url' => '/admin/gestalt_profile_relationship/create'])->run();
|
||||
//});
|
||||
|
||||
$table->addAction(function($row) {
|
||||
return IconBtnViewWidget::create(['url' => '/admin/gestalt_profile_relationship/view/' . $row['id']])->run();
|
||||
});
|
||||
//$table->addAction(function($row) {
|
||||
// return IconBtnEditWidget::create(['url' => '/admin/gestalt_profile_relationship/update/' . $row['id']])->run();
|
||||
//});
|
||||
$table->addAction(function($row) {
|
||||
return IconBtnDeleteWidget::create(['url' => '/admin/gestalt_profile_relationship/delete/' . $row['id']])->run();
|
||||
});
|
||||
$table->create();
|
||||
$table->render();
|
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
$form = new \itguild\forms\ActiveForm();
|
||||
$form->beginForm("/admin/settings/gestalt_profile_relationship/update");
|
||||
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<h5>Выберите сущности, к которым хотите прикрепить фото</h5>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
|
||||
$form->field(\itguild\forms\inputs\Select::class, "entity[]", [
|
||||
'class' => "form-control",
|
||||
'value' => \kernel\EntityRelation::getEntityByProperty('gestalt_profile_relationship') ?? '',
|
||||
'multiple' => "multiple",
|
||||
|
||||
])
|
||||
->setLabel("Сущности")
|
||||
->setOptions(\kernel\EntityRelation::getEntityList())
|
||||
->render();
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-submit", params: [
|
||||
'class' => "btn btn-primary ",
|
||||
'value' => 'Отправить',
|
||||
'typeInput' => 'submit'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<?php
|
||||
$form->field(\itguild\forms\inputs\Button::class, name: "btn-reset", params: [
|
||||
'class' => "btn btn-warning",
|
||||
'value' => 'Сбросить',
|
||||
'typeInput' => 'reset'
|
||||
])
|
||||
->render();
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$form->endForm();
|
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Collection $gestalt_profile_relationship
|
||||
*/
|
||||
|
||||
use Itguild\EloquentTable\ViewEloquentTable;
|
||||
use Itguild\EloquentTable\ViewJsonTableEloquentModel;
|
||||
use kernel\widgets\IconBtn\IconBtnDeleteWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnEditWidget;
|
||||
use kernel\widgets\IconBtn\IconBtnListWidget;
|
||||
|
||||
$table = new ViewEloquentTable(new ViewJsonTableEloquentModel($gestalt_profile_relationship, [
|
||||
'params' => ["class" => "table table-bordered", "border" => "2"],
|
||||
'baseUrl' => "/admin/gestalt_profile_relationship",
|
||||
]));
|
||||
$table->beforePrint(function () use ($gestalt_profile_relationship) {
|
||||
$btn = IconBtnListWidget::create(['url' => '/admin/gestalt_profile_relationship'])->run();
|
||||
// $btn .= IconBtnEditWidget::create(['url' => '/admin/gestalt_profile_relationship/update/' . $gestalt_profile_relationship->id])->run();
|
||||
$btn .= IconBtnDeleteWidget::create(['url' => '/admin/gestalt_profile_relationship/delete/' . $gestalt_profile_relationship->id])->run();
|
||||
return $btn;
|
||||
});
|
||||
|
||||
$table->rows([
|
||||
'gestalt_profile_id' => [
|
||||
'value' => function ($data) {
|
||||
return \kernel\app_modules\gestalt_profile\models\Gestalt_profile::find($data)->fio ?? '';
|
||||
}
|
||||
],
|
||||
]);
|
||||
|
||||
$table->create();
|
||||
$table->render();
|
@ -94,12 +94,22 @@ class PhotoModule extends Module
|
||||
return substr($photoStr, 0, -1);
|
||||
}
|
||||
|
||||
public function getItem(string $entity, string $entity_id): string
|
||||
public function getItem(string $entity, string $entity_id, array $params = []): string
|
||||
{
|
||||
$photos = Photo::where("entity", $entity)->where("entity_id", $entity_id)->get();
|
||||
$photoStr = "";
|
||||
if (isset($params['width'])){
|
||||
$w = $params['width'];
|
||||
$style = "width: $w;";
|
||||
}
|
||||
elseif(isset($params['cover'])) {
|
||||
$style = "width: 100%; height: 100%; object-fit: cover;";
|
||||
}
|
||||
else {
|
||||
$style = "width: 150px;";
|
||||
}
|
||||
foreach ($photos as $photo) {
|
||||
$photoStr .= "<img src='$photo->image' width='150px'>" . " ";
|
||||
$photoStr .= "<img src='$photo->image' style='$style'>" . " ";
|
||||
}
|
||||
|
||||
return substr($photoStr, 0, -1);
|
||||
|
31
kernel/app_themes/gestalt/GestaltTheme.php
Normal file
31
kernel/app_themes/gestalt/GestaltTheme.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_themes\gestalt;
|
||||
|
||||
use kernel\modules\menu\service\MenuService;
|
||||
use kernel\services\MigrationService;
|
||||
|
||||
class GestaltTheme
|
||||
{
|
||||
public MenuService $menuService;
|
||||
public MigrationService $migrationService;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->menuService = new MenuService();
|
||||
$this->migrationService = new MigrationService();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function init(): void
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
public function deactivate(): void
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\app_themes\gestalt\services;
|
||||
|
||||
class GestaltThemeService
|
||||
{
|
||||
|
||||
}
|
@ -119,4 +119,48 @@ class ModuleController extends ConsoleController
|
||||
$this->out->r("Модуль $slug создан", 'green');
|
||||
}
|
||||
|
||||
public function actionConstructController(): void
|
||||
{
|
||||
$this->out->r("Введите slug контроллера:", 'yellow');
|
||||
$slug = substr(fgets(STDIN), 0, -1);
|
||||
$slug = strtolower($slug);
|
||||
|
||||
$this->out->r("Введите model контроллера:", 'yellow');
|
||||
$model = substr(fgets(STDIN), 0, -1);
|
||||
|
||||
$this->out->r("Введите путь контроллера:", 'yellow');
|
||||
$path = substr(fgets(STDIN), 0, -1);
|
||||
$path = strtolower($path);
|
||||
|
||||
$moduleService = new ModuleService();
|
||||
$moduleService->createController([
|
||||
'slug' => $slug,
|
||||
'model' => $model,
|
||||
], $path);
|
||||
|
||||
$this->out->r("Контроллер $slug создан", 'green');
|
||||
}
|
||||
|
||||
public function actionConstructCRUD(): void
|
||||
{
|
||||
$this->out->r("Введите slug для CRUD:", 'yellow');
|
||||
$slug = substr(fgets(STDIN), 0, -1);
|
||||
$slug = strtolower($slug);
|
||||
|
||||
$this->out->r("Введите model для CRUD:", 'yellow');
|
||||
$model = substr(fgets(STDIN), 0, -1);
|
||||
|
||||
$this->out->r("Введите путь для CRUD:", 'yellow');
|
||||
$path = substr(fgets(STDIN), 0, -1);
|
||||
$path = strtolower($path);
|
||||
|
||||
$moduleService = new ModuleService();
|
||||
$moduleService->createCRUD([
|
||||
'slug' => $slug,
|
||||
'model' => $model,
|
||||
], $path);
|
||||
|
||||
$this->out->r("CRUD $model создан", 'green');
|
||||
}
|
||||
|
||||
}
|
@ -91,6 +91,14 @@ App::$collector->group(["prefix" => "module"], callback: function (RouteCollecto
|
||||
[\kernel\console\controllers\ModuleController::class, 'actionConstructModule'],
|
||||
additionalInfo: ['description' => 'Сгенерировать модуль']
|
||||
);
|
||||
App::$collector->console('construct/controller',
|
||||
[\kernel\console\controllers\ModuleController::class, 'actionConstructController'],
|
||||
additionalInfo: ['description' => 'Сгенерировать контроллер']
|
||||
);
|
||||
App::$collector->console('construct/crud',
|
||||
[\kernel\console\controllers\ModuleController::class, 'actionConstructCRUD'],
|
||||
additionalInfo: ['description' => 'Сгенерировать CRUD']
|
||||
);
|
||||
});
|
||||
|
||||
App::$collector->group(["prefix" => "kernel"], callback: function (RouteCollector $router){
|
||||
|
@ -125,4 +125,12 @@ class Files
|
||||
}
|
||||
}
|
||||
|
||||
public static function isImageByExtension($filename): bool
|
||||
{
|
||||
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
|
||||
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||||
|
||||
return in_array($extension, $allowedExtensions);
|
||||
}
|
||||
|
||||
}
|
19
kernel/helpers/Url.php
Normal file
19
kernel/helpers/Url.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace kernel\helpers;
|
||||
|
||||
class Url
|
||||
{
|
||||
|
||||
public static function get_base_url()
|
||||
{
|
||||
// Удаляем параметр page если он есть
|
||||
$currentUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http")
|
||||
. "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
|
||||
// Удаляем параметр page если он есть
|
||||
$currentUrl = preg_replace('/([?&])page=[^&]*(&|$)/', '$1', $currentUrl);
|
||||
|
||||
return rtrim($currentUrl, '?&');
|
||||
}
|
||||
|
||||
}
|
@ -53,7 +53,7 @@ class MigrationService
|
||||
$dmr->delete($migrationInstance);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception('Не удалось откатить миграции');
|
||||
throw new \Exception('Не удалось откатить миграции: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -644,4 +644,61 @@ class ModuleService
|
||||
return true;
|
||||
}
|
||||
|
||||
public function createCRUD(array $params, string $modulePath)
|
||||
{
|
||||
$slug = $params['slug'];
|
||||
$model = $params['model'];
|
||||
|
||||
$this->createModuleFileByTemplate(
|
||||
KERNEL_TEMPLATES_DIR . '/controllers/kernel_controller_template',
|
||||
$modulePath . '/controllers/' . $model . 'Controller.php',
|
||||
$params
|
||||
);
|
||||
$this->createModuleFileByTemplate(
|
||||
KERNEL_TEMPLATES_DIR . '/models/model_template',
|
||||
$modulePath . '/models/' . $model . '.php',
|
||||
$params
|
||||
);
|
||||
$this->createModuleFileByTemplate(
|
||||
KERNEL_TEMPLATES_DIR . '/models/forms/create_form_template',
|
||||
$modulePath . '/models/forms/Create' . $model . 'Form.php',
|
||||
$params
|
||||
);
|
||||
$this->createModuleFileByTemplate(
|
||||
KERNEL_TEMPLATES_DIR . '/services/service_template',
|
||||
$modulePath . '/services/' . $model . 'Service.php',
|
||||
$params
|
||||
);
|
||||
|
||||
mkdir($modulePath . '/views/' . strtolower($model));
|
||||
|
||||
$this->createModuleFileByTemplate(
|
||||
KERNEL_TEMPLATES_DIR . '/views/index_template',
|
||||
$modulePath . '/views/' . strtolower($model) . '/index.php',
|
||||
$params
|
||||
);
|
||||
$this->createModuleFileByTemplate(
|
||||
KERNEL_TEMPLATES_DIR . '/views/view_template',
|
||||
$modulePath . '/views/' . strtolower($model) . '/view.php',
|
||||
$params
|
||||
);
|
||||
$this->createModuleFileByTemplate(
|
||||
KERNEL_TEMPLATES_DIR . '/views/form_template',
|
||||
$modulePath . '/views/' . strtolower($model) . '/form.php',
|
||||
$params
|
||||
);
|
||||
}
|
||||
|
||||
public function createController(array $params, string $path): void
|
||||
{
|
||||
$slug = $params['slug'];
|
||||
$model = $params['model'];
|
||||
|
||||
$this->createModuleFileByTemplate(
|
||||
KERNEL_TEMPLATES_DIR . '/controllers/kernel_controller_template',
|
||||
$path . '/' . $model . 'Controller.php',
|
||||
$params
|
||||
);
|
||||
}
|
||||
|
||||
}
|
1
resources/themes/gestalt/out/404.html
Normal file
1
resources/themes/gestalt/out/404.html
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
self.__BUILD_MANIFEST=function(r,e,t,_){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:5,errorRate:1e-4,numBits:96,numHashes:14,bitArray:[1,1,0,0,1,0,e,e,e,r,r,r,r,r,e,e,e,r,e,r,r,r,r,e,e,r,r,e,r,e,e,e,r,e,e,e,r,r,r,r,r,e,e,e,e,e,e,r,e,e,e,e,e,r,e,r,r,e,r,r,r,r,e,r,e,r,e,e,e,r,e,r,r,r,r,r,r,e,r,e,r,r,r,r,e,r,e,r,e,e,r,e,r,r,r,r]},__routerFilterDynamic:{numItems:2,errorRate:1e-4,numBits:39,numHashes:14,bitArray:[e,r,r,r,r,e,r,r,e,e,e,e,e,r,r,e,r,e,e,e,r,e,r,r,e,e,r,r,r,e,e,r,r,e,r,e,e,e,r]},"/_error":["static/chunks/pages/_error-4cc25812257ba5bd.js"],sortedPages:["/_app","/_error"]}}(1,0,0,0),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
@ -0,0 +1 @@
|
||||
self.__SSG_MANIFEST=new Set(["\u002Fevents\u002F[slug]","\u002Fparticipants\u002F[slug]"]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[492],{3868:(e,t,r)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/_not-found/page",function(){return r(5623)}])},3384:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"HTTPAccessErrorFallback",{enumerable:!0,get:function(){return o}}),r(306);let l=r(5155);r(2115);let n={error:{fontFamily:'system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',height:"100vh",textAlign:"center",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},desc:{display:"inline-block"},h1:{display:"inline-block",margin:"0 20px 0 0",padding:"0 23px 0 0",fontSize:24,fontWeight:500,verticalAlign:"top",lineHeight:"49px"},h2:{fontSize:14,fontWeight:400,lineHeight:"49px",margin:0}};function o(e){let{status:t,message:r}=e;return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("title",{children:t+": "+r}),(0,l.jsx)("div",{style:n.error,children:(0,l.jsxs)("div",{children:[(0,l.jsx)("style",{dangerouslySetInnerHTML:{__html:"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}),(0,l.jsx)("h1",{className:"next-error-h1",style:n.h1,children:t}),(0,l.jsx)("div",{style:n.desc,children:(0,l.jsx)("h2",{style:n.h2,children:r})})]})})]})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},5623:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return o}});let l=r(5155),n=r(3384);function o(){return(0,l.jsx)(n.HTTPAccessErrorFallback,{status:404,message:"This page could not be found."})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}},e=>{var t=t=>e(e.s=t);e.O(0,[441,517,358],()=>t(3868)),_N_E=e.O()}]);
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[177],{5691:(e,s,n)=>{Promise.resolve().then(n.t.bind(n,9324,23)),Promise.resolve().then(n.t.bind(n,8173,23)),Promise.resolve().then(n.t.bind(n,7970,23))},9324:()=>{}},e=>{var s=s=>e(e.s=s);e.O(0,[722,742,441,517,358],()=>s(5691)),_N_E=e.O()}]);
|
@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[974],{6993:(e,t,r)=>{Promise.resolve().then(r.bind(r,5360)),Promise.resolve().then(r.bind(r,5416)),Promise.resolve().then(r.t.bind(r,8173,23)),Promise.resolve().then(r.t.bind(r,7970,23))},5360:(e,t,r)=>{"use strict";r.d(t,{default:()=>a});var n=r(5155);r(2115);let a=e=>{let{className:t,name:r,variant:a="default",size:l="default"}=e,o={default:"bg-blue text-[16px] text-white",secondary:"text-[16px] text-blue border-[1px] border-blue"},s={default:"max-h-[39px] px-[25px] py-[10px]"},d=o[a]||o.default,u=s[l]||s.default;return(0,n.jsx)("button",{className:"".concat("flex items-center justify-center whitespace-nowrap rounded-[6px] font-[400]"," ").concat(d," ").concat(u," ").concat(t),children:r})}},5416:(e,t,r)=>{"use strict";r.d(t,{default:()=>l});var n=r(5155);r(2115);var a=r(5565);let l=e=>{let{className:t,name:r,variant:l="default"}=e;return(0,n.jsxs)("div",{className:"".concat(t," ").concat({default:"",secondary:"px-[36px] py-[7px] bg-white"}[l]," max-w-[225px] min-w-[180px] min-h-[39px] justify-center items-center w-fit cursor-pointer border-blue border-[1px] flex gap-[10px] rounded-[10px]"),children:[(0,n.jsx)("p",{className:"text-blue font-[700] text-[16px]",children:r}),(0,n.jsx)(a.default,{src:"/images/chevronDown.svg",alt:"chevronDown",width:11,height:8})]})}},5565:(e,t,r)=>{"use strict";r.d(t,{default:()=>a.a});var n=r(4146),a=r.n(n)},4146:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:t[r]})}(t,{default:function(){return d},getImageProps:function(){return s}});let n=r(306),a=r(666),l=r(7970),o=n._(r(5514));function s(e){let{props:t}=(0,a.getImgProps)(e,{defaultLoader:o.default,imgConf:{deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[16,32,48,64,96,128,256,384],path:"/_next/image",loader:"default",dangerouslyAllowSVG:!1,unoptimized:!0}});for(let[e,r]of Object.entries(t))void 0===r&&delete t[e];return{props:t}}let d=l.Image}},e=>{var t=t=>e(e.s=t);e.O(0,[742,441,517,358],()=>t(6993)),_N_E=e.O()}]);
|
@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[731],{4585:(e,s,l)=>{Promise.resolve().then(l.bind(l,6919)),Promise.resolve().then(l.t.bind(l,7970,23))},6919:(e,s,l)=>{"use strict";l.d(s,{default:()=>i});var n=l(5155),r=l(8173),t=l.n(r),a=l(6658);l(2115);let i=()=>{let e=(0,a.usePathname)().split("/").filter(e=>e),s={events:"мероприятия сообщества","event-1":"базовая программа подготовки гештальт-терапевтов - добор",participants:"участники",1:"кириллов кирилл кириллович"};return(0,n.jsx)("nav",{className:"max-w-[1083px] px-[25px] mx-auto",children:(0,n.jsxs)("ol",{className:"flex flex-wrap text-middleGrey font-[350] my-[50px]",children:[(0,n.jsx)("li",{children:(0,n.jsx)(t(),{href:"/",children:"главная"})}),e.map((l,r)=>{let a="/"+e.slice(0,r+1).join("/");return(0,n.jsx)("li",{children:(0,n.jsxs)(t(),{href:a,children:[(0,n.jsx)("span",{className:"mx-[2px]",children:"/"}),s[decodeURIComponent(l)]]})},a)})]})})}}},e=>{var s=s=>e(e.s=s);e.O(0,[742,441,517,358],()=>s(4585)),_N_E=e.O()}]);
|
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user