mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-16 04:02:15 +01:00
add format check, update prettier rules, apply rules consistently
This commit is contained in:
@@ -1,28 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import {computed, ref, inject, type ComputedRef} from 'vue';
|
||||
import { computed, ref, inject, type ComputedRef } from 'vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import {
|
||||
api,
|
||||
type ApiToken,
|
||||
type CreateApiTokenBody
|
||||
} from '@/packages/api/src';
|
||||
import SectionBorder from "@/Components/SectionBorder.vue";
|
||||
import DangerButton from "@/packages/ui/src/Buttons/DangerButton.vue";
|
||||
import TextInput from "../../../packages/ui/src/Input/TextInput.vue";
|
||||
import SecondaryButton from "../../../packages/ui/src/Buttons/SecondaryButton.vue";
|
||||
import DialogModal from "@/packages/ui/src/DialogModal.vue";
|
||||
import InputError from "@/packages/ui/src/Input/InputError.vue";
|
||||
import ActionMessage from "@/Components/ActionMessage.vue";
|
||||
import ConfirmationModal from "@/Components/ConfirmationModal.vue";
|
||||
import ActionSection from "@/Components/ActionSection.vue";
|
||||
import {useForm} from "@inertiajs/vue3";
|
||||
import {useMutation, useQuery, useQueryClient} from "@tanstack/vue-query";
|
||||
import {useNotificationsStore} from "@/utils/notification";
|
||||
import {useClipboard} from "@vueuse/core";
|
||||
import { formatDateTimeLocalized} from "../../../packages/ui/src/utils/time";
|
||||
import {ClockIcon} from "@heroicons/vue/20/solid";
|
||||
import { api, type ApiToken, type CreateApiTokenBody } from '@/packages/api/src';
|
||||
import SectionBorder from '@/Components/SectionBorder.vue';
|
||||
import DangerButton from '@/packages/ui/src/Buttons/DangerButton.vue';
|
||||
import TextInput from '../../../packages/ui/src/Input/TextInput.vue';
|
||||
import SecondaryButton from '../../../packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||
import ConfirmationModal from '@/Components/ConfirmationModal.vue';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query';
|
||||
import { useNotificationsStore } from '@/utils/notification';
|
||||
import { useClipboard } from '@vueuse/core';
|
||||
import { formatDateTimeLocalized } from '../../../packages/ui/src/utils/time';
|
||||
import { ClockIcon } from '@heroicons/vue/20/solid';
|
||||
import type { Organization } from '@/packages/api/src';
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
@@ -37,7 +33,7 @@ const { copy, copied, isSupported } = useClipboard();
|
||||
|
||||
const organization = inject<ComputedRef<Organization>>('organization');
|
||||
|
||||
async function createApiToken(){
|
||||
async function createApiToken() {
|
||||
await handleApiRequestNotifications(
|
||||
() =>
|
||||
createApiTokenMutation.mutateAsync({
|
||||
@@ -57,21 +53,20 @@ const createApiTokenForm = useForm({
|
||||
name: '',
|
||||
});
|
||||
|
||||
function confirmApiTokenDeletion (token: ApiToken) {
|
||||
function confirmApiTokenDeletion(token: ApiToken) {
|
||||
apiTokenBeingDeleted.value = token;
|
||||
}
|
||||
|
||||
function confirmApiTokenRevocation(token: ApiToken){
|
||||
function confirmApiTokenRevocation(token: ApiToken) {
|
||||
apiTokenBeingRevoked.value = token;
|
||||
}
|
||||
|
||||
const displayingToken = ref(false);
|
||||
|
||||
async function deleteApiToken () {
|
||||
if(apiTokenBeingDeleted.value){
|
||||
async function deleteApiToken() {
|
||||
if (apiTokenBeingDeleted.value) {
|
||||
await handleApiRequestNotifications(
|
||||
() =>
|
||||
deleteApiTokenMutation.mutateAsync(apiTokenBeingDeleted.value!.id),
|
||||
() => deleteApiTokenMutation.mutateAsync(apiTokenBeingDeleted.value!.id),
|
||||
'API Token successfully deleted',
|
||||
'There was an error while deleting the API Token',
|
||||
() => {
|
||||
@@ -79,13 +74,12 @@ async function deleteApiToken () {
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function revokeApiToken () {
|
||||
if(apiTokenBeingRevoked.value){
|
||||
async function revokeApiToken() {
|
||||
if (apiTokenBeingRevoked.value) {
|
||||
await handleApiRequestNotifications(
|
||||
() =>
|
||||
revokeApiTokenMutation.mutateAsync(apiTokenBeingRevoked.value!.id),
|
||||
() => revokeApiTokenMutation.mutateAsync(apiTokenBeingRevoked.value!.id),
|
||||
'API Token successfully revoked',
|
||||
'There was an error while revoking the API Token',
|
||||
() => {
|
||||
@@ -93,25 +87,23 @@ async function revokeApiToken () {
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const { data: sharedReportResponseData } = useQuery({
|
||||
queryKey: ['api-tokens'],
|
||||
queryFn: () =>
|
||||
api.getApiTokens(),
|
||||
queryFn: () => api.getApiTokens(),
|
||||
});
|
||||
|
||||
const tokens = computed(() => {
|
||||
return sharedReportResponseData.value?.data ?? [];
|
||||
})
|
||||
});
|
||||
|
||||
const createApiTokenMutation = useMutation({
|
||||
mutationFn: async (apiToken: CreateApiTokenBody) => {
|
||||
return await api.createApiToken(apiToken);
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['api-tokens'] })
|
||||
queryClient.invalidateQueries({ queryKey: ['api-tokens'] });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -124,7 +116,7 @@ const deleteApiTokenMutation = useMutation({
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['api-tokens'] })
|
||||
queryClient.invalidateQueries({ queryKey: ['api-tokens'] });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -137,12 +129,9 @@ const revokeApiTokenMutation = useMutation({
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['api-tokens'] })
|
||||
queryClient.invalidateQueries({ queryKey: ['api-tokens'] });
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -152,8 +141,8 @@ const revokeApiTokenMutation = useMutation({
|
||||
<template #title> Create API Token </template>
|
||||
|
||||
<template #description>
|
||||
API tokens allow third-party services to authenticate with our
|
||||
application on your behalf.
|
||||
API tokens allow third-party services to authenticate with our application on your
|
||||
behalf.
|
||||
</template>
|
||||
|
||||
<template #form>
|
||||
@@ -165,22 +154,17 @@ const revokeApiTokenMutation = useMutation({
|
||||
v-model="createApiTokenForm.name"
|
||||
type="text"
|
||||
class="mt-1 block w-full" />
|
||||
<InputError
|
||||
:message="createApiTokenForm.errors.name"
|
||||
class="mt-2" />
|
||||
<div class="text-text-tertiary text-sm pt-3 flex space-x-1.5 font-medium items-center">
|
||||
<InputError :message="createApiTokenForm.errors.name" class="mt-2" />
|
||||
<div
|
||||
class="text-text-tertiary text-sm pt-3 flex space-x-1.5 font-medium items-center">
|
||||
<ClockIcon class="w-4"></ClockIcon>
|
||||
<span>
|
||||
API Tokens are valid for 1 year
|
||||
</span>
|
||||
<span> API Tokens are valid for 1 year </span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<ActionMessage
|
||||
:on="createApiTokenForm.recentlySuccessful"
|
||||
class="me-3">
|
||||
<ActionMessage :on="createApiTokenForm.recentlySuccessful" class="me-3">
|
||||
Created.
|
||||
</ActionMessage>
|
||||
|
||||
@@ -201,8 +185,8 @@ const revokeApiTokenMutation = useMutation({
|
||||
<template #title> Manage API Tokens </template>
|
||||
|
||||
<template #description>
|
||||
You may delete or revoke any of your existing tokens if they are
|
||||
no longer needed.
|
||||
You may delete or revoke any of your existing tokens if they are no longer
|
||||
needed.
|
||||
</template>
|
||||
|
||||
<!-- API Token List -->
|
||||
@@ -216,21 +200,31 @@ const revokeApiTokenMutation = useMutation({
|
||||
<div>{{ token.name }}</div>
|
||||
<div class="text-sm text-text-tertiary space-x-3">
|
||||
<span v-if="token.created_at">
|
||||
Created at {{ formatDateTimeLocalized(token.created_at, organization?.date_format, organization?.time_format) }}
|
||||
Created at
|
||||
{{
|
||||
formatDateTimeLocalized(
|
||||
token.created_at,
|
||||
organization?.date_format,
|
||||
organization?.time_format
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
<span v-if="token.expires_at">
|
||||
Expires at {{ formatDateTimeLocalized(token.expires_at, organization?.date_format, organization?.time_format) }}
|
||||
</span>
|
||||
<span v-if="token.revoked">
|
||||
Revoked
|
||||
Expires at
|
||||
{{
|
||||
formatDateTimeLocalized(
|
||||
token.expires_at,
|
||||
organization?.date_format,
|
||||
organization?.time_format
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
<span v-if="token.revoked"> Revoked </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center ms-2">
|
||||
<div
|
||||
v-if="token.last_used_ago"
|
||||
class="text-sm text-gray-400">
|
||||
<div v-if="token.last_used_ago" class="text-sm text-gray-400">
|
||||
Last used {{ token.last_used_ago }}
|
||||
</div>
|
||||
<button
|
||||
@@ -260,25 +254,26 @@ const revokeApiTokenMutation = useMutation({
|
||||
|
||||
<template #content>
|
||||
<div>
|
||||
Please copy your new API token. For your security, it won't
|
||||
be shown again.
|
||||
Please copy your new API token. For your security, it won't be shown again.
|
||||
<strong>This token is valid for one year</strong> unless you revoke it.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
</div>
|
||||
<div></div>
|
||||
|
||||
<div class="flex gap-2 pt-6 w-full">
|
||||
<TextInput v-if="newToken" disabled :model-value="newToken" class="flex-1 text-gray-500"></TextInput>
|
||||
<PrimaryButton v-if="isSupported" @click="copy(newToken)">{{ copied ? 'Copied!' : 'Copy Token' }}</PrimaryButton>
|
||||
<TextInput
|
||||
v-if="newToken"
|
||||
disabled
|
||||
:model-value="newToken"
|
||||
class="flex-1 text-gray-500"></TextInput>
|
||||
<PrimaryButton v-if="isSupported" @click="copy(newToken)">{{
|
||||
copied ? 'Copied!' : 'Copy Token'
|
||||
}}</PrimaryButton>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<SecondaryButton @click="displayingToken = false">
|
||||
Close
|
||||
</SecondaryButton>
|
||||
<SecondaryButton @click="displayingToken = false"> Close </SecondaryButton>
|
||||
</template>
|
||||
</DialogModal>
|
||||
|
||||
@@ -288,14 +283,10 @@ const revokeApiTokenMutation = useMutation({
|
||||
@close="apiTokenBeingDeleted = null">
|
||||
<template #title> Delete API Token </template>
|
||||
|
||||
<template #content>
|
||||
Are you sure you would like to delete this API token?
|
||||
</template>
|
||||
<template #content> Are you sure you would like to delete this API token? </template>
|
||||
|
||||
<template #footer>
|
||||
<SecondaryButton @click="apiTokenBeingDeleted = null">
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
<SecondaryButton @click="apiTokenBeingDeleted = null"> Cancel </SecondaryButton>
|
||||
|
||||
<DangerButton
|
||||
class="ms-3"
|
||||
@@ -312,14 +303,10 @@ const revokeApiTokenMutation = useMutation({
|
||||
@close="apiTokenBeingRevoked = null">
|
||||
<template #title> Revoke API Token </template>
|
||||
|
||||
<template #content>
|
||||
Are you sure you would like to revoke this API token?
|
||||
</template>
|
||||
<template #content> Are you sure you would like to revoke this API token? </template>
|
||||
|
||||
<template #footer>
|
||||
<SecondaryButton @click="apiTokenBeingRevoked = null">
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
<SecondaryButton @click="apiTokenBeingRevoked = null"> Cancel </SecondaryButton>
|
||||
|
||||
<DangerButton
|
||||
class="ms-3"
|
||||
|
||||
@@ -45,15 +45,13 @@ const closeModal = () => {
|
||||
|
||||
<template #content>
|
||||
<div class="max-w-xl text-sm text-text-secondary">
|
||||
Once your account is deleted, all of its resources and data will
|
||||
be permanently deleted. Before deleting your account, please
|
||||
download any data or information that you wish to retain.
|
||||
Once your account is deleted, all of its resources and data will be permanently
|
||||
deleted. Before deleting your account, please download any data or information that
|
||||
you wish to retain.
|
||||
</div>
|
||||
|
||||
<div class="mt-5">
|
||||
<DangerButton @click="confirmUserDeletion">
|
||||
Delete Account
|
||||
</DangerButton>
|
||||
<DangerButton @click="confirmUserDeletion"> Delete Account </DangerButton>
|
||||
</div>
|
||||
|
||||
<!-- Delete Account Confirmation Modal -->
|
||||
@@ -61,10 +59,9 @@ const closeModal = () => {
|
||||
<template #title> Delete Account </template>
|
||||
|
||||
<template #content>
|
||||
Are you sure you want to delete your account? Once your
|
||||
account is deleted, all of its resources and data will be
|
||||
permanently deleted. Please enter your password to confirm
|
||||
you would like to permanently delete your account.
|
||||
Are you sure you want to delete your account? Once your account is deleted, all
|
||||
of its resources and data will be permanently deleted. Please enter your
|
||||
password to confirm you would like to permanently delete your account.
|
||||
|
||||
<div class="mt-4">
|
||||
<TextInput
|
||||
@@ -76,16 +73,12 @@ const closeModal = () => {
|
||||
autocomplete="current-password"
|
||||
@keyup.enter="deleteUser" />
|
||||
|
||||
<InputError
|
||||
:message="form.errors.password"
|
||||
class="mt-2" />
|
||||
<InputError :message="form.errors.password" class="mt-2" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<SecondaryButton @click="closeModal">
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
<SecondaryButton @click="closeModal"> Cancel </SecondaryButton>
|
||||
|
||||
<DangerButton
|
||||
class="ms-3"
|
||||
|
||||
@@ -48,25 +48,20 @@ const closeModal = () => {
|
||||
<template #title> Browser Sessions </template>
|
||||
|
||||
<template #description>
|
||||
Manage and log out your active sessions on other browsers and
|
||||
devices.
|
||||
Manage and log out your active sessions on other browsers and devices.
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<div class="max-w-xl text-sm text-text-secondary">
|
||||
If necessary, you may log out of all of your other browser
|
||||
sessions across all of your devices. Some of your recent
|
||||
sessions are listed below; however, this list may not be
|
||||
exhaustive. If you feel your account has been compromised, you
|
||||
should also update your password.
|
||||
If necessary, you may log out of all of your other browser sessions across all of
|
||||
your devices. Some of your recent sessions are listed below; however, this list may
|
||||
not be exhaustive. If you feel your account has been compromised, you should also
|
||||
update your password.
|
||||
</div>
|
||||
|
||||
<!-- Other Browser Sessions -->
|
||||
<div v-if="sessions.length > 0" class="mt-5 space-y-6">
|
||||
<div
|
||||
v-for="(session, i) in sessions"
|
||||
:key="i"
|
||||
class="flex items-center">
|
||||
<div v-for="(session, i) in sessions" :key="i" class="flex items-center">
|
||||
<div>
|
||||
<svg
|
||||
v-if="session.agent.is_desktop"
|
||||
@@ -99,17 +94,9 @@ const closeModal = () => {
|
||||
|
||||
<div class="ms-3">
|
||||
<div class="text-sm text-text-primary font-medium">
|
||||
{{
|
||||
session.agent.platform
|
||||
? session.agent.platform
|
||||
: 'Unknown'
|
||||
}}
|
||||
{{ session.agent.platform ? session.agent.platform : 'Unknown' }}
|
||||
-
|
||||
{{
|
||||
session.agent.browser
|
||||
? session.agent.browser
|
||||
: 'Unknown'
|
||||
}}
|
||||
{{ session.agent.browser ? session.agent.browser : 'Unknown' }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -121,9 +108,7 @@ const closeModal = () => {
|
||||
class="text-green-500 font-semibold"
|
||||
>This device</span
|
||||
>
|
||||
<span v-else
|
||||
>Last active {{ session.last_active }}</span
|
||||
>
|
||||
<span v-else>Last active {{ session.last_active }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -135,9 +120,7 @@ const closeModal = () => {
|
||||
Log Out Other Browser Sessions
|
||||
</PrimaryButton>
|
||||
|
||||
<ActionMessage :on="form.recentlySuccessful" class="ms-3">
|
||||
Done.
|
||||
</ActionMessage>
|
||||
<ActionMessage :on="form.recentlySuccessful" class="ms-3"> Done. </ActionMessage>
|
||||
</div>
|
||||
|
||||
<!-- Log Out Other Devices Confirmation Modal -->
|
||||
@@ -145,9 +128,8 @@ const closeModal = () => {
|
||||
<template #title> Log Out Other Browser Sessions </template>
|
||||
|
||||
<template #content>
|
||||
Please enter your password to confirm you would like to log
|
||||
out of your other browser sessions across all of your
|
||||
devices.
|
||||
Please enter your password to confirm you would like to log out of your other
|
||||
browser sessions across all of your devices.
|
||||
|
||||
<div class="mt-4">
|
||||
<TextInput
|
||||
@@ -159,16 +141,12 @@ const closeModal = () => {
|
||||
autocomplete="current-password"
|
||||
@keyup.enter="logoutOtherBrowserSessions" />
|
||||
|
||||
<InputError
|
||||
:message="form.errors.password"
|
||||
class="mt-2" />
|
||||
<InputError :message="form.errors.password" class="mt-2" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<SecondaryButton @click="closeModal">
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
<SecondaryButton @click="closeModal"> Cancel </SecondaryButton>
|
||||
|
||||
<PrimaryButton
|
||||
class="ms-3"
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import InputLabel from "../../../packages/ui/src/Input/InputLabel.vue";
|
||||
import FormSection from "@/Components/FormSection.vue";
|
||||
import InputLabel from '../../../packages/ui/src/Input/InputLabel.vue';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import { usePreferredColorScheme } from '@vueuse/core';
|
||||
import { themeSetting } from "@/utils/theme";
|
||||
|
||||
const preferredColor = usePreferredColorScheme()
|
||||
import { themeSetting } from '@/utils/theme';
|
||||
|
||||
const preferredColor = usePreferredColorScheme();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FormSection>
|
||||
<template #title> Theme</template>
|
||||
|
||||
<template #description>
|
||||
Choose how you want solidtime to look on your device
|
||||
</template>
|
||||
<template #description> Choose how you want solidtime to look on your device </template>
|
||||
|
||||
<template #form>
|
||||
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<InputLabel for="theme" value="Theme" />
|
||||
<select
|
||||
@@ -31,15 +26,14 @@ const preferredColor = usePreferredColorScheme()
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
<p v-if="themeSetting === 'system'" class="w-full text-sm text-text-tertiary font-medium mt-2">
|
||||
<p
|
||||
v-if="themeSetting === 'system'"
|
||||
class="w-full text-sm text-text-tertiary font-medium mt-2">
|
||||
System default: {{ preferredColor }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</FormSection>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -51,12 +51,7 @@ const enableTwoFactorAuthentication = () => {
|
||||
{},
|
||||
{
|
||||
preserveScroll: true,
|
||||
onSuccess: () =>
|
||||
Promise.all([
|
||||
showQrCode(),
|
||||
showSetupKey(),
|
||||
showRecoveryCodes(),
|
||||
]),
|
||||
onSuccess: () => Promise.all([showQrCode(), showSetupKey(), showRecoveryCodes()]),
|
||||
onFinish: () => {
|
||||
enabling.value = false;
|
||||
confirming.value = props.requiresConfirmation;
|
||||
@@ -97,9 +92,7 @@ const confirmTwoFactorAuthentication = () => {
|
||||
};
|
||||
|
||||
const regenerateRecoveryCodes = () => {
|
||||
axios
|
||||
.post(route('two-factor.recovery-codes'))
|
||||
.then(() => showRecoveryCodes());
|
||||
axios.post(route('two-factor.recovery-codes')).then(() => showRecoveryCodes());
|
||||
};
|
||||
|
||||
const disableTwoFactorAuthentication = () => {
|
||||
@@ -120,8 +113,7 @@ const disableTwoFactorAuthentication = () => {
|
||||
<template #title> Two Factor Authentication </template>
|
||||
|
||||
<template #description>
|
||||
Add additional security to your account using two factor
|
||||
authentication.
|
||||
Add additional security to your account using two factor authentication.
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
@@ -143,10 +135,9 @@ const disableTwoFactorAuthentication = () => {
|
||||
|
||||
<div class="mt-3 max-w-xl text-sm text-text-secondary">
|
||||
<p>
|
||||
When two factor authentication is enabled, you will be
|
||||
prompted for a secure, random token during authentication.
|
||||
You may retrieve this token from your phone's Google
|
||||
Authenticator application.
|
||||
When two factor authentication is enabled, you will be prompted for a secure,
|
||||
random token during authentication. You may retrieve this token from your
|
||||
phone's Google Authenticator application.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -154,29 +145,21 @@ const disableTwoFactorAuthentication = () => {
|
||||
<div v-if="qrCode">
|
||||
<div class="mt-4 max-w-xl text-sm text-text-secondary">
|
||||
<p v-if="confirming" class="font-semibold">
|
||||
To finish enabling two factor authentication, scan
|
||||
the following QR code using your phone's
|
||||
authenticator application or enter the setup key and
|
||||
To finish enabling two factor authentication, scan the following QR code
|
||||
using your phone's authenticator application or enter the setup key and
|
||||
provide the generated OTP code.
|
||||
</p>
|
||||
|
||||
<p v-else>
|
||||
Two factor authentication is now enabled. Scan the
|
||||
following QR code using your phone's authenticator
|
||||
application or enter the setup key.
|
||||
Two factor authentication is now enabled. Scan the following QR code
|
||||
using your phone's authenticator application or enter the setup key.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="mt-4 p-2 inline-block bg-white"
|
||||
v-html="qrCode" />
|
||||
<div class="mt-4 p-2 inline-block bg-white" v-html="qrCode" />
|
||||
|
||||
<div
|
||||
v-if="setupKey"
|
||||
class="mt-4 max-w-xl text-sm text-text-secondary">
|
||||
<p class="font-semibold">
|
||||
Setup Key: <span v-html="setupKey"></span>
|
||||
</p>
|
||||
<div v-if="setupKey" class="mt-4 max-w-xl text-sm text-text-secondary">
|
||||
<p class="font-semibold">Setup Key: <span v-html="setupKey"></span></p>
|
||||
</div>
|
||||
|
||||
<div v-if="confirming" class="mt-4">
|
||||
@@ -193,19 +176,16 @@ const disableTwoFactorAuthentication = () => {
|
||||
autocomplete="one-time-code"
|
||||
@keyup.enter="confirmTwoFactorAuthentication" />
|
||||
|
||||
<InputError
|
||||
:message="confirmationForm.errors.code"
|
||||
class="mt-2" />
|
||||
<InputError :message="confirmationForm.errors.code" class="mt-2" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="recoveryCodes.length > 0 && !confirming">
|
||||
<div class="mt-4 max-w-xl text-sm text-muted">
|
||||
<p class="font-semibold">
|
||||
Store these recovery codes in a secure password
|
||||
manager. They can be used to recover access to your
|
||||
account if your two factor authentication device is
|
||||
lost.
|
||||
Store these recovery codes in a secure password manager. They can be
|
||||
used to recover access to your account if your two factor authentication
|
||||
device is lost.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -220,8 +200,7 @@ const disableTwoFactorAuthentication = () => {
|
||||
|
||||
<div class="mt-5">
|
||||
<div v-if="!twoFactorEnabled">
|
||||
<ConfirmsPassword
|
||||
@confirmed="enableTwoFactorAuthentication">
|
||||
<ConfirmsPassword @confirmed="enableTwoFactorAuthentication">
|
||||
<PrimaryButton
|
||||
type="button"
|
||||
:class="{ 'opacity-25': enabling }"
|
||||
@@ -232,8 +211,7 @@ const disableTwoFactorAuthentication = () => {
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<ConfirmsPassword
|
||||
@confirmed="confirmTwoFactorAuthentication">
|
||||
<ConfirmsPassword @confirmed="confirmTwoFactorAuthentication">
|
||||
<PrimaryButton
|
||||
v-if="confirming"
|
||||
type="button"
|
||||
@@ -260,8 +238,7 @@ const disableTwoFactorAuthentication = () => {
|
||||
</SecondaryButton>
|
||||
</ConfirmsPassword>
|
||||
|
||||
<ConfirmsPassword
|
||||
@confirmed="disableTwoFactorAuthentication">
|
||||
<ConfirmsPassword @confirmed="disableTwoFactorAuthentication">
|
||||
<SecondaryButton
|
||||
v-if="confirming"
|
||||
:class="disabling ? 'opacity-25' : ''"
|
||||
@@ -270,8 +247,7 @@ const disableTwoFactorAuthentication = () => {
|
||||
</SecondaryButton>
|
||||
</ConfirmsPassword>
|
||||
|
||||
<ConfirmsPassword
|
||||
@confirmed="disableTwoFactorAuthentication">
|
||||
<ConfirmsPassword @confirmed="disableTwoFactorAuthentication">
|
||||
<DangerButton
|
||||
v-if="!confirming"
|
||||
:class="{ 'opacity-25': disabling }"
|
||||
|
||||
@@ -55,9 +55,7 @@ const updatePassword = () => {
|
||||
type="password"
|
||||
class="mt-1 block w-full"
|
||||
autocomplete="current-password" />
|
||||
<InputError
|
||||
:message="form.errors.current_password"
|
||||
class="mt-2" />
|
||||
<InputError :message="form.errors.current_password" class="mt-2" />
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
@@ -73,29 +71,21 @@ const updatePassword = () => {
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<InputLabel
|
||||
for="password_confirmation"
|
||||
value="Confirm Password" />
|
||||
<InputLabel for="password_confirmation" value="Confirm Password" />
|
||||
<TextInput
|
||||
id="password_confirmation"
|
||||
v-model="form.password_confirmation"
|
||||
type="password"
|
||||
class="mt-1 block w-full"
|
||||
autocomplete="new-password" />
|
||||
<InputError
|
||||
:message="form.errors.password_confirmation"
|
||||
class="mt-2" />
|
||||
<InputError :message="form.errors.password_confirmation" class="mt-2" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<ActionMessage :on="form.recentlySuccessful" class="me-3">
|
||||
Saved.
|
||||
</ActionMessage>
|
||||
<ActionMessage :on="form.recentlySuccessful" class="me-3"> Saved. </ActionMessage>
|
||||
|
||||
<PrimaryButton
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing">
|
||||
<PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
|
||||
Save
|
||||
</PrimaryButton>
|
||||
</template>
|
||||
|
||||
@@ -28,11 +28,7 @@ const photoPreview = ref<ArrayBuffer | undefined | string | null>(null);
|
||||
const photoInput = ref<HTMLInputElement | null>(null);
|
||||
|
||||
const updateProfileInformation = () => {
|
||||
if (
|
||||
photoInput.value &&
|
||||
photoInput.value.files &&
|
||||
photoInput.value.files?.length > 0
|
||||
) {
|
||||
if (photoInput.value && photoInput.value.files && photoInput.value.files?.length > 0) {
|
||||
form.photo = photoInput.value?.files[0];
|
||||
}
|
||||
|
||||
@@ -100,9 +96,7 @@ const page = usePage<{
|
||||
|
||||
<template #form>
|
||||
<!-- Profile Photo -->
|
||||
<div
|
||||
v-if="page.props.jetstream.managesProfilePhotos"
|
||||
class="col-span-6 sm:col-span-4">
|
||||
<div v-if="page.props.jetstream.managesProfilePhotos" class="col-span-6 sm:col-span-4">
|
||||
<!-- Profile Photo File Input -->
|
||||
<input
|
||||
id="photo"
|
||||
@@ -125,15 +119,10 @@ const page = usePage<{
|
||||
<div v-show="photoPreview" class="mt-2">
|
||||
<span
|
||||
class="block rounded-full w-20 h-20 bg-cover bg-no-repeat bg-center"
|
||||
:style="
|
||||
'background-image: url(\'' + photoPreview + '\');'
|
||||
" />
|
||||
:style="'background-image: url(\'' + photoPreview + '\');'" />
|
||||
</div>
|
||||
|
||||
<SecondaryButton
|
||||
class="mt-2 me-2"
|
||||
type="button"
|
||||
@click.prevent="selectNewPhoto">
|
||||
<SecondaryButton class="mt-2 me-2" type="button" @click.prevent="selectNewPhoto">
|
||||
Select A New Photo
|
||||
</SecondaryButton>
|
||||
|
||||
@@ -175,8 +164,7 @@ const page = usePage<{
|
||||
|
||||
<div
|
||||
v-if="
|
||||
page.props.jetstream.hasEmailVerification &&
|
||||
user.email_verified_at === null
|
||||
page.props.jetstream.hasEmailVerification && user.email_verified_at === null
|
||||
">
|
||||
<p class="text-sm mt-2 text-text-primary">
|
||||
Your email address is unverified.
|
||||
@@ -194,8 +182,7 @@ const page = usePage<{
|
||||
<div
|
||||
v-show="verificationLinkSent"
|
||||
class="mt-2 font-medium text-sm text-green-400">
|
||||
A new verification link has been sent to your email
|
||||
address.
|
||||
A new verification link has been sent to your email address.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -211,8 +198,7 @@ const page = usePage<{
|
||||
class="mt-1 block w-full border-input-border bg-input-background text-text-primary focus:border-input-border-active rounded-md shadow-sm">
|
||||
<option value="" disabled>Select a Timezone</option>
|
||||
<option
|
||||
v-for="(timezoneTranslated, timezoneKey) in $page.props
|
||||
.timezones"
|
||||
v-for="(timezoneTranslated, timezoneKey) in $page.props.timezones"
|
||||
:key="timezoneKey"
|
||||
:value="timezoneKey">
|
||||
{{ timezoneTranslated }}
|
||||
@@ -232,8 +218,7 @@ const page = usePage<{
|
||||
class="mt-1 block w-full border-input-border bg-input-background text-text-primary focus:border-input-border-active rounded-md shadow-sm">
|
||||
<option value="" disabled>Select a week day</option>
|
||||
<option
|
||||
v-for="(weekdayTranslated, weekdayKey) in $page.props
|
||||
.weekdays"
|
||||
v-for="(weekdayTranslated, weekdayKey) in $page.props.weekdays"
|
||||
:key="weekdayKey"
|
||||
:value="weekdayKey">
|
||||
{{ weekdayTranslated }}
|
||||
@@ -244,13 +229,9 @@ const page = usePage<{
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<ActionMessage :on="form.recentlySuccessful" class="me-3">
|
||||
Saved.
|
||||
</ActionMessage>
|
||||
<ActionMessage :on="form.recentlySuccessful" class="me-3"> Saved. </ActionMessage>
|
||||
|
||||
<PrimaryButton
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing">
|
||||
<PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
|
||||
Save
|
||||
</PrimaryButton>
|
||||
</template>
|
||||
|
||||
@@ -9,8 +9,8 @@ import UpdateProfileInformationForm from '@/Pages/Profile/Partials/UpdateProfile
|
||||
import { usePage } from '@inertiajs/vue3';
|
||||
import type { User } from '@/types/models';
|
||||
import type { Session } from '@/types/jetstream';
|
||||
import ApiTokensForm from "@/Pages/Profile/Partials/ApiTokensForm.vue";
|
||||
import ThemeForm from "@/Pages/Profile/Partials/ThemeForm.vue";
|
||||
import ApiTokensForm from '@/Pages/Profile/Partials/ApiTokensForm.vue';
|
||||
import ThemeForm from '@/Pages/Profile/Partials/ThemeForm.vue';
|
||||
|
||||
defineProps<{
|
||||
confirmsTwoFactorAuthentication: boolean;
|
||||
@@ -33,16 +33,13 @@ const page = usePage<{
|
||||
<template>
|
||||
<AppLayout title="Profile">
|
||||
<template #header>
|
||||
<h2 class="font-semibold text-xl text-text-primary leading-tight">
|
||||
Profile
|
||||
</h2>
|
||||
<h2 class="font-semibold text-xl text-text-primary leading-tight">Profile</h2>
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
|
||||
<div v-if="page.props.jetstream.canUpdateProfileInformation">
|
||||
<UpdateProfileInformationForm
|
||||
:user="page.props.auth.user" />
|
||||
<UpdateProfileInformationForm :user="page.props.auth.user" />
|
||||
|
||||
<SectionBorder />
|
||||
</div>
|
||||
@@ -59,10 +56,7 @@ const page = usePage<{
|
||||
<SectionBorder />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="
|
||||
page.props.jetstream.canManageTwoFactorAuthentication
|
||||
">
|
||||
<div v-if="page.props.jetstream.canManageTwoFactorAuthentication">
|
||||
<TwoFactorAuthenticationForm
|
||||
:requires-confirmation="confirmsTwoFactorAuthentication"
|
||||
class="mt-10 sm:mt-0" />
|
||||
@@ -70,15 +64,12 @@ const page = usePage<{
|
||||
<SectionBorder />
|
||||
</div>
|
||||
|
||||
<LogoutOtherBrowserSessionsForm
|
||||
:sessions="sessions"
|
||||
class="mt-10 sm:mt-0" />
|
||||
<LogoutOtherBrowserSessionsForm :sessions="sessions" class="mt-10 sm:mt-0" />
|
||||
<SectionBorder />
|
||||
|
||||
<ApiTokensForm></ApiTokensForm>
|
||||
|
||||
<template
|
||||
v-if="page.props.jetstream.hasAccountDeletionFeatures">
|
||||
<template v-if="page.props.jetstream.hasAccountDeletionFeatures">
|
||||
<SectionBorder />
|
||||
|
||||
<DeleteUserForm class="mt-10 sm:mt-0" />
|
||||
|
||||
Reference in New Issue
Block a user