mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-27 11:41:09 -04:00
Compare commits
2 Commits
dark-calen
...
dark-sideb
| Author | SHA1 | Date | |
|---|---|---|---|
| 2e93082282 | |||
| ca55221c4f |
@ -15,6 +15,13 @@
|
|||||||
bg-gradient-to-r
|
bg-gradient-to-r
|
||||||
from-primary-500
|
from-primary-500
|
||||||
to-primary-400
|
to-primary-400
|
||||||
|
dark:from-gray-700/70 dark:to-gray-800/70
|
||||||
|
bg-primary-500
|
||||||
|
dark:bg-transparent
|
||||||
|
dark:backdrop-blur-xl
|
||||||
|
dark:shadow-glass
|
||||||
|
dark:border
|
||||||
|
dark:border-white/10
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
@ -53,6 +60,7 @@
|
|||||||
cursor-pointer
|
cursor-pointer
|
||||||
md:hidden md:ml-0
|
md:hidden md:ml-0
|
||||||
hover:bg-gray-100
|
hover:bg-gray-100
|
||||||
|
dark:bg-gray-800 dark:border-gray-500 dark:border
|
||||||
"
|
"
|
||||||
@click.prevent="onToggle"
|
@click.prevent="onToggle"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -15,7 +15,9 @@
|
|||||||
leave-from="opacity-100"
|
leave-from="opacity-100"
|
||||||
leave-to="opacity-0"
|
leave-to="opacity-0"
|
||||||
>
|
>
|
||||||
<DialogOverlay class="fixed inset-0 bg-gray-600 bg-opacity-75" />
|
<DialogOverlay
|
||||||
|
class="fixed inset-0 bg-gray-600 bg-opacity-75 dark:bg-gray-900/90"
|
||||||
|
/>
|
||||||
</TransitionChild>
|
</TransitionChild>
|
||||||
|
|
||||||
<TransitionChild
|
<TransitionChild
|
||||||
@ -27,7 +29,9 @@
|
|||||||
leave-from="translate-x-0"
|
leave-from="translate-x-0"
|
||||||
leave-to="-translate-x-full"
|
leave-to="-translate-x-full"
|
||||||
>
|
>
|
||||||
<div class="relative flex flex-col flex-1 w-full max-w-xs bg-white">
|
<div
|
||||||
|
class="relative flex flex-col flex-1 w-full max-w-xs bg-white dark:bg-gray-800"
|
||||||
|
>
|
||||||
<TransitionChild
|
<TransitionChild
|
||||||
as="template"
|
as="template"
|
||||||
enter="ease-in-out duration-300"
|
enter="ease-in-out duration-300"
|
||||||
@ -40,18 +44,17 @@
|
|||||||
<div class="absolute top-0 right-0 pt-2 -mr-12">
|
<div class="absolute top-0 right-0 pt-2 -mr-12">
|
||||||
<button
|
<button
|
||||||
class="
|
class="
|
||||||
flex
|
flex
|
||||||
items-center
|
items-center
|
||||||
justify-center
|
justify-center
|
||||||
w-10
|
w-10
|
||||||
h-10
|
h-10
|
||||||
ml-1
|
ml-1
|
||||||
rounded-full
|
rounded-full
|
||||||
focus:outline-none
|
focus:outline-none
|
||||||
focus:ring-2
|
focus:ring-2
|
||||||
focus:ring-inset
|
focus:ring-inset
|
||||||
focus:ring-white
|
focus:ring-white"
|
||||||
"
|
|
||||||
@click="globalStore.setSidebarVisibility(false)"
|
@click="globalStore.setSidebarVisibility(false)"
|
||||||
>
|
>
|
||||||
<span class="sr-only">Close sidebar</span>
|
<span class="sr-only">Close sidebar</span>
|
||||||
@ -82,8 +85,8 @@
|
|||||||
:to="item.link"
|
:to="item.link"
|
||||||
:class="[
|
:class="[
|
||||||
hasActiveUrl(item.link)
|
hasActiveUrl(item.link)
|
||||||
? 'text-primary-500 border-primary-500 bg-gray-100 '
|
? 'text-primary-500 border-primary-500 bg-gray-100 dark:shadow-glass dark:backdrop-blur-xl dark:hover:bg-gray-700 dark:bg-gray-700/50 dark:text-primary-400 dark:font-medium'
|
||||||
: 'text-black',
|
: 'text-black dark:text-gray-300',
|
||||||
'cursor-pointer px-0 pl-4 py-3 border-transparent flex items-center border-l-4 border-solid text-sm not-italic font-medium',
|
'cursor-pointer px-0 pl-4 py-3 border-transparent flex items-center border-l-4 border-solid text-sm not-italic font-medium',
|
||||||
]"
|
]"
|
||||||
@click="globalStore.setSidebarVisibility(false)"
|
@click="globalStore.setSidebarVisibility(false)"
|
||||||
@ -100,6 +103,10 @@
|
|||||||
/>
|
/>
|
||||||
{{ $t(item.title) }}
|
{{ $t(item.title) }}
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<LightDarkSwitch
|
||||||
|
:show-label="false"
|
||||||
|
class="absolute right-6 top-6 !w-auto"
|
||||||
|
/>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -113,17 +120,16 @@
|
|||||||
<!-- DESKTOP MENU -->
|
<!-- DESKTOP MENU -->
|
||||||
<div
|
<div
|
||||||
class="
|
class="
|
||||||
hidden
|
hidden
|
||||||
w-56
|
w-56
|
||||||
h-screen
|
h-screen
|
||||||
pb-32
|
bg-white
|
||||||
overflow-y-auto
|
border-r border-gray-200 border-solid
|
||||||
bg-white
|
xl:w-64
|
||||||
border-r border-gray-200 border-solid
|
md:fixed md:flex md:flex-col md:inset-y-0
|
||||||
xl:w-64
|
pt-16
|
||||||
md:fixed md:flex md:flex-col md:inset-y-0
|
dark:border-gray-800
|
||||||
pt-16
|
dark:bg-gray-800/80"
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="menu in globalStore.menuGroups"
|
v-for="menu in globalStore.menuGroups"
|
||||||
@ -136,8 +142,8 @@
|
|||||||
:to="item.link"
|
:to="item.link"
|
||||||
:class="[
|
:class="[
|
||||||
hasActiveUrl(item.link)
|
hasActiveUrl(item.link)
|
||||||
? 'text-primary-500 border-primary-500 bg-gray-100 '
|
? 'text-primary-500 border-primary-500 bg-gray-100 dark:border-primary-400 dark:shadow-glass dark:backdrop-blur-xl dark:hover:bg-gray-700 dark:bg-gray-700/50 dark:text-primary-400 dark:font-medium'
|
||||||
: 'text-black',
|
: 'text-black dark:hover:bg-transparent dark:hover:text-white dark:text-gray-300',
|
||||||
'cursor-pointer px-0 pl-6 hover:bg-gray-50 py-3 group flex items-center border-l-4 border-solid border-transparent text-sm not-italic font-medium',
|
'cursor-pointer px-0 pl-6 hover:bg-gray-50 py-3 group flex items-center border-l-4 border-solid border-transparent text-sm not-italic font-medium',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
@ -145,8 +151,8 @@
|
|||||||
:name="item.icon"
|
:name="item.icon"
|
||||||
:class="[
|
:class="[
|
||||||
hasActiveUrl(item.link)
|
hasActiveUrl(item.link)
|
||||||
? 'text-primary-500 group-hover:text-primary-500 '
|
? 'text-primary-500 group-hover:text-primary-500 dark:text-primary-400 dark:group-hover:text-primary-500 '
|
||||||
: 'text-gray-400 group-hover:text-black',
|
: 'text-gray-400 group-hover:text-black dark:text-gray-400 dark:group-hover:text-white',
|
||||||
'mr-4 shrink-0 h-5 w-5 ',
|
'mr-4 shrink-0 h-5 w-5 ',
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
@ -154,6 +160,9 @@
|
|||||||
{{ $t(item.title) }}
|
{{ $t(item.title) }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
<LightDarkSwitch
|
||||||
|
class="absolute bottom-0 py-4 border-t border-gray-200 dark:border-gray-700"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -169,6 +178,7 @@ import {
|
|||||||
|
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useGlobalStore } from '@/scripts/admin/stores/global'
|
import { useGlobalStore } from '@/scripts/admin/stores/global'
|
||||||
|
import LightDarkSwitch from '@/scripts/components/LightDarkSwitcher.vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const globalStore = useGlobalStore()
|
const globalStore = useGlobalStore()
|
||||||
|
|||||||
@ -34,6 +34,7 @@ export const useGlobalStore = (useWindow = false) => {
|
|||||||
isAppLoaded: false,
|
isAppLoaded: false,
|
||||||
isSidebarOpen: false,
|
isSidebarOpen: false,
|
||||||
areCurrenciesLoading: false,
|
areCurrenciesLoading: false,
|
||||||
|
isDarkModeOn: false,
|
||||||
|
|
||||||
downloadReport: null,
|
downloadReport: null,
|
||||||
}),
|
}),
|
||||||
@ -70,8 +71,8 @@ export const useGlobalStore = (useWindow = false) => {
|
|||||||
moduleStore.apiToken = response.data.global_settings.api_token
|
moduleStore.apiToken = response.data.global_settings.api_token
|
||||||
moduleStore.enableModules = response.data.modules
|
moduleStore.enableModules = response.data.modules
|
||||||
|
|
||||||
// company store
|
// company store
|
||||||
companyStore.companies = response.data.companies
|
companyStore.companies = response.data.companies
|
||||||
companyStore.selectedCompany = response.data.current_company
|
companyStore.selectedCompany = response.data.current_company
|
||||||
companyStore.setSelectedCompany(response.data.current_company)
|
companyStore.setSelectedCompany(response.data.current_company)
|
||||||
companyStore.selectedCompanySettings =
|
companyStore.selectedCompanySettings =
|
||||||
|
|||||||
101
resources/scripts/components/LightDarkSwitcher.vue
Normal file
101
resources/scripts/components/LightDarkSwitcher.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<!-- This example requires Tailwind CSS v2.0+ -->
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { Switch, SwitchGroup, SwitchLabel } from '@headlessui/vue'
|
||||||
|
import { useGlobalStore } from '@/scripts/admin/stores/global'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
defineProps({
|
||||||
|
showLabel: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
vertical: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const globalStore = useGlobalStore()
|
||||||
|
|
||||||
|
const enabled = ref(
|
||||||
|
localStorage.getItem('theme') === 'dark' ||
|
||||||
|
document.documentElement.classList.contains('dark')
|
||||||
|
)
|
||||||
|
|
||||||
|
globalStore.isDarkModeOn = enabled
|
||||||
|
|
||||||
|
function onChange(val) {
|
||||||
|
if (val) {
|
||||||
|
localStorage.theme = 'dark'
|
||||||
|
document.documentElement.classList.add('dark')
|
||||||
|
document.documentElement.style.setProperty('color-scheme', 'dark')
|
||||||
|
globalStore.isDarkModeOn = true
|
||||||
|
} else {
|
||||||
|
localStorage.theme = 'light'
|
||||||
|
document.documentElement.classList.remove('dark')
|
||||||
|
document.documentElement.style.setProperty('color-scheme', 'light')
|
||||||
|
globalStore.isDarkModeOn = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="w-full flex justify-center">
|
||||||
|
<SwitchGroup
|
||||||
|
as="div"
|
||||||
|
class="flex items-center"
|
||||||
|
:class="vertical ? 'flex-col justify-center' : 'flex-row'"
|
||||||
|
>
|
||||||
|
<Switch
|
||||||
|
v-model="enabled"
|
||||||
|
class="relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 dark:ring-offset-gray-700"
|
||||||
|
:class="[enabled ? 'bg-primary-600' : 'bg-gray-200']"
|
||||||
|
@update:modelValue="onChange"
|
||||||
|
>
|
||||||
|
<span class="sr-only">Use setting</span>
|
||||||
|
<span
|
||||||
|
class="pointer-events-none relative inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200"
|
||||||
|
:class="[enabled ? 'translate-x-5' : 'translate-x-0']"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
|
||||||
|
:class="[
|
||||||
|
enabled
|
||||||
|
? 'opacity-0 ease-out duration-100'
|
||||||
|
: 'opacity-100 ease-in duration-200',
|
||||||
|
]"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<BaseIcon class="h-3 w-3 text-yellow-500" name="SunIcon" />
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
|
||||||
|
:class="[
|
||||||
|
enabled
|
||||||
|
? 'opacity-100 ease-in duration-200'
|
||||||
|
: 'opacity-0 ease-out duration-100',
|
||||||
|
]"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<BaseIcon class="h-3 w-3 text-primary-500" name="MoonIcon" />
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</Switch>
|
||||||
|
<SwitchLabel
|
||||||
|
v-if="showLabel"
|
||||||
|
as="span"
|
||||||
|
class="cursor-pointer"
|
||||||
|
:class="vertical ? 'px-1 text-center mt-2' : 'ml-3'"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="enabled"
|
||||||
|
class="text-sm font-medium text-gray-500 dark:text-gray-400"
|
||||||
|
>
|
||||||
|
Dark Mode
|
||||||
|
</span>
|
||||||
|
<span v-else class="text-sm font-medium text-gray-500">
|
||||||
|
Light Mode
|
||||||
|
</span>
|
||||||
|
</SwitchLabel>
|
||||||
|
</SwitchGroup>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||||
|
|
||||||
<!-- Module Styles -->
|
<!-- Module Styles -->
|
||||||
@foreach(\Crater\Services\Module\ModuleFacade::allStyles() as $name => $path)
|
@foreach (\Crater\Services\Module\ModuleFacade::allStyles() as $name => $path)
|
||||||
<link rel="stylesheet" href="/modules/styles/{{ $name }}">
|
<link rel="stylesheet" href="/modules/styles/{{ $name }}">
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
@ -25,8 +25,8 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body
|
<body
|
||||||
class="h-full overflow-hidden bg-gray-100 font-base
|
class="h-full overflow-hidden bg-gray-100 dark:bg-gray-900 dark:text-white font-base
|
||||||
@if(isset($current_theme)) theme-{{ $current_theme }} @else theme-{{get_app_setting('admin_portal_theme') ?? 'crater'}} @endif ">
|
@if (isset($current_theme)) theme-{{ $current_theme }} @else theme-{{ get_app_setting('admin_portal_theme') ?? 'crater' }} @endif ">
|
||||||
|
|
||||||
<!-- Module Scripts -->
|
<!-- Module Scripts -->
|
||||||
@foreach (\Crater\Services\Module\ModuleFacade::allScripts() as $name => $path)
|
@foreach (\Crater\Services\Module\ModuleFacade::allScripts() as $name => $path)
|
||||||
@ -38,6 +38,14 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
|
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||||
|
document.documentElement.classList.add('dark')
|
||||||
|
document.documentElement.style.setProperty('color-scheme', 'dark');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark')
|
||||||
|
document.documentElement.style.setProperty('color-scheme', 'light')
|
||||||
|
}
|
||||||
|
|
||||||
@if(isset($customer_logo))
|
@if(isset($customer_logo))
|
||||||
|
|
||||||
window.customer_logo = "/storage/{{$customer_logo}}"
|
window.customer_logo = "/storage/{{$customer_logo}}"
|
||||||
@ -57,12 +65,12 @@
|
|||||||
|
|
||||||
window.login_page_description = "{{$login_page_description}}"
|
window.login_page_description = "{{$login_page_description}}"
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
@if(isset($copyright_text))
|
@if(isset($copyright_text))
|
||||||
|
|
||||||
window.copyright_text = "{{$copyright_text}}"
|
window.copyright_text = "{{$copyright_text}}"
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
window.Crater.start()
|
window.Crater.start()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -19,6 +19,7 @@ module.exports = {
|
|||||||
'./resources/scripts/**/*.js',
|
'./resources/scripts/**/*.js',
|
||||||
'./resources/scripts/**/*.vue',
|
'./resources/scripts/**/*.vue',
|
||||||
],
|
],
|
||||||
|
darkMode: 'class',
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
|
|||||||
Reference in New Issue
Block a user