92 lines
2.5 KiB
TypeScript
92 lines
2.5 KiB
TypeScript
import type { ReactNode } from "react";
|
||
|
||
interface EmptyStateProps {
|
||
icon?: string;
|
||
title: string;
|
||
description?: string;
|
||
action?: ReactNode;
|
||
}
|
||
|
||
export function EmptyState({ icon = "📭", title, description, action }: EmptyStateProps) {
|
||
return (
|
||
<div
|
||
style={{
|
||
padding: "3rem 2rem",
|
||
textAlign: "center",
|
||
background: "var(--secondary-alt-bg)",
|
||
borderRadius: "16px",
|
||
border: "1px dashed var(--border-color)",
|
||
color: "var(--text-muted)"
|
||
}}
|
||
>
|
||
<div style={{ fontSize: "3rem", marginBottom: "1rem" }}>{icon}</div>
|
||
<h3 style={{ margin: "0 0 0.5rem 0", color: "var(--text-color)" }}>{title}</h3>
|
||
{description && <p style={{ margin: "0 0 1.5rem 0", fontSize: "0.95rem" }}>{description}</p>}
|
||
{action}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export function LoadingState({ message = "Loading..." }: { message?: string }) {
|
||
return (
|
||
<div
|
||
style={{
|
||
padding: "3rem 2rem",
|
||
textAlign: "center"
|
||
}}
|
||
>
|
||
<div
|
||
style={{
|
||
width: "40px",
|
||
height: "40px",
|
||
border: "4px solid rgba(255, 255, 255, 0.2)",
|
||
borderTopColor: "currentColor",
|
||
borderRadius: "50%",
|
||
animation: "spin 0.8s linear infinite",
|
||
margin: "0 auto 1rem"
|
||
}}
|
||
></div>
|
||
<p style={{ color: "var(--text-muted)", margin: 0 }}>{message}</p>
|
||
<style>{`
|
||
@keyframes spin {
|
||
to { transform: rotate(360deg); }
|
||
}
|
||
`}</style>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export function ErrorState({ message, onRetry }: { message: string, onRetry?: () => void }) {
|
||
return (
|
||
<div
|
||
style={{
|
||
padding: "3rem 2rem",
|
||
textAlign: "center",
|
||
background: "rgba(244, 67, 54, 0.1)",
|
||
borderRadius: "16px",
|
||
border: "1px solid rgba(244, 67, 54, 0.3)"
|
||
}}
|
||
>
|
||
<div style={{ fontSize: "3rem", marginBottom: "1rem" }}>⚠️</div>
|
||
<h3 style={{ margin: "0 0 0.5rem 0", color: "var(--text-color)" }}>Something went wrong</h3>
|
||
<p style={{ margin: "0 0 1.5rem 0", color: "var(--text-muted)", fontSize: "0.95rem" }}>{message}</p>
|
||
{onRetry && (
|
||
<button
|
||
onClick={onRetry}
|
||
style={{
|
||
background: "var(--accent-color)",
|
||
border: "none",
|
||
padding: "0.75rem 1.5rem",
|
||
borderRadius: "8px",
|
||
color: "white",
|
||
fontWeight: 600,
|
||
cursor: "pointer"
|
||
}}
|
||
>
|
||
🔄 Try Again
|
||
</button>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|