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.
@ -24,7 +33,7 @@ class EventController extends Controller
{
$behaviors = [
'verbs' => [
'class' => VerbFilter::className(),
'class' => VerbFilter::class,
'actions' => [
'delete' => ['post'],
],
@ -32,18 +41,19 @@ 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(),
'class' => AccessControl::class,
'rules' => [
// allow authenticated users
[
'actions' =>$allowedActions,
'actions' => $allowedActions,
'allow' => true,
'roles' => ['@'],
],
@ -103,14 +113,15 @@ 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,
]);
}
}
/**
* Updates an existing Event model.
@ -123,14 +134,15 @@ 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,
]);
}
}
/**
* Deletes an existing Event 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.');
}
}
}

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,6 +3,7 @@ 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
@ -13,7 +14,8 @@ All other errors are RE-THROWN to be caught by the calling service so an alert c
@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

@ -20,35 +20,28 @@ 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 = [];
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 = {
@ -57,22 +50,22 @@ export class MonthCalendarComponent implements OnInit, OnChanges {
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;
}
}