/** * Skeleton primitives for Yatra Pro module pages. * * Replaces the generic centered * pattern that all six Growth/Agency module pages used while their * meta endpoint was in-flight. A spinning icon over an empty page * gives no sense of what's about to render — a layout-shaped * skeleton lets the operator anticipate the page and feels faster * even when the actual fetch time is unchanged. * * Each export below maps to a real shape used by one or more of * the module pages (page meta gate, tabbed content, settings form, * stat-grid section). Reuse aggressively — every module page * follows the same PageHeader + intro Card + content body shape. */ import React from "react"; import { Card, CardContent, CardHeader } from "./card"; const Bar: React.FC<{ className?: string }> = ({ className = "" }) => (
); /** * Page-level skeleton for the initial meta/license check on every * Pro module page. Mirrors the universal Header + intro Alert + * content area shape so the page doesn't visually "jump" once * data arrives. */ export const ModulePageSkeleton: React.FC<{ /** Variant of the content body skeleton to render. */ variant?: "tabs" | "form" | "list"; }> = ({ variant = "tabs" }) => { return (
{/* Page header (title + subtitle) */}
{/* Intro/about info card — every Pro module renders one of these above the main content (tier badge, description, doc link). */}
{variant === "tabs" && } {variant === "form" && } {variant === "list" && }
); }; /** * Tabbed content card with a faux tab strip + 5-row table preview. * Matches Webhooks, Channel Manager, Team, WhatsApp layouts. */ export const ModuleTabsSkeleton: React.FC<{ /** Number of tabs to render in the faux strip. */ tabCount?: number; /** Number of rows in the faux table body. */ rows?: number; /** Number of columns in the faux table body. */ columns?: number; }> = ({ tabCount = 4, rows = 5, columns = 5 }) => { return ( {/* Tab strip */}
{Array.from({ length: tabCount }).map((_, i) => (
))}
); }; /** * Table-shaped skeleton with header row + body rows. Drop-in * replacement for the centered spinners that previously sat inside * tab content panels. */ export const ModuleTableSkeleton: React.FC<{ rows?: number; columns?: number; }> = ({ rows = 5, columns = 5 }) => { const cols = Math.max(1, columns); return (
{/* Toolbar row (search + filters that most module tabs have) */}
{/* Header */}
{Array.from({ length: cols }).map((_, i) => ( ))}
{/* Rows */} {Array.from({ length: rows }).map((_, rowIndex) => (
{Array.from({ length: cols }).map((_, colIndex) => ( ))}
))}
); }; /** * Settings-form-shaped skeleton: label/input pairs in a single * column. Used for AI Assistant key form, WhatsApp credentials, * White Label settings. */ export const ModuleFormSkeleton: React.FC<{ /** Number of label+input rows. */ rows?: number; }> = ({ rows = 6 }) => { return ( {Array.from({ length: rows }).map((_, i) => (
))}
); }; /** * Card-list shape — for tabs that render channels, members, or * other entity cards instead of a strict table (Channel Manager's * Channels tab, Team Members layout in card mode, etc.). */ export const ModuleListSkeleton: React.FC<{ /** Number of list rows. */ rows?: number; }> = ({ rows = 4 }) => { return (
{Array.from({ length: rows }).map((_, i) => (
))}
); }; /** * Stat-grid skeleton — for analytics/usage sections (AI Assistant * usage tab, WhatsApp templates count, etc.). 4 stat tiles in a * responsive grid. */ export const ModuleStatGridSkeleton: React.FC<{ /** Number of stat tiles. */ tiles?: number; }> = ({ tiles = 4 }) => { return (
{Array.from({ length: tiles }).map((_, i) => ( ))}
); }; /** * Compact section-content skeleton — for in-card content loads * where the surrounding card chrome is already rendered (e.g. * Webhooks certificate section, AI Assistant prompt detail panel). */ export const ModuleSectionSkeleton: React.FC<{ /** Number of label/value lines. */ lines?: number; }> = ({ lines = 4 }) => { return (
{Array.from({ length: lines }).map((_, i) => (
))}
); };