feature: repurpose Hacker News PWA into a 4% cashback card UI on Angular 20 - #516
feature: repurpose Hacker News PWA into a 4% cashback card UI on Angular 20#516devin-ai-integration[bot] wants to merge 2 commits into
Conversation
…on Angular 20 Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…s are readable on light themes Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
🧪 End-to-end test results — green after one fixDrove the real UI on a local
✅ The 4% rate is applied correctly everywhere (14/14 rows verified)
Also passing: 🔴 Found and fixed: settings overlay was white-on-white in the Default theme
Fixed in c14edff by dropping the hard-coded white so the popup inherits the themed Not coveredProduction bundle was built but not served/clicked through; no mobile-viewport pass; the |
Summary
Replaces the Hacker News domain with a credit card cashback product ("Vantage 4% Cash Card") and moves the app from Angular 9 + modules + TSLint + Protractor to Angular 20 standalone/signals + ESLint + Playwright. The app shell that was worth keeping — lazy feature routes, the
SettingsServicetheme engine, the centralized data service, and@angular/service-worker— is preserved; everything HN-specific (feeds/,item-details/,user/,hackernews-api.service.ts,unfetch/lazyFetch,rxjs-compat, thega(...)calls) is gone.The 4% rate exists in exactly one place and everything else derives from it, so the ledger, per-transaction amounts and the rewards breakdown can't disagree:
Data service — mocked today, HTTP tomorrow, without touching callers.
environment.apiBaseUrlis'', so every method falls through to in-memory fixtures; set it and the same methods issueHttpClientrequests:fetchRewardsSummary()is derived rather than stored:summarizeRewards(transactions)groups bySpendCategory, sums spend/cashback and computes each category's share of total cashback.Signals over subscriptions. Components hold no RxJS subscriptions;
shared/util/load-state.tsfolds an observable into a three-state signal so every view gets loading/error handling for free:SettingsServiceis now a singlesignal<Settings>withcomputedprojections (theme,maskAmounts,titleFontSize,rowPadding), still persisted tolocalStorageand still honouringprefers-color-scheme. It gainedmaskAmounts— a card-appropriate privacy toggle that blanks every balance to••••via the newamountpipe.Routes (
/→/dashboard, wildcard →/dashboard), each feature lazily loaded:/dashboard/transactions/transactions/:id$54.72 × 4% = $2.19calculation breakdown (:idbound viawithComponentInputBinding())/rewards/accountThe settings overlay and the account page share one
SettingsControlsComponent, so the theme engine has a single implementation.Toolchain: Angular 20.3 / TypeScript 5.9 / RxJS 7.8;
provideHttpClient(withFetch()),provideRouter(...),provideServiceWorker(...)inapp.config.ts; SCSS migrated off deprecated@importto@use; assets moved topublic/; Travis → GitHub Actions running lint + unit + e2e + build; Firebase hosting now points atdist/vantage-cashback/browserwithno-cacheon the ngsw files. Icons/favicon are generated fromscripts/generate-icons.pyso the brand mark has one source.Verification
ng build(clean, no warnings),ng lint, 13 Karma/Jasmine specs, 5 Playwright specs — all green.localhost:4200: every route renders the mocked data with 4% applied (e.g.$1,879.36spend →$75.19cash back), and the Default/Night/AMOLED themes still work.Link to Devin session: https://app.devin.ai/sessions/702cce9e35ca4feb869e1e2d4dffb55c
Requested by: @Colhodm
Devin Review