Compare commits
6 Commits
claude/pra
...
6bd080f8c4
| Author | SHA1 | Date | |
|---|---|---|---|
| 6bd080f8c4 | |||
| be3a5191c5 | |||
| 7d4df25d16 | |||
| 538828b91a | |||
| 14160854b9 | |||
| 36d486d78c |
@@ -9,5 +9,20 @@
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
<script>
|
||||
(function(d,t) {
|
||||
var BASE_URL="https//chat.hoaledgeriq.com";
|
||||
var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
||||
g.src=BASE_URL+"/packs/js/sdk.js";
|
||||
g.async = true;
|
||||
s.parentNode.insertBefore(g,s);
|
||||
g.onload=function(){
|
||||
window.chatwootSDK.run({
|
||||
websiteToken: 'K6VXvTtKXvaCMvre4yK85SPb',
|
||||
baseUrl: BASE_URL
|
||||
})
|
||||
}
|
||||
})(document,"script");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { IconDeviceFloppy, IconUpload, IconDownload, IconInfoCircle } from '@tab
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../services/api';
|
||||
import { useIsReadOnly } from '../../stores/authStore';
|
||||
import { usePreferencesStore } from '../../stores/preferencesStore';
|
||||
|
||||
interface BudgetLine {
|
||||
account_id: string;
|
||||
@@ -98,6 +99,11 @@ export function BudgetsPage() {
|
||||
const queryClient = useQueryClient();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const isReadOnly = useIsReadOnly();
|
||||
const isDark = usePreferencesStore((s) => s.colorScheme) === 'dark';
|
||||
const stickyBg = isDark ? 'var(--mantine-color-dark-7)' : 'white';
|
||||
const stickyBorder = isDark ? 'var(--mantine-color-dark-4)' : '#e9ecef';
|
||||
const incomeSectionBg = isDark ? 'var(--mantine-color-green-9)' : '#e6f9e6';
|
||||
const expenseSectionBg = isDark ? 'var(--mantine-color-red-9)' : '#fde8e8';
|
||||
|
||||
const { isLoading } = useQuery<BudgetLine[]>({
|
||||
queryKey: ['budgets', year],
|
||||
@@ -317,8 +323,8 @@ export function BudgetsPage() {
|
||||
<Table striped highlightOnHover style={{ minWidth: 1600 }}>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th style={{ position: 'sticky', left: 0, background: 'white', zIndex: 2, minWidth: 120 }}>Acct #</Table.Th>
|
||||
<Table.Th style={{ position: 'sticky', left: 120, background: 'white', zIndex: 2, minWidth: 220 }}>Account Name</Table.Th>
|
||||
<Table.Th style={{ position: 'sticky', left: 0, background: stickyBg, zIndex: 2, minWidth: 120 }}>Acct #</Table.Th>
|
||||
<Table.Th style={{ position: 'sticky', left: 120, background: stickyBg, zIndex: 2, minWidth: 220 }}>Account Name</Table.Th>
|
||||
{monthLabels.map((m) => (
|
||||
<Table.Th key={m} ta="right" style={{ minWidth: 90 }}>{m}</Table.Th>
|
||||
))}
|
||||
@@ -337,7 +343,7 @@ export function BudgetsPage() {
|
||||
const lines = budgetData.filter((b) => b.account_type === type);
|
||||
if (lines.length === 0) return null;
|
||||
|
||||
const sectionBg = type === 'income' ? '#e6f9e6' : '#fde8e8';
|
||||
const sectionBg = type === 'income' ? incomeSectionBg : expenseSectionBg;
|
||||
const sectionTotal = lines.reduce((sum, line) => sum + (line.annual_total || 0), 0);
|
||||
|
||||
return [
|
||||
@@ -368,9 +374,9 @@ export function BudgetsPage() {
|
||||
style={{
|
||||
position: 'sticky',
|
||||
left: 0,
|
||||
background: 'white',
|
||||
background: stickyBg,
|
||||
zIndex: 1,
|
||||
borderRight: '1px solid #e9ecef',
|
||||
borderRight: `1px solid ${stickyBorder}`,
|
||||
}}
|
||||
>
|
||||
<Text size="sm" c="dimmed" ff="monospace">{line.account_number}</Text>
|
||||
@@ -379,9 +385,9 @@ export function BudgetsPage() {
|
||||
style={{
|
||||
position: 'sticky',
|
||||
left: 120,
|
||||
background: 'white',
|
||||
background: stickyBg,
|
||||
zIndex: 1,
|
||||
borderRight: '1px solid #e9ecef',
|
||||
borderRight: `1px solid ${stickyBorder}`,
|
||||
}}
|
||||
>
|
||||
<Group gap={6} wrap="nowrap">
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
IconArrowLeft, IconArrowRight, IconCalendar,
|
||||
} from '@tabler/icons-react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { usePreferencesStore } from '../../stores/preferencesStore';
|
||||
import {
|
||||
AreaChart, Area, XAxis, YAxis, CartesianGrid,
|
||||
Tooltip as RechartsTooltip, ResponsiveContainer, Legend,
|
||||
@@ -79,6 +80,7 @@ export function CashFlowForecastPage() {
|
||||
const now = new Date();
|
||||
const currentYear = now.getFullYear();
|
||||
const currentMonth = now.getMonth() + 1;
|
||||
const isDark = usePreferencesStore((s) => s.colorScheme) === 'dark';
|
||||
|
||||
// Filter: All, Operating, Reserve
|
||||
const [fundFilter, setFundFilter] = useState<string>('all');
|
||||
@@ -418,10 +420,10 @@ export function CashFlowForecastPage() {
|
||||
<tr
|
||||
key={d.month}
|
||||
style={{
|
||||
borderBottom: '1px solid var(--mantine-color-gray-2)',
|
||||
borderBottom: `1px solid ${isDark ? 'var(--mantine-color-dark-4)' : 'var(--mantine-color-gray-2)'}`,
|
||||
backgroundColor: d.is_forecast
|
||||
? 'var(--mantine-color-orange-0)'
|
||||
: i % 2 === 0 ? 'transparent' : 'var(--mantine-color-gray-0)',
|
||||
? (isDark ? 'var(--mantine-color-orange-9)' : 'var(--mantine-color-orange-0)')
|
||||
: i % 2 === 0 ? 'transparent' : (isDark ? 'var(--mantine-color-dark-5)' : 'var(--mantine-color-gray-0)'),
|
||||
}}
|
||||
>
|
||||
<td style={{ padding: '6px 12px', fontWeight: 500 }}>{d.month}</td>
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../services/api';
|
||||
import { useIsReadOnly } from '../../stores/authStore';
|
||||
import { usePreferencesStore } from '../../stores/preferencesStore';
|
||||
import { AttachmentPanel } from '../../components/attachments/AttachmentPanel';
|
||||
|
||||
interface ActualLine {
|
||||
@@ -66,6 +67,11 @@ export function MonthlyActualsPage() {
|
||||
const [savedJEId, setSavedJEId] = useState<string | null>(null);
|
||||
const queryClient = useQueryClient();
|
||||
const isReadOnly = useIsReadOnly();
|
||||
const isDark = usePreferencesStore((s) => s.colorScheme) === 'dark';
|
||||
const stickyBg = isDark ? 'var(--mantine-color-dark-7)' : 'white';
|
||||
const stickyBorder = isDark ? 'var(--mantine-color-dark-4)' : '#e9ecef';
|
||||
const incomeBg = isDark ? 'var(--mantine-color-green-9)' : '#e6f9e6';
|
||||
const expenseBg = isDark ? 'var(--mantine-color-red-9)' : '#fde8e8';
|
||||
|
||||
const yearOptions = Array.from({ length: 5 }, (_, i) => {
|
||||
const y = new Date().getFullYear() - 2 + i;
|
||||
@@ -178,16 +184,16 @@ export function MonthlyActualsPage() {
|
||||
<Table.Tr key={line.account_id}>
|
||||
<Table.Td
|
||||
style={{
|
||||
position: 'sticky', left: 0, background: 'white', zIndex: 1,
|
||||
borderRight: '1px solid #e9ecef',
|
||||
position: 'sticky', left: 0, background: stickyBg, zIndex: 1,
|
||||
borderRight: `1px solid ${stickyBorder}`,
|
||||
}}
|
||||
>
|
||||
<Text size="sm" c="dimmed" ff="monospace">{line.account_number}</Text>
|
||||
</Table.Td>
|
||||
<Table.Td
|
||||
style={{
|
||||
position: 'sticky', left: 120, background: 'white', zIndex: 1,
|
||||
borderRight: '1px solid #e9ecef',
|
||||
position: 'sticky', left: 120, background: stickyBg, zIndex: 1,
|
||||
borderRight: `1px solid ${stickyBorder}`,
|
||||
}}
|
||||
>
|
||||
<Group gap={6} wrap="nowrap">
|
||||
@@ -292,10 +298,10 @@ export function MonthlyActualsPage() {
|
||||
<Table striped highlightOnHover style={{ minWidth: 700 }}>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th style={{ position: 'sticky', left: 0, background: 'white', zIndex: 2, minWidth: 120 }}>
|
||||
<Table.Th style={{ position: 'sticky', left: 0, background: stickyBg, zIndex: 2, minWidth: 120 }}>
|
||||
Acct #
|
||||
</Table.Th>
|
||||
<Table.Th style={{ position: 'sticky', left: 120, background: 'white', zIndex: 2, minWidth: 220 }}>
|
||||
<Table.Th style={{ position: 'sticky', left: 120, background: stickyBg, zIndex: 2, minWidth: 220 }}>
|
||||
Account Name
|
||||
</Table.Th>
|
||||
<Table.Th ta="right" style={{ minWidth: 110 }}>Budget</Table.Th>
|
||||
@@ -304,8 +310,8 @@ export function MonthlyActualsPage() {
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{renderSection('Income', incomeLines, '#e6f9e6', totals.incomeBudget, totals.incomeActual)}
|
||||
{renderSection('Expenses', expenseLines, '#fde8e8', totals.expenseBudget, totals.expenseActual)}
|
||||
{renderSection('Income', incomeLines, incomeBg, totals.incomeBudget, totals.incomeActual)}
|
||||
{renderSection('Expenses', expenseLines, expenseBg, totals.expenseBudget, totals.expenseActual)}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
} from '@mantine/core';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import api from '../../services/api';
|
||||
import { usePreferencesStore } from '../../stores/preferencesStore';
|
||||
|
||||
interface BudgetVsActualLine {
|
||||
account_id: string;
|
||||
@@ -46,6 +47,9 @@ const monthFilterOptions = [
|
||||
export function BudgetVsActualPage() {
|
||||
const [year, setYear] = useState(new Date().getFullYear().toString());
|
||||
const [month, setMonth] = useState('');
|
||||
const isDark = usePreferencesStore((s) => s.colorScheme) === 'dark';
|
||||
const incomeBg = isDark ? 'var(--mantine-color-green-9)' : '#e6f9e6';
|
||||
const expenseBg = isDark ? 'var(--mantine-color-red-9)' : '#fde8e8';
|
||||
|
||||
const yearOptions = Array.from({ length: 5 }, (_, i) => {
|
||||
const y = new Date().getFullYear() - 2 + i;
|
||||
@@ -92,7 +96,7 @@ export function BudgetVsActualPage() {
|
||||
|
||||
const renderSection = (title: string, sectionLines: BudgetVsActualLine[], isExpense: boolean, totalBudget: number, totalActual: number) => (
|
||||
<>
|
||||
<Table.Tr style={{ background: isExpense ? '#fde8e8' : '#e6f9e6' }}>
|
||||
<Table.Tr style={{ background: isExpense ? expenseBg : incomeBg }}>
|
||||
<Table.Td colSpan={6} fw={700}>{title}</Table.Td>
|
||||
</Table.Tr>
|
||||
{sectionLines.map((line) => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
IconTrendingUp, IconTrendingDown, IconAlertTriangle, IconChartBar,
|
||||
} from '@tabler/icons-react';
|
||||
import api from '../../services/api';
|
||||
import { usePreferencesStore } from '../../stores/preferencesStore';
|
||||
|
||||
interface BudgetVsActualItem {
|
||||
account_id: string;
|
||||
@@ -48,6 +49,9 @@ export function QuarterlyReportPage() {
|
||||
const currentQuarter = Math.ceil((now.getMonth() + 1) / 3);
|
||||
const defaultQuarter = currentQuarter;
|
||||
const defaultYear = now.getFullYear();
|
||||
const isDark = usePreferencesStore((s) => s.colorScheme) === 'dark';
|
||||
const incomeBg = isDark ? 'var(--mantine-color-green-9)' : '#e6f9e6';
|
||||
const expenseBg = isDark ? 'var(--mantine-color-red-9)' : '#fde8e8';
|
||||
|
||||
const [year, setYear] = useState(String(defaultYear));
|
||||
const [quarter, setQuarter] = useState(String(defaultQuarter));
|
||||
@@ -207,7 +211,7 @@ export function QuarterlyReportPage() {
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{incomeItems.length > 0 && (
|
||||
<Table.Tr style={{ background: '#e6f9e6' }}>
|
||||
<Table.Tr style={{ background: incomeBg }}>
|
||||
<Table.Td colSpan={8} fw={700}>Income</Table.Td>
|
||||
</Table.Tr>
|
||||
)}
|
||||
@@ -215,7 +219,7 @@ export function QuarterlyReportPage() {
|
||||
<BVARow key={item.account_id} item={item} isExpense={false} />
|
||||
))}
|
||||
{incomeItems.length > 0 && (
|
||||
<Table.Tr style={{ background: '#e6f9e6' }}>
|
||||
<Table.Tr style={{ background: incomeBg }}>
|
||||
<Table.Td colSpan={2} fw={700}>Total Income</Table.Td>
|
||||
<Table.Td ta="right" fw={700} ff="monospace">{fmt(incomeItems.reduce((s, i) => s + i.quarter_budget, 0))}</Table.Td>
|
||||
<Table.Td ta="right" fw={700} ff="monospace">{fmt(incomeItems.reduce((s, i) => s + i.quarter_actual, 0))}</Table.Td>
|
||||
@@ -226,7 +230,7 @@ export function QuarterlyReportPage() {
|
||||
</Table.Tr>
|
||||
)}
|
||||
{expenseItems.length > 0 && (
|
||||
<Table.Tr style={{ background: '#fde8e8' }}>
|
||||
<Table.Tr style={{ background: expenseBg }}>
|
||||
<Table.Td colSpan={8} fw={700}>Expenses</Table.Td>
|
||||
</Table.Tr>
|
||||
)}
|
||||
@@ -234,7 +238,7 @@ export function QuarterlyReportPage() {
|
||||
<BVARow key={item.account_id} item={item} isExpense={true} />
|
||||
))}
|
||||
{expenseItems.length > 0 && (
|
||||
<Table.Tr style={{ background: '#fde8e8' }}>
|
||||
<Table.Tr style={{ background: expenseBg }}>
|
||||
<Table.Td colSpan={2} fw={700}>Total Expenses</Table.Td>
|
||||
<Table.Td ta="right" fw={700} ff="monospace">{fmt(expenseItems.reduce((s, i) => s + i.quarter_budget, 0))}</Table.Td>
|
||||
<Table.Td ta="right" fw={700} ff="monospace">{fmt(expenseItems.reduce((s, i) => s + i.quarter_actual, 0))}</Table.Td>
|
||||
|
||||
Reference in New Issue
Block a user