Skip to content

Commit 101ff04

Browse files
feat: newm-admin Earnings dashboard
1 parent 2ac2bef commit 101ff04

24 files changed

Lines changed: 2717 additions & 66 deletions

.agent/task/admin/newm-admin.md

Lines changed: 170 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,172 @@ graph LR
7676

7777
**Priority:** High
7878

79+
#### API Endpoints
80+
81+
The admin app uses JWT-protected admin endpoints from the backend:
82+
83+
| Endpoint | Method | Purpose |
84+
|----------|--------|---------|
85+
| `/v1/earnings/admin` | GET | Fetch all earnings records |
86+
| `/v1/earnings/admin` | POST | Batch create earnings (accepts `List<Earning>`) |
87+
| `/v1/earnings/admin/{songIdOrIsrc}` | GET | Get earnings by song ID or ISRC |
88+
| `/v1/earnings/admin/{songIdOrIsrc}` | POST | Create royalty splits for a song |
89+
90+
**Earning Model Fields:**
91+
- `id` (UUID), `songId` (UUID), `stakeAddress`, `amount` (Long, 6 decimals)
92+
- `memo`, `startDate`, `endDate`, `claimed`, `claimedAt`, `claimOrderId`
93+
- `createdAt`, `nftPolicyId`, `nftAssetName`
94+
95+
**AddSongRoyaltyRequest:** Either `newmAmount` or `usdAmount` (BigInteger, 6 decimals)
96+
97+
---
98+
99+
#### UI Components
100+
101+
##### Summary Boxes
102+
103+
Three summary cards at the top of the Earnings dashboard, calculated from the filtered data:
104+
105+
| Box | Description | Calculation |
106+
|-----|-------------|-------------|
107+
| **Total Earnings** | Sum of all earnings in current filter | `Σ earning.amount` |
108+
| **Claimed Earnings** | Sum of claimed earnings | `Σ earning.amount WHERE claimed == true` |
109+
| **Unclaimed Earnings** | Sum of unclaimed earnings | `Total - Claimed` |
110+
111+
> [!NOTE]
112+
> All amounts display in NEWM tokens with 6 decimal places, prefixed with `Ɲ` symbol (e.g., `Ɲ 1,234.567890`).
113+
114+
##### Earnings Table
115+
116+
A sortable, filterable table displaying all earnings:
117+
118+
| Column | Sortable | Filterable | Notes |
119+
|--------|----------|------------|-------|
120+
| ID ||| UUID |
121+
| Song ID ||| UUID or display song title if available |
122+
| Stake Address ||| Cardano stake address |
123+
| Amount ||| Display as `Ɲ X.XXXXXX` |
124+
| Memo ||| Freeform text |
125+
| Claimed ||| Boolean (checkbox filter) |
126+
| Claimed At ||| DateTime, null if unclaimed |
127+
| Created At ||| DateTime (supports date range filter) |
128+
129+
**Table Features:**
130+
- **Refresh Button:** Fetches latest data from server
131+
- **Date Range Filter:** Filter by `createdAt` date range (critical requirement)
132+
- **Infinite Scroll:** Virtual list handles large datasets efficiently
133+
134+
##### Toast Notification System
135+
136+
A toast notification system to inform users of API operation results:
137+
138+
| Toast Type | Behavior | Auto-Dismiss |
139+
|------------|----------|--------------|
140+
| **Success** | Green background, checkmark icon | 5 seconds |
141+
| **Warning** | Yellow/orange background, warning icon | Manual X close required |
142+
| **Error** | Red background, error icon | Manual X close required |
143+
144+
Toast content should include:
145+
- Clear message describing success or failure
146+
- For failures: Include error message from API response
147+
- Position: Top-right corner of the work area, stacked if multiple
148+
149+
---
150+
151+
#### Workflows
152+
153+
##### Add Earnings (Single Song)
154+
155+
**Button:** "Add Earnings" in the toolbar
156+
157+
**Dialog Fields:**
158+
| Field | Type | Description |
159+
|-------|------|-------------|
160+
| Song ID or ISRC | Text input | Accepts UUID or ISRC format (e.g., `IE-LOI-23-01693`) |
161+
| Amount (USD) | Decimal input | User enters USD value (e.g., `10.50`) |
162+
163+
**Process:**
164+
1. User enters songId/ISRC and USD amount
165+
2. Convert amount to 6-decimal integer: `10.50``10500000`
166+
3. Call `POST /v1/earnings/admin/{songIdOrIsrc}` with `{ usdAmount: 10500000 }`
167+
4. On success: Show success toast, refresh table
168+
5. On failure: Show error toast with API error message
169+
170+
##### Upload Earnings CSV
171+
172+
**Button:** "Upload CSV" in the toolbar
173+
174+
**CSV Format (Input):**
175+
```csv
176+
songId_or_isrc,amount_usd
177+
550e8400-e29b-41d4-a716-446655440000,10.50
178+
IE-LOI-23-01693,25.00
179+
```
180+
181+
**Process:**
182+
1. User selects CSV file via native file picker
183+
2. Parse CSV, validate format (2 columns required)
184+
3. For each row:
185+
- Convert USD to 6-decimal integer
186+
- Call `POST /v1/earnings/admin/{songIdOrIsrc}`
187+
- Record result (success or error message)
188+
4. Modify CSV to add result column
189+
5. Save modified CSV with results
190+
191+
**CSV Format (Output):**
192+
```csv
193+
songId_or_isrc,amount_usd,result
194+
550e8400-e29b-41d4-a716-446655440000,10.50,Success
195+
IE-LOI-23-01693,25.00,Error: No song found with ISRC: IE-LOI-23-01693
196+
```
197+
198+
6. Show summary toast: "Processed X records: Y succeeded, Z failed"
199+
7. If any failures: Show warning toast prompting user to check output file
200+
201+
##### Delete Earnings (Multi-Select)
202+
203+
**Button:** "Delete Selected" in the toolbar (disabled when no rows selected)
204+
205+
**UI Requirements:**
206+
| Element | Description |
207+
|---------|-------------|
208+
| Checkbox column | Leftmost column with checkbox for each row |
209+
| Select All | Header checkbox to select/deselect all filtered rows. Shows indeterminate (minus icon) when some rows selected, check when all selected |
210+
| Delete Button | Enabled only when 1+ rows selected, shows count |
211+
| Confirmation | Modal dialog before deletion |
212+
213+
**Process:**
214+
1. User selects one or more rows via checkboxes
215+
2. "Delete Selected (N)" button becomes enabled
216+
3. User clicks delete button
217+
4. Confirmation dialog: "Delete N earnings records? This cannot be undone."
218+
5. On confirm: Call `DELETE /v1/earnings/admin` with list of earning IDs
219+
6. On success: Refresh table, show success toast
220+
7. On failure: Show error toast with API error message
221+
222+
**API Endpoint:**
223+
- `DELETE /v1/earnings/admin` - Admin-only endpoint
224+
- Request body: `["uuid1", "uuid2", ...]`
225+
- Response: `204 No Content` on success
226+
227+
---
228+
229+
#### Implementation Status
230+
79231
| Requirement | Status |
80232
|-------------|--------|
81-
| List all earnings with pagination | ⬜ Not started |
82-
| Filter by artist, song, date range | ⬜ Not started |
83-
| View earnings details | ⬜ Not started |
84-
| Export earnings data | ⬜ Not started |
233+
| List all earnings with sortable, scrollable table | ✅ Completed |
234+
| Filter by date range | ✅ Completed |
235+
| Filter by stake address, song, memo | ✅ Completed |
236+
| Summary boxes (Total/Claimed/Unclaimed) | ✅ Completed |
237+
| NEWM token display with Ɲ symbol | ✅ Completed |
238+
| Refresh button | ✅ Completed |
239+
| Toast notification system | ✅ Completed |
240+
| Add Earnings dialog | ✅ Completed |
241+
| Upload CSV workflow | ✅ Completed |
242+
| CSV result export | ✅ Completed |
243+
| Delete earnings (multi-select) | ✅ Completed |
244+
| Select All header checkbox (with indeterminate state) | ✅ Completed |
85245

