ab79080f0b
Frontend: - Create reusable DataStates components (LoadingState, ErrorState, EmptyState) - Refactor 12 pages to use shared state components instead of inline JSX - Extract useInstanceActions hook to eliminate session action duplication - Update dashboard and sessions pages to use shared hook OpenSpec: - Archive completed mobile-app-usability change (44/44 tasks) - Archive completed add-config-profiles change (15/15 tasks) Quality: TypeScript check passes, production build succeeds
35 lines
762 B
TypeScript
35 lines
762 B
TypeScript
import { Icon } from "./icon";
|
|
|
|
interface LoadingStateProps {
|
|
message?: string;
|
|
}
|
|
|
|
export const LoadingState = ({ message = "Loading..." }: LoadingStateProps) => (
|
|
<p className="muted">{message}</p>
|
|
);
|
|
|
|
interface ErrorStateProps {
|
|
message?: string;
|
|
onRetry?: () => void;
|
|
}
|
|
|
|
export const ErrorState = ({ message = "Failed to load", onRetry }: ErrorStateProps) => (
|
|
<div className="card stack">
|
|
<p>{message}</p>
|
|
{onRetry && (
|
|
<button className="secondary-button" onClick={onRetry} type="button">
|
|
<Icon name="refresh" size="sm" />
|
|
Retry
|
|
</button>
|
|
)}
|
|
</div>
|
|
);
|
|
|
|
interface EmptyStateProps {
|
|
message: string;
|
|
}
|
|
|
|
export const EmptyState = ({ message }: EmptyStateProps) => (
|
|
<p className="muted">{message}</p>
|
|
);
|