mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-17 12:42:15 +01:00
refactor to shadcn components, dynamically load extension frontend
add jetstream permissions, add dynamic inertia module loading, add shadcn components, change modals and dropdowns to shadcn dismissable layer,
This commit is contained in:
@@ -129,7 +129,7 @@ const deleteApiToken = () => {
|
||||
createApiTokenForm.permissions
|
||||
"
|
||||
:value="permission" />
|
||||
<span class="ms-2 text-sm text-muted">{{
|
||||
<span class="ms-2 text-sm text-text-secondary">{{
|
||||
permission
|
||||
}}</span>
|
||||
</label>
|
||||
|
||||
@@ -33,7 +33,7 @@ const submit = () => {
|
||||
<AuthenticationCardLogo />
|
||||
</template>
|
||||
|
||||
<div class="mb-4 text-sm text-muted">
|
||||
<div class="mb-4 text-sm text-text-secondary">
|
||||
This is a secure area of the application. Please confirm your
|
||||
password before continuing.
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@ const submit = () => {
|
||||
<AuthenticationCardLogo />
|
||||
</template>
|
||||
|
||||
<div class="mb-4 text-sm text-muted">
|
||||
<div class="mb-4 text-sm text-text-secondary">
|
||||
Forgot your password? No problem. Just let us know your email
|
||||
address and we will email you a password reset link that will allow
|
||||
you to choose a new one.
|
||||
|
||||
@@ -44,7 +44,7 @@ const page = usePage<{
|
||||
|
||||
<template #actions>
|
||||
<Link
|
||||
class="py-8 text-muted text-sm font-medium opacity-90 hover:opacity-100 transition"
|
||||
class="py-8 text-text-secondary text-sm font-medium opacity-90 hover:opacity-100 transition"
|
||||
:href="route('register')">
|
||||
No account yet? <span class="text-text-primary">Register here!</span>
|
||||
</Link>
|
||||
@@ -89,7 +89,7 @@ const page = usePage<{
|
||||
<Link
|
||||
v-if="canResetPassword"
|
||||
:href="route('password.request')"
|
||||
class="underline text-sm text-muted hover:text-text-primary rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||
class="underline text-sm text-text-secondary hover:text-text-primary rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||
Forgot your password?
|
||||
</Link>
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ const page = usePage<{
|
||||
|
||||
<template #actions>
|
||||
<Link
|
||||
class="py-8 text-muted text-sm font-medium opacity-90 hover:opacity-100 transition"
|
||||
class="py-8 text-text-secondary text-sm font-medium opacity-90 hover:opacity-100 transition"
|
||||
:href="route('login')">
|
||||
Already have an account?
|
||||
<span class="text-text-primary">Login here!</span>
|
||||
@@ -135,14 +135,14 @@ const page = usePage<{
|
||||
<a
|
||||
target="_blank"
|
||||
:href="page.props.terms_url"
|
||||
class="underline text-sm text-muted hover:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||
class="underline text-sm text-text-secondary hover:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||
>Terms of Service</a
|
||||
>
|
||||
and
|
||||
<a
|
||||
target="_blank"
|
||||
:href="page.props.privacy_policy_url"
|
||||
class="underline text-sm text-muted hover:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||
class="underline text-sm text-text-secondary hover:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||
>Privacy Policy</a
|
||||
>
|
||||
</div>
|
||||
@@ -173,7 +173,7 @@ const page = usePage<{
|
||||
<div class="flex items-center justify-end mt-4">
|
||||
<Link
|
||||
:href="route('login')"
|
||||
class="underline text-sm text-muted hover:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||
class="underline text-sm text-text-secondary hover:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||
Already registered?
|
||||
</Link>
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ const submit = () => {
|
||||
<AuthenticationCardLogo />
|
||||
</template>
|
||||
|
||||
<div class="mb-4 text-sm text-muted">
|
||||
<div class="mb-4 text-sm text-text-secondary">
|
||||
<template v-if="!recovery">
|
||||
Please confirm access to your account by entering the
|
||||
authentication code provided by your authenticator application.
|
||||
@@ -87,7 +87,7 @@ const submit = () => {
|
||||
<div class="flex items-center justify-end mt-4">
|
||||
<button
|
||||
type="button"
|
||||
class="text-sm text-muted hover:text-text-primary underline cursor-pointer"
|
||||
class="text-sm text-text-secondary hover:text-text-primary underline cursor-pointer"
|
||||
@click.prevent="toggleRecovery">
|
||||
<template v-if="!recovery"> Use a recovery code</template>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ const verificationLinkSent = computed(
|
||||
<AuthenticationCardLogo />
|
||||
</template>
|
||||
|
||||
<div class="mb-4 text-sm text-muted">
|
||||
<div class="mb-4 text-sm text-text-secondary">
|
||||
Before continuing, could you verify your email address by clicking
|
||||
on the link we just emailed to you? If you didn't receive the email,
|
||||
we will gladly send you another.
|
||||
@@ -53,7 +53,7 @@ const verificationLinkSent = computed(
|
||||
:href="route('logout')"
|
||||
method="post"
|
||||
as="button"
|
||||
class="underline text-sm text-muted hover:text-text-secondary rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800 ms-2">
|
||||
class="underline text-sm text-text-secondary hover:text-text-secondary rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800 ms-2">
|
||||
Log Out
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -20,10 +20,6 @@ onMounted(() => {
|
||||
|
||||
const activeTab = ref<'active' | 'archived'>('active');
|
||||
|
||||
function isActiveTab(tab: string) {
|
||||
return activeTab.value === tab;
|
||||
}
|
||||
|
||||
const createClient = ref(false);
|
||||
|
||||
const { clients } = storeToRefs(useClientsStore());
|
||||
@@ -44,15 +40,16 @@ const shownClients = computed(() => {
|
||||
class="py-5 border-b border-default-background-separator flex justify-between items-center">
|
||||
<div class="flex items-center space-x-3 sm:space-x-6">
|
||||
<PageTitle :icon="UserCircleIcon" title="Clients"> </PageTitle>
|
||||
<TabBar>
|
||||
<TabBar
|
||||
v-model="activeTab"
|
||||
>
|
||||
<TabBarItem
|
||||
:active="isActiveTab('active')"
|
||||
@click="activeTab = 'active'"
|
||||
value="active"
|
||||
>Active</TabBarItem
|
||||
>
|
||||
<TabBarItem
|
||||
:active="isActiveTab('archived')"
|
||||
@click="activeTab = 'archived'">
|
||||
value="archived"
|
||||
>
|
||||
Archived
|
||||
</TabBarItem>
|
||||
</TabBar>
|
||||
|
||||
@@ -21,9 +21,6 @@ defineProps<{
|
||||
}>();
|
||||
|
||||
const activeTab = ref<'all' | 'invitations'>('all');
|
||||
function isActiveTab(tab: string) {
|
||||
return activeTab.value === tab;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -32,15 +29,15 @@ function isActiveTab(tab: string) {
|
||||
class="py-5 border-b border-default-background-separator flex justify-between items-center">
|
||||
<div class="flex items-center space-x-4 sm:space-x-6">
|
||||
<PageTitle :icon="UserGroupIcon" title="Members"> </PageTitle>
|
||||
<TabBar>
|
||||
<TabBar
|
||||
v-model="activeTab"
|
||||
>
|
||||
<TabBarItem
|
||||
:active="isActiveTab('all')"
|
||||
@click="activeTab = 'all'"
|
||||
value="all"
|
||||
>All</TabBarItem
|
||||
>
|
||||
<TabBarItem
|
||||
:active="isActiveTab('invitations')"
|
||||
@click="activeTab = 'invitations'"
|
||||
value="invitations"
|
||||
>Invitations</TabBarItem
|
||||
>
|
||||
</TabBar>
|
||||
|
||||
@@ -44,7 +44,7 @@ const closeModal = () => {
|
||||
<template #description> Permanently delete your account. </template>
|
||||
|
||||
<template #content>
|
||||
<div class="max-w-xl text-sm text-muted">
|
||||
<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.
|
||||
|
||||
@@ -53,7 +53,7 @@ const closeModal = () => {
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<div class="max-w-xl text-sm text-muted">
|
||||
<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
|
||||
@@ -113,7 +113,7 @@ const closeModal = () => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="text-xs text-muted">
|
||||
<div class="text-xs text-text-secondary">
|
||||
{{ session.ip_address }},
|
||||
|
||||
<span
|
||||
|
||||
@@ -141,7 +141,7 @@ const disableTwoFactorAuthentication = () => {
|
||||
You have not enabled two factor authentication.
|
||||
</h3>
|
||||
|
||||
<div class="mt-3 max-w-xl text-sm text-muted">
|
||||
<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.
|
||||
@@ -152,7 +152,7 @@ const disableTwoFactorAuthentication = () => {
|
||||
|
||||
<div v-if="twoFactorEnabled">
|
||||
<div v-if="qrCode">
|
||||
<div class="mt-4 max-w-xl text-sm text-muted">
|
||||
<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
|
||||
@@ -173,7 +173,7 @@ const disableTwoFactorAuthentication = () => {
|
||||
|
||||
<div
|
||||
v-if="setupKey"
|
||||
class="mt-4 max-w-xl text-sm text-muted">
|
||||
class="mt-4 max-w-xl text-sm text-text-secondary">
|
||||
<p class="font-semibold">
|
||||
Setup Key: <span v-html="setupKey"></span>
|
||||
</p>
|
||||
|
||||
@@ -185,7 +185,7 @@ const page = usePage<{
|
||||
:href="route('verification.send')"
|
||||
method="post"
|
||||
as="button"
|
||||
class="underline text-sm text-muted hover:text-text-secondary rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800"
|
||||
class="underline text-sm text-text-secondary hover:text-text-secondary rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800"
|
||||
@click.prevent="sendEmailVerification">
|
||||
Click here to re-send the verification email.
|
||||
</Link>
|
||||
|
||||
@@ -60,10 +60,6 @@ const showEditProjectModal = ref(false);
|
||||
|
||||
const activeTab = ref<'active' | 'done'>('active');
|
||||
|
||||
function isActiveTab(tab: string) {
|
||||
return activeTab.value === tab;
|
||||
}
|
||||
|
||||
const { tasks } = storeToRefs(useTasksStore());
|
||||
|
||||
const shownTasks = computed(() => {
|
||||
@@ -97,7 +93,7 @@ const shownTasks = computed(() => {
|
||||
<div
|
||||
class="flex items-center space-x-3 text-text-primary font-semibold text-base">
|
||||
<ChevronRightIcon
|
||||
class="h-5 w-5 flex-shrink-0 text-muted"
|
||||
class="h-5 w-5 flex-shrink-0 text-text-secondary"
|
||||
aria-hidden="true" />
|
||||
<div class="flex space-x-3 items-center">
|
||||
<div
|
||||
@@ -149,15 +145,15 @@ const shownTasks = computed(() => {
|
||||
<div
|
||||
class="w-full items-center flex justify-between">
|
||||
<div class="pl-6">
|
||||
<TabBar>
|
||||
<TabBar
|
||||
v-model="activeTab"
|
||||
>
|
||||
<TabBarItem
|
||||
:active="isActiveTab('active')"
|
||||
@click="activeTab = 'active'"
|
||||
value="active"
|
||||
>Active
|
||||
</TabBarItem>
|
||||
<TabBarItem
|
||||
:active="isActiveTab('done')"
|
||||
@click="activeTab = 'done'"
|
||||
value="done"
|
||||
>Done
|
||||
</TabBarItem>
|
||||
</TabBar>
|
||||
|
||||
@@ -35,10 +35,6 @@ const { organization } = storeToRefs(useOrganizationStore());
|
||||
|
||||
const activeTab = ref<'active' | 'archived'>('active');
|
||||
|
||||
function isActiveTab(tab: string) {
|
||||
return activeTab.value === tab;
|
||||
}
|
||||
|
||||
const { projects } = storeToRefs(useProjectsStore());
|
||||
|
||||
const shownProjects = computed(() => {
|
||||
@@ -74,17 +70,16 @@ const showBillableRate = computed(() => {
|
||||
class="py-3 sm:py-5 border-b border-default-background-separator flex justify-between items-center">
|
||||
<div class="flex items-center space-x-3 sm:space-x-6">
|
||||
<PageTitle :icon="FolderIcon" title="Projects"></PageTitle>
|
||||
<TabBar>
|
||||
<TabBar
|
||||
v-model="activeTab"
|
||||
>
|
||||
<TabBarItem
|
||||
:active="isActiveTab('active')"
|
||||
@click="activeTab = 'active'"
|
||||
value="active"
|
||||
>Active</TabBarItem
|
||||
>
|
||||
<TabBarItem
|
||||
:active="isActiveTab('archived')"
|
||||
@click="activeTab = 'archived'">
|
||||
Archived
|
||||
</TabBarItem>
|
||||
value="archived"
|
||||
>Archived</TabBarItem>
|
||||
</TabBar>
|
||||
</div>
|
||||
<SecondaryButton
|
||||
|
||||
@@ -430,7 +430,7 @@ const tableData = computed(() => {
|
||||
class="grid items-center"
|
||||
style="grid-template-columns: 1fr 100px 150px">
|
||||
<div
|
||||
class="contents [&>*]:border-card-background-separator [&>*]:border-b [&>*]:bg-tertiary [&>*]:pb-1.5 [&>*]:pt-1 text-muted text-sm">
|
||||
class="contents [&>*]:border-card-background-separator [&>*]:border-b [&>*]:bg-tertiary [&>*]:pb-1.5 [&>*]:pt-1 text-text-secondary text-sm">
|
||||
<div class="pl-6">Name</div>
|
||||
<div class="text-right">Duration</div>
|
||||
<div class="text-right pr-6">Cost</div>
|
||||
|
||||
@@ -141,7 +141,7 @@ function getGroupLabel(key: string) {
|
||||
<template>
|
||||
<Head :title="sharedReportResponseData?.name" />
|
||||
|
||||
<div class="text-muted">
|
||||
<div class="text-text-secondary">
|
||||
<MainContainer
|
||||
class="py-3 sm:py-5 border-b border-default-background-separator flex justify-between items-center">
|
||||
<div class="flex items-center space-x-3 sm:space-x-6">
|
||||
@@ -174,7 +174,7 @@ function getGroupLabel(key: string) {
|
||||
class="grid items-center"
|
||||
style="grid-template-columns: 1fr 100px 150px">
|
||||
<div
|
||||
class="contents [&>*]:border-card-background-separator [&>*]:border-b [&>*]:bg-tertiary [&>*]:pb-1.5 [&>*]:pt-1 text-muted text-sm">
|
||||
class="contents [&>*]:border-card-background-separator [&>*]:border-b [&>*]:bg-tertiary [&>*]:pb-1.5 [&>*]:pt-1 text-text-secondary text-sm">
|
||||
<div class="pl-6">Name</div>
|
||||
<div class="text-right">Duration</div>
|
||||
<div class="text-right pr-6">Cost</div>
|
||||
|
||||
@@ -50,7 +50,7 @@ const page = usePage<{
|
||||
<div class="text-text-primary">
|
||||
{{ page.props.auth.user.name }}
|
||||
</div>
|
||||
<div class="text-sm text-muted">
|
||||
<div class="text-sm text-text-secondary">
|
||||
{{ page.props.auth.user.email }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,7 @@ const deleteTeam = () => {
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<div class="max-w-xl text-sm text-muted">
|
||||
<div class="max-w-xl text-sm text-text-secondary">
|
||||
Once a organization is deleted, all of its resources and data
|
||||
will be permanently deleted. Before deleting this organization,
|
||||
please download any data or information regarding this
|
||||
|
||||
@@ -208,7 +208,7 @@ const showResultModal = ref(false);
|
||||
<div
|
||||
v-if="currentImporterDescription"
|
||||
class="py-3 text-text-primary">
|
||||
<div class="font-semibold text-muted py-1">
|
||||
<div class="font-semibold text-text-secondary py-1">
|
||||
Instructions:
|
||||
</div>
|
||||
<div
|
||||
@@ -221,10 +221,10 @@ const showResultModal = ref(false);
|
||||
class="mt-2 flex justify-center rounded-lg border border-dashed border-border-primary px-6 py-10">
|
||||
<div class="text-center">
|
||||
<DocumentIcon
|
||||
class="mx-auto h-8 w-8 text-muted"
|
||||
class="mx-auto h-8 w-8 text-text-secondary"
|
||||
aria-hidden="true" />
|
||||
|
||||
<div class="mt-4 flex text-sm leading-6 text-muted">
|
||||
<div class="mt-4 flex text-sm leading-6 text-text-secondary">
|
||||
<label
|
||||
for="file-upload"
|
||||
class="relative cursor-pointer rounded-md font-semibold text-text-primary focus-within:outline-none focus-within:ring-2 focus-within:ring-indigo-600 focus-within:ring-offset-2 focus-within:ring-offset-gray-900 hover:text-indigo-500">
|
||||
@@ -241,7 +241,7 @@ const showResultModal = ref(false);
|
||||
@change="updateFiles" />
|
||||
</label>
|
||||
</div>
|
||||
<p class="text-xs leading-5 text-muted">
|
||||
<p class="text-xs leading-5 text-text-secondary">
|
||||
CSV and ZIP are supported
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -54,7 +54,7 @@ const updateTeamName = () => {
|
||||
<div class="text-text-primary">
|
||||
{{ team.owner.name }}
|
||||
</div>
|
||||
<div class="text-muted text-sm">
|
||||
<div class="text-text-secondary text-sm">
|
||||
{{ team.owner.email }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -203,7 +203,7 @@ function deleteSelected() {
|
||||
</div>
|
||||
<div
|
||||
v-else-if="allTimeEntriesLoaded"
|
||||
class="flex justify-center items-center py-5 text-muted font-medium">
|
||||
class="flex justify-center items-center py-5 text-text-secondary font-medium">
|
||||
All time entries are loaded!
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user