toga-ai 1.0.168 → 1.0.169
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/knowledge/INDEX.md
CHANGED
|
@@ -21,7 +21,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
21
21
|
- **dbchanges2** (Database Changes) _(framework core)_ — 1 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
|
|
22
22
|
- **toga2-supply** (TOGa Supply) — 3 doc(s) → [2.0/apps/toga2-supply/INDEX.md](2.0/apps/toga2-supply/INDEX.md)
|
|
23
23
|
- **saml** (SAML SSO Gateway) — 2 doc(s) → [2.0/apps/saml/INDEX.md](2.0/apps/saml/INDEX.md)
|
|
24
|
-
- **toga2-view** (TOGa View Frontend) —
|
|
24
|
+
- **toga2-view** (TOGa View Frontend) — 1 doc(s) → [2.0/apps/toga2-view/INDEX.md](2.0/apps/toga2-view/INDEX.md)
|
|
25
25
|
- **toga2-hub** (TOGa Hub) — 2 doc(s) → [2.0/apps/toga2-hub/INDEX.md](2.0/apps/toga2-hub/INDEX.md)
|
|
26
26
|
- **talos** (TOGa IQ) — 6 doc(s) → [2.0/apps/talos/INDEX.md](2.0/apps/talos/INDEX.md)
|
|
27
27
|
- **voice-to-voice** (TOGa Voice) — 4 doc(s) → [2.0/apps/voice-to-voice/INDEX.md](2.0/apps/voice-to-voice/INDEX.md)
|
|
@@ -4,4 +4,5 @@
|
|
|
4
4
|
|-----|-----------|---------|-------|
|
|
5
5
|
| [Rate Monthly Reconciliation Report](features/monthly-reconciliation-report.md) | 1.0 | A monthly cron that emails an Excel reconciliation report covering all Rate subscription sales orders and their linked PayPal payments for the prior calendar mo | worker/crons/notifications/reports/rate/send_monthly_rate_purchases_report.php, worker/schedules/cron.worker.notification.json |
|
|
6
6
|
| [Rate SAML SSO](features/saml-sso.md) | 2.0 | Rate uses Azure AD as its IdP (`login.rate.com`). | _underscore/Model/Rate/ClientAuthentication.php, saml/Controller/Index.php, toga2-view/src/hooks/useAuthenticationFlow.ts |
|
|
7
|
+
| [Service Card Entitlement Display](features/service-card-entitlements.md) | 2.0 | Rate's home and services pages display one service card per purchased entitlement. | src/components/ServiceCard/ServiceCard.tsx, src/components/ServiceCard/index.ts, src/hooks/useBundleServices.ts, src/pages/Home/api/homeApi.ts, src/pages/Home/view/HomePage.tsx, src/pages/Home/viewModels/useHomePageViewModel.ts, src/pages/Services/view/ServicesPage.tsx, src/pages/Services/viewModels/useServicePageViewModel.ts |
|
|
7
8
|
| [Rate](profile.md) | 2.0 | Rate is a mortgage/lending client. | |
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Service Card Entitlement Display"
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: toga2-view
|
|
5
|
+
project: TOGa View
|
|
6
|
+
client: rate
|
|
7
|
+
type: client-feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-06-23
|
|
10
|
+
owners: ["bala"]
|
|
11
|
+
files:
|
|
12
|
+
- src/components/ServiceCard/ServiceCard.tsx
|
|
13
|
+
- src/components/ServiceCard/index.ts
|
|
14
|
+
- src/hooks/useBundleServices.ts
|
|
15
|
+
- src/pages/Home/api/homeApi.ts
|
|
16
|
+
- src/pages/Home/view/HomePage.tsx
|
|
17
|
+
- src/pages/Home/viewModels/useHomePageViewModel.ts
|
|
18
|
+
- src/pages/Services/view/ServicesPage.tsx
|
|
19
|
+
- src/pages/Services/viewModels/useServicePageViewModel.ts
|
|
20
|
+
related:
|
|
21
|
+
- clients/rate/profile.md
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Summary
|
|
25
|
+
|
|
26
|
+
Rate's home and services pages display one service card per purchased entitlement. The card
|
|
27
|
+
shows a hero image, title, Active badge, contract number, plan, price (or address for warranty
|
|
28
|
+
cards), renewal date, and a Manage button. Previously the UI showed one card per bundle type
|
|
29
|
+
regardless of how many entitlements the user had purchased.
|
|
30
|
+
|
|
31
|
+
## Key files / entry points
|
|
32
|
+
|
|
33
|
+
- `ServiceCard.tsx` — the card component; accepts `serviceType` to switch the second data row
|
|
34
|
+
between Price (tech) and Address (warranty)
|
|
35
|
+
- `useBundleServices.ts` — shared hook returning one `BundleService` per active entitlement;
|
|
36
|
+
used by both `useHomePageViewModel` and `useServicePageViewModel`
|
|
37
|
+
- `homeApi.ts` — `getActiveServices()` fetches entitlements with subscription and address fields
|
|
38
|
+
- `HomePage.tsx` — shows max 3 cards; "View All Services" tertiary text button links to `/services`
|
|
39
|
+
- `ServicesPage.tsx` — shows all entitlements in a 2-column grid, scrollable
|
|
40
|
+
|
|
41
|
+
## How it works
|
|
42
|
+
|
|
43
|
+
1. `getActiveServices(borrowerId)` queries `Entitlements` with:
|
|
44
|
+
- INNER JOIN: `Contacts`, `Customers`, `Subscriptions`
|
|
45
|
+
- LEFT JOIN (`ojoin`): `ContactAddresses`, `Addresses` — keeps entitlements whose contact
|
|
46
|
+
has no address instead of dropping the row
|
|
47
|
+
- Fields: `uuid`, `number`, `saleItem.title/uuid`, `subscription.isActive/amount/frequency/dateEnd`,
|
|
48
|
+
`contact.primaryContactAddress.address.line1`
|
|
49
|
+
|
|
50
|
+
2. `useBundleServices` filters `subscription.isActive === true` and builds one `BundleService`
|
|
51
|
+
per entitlement. It also fetches bundles to resolve `bundleUuid` for navigation.
|
|
52
|
+
|
|
53
|
+
3. `detectServiceType(title)` classifies each card:
|
|
54
|
+
- `'warranty'` — title includes "warranty" or "whole home" (and NOT "tech")
|
|
55
|
+
- `'tech'` — title includes "tech" or "support"
|
|
56
|
+
- `'other'` — everything else
|
|
57
|
+
|
|
58
|
+
4. `ServiceCard` renders the data rows based on `serviceType`:
|
|
59
|
+
- Tech / other → row 2: **Price** (`$XX.XX`)
|
|
60
|
+
- Warranty → row 2: **Address** (`contact.primaryContactAddress.address.line1`)
|
|
61
|
+
|
|
62
|
+
5. Home page slices `allServices` to 3 (`HOME_SERVICE_LIMIT`). If more exist, a tertiary
|
|
63
|
+
"View All Services" text link appears below the cards pointing to `/services`.
|
|
64
|
+
|
|
65
|
+
6. Services page renders all entitlements with no cap in a `grid-cols-1 md:grid-cols-2` grid.
|
|
66
|
+
|
|
67
|
+
## Data model
|
|
68
|
+
|
|
69
|
+
Address path in DB:
|
|
70
|
+
```
|
|
71
|
+
Entitlements.contactId
|
|
72
|
+
→ Contacts.primaryContactAddressId
|
|
73
|
+
→ ContactAddresses.id → ContactAddresses.addressId
|
|
74
|
+
→ Addresses.line1
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Contract number comes from `Entitlements.number` (auto-incremented with ET prefix, e.g. `ET100017`).
|
|
78
|
+
|
|
79
|
+
## Client variations
|
|
80
|
+
|
|
81
|
+
This feature is Rate-specific. The warranty card showing Address instead of Price is driven
|
|
82
|
+
by Rate's product mix (Whole Home Warranty + Tech Support). Other clients with different
|
|
83
|
+
product types would need `detectServiceType` extended or overridden.
|
|
84
|
+
|
|
85
|
+
## Gotchas / known issues
|
|
86
|
+
|
|
87
|
+
- **`ojoin` is required for address** — using INNER JOIN (`join`) drops every entitlement
|
|
88
|
+
whose contact has no `primaryContactAddressId`, silently hiding those cards.
|
|
89
|
+
- **`T00:00:00` in date formatting** — `formatDate` appends this before parsing to avoid
|
|
90
|
+
timezone offset shifting the renewal date back by one day.
|
|
91
|
+
- **Per-entitlement, not per-bundle** — `useBundleServices` intentionally does not dedup.
|
|
92
|
+
A user with 8 entitlements of the same product sees 8 cards. The old dedup-by-bundle
|
|
93
|
+
behavior (1 card per service type) was the previous design.
|
|
94
|
+
- **Inactive bundles are not shown** — the new design only renders active entitlements.
|
|
95
|
+
The "Add a subscription" dashed button (handled by `useAddSubscription` hook +
|
|
96
|
+
`AddSubscriptionSheet`) replaces the old "Get Started" inactive bundle cards.
|
|
97
|
+
- **`useBundleServices` is shared** — both `useHomePageViewModel` and `useServicePageViewModel`
|
|
98
|
+
call it. Changes to the hook affect both pages.
|
|
99
|
+
|
|
100
|
+
## Change history
|
|
101
|
+
|
|
102
|
+
- 2026-06-23 — Initial implementation: per-entitlement card display, new ServiceCard component,
|
|
103
|
+
address via LEFT JOIN, 3-card home limit with View All Services tertiary button (bala)
|
package/package.json
CHANGED