mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-10-07 21:33:18 +01:00
Move email preference to notifications section
This commit is contained in:
committed by
Gregor Vostrak
parent
593372bae5
commit
77f14b696e
106
resources/js/Pages/Profile/Partials/NotificationSettingsForm.vue
Normal file
106
resources/js/Pages/Profile/Partials/NotificationSettingsForm.vue
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
|
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||||
|
import FormSection from '@/Components/FormSection.vue';
|
||||||
|
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||||
|
import { Checkbox } from '@/packages/ui/src';
|
||||||
|
import {
|
||||||
|
Field,
|
||||||
|
FieldContent,
|
||||||
|
FieldDescription,
|
||||||
|
FieldError,
|
||||||
|
FieldLabel,
|
||||||
|
} from '@/packages/ui/src/field';
|
||||||
|
import { getApiValidationFieldErrors } from '@/utils/apiValidation';
|
||||||
|
import { useUpdateUserMutation, useUserQuery } from '@/utils/useUserQuery';
|
||||||
|
|
||||||
|
const { user } = useUserQuery();
|
||||||
|
const updateUser = useUpdateUserMutation();
|
||||||
|
|
||||||
|
const sendTimeEntryStillRunningEmail = ref(true);
|
||||||
|
const recentlySaved = ref(false);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
user,
|
||||||
|
(currentUser, previousUser) => {
|
||||||
|
if (currentUser && previousUser === undefined) {
|
||||||
|
sendTimeEntryStillRunningEmail.value =
|
||||||
|
currentUser.send_time_entry_still_running_email;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
const isUserLoaded = computed(() => user.value !== undefined);
|
||||||
|
const isSaveDisabled = computed(() => !isUserLoaded.value || updateUser.isPending.value);
|
||||||
|
const fieldErrors = computed<Record<string, string>>(() =>
|
||||||
|
getApiValidationFieldErrors(updateUser.error.value)
|
||||||
|
);
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
if (isSaveDisabled.value || !user.value) return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
sendTimeEntryStillRunningEmail.value === user.value.send_time_entry_still_running_email
|
||||||
|
) {
|
||||||
|
flashSaved();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const updatedUser = await updateUser.mutateAsync({
|
||||||
|
userId: user.value.id,
|
||||||
|
body: {
|
||||||
|
send_time_entry_still_running_email: sendTimeEntryStillRunningEmail.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
sendTimeEntryStillRunningEmail.value = updatedUser.send_time_entry_still_running_email;
|
||||||
|
flashSaved();
|
||||||
|
} catch {
|
||||||
|
// 422: field errors render below. Other errors: toast handled in the mutation.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function flashSaved() {
|
||||||
|
recentlySaved.value = true;
|
||||||
|
setTimeout(() => (recentlySaved.value = false), 2000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FormSection @submitted="save">
|
||||||
|
<template #title>Notifications</template>
|
||||||
|
|
||||||
|
<template #description>Choose which email notifications you want to receive.</template>
|
||||||
|
|
||||||
|
<template #form>
|
||||||
|
<div class="col-span-6 sm:col-span-4">
|
||||||
|
<Field orientation="horizontal">
|
||||||
|
<Checkbox
|
||||||
|
id="send_time_entry_still_running_email"
|
||||||
|
v-model:checked="sendTimeEntryStillRunningEmail"
|
||||||
|
:disabled="!isUserLoaded" />
|
||||||
|
<FieldContent>
|
||||||
|
<FieldLabel for="send_time_entry_still_running_email">
|
||||||
|
Still-running time entry reminders
|
||||||
|
</FieldLabel>
|
||||||
|
<FieldDescription>
|
||||||
|
Email me when a time entry has been running for more than 8 hours.
|
||||||
|
</FieldDescription>
|
||||||
|
</FieldContent>
|
||||||
|
</Field>
|
||||||
|
<FieldError v-if="fieldErrors.send_time_entry_still_running_email">
|
||||||
|
{{ fieldErrors.send_time_entry_still_running_email }}
|
||||||
|
</FieldError>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #actions>
|
||||||
|
<ActionMessage :on="recentlySaved" class="me-3">Saved.</ActionMessage>
|
||||||
|
|
||||||
|
<PrimaryButton :class="{ 'opacity-25': isSaveDisabled }" :disabled="isSaveDisabled">
|
||||||
|
Save
|
||||||
|
</PrimaryButton>
|
||||||
|
</template>
|
||||||
|
</FormSection>
|
||||||
|
</template>
|
||||||
@@ -8,7 +8,6 @@ import { Button } from '@/packages/ui/src/Buttons';
|
|||||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||||
import { Checkbox } from '@/packages/ui/src';
|
|
||||||
import {
|
import {
|
||||||
useResendUserEmailVerificationMutation,
|
useResendUserEmailVerificationMutation,
|
||||||
useResetUserPendingEmailMutation,
|
useResetUserPendingEmailMutation,
|
||||||
@@ -27,7 +26,6 @@ const name = ref('');
|
|||||||
const email = ref('');
|
const email = ref('');
|
||||||
const timezone = ref('');
|
const timezone = ref('');
|
||||||
const weekStart = ref('');
|
const weekStart = ref('');
|
||||||
const sendTimeEntryStillRunningEmail = ref(true);
|
|
||||||
|
|
||||||
const photoBase64 = ref<string | null>(null);
|
const photoBase64 = ref<string | null>(null);
|
||||||
const photoPreview = ref<string | null>(null);
|
const photoPreview = ref<string | null>(null);
|
||||||
@@ -42,7 +40,6 @@ function seedForm(u: User) {
|
|||||||
email.value = u.email;
|
email.value = u.email;
|
||||||
timezone.value = u.timezone;
|
timezone.value = u.timezone;
|
||||||
weekStart.value = u.week_start;
|
weekStart.value = u.week_start;
|
||||||
sendTimeEntryStillRunningEmail.value = u.send_time_entry_still_running_email;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -81,11 +78,6 @@ function buildPayload(): UpdateUserBody {
|
|||||||
if (weekStart.value !== user.value.week_start) {
|
if (weekStart.value !== user.value.week_start) {
|
||||||
body.week_start = weekStart.value as UpdateUserBody['week_start'];
|
body.week_start = weekStart.value as UpdateUserBody['week_start'];
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
sendTimeEntryStillRunningEmail.value !== user.value.send_time_entry_still_running_email
|
|
||||||
) {
|
|
||||||
body.send_time_entry_still_running_email = sendTimeEntryStillRunningEmail.value;
|
|
||||||
}
|
|
||||||
if (photoBase64.value !== null) body.photo = photoBase64.value;
|
if (photoBase64.value !== null) body.photo = photoBase64.value;
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
@@ -339,20 +331,6 @@ const page = usePage<{
|
|||||||
<FieldError v-if="fieldErrors.week_start">{{ fieldErrors.week_start }}</FieldError>
|
<FieldError v-if="fieldErrors.week_start">{{ fieldErrors.week_start }}</FieldError>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
<div class="col-span-6 sm:col-span-4">
|
|
||||||
<Field orientation="horizontal">
|
|
||||||
<Checkbox
|
|
||||||
id="send_time_entry_still_running_email"
|
|
||||||
v-model:checked="sendTimeEntryStillRunningEmail"
|
|
||||||
:disabled="!isUserLoaded" />
|
|
||||||
<FieldLabel for="send_time_entry_still_running_email">
|
|
||||||
Email me when a time entry has been running for more than 8 hours
|
|
||||||
</FieldLabel>
|
|
||||||
</Field>
|
|
||||||
<FieldError v-if="fieldErrors.send_time_entry_still_running_email">
|
|
||||||
{{ fieldErrors.send_time_entry_still_running_email }}
|
|
||||||
</FieldError>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #actions>
|
<template #actions>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import UpdateProfileInformationForm from '@/Pages/Profile/Partials/UpdateProfile
|
|||||||
import type { Session } from '@/types/jetstream';
|
import type { Session } from '@/types/jetstream';
|
||||||
import ApiTokensForm from '@/Pages/Profile/Partials/ApiTokensForm.vue';
|
import ApiTokensForm from '@/Pages/Profile/Partials/ApiTokensForm.vue';
|
||||||
import ThemeForm from '@/Pages/Profile/Partials/ThemeForm.vue';
|
import ThemeForm from '@/Pages/Profile/Partials/ThemeForm.vue';
|
||||||
|
import NotificationSettingsForm from '@/Pages/Profile/Partials/NotificationSettingsForm.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
confirmsTwoFactorAuthentication: boolean;
|
confirmsTwoFactorAuthentication: boolean;
|
||||||
@@ -36,6 +37,12 @@ defineProps<{
|
|||||||
<SectionBorder />
|
<SectionBorder />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<NotificationSettingsForm />
|
||||||
|
|
||||||
|
<SectionBorder />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<UpdatePasswordForm class="mt-10 sm:mt-0" />
|
<UpdatePasswordForm class="mt-10 sm:mt-0" />
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user