add admin timetable

This commit is contained in:
Roland Schneider 2019-10-23 08:49:40 +02:00 committed by Roland Schneider
parent 1300bfc752
commit bf85c737d5
32 changed files with 1037 additions and 120 deletions

View File

@ -170,6 +170,8 @@ class AdminMenuStructure{
$items[] = ['label' => 'Termek', 'url' => ['/room' ] ];
$items[] = ['label' => 'Esemény típusok', 'url' => ['/event-type' ] ];
$items[] = ['label' => 'Események', 'url' => ['/event/event/index' ] ];
$items[] = ['label' => 'Órarend', 'url' => ['/event/event/timetable' ] ];
$items[] = ['label' => 'Hét másolása', 'url' => ['/event/event/copy-week' ] ];
$this->menuItems[] = ['label' => 'Csoportos edzés', 'url' => $this->emptyUrl,
'items' => $items
];

View File

@ -8,6 +8,12 @@
namespace common\components;
use DateInterval;
use DateTime;
use DateTimeZone;
use Exception;
use Yii;
use yii\base\InvalidConfigException;
use yii\i18n\Formatter;
class DateUtil
@ -16,12 +22,13 @@ class DateUtil
* Get UTC today @00:00:00 .
* Helper method to generate date for mysql
*
* @return \DateTime
* @return DateTime
* @throws Exception
*/
public static function todayStart( ){
$d2 = new \DateTime();
$d2->setTimezone( new \DateTimeZone( "UTC" ) );
$d2->setTime(0, 0, 0);
$d2 = new DateTime();
$d2->setTimezone( new DateTimeZone('UTC') );
$d2->setTime(0, 0);
return $d2;
}
@ -29,13 +36,14 @@ class DateUtil
* Get UTC t @00:00:00 .
* Helper method to generate date for mysql
*
* @return \DateTime
* @return DateTime
* @throws Exception
*/
public static function tomorrowStart( ){
$d2 = new \DateTime();
$d2->add(new \DateInterval('P1D'));
$d2->setTimezone( new \DateTimeZone( "UTC" ) );
$d2->setTime(0, 0, 0);
$d2 = new DateTime();
$d2->add(new DateInterval('P1D'));
$d2->setTimezone( new DateTimeZone('UTC') );
$d2->setTime(0, 0);
return $d2;
}
@ -44,11 +52,11 @@ class DateUtil
public static function addMonth($timestamp, $monthCount = 1)
{
if ($timestamp instanceof \DateTime) {
if ($timestamp instanceof DateTime) {
$d1 = $timestamp;
} else {
$d1 = new \DateTime();
$d1 = new DateTime();
if (isset($timestamp)) {
$d1->setTimestamp($timestamp);
@ -63,28 +71,34 @@ class DateUtil
$day = $d1->format('d');
$year += floor($monthToAdd / 12);
$monthToAdd = $monthToAdd % 12;
$monthToAdd %= 12;
$month += $monthToAdd;
if ($month > 12) {
$year++;
$month = $month % 12;
if ($month === 0)
$month %= 12;
if ($month === 0) {
$month = 12;
}
}
if (!checkdate($month, $day, $year)) {
$d2 = \DateTime::createFromFormat('Y-n-j', $year . '-' . $month . '-1');
$d2 = DateTime::createFromFormat('Y-n-j', $year . '-' . $month . '-1');
$d2->modify('last day of');
} else {
$d2 = \DateTime::createFromFormat('Y-n-d', $year . '-' . $month . '-' . $day);
$d2 = DateTime::createFromFormat('Y-n-d', $year . '-' . $month . '-' . $day);
}
$d2->setTime(0, 0, 0);
$d2->setTime(0, 0);
return $d2;
}
/**
* @param $dateTimeObject
* @return string
* @throws InvalidConfigException
*/
public static function formatUtc($dateTimeObject)
{
$formatter = new Formatter;
@ -93,6 +107,11 @@ class DateUtil
return $formatter->asDatetime($dateTimeObject);
}
/**
* @param $dateTimeObject
* @return string
* @throws InvalidConfigException
*/
public static function formatDateUtc($dateTimeObject)
{
$formatter = new Formatter;
@ -103,9 +122,27 @@ class DateUtil
public static function parseDate($dateString){
$date = \DateTime::createFromFormat("Y.m.d", $dateString, new \DateTimeZone( 'UTC'));
$date->setTime(0, 0, 0);
$date = DateTime::createFromFormat('Y.m.d', $dateString, new DateTimeZone( 'UTC'));
$date->setTime(0, 0);
return $date;
}
}
/**
* @param integer $weekDay Numeric representation of the day of the week. @See https://www.php.net/manual/en/function.date.php
* @return string
*/
public static function getLocalDayName($weekDay){
$translations = [
0 => Yii::t('common', 'Sunday'),
1 => Yii::t('common', 'Monday'),
2 => Yii::t('common', 'Tuesday'),
3 => Yii::t('common', 'Wednesday'),
4 => Yii::t('common', 'Thursday'),
5 => Yii::t('common', 'Friday'),
6 => Yii::t('common', 'Saturday'),
7 => Yii::t('common', 'Sunday'),
];
return $translations[$weekDay];
}
}

View File

@ -5,15 +5,24 @@ namespace common\modules\event\controllers;
use common\manager\EventRegistrationManager;
use common\models\CardEventRegistrationForm;
use common\modules\event\EventModule;
use common\modules\event\models\copy\CopyWeekSearch;
use common\modules\event\models\EventPermissions;
use common\modules\event\models\timetable\TimeTableSearch;
use DateTime;
use Exception;
use Throwable;
use Yii;
use common\models\Event;
use common\modules\event\models\EventSearch;
use yii\data\ActiveDataProvider;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\HttpException;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\Response;
/** @noinspection PhpUnused */
/**
* EventController implements the CRUD actions for Event model.
@ -22,9 +31,9 @@ class EventController extends Controller
{
public function behaviors()
{
$behaviors = [
$behaviors = [
'verbs' => [
'class' => VerbFilter::className(),
'class' => VerbFilter::class,
'actions' => [
'delete' => ['post'],
],
@ -32,24 +41,25 @@ class EventController extends Controller
];
$module = EventModule::getInstance();
$allowedActions = [ 'index','view', 'reserve-card','cancel-registration','delete-registration' ];
if ( $module->mode == 'backend' ){
assert(isset($module), 'event module not set');
$allowedActions = ['index', 'view', 'reserve-card', 'cancel-registration', 'delete-registration', 'timetable','copy-week'];
if ($module->mode === 'backend') {
$allowedActions[] = 'create';
$allowedActions[] = 'update';
$allowedActions[] = 'delete';
}
$behaviors['access'] = [
'class' => \yii\filters\AccessControl::className(),
'rules' => [
// allow authenticated users
[
'actions' =>$allowedActions,
'allow' => true,
'roles' => ['@'],
],
// everything else is denied
'class' => AccessControl::class,
'rules' => [
// allow authenticated users
[
'actions' => $allowedActions,
'allow' => true,
'roles' => ['@'],
],
];
// everything else is denied
],
];
return $behaviors;
}
@ -84,7 +94,7 @@ class EventController extends Controller
$dataProvider = new ActiveDataProvider([
'query' => $eventRegistrationManager->createFindRegistrationsQuery($id),
'query' => $eventRegistrationManager->createFindRegistrationsQuery($id),
]
);
return $this->render('view', [
@ -103,13 +113,14 @@ class EventController extends Controller
{
$model = new Event();
/** @noinspection NotOptimalIfConditionsInspection */
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
return $this->render('create', [
'model' => $model,
]);
}
/**
@ -123,13 +134,14 @@ class EventController extends Controller
{
$model = $this->findModel($id);
/** @noinspection NotOptimalIfConditionsInspection */
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
return $this->render('update', [
'model' => $model,
]);
}
/**
@ -138,65 +150,63 @@ class EventController extends Controller
* @param integer $id
* @return mixed
* @throws NotFoundHttpException
* @throws \yii\db\Exception
* @throws Throwable
*/
public function actionDelete($id)
{
$manager = new EventRegistrationManager();
$manager->deleteEvent($this->findModel($id));
return $this->redirect(['index']);
}
}/** @noinspection PhpUnused */
/**
* @param $id
* @return \yii\web\Response
* @throws \yii\db\Exception
* @throws \Exception
* @return Response
* @throws Exception
*/
public function actionCancelRegistration($id)
{
$eventRegistrationManager = new EventRegistrationManager();
$db = \Yii::$app->db;
$db = Yii::$app->db;
$tx = $db->beginTransaction();
try{
try {
$registration = $eventRegistrationManager->loadRegistration($id);
$eventRegistrationManager->cancelRegistration($registration);
$tx->commit();
return $this->redirect(['view', 'id' => $registration->id_event]);
}catch (\Exception $ex){
} catch (Exception $ex) {
$tx->rollBack();
throw $ex;
}
}
}/** @noinspection PhpUnused */
/**
* @param $id
* @return \yii\web\Response
* @throws \yii\db\Exception
* @throws \Exception
* @return Response
* @throws Exception
*/
public function actionDeleteRegistration($id)
{
$eventRegistrationManager = new EventRegistrationManager();
$db = \Yii::$app->db;
$db = Yii::$app->db;
$tx = $db->beginTransaction();
try{
try {
$registration = $eventRegistrationManager->loadRegistration($id);
$eventRegistrationManager->deleteRegistration($registration);
$tx->commit();
return $this->redirect(['view', 'id' => $registration->id_event]);
}catch (\Exception $ex){
} catch (Exception $ex) {
$tx->rollBack();
throw $ex;
}
}
}/** @noinspection PhpUnused */
/**
* @param $id
* @return string|\yii\web\Response
* @return string|Response
* @throws NotFoundHttpException
* @throws \yii\db\Exception
* @throws Exception
*/
public function actionReserveCard($id)
{
@ -210,11 +220,11 @@ class EventController extends Controller
$manager = new EventRegistrationManager();
try {
$manager->registerCard($model);
} catch (HttpException $e) {
} /** @noinspection PhpRedundantCatchClauseInspection */ catch (HttpException $e) {
if (array_key_exists($e->getCode(), EventRegistrationManager::$STATES)) {
$model->addError("card_number", Yii::t('event-registration', EventRegistrationManager::$STATES[$e->getCode()]));
$model->addError('card_number', Yii::t('event-registration', EventRegistrationManager::$STATES[$e->getCode()]));
} else {
$model->addError("card_number", Yii::t('event-registration', "Unknown Error"));
$model->addError('card_number', Yii::t('event-registration', 'Unknown Error'));
}
}
}
@ -223,9 +233,9 @@ class EventController extends Controller
'model' => $model,
'event' => $event,
]);
} else {
return $this->redirect(['view', 'id' => $id]);
}
return $this->redirect(['view', 'id' => $id]);
}
return $this->render('register_card', [
'model' => $model,
@ -233,6 +243,28 @@ class EventController extends Controller
]);
}
/** @noinspection PhpUnused */
/**
* @return string
* @throws Exception
*/
public function actionTimetable()
{
$search = new TimeTableSearch();
$search->startDateString = (new DateTime())->format('Y.m.d');
$dataProvider = $search->search(Yii::$app->request->get());
return $this->render('timetable', array(
'model' => $search,
'dataProvider' => $dataProvider
));
}
public function actionCopyWeek(){
$model = new CopyWeekSearch();
$model->search(\Yii::$app->request->get());
return $this->render('copy_week',['model' => $model]);
}
/**
* Finds the Event model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
@ -244,8 +276,9 @@ class EventController extends Controller
{
if (($model = Event::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
throw new NotFoundHttpException('The requested page does not exist.');
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace common\modules\event\manager;
use common\models\Event;
use common\modules\event\models\timetable\TimeTableMonth;
use common\modules\event\models\timetable\TimeTableMonthDay;
use common\modules\event\models\timetable\TimeTableMonthWeek;
use customerapi\models\available\EventInterval;
use DateTime;
use Exception;
class EventManager
{
/**
* @param EventInterval $interval
* @return TimeTableMonth
* @throws Exception
*/
public function loadTimeTable($interval)
{
$timeTable = new TimeTableMonth();
$timeTable->interval = $interval;
/** @var DateTime[] $displayDates */
$displayDates = $interval->getAllDisplayDates();
$timeTable->weeks = [];
/** @var DateTime $displayDate */
foreach ($displayDates as $displayDate) {
$timeTableMonthDay = new TimeTableMonthDay();
$timeTableMonthDay->date = $displayDate;
$timeTableMonthDay->active = $interval->isActive($displayDate);
$timeTable->days[] = $timeTableMonthDay;
$weekNumber = $displayDate->format('W');
if (!isset($timeTable->weeks[$weekNumber])) {
$week = new TimeTableMonthWeek();
$week->weekNumber = $weekNumber;
$timeTable->weeks[$weekNumber] = $week;
}
$weekDayName = strtolower($displayDate->format('l'));
$timeTable->weeks[$weekNumber]->$weekDayName = $timeTableMonthDay;
}
// get events between active dates
$query = Event::find();
$query = $query->select(
[
'{{event}}.*',
// 'COUNT({{event_registration}}.id) AS reservationCount'
]);
$events = $query
->innerJoinWith('trainer')
->innerJoinWith('eventType')
->innerJoinWith('room')
->joinWith('activeEventRegistrations')
->andWhere(['>=', 'event.start', $interval->firstActiveDate->getTimestamp()])
->andWhere(['<', 'event.start', (clone $interval->lastActiveDate)->modify('+1 day')->getTimestamp()])
->andWhere(['event.active' => '1'])
->orderBy([
'event.start' => SORT_ASC
])
->all();
// set events per day
/** @var Event $event */
foreach ($events as $event) {
$eventDay = new DateTime();
$eventDay->setTimestamp($event->start);
$eventDay->setTime(0, 0);
foreach ($timeTable->days as $date) {
if ($date->date == $eventDay) {
$date->events[] = $event;
break;
}
}
}
return $timeTable;
}
}

