Components / Content Card
Content Card
The generated-post card: 9:16 media rendered through MediaPlayer with the two-cell ContentCardFooter (account and schedule) beneath, wrapped in the gradient hover glow.
import { ContentCard, ContentCardSkeleton, type ContentDestination } from '@layers/ui/content-card'Rendered stock
House rules
- Feed it the post shape (id, media_urls, media_type); the footer comes from one destinations array, each entry pairing an account with the time it goes out.
- onMediaClick opens the post; onFooterClick opens assignment and scheduling. They are separate targets on purpose.
- unassigned and needsApproval are the two accountless states, and they are NOT interchangeable: unassigned means nothing owns this piece yet, needsApproval means an owner is waiting on a human verdict. Both are read only when destinations is empty — with a destination the pill itself carries the state.
- hideFooter rounds the media region into a full card and stops it stretching, so a footerless card can sit in a MIXED grid beside footered ones without painting a blank band under its media.
- Styles ship with the component (content-card.css is self-imported).
- ContentRenderer is a near duplicate that accepts nullable post fields; prefer ContentCard when your data is non-nullable.
- While a grid is loading, render ContentCardSkeleton tiles — the same shell (9:16 media plus footer), so tiles do not change size on load.