refactor(push-notification): use native time input and polish notification UI

PushNotificationPermission:
- Swap hour/minute number inputs and AM/PM toggle for native <input type="time">
- Add timeValue computed to keep existing hour/minute/AM-PM state in sync
- Remove unused checkHourInput and checkMinuteInput
- Tighten copy and layout: headings, labels, char count, button spacing

AccountViewView:
- Show reminder time and message in a bordered box with Time/Message labels
- Adjust spacing in notifications section
This commit is contained in:
Jose Olarte III
2026-01-30 15:35:47 +08:00
parent 22c3ac80c2
commit 1345118b79
2 changed files with 57 additions and 72 deletions

View File

@@ -14,64 +14,54 @@
<div
class="flex w-11/12 max-w-sm mx-auto mb-3 overflow-hidden bg-white rounded-lg shadow-lg"
>
<div class="w-full px-6 py-6 text-slate-900 text-center">
<p v-if="isSystemReady" class="text-lg mb-4">
<div class="w-full px-6 py-6 text-slate-900">
<h1 v-if="isSystemReady" class="text-center font-bold mb-4">
<span v-if="isDailyCheck">
Would you like to be notified of new activity, up to once a day?
</span>
<span v-else>
Would you like to get a reminder message once a day?
</span>
</p>
<p v-else class="text-lg mb-4">
</h1>
<h1 v-else class="text-center font-bold mb-4">
{{ waitingMessage }}
<font-awesome icon="spinner" spin />
</p>
</h1>
<div v-if="canShowNotificationForm">
<div v-if="isDailyCheck">
<span>Yes, send me a message when there is new data for me</span>
<span
><b>Yes</b>, send me a message when there is new data for
me</span
>
</div>
<div v-else>
<span>Yes, send me this message:</span>
<span class="text-slate-500 text-sm font-bold"
>Send me this message:</span
>
<!-- eslint-disable -->
<textarea
type="text"
id="push-message"
v-model="messageInput"
class="rounded border border-slate-400 mt-2 px-2 py-2 w-full"
class="rounded border border-slate-400 mt-2 p-2 w-full"
maxlength="100"
></textarea
>
<!-- eslint-enable -->
<span class="w-full flex justify-between text-xs text-slate-500">
<span></span>
<div class="text-xs text-slate-500">
<span>(100 characters max)</span>
</span>
</div>
</div>
<div>
<span class="flex flex-row justify-center">
<span class="mt-2">... at: </span>
<input
v-model="hourInput"
type="number"
class="rounded-l border border-r-0 border-slate-400 ml-2 mt-2 px-2 py-2 text-center w-20"
@change="checkHourInput"
/>
<input
v-model="minuteInput"
type="number"
class="border border-slate-400 mt-2 px-2 py-2 text-center w-20"
@change="checkMinuteInput"
/>
<span
class="rounded-r border border-slate-400 bg-slate-200 text-center text-blue-500 mt-2 px-2 py-2 w-20"
@click="toggleHourAm"
>
<span>{{ amPmLabel }} <font-awesome :icon="amPmIcon" /></span>
</span>
</span>
<div class="mt-2 mb-4 flex items-center gap-2">
<label for="time" class="text-slate-500 text-sm font-bold">At this time:</label>
<input
v-model="timeValue"
type="time"
id="time"
class="!px-4 !py-4 text-md bg-white border border-slate-400 rounded"
required
/>
</div>
<button
class="block w-full text-center text-md font-bold uppercase bg-blue-600 text-white mt-2 px-2 py-2 rounded-md"
@@ -82,7 +72,7 @@
</div>
<button
class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white mt-4 px-2 py-2 rounded-md"
class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white mt-2 px-2 py-2 rounded-md"
@click="close()"
>
No, Not Now
@@ -393,36 +383,6 @@ export default class PushNotificationPermission extends Vue {
);
}
private checkHourInput() {
const hourNum = parseInt(this.hourInput);
if (isNaN(hourNum)) {
this.hourInput = "12";
} else if (hourNum < 1) {
this.hourInput = "12";
this.hourAm = !this.hourAm;
} else if (hourNum > 12) {
this.hourInput = "1";
this.hourAm = !this.hourAm;
} else {
this.hourInput = hourNum.toString();
}
}
private checkMinuteInput() {
const minuteNum = parseInt(this.minuteInput);
if (isNaN(minuteNum)) {
this.minuteInput = "00";
} else if (minuteNum < 0) {
this.minuteInput = "59";
} else if (minuteNum < 10) {
this.minuteInput = "0" + minuteNum;
} else if (minuteNum > 59) {
this.minuteInput = "00";
} else {
this.minuteInput = minuteNum.toString();
}
}
private async turnOnNotifications() {
let notifyCloser = () => {};
return this.askPermission()
@@ -655,6 +615,27 @@ export default class PushNotificationPermission extends Vue {
return `${this.hourInput}:${this.minuteInput} ${this.hourAm ? "AM" : "PM"}`;
}
/**
* Two-way binding for native time input (HH:mm 24h).
* Syncs with hourInput, minuteInput, and hourAm.
*/
get timeValue(): string {
return this.convertTo24HourFormat();
}
set timeValue(value: string) {
const [h = "0", m = "0"] = value.split(":");
const hour24 = parseInt(h, 10);
const minute = parseInt(m, 10);
this.minuteInput = minute.toString().padStart(2, "0");
if (hour24 >= 12) {
this.hourAm = false;
this.hourInput = hour24 === 12 ? "12" : (hour24 - 12).toString();
} else {
this.hourAm = true;
this.hourInput = hour24 === 0 ? "12" : hour24.toString();
}
}
/**
* Toggles the AM/PM state for the hour input
*/

View File

@@ -84,7 +84,7 @@
aria-labelledby="notificationsHeading"
>
<h2 id="notificationsHeading" class="mb-2 font-bold">Notifications</h2>
<div class="flex items-center justify-between">
<div class="flex items-center justify-between mb-2">
<div>
Reminder Notification
<button
@@ -124,11 +124,15 @@
</div>
</div>
<div v-if="notifyingReminder" class="w-full">
<div class="flex justify-between mb-2">
<span class="ml-8 mr-8"
>Message: "{{ notifyingReminderMessage }}"</span
>
<span>{{ notifyingReminderTime.replace(" ", "&nbsp;") }}</span>
<div
class="text-sm text-slate-500 mb-2 bg-white rounded px-3 py-2 border border-slate-200"
>
<div>
<b>Time:</b> {{ notifyingReminderTime.replace(" ", "&nbsp;") }}
</div>
<div>
<b>Message:</b> <i>"{{ notifyingReminderMessage }}"</i>
</div>
</div>
<div class="mt-2 text-center">
<button
@@ -139,7 +143,7 @@
</button>
</div>
</div>
<div v-if="false" class="mt-2 flex items-center justify-between">
<div v-if="false" class="mt-4 flex items-center justify-between">
<!-- label -->
<div>
New Activity Notification