diff --git a/.changelogs/v0.26.0.md b/.changelogs/v0.26.0.md new file mode 100644 index 0000000..ae51783 --- /dev/null +++ b/.changelogs/v0.26.0.md @@ -0,0 +1,61 @@ +# Release v0.26.0 - Smart Stock Fund Notifications + +Released: 2026-01-18 + +## Overview + +This release improves the user experience by intelligently suppressing stock fund action prompts when the US stock market is closed, and fixes a visual alignment issue in entry forms. + +## New Features + +### Market-Aware Stock Fund Notifications +- **Weekend detection**: Stock funds no longer prompt for action on Saturdays and Sundays +- **Holiday detection**: Stock funds skip prompts on all major US stock market holidays: + - New Year's Day (with weekend observance) + - Martin Luther King Jr. Day (3rd Monday of January) + - Presidents Day (3rd Monday of February) + - Good Friday (Friday before Easter) + - Memorial Day (Last Monday of May) + - Juneteenth (June 19, with weekend observance) + - Independence Day (July 4, with weekend observance) + - Labor Day (1st Monday of September) + - Thanksgiving (4th Thursday of November) + - Christmas (December 25, with weekend observance) +- **Applies to**: ActionableFundsBanner on dashboard and nav badge count +- **Other fund types unaffected**: Crypto, cash, and derivatives funds still prompt as normal (24/7 markets) + +### GitHub App Link +- Added link to the GitHub App installation page + +## Bug Fixes + +### Form Input Alignment +- Fixed an issue where the "Update first" wizard indicator caused the Equity input field to be pushed down relative to the Date field +- Applied consistent fixed-height label rows (`h-5`) across all form fields with wizard indicators +- Affects both Cash Balance and standard trading fund entry forms + +## Technical Details + +### New Utility Functions +- `isStockMarketClosed(date?)`: Check if US stock market is closed on a given date +- `isUSMarketHoliday(date)`: Internal helper for holiday detection +- `calculateEaster(year)`: Easter calculation for Good Friday determination + +### Files Changed +- `packages/web/src/utils/format.ts` - Added market closed detection utilities +- `packages/web/src/components/ActionableFundsBanner.tsx` - Filter stock funds on market closed days +- `packages/web/src/components/Layout.tsx` - Apply same filter to nav badge count +- `packages/web/src/components/EntryForm.tsx` - Fixed label row heights for alignment + +## Installation + +```bash +git clone https://github.com/atomantic/EscapeMint.git +cd EscapeMint +npm run setup +npm run dev +``` + +## Full Changelog + +**Full Diff**: https://github.com/atomantic/EscapeMint/compare/v0.25.0...v0.26.0 diff --git a/package-lock.json b/package-lock.json index cbf9ea9..f06fe1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "escapemint", - "version": "0.25.0", + "version": "0.26.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "escapemint", - "version": "0.25.0", + "version": "0.26.0", "license": "MIT", "workspaces": [ "packages/*" diff --git a/package.json b/package.json index 6029a5a..76160c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "escapemint", - "version": "0.25.0", + "version": "0.26.0", "type": "module", "private": true, "description": "A local-first, open-source capital allocation engine for rules-based fund management", diff --git a/packages/web/src/components/ActionableFundsBanner.tsx b/packages/web/src/components/ActionableFundsBanner.tsx index 99f81eb..9c6801a 100644 --- a/packages/web/src/components/ActionableFundsBanner.tsx +++ b/packages/web/src/components/ActionableFundsBanner.tsx @@ -3,6 +3,7 @@ import { Link } from 'react-router-dom' import { fetchActionableFunds, FUNDS_CHANGED_EVENT, type ActionableFund } from '../api/funds' import { getFundTypeFeatures } from '@escapemint/engine' import { useSettings } from '../contexts/SettingsContext' +import { isStockMarketClosed } from '../utils/format' // Days overdue threshold for high urgency styling (red border) const URGENCY_THRESHOLD_DAYS = 7 @@ -73,7 +74,17 @@ export function ActionableFundsBanner() { notifyActionableDismissed(newVisibleCount) } - const visibleFunds = actionableFunds.filter(f => !dismissed.has(f.id)) + // Check if stock market is closed (weekend or holiday) + // No memoization needed - lightweight check that updates correctly when data refreshes + const marketClosed = isStockMarketClosed() + + // Filter out dismissed funds and stock funds when market is closed + const visibleFunds = actionableFunds.filter(f => { + if (dismissed.has(f.id)) return false + // Skip stock funds on weekends/holidays since market is closed + if (marketClosed && f.fundType === 'stock') return false + return true + }) // Notify on initial load and when actionable funds change useEffect(() => { diff --git a/packages/web/src/components/EntryForm.tsx b/packages/web/src/components/EntryForm.tsx index 6d1e2ae..47cc1d2 100644 --- a/packages/web/src/components/EntryForm.tsx +++ b/packages/web/src/components/EntryForm.tsx @@ -106,9 +106,10 @@ export const parseFormulaValue = (input: string): number => { } // Wizard indicator component - animated arrow pointing to a field +// Uses absolute positioning to avoid affecting vertical layout function WizardIndicator({ label }: { label: string }) { return ( -
Historical data: SPXL (3x Russell 1000), VTI (Total US Market), BRGNX (Russell 1000), TQQQ (3x NASDAQ), BTC (Bitcoin)
All calculations run in-browser using EscapeMint engine
+