feat: add DepositCalendar component with iCal export functionality#194
feat: add DepositCalendar component with iCal export functionality#194BigJohn-dev wants to merge 1 commit into
Conversation
- Introduced a new DepositCalendar component to display deposit schedules for rotational pools. - Implemented event handling for deposit events, including urgency indicators and time remaining. - Added iCal export functionality for individual pools and all deposits using ical-generator. - Created hooks to fetch active rotational pools and manage loading states. - Enhanced user experience with mobile and desktop views for calendar display. - Included empty state handling and loading skeletons for better UI feedback.
Sendi0011
left a comment
There was a problem hiding this comment.
The calendar component is well structured and the iCal export is a great feature. Two issues need fixing:
-
CI is failing — All 3 frontend checks fail at "Install dependencies" (exit code 1). Likely a peer dependency conflict from adding
ical-generator@^11.0.0. Runpnpm installlocally and verify it resolves cleanly. Also, thepackage-lock.jsondiff is ~11k lines — make sure you're usingpnpm, notnpm. -
Functional bug —
useAllRotationalPoolsqueries/api/pools?creator=...which only returns pools where the user is the creator. If a user has joined (but not created) rotational pools, those won't appear in the calendar. This should query bymember_addressinstead.
Minor: depositAmount falls back to 0 when null — the calendar shows "0.00 XLM" which is misleading. Consider showing "Unknown" or hiding the amount.
Also fix conflict.
Closes #186
Deposit Calendar View for Dashboard
PR Summary
Adds a new Deposit Calendar tab to the dashboard that displays all upcoming deposit obligations across a user's rotational pools in a monthly calendar grid (desktop) or timeline list (mobile). Includes iCal/Google Calendar export for individual pools or all deposits at once.
Branch:
feat/pool-deposit-calendarRelated Issue: Deposit Calendar view for rotational pool members
Motivation
Rotational pool members currently have no way to see their upcoming deposit obligations at a glance across all their pools. The only way to know when a deposit is due is to open each pool's detail page individually and check the round deadline. This is especially painful for users in multiple rotational pools.
This feature adds a dedicated calendar view that aggregates deposit deadlines from all rotational pools, with color-coded urgency indicators and one-click calendar export.
Changes
New Files
frontend/components/dashboard/deposit-calendar.tsxDepositCalendarcomponent with calendar grid, mobile list view, event cards, empty state, and color-coded urgencyfrontend/hooks/useAllRotationalPools.ts/api/poolsendpointfrontend/lib/ical-export.tsical-generatorv11 — generates.icsfiles for single pools or all deposits, plus a download helperModified Files
frontend/components/dashboard/dashboard-tabs.tsxTabsListgrid (6→7 cols), importedDepositCalendar, addedTabsContentfor"calendar"valuefrontend/package.jsonical-generatordependencyDependency Added
Architecture
Data Flow
Key Design Decisions
PoolDataProvider integration: Each pool's on-chain data is read through the existing
usePoolDatahook, which registers withPoolDataProviderfor centralized polling and caching. This avoids redundant RPC calls and keeps the calendar data in sync with the rest of the dashboard.No new API routes: The feature reuses the existing
/api/poolsendpoint for pool metadata and reads on-chain state through the establishedPoolDataProvidercache layer.Calendar grid is hand-rolled: Rather than adding a heavy calendar library, the 6-week grid is built with Tailwind CSS grid utilities and simple date helpers. This keeps the bundle small and the styling consistent with the rest of the app.
Mobile-first responsive: Uses the existing
useIsMobile()hook (768px breakpoint). Desktop shows the monthly grid; mobile switches to a scrollable timeline list.PoolEventItem pattern: Since React hooks cannot be called in loops, each pool is rendered as its own
PoolEventItemcomponent that independently callsusePoolData. These render nothing visible — they just report their on-chain state back to the parent via theonEventReadycallback.Acceptance Criteria Checklist
router.push(/dashboard/group/${poolId})handleExportAll→generateAllICaluseIsMobile()switches toMobileListViewat <768pxCalendarEmptyStatewith message and CTACalendarCheckicon + "Paid" badge whenhasDeposited === trueComponent API
<DepositCalendar />No required props. Connects to wallet via
useStellar(), fetches pools viauseAllRotationalPools(), and reads on-chain state viausePoolData()per pool.DepositEvent(exported type)useAllRotationalPools()hookiCal Export Format
Each generated
.icsevent includes:Deposit due: [pool name]Deposit [amount] [token] to [pool name]. Pool contract: [address]nextPayoutTime/dashboard/group/[poolId])Calendar name for single-pool export: the pool name.
Calendar name for export-all:
"JointSave - All Deposits".Color Coding
emerald-500/15emerald-500/40emerald-400bg-emerald-500emerald-500/15emerald-500/40emerald-400bg-emerald-500yellow-500/15yellow-500/40yellow-400bg-yellow-500red-500/15red-500/40red-400bg-red-500Testing Notes
tsc --noEmitwith zero errors (pre-existing errors ingroup-actions.tsxare unrelated).icsfile.icsinto Google Calendar / Apple Calendar — events should appear correctly.icsScreenshots
Bundle Impact
ical-generator@11.0.0(~46 KB gzipped) — only imported inlib/ical-export.ts, tree-shaken to minimal footprintdeposit-calendar.tsx— loaded lazily as part of the Calendar tab (Next.js code splitting)