From 02e207860f54544f4d9cd7c49eb858c2ec4683dd Mon Sep 17 00:00:00 2001 From: Regis Freyd <djaiss@users.noreply.github.com> Date: Thu, 24 Feb 2022 16:31:36 -0500 Subject: [PATCH] feat: indicate time for notification channel (monicahq/chandler#47) --- .../Notifications/NotificationsController.php | 3 + .../NotificationsIndexViewHelper.php | 1 + app/Jobs/SetupAccount.php | 1 + app/Models/UserNotificationChannel.php | 1 + .../CreateUserNotificationChannel.php | 5 +- .../UserNotificationChannelFactory.php | 1 + .../Notifications/Partials/Emails.vue | 120 +++++++++++++++++- resources/js/Shared/Modules/Reminders.vue | 3 +- .../NotificationsIndexViewHelperTest.php | 2 + .../CreateUserNotificationChannelTest.php | 1 + 10 files changed, 134 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Settings/Notifications/NotificationsController.php b/app/Http/Controllers/Settings/Notifications/NotificationsController.php index 554d3278bc5..260b1a85853 100644 --- a/app/Http/Controllers/Settings/Notifications/NotificationsController.php +++ b/app/Http/Controllers/Settings/Notifications/NotificationsController.php @@ -24,6 +24,8 @@ public function index() public function store(Request $request) { + $time = $request->input('hours').':'.$request->input('minutes'); + $data = [ 'account_id' => Auth::user()->account_id, 'author_id' => Auth::user()->id, @@ -31,6 +33,7 @@ public function store(Request $request) 'type' => UserNotificationChannel::TYPE_EMAIL, 'content' => $request->input('content'), 'verify_email' => true, + 'preferred_time' => $time, ]; $channel = (new CreateUserNotificationChannel)->execute($data); diff --git a/app/Http/Controllers/Settings/Notifications/ViewHelpers/NotificationsIndexViewHelper.php b/app/Http/Controllers/Settings/Notifications/ViewHelpers/NotificationsIndexViewHelper.php index 54f4be36731..112594ca0f6 100644 --- a/app/Http/Controllers/Settings/Notifications/ViewHelpers/NotificationsIndexViewHelper.php +++ b/app/Http/Controllers/Settings/Notifications/ViewHelpers/NotificationsIndexViewHelper.php @@ -38,6 +38,7 @@ public static function dtoEmail(UserNotificationChannel $channel, User $user): a 'content' => $channel->content, 'active' => $channel->active, 'verified_at' => $channel->verified_at ? $channel->verified_at->format('Y-m-d H:i:s') : null, + 'preferred_time' => $channel->preferred_time->format('H:i'), 'url' => [ 'store' => route('settings.notifications.store'), 'send_test' => route('settings.notifications.test.store', [ diff --git a/app/Jobs/SetupAccount.php b/app/Jobs/SetupAccount.php index dbf3066b311..624230469a7 100644 --- a/app/Jobs/SetupAccount.php +++ b/app/Jobs/SetupAccount.php @@ -90,6 +90,7 @@ private function addNotificationChannel(): void 'type' => UserNotificationChannel::TYPE_EMAIL, 'content' => $this->user->email, 'verify_email' => false, + 'preferred_time' => '09:00', ]); $channel->verified_at = Carbon::now(); diff --git a/app/Models/UserNotificationChannel.php b/app/Models/UserNotificationChannel.php index 3e3911c2193..3d6eadc10b6 100644 --- a/app/Models/UserNotificationChannel.php +++ b/app/Models/UserNotificationChannel.php @@ -50,6 +50,7 @@ class UserNotificationChannel extends Model */ protected $dates = [ 'verified_at', + 'preferred_time', ]; /** diff --git a/app/Services/User/NotificationChannels/CreateUserNotificationChannel.php b/app/Services/User/NotificationChannels/CreateUserNotificationChannel.php index e53173b3781..2d9cb7a8bae 100644 --- a/app/Services/User/NotificationChannels/CreateUserNotificationChannel.php +++ b/app/Services/User/NotificationChannels/CreateUserNotificationChannel.php @@ -30,6 +30,7 @@ public function rules(): array 'type' => 'required|string|max:255', 'content' => 'required|string|max:65535', 'verify_email' => 'nullable|boolean', + 'preferred_time' => 'nullable|date_format:H:i', ]; } @@ -81,8 +82,10 @@ private function create(): void 'label' => $this->data['label'], 'type' => $this->data['type'], 'content' => $this->data['content'], + 'preferred_time' => $this->data['preferred_time'], ]); + // add a verification link if the channel is email if ($this->data['verify_email']) { $uuid = Str::uuid(); @@ -98,7 +101,7 @@ private function verifyChannel(): void { if ($this->data['type'] === UserNotificationChannel::TYPE_EMAIL && $this->data['verify_email']) { // we need to verify the email address by sending a verification email - SendVerificationEmailChannel::dispatch($this->userNotificationChannel); + SendVerificationEmailChannel::dispatch($this->userNotificationChannel)->onQueue('high'); } } diff --git a/database/factories/UserNotificationChannelFactory.php b/database/factories/UserNotificationChannelFactory.php index 734100a52fc..c84f1879f21 100644 --- a/database/factories/UserNotificationChannelFactory.php +++ b/database/factories/UserNotificationChannelFactory.php @@ -29,6 +29,7 @@ public function definition() 'content' => 'admin@admin.com', 'active' => true, 'verified_at' => null, + 'preferred_time' => '09:00:00', ]; } } diff --git a/resources/js/Pages/Settings/Notifications/Partials/Emails.vue b/resources/js/Pages/Settings/Notifications/Partials/Emails.vue index 0c4eb8768cc..5672209ce58 100644 --- a/resources/js/Pages/Settings/Notifications/Partials/Emails.vue +++ b/resources/js/Pages/Settings/Notifications/Partials/Emails.vue @@ -14,6 +14,12 @@ border-bottom-right-radius: 8px; } } + +select { + padding-left: 8px; + padding-right: 20px; + background-position: right 3px center; +} </style> <template> @@ -32,6 +38,7 @@ <div class="border-b border-gray-200 p-5"> <errors :errors="form.errors" /> + <!-- content --> <text-input :ref="'content'" v-model="form.content" @@ -45,16 +52,123 @@ :maxlength="255" @esc-key-pressed="addEmailModalShown = false" /> + <!-- label --> <text-input v-model="form.label" :label="'Give this email address a name'" :type="'text'" :autofocus="true" :input-class="'block w-full'" + :div-outer-class="'mb-4'" :required="true" :autocomplete="false" :maxlength="255" @esc-key-pressed="addEmailModalShown = false" /> + + <!-- preferred time --> + <p class="mb-2 block text-sm">At which time should we send the notification, when the reminder occurs?</p> + <div class="flex items-center text-sm font-medium text-gray-700"> + <span class="mr-2">At</span> + + <select + v-model="form.hours" + class="mr-1 rounded-md border-gray-300 bg-white py-2 px-3 shadow-sm focus:border-indigo-300 focus:outline-none focus:ring focus:ring-indigo-200 focus:ring-opacity-50 sm:text-sm" + :required="required"> + <option value="00">00</option> + <option value="01">01</option> + <option value="02">02</option> + <option value="03">03</option> + <option value="04">04</option> + <option value="05">05</option> + <option value="06">06</option> + <option value="07">07</option> + <option value="08">08</option> + <option value="09">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="23">23</option> + </select> + + <span class="mr-2">h:</span> + + <select + v-model="form.minutes" + class="mr-1 rounded-md border-gray-300 bg-white py-2 px-3 shadow-sm focus:border-indigo-300 focus:outline-none focus:ring focus:ring-indigo-200 focus:ring-opacity-50 sm:text-sm" + :required="required"> + <option value="00">00</option> + <option value="01">01</option> + <option value="02">02</option> + <option value="03">03</option> + <option value="04">04</option> + <option value="05">05</option> + <option value="06">06</option> + <option value="07">07</option> + <option value="08">08</option> + <option value="09">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="22">22</option> + <option value="23">23</option> + <option value="24">24</option> + <option value="25">25</option> + <option value="26">26</option> + <option value="27">27</option> + <option value="28">28</option> + <option value="29">29</option> + <option value="30">30</option> + <option value="31">31</option> + <option value="32">32</option> + <option value="33">33</option> + <option value="34">34</option> + <option value="35">35</option> + <option value="36">36</option> + <option value="37">37</option> + <option value="38">38</option> + <option value="39">39</option> + <option value="40">40</option> + <option value="41">41</option> + <option value="42">42</option> + <option value="43">43</option> + <option value="44">44</option> + <option value="45">45</option> + <option value="46">46</option> + <option value="47">47</option> + <option value="48">48</option> + <option value="49">49</option> + <option value="50">50</option> + <option value="51">51</option> + <option value="52">52</option> + <option value="53">53</option> + <option value="54">54</option> + <option value="55">55</option> + <option value="56">56</option> + <option value="57">57</option> + <option value="57">58</option> + <option value="57">59</option> + </select> + + <span>m</span> + </div> </div> <div class="border-b border-gray-200 p-5"> @@ -97,7 +211,7 @@ <span class="mb-0 block">{{ email.content }}</span> <ul class="bulleted-list mr-2 text-sm text-gray-500"> <li v-if="email.label" class="mr-1 inline">{{ email.label }}</li> - <li class="inline">Sent at 9:00pm</li> + <li class="inline">Sent at {{ email.preferred_time }}</li> </ul> </div> </div> @@ -186,6 +300,8 @@ export default { form: { content: '', label: '', + minutes: '', + hours: '', errors: [], }, }; @@ -193,6 +309,8 @@ export default { mounted() { this.localEmails = this.data.emails; + this.form.hours = '09'; + this.form.minutes = '00'; }, methods: { diff --git a/resources/js/Shared/Modules/Reminders.vue b/resources/js/Shared/Modules/Reminders.vue index 7e043fe884b..7d53ea2d947 100644 --- a/resources/js/Shared/Modules/Reminders.vue +++ b/resources/js/Shared/Modules/Reminders.vue @@ -322,7 +322,7 @@ select { v-model="form.month" :data="data.months" :required="true" - :div-outer-class="'mb-5 mr-2'" + :div-outer-class="'mr-2'" :placeholder="'Choose a value'" :dropdown-class="'block w-full'" :label="'Month'" /> @@ -331,7 +331,6 @@ select { v-model="form.day" :data="data.days" :required="true" - :div-outer-class="'mb-5'" :placeholder="'Choose a value'" :dropdown-class="'block w-full'" :label="'Day'" /> diff --git a/tests/Unit/Controllers/Settings/Notifications/ViewHelpers/NotificationsIndexViewHelperTest.php b/tests/Unit/Controllers/Settings/Notifications/ViewHelpers/NotificationsIndexViewHelperTest.php index 259d93aaf09..75861e77d38 100644 --- a/tests/Unit/Controllers/Settings/Notifications/ViewHelpers/NotificationsIndexViewHelperTest.php +++ b/tests/Unit/Controllers/Settings/Notifications/ViewHelpers/NotificationsIndexViewHelperTest.php @@ -50,6 +50,7 @@ public function it_gets_the_data_needed_for_email_notification_channel(): void 'type' => UserNotificationChannel::TYPE_EMAIL, 'label' => 'super', 'verified_at' => '2020-01-01 00:00:00', + 'preferred_time' => '09:00:00', ]); $array = NotificationsIndexViewHelper::dtoEmail($channel, $user); @@ -61,6 +62,7 @@ public function it_gets_the_data_needed_for_email_notification_channel(): void 'content' => 'admin@admin.com', 'active' => $channel->active, 'verified_at' => '2020-01-01 00:00:00', + 'preferred_time' => '09:00', 'url' => [ 'store' => env('APP_URL').'/settings/notifications', 'send_test' => env('APP_URL').'/settings/notifications/'.$channel->id.'/test', diff --git a/tests/Unit/Services/User/NotificationChannels/CreateUserNotificationChannelTest.php b/tests/Unit/Services/User/NotificationChannels/CreateUserNotificationChannelTest.php index d1d0e94b6a8..96c99a11b14 100644 --- a/tests/Unit/Services/User/NotificationChannels/CreateUserNotificationChannelTest.php +++ b/tests/Unit/Services/User/NotificationChannels/CreateUserNotificationChannelTest.php @@ -80,6 +80,7 @@ private function executeService(User $author, Account $account, string $channelT 'type' => $channelType, 'content' => 'admin@admin.com', 'verify_email' => true, + 'preferred_time' => '09:00', ]; $channel = (new CreateUserNotificationChannel)->execute($request);