View File

@ -0,0 +1,92 @@
<?php
namespace common\modules\event\models\copy;
use common\components\DateUtil;
use common\modules\event\manager\EventManager;
use common\modules\event\models\timetable\TimeTableMonth;
use customerapi\models\available\EventInterval;
use DateTime;
use Exception;
use Yii;
use common\models\Event;
use yii\base\Model;
use yii\data\ArrayDataProvider;
/**
* @property string $sourceDateString
* @property string $targetDateString
* @property integer $timestampSource
* @property integer $timestampTarget
* @property EventInterval $sourceInterval
* @property EventInterval $targetInterval
* @property TimeTableMonth $sourceTimeTable
* @property TimeTableMonth $targetTimeTable
* @property string[] $tableHeaders
*/
class CopyWeekSearch extends Model
{
public $sourceDateString;
public $timestampSource;
public $targetDateString;
public $timestampTarget;
public $sourceInterval;
public $targetInterval;
public $sourceTimeTable;
public $targetTimeTable;
public $tableHeaders;
/**
* @inheritdoc
*/
public function rules()
{
return [
[['sourceDateString',], 'date', 'format' => Yii::$app->formatter->dateFormat, 'timestampAttribute' => 'timestampSource', 'timeZone' => 'UTC'],
[['targetDateString',], 'date', 'format' => Yii::$app->formatter->dateFormat, 'timestampAttribute' => 'timestampTarget', 'timeZone' => 'UTC'],
];
}
public function attributeLabels()
{
return [
'sourceDateString' => 'Forrás Dátum',
'targetDateString' => 'Cél Dátum',
];
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @throws Exception
*/
public function search($params)
{
$sourceDate = null;
$targetDate = null;
$this->load($params);
if ($this->validate()) {
$sourceDate = new DateTime();
$sourceDate->setTimestamp($this->timestampSource);
$targetDate = new DateTime();
$targetDate->setTimestamp($this->timestampTarget);
}
$this->sourceInterval = EventInterval::createInterval($sourceDate,7,7);
$this->targetInterval = EventInterval::createInterval($targetDate,7,7);
$eventManager = new EventManager();
$this->sourceTimeTable = $eventManager->loadTimeTable($this->sourceInterval);
$this->targetTimeTable = $eventManager->loadTimeTable($this->targetInterval);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace common\modules\event\models\timetable;
use yii\base\Model;
/**
* Class TimeTableModel
* @property TimeTableMonth $timeTableMonth
*/
class TimeTableModel extends Model
{
public $timeTableMonth;
}

View File

@ -0,0 +1,32 @@
<?php
namespace common\modules\event\models\timetable;
use customerapi\models\available\EventInterval;
use yii\data\ArrayDataProvider;
/** @noinspection PhpUnused */
/**
* Class TimeTableMonth
* @property EventInterval $interval
* @property TimeTableMonthDay[] $days
* @property TimeTableMonthWeek[] $weeks
*/
class TimeTableMonth
{
public $interval;
public $days = array();
public $weekDayNames = array();
public $weeks;
public function getWeeksArrayDataProvider()
{
return new ArrayDataProvider([
'allModels' => $this->weeks
]);
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace common\modules\event\models\timetable;
use \DateTime;
/**
* Class TimeTableMonthDay
* @param DateTime $date
* @param TimeTableMonthDayEvent[] $events
* @param boolean $actives
*/
class TimeTableMonthDay
{
public $date;
public $events = array();
public $active;
}

View File

@ -0,0 +1,14 @@
<?php
namespace common\modules\event\models\timetable;
use common\models\Event;
/**
* Class TimeTableMonthDayEvent
* @property Event $event
*/
class TimeTableMonthDayEvent
{
public $event;
}

View File

@ -0,0 +1,50 @@
<?php /** @noinspection ALL */
namespace common\modules\event\models\timetable;
use customerapi\models\available\EventInterval;
/** @noinspection PhpUnused */
/**
* Class TimeTableMonthWeek
* @property EventInterval $interval
* @property TimeTableMonthDay $monday
* @property TimeTableMonthDay $tuesday
* @property TimeTableMonthDay $wednesday
* @property TimeTableMonthDay $thursday
* @property TimeTableMonthDay $friday
* @property TimeTableMonthDay $saturday
* @property TimeTableMonthDay $sunday
* @property integer $weekNumber
*/
class TimeTableMonthWeek
{
public $monday;
public $tuesday;
public $wednesday;
public $thursday;
public $friday;
public $saturday;
public $sunday;
public $weekNumber;
/**Get the week day bay property name
* @param $weekDay
* @return mixed
*/
public function getWeekDay($weekDay)
{
$days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
$days = array_combine($days, $days);
$objectAttribute = $days[$weekDay];
/** @var TimeTableMonthDay $day */
return $this->$objectAttribute;
}
}

View File

@ -0,0 +1,86 @@
<?php
namespace common\modules\event\models\timetable;
use common\components\DateUtil;
use common\modules\event\manager\EventManager;
use customerapi\models\available\EventInterval;
use DateTime;
use Exception;
use Yii;
use yii\base\Model;
use yii\data\ArrayDataProvider;
/**
* @property string[] $tableHeaders
* @property TimeTableModel $tableModel
*/
class TimeTableSearch extends Model
{
public $startDateString;
public $timestampStart;
public $tableHeaders;
public $tableModel;
/**
* @inheritdoc
*/
public function rules()
{
return [
[['startDateString',], 'date', 'format' => Yii::$app->formatter->dateFormat, 'timestampAttribute' => 'timestampStart', 'timeZone' => 'UTC'],
];
}
public function attributeLabels()
{
return [
'startDateString' => 'Dátum'
];
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ArrayDataProvider
* @throws Exception
*/
public function search($params)
{
$today = null;
$this->load($params);
if ($this->validate()) {
$today = new DateTime( );
$today->setTimestamp($this->timestampStart);
}
$interval = EventInterval::createInterval($today);
$em = new EventManager();
$timeTable = $em->loadTimeTable($interval);
$this->tableModel = new TimeTableModel();
$this->tableModel->timeTableMonth = $timeTable;
/** @var DateTime[] $displayDates */
$displayDates = $interval->getAllDisplayDates();
for ($i = 0; $i < 7; $i++) {
$timeTable->weekDayNames[] = DateUtil::getLocalDayName($displayDates[$i]->format('w'));
}
$this->tableHeaders = [''];
$this->tableHeaders = array_merge($this->tableHeaders, $timeTable->weekDayNames);
$dataProvider = new ArrayDataProvider([
'allModels' => $timeTable->weeks
]);
return $dataProvider;
}
}

View File

@ -0,0 +1,57 @@
<?php
use kartik\widgets\DatePicker;
use kartik\widgets\DateTimePicker;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $model backend\models\EventSearch */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="event-search">
<?php $form = ActiveForm::begin([
'action' => ['copy-week'],
'method' => 'get',
]); ?>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Keresés</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<?= $form->field($model, 'sourceDateString')->widget(DatePicker::class, [
'pluginOptions' => [
'autoclose' => true,
'format' => 'yyyy.mm.dd'
],
'options' => [
'autocomplete' => 'off'
]
]) ?>
</div>
<div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<?= $form->field($model, 'targetDateString')->widget(DatePicker::class, [
'pluginOptions' => [
'autoclose' => true,
'format' => 'yyyy.mm.dd'
],
'options' => [
'autocomplete' => 'off'
]
]) ?>
</div>
</div>
</div>
<div class="panel-footer">
<?= Html::submitButton(Yii::t('event', 'Search'), ['class' => 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>

View File

@ -0,0 +1,46 @@
<?php
use kartik\widgets\DatePicker;
use kartik\widgets\DateTimePicker;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $model backend\models\EventSearch */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="event-search">
<?php $form = ActiveForm::begin([
'action' => ['timetable'],
'method' => 'get',
]); ?>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Keresés</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<?= $form->field($model, 'startDateString')->widget(DatePicker::class, [
'pluginOptions' => [
'autoclose' => true,
'format' => 'yyyy.mm.dd'
],
'options' => [
'autocomplete' => 'off'
]
]) ?>
</div>
</div>
</div>
<div class="panel-footer">
<?= Html::submitButton(Yii::t('event', 'Search'), ['class' => 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>

View File

@ -0,0 +1,22 @@
<?php use common\modules\event\models\copy\CopyWeekSearch;
use common\modules\event\widgets\timetable\TimeTableMonthView;
/* @var $this yii\web\View */
/* @var $tableHeaders string */
/* @var $model CopyWeekSearch */
use common\modules\event\models\timetable\TimeTableModel;
use yii\grid\GridView as GridViewAlias; ?>
<style>
</style>
<h1>Hét másolása</h1>
<?php
echo $this->render('_copy_week_search', ['model' => $model]);
?>
<h2>Forrás hét</h2>
<?= TimeTableMonthView::widget(['timeTable' => $model->sourceTimeTable]) ?>
<h2>Cél hét</h2>
<?= TimeTableMonthView::widget(['timeTable' => $model->targetTimeTable]) ?>

View File

@ -0,0 +1,30 @@
<?php use common\modules\event\models\timetable\TimeTableSearch;
/* @var $this yii\web\View */
/* @var $tableHeaders string */
/* @var $model TimeTableSearch */
/* @var $tableModel TimeTableModel */
$tableModel = $model->tableModel;
$timeTable = $model->tableModel->timeTableMonth;
use common\modules\event\models\timetable\TimeTableModel;
use common\modules\event\widgets\timetable\TimeTableMonthView;
?>
<style>
</style>
<h1>Órarend</h1>
<?php echo $this->render('_timetable_search', ['model' => $model]); ?>
<h2>
<?= $timeTable->interval->firstActiveDate->format("Y") ?>
-
<?= $timeTable->interval->firstActiveDate->format("m") ?>
</h2>
<?= TimeTableMonthView::widget(['timeTable' => $timeTable]) ?>

View File

@ -0,0 +1,30 @@
<?php
namespace common\modules\event\widgets\day;
use common\modules\event\models\timetable\TimeTableMonthDay;
use yii\base\Widget;
/** @noinspection PhpUnused */
/**
* Class TimeTableMonthDayView
* @package common\modules\event\widgets
*
* @property TimeTableMonthDay $day
*/
class TimeTableMonthDayView extends \yii\bootstrap\Widget
{
public $day;
public function init(){
parent::init();
}
public function run(){
return $this->render('_day', [ 'day' => $this->day]);
}
}

View File

@ -0,0 +1,20 @@
<?php
/* @var $day TimeTableMonthDay */
use common\models\Event;
use common\modules\event\models\timetable\TimeTableMonthDay;
use common\modules\event\widgets\event\EventView;
?>
<h3>
<?= $day->date->format('d') ?>
</h3>
<?php if (count($day->events) === 0) {
echo EventView::widget(['event' => null]);
} else {
/** @var Event $event */
foreach ($day->events as $event) {
echo EventView::widget(['event' => $event]);
}
} ?>

View File

@ -0,0 +1,45 @@
<?php
namespace common\modules\event\widgets\event;
use common\models\Event;
use common\modules\event\models\timetable\TimeTableMonthDay;
use yii\base\Widget;
/** @noinspection PhpUnused */
/**
* Class TimeTableMonthDayView
* @package common\modules\event\widgets
*
* @property Event $event
*/
class EventView extends \yii\bootstrap\Widget
{
public $event;
public $start;
public $end;
public function init(){
parent::init();
if ( isset($this->event )){
$this->start = new \DateTime();
$this->start->setTimestamp($this->event->start);
$this->end = new \DateTime();
$this->end->setTimestamp($this->event->end);
}
}
public function run(){
return $this->render('_event',
[
'event' => $this->event,
'start' => $this->start,
'end' => $this->end
]
);
}
}

View File

@ -0,0 +1,33 @@
<?php
/* @var $event Event */
/* @var $start DateTime */
/* @var $end DateTime */
use common\models\Event;
use common\modules\event\models\timetable\TimeTableMonthDay;
use yii\helpers\Html;
use yii\helpers\Url;
if (!isset($event)) {
?>
<div class="alert alert-info">Nincs esemény</div>
<?php
} else {
?>
<div class="alert alert-success">
<?= Html::a( $start->format('H:i') .'-' . $end->format('H:i') , Url::toRoute(['event/update', 'id' => $event->id ] ) ) ?>
<br>
<?= Html::a( $event->eventType->name , Url::toRoute(['/event-type/view', 'id'=> $event->eventType->id])) ?>
<br>
<?= Html::a( $event->room->name , Url::toRoute(['/room/view', 'id' => $event->room->id]) )?>
<br>
<?= Html::a( $event->trainer->name , Url::toRoute(['/trainer/view', 'id' => $event->trainer->id]) )?>
<br>
<?= $event->eventRegistrationCount ?>
/
<?= $event->seat_count ?>
</div>
<?php
}

View File

@ -0,0 +1,39 @@
<?php
namespace common\modules\event\widgets\timetable;
use common\modules\event\models\timetable\TimeTableMonthDay;
use common\modules\event\models\timetable\TimeTableMonthWeek;
use common\modules\event\widgets\day\TimeTableMonthDayView;
use yii\bootstrap\Widget;
/** @noinspection PhpUnused */
/**
* Class TimeTableMonthDayView
* @package common\modules\event\widgets
*
* @property TimeTableMonthDay $day
*/
class TimeTableMonthView extends Widget
{
public $timeTable;
public function run() {
return $this->render('_timetable', [ 'timeTable' => $this->timeTable]);
}
public static function renderDay($weekDay ){
/**
* @param TimeTableMonthWeek $week
* @return string
*/
return static function ($week) use ($weekDay) {
return TimeTableMonthDayView::widget(['day' => $week->getWeekDay($weekDay)]);
};
}
}

View File

@ -0,0 +1,79 @@
<?php
/* @var $timeTable TimeTableMonth */
use common\models\Event;
use common\modules\event\models\timetable\TimeTableMonth;
use common\modules\event\models\timetable\TimeTableMonthDay;
use common\modules\event\models\timetable\TimeTableMonthWeek;
use common\modules\event\widgets\day\TimeTableMonthDayView;
use common\modules\event\widgets\event\EventView;
use common\modules\event\widgets\timetable\TimeTableMonthView;
use yii\grid\ActionColumn;
use yii\grid\GridView;
?>
<?php
?>
<?= GridView::widget([
'dataProvider' => $timeTable->getWeeksArrayDataProvider(),
'columns' => [
[
'attribute' => 'weekNumber',
'label' => '',
'value' => static function ($model,$key){
return $model->weekNumber;
}
],
[
'attribute' => 'monday',
'label' => 'Hétfő',
'format' => 'raw',
'value' => TimeTableMonthView::renderDay('monday')
],
[
'attribute' => 'tuesday',
'label' => 'Kedd',
'format' => 'raw',
'value' => TimeTableMonthView::renderDay('tuesday')
],
[
'attribute' => 'wednesday',
'label' => 'Szerda',
'format' => 'raw',
'value' => TimeTableMonthView::renderDay('wednesday')
],
[
'attribute' => 'thursday',
'label' => 'Csütörtök',
'format' => 'raw',
'value' => TimeTableMonthView::renderDay('thursday')
],
[
'attribute' => 'friday',
'label' => 'Péntek',
'format' => 'raw',
'value' => TimeTableMonthView::renderDay('friday')
],
[
'attribute' => 'saturday',
'format' => 'raw',
'label' => 'Szombat',
'value' => TimeTableMonthView::renderDay('saturday')
],
[
'attribute' => 'Sunday',
'label' => 'Vasárnap',
'format' => 'raw',
'value' => TimeTableMonthView::renderDay('sunday')
],
[
'class' => ActionColumn::class,
'template' => '{view} {update}',
],
],
]) ?>

View File

@ -3,17 +3,19 @@ import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from "@angular/c
import { Observable, throwError } from "rxjs";
import { catchError } from "rxjs/operators";
import { AuthenticationService} from "../services/authentication.service";
import {NavigationService} from "../services/navigation.service";
/*
Http error interceptor works with the calling service and the API's
It intercepts the responses from the API and check for the status codes (if there were any errors).
Error Status 401: Unauthorized Response - the user will be automatically logged out
All other errors are RE-THROWN to be caught by the calling service so an alert can be displayed to the user
All other errors are RE-THROWN to be caught by the calling service so an alert can be displayed to the user
*/
@Injectable()
export class ErrorInterceptor implements HttpInterceptor{
constructor(private authenticationService: AuthenticationService){}
constructor(private authenticationService: AuthenticationService,
private navigationService: NavigationService){}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
return next.handle(request)
@ -22,7 +24,8 @@ All other errors are RE-THROWN to be caught by the calling service so an alert c
if(err.status === 401){
// auto logout on unauthorized response
this.authenticationService.logout();
location.reload(true);
this.navigationService.navigateToLogin();
// location.reload(true);
}
const error = err.error.message || err.statusText;

View File

@ -76,6 +76,7 @@ export class FakeBackendInterceptor implements HttpInterceptor {
let reservedAt = id % 2 ? this.createEventDate(0, 1) : null;
events.push(
{
room: undefined,
id: id,
name: 'esemény ' + id,
start: this.createEventDate(dayIndex, hourIndex),
@ -84,7 +85,7 @@ export class FakeBackendInterceptor implements HttpInterceptor {
eventType: eventTypes[id % eventTypes.length],
reservedAt: reservedAt,
reservationCount: id % 11,
seatCount: 10,
seatCount: 10
}
)
}

View File

@ -1,7 +1,6 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {Event} from "../../services/event.service";
import * as moment from "moment";
import {MonthCalendarEvent} from "../month-calendar/month-calendar.component";
import {dateToMoment, MonthCalendarEvent} from "../month-calendar/month-calendar.component";
@Component({
selector: 'app-month-calendar-event',
@ -23,7 +22,7 @@ export class MonthCalendarEventComponent implements OnInit {
}
formatTime() {
return moment(this.event.start).format('HH:mm');
return dateToMoment(this.event.start).utc().format('HH:mm');
}
hasTrainer() {

View File

@ -6,7 +6,7 @@
</div>
</header>
<div *ngIf="eventsAvailableResponse" class="row border border-right-0 border-bottom-0">
<ng-container *ngFor="let day of eventsAvailableResponse.days; let i = index">
<ng-container *ngFor="let day of eventsAvailableResponse.dates; let i = index">
<div app-month-calendar-day [day]="day" (onEvent)="handleEvent($event)" ></div>
<div *ngIf="i > 0 && ( ((i+1) % 7) == 0)" class="w-100"></div>
</ng-container>

View File

@ -1,6 +1,6 @@
import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
import {Event, EventsAvailableResponse} from "../../services/event.service";
import * as moment from "moment";
import * as moment from "moment";
@Component({
selector: 'app-month-calendar',
@ -20,59 +20,52 @@ export class MonthCalendarComponent implements OnInit, OnChanges {
@Output()
onEvent: EventEmitter<MonthCalendarEvent> = new EventEmitter<MonthCalendarEvent>();
constructor( ) { }
constructor() {
}
ngOnInit() {
moment.locale('hu');
//
this.fillDaysOfWeek();
//
// let firstDay = moment().startOf('week');
//
// this.days = [];
// if ( this.eventsAvailableResponse ){
//
// for ( let i = 0; i < this.eventsAvailableResponse.days.length; i++){
// this.days.push({
// date: this.eventsAvailableResponse.days[i],
// events: [],
// active: true
// })
// }
// }
}
fillDaysOfWeek(){
fillDaysOfWeek() {
this.daysOfWeek = [];
let startOfWeek = moment().startOf("week");
for ( let i = 0; i < 7 ; i++ ){
let momWeekDay = startOfWeek.clone().add(i,'d');
const dayOfWeek = {
name: momWeekDay.format("dddd"),
};
this.daysOfWeek.push(dayOfWeek);
if ( this.eventsAvailableResponse) {
for (let i = 0; i < this.eventsAvailableResponse.dates.length && i < 7; i++) {
const date = moment.unix(this.eventsAvailableResponse.dates[i].date);
const dayOfWeek = {
name: date.format("dddd"),
};
this.daysOfWeek.push(dayOfWeek);
}
}else{
let startOfWeek = moment().startOf("week");
for ( let i = 0; i < 7 ; i++ ){
let momWeekDay = startOfWeek.clone().add(i,'d');
const dayOfWeek = {
name: momWeekDay.format("dddd"),
};
this.daysOfWeek.push(dayOfWeek);
}
}
}
ngOnChanges(changes: SimpleChanges): void {
console.info(changes);
if ( changes.hasOwnProperty('eventsAvailableResponse')){
if (changes.hasOwnProperty('eventsAvailableResponse')) {
this.fillDaysOfWeek();
}
}
handleEvent($event){
handleEvent($event) {
this.onEvent.emit($event);
}
}
export interface Day {
date: number;
date: unixTime;
events: Event[];
active: boolean;
}
@ -82,9 +75,15 @@ export interface DayOfWeek {
}
export function dateToMoment(date: number) {
return moment(date);
return moment.unix(date);
}
/**
* Unix time is the number of seconds that have elapsed since the Unix epoch,
* that is the time 00:00:00 UTC on 1 January 1970
*/
type unixTime= number;
export interface MonthCalendarEvent {
type: string; // type of the month calendar event
event: Event; // the fitness event

View File

@ -25,6 +25,5 @@ export class HomeComponent implements OnInit {
handleEvent($event: MonthCalendarEvent) {
console.info($event);
this.navigationService.navigateToEventDetails($event.event.id);
}
}

View File

@ -31,7 +31,7 @@ export class Endpoints {
public static GET_EVENTS_AVAILABLE(){
return `${this.baseUrl}/events/available`;
return `${this.baseUrl}/event/available`;
}
}

View File

@ -73,7 +73,7 @@ export interface DayToDisplay {
}
export interface EventsAvailableResponse {
days: DayToDisplay[];
dates: DayToDisplay[];
events: Event[];
}

View File

@ -20,5 +20,9 @@ export class NavigationService {
this.navigate(['/home' ])
}
public navigateToLogin(){
this.navigate(['/login' ])
}
}

View File

@ -82,6 +82,7 @@ class EventController extends CustomerApiController
}
}
return
$this->asJson([
'interval' => $interval,

View File

@ -17,6 +17,9 @@ use DateTime;
class EventInterval
{
public $year;
public $month;
public $countOfActiveDays = 14;
public $daysToDisplay = 21;
@ -26,19 +29,27 @@ class EventInterval
public $firstDisplayDate;
public $lastDisplayDate;
private function __construct()
private function __construct($today = null, $countOfActiveDays = 14,$daysToDisplay = 21)
{
$firstActiveDay = new DateTime();
$this->countOfActiveDays = $countOfActiveDays;
$this->daysToDisplay = $daysToDisplay;
if ( !isset($today)){
$today = new DateTime();
}
$today->setTime(0, 0);
$firstActiveDay = clone $today;
$firstActiveDay->setTime(0, 0);
$this->firstActiveDate = $firstActiveDay;
$lastActiveDay = new DateTime();
$lastActiveDay = clone $firstActiveDay;
$lastActiveDay->setTime(0, 0);
$lastActiveDay->modify('+' . $this->countOfActiveDays . ' day');
$this->lastActiveDate = $lastActiveDay;
$firstDisplayDate = new DateTime();
$firstDisplayDate = clone $firstActiveDay;
$firstDisplayDate->modify('this week');
$firstDisplayDate->setTime(0, 0);
$this->firstDisplayDate = $firstDisplayDate;
@ -50,7 +61,37 @@ class EventInterval
}
public static function createInterval(){
return new EventInterval();
}
public static function createInterval($today = null,$countOfActiveDays = 14,$daysToDisplay = 21)
{
return new EventInterval($today,$countOfActiveDays,$daysToDisplay);
}
/**
* @param DateTime $day
* @return bool true if active, otherwise false
*/
public function isActive($day)
{
$afterFirstActiveDay = $this->firstActiveDate < $day || $this->firstActiveDate == $day;
$beforeLastActiveDay = $this->lastActiveDate > $day || $this->lastActiveDate == $day;
return ($afterFirstActiveDay && $beforeLastActiveDay);
}
/**
* @return DateTime[]
*/
public function getAllDisplayDates()
{
$dates = array();
for ($i = 0; $i < $this->daysToDisplay; $i++) {
$date = clone $this->firstDisplayDate;
$date = $date->modify('+' . $i . ' day');
$dates[] = $date;
}
return $dates;
}
}