From bf85c737d54e4c46f6ad104d833074af857b105f Mon Sep 17 00:00:00 2001 From: Roland Schneider Date: Wed, 23 Oct 2019 08:49:40 +0200 Subject: [PATCH] add admin timetable --- backend/components/AdminMenuStructure.php | 2 + common/components/DateUtil.php | 77 ++++++++--- .../event/controllers/EventController.php | 129 +++++++++++------- common/modules/event/manager/EventManager.php | 90 ++++++++++++ .../event/models/copy/CopyWeekSearch.php | 92 +++++++++++++ .../event/models/timetable/TimeTableModel.php | 13 ++ .../event/models/timetable/TimeTableMonth.php | 32 +++++ .../models/timetable/TimeTableMonthDay.php | 20 +++ .../timetable/TimeTableMonthDayEvent.php | 14 ++ .../models/timetable/TimeTableMonthWeek.php | 50 +++++++ .../models/timetable/TimeTableSearch.php | 86 ++++++++++++ .../event/views/event/_copy_week_search.php | 57 ++++++++ .../event/views/event/_timetable_search.php | 46 +++++++ .../modules/event/views/event/copy_week.php | 22 +++ .../modules/event/views/event/timetable.php | 30 ++++ .../widgets/day/TimeTableMonthDayView.php | 30 ++++ .../modules/event/widgets/day/views/_day.php | 20 +++ .../modules/event/widgets/event/EventView.php | 45 ++++++ .../event/widgets/event/views/_event.php | 33 +++++ .../widgets/timetable/TimeTableMonthView.php | 39 ++++++ .../widgets/timetable/views/_timetable.php | 79 +++++++++++ .../app/src/app/_helpers/error.interceptor.ts | 9 +- customer/app/src/app/_helpers/fake-backend.ts | 3 +- .../month-calendar-event.component.ts | 5 +- .../month-calendar.component.html | 2 +- .../month-calendar.component.ts | 67 +++++---- .../app/src/app/pages/home/home.component.ts | 1 - customer/app/src/app/services/endpoints.ts | 2 +- .../app/src/app/services/event.service.ts | 2 +- .../src/app/services/navigation.service.ts | 4 + customerapi/controllers/EventController.php | 1 + .../models/available/EventInterval.php | 55 +++++++- 32 files changed, 1037 insertions(+), 120 deletions(-) create mode 100644 common/modules/event/manager/EventManager.php create mode 100644 common/modules/event/models/copy/CopyWeekSearch.php create mode 100644 common/modules/event/models/timetable/TimeTableModel.php create mode 100644 common/modules/event/models/timetable/TimeTableMonth.php create mode 100644 common/modules/event/models/timetable/TimeTableMonthDay.php create mode 100644 common/modules/event/models/timetable/TimeTableMonthDayEvent.php create mode 100644 common/modules/event/models/timetable/TimeTableMonthWeek.php create mode 100644 common/modules/event/models/timetable/TimeTableSearch.php create mode 100644 common/modules/event/views/event/_copy_week_search.php create mode 100644 common/modules/event/views/event/_timetable_search.php create mode 100644 common/modules/event/views/event/copy_week.php create mode 100644 common/modules/event/views/event/timetable.php create mode 100644 common/modules/event/widgets/day/TimeTableMonthDayView.php create mode 100644 common/modules/event/widgets/day/views/_day.php create mode 100644 common/modules/event/widgets/event/EventView.php create mode 100644 common/modules/event/widgets/event/views/_event.php create mode 100644 common/modules/event/widgets/timetable/TimeTableMonthView.php create mode 100644 common/modules/event/widgets/timetable/views/_timetable.php diff --git a/backend/components/AdminMenuStructure.php b/backend/components/AdminMenuStructure.php index b847eaa..86bcd13 100644 --- a/backend/components/AdminMenuStructure.php +++ b/backend/components/AdminMenuStructure.php @@ -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 ]; diff --git a/common/components/DateUtil.php b/common/components/DateUtil.php index eb9437e..cf316ce 100644 --- a/common/components/DateUtil.php +++ b/common/components/DateUtil.php @@ -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; } -} \ No newline at end of file + /** + * @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]; + } + +} diff --git a/common/modules/event/controllers/EventController.php b/common/modules/event/controllers/EventController.php index 47f8dc8..838ae51 100644 --- a/common/modules/event/controllers/EventController.php +++ b/common/modules/event/controllers/EventController.php @@ -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.'); } + } diff --git a/common/modules/event/manager/EventManager.php b/common/modules/event/manager/EventManager.php new file mode 100644 index 0000000..fc95ce1 --- /dev/null +++ b/common/modules/event/manager/EventManager.php @@ -0,0 +1,90 @@ +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; + } + +} diff --git a/common/modules/event/models/copy/CopyWeekSearch.php b/common/modules/event/models/copy/CopyWeekSearch.php new file mode 100644 index 0000000..a2299fd --- /dev/null +++ b/common/modules/event/models/copy/CopyWeekSearch.php @@ -0,0 +1,92 @@ + 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); + } +} diff --git a/common/modules/event/models/timetable/TimeTableModel.php b/common/modules/event/models/timetable/TimeTableModel.php new file mode 100644 index 0000000..5aeb2a9 --- /dev/null +++ b/common/modules/event/models/timetable/TimeTableModel.php @@ -0,0 +1,13 @@ + $this->weeks + ]); + } + +} diff --git a/common/modules/event/models/timetable/TimeTableMonthDay.php b/common/modules/event/models/timetable/TimeTableMonthDay.php new file mode 100644 index 0000000..e876e8b --- /dev/null +++ b/common/modules/event/models/timetable/TimeTableMonthDay.php @@ -0,0 +1,20 @@ +$objectAttribute; + } + +} diff --git a/common/modules/event/models/timetable/TimeTableSearch.php b/common/modules/event/models/timetable/TimeTableSearch.php new file mode 100644 index 0000000..26a6df2 --- /dev/null +++ b/common/modules/event/models/timetable/TimeTableSearch.php @@ -0,0 +1,86 @@ + 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; + } +} diff --git a/common/modules/event/views/event/_copy_week_search.php b/common/modules/event/views/event/_copy_week_search.php new file mode 100644 index 0000000..d7a7c02 --- /dev/null +++ b/common/modules/event/views/event/_copy_week_search.php @@ -0,0 +1,57 @@ + + + diff --git a/common/modules/event/views/event/_timetable_search.php b/common/modules/event/views/event/_timetable_search.php new file mode 100644 index 0000000..8743da0 --- /dev/null +++ b/common/modules/event/views/event/_timetable_search.php @@ -0,0 +1,46 @@ + + + diff --git a/common/modules/event/views/event/copy_week.php b/common/modules/event/views/event/copy_week.php new file mode 100644 index 0000000..99eed18 --- /dev/null +++ b/common/modules/event/views/event/copy_week.php @@ -0,0 +1,22 @@ + + +

Hét másolása

+render('_copy_week_search', ['model' => $model]); +?> +

Forrás hét

+ $model->sourceTimeTable]) ?> +

Cél hét

+ $model->targetTimeTable]) ?> diff --git a/common/modules/event/views/event/timetable.php b/common/modules/event/views/event/timetable.php new file mode 100644 index 0000000..1387cf8 --- /dev/null +++ b/common/modules/event/views/event/timetable.php @@ -0,0 +1,30 @@ +tableModel; +$timeTable = $model->tableModel->timeTableMonth; + + +use common\modules\event\models\timetable\TimeTableModel; +use common\modules\event\widgets\timetable\TimeTableMonthView; + +?> + + +

Órarend

+render('_timetable_search', ['model' => $model]); ?> + +

+ interval->firstActiveDate->format("Y") ?> + - + interval->firstActiveDate->format("m") ?> +

+ $timeTable]) ?> + diff --git a/common/modules/event/widgets/day/TimeTableMonthDayView.php b/common/modules/event/widgets/day/TimeTableMonthDayView.php new file mode 100644 index 0000000..bd1b064 --- /dev/null +++ b/common/modules/event/widgets/day/TimeTableMonthDayView.php @@ -0,0 +1,30 @@ +render('_day', [ 'day' => $this->day]); + } + + + +} diff --git a/common/modules/event/widgets/day/views/_day.php b/common/modules/event/widgets/day/views/_day.php new file mode 100644 index 0000000..e7ca2b3 --- /dev/null +++ b/common/modules/event/widgets/day/views/_day.php @@ -0,0 +1,20 @@ + +

+ date->format('d') ?> +

+ +events) === 0) { + echo EventView::widget(['event' => null]); +} else { + /** @var Event $event */ + foreach ($day->events as $event) { + echo EventView::widget(['event' => $event]); + } +} ?> diff --git a/common/modules/event/widgets/event/EventView.php b/common/modules/event/widgets/event/EventView.php new file mode 100644 index 0000000..740abd1 --- /dev/null +++ b/common/modules/event/widgets/event/EventView.php @@ -0,0 +1,45 @@ +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 + ] + ); + } + + + +} diff --git a/common/modules/event/widgets/event/views/_event.php b/common/modules/event/widgets/event/views/_event.php new file mode 100644 index 0000000..cd31ea0 --- /dev/null +++ b/common/modules/event/widgets/event/views/_event.php @@ -0,0 +1,33 @@ + +
Nincs esemény
+ +
+ format('H:i') .'-' . $end->format('H:i') , Url::toRoute(['event/update', 'id' => $event->id ] ) ) ?> +
+ eventType->name , Url::toRoute(['/event-type/view', 'id'=> $event->eventType->id])) ?> +
+ room->name , Url::toRoute(['/room/view', 'id' => $event->room->id]) )?> +
+ trainer->name , Url::toRoute(['/trainer/view', 'id' => $event->trainer->id]) )?> +
+ eventRegistrationCount ?> + / + seat_count ?> +
+ + 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)]); + }; + + } + +} diff --git a/common/modules/event/widgets/timetable/views/_timetable.php b/common/modules/event/widgets/timetable/views/_timetable.php new file mode 100644 index 0000000..c251634 --- /dev/null +++ b/common/modules/event/widgets/timetable/views/_timetable.php @@ -0,0 +1,79 @@ + + + $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}', + ], + ], +]) ?> diff --git a/customer/app/src/app/_helpers/error.interceptor.ts b/customer/app/src/app/_helpers/error.interceptor.ts index 1660dfe..6c4c25a 100644 --- a/customer/app/src/app/_helpers/error.interceptor.ts +++ b/customer/app/src/app/_helpers/error.interceptor.ts @@ -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, next: HttpHandler): Observable>{ 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; diff --git a/customer/app/src/app/_helpers/fake-backend.ts b/customer/app/src/app/_helpers/fake-backend.ts index cc8954c..a7ff8f4 100644 --- a/customer/app/src/app/_helpers/fake-backend.ts +++ b/customer/app/src/app/_helpers/fake-backend.ts @@ -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 } ) } diff --git a/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.ts b/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.ts index e679eb1..fefa463 100644 --- a/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.ts +++ b/customer/app/src/app/components/month-calendar-event/month-calendar-event.component.ts @@ -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() { diff --git a/customer/app/src/app/components/month-calendar/month-calendar.component.html b/customer/app/src/app/components/month-calendar/month-calendar.component.html index 9092f69..54580f2 100644 --- a/customer/app/src/app/components/month-calendar/month-calendar.component.html +++ b/customer/app/src/app/components/month-calendar/month-calendar.component.html @@ -6,7 +6,7 @@
- +
diff --git a/customer/app/src/app/components/month-calendar/month-calendar.component.ts b/customer/app/src/app/components/month-calendar/month-calendar.component.ts index c795fa9..0bc8b03 100644 --- a/customer/app/src/app/components/month-calendar/month-calendar.component.ts +++ b/customer/app/src/app/components/month-calendar/month-calendar.component.ts @@ -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 = new EventEmitter(); - 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 diff --git a/customer/app/src/app/pages/home/home.component.ts b/customer/app/src/app/pages/home/home.component.ts index 138f15a..b5d873f 100644 --- a/customer/app/src/app/pages/home/home.component.ts +++ b/customer/app/src/app/pages/home/home.component.ts @@ -25,6 +25,5 @@ export class HomeComponent implements OnInit { handleEvent($event: MonthCalendarEvent) { console.info($event); this.navigationService.navigateToEventDetails($event.event.id); - } } diff --git a/customer/app/src/app/services/endpoints.ts b/customer/app/src/app/services/endpoints.ts index c3dbe10..3376a2e 100644 --- a/customer/app/src/app/services/endpoints.ts +++ b/customer/app/src/app/services/endpoints.ts @@ -31,7 +31,7 @@ export class Endpoints { public static GET_EVENTS_AVAILABLE(){ - return `${this.baseUrl}/events/available`; + return `${this.baseUrl}/event/available`; } } diff --git a/customer/app/src/app/services/event.service.ts b/customer/app/src/app/services/event.service.ts index a2b7a36..87c9c07 100644 --- a/customer/app/src/app/services/event.service.ts +++ b/customer/app/src/app/services/event.service.ts @@ -73,7 +73,7 @@ export interface DayToDisplay { } export interface EventsAvailableResponse { - days: DayToDisplay[]; + dates: DayToDisplay[]; events: Event[]; } diff --git a/customer/app/src/app/services/navigation.service.ts b/customer/app/src/app/services/navigation.service.ts index 68c309a..3814cb6 100644 --- a/customer/app/src/app/services/navigation.service.ts +++ b/customer/app/src/app/services/navigation.service.ts @@ -20,5 +20,9 @@ export class NavigationService { this.navigate(['/home' ]) } + public navigateToLogin(){ + this.navigate(['/login' ]) + } + } diff --git a/customerapi/controllers/EventController.php b/customerapi/controllers/EventController.php index fc5b7db..22e2b8f 100644 --- a/customerapi/controllers/EventController.php +++ b/customerapi/controllers/EventController.php @@ -82,6 +82,7 @@ class EventController extends CustomerApiController } } + return $this->asJson([ 'interval' => $interval, diff --git a/customerapi/models/available/EventInterval.php b/customerapi/models/available/EventInterval.php index 2c100c2..accb781 100644 --- a/customerapi/models/available/EventInterval.php +++ b/customerapi/models/available/EventInterval.php @@ -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; + } + + + }