mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-10-30 13:11:08 -04:00 
			
		
		
		
	v6 update
This commit is contained in:
		
							
								
								
									
										11
									
								
								resources/scripts/customer/views/dashboard/Dashboard.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								resources/scripts/customer/views/dashboard/Dashboard.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| <template> | ||||
|   <BasePage> | ||||
|     <DashboardStats /> | ||||
|     <DashboardTable /> | ||||
|   </BasePage> | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| import DashboardStats from '@/scripts/customer/views/dashboard/DashboardStats.vue' | ||||
| import DashboardTable from '@/scripts/customer/views/dashboard/DashboardTable.vue' | ||||
| </script> | ||||
| @ -0,0 +1,66 @@ | ||||
| <template> | ||||
|   <div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-9 xl:gap-8"> | ||||
|     <!-- Amount Due --> | ||||
|     <DashboardStatsItem | ||||
|       :icon-component="DollarIcon" | ||||
|       :loading="!globalStore.getDashboardDataLoaded" | ||||
|       :route="{ name: 'invoices.dashboard' }" | ||||
|       :large="true" | ||||
|       :label="$t('dashboard.cards.due_amount')" | ||||
|     > | ||||
|       <BaseFormatMoney | ||||
|         :amount="dashboardStore.totalDueAmount" | ||||
|         :currency="globalStore.currency" | ||||
|       /> | ||||
|     </DashboardStatsItem> | ||||
|  | ||||
|     <!-- Invoices --> | ||||
|     <DashboardStatsItem | ||||
|       :icon-component="InvoiceIcon" | ||||
|       :loading="!globalStore.getDashboardDataLoaded" | ||||
|       :route="{ name: 'invoices.dashboard' }" | ||||
|       :label="$t('dashboard.cards.invoices')" | ||||
|     > | ||||
|       {{ dashboardStore.invoiceCount }} | ||||
|     </DashboardStatsItem> | ||||
|  | ||||
|     <!-- Estimates --> | ||||
|     <DashboardStatsItem | ||||
|       :icon-component="EstimateIcon" | ||||
|       :loading="!globalStore.getDashboardDataLoaded" | ||||
|       :route="{ name: 'estimates.dashboard' }" | ||||
|       :label="$t('dashboard.cards.estimates')" | ||||
|     > | ||||
|       {{ dashboardStore.estimateCount }} | ||||
|     </DashboardStatsItem> | ||||
|  | ||||
|     <!-- Payments --> | ||||
|  | ||||
|     <DashboardStatsItem | ||||
|       :icon-component="PaymentIcon" | ||||
|       :loading="!globalStore.getDashboardDataLoaded" | ||||
|       :route="{ name: 'payments.dashboard' }" | ||||
|       :label="$t('dashboard.cards.payments')" | ||||
|     > | ||||
|       {{ dashboardStore.paymentCount }} | ||||
|     </DashboardStatsItem> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| import { inject } from 'vue' | ||||
| import DollarIcon from '@/scripts/components/icons/dashboard/DollarIcon.vue' | ||||
| import InvoiceIcon from '@/scripts/components/icons/dashboard/InvoiceIcon.vue' | ||||
| import PaymentIcon from '@/scripts/components/icons/dashboard/PaymentIcon.vue' | ||||
| import EstimateIcon from '@/scripts/components/icons/dashboard/EstimateIcon.vue' | ||||
|  | ||||
| import { useGlobalStore } from '@/scripts/customer/stores/global' | ||||
| import { useDashboardStore } from '@/scripts/customer/stores/dashboard' | ||||
| import DashboardStatsItem from '@/scripts/customer/views/dashboard/DashboardStatsItem.vue' | ||||
| //store | ||||
|  | ||||
| const utils = inject('utils') | ||||
| const globalStore = useGlobalStore() | ||||
| const dashboardStore = useDashboardStore() | ||||
| dashboardStore.loadData() | ||||
| </script> | ||||
| @ -0,0 +1,64 @@ | ||||
| <template> | ||||
|   <router-link | ||||
|     v-if="!loading" | ||||
|     class=" | ||||
|       relative | ||||
|       flex | ||||
|       justify-between | ||||
|       p-3 | ||||
|       bg-white | ||||
|       rounded | ||||
|       shadow | ||||
|       hover:bg-gray-50 | ||||
|       xl:p-4 | ||||
|       lg:col-span-2 | ||||
|     " | ||||
|     :class="{ 'lg:!col-span-3': large }" | ||||
|     :to="route" | ||||
|   > | ||||
|     <div> | ||||
|       <span class="text-xl font-semibold leading-tight text-black xl:text-3xl"> | ||||
|         <slot /> | ||||
|       </span> | ||||
|       <span class="block mt-1 text-sm leading-tight text-gray-500 xl:text-lg"> | ||||
|         {{ label }} | ||||
|       </span> | ||||
|     </div> | ||||
|     <div class="flex items-center"> | ||||
|       <component :is="iconComponent" class="w-10 h-10 xl:w-12 xl:h-12" /> | ||||
|     </div> | ||||
|   </router-link> | ||||
|  | ||||
|   <StatsCardPlaceholder v-else-if="large" /> | ||||
|  | ||||
|   <StatsCardSmPlaceholder v-else /> | ||||
| </template> | ||||
|  | ||||
|  | ||||
| <script setup> | ||||
| import StatsCardPlaceholder from '@/scripts/customer/views/dashboard/DashboardStatsPlaceholder.vue' | ||||
| import StatsCardSmPlaceholder from '@/scripts/customer/views/dashboard/DashboardStatsSmPlaceholder.vue' | ||||
|  | ||||
| defineProps({ | ||||
|   iconComponent: { | ||||
|     type: Object, | ||||
|     required: true, | ||||
|   }, | ||||
|   loading: { | ||||
|     type: Boolean, | ||||
|     default: false, | ||||
|   }, | ||||
|   route: { | ||||
|     type: Object, | ||||
|     required: true, | ||||
|   }, | ||||
|   label: { | ||||
|     type: String, | ||||
|     required: true, | ||||
|   }, | ||||
|   large: { | ||||
|     type: Boolean, | ||||
|     default: false, | ||||
|   }, | ||||
| }) | ||||
| </script> | ||||
| @ -0,0 +1,20 @@ | ||||
| <template> | ||||
|   <BaseContentPlaceholders | ||||
|     :rounded="true" | ||||
|     class="relative flex justify-between w-full p-3 bg-white rounded shadow lg:col-span-3 xl:p-4" | ||||
|   > | ||||
|     <div> | ||||
|       <BaseContentPlaceholdersText | ||||
|         class="h-5 -mb-1 w-14 xl:mb-6 xl:h-7" | ||||
|         :lines="1" | ||||
|       /> | ||||
|       <BaseContentPlaceholdersText class="h-3 w-28 xl:h-4" :lines="1" /> | ||||
|     </div> | ||||
|     <div class="flex items-center"> | ||||
|       <BaseContentPlaceholdersBox | ||||
|         :circle="true" | ||||
|         class="w-10 h-10 xl:w-12 xl:h-12" | ||||
|       /> | ||||
|     </div> | ||||
|   </BaseContentPlaceholders> | ||||
| </template> | ||||
| @ -0,0 +1,31 @@ | ||||
| <template> | ||||
|   <BaseContentPlaceholders | ||||
|     :rounded="true" | ||||
|     class=" | ||||
|       relative | ||||
|       flex | ||||
|       justify-between | ||||
|       w-full | ||||
|       p-3 | ||||
|       bg-white | ||||
|       rounded | ||||
|       shadow | ||||
|       lg:col-span-2 | ||||
|       xl:p-4 | ||||
|     " | ||||
|   > | ||||
|     <div> | ||||
|       <BaseContentPlaceholdersText | ||||
|         class="w-12 h-5 -mb-1 xl:mb-6 xl:h-7" | ||||
|         :lines="1" | ||||
|       /> | ||||
|       <BaseContentPlaceholdersText class="w-20 h-3 xl:h-4" :lines="1" /> | ||||
|     </div> | ||||
|     <div class="flex items-center"> | ||||
|       <BaseContentPlaceholdersBox | ||||
|         :circle="true" | ||||
|         class="w-10 h-10 xl:w-12 xl:h-12" | ||||
|       /> | ||||
|     </div> | ||||
|   </BaseContentPlaceholders> | ||||
| </template> | ||||
							
								
								
									
										149
									
								
								resources/scripts/customer/views/dashboard/DashboardTable.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								resources/scripts/customer/views/dashboard/DashboardTable.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,149 @@ | ||||
