Compare commits

..

5 commits

Author SHA1 Message Date
rocketdebris
1195ad8d4a Added appropriate dials to invoices page. 2025-12-20 23:41:41 -05:00
rocketdebris
982b627c63 Added the Jobs Todos that Courtney asked for on the Jobs page. 2025-12-20 23:41:15 -05:00
rocketdebris
0fc4e58543 Moved Charts to Estimates page from Clients page. 2025-12-20 23:40:24 -05:00
rocketdebris
176d9c7e7b Added the 15 Day Follow up Chart 2025-12-20 23:39:50 -05:00
rocketdebris
2034842d26 Removed the todo charts from Client to move them to other pages. 2025-12-20 23:39:01 -05:00
5 changed files with 415 additions and 102 deletions

View file

@ -1,101 +1,6 @@
<template>
<div class="page-container">
<H2>Client Contact List</H2>
<!-- Status Chart Section -->
<div class="widgets-grid">
<!-- Incomplete Bids Widget -->
<Card>
<template #header>
<div class="widget-header">
<Edit class="widget-icon" />
<h3>Incomplete Bids</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Incomplete Bids"
:todoNumber="bidsTodoNumber"
:completedNumber="bidsCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/calendar')">
Incomplete Bids
</button>
</div>
</template>
</Card>
<!-- Unapproved Estimates Widget -->
<Card>
<template #header>
<div class="widget-header">
<ChatBubbleQuestion class="widget-icon" />
<h3>Unapproved Estimates</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Unapproved Estimates"
:todoNumber="estimatesTodoNumber"
:completedNumber="estimatesCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/estimates')">
Unapproved Estimates
</button>
</div>
</template>
</Card>
<!-- Half Down Widget -->
<Card>
<template #header>
<div class="widget-header">
<CreditCard class="widget-icon" />
<h3>Half Down Payments</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Half Down Payments"
:todoNumber="halfDownTodoNumber"
:completedNumber="halfDownCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/jobs')">
Half Down Payments
</button>
</div>
</template>
</Card>
<!-- Late Balances Widget -->
<Card>
<template #header>
<div class="widget-header">
<CardNoAccess class="widget-icon" />
<h3>Late Balances</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Late Balances"
:todoNumber="balancesTodoNumber"
:completedNumber="balancesCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/jobs')">
Late Balances
</button>
</div>
</template>
</Card>
</div>
<DataTable
:data="tableData"

View file

@ -1,6 +1,101 @@
<template>
<div>
<div class="page-container">
<h2>Estimates</h2>
<!-- Todo Chart Section -->
<div class="widgets-grid">
<!-- Incomplete Bids Widget -->
<Card>
<template #header>
<div class="widget-header">
<Edit class="widget-icon" />
<h3>Incomplete Bids</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Incomplete Bids"
:todoNumber="bidsTodoNumber"
:completedNumber="bidsCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/calendar')">
Incomplete Bids
</button>
</div>
</template>
</Card>
<!-- Unapproved Estimates Widget -->
<Card>
<template #header>
<div class="widget-header">
<ChatBubbleQuestion class="widget-icon" />
<h3>Unapproved Estimates</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Unapproved Estimates"
:todoNumber="estimatesTodoNumber"
:completedNumber="estimatesCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/estimates')">
Unapproved Estimates
</button>
</div>
</template>
</Card>
<!-- Half Down Widget -->
<Card>
<template #header>
<div class="widget-header">
<CreditCard class="widget-icon" />
<h3>Half Down Payments</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Half Down Payments"
:todoNumber="halfDownTodoNumber"
:completedNumber="halfDownCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/jobs')">
Half Down Payments
</button>
</div>
</template>
</Card>
<!-- Late Balances Widget -->
<Card>
<template #header>
<div class="widget-header">
<Hammer class="widget-icon" />
<h3>Jobs In Queue</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Jobs In Queue"
:todoNumber="jobQueueTodoNumber"
:completedNumber="jobQueueCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/jobs')">
View Queued Jobs
</button>
</div>
</template>
</Card>
</div>
<DataTable
:data="tableData"
:columns="columns"
@ -33,7 +128,10 @@
</div>
</template>
<script setup>
import Card from "../common/Card.vue";
import DataTable from "../common/DataTable.vue";
import TodoChart from "../common/TodoChart.vue";
import { Edit, ChatBubbleQuestion, CreditCard, Hammer } from "@iconoir/vue";
import { ref, onMounted } from "vue";
import Api from "../../api";
import { useLoadingStore } from "../../stores/loading";
@ -188,4 +286,45 @@ onMounted(async () => {
});
</script>
<style lang=""></style>
<style lang="css">
.widgets-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-bottom: 20px;
}
.widget-header {
display: flex;
align-items: center;
gap: 10px;
padding: 20px 20px 0;
}
.widget-icon {
color: var(--theme-primary-strong);
width: 24px;
height: 24px;
}
.widget-header h3 {
margin: 0;
color: #2c3e50;
font-size: 1.2rem;
}
.widget-content {
display: flex;
flex-direction: column;
margin: 0;
width: 200px;
align-items: center;
padding: 20px 20px 20px;
/*gap: 15px;*/
}
.page-container {
height: 100%;
margin: 20px;
gap: 20px;
background-color: transparent;
}
</style>

