From de47ccec7715a1434a2ae28d2d8d597bd359e15c Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 9 Sep 2021 17:00:27 +0300 Subject: [PATCH 1/7] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reports/controllers/AjaxController.php | 26 +- .../reports/controllers/ReportsController.php | 47 ++- .../reports/views/reports/calendar.php | 33 ++ .../modules/reports/views/reports/index.php | 17 +- .../views/reports/non-exist_user_id.php | 10 + .../modules/reports/views/reports/user.php | 374 ------------------ 6 files changed, 105 insertions(+), 402 deletions(-) create mode 100644 backend/modules/reports/views/reports/calendar.php create mode 100644 backend/modules/reports/views/reports/non-exist_user_id.php delete mode 100644 backend/modules/reports/views/reports/user.php diff --git a/backend/modules/reports/controllers/AjaxController.php b/backend/modules/reports/controllers/AjaxController.php index 3971529..16de037 100644 --- a/backend/modules/reports/controllers/AjaxController.php +++ b/backend/modules/reports/controllers/AjaxController.php @@ -3,10 +3,9 @@ namespace backend\modules\reports\controllers; use backend\modules\reports\models\Month; -use common\classes\Debug; use Yii; use backend\modules\reports\models\ReportsSearch; -use yii\web\JsonResponseFormatter; +use yii\helpers\ArrayHelper; use yii\web\Response; class AjaxController extends \yii\web\Controller @@ -15,12 +14,23 @@ class AjaxController extends \yii\web\Controller public function actionGetReportsForMonthByIdYearMonth($user_id, $year, $month){ $searchModel = new ReportsSearch(); $dataProvider = $searchModel->search(Yii::$app->request->queryParams); - - $reports = $dataProvider->getModels(); - $reports_array = array_column($reports, 'attributes'); - foreach ($reports as $i => $report){ - $reports_array[$i]['today'] = array_column($report->task, 'attributes'); - } + $reports_array = ArrayHelper::toArray($dataProvider->getModels(), [ + 'common\models\Reports' => [ + 'id', + 'created_at', + 'difficulties', + 'tomorrow', + 'user_card_id', + 'today' => function ($report) { + return ArrayHelper::toArray($report->task, [ + 'common\models\ReportsTask' => [ + 'hours_spent', + 'task' + ], + ]); + } + ], + ]); $response = Yii::$app->response; $response->format = Response::FORMAT_JSON; diff --git a/backend/modules/reports/controllers/ReportsController.php b/backend/modules/reports/controllers/ReportsController.php index 5f11f35..3a0e29a 100644 --- a/backend/modules/reports/controllers/ReportsController.php +++ b/backend/modules/reports/controllers/ReportsController.php @@ -7,8 +7,8 @@ use Yii; use common\models\Reports; use backend\modules\reports\models\ReportsSearch; use yii\filters\AccessControl; +use yii\helpers\ArrayHelper; use yii\web\Controller; -use yii\web\JsonResponseFormatter; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -48,9 +48,14 @@ class ReportsController extends Controller public function actionIndex() { $searchModel = new ReportsSearch(); - $user_id__fio = []; - foreach ($searchModel->search([])->getModels() as $model) - $user_id__fio[$model->user_card_id] = \common\models\Reports::getFio($model); + $user_id__fio = ArrayHelper::map(ArrayHelper::toArray($searchModel->search([])->getModels(), [ + 'common\models\Reports' => [ + 'user_card_id', + 'fio' => function ($report) { + return Reports::getFio($report); + } + ], + ]),'user_card_id', 'fio'); $dataProvider = $searchModel->search(Yii::$app->request->queryParams); return $this->render('index', [ @@ -61,14 +66,38 @@ class ReportsController extends Controller } - public function actionUser($user_id) + public function actionCalendar($user_id) { $searchModel = new ReportsSearch(); - $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + $searchModel->user_card_id = $user_id; + $dataProvider = $searchModel->search([]); - return $this->render('user', [ - 'searchModel' => $searchModel, - 'dataProvider' => $dataProvider, + + $reports_array = ArrayHelper::toArray($dataProvider->getModels(), [ + 'common\models\Reports' => [ + 'id', + 'created_at', + 'difficulties', + 'tomorrow', + 'user_card_id', + 'today' => function ($report) { + return ArrayHelper::toArray($report->task, [ + 'common\models\ReportsTask' => [ + 'hours_spent', + 'task' + ], + ]); + } + ], + ]); + + if (!$dataProvider->getCount()){ + return $this->render('non-exist_user_id', ['id' => $user_id]); + } + return $this->render('calendar', [ + 'reports' => $reports_array, + 'fio' => Reports::getFio($searchModel), + 'USER_ID' => $user_id ]); } diff --git a/backend/modules/reports/views/reports/calendar.php b/backend/modules/reports/views/reports/calendar.php new file mode 100644 index 0000000..1521155 --- /dev/null +++ b/backend/modules/reports/views/reports/calendar.php @@ -0,0 +1,33 @@ +registerJs('let userID = '. $USER_ID); +$this->registerJs(file_get_contents(Url::base(true).'/js/calendar.js')); +$this->registerCssFile('@web/css/calendar.css'); +$this->title = 'Календарь пользователя - ' . $fio; +?> + 'calendar-contain'])?> + 'calendar__sidebar'])?> + 'title-bar'])?> + Назад', Yii::$app->request->referrer, ['class' => 'btn btn-primary',]) ?> + 'form-control', 'id' => 'date',]) ?> + + + '.date('F d'), ['class' => 'sidebar__heading'])?> + + 'sidebar__list'])?> + + + + 'calendar__days'])?> + + + + + diff --git a/backend/modules/reports/views/reports/index.php b/backend/modules/reports/views/reports/index.php index 68156b5..c236c06 100644 --- a/backend/modules/reports/views/reports/index.php +++ b/backend/modules/reports/views/reports/index.php @@ -5,6 +5,7 @@ use common\models\Reports; use yii\helpers\Html; use yii\grid\GridView; use yii\widgets\ActiveForm; +use yii\widgets\Pjax; /* @var $this yii\web\View */ @@ -14,15 +15,7 @@ use yii\widgets\ActiveForm; $this->title = 'Отчеты'; $this->params['breadcrumbs'][] = $this->title; -$this->registerCss(' -.date_sort { -display: inline-flex; -} -.row * { - margin-right: 10px; -} -'); - +$this->registerCss('.row * {margin-right: 10px;}'); define('TODAY', date('Y-m-d')); define('WEEK_AGO', date('Y-m-d', time() - 3600 * 24 * 7)); function next_day($date, $number) @@ -50,7 +43,7 @@ function next_day($date, $number) 'row'])?> 'col-xs-6'])?> - 'get', 'options' => ['class' => 'date_sort'] ])?> + 'get', 'options' => ['style' => 'display: inline-flex;'] ])?> attributes )as $attribute): ?> @@ -77,6 +70,7 @@ function next_day($date, $number) + $dataProvider, 'filterModel' => $searchModel, @@ -122,7 +116,7 @@ function next_day($date, $number) ]), 'value' => function ($model) { return Html::a(Reports::getFio($model).' '.Html::tag('i', null, ['class' => 'far fa-calendar-alt']), - ['user', 'user_id' => $model['user_card_id']]); + ['calendar', 'user_id' => $model['user_card_id']]); }, ], @@ -130,3 +124,4 @@ function next_day($date, $number) ['class' => 'yii\grid\ActionColumn'], ], ]);?> + diff --git a/backend/modules/reports/views/reports/non-exist_user_id.php b/backend/modules/reports/views/reports/non-exist_user_id.php new file mode 100644 index 0000000..4fa136a --- /dev/null +++ b/backend/modules/reports/views/reports/non-exist_user_id.php @@ -0,0 +1,10 @@ +title = 'Ошибка. Не удалось найти пользователя с таким ID - '.$id; +if (!Yii::$app->request->referrer){ + echo \yii\helpers\Html::a(' Репорты', ['index'], ['class' => 'btn btn-primary',]); +} else{ + echo \yii\helpers\Html::a(' Назад', Yii::$app->request->referrer, ['class' => 'btn btn-primary',]); +} diff --git a/backend/modules/reports/views/reports/user.php b/backend/modules/reports/views/reports/user.php deleted file mode 100644 index f6b0eaf..0000000 --- a/backend/modules/reports/views/reports/user.php +++ /dev/null @@ -1,374 +0,0 @@ -getModels(); -$USER_ID = $searchModel->user_card_id; - -$reports_array = array_column($reports, 'attributes'); -foreach ($reports as $i => $report){ - $reports_array[$i]['today'] = array_column($report->task, 'attributes'); -} -$reports_month = json_encode(array_merge( - ['reports' => $reports_array], - ['month' => (array)new Month()]) -); - -$this->registerCssFile('@web/css/calendar.css'); -$this->title = 'Календарь пользователя - ' . Reports::getFio($searchModel); -?> - - 'calendar-contain'])?> - 'calendar__sidebar'])?> - 'title-bar'])?> - Назад', Yii::$app->request->referrer, ['class' => 'btn btn-primary',]) ?> - 'form-control', 'id' => 'date',]) ?> - - - '.date('F d'), ['class' => 'sidebar__heading'])?> - - 'sidebar__list'])?> - - - - 'calendar__days'])?> - - - - - - - - From 125bddde2184699d6b3f79ed24387a9667d940cd Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 10 Sep 2021 17:39:40 +0300 Subject: [PATCH 2/7] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=B2=D0=B8=D0=B4=D0=B6=D0=B5=D1=82=20=D1=81=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=BE=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=D0=BC=204=20=D0=B3=D0=BB=D0=B0=D0=B2=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B9=20?= =?UTF-8?q?=D0=BA=D0=B0=D0=BB=D0=B5=D0=BD=D0=B4=D0=B0=D1=80=D1=8F=20=D0=B2?= =?UTF-8?q?=20js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calendar/controllers/AjaxController.php | 32 ++ .../controllers/CalendarController.php | 9 +- .../calendar/views/calendar/alternative.php | 80 ++++ .../modules/calendar/views/calendar/index.php | 7 +- .../modules/card/models/UserCardSearch.php | 5 +- backend/web/css/calendar.css | 5 +- backend/widgets/AppAsset.php | 17 + backend/widgets/Calendar.php | 203 ++++++++++ backend/widgets/Calendar/assets/css/style.css | 383 ++++++++++++++++++ backend/widgets/Calendar/assets/js/script.js | 0 .../Calendar/assets/js/src/CalendarHelper.js | 186 +++++++++ .../Calendar/assets/js/src/DateHelper.js | 87 ++++ 12 files changed, 1009 insertions(+), 5 deletions(-) create mode 100644 backend/modules/calendar/controllers/AjaxController.php create mode 100644 backend/modules/calendar/views/calendar/alternative.php create mode 100644 backend/widgets/AppAsset.php create mode 100644 backend/widgets/Calendar.php create mode 100644 backend/widgets/Calendar/assets/css/style.css create mode 100644 backend/widgets/Calendar/assets/js/script.js create mode 100644 backend/widgets/Calendar/assets/js/src/CalendarHelper.js create mode 100644 backend/widgets/Calendar/assets/js/src/DateHelper.js diff --git a/backend/modules/calendar/controllers/AjaxController.php b/backend/modules/calendar/controllers/AjaxController.php new file mode 100644 index 0000000..85530c3 --- /dev/null +++ b/backend/modules/calendar/controllers/AjaxController.php @@ -0,0 +1,32 @@ +search(Yii::$app->request->queryParams)->getModels(); + $models_array = ArrayHelper::toArray($models, [ + 'backend\modules\card\models\UserCard' => [ + 'id', + 'dob', + 'fio' + ], + ]); + + $response = Yii::$app->response; + $response->format = Response::FORMAT_JSON; + $response->getHeaders()->set('Content-Type', 'application/json; charset=utf-8'); + $response->content = json_encode( + $models_array + ); + return $response; + } +}?> diff --git a/backend/modules/calendar/controllers/CalendarController.php b/backend/modules/calendar/controllers/CalendarController.php index 86ae7e3..c6760bd 100644 --- a/backend/modules/calendar/controllers/CalendarController.php +++ b/backend/modules/calendar/controllers/CalendarController.php @@ -3,7 +3,6 @@ namespace backend\modules\calendar\controllers; use backend\modules\card\models\UserCardSearch; -use common\classes\Debug; use Yii; use yii\data\ArrayDataProvider; use yii\filters\AccessControl; @@ -43,6 +42,14 @@ class CalendarController extends Controller * Renders the index view for the module * @return string */ + public function actionAlternative(){ + $searchModel = new UserCardSearch(); + $dataProvider = $searchModel->search(['month'=>date('m', strtotime('2019-07-03'))]); + return $this->render('alternative', [ + 'dataProvider' => $dataProvider + ]); + } + public function actionIndex() { $searchModel = new UserCardSearch(); diff --git a/backend/modules/calendar/views/calendar/alternative.php b/backend/modules/calendar/views/calendar/alternative.php new file mode 100644 index 0000000..4b20d21 --- /dev/null +++ b/backend/modules/calendar/views/calendar/alternative.php @@ -0,0 +1,80 @@ +title = 'Календарь ДР'; +?> + Html::a(' Назад', + Yii::$app->request->referrer, ['class' => 'btn btn-primary',]), + 'runBuild' => "function (date, content){ + this.build(date, content) + }", + 'updateContent' => "function(date){ + let monthNumber = date.substr(5, 2); + return fetch('../ajax/get-birthday-by-month?' + + 'month=' + monthNumber) + .then((res) => { + return res.json() + }) + }", + 'getColor' => "function (date, dates = null) { + for (let contentDate of dates) { + if (contentDate['dob'].substr(8, 2) == DateHelper.intToDate(date.getDate())) { + return 'success'; + } + } + }", + 'getHtmlContentForDate' => 'function (content, date) { + let flag = false + let html = ` + + + + + + + + `; + for (let i = 1; i <= content.length; i++) { + let model = content[i - 1]; + if (model["dob"].substr(8, 2) == date.substr(8, 2)) { + flag = true; + html += `` + html += `` + html += `` + html += `` + html += `` + html += `` + } + } + html += `
#ФИОДата рождения 
${i}${model["fio"]}${model["dob"]} + + + + + + +
` + if (flag) return html; + return "empty" + }' +]) ?> + + diff --git a/backend/modules/calendar/views/calendar/index.php b/backend/modules/calendar/views/calendar/index.php index 148d8a5..18a1223 100644 --- a/backend/modules/calendar/views/calendar/index.php +++ b/backend/modules/calendar/views/calendar/index.php @@ -4,9 +4,10 @@ /* @var $dataProvider yii\data\ActiveDataProvider */ use yii\grid\GridView; +use yii\helpers\Html; use yii\widgets\Pjax; ?> - +

- + 'far fa-calendar-alt']), + ['alternative'], ['class' => 'btn btn-success', 'style' => 'margin-left: 10px'])?> +
'reload']); echo GridView::widget([ diff --git a/backend/modules/card/models/UserCardSearch.php b/backend/modules/card/models/UserCardSearch.php index cb6676b..4fd7e0a 100755 --- a/backend/modules/card/models/UserCardSearch.php +++ b/backend/modules/card/models/UserCardSearch.php @@ -6,7 +6,6 @@ use common\classes\Debug; use Yii; use yii\base\Model; use yii\data\ActiveDataProvider; -use backend\modules\card\models\UserCard; /** * UserCardSearch represents the model behind the search form of `backend\modules\card\models\UserCard`. @@ -64,6 +63,10 @@ class UserCardSearch extends UserCard $query->where(['deleted_at' => null]); + if (isset($params['month'])) { + $query->andFilterWhere(['=', 'MONTH(dob)', $params['month']]); + } + // grid filtering conditions $query->andFilterWhere([ 'id' => $this->id, diff --git a/backend/web/css/calendar.css b/backend/web/css/calendar.css index e5f844d..6d9188b 100644 --- a/backend/web/css/calendar.css +++ b/backend/web/css/calendar.css @@ -291,6 +291,9 @@ text-align: center; display: flex; flex: 56px 0 0; + max-height: 44px; + box-shadow: 0px 5px 5px -5px rgba(34, 60, 80, 0.6); + align-items: center } .top-bar__days { @@ -299,7 +302,7 @@ color: #2d4338; font-weight: 100; -webkit-font-smoothing: subpixel-antialiased; - font-size: 1rem; + font-size: 18px; } .calendar__week { diff --git a/backend/widgets/AppAsset.php b/backend/widgets/AppAsset.php new file mode 100644 index 0000000..0bcc5f8 --- /dev/null +++ b/backend/widgets/AppAsset.php @@ -0,0 +1,17 @@ + { + return res.json() + }) + }"; + public $getColor = "function (date, dates = null) { + for (let contentDate of dates) { + if (contentDate['dob'].substr(8, 2) == DateHelper.intToDate(date.getDate())) { + return 'success'; + } + } + }"; + public $getHtmlContentForDate = 'function (content, date) { + console.log(content) + let flag = false + let html = ` + + + + + + + + `; + for (let i = 1; i <= content.length; i++) { + let model = content[i - 1]; + if (model["dob"].substr(8, 2) == date.substr(8, 2)) { + flag = true; + html += `` + html += `` + html += `` + html += `` + html += `` + html += `` + } + } + html += `
#ФИОДата рождения 
${i}${model["fio"]}${model["dob"]} + + + + + + +
` + if (flag) return html; + return "empty" + }'; + + /* + + CalendarHelper._updateContent = async function(){ + let monthNumber = date.substr(5, 2); + return fetch('../ajax/get-birthday-by-month?' + + 'month=' + monthNumber) + .then((res) => { + return res.json() + }) + } + + CalendarHelper._getColor = function (date, dates = null) { + for (let contentDate of dates) { + if (contentDate['dob'].substr(8, 2) == DateHelper.intToDate(date.getDate())) { + return 'success'; + } + } + } + + CalendarHelper._getHtmlContentForDate = function (content, date) { + console.log(content) + let flag = false + + let html = ` + + + + + + + `; + for (let i = 1; i <= content.length; i++) { + + let model = content[i - 1]; + if (model['dob'].substr(8, 2) == date.substr(8, 2)) { + flag = true; + html += `` + html += `` + html += `` + html += `` + html += `` + html += `` + } + } + html += `
#ФИО + Дата рождения 
${i}${model['fio']}${model['dob']} + + + + + + +
` + if (flag) return html; + return "empty" + } + */ + + public function init() + { + parent::init(); + $view = $this->getView(); + AppAsset::register($view); + } + + public function run() + { + + echo Html::beginTag('section', ['class' => 'calendar-contain']); + echo Html::beginTag('aside', ['class' => 'calendar__sidebar']); + echo Html::beginTag('section', ['class' => 'title-bar']); + echo $this->button; + echo Html::input('date', null, date('Y-m-d'), ['class' => 'form-control', 'id' => 'date',]); + echo Html::endTag('section'); + echo Html::tag('h2', date('l') . '
' . date('F d'), ['class' => 'sidebar__heading']); + echo Html::beginTag('ul', ['class' => 'sidebar__list']); + echo Html::endTag('ul'); + echo Html::endTag('aside'); + echo Html::beginTag('section', ['class' => 'calendar__days']); + echo Html::endTag('section'); + echo Html::endTag('section'); + + $this->view->registerJs(' + CalendarHelper._runBuild = ' . $this->runBuild . '; + CalendarHelper._getHtmlContentForDate = ' . $this->getHtmlContentForDate . '; + CalendarHelper._updateContent = async ' . $this->updateContent . '; + CalendarHelper._getColor = ' . $this->getColor . '; + + CalendarHelper.main()' + ); + } + +} + + +?> + + diff --git a/backend/widgets/Calendar/assets/css/style.css b/backend/widgets/Calendar/assets/css/style.css new file mode 100644 index 0000000..6d9188b --- /dev/null +++ b/backend/widgets/Calendar/assets/css/style.css @@ -0,0 +1,383 @@ +.calendar-contain { + position: relative; + left: 0; + right: 0; + border-radius: 0; + width: 100%; + overflow: hidden; + max-width: 1920px; + min-width: 450px; + margin: 1rem auto; + background-color: #f5f7f6; + box-shadow: 5px 5px 72px rgba(30, 46, 50, 0.5); + color: #040605; +} + +@media screen and (min-width: 55em) { + .calendar-contain { + margin: auto; + top: 5%; + } +} + +.title-bar { + position: relative; + width: 100%; + display: flex; + text-align: right; + background: #f5f7f6; + padding: 0.5rem; + margin-bottom: 0; +} + +.title-bar:after { + display: table; + clear: both; +} + +.title-bar__burger { + display: block; + position: relative; + float: left; + overflow: hidden; + margin: 0; + padding: 0; + width: 38px; + height: 30px; + font-size: 0; + text-indent: -9999px; + appearance: none; + box-shadow: none; + border: none; + cursor: pointer; + background: none; +} + +.title-bar__burger:focus { + outline: none; +} + +.burger__lines { + display: block; + position: absolute; + width: 18px; + top: 15px; + left: 0; + right: 0; + margin: auto; + height: 1px; + background: #040605; +} + +.burger__lines:before, .burger__lines:after { + position: absolute; + display: block; + left: 0; + width: 100%; + height: 1px; + background-color: #040605; + content: ""; +} + +.burger__lines:before { + top: -5px; +} + +.burger__lines:after { + bottom: -5px; +} + +.title-bar__year { + display: block; + position: relative; + float: left; + font-size: 1rem; + line-height: 30px; + width: 43%; + padding: 0 0.5rem; + text-align: left; +} + +@media screen and (min-width: 55em) { + .title-bar__year { + width: 27%; + } +} + +.title-bar__month { + position: relative; + /*float: center;*/ + font-size: 1rem; + line-height: 30px; + width: 22%; + padding: 0 0.5rem; + text-align: center; + margin-right: 67px; + word-spacing: 30px; +} + +@media screen and (min-width: 55em) { + .title-bar__month { + width: 12%; + } +} + +.title-bar__minimize, .title-bar__maximize, .title-bar__close { + position: relative; + float: left; + width: 34px; + height: 34px; +} + +.title-bar__minimize:before, .title-bar__maximize:before, .title-bar__close:before, .title-bar__minimize:after, .title-bar__maximize:after, .title-bar__close:after { + top: 30%; + right: 30%; + bottom: 30%; + left: 30%; + content: " "; + position: absolute; + border-color: #8e8e8e; + border-style: solid; + border-width: 0 0 2px 0; +} + +.title-bar .title-bar__controls { + display: inline-block; + vertical-align: top; + position: relative; + float: right; + width: auto; +} + +.title-bar .title-bar__controls:before, .title-bar .title-bar__controls:after { + content: none; +} + +.title-bar .title-bar__minimize:before { + border-bottom-width: 2px; +} + +.title-bar .title-bar__maximize:before { + border-width: 1px 1px 2px 1px; +} + +.title-bar .title-bar__close:before, .title-bar .title-bar__close:after { + bottom: 50%; + top: 49.9%; +} + +.title-bar .title-bar__close:before { + transform: rotate(45deg); +} + +.title-bar .title-bar__close:after { + transform: rotate(-45deg); +} + +.calendar__sidebar { + width: 100%; + margin: 0 auto; + float: none; + background: linear-gradient(120deg, #eff3f3, #e1e7e8); + padding-bottom: 0.7rem; +} + +@media screen and (min-width: 55em) { + .calendar__sidebar { + position: absolute; + height: 100%; + width: 50%; + float: left; + margin-bottom: 0; + } +} + +.calendar__sidebar .content { + padding: 2rem 1.5rem 2rem 4rem; + color: #040605; +} + +.sidebar__nav { + display: flex; + align-items: center; + justify-content: flex-start; + margin-bottom: 0.9rem; + padding: 0.7rem 1rem; + background-color: #f5f7f6; +} + +.sidebar__nav-item { + display: inline-block; + width: 22px; + margin-right: 23px; + padding: 0; + opacity: 0.8; +} + +.sidebar__list { + list-style: none; + margin: 0; + padding-left: 1rem; + padding-right: 1rem; +} + +.sidebar__list-item { + margin: 1.2rem 0; + color: #2d4338; + font-weight: 100; + font-size: 1rem; +} + +.list-item__time { + display: inline-block; + width: 60px; +} + +@media screen and (min-width: 55em) { + .list-item__time { + margin-right: 2rem; + } +} + +.sidebar__list-item--complete { + color: rgba(4, 6, 5, 0.3); +} + +.sidebar__list-item--complete .list-item__time { + color: rgba(4, 6, 5, 0.3); +} + +.sidebar__heading { + font-size: 2.2rem; + font-weight: bold; + padding-left: 1rem; + padding-right: 1rem; + margin-bottom: 3rem; + margin-top: 1rem; +} + +.sidebar__heading span { + float: right; + font-weight: 300; +} + +.calendar__heading-highlight { + color: #2d444a; + font-weight: 900; +} + +.calendar__days { + display: flex; + flex-flow: column wrap; + align-items: stretch; + width: 100%; + float: none; + min-height: 580px; + height: 100%; + font-size: 12px; + /*padding: 0.8rem 0 1rem 1rem;*/ + background: #f5f7f6; +} + +@media screen and (min-width: 55em) { + .calendar__days { + width: 50%; + float: right; + } +} + +.calendar__top-bar { + background: #b8cad6; + text-align: center; + display: flex; + flex: 56px 0 0; + max-height: 44px; + box-shadow: 0px 5px 5px -5px rgba(34, 60, 80, 0.6); + align-items: center +} + +.top-bar__days { + width: 100%; + padding: 0 5px; + color: #2d4338; + font-weight: 100; + -webkit-font-smoothing: subpixel-antialiased; + font-size: 18px; +} + +.calendar__week { + display: flex; + flex: 1 1 0; +} + +.calendar__day { + text-align: center; + display: flex; + flex-flow: column wrap; + + width: 100%; + justify-content: space-around; + /*padding: 1.9rem 0.2rem 0.2rem;*/ +} + + +.calendar__date { + /*margin: 25px;*/ + color: #040605; + font-size: 1.7rem; + font-weight: 600; + line-height: 0.7; +} + +@media screen and (min-width: 55em) { + .calendar__date { + font-size: 2.3rem; + } +} + +.calendar__week .inactive .calendar__date, .calendar__week .inactive .task-count { + color: #c6c6c6; +} + +.calendar__week .today .calendar__date { + color: #fd588a; +} + +.calendar__task { + color: #040605; + display: flex; + font-size: 0.8rem; +} + +@media screen and (min-width: 55em) { + .calendar__task { + font-size: 1rem; + } +} + +.calendar__task.calendar__task--today { + color: #fd588a; +} + + +.danger { + color: red; +} + +.success { + color: green; +} + +.calendar__day:hover { + color: #0a0a0a; + background: #c2c2c2; + cursor: pointer; +} +.calendar__day:active { + background: #727272; + cursor: pointer; +} + +.active_day { + background: #cdcfce; +} \ No newline at end of file diff --git a/backend/widgets/Calendar/assets/js/script.js b/backend/widgets/Calendar/assets/js/script.js new file mode 100644 index 0000000..e69de29 diff --git a/backend/widgets/Calendar/assets/js/src/CalendarHelper.js b/backend/widgets/Calendar/assets/js/src/CalendarHelper.js new file mode 100644 index 0000000..aa8dbc7 --- /dev/null +++ b/backend/widgets/Calendar/assets/js/src/CalendarHelper.js @@ -0,0 +1,186 @@ +class CalendarHelper { + + static build(date, dates = null) { + const _daysNames = `
+ Mon + Tue + Wed + Thu + Fri + Sat + Sun +
`; + + + let month = DateHelper.getMonth(date) + + let html = `
`, index = 1, indexRaw = 0; + + for (let i = 0, dayNum = month[i]; i < month.length; i++, dayNum = month[i]) { + let className = `` + if (this._isInactive(dayNum, i)) { + className = 'inactive' + } + let color = this._getColor(new Date(date.getFullYear(), date.getMonth(), dayNum), dates) + html += this._getCalendarDay(dayNum, className, color) + if ((i + 1) % 7 == 0) { + + html += `
` + + + } + + } + html = removeExcessTagSection(html) + + document.querySelector('.calendar__days').innerHTML = _daysNames + html + + + function removeExcessTagSection(html) { + return html.substr(0, html.length - 9) + } + } + + static main(day = null) { + let datePicker = document.querySelector('#date'); + let oldDate = datePicker.value.substr(0, 7); + + let nameDateBoard = document.querySelector('.sidebar__heading'); + let contentBoard = document.querySelector('.sidebar__list'); + + this._updateContent(datePicker.value) + .then(content => { + + this._runBuild(DateHelper.stringToDate(datePicker.value), content) + + datePicker.onchange = function (day = null) { + let days = document.querySelectorAll('.calendar__day ') + + for (let i = 0; i < days.length; i++) { + if (days[i].classList.contains('active_day')) + days[i].classList.remove('active_day') + } + + if (!CalendarHelper.isOldDatePicker(datePicker, oldDate)) { + oldDate = datePicker.value.substr(0, 7); + + CalendarHelper._updateContent(datePicker.value) + .then(content => { + + CalendarHelper.main(day) + let date = new Date(datePicker.value); + let monthName = date.toLocaleString('default', {month: 'long'}); + let dayWeekName = date.toLocaleString('default', {weekday: 'long'}); + nameDateBoard.innerHTML = `${dayWeekName}
${monthName} ${datePicker.value.substr(8, 2)}`; + contentBoard.innerHTML = CalendarHelper._getHtmlContentForDate(content, datePicker.value) + }) + + } + let date = new Date(datePicker.value); + let monthName = date.toLocaleString('default', {month: 'long'}); + let dayWeekName = date.toLocaleString('default', {weekday: 'long'}); + nameDateBoard.innerHTML = `${dayWeekName}
${monthName} ${datePicker.value.substr(8, 2)}`; + contentBoard.innerHTML = CalendarHelper._getHtmlContentForDate(content, datePicker.value) + } + + let days = document.querySelectorAll('.calendar__day'); + + for (let i = 0; i < Object.keys(days).length; i++) { + let dateDay = parseInt(days[i].textContent); + if (day) { + if (parseInt(day.textContent) == dateDay && !days[i].classList.contains('inactive')) { + days[i].classList.add('active_day') + } + } + + if (days[i].classList.contains('inactive')) { + days[i].onclick = function () { + let date = CalendarHelper._getFutureDate(datePicker.value, parseInt(days[i].textContent)) + datePicker.value = date; + datePicker.onchange(this) + } + } else { + days[i].onclick = function () { + datePicker.value = datePicker.value.substr(0, 8) + DateHelper.intToDate(dateDay); + datePicker.onchange(this) + days[i].classList.add('active_day') + } + } + } + + + }) + } + + static _getHtmlContentForDate(content, date) { + /* making html content; Example: return "In this day Birthday of " +content['date']['user']; */ + } + + + static _runBuild(date, content) { + /*making something for dates from content = [date1, date2, ...]*/ + + this.build(date, content) + } + + static + async _updateContent(date) { + let monthNumber = date.substr(5, 2); + return fetch('../ajax/get-birthday-by-month?' + + 'month=' + monthNumber) + .then((res) => { + return res.json() + }) + + } + + static isOldDatePicker(datePicker, oldDate) { + if (datePicker.value.substr(0, 7) == oldDate) + return true; + return false + } + + static _isInactive(numDay, i) { + if (i < 8 && numDay !== i + 1) { + return (numDay > i) + } else { + return (i - 8) > numDay + } + } + + static _getCalendarDay(dayNum, className = ``, color = ``) { + return `
+ ${dayNum} +
`; + } + + static _getColor(date, dates = null) { + if (dates != null && dates.includes(DateHelper.dateToString(date))) { + return 'success'; + } + if ([6, 0].includes(date.getDay())) + return; + + return 'danger'; + } + + static _getFutureDate(dat, value) { + let date = new Date(dat); + if (value < 8) { + if (date.getMonth() == 11) { + date = new Date(date.getFullYear() + 1, 0, value); + } else { + date = new Date(date.getFullYear(), date.getMonth() + 1, value); + } + } else { + if (date.getMonth() == 0) { + date = new Date(date.getFullYear() - 1, 11, value); + } else { + date = new Date(date.getFullYear(), date.getMonth() - 1, value); + } + } + return date.getFullYear() + '-' + DateHelper.intToDate(date.getMonth() + 1) + '-' + DateHelper.intToDate(value); + + } + +} diff --git a/backend/widgets/Calendar/assets/js/src/DateHelper.js b/backend/widgets/Calendar/assets/js/src/DateHelper.js new file mode 100644 index 0000000..c2a524a --- /dev/null +++ b/backend/widgets/Calendar/assets/js/src/DateHelper.js @@ -0,0 +1,87 @@ +class DateHelper { + static getMonth(date) { + date = this.nextMonth(date) + date = this.prevDay(date) + let days = [], last = date, quantity = this.getQuantity(date) + for (let i = 0; i < (7 - last.getDay()) % 7; i++) { + days.push((7 - last.getDay()) % 7 - i) + } + for (let i = 0; i < last.getDate(); i++) { + days.push(last.getDate() - i) + } + date = this.prevMonth(date) + date = this.nextMonth(date) + date = this.prevDay(date) + for (let i = 0, lenDays = quantity - days.length; i < lenDays; i++) { + days.push(date.getDate() - i) + } + return days.reverse(); + } + + static getQuantity(date) { + if (this.isDayOff(date)) { + return 42 + } + if (this.prevDay(this.nextMonth(date)).getDate() == 28) { + return 28; + } + return 35 + + } + + static isDayOff(date) { + return [6, 0].includes(new Date(date.getFullYear(), date.getMonth(), 1).getDay()) + } + + static prevDay(date) { + return new Date(date.getTime() - 1000 * 3600 * 24) + } + + static nextMonth(date) { + if (this.isDecember(date)) { + return new Date(date.getFullYear() + 1, 0, 1) + } + return new Date(date.getFullYear(), date.getMonth() + 1, 1) + } + + static prevMonth(date) { + if (this.isJanuary(date)) { + return new Date(date.getFullYear() - 1, 11, 1) + } + return new Date(date.getFullYear(), date.getMonth() - 1, 1) + } + + static isDecember(date) { + return 11 == date.getMonth() + } + + static isJanuary(date) { + return 0 == date.getMonth() + } + + static intToDate(number_date) { + if (Math.floor(number_date / 10) === 0) + number_date = '0' + number_date; + return number_date + } + + static dateToString(date) { + let year = date.getFullYear() + let day = this.intToDate(date.getDate()) + let month = this.intToDate(this.isDecember(date) ? 0 : date.getMonth() + 1) + return year + '-' + month + '-' + day + } + + static stringToDate(date) { + let month = parseInt(date.substr(5, 2)) + return new Date(date.substr(0, 4), month, date.substr(7, 2)) + } + + static getDates(array) { + let dates = [] + for (let model of array) { + dates.push(model['date']) + } + return dates + } +} From bee3921de09786acd887acc9a6c8748da9cc8b60 Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 10 Sep 2021 18:21:23 +0300 Subject: [PATCH 3/7] =?UTF-8?q?=D0=9E=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=B0=D0=BB=D0=B5=D0=BD=D0=B4?= =?UTF-8?q?=D0=B0=D1=80=D1=8F=20=D1=81=20=D0=BF=D0=BE=D0=BC=D0=BE=D1=89?= =?UTF-8?q?=D1=8C=D1=8E=20=D0=B2=D0=B8=D0=B4=D0=B6=D0=B5=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reports/controllers/AjaxController.php | 5 +- .../reports/views/reports/calendar.php | 128 +++++++++++++++--- 2 files changed, 113 insertions(+), 20 deletions(-) diff --git a/backend/modules/reports/controllers/AjaxController.php b/backend/modules/reports/controllers/AjaxController.php index 16de037..7b81181 100644 --- a/backend/modules/reports/controllers/AjaxController.php +++ b/backend/modules/reports/controllers/AjaxController.php @@ -35,10 +35,7 @@ class AjaxController extends \yii\web\Controller $response = Yii::$app->response; $response->format = Response::FORMAT_JSON; $response->getHeaders()->set('Content-Type', 'application/json; charset=utf-8'); - $response->content = json_encode(array_merge( - ['reports' => $reports_array], - ['month' => (array)new Month($year.'-'.$month.'-01')]) - ); + $response->content = json_encode($reports_array); return $response; } diff --git a/backend/modules/reports/views/reports/calendar.php b/backend/modules/reports/views/reports/calendar.php index 1521155..54f624c 100644 --- a/backend/modules/reports/views/reports/calendar.php +++ b/backend/modules/reports/views/reports/calendar.php @@ -7,27 +7,123 @@ use yii\helpers\Url; /* @var $fio */ /* @var $USER_ID */ -$this->registerJs('let userID = '. $USER_ID); -$this->registerJs(file_get_contents(Url::base(true).'/js/calendar.js')); -$this->registerCssFile('@web/css/calendar.css'); $this->title = 'Календарь пользователя - ' . $fio; ?> - 'calendar-contain'])?> - 'calendar__sidebar'])?> - 'title-bar'])?> - Назад', Yii::$app->request->referrer, ['class' => 'btn btn-primary',]) ?> - 'form-control', 'id' => 'date',]) ?> - + Html::a(' Назад', + Yii::$app->request->referrer, ['class' => 'btn btn-primary',]), - '.date('F d'), ['class' => 'sidebar__heading'])?> + 'runBuild' => "function (date, content){ + contentDays = [] + for (let item of content){ + contentDays.push(item['created_at']) + } + this.build(date, contentDays) + }", + + 'updateContent' => "function(date){ + let monthNumber = date.substr(5, 2); + let yearNumber = date.substr(0, 4); + return fetch('../ajax/get-reports-for-month-by-id-year-month?user_id='+".$USER_ID."+ + '&month=' + monthNumber + + '&year=' + yearNumber) + .then((res) => { + return res.json() + }) + }", + + 'getColor' => "function (date, dates = null) { + let d = date; + if ([6, 0].includes(d.getDay())) + return; + for (let i = 0; i < dates.length; i++) { + if (dates[i] == DateHelper.dateToString(date)) { + return 'success'; + } + } + + return 'danger'; + }", + + 'getHtmlContentForDate' => "function (content, date) { + if ([0, 6].includes(new Date(date).getDay())) { + return 'Выходной день'; + } + let j = 0; + let html = `