- activities indexes + client_events/client_errors/rollups/alerts collections - global function middleware via createStart; reads skipped on success - actor stash, denial dedup, control-flow error guards - api route logging, auth event overrides, beacon endpoint, web vitals - centralized admin role checks, shared skeletons, award-badges fix - extracted deriveRunState with tests
36 lines
946 B
TypeScript
36 lines
946 B
TypeScript
import { Box, Group, Paper, Skeleton } from "@mantine/core";
|
|
import type { MantineRadius } from "@mantine/core";
|
|
|
|
export interface CardSkeletonProps {
|
|
withAvatar?: boolean;
|
|
avatarSize?: number;
|
|
withBadge?: boolean;
|
|
radius?: MantineRadius;
|
|
opacity?: number;
|
|
}
|
|
|
|
export const CardSkeleton = ({
|
|
withAvatar = true,
|
|
avatarSize = 32,
|
|
withBadge = true,
|
|
radius = "md",
|
|
opacity = 1,
|
|
}: CardSkeletonProps) => {
|
|
return (
|
|
<Paper p="sm" withBorder radius={radius} style={{ opacity }}>
|
|
<Group gap="sm" align="center" wrap="nowrap">
|
|
{withAvatar && (
|
|
<Skeleton height={avatarSize} width={avatarSize} radius="sm" />
|
|
)}
|
|
<Box style={{ flex: 1 }}>
|
|
<Skeleton height={16} width="70%" mb={4} />
|
|
<Skeleton height={12} width="40%" />
|
|
</Box>
|
|
{withBadge && <Skeleton height={20} width={60} radius="xl" />}
|
|
</Group>
|
|
</Paper>
|
|
);
|
|
};
|
|
|
|
export default CardSkeleton;
|