View file

@ -160,6 +160,29 @@
</div>
</template>
</Card>
<!-- 15 Day Follow Up Widget -->
<Card >
<template #header>
<div class="widget-header">
<Calendar class="widget-icon" />
<h3>15 Day Follow Ups</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="15 Day Follow Ups"
:todoNumber="fifteenDayTodoNumber"
:completedNumber="fifteenDayCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/calendar')">
View Follow Ups
</button>
</div>
</template>
</Card>
<!-- Late Balances Widget -->
<Card >
<template #header>
@ -177,7 +200,7 @@
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/jobs')">
@click="navigateTo('/invoices')">
Late Balances
</button>
</div>

View file

@ -1,6 +1,55 @@
<template>
<div>
<div class="page-container">
<h2>Invoices</h2>
<!-- Todo Chart Section -->
<div class = "widgets-grid">
<!-- Ready to Invoice Widget -->
<Card>
<template #header>
<div class="widget-header">
<CalendarCheck class="widget-icon" />
<h3>Ready To Invoice</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Ready To Invoice"
:todoNumber="invoiceTodoNumber"
:completedNumber="invoiceCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="filterBy('ready')">
View Ready To Invoice
</button>
</div>
</template>
</Card>
<!-- Late Balances Widget -->
<Card>
<template #header>
<div class="widget-header">
<CardNoAccess class="widget-icon" />
<h3>Late Balances</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Late Balances"
:todoNumber="balancesTodoNumber"
:completedNumber="balancesCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="filterBy('late')">
View Late Balances
</button>
</div>
</template>
</Card>
</div>
<DataTable
:data="tableData"
:columns="columns"
@ -13,12 +62,15 @@
</div>
</template>
<script setup>
import Card from "../common/Card.vue";
import DataTable from "../common/DataTable.vue";
import TodoChart from "../common/TodoChart.vue";
import { ref, onMounted } from "vue";
import Api from "../../api";
import { useLoadingStore } from "../../stores/loading";
import { usePaginationStore } from "../../stores/pagination";
import { useFiltersStore } from "../../stores/filters";
import { CardNoAccess, CalendarCheck } from "@iconoir/vue";
const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore();
@ -44,6 +96,10 @@ const columns = [
{ label: "Grand Total", fieldName: "grandTotal", type: "text", sortable: true },
];
const filterBy = () => {
console.log("DEBUG: Invoices filterBy not implemented yet.");
}
const handleInvoiceClick = () => {
}
@ -135,4 +191,45 @@ onMounted(async () => {
});
</script>
<style lang=""></style>
<style lang="css">
.widgets-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-bottom: 20px;
}
.widget-header {
display: flex;
align-items: center;
gap: 10px;
padding: 20px 20px 0;
}
.widget-icon {
color: var(--theme-primary-strong);
width: 24px;
height: 24px;
}
.widget-header h3 {
margin: 0;
color: #2c3e50;
font-size: 1.2rem;
}
.widget-content {
display: flex;
flex-direction: column;
margin: 0;
width: 200px;
align-items: center;
padding: 20px 20px 20px;
/*gap: 15px;*/
}
.page-container {
height: 100%;
margin: 20px;
gap: 20px;
background-color: transparent;
}
</style>

