diff --git a/HISTORY.md b/HISTORY.md index 4201f1e..1cfcad9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -183,7 +183,7 @@ ### Release Image -![Doing my part](/img/doingmypart.jpg) +![Bill Tracker release preview](/brand/social-preview.png) --- @@ -301,7 +301,7 @@ ### Release Image -![Doing my part](/img/doingmypart.jpg) +![Bill Tracker release preview](/brand/social-preview.png) --- @@ -433,7 +433,7 @@ ### Release Image -![Doing my part](/img/doingmypart.jpg) +![Bill Tracker release preview](/brand/social-preview.png) --- ## v0.35.1 @@ -448,7 +448,7 @@ ### Release Image -![Doing my part](/img/doingmypart.jpg) +![Bill Tracker release preview](/brand/social-preview.png) --- ## v0.35.0 @@ -467,7 +467,7 @@ ### Release Image -![Doing my part](/img/doingmypart.jpg) +![Bill Tracker release preview](/brand/social-preview.png) --- ## v0.34.3 @@ -516,7 +516,7 @@ ### Release Image -![Doing my part](/img/doingmypart.jpg) +![Bill Tracker release preview](/brand/social-preview.png) --- ## v0.34.2 @@ -806,7 +806,7 @@ ### Release Image -![Doing my part](/img/doingmypart.jpg) +![Bill Tracker release preview](/brand/social-preview.png) ## v0.28.0 @@ -821,7 +821,7 @@ - **Login device details** — Login history now stores parsed browser, OS, device type, and a short privacy-preserving device fingerprint hash derived from user-agent plus coarse IP prefix. The Profile login history dialog shows the richer device details to help users recognize their own sign-ins. - **Profile last-login card** — The Profile summary now shows the most recent login date, IP address, device type, browser, and OS inline. Clicking the modern last-login card opens the full login history modal with device IDs and recent sign-in details. - **Public privacy page** — Added public `/api/privacy` and `/privacy` pages with a modern, scan-friendly policy layout, plus an About page Privacy button. The Profile login-history modal now notes that login device details are shown only to the user and are not shared with admins in the app UI. -- **Release notes image support** — Release notes now render Markdown image blocks in a centered responsive frame, and the in-app release notes dialog displays the `doingmypart.jpg` release image at the end of the v0.28.0 entry. +- **Release notes image support** — Release notes now render Markdown image blocks in a centered responsive frame, and the in-app release notes dialog displays branded release art at the end of the v0.28.0 entry. - **Backend-controlled update card reset** — The “What’s new” card now relies only on the backend `last_seen_version` check. `/api/auth/me` exposes the active `release_notes_version`, acknowledging an update stores that version, and any future package-version update will automatically show the card again for users who have not seen it. - **Instant bill search and filters** — Bills and Tracker now include search inputs for quickly finding bills by name, category, notes, or amount. Bills adds category, billing-cycle, autopay, due-bucket, debt, and inactive filters; Tracker adds current-month category, billing-cycle, unpaid, overdue, autopay, due-bucket, and debt filters. - **Command palette bill lookup** — Added a global Ctrl+K command palette for finding bills by name, category, notes, due details, or amount, with quick jumps into Bills or the current Tracker search. @@ -858,7 +858,7 @@ ### Release Image -![Doing my part](/img/doingmypart.jpg) +![Bill Tracker release preview](/brand/social-preview.png) ## v0.27.04 diff --git a/client/components/admin/AuthMethodsCard.tsx b/client/components/admin/AuthMethodsCard.tsx index c71682e..b5240c7 100644 --- a/client/components/admin/AuthMethodsCard.tsx +++ b/client/components/admin/AuthMethodsCard.tsx @@ -7,7 +7,7 @@ import { Input } from '@/components/ui/input'; import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; import { FieldRow, Toggle } from './adminShared'; -const AUTHENTIK_ICON_URL = '/img/auth.png'; +const OIDC_ICON_URL = '/img/auth.svg'; interface OidcForm { local_login_enabled: boolean; @@ -248,7 +248,7 @@ export default function AuthMethodsCard() {
{ e.preventDefault(); @@ -455,17 +454,15 @@ export default function LoginPage() { window.location.href = authMode?.oidc_login_url || ''; }} > - {isAuthentikProvider && ( - { - (e.target as HTMLImageElement).style.display = 'none'; - }} - /> - )} + { + (e.target as HTMLImageElement).style.display = 'none'; + }} + /> Continue with {providerName} )} diff --git a/client/public/brand/logo.png b/client/public/brand/logo.png index 47f76e2..c116585 100644 Binary files a/client/public/brand/logo.png and b/client/public/brand/logo.png differ diff --git a/client/public/img/auth.png b/client/public/img/auth.png index b004273..bf8de61 100644 Binary files a/client/public/img/auth.png and b/client/public/img/auth.png differ diff --git a/client/public/img/auth.svg b/client/public/img/auth.svg index 6fd48b0..9ad7039 100644 --- a/client/public/img/auth.svg +++ b/client/public/img/auth.svg @@ -1,11 +1,27 @@ - - - - + + Bill Tracker secure access + A dark security shield with a green confirmation check and teal connection points. + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/img/doingmypart.jpg b/client/public/img/doingmypart.jpg deleted file mode 100644 index af1a8dc..0000000 Binary files a/client/public/img/doingmypart.jpg and /dev/null differ diff --git a/client/public/img/logo.png b/client/public/img/logo.png index c54b46f..2eb1dd2 100644 Binary files a/client/public/img/logo.png and b/client/public/img/logo.png differ diff --git a/docs/BRAND.md b/docs/BRAND.md index e3c3b69..9d3fd14 100644 --- a/docs/BRAND.md +++ b/docs/BRAND.md @@ -32,14 +32,14 @@ The visual lane is **premium calm**. ## Core Colors -| Token | Hex | Use | -| --- | --- | --- | -| Ink | `#101417` | Dark app shell, mark background, premium depth | -| Paper | `#f8faf9` | Light app background, high-contrast text on dark | +| Token | Hex | Use | +| ----- | --------- | --------------------------------------------------- | +| Ink | `#101417` | Dark app shell, mark background, premium depth | +| Paper | `#f8faf9` | Light app background, high-contrast text on dark | | Trust | `#40c878` | Primary actions, brand mark, success, active states | -| Teal | `#23b6a8` | Bank sync, data flow, secondary brand accent | -| Amber | `#d99a24` | Due soon, warnings, drift, review-needed states | -| Rose | `#df4661` | Overdue, destructive, high urgency | +| Teal | `#23b6a8` | Bank sync, data flow, secondary brand accent | +| Amber | `#d99a24` | Due soon, warnings, drift, review-needed states | +| Rose | `#df4661` | Overdue, destructive, high urgency | The app implementation maps these through OKLCH theme tokens in `client/index.css`; do not hardcode the hex values in components unless creating static brand assets. @@ -49,7 +49,7 @@ Primary source files live in `client/public/brand/`. - `lockup.svg` - primary logo for dark surfaces. - `lockup-light.svg` - primary logo for light surfaces. -- `logo.png` - raster export of the primary logo for docs and non-SVG contexts. +- `logo.png` - light-surface raster export of the primary logo for docs and non-SVG contexts. - `mark.svg` - compact app mark and favicon. - `mark.png` - raster export of the compact app mark. - `mark-mono.svg` - single-color mark for constrained contexts. @@ -59,6 +59,11 @@ Primary source files live in `client/public/brand/`. - `pwa-192.png`, `pwa-512.png`, `pwa-maskable.svg`, `pwa-maskable-512.png`, `apple-touch-icon.png` - install surfaces. - `glyphs/*.svg` - standalone product glyph source files. +Supporting app artwork: + +- `client/public/img/auth.svg` - branded secure-access glyph for OIDC/authentication surfaces. +- `client/public/img/auth.png` - raster fallback export of the secure-access glyph. + Rules: - Use the full lockup when the product needs to introduce itself. @@ -70,15 +75,15 @@ Rules: Bill Tracker has a small proprietary product glyph set for page identity only: -| Product area | Asset | -| --- | --- | -| Tracker | `client/public/brand/glyphs/tracker.svg` | -| Bills | `client/public/brand/glyphs/bills.svg` | -| Calendar | `client/public/brand/glyphs/calendar.svg` | -| Analytics | `client/public/brand/glyphs/analytics.svg` | -| Data / Banking | `client/public/brand/glyphs/data-banking.svg` | +| Product area | Asset | +| ----------------- | ------------------------------------------------ | +| Tracker | `client/public/brand/glyphs/tracker.svg` | +| Bills | `client/public/brand/glyphs/bills.svg` | +| Calendar | `client/public/brand/glyphs/calendar.svg` | +| Analytics | `client/public/brand/glyphs/analytics.svg` | +| Data / Banking | `client/public/brand/glyphs/data-banking.svg` | | Snowball / Payoff | `client/public/brand/glyphs/snowball-payoff.svg` | -| Admin / Security | `client/public/brand/glyphs/admin-security.svg` | +| Admin / Security | `client/public/brand/glyphs/admin-security.svg` | Rules: @@ -86,6 +91,7 @@ Rules: - Keep Lucide icons for actions, controls, menus, buttons, tables, and common UI patterns. - Never replace familiar action icons such as edit, delete, search, settings, upload, download, calendar navigation, or logout. - Glyphs should reuse the mark language: bars, checks, ledger lines, quiet rounded geometry. +- Avoid third-party-style or novelty images inside core app surfaces unless the product explicitly needs a partner logo. ## Typography diff --git a/docs/Engineering_Reference_Manual.md b/docs/Engineering_Reference_Manual.md index 526ff3f..a356a76 100644 --- a/docs/Engineering_Reference_Manual.md +++ b/docs/Engineering_Reference_Manual.md @@ -1222,7 +1222,11 @@ The lazy audit helper in `db/database.js` is: let _logAudit = null; function getLogAudit() { if (!_logAudit) { - try { _logAudit = require('../services/auditService').logAudit; } catch { _logAudit = () => {}; } + try { + _logAudit = require('../services/auditService').logAudit; + } catch { + _logAudit = () => {}; + } } return _logAudit; } @@ -1255,7 +1259,7 @@ Creates the React root and wraps `App` with global providers. Theme is provided ### `client/App.tsx` - Creates a TanStack `QueryClient` with: - - Global `QueryCache.onError` — toasts a `sonner` error when a *background* refetch fails while stale data is on screen. Pages render inline errors on the initial load so the toast only fires for refetches. + - Global `QueryCache.onError` — toasts a `sonner` error when a _background_ refetch fails while stale data is on screen. Pages render inline errors on the initial load so the toast only fires for refetches. - `staleTime: 2 * 60 * 1000`, `retry: 1`, `refetchOnWindowFocus: false`. - Uses lazy loading and `Suspense` with `PageLoader` for most pages. - Wraps route elements in `ErrorBoundary`; pages further wrap in `PageTransition`. @@ -1310,8 +1314,8 @@ Routes (all rendered through `Routes` with `ErrorBoundary`, lazy + `Suspense` fo - Exposes grouped functions for `auth`, `admin`, `notifications`, `profile`, `tracker`, `calendar`, `summary`, `bills`, `payments`, `categories`, `settings`, `analytics`, `status`, `version`/`about`, `import`, `export`, `data-sources`, `transactions`, `matches`, `snowball`, `subscriptions`, `spending`, `monthlyStartingAmounts`, `csvImport`, `matchSuggestions`, `bankTransactionsLedger`, `matchTransaction`, `unmatchTransaction`, `ignoreTransaction`, `unignoreTransaction`, `applyTransactionMerchantMatch`, `autoCategorizeTransactions`, `categoryGroups`, `copySpendingBudgets`, `spendingIncome`, `spendingCategoryRules`, `createPaymentOrConfirm` (via `client/lib/paymentActions.ts`). - File download/upload endpoints use raw `fetch` because responses/bodies are blobs or octet streams. - **All 16 import sites** that referenced `@/api.js` were normalized to `@/api` so Vite/TS resolve the `.ts`. -- **Track C response typing** — see §7 *Domain types* for the full list. In short, the high-traffic domains (`auth`, `bills`, `payments`, `categories`, `tracker`, `snowball`, `subscriptions`, `spending`, `bank-ledger`) all return typed responses via `get` / `post`; the remaining single-consumer non-money casts (adminUsers, version/about/privacy/health/importHistory) are deliberately left as-is. -- **Server error-shape consistency (Track D).** The global 500 handler in `server.js` emits `{ error, code: 'INTERNAL_ERROR' }` so an unexpected server error carries the same `{error, code}` field the client can switch on as every structured 4xx. See §5 *Response conventions*. +- **Track C response typing** — see §7 _Domain types_ for the full list. In short, the high-traffic domains (`auth`, `bills`, `payments`, `categories`, `tracker`, `snowball`, `subscriptions`, `spending`, `bank-ledger`) all return typed responses via `get` / `post`; the remaining single-consumer non-money casts (adminUsers, version/about/privacy/health/importHistory) are deliberately left as-is. +- **Server error-shape consistency (Track D).** The global 500 handler in `server.js` emits `{ error, code: 'INTERNAL_ERROR' }` so an unexpected server error carries the same `{error, code}` field the client can switch on as every structured 4xx. See §5 _Response conventions_. ### Domain types — `client/types.ts` @@ -1514,7 +1518,7 @@ Forgejo Actions runs on every push and PR: `actions/checkout@v4` on `node:22-boo ### Vite (`vite.config.mjs`) - `@vitejs/plugin-react` with `babel-plugin-react-compiler` enabled (React 19 auto-memoization). The codebase is rules-of-hooks clean (enforced by `eslint-plugin-react-hooks`). -- `vite-plugin-pwa` with `registerType: 'autoUpdate'`, manifest, icons in `client/public/img/`, runtime caching for `/api/(tracker|bills|calendar|summary|analytics|snowball|categories)` via `NetworkFirst` (5s network timeout, 30-entry max, 5-min max-age). +- `vite-plugin-pwa` with `registerType: 'autoUpdate'`, manifest, icons in `client/public/brand/`, runtime caching for `/api/(tracker|bills|calendar|summary|analytics|snowball|categories)` via `NetworkFirst` (5s network timeout, 30-entry max, 5-min max-age). - `__APP_VERSION__` is injected at build time from `package.json`; the SPA reads it through `client/lib/version.ts`. - Manual chunk splitting: `vendor-react` (react / react-dom / react-router-dom), `vendor-radix` (dialog / select / dropdown-menu / tabs / tooltip / alert-dialog), `vendor-motion` (framer-motion), `vendor-query` (@tanstack/react-query + @tanstack/react-virtual). - `resolve.alias['@']` → `client/`, matches the Vite alias and the `tsconfig.json` `paths` mapping. diff --git a/docs/images/logo_cut.png b/docs/images/logo_cut.png index c54b46f..2eb1dd2 100644 Binary files a/docs/images/logo_cut.png and b/docs/images/logo_cut.png differ diff --git a/img/auth.png b/img/auth.png index b004273..bf8de61 100644 Binary files a/img/auth.png and b/img/auth.png differ diff --git a/img/logo.png b/img/logo.png index c54b46f..2eb1dd2 100644 Binary files a/img/logo.png and b/img/logo.png differ diff --git a/img/logo_cut.png b/img/logo_cut.png index c54b46f..2eb1dd2 100644 Binary files a/img/logo_cut.png and b/img/logo_cut.png differ diff --git a/vite.config.mjs b/vite.config.mjs index 3c15c18..1dea229 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -36,6 +36,7 @@ export default defineConfig({ 'brand/empty-state.svg', 'brand/social-preview.svg', 'brand/social-preview.png', + 'img/auth.svg', 'brand/pwa-maskable.svg', 'brand/glyphs/tracker.svg', 'brand/glyphs/bills.svg',