removed expense and income vs outflow and inflow

This commit is contained in:
2026-05-18 07:58:35 +05:30
parent 58271584ce
commit fff304ad1e
13 changed files with 48 additions and 53 deletions

View File

@@ -18,13 +18,8 @@ import {
prepareReport,
} from "./features/report";
/** Map the internal UI mode to the API flow param */
function modeToFlow(mode: "expense" | "income"): "outflows" | "inflows" {
return mode === "expense" ? "outflows" : "inflows";
}
export default function Dashboard() {
const [mode, setMode] = React.useState<"expense" | "income">("expense");
const [flow, setFlow] = React.useState<"outflows" | "inflows">("outflows");
const [appliedPayees, setAppliedPayees] = React.useState<string[]>([]);
const [appliedTags, setAppliedTags] = React.useState<string[]>([]);
@@ -37,7 +32,7 @@ export default function Dashboard() {
const report = useReport({
periods: ["daily", "weekly", "monthly", "all"],
flow: modeToFlow(mode),
flow: flow,
payee: appliedPayees.length > 0 ? appliedPayees : undefined,
tags: appliedTags.length > 0 ? appliedTags : undefined,
});
@@ -77,9 +72,9 @@ export default function Dashboard() {
const isLoading = report.isLoading;
const error = report.error;
/** Callback for the ConfigurableDashboard's mode toggle */
const handleModeChange = React.useCallback((newState: DashboardState) => {
setMode(newState.mode);
/** Callback for the ConfigurableDashboard's flow toggle */
const handleFlowChange = React.useCallback((newState: DashboardState) => {
setFlow(newState.flow);
}, []);
if (isLoading && !report.data) {
@@ -166,7 +161,7 @@ export default function Dashboard() {
config={configuration}
data={data}
isFetching={report.isFetching}
onModeChange={handleModeChange}
onFlowChange={handleFlowChange}
/>
</Box>
);

View File

@@ -4,12 +4,12 @@ import {
GroupKey,
} from "../../features/report";
export type DashboardMode = "expense" | "income";
export type DashboardFlow = "outflows" | "inflows";
export type DashboardPeriodType = "rolling" | "calendar";
export type DashboardSelectedPeriodId = string | null;
export interface DashboardState {
mode: DashboardMode;
flow: DashboardFlow;
periodType: DashboardPeriodType;
selectedPeriodId: DashboardSelectedPeriodId;
selectedGroupKey: GroupKey | null;
@@ -43,7 +43,7 @@ export interface ThemeAwarePalette {
export interface DashboardConfig {
sections: DashboardSection[];
style?: {
palette?: Record<DashboardMode, ThemeAwarePalette>;
palette?: Record<DashboardFlow, ThemeAwarePalette>;
};
}
@@ -51,5 +51,5 @@ export interface DashboardProps {
config: DashboardConfig;
data: ReportData;
isFetching?: boolean;
onModeChange?: (state: DashboardState) => void;
onFlowChange?: (state: DashboardState) => void;
}

View File

@@ -4,24 +4,24 @@ import { DashboardProps, DashboardState } from "./Dashboard.models";
export default function Dashboard(props: DashboardProps) {
const [state, setState] = React.useState<DashboardState>({
mode: "expense",
flow: "outflows",
periodType: "rolling",
selectedPeriodId: null,
selectedGroupKey: null,
comparison: false,
});
const toggleMode = (
const toggleFlow = (
event: React.MouseEvent<HTMLElement>,
newMode: "expense" | "income" | null
newFlow: "outflows" | "inflows" | null
) => {
if (newMode !== null && newMode !== state.mode) {
if (newFlow !== null && newFlow !== state.flow) {
setState(prev => {
const next = {
...prev,
mode: newMode,
flow: newFlow,
};
props.onModeChange?.(next);
props.onFlowChange?.(next);
return next;
});
}
@@ -54,7 +54,7 @@ export default function Dashboard(props: DashboardProps) {
{...props}
state={state}
setState={setState}
toggleMode={toggleMode}
toggleFlow={toggleFlow}
togglePeriodType={togglePeriodType}
toggleComparison={toggleComparison}
setSelectedPeriodId={setSelectedPeriodId}

View File

@@ -14,7 +14,7 @@ import { DashboardProps, DashboardState } from "./Dashboard.models";
interface ViewProps extends DashboardProps {
state: DashboardState;
setState: React.Dispatch<React.SetStateAction<DashboardState>>;
toggleMode: (event: React.MouseEvent<HTMLElement>, newMode: "expense" | "income" | null) => void;
toggleFlow: (event: React.MouseEvent<HTMLElement>, newFlow: "outflows" | "inflows" | null) => void;
togglePeriodType: () => void;
setSelectedPeriodId: (id: string | null) => void;
setSelectedGroupKey: (groupKey: GroupKey | null) => void;
@@ -26,7 +26,7 @@ export default function DashboardView({
data,
state,
setState,
toggleMode,
toggleFlow,
togglePeriodType,
toggleComparison,
setSelectedPeriodId,
@@ -34,11 +34,11 @@ export default function DashboardView({
}: ViewProps) {
const theme = useTheme();
const themeMode = theme.palette.mode;
const { mode, periodType, comparison, selectedPeriodId, selectedGroupKey } = state;
const { flow, periodType, comparison, selectedPeriodId, selectedGroupKey } = state;
// Resolve colors with fallbacks
const colors = React.useMemo(() => {
const palette = config.style?.palette?.[mode];
const palette = config.style?.palette?.[flow];
const modeColors = palette ? palette[themeMode] : null;
if (modeColors) {
@@ -50,13 +50,13 @@ export default function DashboardView({
}
// Fallback to standard theme colors
const themeColor = mode === 'expense' ? theme.palette.error : theme.palette.success;
const themeColor = flow === 'outflows' ? theme.palette.error : theme.palette.success;
return {
primary: themeColor.main,
light: alpha(themeColor.main, themeMode === 'light' ? 0.08 : 0.15),
text: themeColor.main
};
}, [config.style?.palette, mode, themeMode, theme.palette]);
}, [config.style?.palette, flow, themeMode, theme.palette]);
return (
<Container
@@ -71,9 +71,9 @@ export default function DashboardView({
>
<Box sx={{ display: "flex", justifyContent: "center", mb: 3 }}>
<ToggleButtonGroup
value={mode}
value={flow}
exclusive
onChange={toggleMode}
onChange={toggleFlow}
sx={{
borderRadius: 3,
overflow: "hidden",
@@ -89,8 +89,8 @@ export default function DashboardView({
},
}}
>
<ToggleButton value="expense">Expenses</ToggleButton>
<ToggleButton value="income">Income</ToggleButton>
<ToggleButton value="outflows">Outflows</ToggleButton>
<ToggleButton value="inflows">Inflows</ToggleButton>
</ToggleButtonGroup>
</Box>
@@ -118,7 +118,7 @@ export default function DashboardView({
colorScheme={colors}
// State management
mode={mode}
flow={flow}
periodType={periodType}
comparison={comparison}

View File

@@ -54,7 +54,7 @@ function attachComparison(
export function buildChartData(
reportData: ReportData,
key: PeriodKey,
mode: "expense" | "income",
flow: "outflows" | "inflows",
comparison: boolean
): ChartDataPoint[] {
const merged = mergeBucketPeriods(reportData.buckets, key);

View File

@@ -1,5 +1,5 @@
import {
DashboardMode,
DashboardFlow,
DashboardPeriodType,
DashboardSelectedPeriodId
} from "../Dashboard";
@@ -29,7 +29,7 @@ export interface HistoryChartProps {
text: string;
};
mode: DashboardMode;
flow: DashboardFlow;
periodType: DashboardPeriodType;
selectedPeriodId: DashboardSelectedPeriodId;
comparison: boolean;

View File

@@ -7,7 +7,7 @@ export default function HistoryChart(props: HistoryChartProps) {
const {
tabs,
reportData,
mode,
flow,
comparison,
selectedPeriodId,
setSelectedPeriodId
@@ -19,8 +19,8 @@ export default function HistoryChart(props: HistoryChartProps) {
const activeDataKey = tabToKey(activeTab);
const currentData = React.useMemo(() => {
return buildChartData(reportData, activeDataKey, mode, comparison);
}, [reportData, activeDataKey, mode, comparison]);
return buildChartData(reportData, activeDataKey, flow, comparison);
}, [reportData, activeDataKey, flow, comparison]);
const maxAmount =
currentData.length > 0

View File

@@ -35,7 +35,7 @@ export default function HistoryChartView(props: ViewProps) {
tabs,
colorScheme,
mode,
flow,
periodType,
selectedPeriodId,
comparison,

View File

@@ -47,7 +47,7 @@ export function buildLatestItems(
reportData: ReportData,
selectedPeriodId: string | null,
selectedGroupKey: GroupKey | null,
mode: "expense" | "income"
flow: "outflows" | "inflows"
): LatestItem[] {
const txns = extractTransactions(reportData, selectedPeriodId, selectedGroupKey);

View File

@@ -5,7 +5,7 @@ import LatestItemsView from "./LatestItems.view";
type Props = {
reportData: ReportData;
mode: "expense" | "income";
flow: "outflows" | "inflows";
selectedPeriodId: string | null;
selectedGroupKey?: GroupKey | null;
accentColor: string;
@@ -14,7 +14,7 @@ type Props = {
export default function LatestItems({
reportData,
mode,
flow,
selectedPeriodId,
selectedGroupKey = null,
accentColor,
@@ -23,8 +23,8 @@ export default function LatestItems({
const [visibleCount, setVisibleCount] = React.useState(5);
const allItems = React.useMemo(() => {
return buildLatestItems(reportData, selectedPeriodId, selectedGroupKey, mode);
}, [reportData, selectedPeriodId, selectedGroupKey, mode]);
return buildLatestItems(reportData, selectedPeriodId, selectedGroupKey, flow);
}, [reportData, selectedPeriodId, selectedGroupKey, flow]);
const visibleItems = React.useMemo(() => {
return allItems.slice(0, visibleCount);

View File

@@ -11,7 +11,7 @@ export interface TagItem {
export function extractTopTags(
reportData: ReportData,
mode: "expense" | "income",
flow: "outflows" | "inflows",
selectedPeriodId?: string | null
): { items: TagItem[]; total: number } {
const tagMap = new Map<string, number>();

View File

@@ -6,7 +6,7 @@ import { extractTopTags } from "./TopTags.adapter";
type Props = {
reportData: ReportData;
mode: "expense" | "income";
flow: "outflows" | "inflows";
selectedPeriodId?: string | null;
selectedGroupKey?: GroupKey | null;
setSelectedGroupKey?: (key: GroupKey | null) => void;
@@ -16,7 +16,7 @@ type Props = {
export default function TopTags({
reportData,
mode,
flow,
selectedPeriodId,
selectedGroupKey,
setSelectedGroupKey,
@@ -24,8 +24,8 @@ export default function TopTags({
isFetching,
}: Props) {
const { items, total } = React.useMemo(() => {
return extractTopTags(reportData, mode, selectedPeriodId);
}, [reportData, mode, selectedPeriodId]);
return extractTopTags(reportData, flow, selectedPeriodId);
}, [reportData, flow, selectedPeriodId]);
return (
<Box
@@ -48,7 +48,7 @@ export default function TopTags({
progressAmount={item.amount}
totalAmount={total}
compact={compact}
colorTheme={mode === "expense" ? "error" : "success"}
colorTheme={flow === "outflows" ? "error" : "success"}
selected={isSelected}
isFetching={isFetching}
onClick={() => {

View File

@@ -39,7 +39,7 @@ export const configuration: DashboardConfig = {
],
style: {
palette: {
expense: {
outflows: {
light: {
primary: "#d32f2f",
background: "#fdecea",
@@ -51,7 +51,7 @@ export const configuration: DashboardConfig = {
text: "#ffcdd2"
}
},
income: {
inflows: {
light: {
primary: "#2e7d32",
background: "#e8f5e9",