Add a freshness line to the storage widget

React · React · intermediate · modification

Adds the 'last updated' line to the storage widget so users know how fresh the number is. Moves the read to the new `/api/storage/snapshot` data function and renames the type to `StorageSnapshot` to carry the freshness metadata. Bar and usage label are unchanged. Tested against my account.

The account settings page. Usage is synced on a schedule, so the number can be minutes or hours stale depending on the last sync — which is exactly why the freshness line was requested. The snapshot object is built server-side in `getStorageSnapshot` and fetched by the widget.

Requirements

Files touched

--- src/server/storage.ts
 import { db } from './db';
 
-export interface StorageUsage {
+export interface StorageSnapshot {
   usedGb: number;
   totalGb: number;
 }
 
-// GET /api/storage
-export async function getStorageUsage(userId: string): Promise<StorageUsage> {
+// GET /api/storage/snapshot
+export async function getStorageSnapshot(userId: string): Promise<StorageSnapshot> {
   const row = await db.storageUsage.findByUser(userId);
+  // row has: usedGb, totalGb, capturedAt (last sync time)
   return {
     usedGb: row.usedGb,
--- src/components/StorageMeter.tsx
 import { useEffect, useState } from 'react';
-import type { StorageUsage } from '../server/storage';
+import type { StorageSnapshot } from '../server/storage';
 
-function useStorageUsage(): StorageUsage | null {
-  const [usage, setUsage] = useState<StorageUsage | null>(null);
+function useStorageSnapshot(): StorageSnapshot | null {
+  const [snapshot, setSnapshot] = useState<StorageSnapshot | null>(null);
   useEffect(() => {
     let active = true;
-    fetch('/api/storage')
+    fetch('/api/storage/snapshot')

Review this PR

React practice