mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 10:44:03 +00:00
feat: add quick payment action and improve copy button UX
Mini App Home Screen: - Add 'Record Payment' button to utilities and rent period cards - Pre-fill payment amount with member's share (rentShare/utilityShare) - Modal dialog with amount input and currency display - Toast notifications for copy and payment success/failure feedback Copy Button Improvements: - Increase spacing between icon and text (4px → 8px) - Add hover background and padding for better touch target - Green background highlight when copied (in addition to icon color change) - Toast notification appears when copying any value Backend: - Add /api/miniapp/payments/add endpoint for quick payments - Payment notifications sent to 'reminders' topic in Telegram - Include member name, payment type, amount, and period in notification Files: - New: apps/miniapp/src/components/ui/toast.tsx - Modified: apps/miniapp/src/routes/home.tsx, apps/miniapp/src/index.css, apps/miniapp/src/theme.css, apps/miniapp/src/i18n.ts, apps/bot/src/miniapp-billing.ts, apps/bot/src/server.ts Quality Gates: ✅ format, lint, typecheck, build, test Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
60
.trae/documents/plan-home-no-payment-and-qa-overrides.md
Normal file
60
.trae/documents/plan-home-no-payment-and-qa-overrides.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Plan: Fix Home “No Payment” + Add QA Period Overrides
|
||||
|
||||
## Goals
|
||||
|
||||
- Remove the “Due” chip from the **No payment period** card.
|
||||
- In **No payment period**, don’t show rent/utilities balances; show only purchase-related balance and household info (FX if available).
|
||||
- Fix “Upcoming” dates so they never show negative days (e.g., “-11d left”); if the reminder/warning already passed in the current period, show the next period’s start date instead.
|
||||
- Add **period/date overrides** to the hidden QA “Testing view” so you can reliably test all Home variants.
|
||||
|
||||
## Changes
|
||||
|
||||
### 1) Home: remove “Due” chip from No-payment card
|
||||
|
||||
- In [home.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/home.tsx), stop rendering the `focusBadge()` inside the `mode() === 'none'` card.
|
||||
- Keep the existing Due/Settled chip behavior for utilities/rent modes unchanged.
|
||||
|
||||
### 2) Home: No-payment mode shows purchases-only balance
|
||||
|
||||
- In [home.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/home.tsx):
|
||||
- When `homeMode() === 'none'`, hide the current “Your balance” card (which includes rent + utilities).
|
||||
- Replace it with a purchases-focused card that shows:
|
||||
- Member purchase offset (from `currentMemberLine().purchaseOffsetMajor`) as the primary amount.
|
||||
- Household purchase totals (count + sum) computed from the existing dashboard ledger entries where `kind === 'purchase'`.
|
||||
- Household member count (from dashboard member lines length).
|
||||
- Keep household informational cards that are not “due/balance for rent/utilities” (e.g., the FX card if present/available).
|
||||
|
||||
### 3) Home: Upcoming utilities/rent start date never goes negative
|
||||
|
||||
- Update upcoming calculations in No-payment mode:
|
||||
- If `daysUntilPeriodDay(period, reminderDay, timezone)` is `>= 0`, show as-is.
|
||||
- If it is `< 0`, compute the next period (`BillingPeriod.fromString(period).next().toString()`) and compute:
|
||||
- `formatPeriodDay(nextPeriod, reminderDay, locale)`
|
||||
- `daysUntilPeriodDay(nextPeriod, reminderDay, timezone)`
|
||||
- Apply the same logic for rent warning day and utilities reminder day.
|
||||
- This ensures “Utilities starts …” always points to a future date and shows a non-negative countdown.
|
||||
|
||||
### 4) QA Testing View: add period/date overrides
|
||||
|
||||
- Extend the existing hidden “Testing view” (opened by 5 taps on the role badge) in:
|
||||
- [shell.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/components/layout/shell.tsx)
|
||||
- [dashboard-context.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/contexts/dashboard-context.tsx)
|
||||
- Add two optional overrides stored in `DashboardContext`:
|
||||
- `testingPeriodOverride?: string | null` (format `YYYY-MM`)
|
||||
- `testingTodayOverride?: string | null` (format `YYYY-MM-DD`)
|
||||
- Home uses `effectivePeriod = testingPeriodOverride ?? dashboard.period`.
|
||||
- Date helpers used by Home (`daysUntilPeriodDay`, `compareTodayToPeriodDay`) accept an optional “today override” so Home can behave as if it’s a different day without changing system time.
|
||||
|
||||
### 5) Copy updates
|
||||
|
||||
- Add/adjust i18n strings needed for the purchases-only card and QA fields in:
|
||||
- [i18n.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/i18n.ts)
|
||||
|
||||
## Verification
|
||||
|
||||
- Run: `bun run format:check`, `bun run lint`, `bun run typecheck`, `bun run test`, `bun run build`
|
||||
- Manual checks in miniapp:
|
||||
- Set QA overrides to land inside utilities window / rent window / no-payment window and confirm Home variant changes.
|
||||
- Confirm no-payment “Upcoming” countdown never shows negative values.
|
||||
- Confirm no-payment mode hides rent/utilities balance and no longer shows “Due” chip on that card.
|
||||
- Confirm no-payment mode shows purchase offset + household purchase stats + member count.
|
||||
@@ -0,0 +1,195 @@
|
||||
# Plan: Miniapp Home “Current Period” + Rent Credentials
|
||||
|
||||
## Summary
|
||||
|
||||
Implement a “current payment period” focused Home screen with three modes:
|
||||
|
||||
- **Utilities period** (between utilities reminder day and utilities due day, inclusive)
|
||||
- **Rent period** (between rent warning day and rent due day, inclusive)
|
||||
- **No payment period** (everything else)
|
||||
|
||||
Add **rent payment credentials** (one-or-more destinations) to the backend + database, editable by admins and visible to all members. Also add a **resident-accessible utility bill submission** flow surfaced on Home during the utilities window when no utility bills are recorded yet.
|
||||
|
||||
## Current State Analysis (repo-grounded)
|
||||
|
||||
### Miniapp UI and data flow
|
||||
|
||||
- Home route today is a single view rendering “Your balance”, optional rent FX, and latest activity, driven by `MiniAppDashboard` from `DashboardContext`.
|
||||
- [home.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/home.tsx#L1-L178)
|
||||
- [dashboard-context.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/contexts/dashboard-context.tsx#L240-L366)
|
||||
- `MiniAppDashboard` already carries `period`, `timezone`, `rentDueDay`, `utilitiesDueDay`, and `paymentBalanceAdjustmentPolicy`, but **does not include** `rentWarningDay` / `utilitiesReminderDay` or any payment destinations.
|
||||
- [miniapp-api.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/miniapp-api.ts#L95-L143)
|
||||
- Date helpers exist to compare “today in timezone” against a day inside a given `period` and to compute days remaining.
|
||||
- [dates.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/lib/dates.ts#L105-L172)
|
||||
|
||||
### Backend / domain
|
||||
|
||||
- Miniapp dashboard API maps `FinanceCommandService.generateDashboard()` into `MiniAppDashboard`.
|
||||
- [miniapp-dashboard.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-dashboard.ts#L12-L150)
|
||||
- `FinanceDashboard` is built from billing settings + cycle state; it uses `rentWarningDay` and `utilitiesReminderDay` internally for FX lock dates, but it currently only exposes `rentDueDay` and `utilitiesDueDay` to the miniapp.
|
||||
- [finance-command-service.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/application/src/finance-command-service.ts#L287-L599)
|
||||
- Billing settings are persisted in Postgres via Drizzle table `household_billing_settings` (already includes rent/utilities due and reminder/warning days + timezone).
|
||||
- [schema.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/db/src/schema.ts#L24-L50)
|
||||
- Repository accessors: [household-config-repository.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/adapters-db/src/household-config-repository.ts#L944-L1066)
|
||||
- Utility bills are currently **admin-only** in the miniapp (`/api/miniapp/admin/utility-bills/add`) and the UI hides add/edit behind `effectiveIsAdmin()`.
|
||||
- UI: [ledger.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/ledger.tsx#L617-L652)
|
||||
- API handler: [miniapp-billing.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-billing.ts#L721-L790)
|
||||
|
||||
## Proposed Changes (decision-complete)
|
||||
|
||||
### 1) Add rent payment destinations to DB + ports
|
||||
|
||||
**Decision:** store rent credentials as a JSON array on `household_billing_settings` to support multiple destinations without introducing a new table (pre-1.0 simplicity + cohesion with billing config).
|
||||
|
||||
- Add a new `jsonb` column on `household_billing_settings`:
|
||||
- `rent_payment_destinations` (nullable, default `null`)
|
||||
- Add a strongly-typed record shape in ports:
|
||||
- `HouseholdRentPaymentDestination`:
|
||||
- `label: string` (e.g., “TBC card”, “Bank transfer”)
|
||||
- `recipientName: string | null`
|
||||
- `bankName: string | null`
|
||||
- `account: string` (account number / card number / IBAN; stored as plain text)
|
||||
- `note: string | null`
|
||||
- `link: string | null` (optional URL/deeplink)
|
||||
- Add `rentPaymentDestinations?: readonly HouseholdRentPaymentDestination[] | null` to `HouseholdBillingSettingsRecord` and the `updateHouseholdBillingSettings` input.
|
||||
|
||||
Files:
|
||||
|
||||
- DB schema + migration:
|
||||
- [schema.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/db/src/schema.ts)
|
||||
- `packages/db/drizzle/00xx_*.sql` (new migration)
|
||||
- Ports:
|
||||
- [household-config.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/ports/src/household-config.ts)
|
||||
- DB adapter mapping:
|
||||
- [household-config-repository.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/adapters-db/src/household-config-repository.ts#L944-L1066)
|
||||
|
||||
### 2) Expose needed fields to the miniapp dashboard contract
|
||||
|
||||
**Goal:** let the miniapp compute “current period” locally and render period-specific UI consistently.
|
||||
|
||||
- Extend `FinanceDashboard` to include:
|
||||
- `rentWarningDay`
|
||||
- `utilitiesReminderDay`
|
||||
- `rentPaymentDestinations`
|
||||
- Return these from `buildFinanceDashboard(...)` using the persisted billing settings.
|
||||
- Extend bot miniapp dashboard handler serialization:
|
||||
- Include those fields in the `dashboard` JSON payload.
|
||||
- Extend miniapp client types:
|
||||
- `MiniAppDashboard` adds `rentWarningDay`, `utilitiesReminderDay`, and `rentPaymentDestinations`.
|
||||
- Update demo fixtures so the miniapp still renders in demo mode.
|
||||
|
||||
Files:
|
||||
|
||||
- Application:
|
||||
- [finance-command-service.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/application/src/finance-command-service.ts)
|
||||
- Bot:
|
||||
- [miniapp-dashboard.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-dashboard.ts)
|
||||
- Miniapp API types + demo:
|
||||
- [miniapp-api.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/miniapp-api.ts)
|
||||
- [miniapp-demo.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/demo/miniapp-demo.ts)
|
||||
|
||||
### 3) Add admin editing UI for rent payment destinations
|
||||
|
||||
**Decision:** rent credentials are visible to everyone, but **only admins can edit** (implemented in Settings screen next to other billing settings).
|
||||
|
||||
- Extend the Settings “Billing settings” modal form state to include a list editor:
|
||||
- Add destination
|
||||
- Remove destination
|
||||
- Edit fields (label, recipient, bank, account, note, link)
|
||||
- Extend `updateMiniAppBillingSettings(...)` request/response types to carry the new field.
|
||||
- Extend backend handler that parses settings update payload and calls `updateHouseholdBillingSettings`.
|
||||
|
||||
Files:
|
||||
|
||||
- Miniapp:
|
||||
- [settings.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/settings.tsx)
|
||||
- [miniapp-api.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/miniapp-api.ts) (`MiniAppBillingSettings` + `updateMiniAppBillingSettings`)
|
||||
- [i18n.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/i18n.ts) (new strings)
|
||||
- Bot:
|
||||
- [miniapp-admin.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-admin.ts) (payload parsing)
|
||||
- Application:
|
||||
- [miniapp-admin-service.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/application/src/miniapp-admin-service.ts) (include field into repository update input)
|
||||
|
||||
### 4) Implement “3 versions of Home” (utilities / rent / no payment)
|
||||
|
||||
**Decision:** Home determines an active mode as “Reminder→Due” (inclusive). It uses:
|
||||
|
||||
- `dashboard.period`
|
||||
- `dashboard.timezone`
|
||||
- `dashboard.utilitiesReminderDay` / `dashboard.utilitiesDueDay`
|
||||
- `dashboard.rentWarningDay` / `dashboard.rentDueDay`
|
||||
|
||||
#### 4.1 Utilities mode
|
||||
|
||||
- Show a primary “Utilities” card:
|
||||
- Amount to pay = utilities base share + purchase offset if policy is `utilities`
|
||||
- Show due date and days left using existing copy keys (`dueOnLabel`, `daysLeftLabel`, etc.)
|
||||
- If **no utility bills recorded yet** (`utilityLedger().length === 0`):
|
||||
- Show an inline “Fill utilities” call-to-action:
|
||||
- A simple add-utility-bill form embedded on Home (visible to all members).
|
||||
- After successful submission + refresh, the CTA disappears and the normal utilities card renders.
|
||||
- Optional: provide a link to the Ledger screen as fallback (if the user prefers to do it there).
|
||||
|
||||
#### 4.2 Rent mode
|
||||
|
||||
- Show a primary “Rent” card:
|
||||
- Amount to pay = rent base share + purchase offset if policy is `rent`
|
||||
- Show due date and days left/overdue visuals.
|
||||
- Show one-or-more “Payment destination” cards listing:
|
||||
- Label, recipient, bank, account, note/link
|
||||
|
||||
#### 4.3 No payment mode
|
||||
|
||||
- Show an “Upcoming” card:
|
||||
- Days until utilities reminder day
|
||||
- Days until rent warning day
|
||||
- Continue to show “Your balance” and latest activity as secondary content (so the screen stays useful).
|
||||
|
||||
Files:
|
||||
|
||||
- [home.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/home.tsx)
|
||||
- Potentially add a tiny helper in `apps/miniapp/src/lib/` for `computeHomePeriodMode(...)` if Home gets too large.
|
||||
- [i18n.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/i18n.ts) (strings for new cards/actions)
|
||||
|
||||
### 5) Allow non-admin utility bill submission (for Home CTA)
|
||||
|
||||
**Decision:** add a new miniapp endpoint that allows any authorized member to add a utility bill, used by the Home CTA. Admin endpoints remain unchanged for editing/deleting.
|
||||
|
||||
- Add a new bot handler:
|
||||
- `POST /api/miniapp/utility-bills/add` (name can be finalized during implementation)
|
||||
- Auth: authorized member session required
|
||||
- Action: call `FinanceCommandService.addUtilityBill(billName, amountMajor, memberId, currency)`
|
||||
- Response: `{ ok, authorized, cycleState }` or `{ ok, error }`
|
||||
- Wire it into the bot server router.
|
||||
- Add a miniapp client function to call it (parallel to `addMiniAppUtilityBill`, but non-admin path).
|
||||
- Home CTA uses this endpoint, then triggers `refreshHouseholdData(true, true)` so the dashboard updates.
|
||||
|
||||
Files:
|
||||
|
||||
- Bot:
|
||||
- [miniapp-billing.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-billing.ts) (new handler)
|
||||
- [server.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/server.ts) (new route option + dispatch)
|
||||
- [index.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/index.ts) (compose and pass the new handler into `createBotWebhookServer`)
|
||||
- Miniapp:
|
||||
- [miniapp-api.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/miniapp-api.ts) (new function)
|
||||
- [home.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/home.tsx) (use it)
|
||||
|
||||
## Assumptions & Decisions
|
||||
|
||||
- Period selection is **Reminder→Due inclusive** (utilities: `utilitiesReminderDay..utilitiesDueDay`, rent: `rentWarningDay..rentDueDay`).
|
||||
- Rent payment credentials are **structured** and stored as **plain text** fields (no secrets); they are visible to all household members and editable by admins only.
|
||||
- Utilities “fill” flow is initially “rent-only credentials now”; utilities destinations are out of scope.
|
||||
- Utility bill submission from Home is allowed for any authorized member; edit/delete remains admin-only.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
- Typecheck, lint, test, build (repo quality gates):
|
||||
- `bun run format:check`
|
||||
- `bun run lint`
|
||||
- `bun run typecheck`
|
||||
- `bun run test`
|
||||
- `bun run build`
|
||||
- Manual miniapp checks:
|
||||
- Home renders correctly in all 3 modes by adjusting due/reminder days in Settings.
|
||||
- Utilities window + no bills: Home CTA allows submission and then switches to normal utilities view after refresh.
|
||||
- Rent window: rent credentials render correctly; multiple destinations show; admin edits persist and reload.
|
||||
62
.trae/documents/ui_tweaks_and_reactivity.md
Normal file
62
.trae/documents/ui_tweaks_and_reactivity.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Plan - UI Tweaks and Reactive Updates
|
||||
|
||||
This plan outlines the changes needed to ensure data reactivity after updates, improve chart visibility with better colors, and enhance the "Latest activity" section with a "show more" functionality.
|
||||
|
||||
## 1. Reactive Data Updates
|
||||
|
||||
### Analysis
|
||||
|
||||
Currently, when a purchase or payment is added in [ledger.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/ledger.tsx), `refreshHouseholdData(true, true)` is called. This function invalidates the TanStack Query cache in [session-context.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/contexts/session-context.tsx), but [DashboardProvider](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/contexts/dashboard-context.tsx) stores data in local signals (`setDashboard`) and does not automatically refetch when the cache is invalidated.
|
||||
|
||||
### Proposed Changes
|
||||
|
||||
- **session-context.tsx**:
|
||||
- Add a way to register "data listeners" or simply a list of refresh callbacks.
|
||||
- Update `refreshHouseholdData` to execute these callbacks.
|
||||
- **dashboard-context.tsx**:
|
||||
- In `DashboardProvider`, register `loadDashboardData` as a listener in the session context on mount.
|
||||
- **App.tsx**:
|
||||
- Ensure `DashboardProvider` is correctly integrated with the session's refresh mechanism.
|
||||
|
||||
## 2. Chart Colors Improvement
|
||||
|
||||
### Analysis
|
||||
|
||||
Current chart colors in [dashboard-context.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/contexts/dashboard-context.tsx) and [theme.css](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/theme.css) are somewhat similar, making them hard to distinguish.
|
||||
|
||||
### Proposed Changes
|
||||
|
||||
- **dashboard-context.tsx**:
|
||||
- Update `chartPalette` with more distinct, high-contrast colors.
|
||||
- Proposed palette: `#3ecf8e` (Emerald), `#3b82f6` (Blue), `#ef4444` (Red), `#f59e0b` (Amber), `#8b5cf6` (Violet), `#ec4899` (Pink).
|
||||
- **theme.css**:
|
||||
- Update `--chart-1` through `--chart-6` variables to match the new palette for consistency across the app.
|
||||
|
||||
## 3. "Show More" for Latest Activity
|
||||
|
||||
### Analysis
|
||||
|
||||
The "Latest activity" section in [home.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/home.tsx) currently only shows the first 5 entries of the ledger.
|
||||
|
||||
### Proposed Changes
|
||||
|
||||
- **home.tsx**:
|
||||
- Add a local signal `showAllActivity` (default `false`).
|
||||
- Update the `For` loop to show either `slice(0, 5)` or the full `ledger` based on the signal.
|
||||
- Add a "Show more" button that appears if `ledger.length > 5`.
|
||||
- Style the button to match the app's UI.
|
||||
- **i18n.ts**:
|
||||
- Add translations for "Show more" and "Show less" (or "Collapse").
|
||||
|
||||
## Verification Plan
|
||||
|
||||
### Automated Tests
|
||||
|
||||
- Since this is mostly UI/UX, manual verification in the browser is preferred.
|
||||
- Check if `invalidateQueries` is called after adding a purchase (can be checked via network tab).
|
||||
|
||||
### Manual Verification
|
||||
|
||||
1. **Reactivity**: Add a purchase and verify that the dashboard balances and "Latest activity" update immediately without manual page refresh.
|
||||
2. **Chart Colors**: Navigate to the balances page and verify that chart slices are easily distinguishable.
|
||||
3. **Show More**: On the home page, ensure "Show more" appears when there are > 5 activities and correctly expands the list.
|
||||
Reference in New Issue
Block a user