View file

@ -1,6 +1,101 @@
<template>
<div>
<div class="page-container">
<h2>Jobs</h2>
<!-- Todo Chart Section -->
<div class = "widgets-grid">
<!-- Jobs in Queue Widget -->
<Card>
<template #header>
<div class="widget-header">
<Hammer class="widget-icon" />
<h3>Jobs In Queue</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Jobs In Queue"
:todoNumber="jobQueueTodoNumber"
:completedNumber="jobQueueCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="filterBy('in queue')">
View Queued Jobs
</button>
</div>
</template>
</Card>
<!-- Jobs In Progress Widget -->
<Card>
<template #header>
<div class="widget-header">
<Hammer class="widget-icon" />
<h3>Jobs In Progress</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Jobs in Progress"
:todoNumber="progressTodoNumber"
:completedNumber="progressCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="filterBy('in progress')">
View Jobs In Progress
</button>
</div>
</template>
</Card>
<!-- Late Jobs Widget -->
<Card>
<template #header>
<div class="widget-header">
<Alarm class="widget-icon" />
<h3>Late Jobs</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Late Jobs"
:todoNumber="lateTodoNumber"
:completedNumber="lateCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="filterBy('late')">
View Late Jobs
</button>
</div>
</template>
</Card>
<!-- Ready to Invoice Widget -->
<Card>
<template #header>
<div class="widget-header">
<CalendarCheck class="widget-icon" />
<h3>Ready To Invoice</h3>
</div>
</template>
<template #content>
<div class="widget-content">
<TodoChart
title="Ready To Invoice"
:todoNumber="invoiceTodoNumber"
:completedNumber="invoiceCompletedNumber"
>
</TodoChart>
<button class="sidebar-button"
@click="navigateTo('/invoices')">
View Ready To Invoice
</button>
</div>
</template>
</Card>
</div>
<DataTable
:data="tableData"
:columns="columns"
@ -13,13 +108,17 @@
</div>
</template>
<script setup>
import Card from "../common/Card.vue";
import DataTable from "../common/DataTable.vue";
import TodoChart from "../common/TodoChart.vue";
import { ref, onMounted } from "vue";
import { useRouter } from "vue-router";
import Api from "../../api";
import { useLoadingStore } from "../../stores/loading";
import { usePaginationStore } from "../../stores/pagination";
import { useFiltersStore } from "../../stores/filters";
import { useNotificationStore } from "../../stores/notifications-primevue";
import { Alarm, CalendarCheck, Hammer } from "@iconoir/vue";
const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore();
@ -38,6 +137,15 @@ const columns = [
{ label: "Progress", fieldName: "percentComplete", type: "text", sortable: true },
];
const router = useRouter();
const navigateTo = (path) => {
router.push(path);
};
const filterBy = (filter) => {
console.log("DEBUG: Jobs filterBy not implemented yet.");
};
// Handle lazy loading events from DataTable
const handleLazyLoad = async (event) => {
console.log("Jobs page - handling lazy load:", event);
@ -169,4 +277,45 @@ onMounted(async () => {
// });
});
</script>
<style lang=""></style>
<style lang="css">
.widgets-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-bottom: 20px;
}
.widget-header {
display: flex;
align-items: center;
gap: 10px;
padding: 20px 20px 0;
}
.widget-icon {
color: var(--theme-primary-strong);
width: 24px;
height: 24px;
}
.widget-header h3 {
margin: 0;
color: #2c3e50;
font-size: 1.2rem;
}
.widget-content {
display: flex;
flex-direction: column;
margin: 0;
width: 200px;
align-items: center;
padding: 20px 20px 20px;
/*gap: 15px;*/
}
.page-container {
height: 100%;
margin: 20px;
gap: 20px;
background-color: transparent;
}
</style>