86246
### 🔲 Refunds Processing
87247

@@ -152,11 +312,14 @@ cd newm-admin && cargo build
152312
# Run (development)
153313
cd newm-admin && cargo run
154314

315+
# Check for Format issues
316+
cd newm-admin && cd newm-admin && cargo fmt --all -- --check
317+
155318
# Format code
156-
cd newm-admin && cargo fmt
319+
cd newm-admin && cd newm-admin && cargo fmt --all
157320

158321
# Lint
159-
cd newm-admin && cargo clippy
322+
cd newm-admin && cargo clippy --all-targets --all-features -- -D warnings
160323
```
161324

162325
---
@@ -178,6 +341,7 @@ The admin app communicates with the NEWM backend:
178341

179342
| Date | Feature | Description |
180343
|------|---------|-------------|
344+
| 2026-01-08 | Earnings Table | Full-featured earnings table with filtering, sorting, date range, summary stats, copy-to-clipboard |
181345
| 2026-01-07 | Dashboard | Added sidebar nav with Earnings/Refunds, work area panels |
182346
| 2026-01-07 | Auth | JWT admin validation, login view with environment selector |
183347
| 2026-01-06 | Init | Project setup with GPUI, basic login UI |

.agent/workflows/admin.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,24 @@ cd newm-admin && cargo run
5656
cd newm-admin && cargo build --release
5757
```
5858

59+
### Format Code Check
60+
// turbo
61+
```bash
62+
cd newm-admin && cargo fmt --all -- --check
63+
```
64+
5965
### Format Code
6066

6167
// turbo
6268
```bash
63-
cd newm-admin && cargo fmt
69+
cd newm-admin && cargo fmt --all
6470
```
6571

6672
### Lint
6773

6874
// turbo
6975
```bash
70-
cd newm-admin && cargo clippy
76+
cd newm-admin && cargo clippy --all-targets --all-features -- -D warnings
7177
```
7278

7379
---
@@ -206,4 +212,4 @@ When visual verification of UI changes is needed:
206212
4. Document what specific UI elements should be visible in the screenshot
207213

208214
Example prompt to user:
209-
> "Please run the application and take a screenshot of [specific view]. I need to verify that [specific UI element] appears correctly. Attach the screenshot to your reply."
215+
> "Please run the application and take a screenshot of [specific view]. I need to verify that [specific UI element] appears correctly. Attach the screenshot to your reply."

newm-admin/Cargo.lock

Lines changed: 66 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

newm-admin/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,11 @@ anyhow = "1"
2828

2929
# JWT Parsing
3030
base64 = "0.22"
31+
chrono = "0.4.42"
32+
33+
# CSV Import
34+
csv = "1.3"
35+
rfd = "0.15"
36+
37+
[dev-dependencies]
38+
tempfile = "3"

0 commit comments

Comments
 (0)