mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-10-31 13:41:09 -04:00 
			
		
		
		
	Compare commits
	
		
			7 Commits
		
	
	
		
			test-uffiz
			...
			dark-invoi
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 235fb5494d | |||
| 04c7ae39a2 | |||
| 18b5705372 | |||
| c61fbad5ce | |||
| 15f3f566e3 | |||
| 2e93082282 | |||
| ca55221c4f | 
| @ -15,6 +15,13 @@ | ||||
|       bg-gradient-to-r | ||||
|       from-primary-500 | ||||
|       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 | ||||
| @ -53,6 +60,7 @@ | ||||
|         cursor-pointer | ||||
|         md:hidden md:ml-0 | ||||
|         hover:bg-gray-100 | ||||
|         dark:bg-gray-800 dark:border-gray-500 dark:border | ||||
|       " | ||||
|       @click.prevent="onToggle" | ||||
|     > | ||||
|  | ||||
| @ -15,7 +15,9 @@ | ||||
|         leave-from="opacity-100" | ||||
|         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 | ||||
| @ -27,7 +29,9 @@ | ||||
|         leave-from="translate-x-0" | ||||
|         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 | ||||
|             as="template" | ||||
|             enter="ease-in-out duration-300" | ||||
| @ -40,18 +44,17 @@ | ||||
|             <div class="absolute top-0 right-0 pt-2 -mr-12"> | ||||
|               <button | ||||
|                 class=" | ||||
|                   flex | ||||
|                   items-center | ||||
|                   justify-center | ||||
|                   w-10 | ||||
|                   h-10 | ||||
|                   ml-1 | ||||
|                   rounded-full | ||||
|                   focus:outline-none | ||||
|                   focus:ring-2 | ||||
|                   focus:ring-inset | ||||
|                   focus:ring-white | ||||
|                 " | ||||
|                 flex | ||||
|                 items-center | ||||
|                 justify-center | ||||
|                 w-10 | ||||
|                 h-10 | ||||
|                 ml-1 | ||||
|                 rounded-full | ||||
|                 focus:outline-none | ||||
|                 focus:ring-2 | ||||
|                 focus:ring-inset | ||||
|                 focus:ring-white" | ||||
|                 @click="globalStore.setSidebarVisibility(false)" | ||||
|               > | ||||
|                 <span class="sr-only">Close sidebar</span> | ||||
| @ -82,8 +85,8 @@ | ||||
|                 :to="item.link" | ||||
|                 :class="[ | ||||
|                   hasActiveUrl(item.link) | ||||
|                     ? 'text-primary-500 border-primary-500 bg-gray-100 ' | ||||
|                     : 'text-black', | ||||
|                     ? '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 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', | ||||
|                 ]" | ||||
|                 @click="globalStore.setSidebarVisibility(false)" | ||||
| @ -100,6 +103,10 @@ | ||||
|                 /> | ||||
|                 {{ $t(item.title) }} | ||||
|               </router-link> | ||||
|               <LightDarkSwitch | ||||
|                 :show-label="false" | ||||
|                 class="absolute right-6 top-6 !w-auto" | ||||
|               /> | ||||
|             </nav> | ||||
|           </div> | ||||
|         </div> | ||||
| @ -113,17 +120,16 @@ | ||||
|   <!-- DESKTOP MENU --> | ||||
|   <div | ||||
|     class=" | ||||
|       hidden | ||||
|       w-56 | ||||
|       h-screen | ||||
|       pb-32 | ||||
|       overflow-y-auto | ||||
|       bg-white | ||||
|       border-r border-gray-200 border-solid | ||||
|       xl:w-64 | ||||
|       md:fixed md:flex md:flex-col md:inset-y-0 | ||||
|       pt-16 | ||||
|     " | ||||
|     hidden | ||||
|     w-56 | ||||
|     h-screen | ||||
|     bg-white | ||||
|     border-r border-gray-200 border-solid | ||||
|     xl:w-64 | ||||
|     md:fixed md:flex md:flex-col md:inset-y-0 | ||||
|     pt-16 | ||||
|     dark:border-gray-800 | ||||
|     dark:bg-gray-800/80" | ||||
|   > | ||||
|     <div | ||||
|       v-for="menu in globalStore.menuGroups" | ||||
| @ -136,8 +142,8 @@ | ||||
|         :to="item.link" | ||||
|         :class="[ | ||||
|           hasActiveUrl(item.link) | ||||
|             ? 'text-primary-500 border-primary-500 bg-gray-100 ' | ||||
|             : 'text-black', | ||||
|             ? '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 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', | ||||
|         ]" | ||||
|       > | ||||
| @ -145,8 +151,8 @@ | ||||
|           :name="item.icon" | ||||
|           :class="[ | ||||
|             hasActiveUrl(item.link) | ||||
|               ? 'text-primary-500 group-hover:text-primary-500 ' | ||||
|               : 'text-gray-400 group-hover:text-black', | ||||
|               ? '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 dark:text-gray-400 dark:group-hover:text-white', | ||||
|             'mr-4 shrink-0 h-5 w-5 ', | ||||
|           ]" | ||||
|         /> | ||||
| @ -154,6 +160,9 @@ | ||||
|         {{ $t(item.title) }} | ||||
|       </router-link> | ||||
|     </div> | ||||
|     <LightDarkSwitch | ||||
|       class="absolute bottom-0 py-4 border-t border-gray-200 dark:border-gray-700" | ||||
|     /> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| @ -169,6 +178,7 @@ import { | ||||
|  | ||||
| import { useRoute } from 'vue-router' | ||||
| import { useGlobalStore } from '@/scripts/admin/stores/global' | ||||
| import LightDarkSwitch from '@/scripts/components/LightDarkSwitcher.vue' | ||||
|  | ||||
| const route = useRoute() | ||||
| const globalStore = useGlobalStore() | ||||
|  | ||||
| @ -34,6 +34,7 @@ export const useGlobalStore = (useWindow = false) => { | ||||
|       isAppLoaded: false, | ||||
|       isSidebarOpen: false, | ||||
|       areCurrenciesLoading: false, | ||||
|       isDarkModeOn: false, | ||||
|  | ||||
|       downloadReport: null, | ||||
|     }), | ||||
| @ -70,8 +71,8 @@ export const useGlobalStore = (useWindow = false) => { | ||||
|               moduleStore.apiToken = response.data.global_settings.api_token | ||||
|               moduleStore.enableModules = response.data.modules | ||||
|  | ||||
|                 // company store | ||||
|                 companyStore.companies = response.data.companies | ||||
|               // company store | ||||
|               companyStore.companies = response.data.companies | ||||
|               companyStore.selectedCompany = response.data.current_company | ||||
|               companyStore.setSelectedCompany(response.data.current_company) | ||||
|               companyStore.selectedCompanySettings = | ||||
|  | ||||
| @ -1,46 +1,46 @@ | ||||
| <template> | ||||
|   <div class="bg-white shadow overflow-hidden rounded-lg mt-6"> | ||||
|   <div class="bg-white shadow overflow-hidden rounded-lg mt-6 dark:bg-gray-800"> | ||||
|     <div class="px-4 py-5 sm:px-6"> | ||||
|       <h3 class="text-lg leading-6 font-medium text-gray-900"> | ||||
|       <h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-gray-400"> | ||||
|         {{ $t('invoices.invoice_information') }} | ||||
|       </h3> | ||||
|     </div> | ||||
|     <div v-if="invoice" class="border-t border-gray-200 px-4 py-5 sm:p-0"> | ||||
|       <dl class="sm:divide-y sm:divide-gray-200"> | ||||
|       <dl class="sm:divide-y sm:divide-gray-200 dark:sm:divide-gray-500"> | ||||
|         <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> | ||||
|           <dt class="text-sm font-medium text-gray-500"> | ||||
|           <dt class="text-sm font-medium text-gray-500 dark:text-gray-400"> | ||||
|             {{ $t('general.from') }} | ||||
|           </dt> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2   dark:text-gray-100"> | ||||
|             {{ invoice.company.name }} | ||||
|           </dd> | ||||
|         </div> | ||||
|         <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> | ||||
|           <dt class="text-sm font-medium text-gray-500"> | ||||
|           <dt class="text-sm font-medium text-gray-500 dark:text-gray-400"> | ||||
|             {{ $t('general.to') }} | ||||
|           </dt> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2   dark:text-gray-100"> | ||||
|             {{ invoice.customer.name }} | ||||
|           </dd> | ||||
|         </div> | ||||
|         <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> | ||||
|           <dt class="text-sm font-medium text-gray-500 capitalize"> | ||||
|           <dt class="text-sm font-medium text-gray-500 capitalize dark:text-gray-400 "> | ||||
|             {{ $t('invoices.paid_status').toLowerCase() }} | ||||
|           </dt> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2 "> | ||||
|             <BaseInvoiceStatusBadge | ||||
|               :status="invoice.paid_status" | ||||
|               class="px-3 py-1" | ||||
|               class="px-3 py-1 dark:text-gray-400" | ||||
|             > | ||||
|               {{ invoice.paid_status }} | ||||
|             </BaseInvoiceStatusBadge> | ||||
|           </dd> | ||||
|         </div> | ||||
|         <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> | ||||
|           <dt class="text-sm font-medium text-gray-500"> | ||||
|           <dt class="text-sm font-medium text-gray-500 dark:text-gray-400"> | ||||
|             {{ $t('invoices.total') }} | ||||
|           </dt> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2 dark:border-gray-600 dark:bg-gray-700 dark:text-white"> | ||||
|             <BaseFormatMoney | ||||
|               :currency="invoice.currency" | ||||
|               :amount="invoice.total" | ||||
| @ -54,7 +54,7 @@ | ||||
|           <dt class="text-sm font-medium text-gray-500"> | ||||
|             {{ $t('invoices.notes') }} | ||||
|           </dt> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> | ||||
|           <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2 dark:text-gray-100" > | ||||
|             <span v-html="invoice.formatted_notes"></span> | ||||
|           </dd> | ||||
|         </div> | ||||
|  | ||||
							
								
								
									
										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> | ||||
| @ -1,5 +1,9 @@ | ||||
| <template> | ||||
|   <div class="bg-white rounded-lg shadow"> | ||||
|   <div | ||||
|     class="bg-white rounded-lg shadow dark:bg-gray-800 dark:text-white dark:shadow-glass dark:border dark:border-white/10 dark:bg-gray-800/70 relative" | ||||
|   > | ||||
|     <BaseDarkHighlight class="z-[-1] mt-10" /> | ||||
|  | ||||
|     <div | ||||
|       v-if="hasHeaderSlot" | ||||
|       class="px-5 py-4 text-black border-b border-gray-100 border-solid" | ||||
|  | ||||
							
								
								
									
										21
									
								
								resources/scripts/components/base/BaseDarkHighlight.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								resources/scripts/components/base/BaseDarkHighlight.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| <template> | ||||
|   <div | ||||
|     class=" | ||||
|       hidden | ||||
|       top-0 | ||||
|       w-full | ||||
|       absolute | ||||
|       ml-auto | ||||
|       mr-auto | ||||
|       left-0 | ||||
|       right-0 | ||||
|       text-center | ||||
|       h-full | ||||
|       rounded-full | ||||
|       bg-highlight/[.10] | ||||
|       blur-2xl | ||||
|       dark:block | ||||
|       z-[-1] | ||||
|     " | ||||
|   /> | ||||
| </template> | ||||
| @ -17,7 +17,7 @@ | ||||
|     <meta name="csrf-token" content="{{ csrf_token() }}"> | ||||
|  | ||||
|     <!-- 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 }}"> | ||||
|     @endforeach | ||||
|  | ||||
| @ -25,8 +25,8 @@ | ||||
| </head> | ||||
|  | ||||
| <body | ||||
|     class="h-full overflow-hidden bg-gray-100 font-base | ||||
|     @if(isset($current_theme)) theme-{{ $current_theme }} @else theme-{{get_app_setting('admin_portal_theme') ?? 'crater'}} @endif "> | ||||
|     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 "> | ||||
|  | ||||
|     <!-- Module Scripts --> | ||||
|     @foreach (\Crater\Services\Module\ModuleFacade::allScripts() as $name => $path) | ||||
| @ -38,6 +38,14 @@ | ||||
|     @endforeach | ||||
|  | ||||
|     <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)) | ||||
|  | ||||
|         window.customer_logo = "/storage/{{$customer_logo}}" | ||||
| @ -57,12 +65,12 @@ | ||||
|  | ||||
|         window.login_page_description = "{{$login_page_description}}" | ||||
|  | ||||
|         @endif      | ||||
|         @endif | ||||
|         @if(isset($copyright_text)) | ||||
|  | ||||
|         window.copyright_text = "{{$copyright_text}}" | ||||
|  | ||||
|         @endif     | ||||
|         @endif | ||||
|  | ||||
|         window.Crater.start() | ||||
|     </script> | ||||
|  | ||||
| @ -19,6 +19,7 @@ module.exports = { | ||||
|     './resources/scripts/**/*.js', | ||||
|     './resources/scripts/**/*.vue', | ||||
|   ], | ||||
|   darkMode: 'class', | ||||
|   theme: { | ||||
|     extend: { | ||||
|       colors: { | ||||
| @ -35,6 +36,7 @@ module.exports = { | ||||
|           900: withOpacityValue('--color-primary-900'), | ||||
|         }, | ||||
|         black: '#040405', | ||||
|         highlight: 'rgb(56, 189, 248)', | ||||
|         red: colors.red, | ||||
|         teal: colors.teal, | ||||
|         gray: colors.slate, | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	