mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-14 19:22:14 +01:00
add light mode
This commit is contained in:
@@ -13,7 +13,7 @@ defineProps<{
|
||||
<template>
|
||||
<AppLayout title="API Tokens">
|
||||
<template #header>
|
||||
<h2 class="font-semibold text-xl text-white leading-tight">
|
||||
<h2 class="font-semibold text-xl text-text-primary leading-tight">
|
||||
API Tokens
|
||||
</h2>
|
||||
</template>
|
||||
|
||||
@@ -173,7 +173,7 @@ const deleteApiToken = () => {
|
||||
v-for="token in tokens"
|
||||
:key="token.id"
|
||||
class="flex items-center justify-between">
|
||||
<div class="break-all text-white">
|
||||
<div class="break-all text-text-primary">
|
||||
{{ token.name }}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ const page = usePage<{
|
||||
<Link
|
||||
class="py-8 text-muted text-sm font-medium opacity-90 hover:opacity-100 transition"
|
||||
:href="route('register')">
|
||||
No account yet? <span class="text-white">Register here!</span>
|
||||
No account yet? <span class="text-text-primary">Register here!</span>
|
||||
</Link>
|
||||
</template>
|
||||
|
||||
@@ -89,7 +89,7 @@ const page = usePage<{
|
||||
<Link
|
||||
v-if="canResetPassword"
|
||||
:href="route('password.request')"
|
||||
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-muted hover:text-text-primary rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||
Forgot your password?
|
||||
</Link>
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ const page = usePage<{
|
||||
class="py-8 text-muted text-sm font-medium opacity-90 hover:opacity-100 transition"
|
||||
:href="route('login')">
|
||||
Already have an account?
|
||||
<span class="text-white">Login here!</span>
|
||||
<span class="text-text-primary">Login here!</span>
|
||||
</Link>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ const closeModal = () => {
|
||||
<div>
|
||||
<svg
|
||||
v-if="session.agent.is_desktop"
|
||||
class="w-8 h-8 text-white"
|
||||
class="w-8 h-8 text-text-primary"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -98,7 +98,7 @@ const closeModal = () => {
|
||||
</div>
|
||||
|
||||
<div class="ms-3">
|
||||
<div class="text-sm text-white font-medium">
|
||||
<div class="text-sm text-text-primary font-medium">
|
||||
{{
|
||||
session.agent.platform
|
||||
? session.agent.platform
|
||||
|
||||
45
resources/js/Pages/Profile/Partials/ThemeForm.vue
Normal file
45
resources/js/Pages/Profile/Partials/ThemeForm.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
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()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FormSection>
|
||||
<template #title> Theme</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
|
||||
id="theme"
|
||||
v-model="themeSetting"
|
||||
name="theme"
|
||||
required
|
||||
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="system">System</option>
|
||||
<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">
|
||||
System default: {{ preferredColor }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</FormSection>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -208,7 +208,7 @@ const page = usePage<{
|
||||
v-model="form.timezone"
|
||||
name="timezone"
|
||||
required
|
||||
class="mt-1 block w-full border-input-border bg-input-background text-white focus:border-input-border-active rounded-md shadow-sm">
|
||||
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
|
||||
@@ -229,7 +229,26 @@ const page = usePage<{
|
||||
v-model="form.week_start"
|
||||
name="week_start"
|
||||
required
|
||||
class="mt-1 block w-full border-input-border bg-input-background text-white focus:border-input-border-active rounded-md shadow-sm">
|
||||
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"
|
||||
:key="weekdayKey"
|
||||
:value="weekdayKey">
|
||||
{{ weekdayTranslated }}
|
||||
</option>
|
||||
</select>
|
||||
<InputError :message="form.errors.week_start" class="mt-2" />
|
||||
</div>
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<InputLabel for="week_start" value="Start of the week" />
|
||||
<select
|
||||
id="week_start"
|
||||
v-model="form.week_start"
|
||||
name="week_start"
|
||||
required
|
||||
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
|
||||
|
||||
@@ -10,6 +10,7 @@ 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";
|
||||
|
||||
defineProps<{
|
||||
confirmsTwoFactorAuthentication: boolean;
|
||||
@@ -32,7 +33,7 @@ const page = usePage<{
|
||||
<template>
|
||||
<AppLayout title="Profile">
|
||||
<template #header>
|
||||
<h2 class="font-semibold text-xl text-white leading-tight">
|
||||
<h2 class="font-semibold text-xl text-text-primary leading-tight">
|
||||
Profile
|
||||
</h2>
|
||||
</template>
|
||||
@@ -46,6 +47,12 @@ const page = usePage<{
|
||||
<SectionBorder />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ThemeForm />
|
||||
|
||||
<SectionBorder />
|
||||
</div>
|
||||
|
||||
<div v-if="page.props.jetstream.canUpdatePassword">
|
||||
<UpdatePasswordForm class="mt-10 sm:mt-0" />
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ const shownTasks = computed(() => {
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
class="flex items-center space-x-3 text-white font-bold text-base">
|
||||
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"
|
||||
aria-hidden="true" />
|
||||
|
||||
@@ -410,7 +410,7 @@ const tableData = computed(() => {
|
||||
<div
|
||||
class="col-span-3 bg-card-background rounded-lg border border-card-border pt-3">
|
||||
<div
|
||||
class="text-sm flex text-white items-center space-x-3 font-medium px-6 border-b border-card-background-separator pb-3">
|
||||
class="text-sm flex text-text-primary items-center space-x-3 font-medium px-6 border-b border-card-background-separator pb-3">
|
||||
<span>Group by</span>
|
||||
<ReportingGroupBySelect
|
||||
v-model="group"
|
||||
@@ -476,7 +476,7 @@ const tableData = computed(() => {
|
||||
<div
|
||||
v-else
|
||||
class="chart flex flex-col items-center justify-center py-12 col-span-3">
|
||||
<p class="text-lg text-white font-semibold">
|
||||
<p class="text-lg text-text-primary font-semibold">
|
||||
No time entries found
|
||||
</p>
|
||||
<p>Try to change the filters and time range</p>
|
||||
|
||||
@@ -421,7 +421,7 @@ async function downloadExport(format: ExportFormat) {
|
||||
<div class="text-center pt-12">
|
||||
<ClockIcon
|
||||
class="w-8 text-icon-default inline pb-2"></ClockIcon>
|
||||
<h3 class="text-white font-semibold">
|
||||
<h3 class="text-text-primary font-semibold">
|
||||
No time entries found
|
||||
</h3>
|
||||
<p class="pb-5">
|
||||
@@ -493,6 +493,6 @@ async function downloadExport(format: ExportFormat) {
|
||||
@apply bg-secondary h-8 w-8 flex items-center justify-center rounded border border-border-tertiary text-text-secondary hover:text-text-primary transition cursor-pointer hover:border-border-secondary hover:bg-secondary focus-visible:text-text-primary focus-visible:outline-0 focus-visible:ring-2 focus-visible:ring-ring;
|
||||
}
|
||||
.pagination-item[data-selected] {
|
||||
@apply text-white bg-accent-300/10 border border-accent-300/20 rounded-md font-medium hover:bg-accent-300/20 active:bg-accent-300/20 outline-0 focus-visible:ring-2 focus:ring-ring transition ease-in-out duration-150;
|
||||
@apply text-text-primary bg-accent-300/10 border border-accent-300/20 rounded-md font-medium hover:bg-accent-300/20 active:bg-accent-300/20 outline-0 focus-visible:ring-2 focus:ring-ring transition ease-in-out duration-150;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -181,6 +181,6 @@ watch(currentPage, () => {
|
||||
@apply bg-secondary h-8 w-8 flex items-center justify-center rounded border border-border-tertiary text-text-secondary hover:text-text-primary transition cursor-pointer hover:border-border-secondary hover:bg-secondary focus-visible:text-text-primary focus-visible:outline-0 focus-visible:ring-2 focus-visible:ring-ring;
|
||||
}
|
||||
.pagination-item[data-selected] {
|
||||
@apply text-white bg-accent-300/10 border border-accent-300/20 rounded-md font-medium hover:bg-accent-300/20 active:bg-accent-300/20 outline-0 focus-visible:ring-2 focus:ring-ring transition ease-in-out duration-150;
|
||||
@apply text-text-primary bg-accent-300/10 border border-accent-300/20 rounded-md font-medium hover:bg-accent-300/20 active:bg-accent-300/20 outline-0 focus-visible:ring-2 focus:ring-ring transition ease-in-out duration-150;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -162,7 +162,7 @@ function getGroupLabel(key: string) {
|
||||
<div
|
||||
class="col-span-3 bg-card-background rounded-lg border border-card-border pt-3">
|
||||
<div
|
||||
class="text-sm flex text-white items-center font-medium px-6 border-b border-card-background-separator pb-3">
|
||||
class="text-sm flex text-text-primary items-center font-medium px-6 border-b border-card-background-separator pb-3">
|
||||
Group by
|
||||
<strong class="px-2">{{ getGroupLabel(group) }}</strong>
|
||||
and
|
||||
@@ -219,7 +219,7 @@ function getGroupLabel(key: string) {
|
||||
<div
|
||||
v-else
|
||||
class="chart flex flex-col items-center justify-center py-12 col-span-3">
|
||||
<p class="text-lg text-white font-semibold">
|
||||
<p class="text-lg text-text-primary font-semibold">
|
||||
No time entries found
|
||||
</p>
|
||||
<p>Try to change the filters and time range</p>
|
||||
|
||||
@@ -6,7 +6,7 @@ import CreateTeamForm from '@/Pages/Teams/Partials/CreateTeamForm.vue';
|
||||
<template>
|
||||
<AppLayout title="Create Organization">
|
||||
<template #header>
|
||||
<h2 class="font-semibold text-xl text-white leading-tight">
|
||||
<h2 class="font-semibold text-xl text-text-primary leading-tight">
|
||||
Create Organization
|
||||
</h2>
|
||||
</template>
|
||||
|
||||
@@ -47,7 +47,7 @@ const page = usePage<{
|
||||
:alt="page.props.auth.user.name" />
|
||||
|
||||
<div class="ms-4 leading-tight">
|
||||
<div class="text-white">
|
||||
<div class="text-text-primary">
|
||||
{{ page.props.auth.user.name }}
|
||||
</div>
|
||||
<div class="text-sm text-muted">
|
||||
|
||||
@@ -89,7 +89,7 @@ async function exportData() {
|
||||
</Card>
|
||||
<Card>
|
||||
<div
|
||||
class="py-6 flex-col bg-card-background items-center flex space-y-5 text-center text-sm">
|
||||
class="py-6 flex-col items-center flex space-y-5 text-center text-sm">
|
||||
<div>
|
||||
The following organization will be exported: <br />
|
||||
<strong class="font-semibold">{{
|
||||
|
||||
@@ -142,7 +142,7 @@ const showResultModal = ref(false);
|
||||
|
||||
<div
|
||||
class="py-2.5 px-3 border-t border-t-card-background-separator">
|
||||
<span class="text-white font-semibold">Clients created:</span>
|
||||
<span class="text-text-primary font-semibold">Clients created:</span>
|
||||
{{ reportResult?.report.clients.created }}
|
||||
</div>
|
||||
<div
|
||||
@@ -187,14 +187,14 @@ const showResultModal = ref(false);
|
||||
|
||||
<Card>
|
||||
<div
|
||||
class="px-4 py-5 sm:px-5 bg-card-background shadow sm:rounded-tl-md sm:rounded-tr-md">
|
||||
class="px-4 py-5 sm:px-5">
|
||||
<div>
|
||||
<InputLabel for="importType" value="Import Type" />
|
||||
<select
|
||||
id="importType"
|
||||
v-model="importType"
|
||||
name="importType"
|
||||
class="mt-1 block w-full border-input-border bg-input-background text-white focus:border-input-border-active rounded-md shadow-sm">
|
||||
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="null" selected disabled>
|
||||
Select an import type to get instructions...
|
||||
</option>
|
||||
@@ -218,7 +218,7 @@ const showResultModal = ref(false);
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="mt-2 flex justify-center rounded-lg border border-dashed border-white/30 px-6 py-10">
|
||||
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"
|
||||
@@ -227,7 +227,7 @@ const showResultModal = ref(false);
|
||||
<div class="mt-4 flex text-sm leading-6 text-muted">
|
||||
<label
|
||||
for="file-upload"
|
||||
class="relative cursor-pointer rounded-md bg-gray-900 font-semibold text-white 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">
|
||||
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">
|
||||
<span v-if="files">{{ filenames }}</span>
|
||||
<span v-else
|
||||
>Upload a Toggl/Clockify Export</span
|
||||
|
||||
@@ -191,7 +191,7 @@ const displayableRole = (role: string) => {
|
||||
<!-- Role Name -->
|
||||
<div class="flex items-center">
|
||||
<div
|
||||
class="text-sm text-white"
|
||||
class="text-sm text-text-primary"
|
||||
:class="{
|
||||
'font-semibold':
|
||||
addTeamMemberForm.role ==
|
||||
|
||||
@@ -51,7 +51,7 @@ const updateTeamName = () => {
|
||||
:alt="team.owner.name" />
|
||||
|
||||
<div class="ms-4 leading-tight">
|
||||
<div class="text-white">
|
||||
<div class="text-text-primary">
|
||||
{{ team.owner.name }}
|
||||
</div>
|
||||
<div class="text-muted text-sm">
|
||||
@@ -93,7 +93,7 @@ const updateTeamName = () => {
|
||||
v-model="form.currency"
|
||||
name="currency"
|
||||
:disabled="!permissions.canUpdateTeam"
|
||||
class="mt-1 block w-full border-input-border bg-input-background text-white focus:border-input-border-active rounded-md shadow-sm">
|
||||
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 currency</option>
|
||||
<option
|
||||
v-for="(currencyTranslated, currencyKey) in $page.props
|
||||
|
||||
@@ -18,7 +18,7 @@ defineProps<{
|
||||
<template>
|
||||
<AppLayout title="Organization Settings">
|
||||
<template #header>
|
||||
<h2 class="font-semibold text-xl text-white leading-tight">
|
||||
<h2 class="font-semibold text-xl text-text-primary leading-tight">
|
||||
Organization Settings
|
||||
</h2>
|
||||
</template>
|
||||
|
||||
@@ -132,7 +132,7 @@ function deleteSelected() {
|
||||
:clients></TimeEntryCreateModal>
|
||||
<AppLayout title="Dashboard" data-testid="time_view">
|
||||
<MainContainer
|
||||
class="pt-5 lg:pt-8 pb-4 lg:pb-6 border-b border-default-background-separator">
|
||||
class="pt-5 lg:pt-8 pb-4 lg:pb-6">
|
||||
<div
|
||||
class="lg:flex items-end lg:divide-x divide-default-background-separator divide-y lg:divide-y-0 space-y-2 lg:space-y-0 lg:space-x-2">
|
||||
<div class="flex-1">
|
||||
@@ -191,13 +191,13 @@ function deleteSelected() {
|
||||
:tags="tags"></TimeEntryGroupedTable>
|
||||
<div v-if="timeEntries.length === 0" class="text-center pt-12">
|
||||
<ClockIcon class="w-8 text-icon-default inline pb-2"></ClockIcon>
|
||||
<h3 class="text-white font-semibold">No time entries found</h3>
|
||||
<h3 class="text-text-primary font-semibold">No time entries found</h3>
|
||||
<p class="pb-5">Create your first time entry now!</p>
|
||||
</div>
|
||||
<div ref="loadMoreContainer">
|
||||
<div
|
||||
v-if="loading && !allTimeEntriesLoaded"
|
||||
class="flex justify-center items-center py-5 text-white font-medium">
|
||||
class="flex justify-center items-center py-5 text-text-primary font-medium">
|
||||
<LoadingSpinner></LoadingSpinner>
|
||||
<span> Loading more time entries... </span>
|
||||
</div>
|
||||
|
||||
@@ -23,21 +23,21 @@ const user = computed(() => page?.props?.auth?.user);
|
||||
<Head title="Welcome" />
|
||||
|
||||
<div
|
||||
class="relative sm:flex sm:justify-center sm:items-center min-h-screen bg-dots-darker bg-center bg-gray-100 dark:bg-dots-lighter dark:bg-gray-900 selection:bg-red-500 selection:text-white">
|
||||
class="relative sm:flex sm:justify-center sm:items-center min-h-screen bg-dots-darker bg-center bg-gray-100 dark:bg-dots-lighter dark:bg-gray-900 selection:bg-red-500 selection:text-text-primary">
|
||||
<div
|
||||
v-if="canLogin"
|
||||
class="sm:fixed sm:top-0 sm:end-0 p-6 text-end z-10">
|
||||
<Link
|
||||
v-if="user"
|
||||
:href="route('dashboard')"
|
||||
class="font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500"
|
||||
class="font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-text-primary focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500"
|
||||
>Dashboard</Link
|
||||
>
|
||||
|
||||
<template v-else>
|
||||
<Link
|
||||
:href="route('login')"
|
||||
class="font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500"
|
||||
class="font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-text-primary focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500"
|
||||
>Log in</Link
|
||||
>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user