mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-10-29 04:31:08 -04:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			dark-wizar
			...
			fix-logout
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bdf8fa8b5a | |||
| ba298cdb0a | |||
| 05d5ce26fd | |||
| 393fe20010 | |||
| 57bdbd2897 | 
							
								
								
									
										9
									
								
								.github/workflows/uffizzi-build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.github/workflows/uffizzi-build.yml
									
									
									
									
										vendored
									
									
								
							| @ -14,8 +14,6 @@ jobs: | ||||
|     steps: | ||||
|       - name: Checkout git repo | ||||
|         uses: actions/checkout@v3 | ||||
|       - name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2         | ||||
|       - name: Generate UUID image name | ||||
|         id: uuid | ||||
|         run: echo "UUID_TAG_APP=$(uuidgen)" >> $GITHUB_ENV | ||||
| @ -33,11 +31,10 @@ jobs: | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           labels: ${{ steps.meta.outputs.labels }} | ||||
|           file: ./uffizzi/Dockerfile | ||||
|           cache-from: type=gha | ||||
|           cache-to: type=gha,mode=max | ||||
|  | ||||
|  | ||||
|   build-nginx: | ||||
|     needs:  | ||||
|       - build-application | ||||
|     name: Build and Push `nginx` | ||||
|     runs-on: ubuntu-latest | ||||
|     if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }} | ||||
| @ -65,6 +62,8 @@ jobs: | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           labels: ${{ steps.meta.outputs.labels }} | ||||
|           file: ./uffizzi/nginx/Dockerfile | ||||
|           build-args: | | ||||
|             BASE_IMAGE=${{ needs.build-application.outputs.tags }} | ||||
|           cache-from: type=gha | ||||
|           cache-to: type=gha,mode=max | ||||
|  | ||||
|  | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -16,4 +16,5 @@ Homestead.yaml | ||||
| .gitkeep | ||||
| /public/docs | ||||
| /.scribe | ||||
| !storage/fonts/.gitkeep | ||||
| !storage/fonts/.gitkeep | ||||
| .DS_Store | ||||
|  | ||||
| @ -55,7 +55,7 @@ class CreateTemplateCommand extends Command | ||||
|         copy(public_path("/build/img/PDF/{$type}1.png"), public_path("/build/img/PDF/{$templateName}.png")); | ||||
|         copy(resource_path("/static/img/PDF/{$type}1.png"), resource_path("/static/img/PDF/{$templateName}.png")); | ||||
|  | ||||
|         $path = resource_path("app/pdf/{$type}/{$templateName}.blade.php"); | ||||
|         $path = resource_path("views/app/pdf/{$type}/{$templateName}.blade.php"); | ||||
|         $type = ucfirst($type); | ||||
|         $this->info("{$type} Template created successfully at ".$path); | ||||
|  | ||||
|  | ||||
| @ -27,6 +27,7 @@ return [ | ||||
|             'tokenizer', | ||||
|             'JSON', | ||||
|             'cURL', | ||||
|             'zip', | ||||
|         ], | ||||
|         'apache' => [ | ||||
|             'mod_rewrite', | ||||
|  | ||||
| @ -35,16 +35,7 @@ | ||||
|       </div> | ||||
|  | ||||
|       <div | ||||
|         class=" | ||||
|           grid | ||||
|           col-span-12 | ||||
|           mt-6 | ||||
|           text-center | ||||
|           xl:mt-0 | ||||
|           sm:grid-cols-4 | ||||
|           xl:text-right xl:col-span-3 xl:grid-cols-1 | ||||
|           xxl:col-span-2 | ||||
|         " | ||||
|         class="grid col-span-12 mt-6 text-center xl:mt-0 sm:grid-cols-4 xl:text-right xl:col-span-3 xl:grid-cols-1 xxl:col-span-2" | ||||
|       > | ||||
|         <div class="px-6 py-2"> | ||||
|           <span class="text-xs leading-5 lg:text-sm"> | ||||
| @ -177,10 +168,12 @@ const getChartInvoices = computed(() => { | ||||
|   return [] | ||||
| }) | ||||
|  | ||||
| const customerId = computed(() => route.params.id) | ||||
|  | ||||
| watch( | ||||
|   route, | ||||
|   () => { | ||||
|     if (route.params.id) { | ||||
|   () => customerId.value, | ||||
|   (id) => { | ||||
|     if (id && route.name === 'customers.view') { | ||||
|       loadCustomer() | ||||
|     } | ||||
|     selectedYear.value = 'This year' | ||||
|  | ||||
| @ -37,32 +37,10 @@ | ||||
|  | ||||
|     <!-- Sidebar --> | ||||
|     <div | ||||
|       class=" | ||||
|         fixed | ||||
|         top-0 | ||||
|         left-0 | ||||
|         hidden | ||||
|         h-full | ||||
|         pt-16 | ||||
|         pb-[6.4rem] | ||||
|         ml-56 | ||||
|         bg-white | ||||
|         xl:ml-64 | ||||
|         w-88 | ||||
|         xl:block | ||||
|       " | ||||
|       class="fixed top-0 left-0 hidden h-full pt-16 pb-[6.4rem] ml-56 bg-white xl:ml-64 w-88 xl:block" | ||||
|     > | ||||
|       <div | ||||
|         class=" | ||||
|           flex | ||||
|           items-center | ||||
|           justify-between | ||||
|           px-4 | ||||
|           pt-8 | ||||
|           pb-2 | ||||
|           border border-gray-200 border-solid | ||||
|           height-full | ||||
|         " | ||||
|         class="flex items-center justify-between px-4 pt-8 pb-2 border border-gray-200 border-solid height-full" | ||||
|       > | ||||
|         <div class="mb-6"> | ||||
|           <BaseInput | ||||
| @ -92,14 +70,7 @@ | ||||
|             </template> | ||||
|  | ||||
|             <div | ||||
|               class=" | ||||
|                 px-4 | ||||
|                 py-1 | ||||
|                 pb-2 | ||||
|                 mb-1 mb-2 | ||||
|                 text-sm | ||||
|                 border-b border-gray-200 border-solid | ||||
|               " | ||||
|               class="px-4 py-1 pb-2 mb-1 mb-2 text-sm border-b border-gray-200 border-solid" | ||||
|             > | ||||
|               {{ $t('general.sort_by') }} | ||||
|             </div> | ||||
| @ -156,12 +127,7 @@ | ||||
|  | ||||
|       <div | ||||
|         ref="estimateListSection" | ||||
|         class=" | ||||
|           h-full | ||||
|           overflow-y-scroll | ||||
|           border-l border-gray-200 border-solid | ||||
|           base-scroll | ||||
|         " | ||||
|         class="h-full overflow-y-scroll border-l border-gray-200 border-solid base-scroll" | ||||
|       > | ||||
|         <div v-for="(estimate, index) in estimateList" :key="index"> | ||||
|           <router-link | ||||
| @ -181,29 +147,11 @@ | ||||
|               <BaseText | ||||
|                 :text="estimate.customer.name" | ||||
|                 :length="30" | ||||
|                 class=" | ||||
|                   pr-2 | ||||
|                   mb-2 | ||||
|                   text-sm | ||||
|                   not-italic | ||||
|                   font-normal | ||||
|                   leading-5 | ||||
|                   text-black | ||||
|                   capitalize | ||||
|                   truncate | ||||
|                 " | ||||
|                 class="pr-2 mb-2 text-sm not-italic font-normal leading-5 text-black capitalize truncate" | ||||
|               /> | ||||
|  | ||||
|               <div | ||||
|                 class=" | ||||
|                   mt-1 | ||||
|                   mb-2 | ||||
|                   text-xs | ||||
|                   not-italic | ||||
|                   font-medium | ||||
|                   leading-5 | ||||
|                   text-gray-600 | ||||
|                 " | ||||
|                 class="mt-1 mb-2 text-xs not-italic font-medium leading-5 text-gray-600" | ||||
|               > | ||||
|                 {{ estimate.estimate_number }} | ||||
|               </div> | ||||
| @ -220,26 +168,11 @@ | ||||
|               <BaseFormatMoney | ||||
|                 :amount="estimate.total" | ||||
|                 :currency="estimate.customer.currency" | ||||
|                 class=" | ||||
|                   block | ||||
|                   mb-2 | ||||
|                   text-xl | ||||
|                   not-italic | ||||
|                   font-semibold | ||||
|                   leading-8 | ||||
|                   text-right text-gray-900 | ||||
|                 " | ||||
|                 class="block mb-2 text-xl not-italic font-semibold leading-8 text-right text-gray-900" | ||||
|               /> | ||||
|  | ||||
|               <div | ||||
|                 class=" | ||||
|                   text-sm | ||||
|                   not-italic | ||||
|                   font-normal | ||||
|                   leading-5 | ||||
|                   text-right text-gray-600 | ||||
|                   est-date | ||||
|                 " | ||||
|                 class="text-sm not-italic font-normal leading-5 text-right text-gray-600 est-date" | ||||
|               > | ||||
|                 {{ estimate.formatted_estimate_date }} | ||||
|               </div> | ||||
| @ -264,13 +197,7 @@ | ||||
|     > | ||||
|       <iframe | ||||
|         :src="`${shareableLink}`" | ||||
|         class=" | ||||
|           flex-1 | ||||
|           border border-gray-400 border-solid | ||||
|           rounded-md | ||||
|           bg-white | ||||
|           frame-style | ||||
|         " | ||||
|         class="flex-1 border border-gray-400 border-solid rounded-md bg-white frame-style" | ||||
|       /> | ||||
|     </div> | ||||
|   </BasePage> | ||||
| @ -345,11 +272,14 @@ const getCurrentEstimateId = computed(() => { | ||||
|   return null | ||||
| }) | ||||
|  | ||||
| watch(route, (to, from) => { | ||||
|   if (to.name === 'estimates.view') { | ||||
|     loadEstimate() | ||||
| const estimateId = computed(() => route.params.id) | ||||
|  | ||||
| watch( | ||||
|   () => estimateId.value, | ||||
|   (id) => { | ||||
|     if (id && route.name === 'estimates.view') loadEstimate() | ||||
|   } | ||||
| }) | ||||
| ) | ||||
|  | ||||
| loadEstimates() | ||||
| loadEstimate() | ||||
|  | ||||
| @ -65,11 +65,14 @@ const getCurrentInvoiceId = computed(() => { | ||||
|   return null | ||||
| }) | ||||
|  | ||||
| watch(route, (to, from) => { | ||||
|   if (to.name === 'invoices.view') { | ||||
|     loadInvoice() | ||||
| const invoiceId = computed(() => route.params.id) | ||||
|  | ||||
| watch( | ||||
|   () => invoiceId.value, | ||||
|   (id) => { | ||||
|     if (id && route.name === 'invoices.view') loadInvoice() | ||||
|   } | ||||
| }) | ||||
| ) | ||||
|  | ||||
| async function onMarkAsSent() { | ||||
|   dialogStore | ||||
| @ -286,32 +289,10 @@ onSearched = debounce(onSearched, 500) | ||||
|  | ||||
|     <!-- sidebar --> | ||||
|     <div | ||||
|       class=" | ||||
|         fixed | ||||
|         top-0 | ||||
|         left-0 | ||||
|         hidden | ||||
|         h-full | ||||
|         pt-16 | ||||
|         pb-[6.4rem] | ||||
|         ml-56 | ||||
|         bg-white | ||||
|         xl:ml-64 | ||||
|         w-88 | ||||
|         xl:block | ||||
|       " | ||||
|       class="fixed top-0 left-0 hidden h-full pt-16 pb-[6.4rem] ml-56 bg-white xl:ml-64 w-88 xl:block" | ||||
|     > | ||||
|       <div | ||||
|         class=" | ||||
|           flex | ||||
|           items-center | ||||
|           justify-between | ||||
|           px-4 | ||||
|           pt-8 | ||||
|           pb-2 | ||||
|           border border-gray-200 border-solid | ||||
|           height-full | ||||
|         " | ||||
|         class="flex items-center justify-between px-4 pt-8 pb-2 border border-gray-200 border-solid height-full" | ||||
|       > | ||||
|         <div class="mb-6"> | ||||
|           <BaseInput | ||||
| @ -335,14 +316,7 @@ onSearched = debounce(onSearched, 500) | ||||
|               </BaseButton> | ||||
|             </template> | ||||
|             <div | ||||
|               class=" | ||||
|                 px-2 | ||||
|                 py-1 | ||||
|                 pb-2 | ||||
|                 mb-1 mb-2 | ||||
|                 text-sm | ||||
|                 border-b border-gray-200 border-solid | ||||
|               " | ||||
|               class="px-2 py-1 pb-2 mb-1 mb-2 text-sm border-b border-gray-200 border-solid" | ||||
|             > | ||||
|               {{ $t('general.sort_by') }} | ||||
|             </div> | ||||
| @ -399,12 +373,7 @@ onSearched = debounce(onSearched, 500) | ||||
|  | ||||
|       <div | ||||
|         ref="invoiceListSection" | ||||
|         class=" | ||||
|           h-full | ||||
|           overflow-y-scroll | ||||
|           border-l border-gray-200 border-solid | ||||
|           base-scroll | ||||
|         " | ||||
|         class="h-full overflow-y-scroll border-l border-gray-200 border-solid base-scroll" | ||||
|       > | ||||
|         <div v-for="(invoice, index) in invoiceList" :key="index"> | ||||
|           <router-link | ||||
| @ -424,29 +393,11 @@ onSearched = debounce(onSearched, 500) | ||||
|               <BaseText | ||||
|                 :text="invoice.customer.name" | ||||
|                 :length="30" | ||||
|                 class=" | ||||
|                   pr-2 | ||||
|                   mb-2 | ||||
|                   text-sm | ||||
|                   not-italic | ||||
|                   font-normal | ||||
|                   leading-5 | ||||
|                   text-black | ||||
|                   capitalize | ||||
|                   truncate | ||||
|                 " | ||||
|                 class="pr-2 mb-2 text-sm not-italic font-normal leading-5 text-black capitalize truncate" | ||||
|               /> | ||||
|  | ||||
|               <div | ||||
|                 class=" | ||||
|                   mt-1 | ||||
|                   mb-2 | ||||
|                   text-xs | ||||
|                   not-italic | ||||
|                   font-medium | ||||
|                   leading-5 | ||||
|                   text-gray-600 | ||||
|                 " | ||||
|                 class="mt-1 mb-2 text-xs not-italic font-medium leading-5 text-gray-600" | ||||
|               > | ||||
|                 {{ invoice.invoice_number }} | ||||
|               </div> | ||||
| @ -460,27 +411,12 @@ onSearched = debounce(onSearched, 500) | ||||
|  | ||||
|             <div class="flex-1 whitespace-nowrap right"> | ||||
|               <BaseFormatMoney | ||||
|                 class=" | ||||
|                   mb-2 | ||||
|                   text-xl | ||||
|                   not-italic | ||||
|                   font-semibold | ||||
|                   leading-8 | ||||
|                   text-right text-gray-900 | ||||
|                   block | ||||
|                 " | ||||
|                 class="mb-2 text-xl not-italic font-semibold leading-8 text-right text-gray-900 block" | ||||
|                 :amount="invoice.total" | ||||
|                 :currency="invoice.customer.currency" | ||||
|               /> | ||||
|               <div | ||||
|                 class=" | ||||
|                   text-sm | ||||
|                   not-italic | ||||
|                   font-normal | ||||
|                   leading-5 | ||||
|                   text-right text-gray-600 | ||||
|                   est-date | ||||
|                 " | ||||
|                 class="text-sm not-italic font-normal leading-5 text-right text-gray-600 est-date" | ||||
|               > | ||||
|                 {{ invoice.formatted_invoice_date }} | ||||
|               </div> | ||||
| @ -505,13 +441,7 @@ onSearched = debounce(onSearched, 500) | ||||
|     > | ||||
|       <iframe | ||||
|         :src="`${shareableLink}`" | ||||
|         class=" | ||||
|           flex-1 | ||||
|           border border-gray-400 border-solid | ||||
|           bg-white | ||||
|           rounded-md | ||||
|           frame-style | ||||
|         " | ||||
|         class="flex-1 border border-gray-400 border-solid bg-white rounded-md frame-style" | ||||
|       /> | ||||
|     </div> | ||||
|   </BasePage> | ||||
|  | ||||
| @ -22,31 +22,10 @@ | ||||
|  | ||||
|     <!-- Sidebar --> | ||||
|     <div | ||||
|       class=" | ||||
|         fixed | ||||
|         top-0 | ||||
|         left-0 | ||||
|         hidden | ||||
|         h-full | ||||
|         pt-16 | ||||
|         pb-[6rem] | ||||
|         ml-56 | ||||
|         bg-white | ||||
|         xl:ml-64 | ||||
|         w-88 | ||||
|         xl:block | ||||
|       " | ||||
|       class="fixed top-0 left-0 hidden h-full pt-16 pb-[6rem] ml-56 bg-white xl:ml-64 w-88 xl:block" | ||||
|     > | ||||
|       <div | ||||
|         class=" | ||||
|           flex | ||||
|           items-center | ||||
|           justify-between | ||||
|           px-4 | ||||
|           pt-8 | ||||
|           pb-6 | ||||
|           border border-gray-200 border-solid | ||||
|         " | ||||
|         class="flex items-center justify-between px-4 pt-8 pb-6 border border-gray-200 border-solid" | ||||
|       > | ||||
|         <BaseInput | ||||
|           v-model="searchData.searchText" | ||||
| @ -70,14 +49,7 @@ | ||||
|             </template> | ||||
|  | ||||
|             <div | ||||
|               class=" | ||||
|                 px-4 | ||||
|                 py-1 | ||||
|                 pb-2 | ||||
|                 mb-2 | ||||
|                 text-sm | ||||
|                 border-b border-gray-200 border-solid | ||||
|               " | ||||
|               class="px-4 py-1 pb-2 mb-2 text-sm border-b border-gray-200 border-solid" | ||||
|             > | ||||
|               {{ $t('general.sort_by') }} | ||||
|             </div> | ||||
| @ -159,43 +131,17 @@ | ||||
|               <BaseText | ||||
|                 :text="payment?.customer?.name" | ||||
|                 :length="30" | ||||
|                 class=" | ||||
|                   pr-2 | ||||
|                   mb-2 | ||||
|                   text-sm | ||||
|                   not-italic | ||||
|                   font-normal | ||||
|                   leading-5 | ||||
|                   text-black | ||||
|                   capitalize | ||||
|                   truncate | ||||
|                 " | ||||
|                 class="pr-2 mb-2 text-sm not-italic font-normal leading-5 text-black capitalize truncate" | ||||
|               /> | ||||
|  | ||||
|               <div | ||||
|                 class=" | ||||
|                   mb-1 | ||||
|                   text-xs | ||||
|                   not-italic | ||||
|                   font-medium | ||||
|                   leading-5 | ||||
|                   text-gray-500 | ||||
|                   capitalize | ||||
|                 " | ||||
|                 class="mb-1 text-xs not-italic font-medium leading-5 text-gray-500 capitalize" | ||||
|               > | ||||
|                 {{ payment?.payment_number }} | ||||
|               </div> | ||||
|  | ||||
|               <div | ||||
|                 class=" | ||||
|                   mb-1 | ||||
|                   text-xs | ||||
|                   not-italic | ||||
|                   font-medium | ||||
|                   leading-5 | ||||
|                   text-gray-500 | ||||
|                   capitalize | ||||
|                 " | ||||
|                 class="mb-1 text-xs not-italic font-medium leading-5 text-gray-500 capitalize" | ||||
|               > | ||||
|                 {{ payment?.invoice_number }} | ||||
|               </div> | ||||
| @ -203,15 +149,7 @@ | ||||
|  | ||||
|             <div class="flex-1 whitespace-nowrap right"> | ||||
|               <BaseFormatMoney | ||||
|                 class=" | ||||
|                   block | ||||
|                   mb-2 | ||||
|                   text-xl | ||||
|                   not-italic | ||||
|                   font-semibold | ||||
|                   leading-8 | ||||
|                   text-right text-gray-900 | ||||
|                 " | ||||
|                 class="block mb-2 text-xl not-italic font-semibold leading-8 text-right text-gray-900" | ||||
|                 :amount="payment?.amount" | ||||
|                 :currency="payment.customer?.currency" | ||||
|               /> | ||||
| @ -313,9 +251,14 @@ const paymentDate = computed(() => { | ||||
|   ) | ||||
| }) | ||||
|  | ||||
| watch(route, () => { | ||||
|   loadPayment() | ||||
| }) | ||||
| const paymentId = computed(() => route.params.id) | ||||
|  | ||||
| watch( | ||||
|   () => paymentId.value, | ||||
|   (id) => { | ||||
|     if (id && route.name === 'payments.view') loadPayment() | ||||
|   } | ||||
| ) | ||||
|  | ||||
| loadPayments() | ||||
| loadPayment() | ||||
|  | ||||
| @ -78,10 +78,12 @@ let isLoading = computed(() => { | ||||
|   return recurringInvoiceStore.isFetchingViewData | ||||
| }) | ||||
|  | ||||
| const invoiceId = computed(() => route.params.id) | ||||
|  | ||||
| watch( | ||||
|   route, | ||||
|   () => { | ||||
|     if (route.params.id && route.name === 'recurring-invoices.view') { | ||||
|   () => invoiceId.value, | ||||
|   (id) => { | ||||
|     if (id && route.name === 'recurring-invoices.view') { | ||||
|       loadRecurringInvoice() | ||||
|     } | ||||
|   }, | ||||
|  | ||||
| @ -11,7 +11,8 @@ RUN apt-get update && apt-get install -y \ | ||||
|     unzip \ | ||||
|     libzip-dev \ | ||||
|     libmagickwand-dev \ | ||||
|     mariadb-client | ||||
|     mariadb-client \ | ||||
|     npm | ||||
|  | ||||
| # Clear cache | ||||
| RUN apt-get clean && rm -rf /var/lib/apt/lists/* | ||||
| @ -45,4 +46,19 @@ RUN chmod -R 775 composer.json composer.lock \ | ||||
| RUN chown -R $(whoami):$(whoami) /var/log/ | ||||
| RUN chmod -R 775 /var/log | ||||
|  | ||||
| # Cleanup manually generated build files | ||||
| RUN rm -rf /var/www/public/build | ||||
| RUN npm config set user 0 | ||||
| RUN npm config set unsafe-perm true | ||||
| # Frontend bulding | ||||
| RUN sed -i 's/DB_CONNECTION=mysql/DB_CONNECTION=sqlite/g' /var/www/.env | ||||
| RUN sed -i 's/DB_DATABASE=crater/DB_DATABASE=\/tmp\/crater.sqlite/g' /var/www/.env | ||||
| RUN touch /tmp/crater.sqlite | ||||
| RUN composer install --no-interaction --prefer-dist | ||||
| RUN npm i -f | ||||
| RUN npm install --save-dev sass | ||||
| RUN export NODE_OPTIONS="--max-old-space-size=4096" && /usr/bin/npx vite build --target=es2020 | ||||
| RUN sed -i 's/DB_CONNECTION=sqlite/DB_CONNECTION=mysql/g' /var/www/.env | ||||
| RUN sed -i 's/DB_DATABASE=\/tmp\/crater.sqlite/DB_DATABASE=crater/g' /var/www/.env | ||||
|  | ||||
| USER crater-user | ||||
|  | ||||
| @ -1,7 +1,9 @@ | ||||
| ARG BASE_IMAGE | ||||
|  | ||||
| FROM $BASE_IMAGE as build | ||||
| FROM nginx:1.17-alpine | ||||
|  | ||||
| RUN rm /etc/nginx/conf.d/default.conf | ||||
|  | ||||
| COPY ./ /var/www | ||||
| COPY --from=build /var/www /var/www | ||||
| COPY ./uffizzi/nginx/nginx /etc/nginx/conf.d/ | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	