| <template> | ||||
|   <div class="grid grid-cols-1 gap-6 mt-10 xl:grid-cols-2"> | ||||
|     <!-- Due Invoices --> | ||||
|     <div class="due-invoices"> | ||||
|       <div class="relative z-10 flex items-center justify-between mb-3"> | ||||
|         <h6 class="mb-0 text-xl font-semibold leading-normal"> | ||||
|           {{ $t('dashboard.recent_invoices_card.title') }} | ||||
|         </h6> | ||||
|  | ||||
|         <BaseButton | ||||
|           size="sm" | ||||
|           variant="primary-outline" | ||||
|           @click="$router.push({ name: 'invoices.dashboard' })" | ||||
|         > | ||||
|           {{ $t('dashboard.recent_invoices_card.view_all') }} | ||||
|         </BaseButton> | ||||
|       </div> | ||||
|       <!-- Recent Invoice--> | ||||
|       <BaseTable | ||||
|         :data="dashboardStore.recentInvoices" | ||||
|         :columns="dueInvoiceColumns" | ||||
|         :loading="!globalStore.getDashboardDataLoaded" | ||||
|       > | ||||
|         <template #cell-invoice_number="{ row }"> | ||||
|           <router-link | ||||
|             :to="{ | ||||
|               path: `/${globalStore.companySlug}/customer/invoices/${row.data.id}/view`, | ||||
|             }" | ||||
|             class="font-medium text-primary-500" | ||||
|           > | ||||
|             {{ row.data.invoice_number }} | ||||
|           </router-link> | ||||
|         </template> | ||||
|  | ||||
|         <template #cell-paid_status="{ row }"> | ||||
|           <BasePaidStatusBadge :status="row.data.paid_status"> | ||||
|             {{ row.data.paid_status }} | ||||
|           </BasePaidStatusBadge> | ||||
|         </template> | ||||
|  | ||||
|         <template #cell-due_amount="{ row }"> | ||||
|           <BaseFormatMoney | ||||
|             :amount="row.data.due_amount" | ||||
|             :currency="globalStore.currency" | ||||
|           /> | ||||
|         </template> | ||||
|       </BaseTable> | ||||
|     </div> | ||||
|  | ||||
|     <!-- Recent Estimates --> | ||||
|     <div class="recent-estimates"> | ||||
|       <div class="relative z-10 flex items-center justify-between mb-3"> | ||||
|         <h6 class="mb-0 text-xl font-semibold leading-normal"> | ||||
|           {{ $t('dashboard.recent_estimate_card.title') }} | ||||
|         </h6> | ||||
|  | ||||
|         <BaseButton | ||||
|           variant="primary-outline" | ||||
|           size="sm" | ||||
|           @click="$router.push({ name: 'estimates.dashboard' })" | ||||
|         > | ||||
|           {{ $t('dashboard.recent_estimate_card.view_all') }} | ||||
|         </BaseButton> | ||||
|       </div> | ||||
|  | ||||
|       <BaseTable | ||||
|         :data="dashboardStore.recentEstimates" | ||||
|         :columns="recentEstimateColumns" | ||||
|         :loading="!globalStore.getDashboardDataLoaded" | ||||
|       > | ||||
|         <template #cell-estimate_number="{ row }"> | ||||
|           <router-link | ||||
|             :to="{ | ||||
|               path: `/${globalStore.companySlug}/customer/estimates/${row.data.id}/view`, | ||||
|             }" | ||||
|             class="font-medium text-primary-500" | ||||
|           > | ||||
|             {{ row.data.estimate_number }} | ||||
|           </router-link> | ||||
|         </template> | ||||
|         <template #cell-status="{ row }"> | ||||
|           <BaseEstimateStatusBadge :status="row.data.status" class="px-3 py-1"> | ||||
|             {{ row.data.status }} | ||||
|           </BaseEstimateStatusBadge> | ||||
|         </template> | ||||
|         <template #cell-total="{ row }"> | ||||
|           <BaseFormatMoney | ||||
|             :amount="row.data.total" | ||||
|             :currency="globalStore.currency" | ||||
|           /> | ||||
|         </template> | ||||
|       </BaseTable> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| import { computed, inject } from 'vue' | ||||
| import { useI18n } from 'vue-i18n' | ||||
| import { useRoute } from 'vue-router' | ||||
| import { useGlobalStore } from '@/scripts/customer/stores/global' | ||||
| import { useDashboardStore } from '@/scripts/customer/stores/dashboard' | ||||
| import BaseTable from '@/scripts/components/base/base-table/BaseTable.vue' | ||||
|  | ||||
| // store | ||||
|  | ||||
| const globalStore = useGlobalStore() | ||||
| const dashboardStore = useDashboardStore() | ||||
| const { tm, t } = useI18n() | ||||
| const utils = inject('utils') | ||||
| const route = useRoute() | ||||
|  | ||||
| //computed prop | ||||
|  | ||||
| const dueInvoiceColumns = computed(() => { | ||||
|   return [ | ||||
|     { | ||||
|       key: 'formattedDueDate', | ||||
|       label: t('dashboard.recent_invoices_card.due_on'), | ||||
|     }, | ||||
|     { | ||||
|       key: 'invoice_number', | ||||
|       label: t('invoices.number'), | ||||
|     }, | ||||
|     { key: 'paid_status', label: t('invoices.status') }, | ||||
|     { | ||||
|       key: 'due_amount', | ||||
|       label: t('dashboard.recent_invoices_card.amount_due'), | ||||
|     }, | ||||
|   ] | ||||
| }) | ||||
| const recentEstimateColumns = computed(() => { | ||||
|   return [ | ||||
|     { | ||||
|       key: 'formattedEstimateDate', | ||||
|       label: t('dashboard.recent_estimate_card.date'), | ||||
|     }, | ||||
|     { | ||||
|       key: 'estimate_number', | ||||
|       label: t('estimates.number'), | ||||
|     }, | ||||
|     { key: 'status', label: t('estimates.status') }, | ||||
|     { | ||||
|       key: 'total', | ||||
|       label: t('dashboard.recent_estimate_card.amount_due'), | ||||
|     }, | ||||
|   ] | ||||
| }) | ||||
| </script> | ||||
		Reference in New Issue
	
	Block a user