0e46fdafb2
- Implemented `AdministrationContent` component for managing account roles. - Created `AdministrationPage` to serve as the main entry point for administration tasks. - Added PDF preview functionality with `PdfPreviewFrame` component for invoice generation. - Introduced `InputColor` component for advanced color selection with various formats. - Established color conversion utilities in `color-converter.ts` for handling color formats. - Defined appearance-related schemas and types in `appearance.ts` for consistent theme management.
38 lines
951 B
TypeScript
38 lines
951 B
TypeScript
import { useState } from "react";
|
|
import Image, { type ImageProps } from "next/image";
|
|
import { cn } from "~/lib/utils";
|
|
import { Skeleton } from "~/components/ui/skeleton";
|
|
|
|
interface ImageWithSkeletonProps extends ImageProps {
|
|
containerClassName?: string;
|
|
}
|
|
|
|
export function ImageWithSkeleton({
|
|
className,
|
|
containerClassName,
|
|
alt,
|
|
...props
|
|
}: ImageWithSkeletonProps) {
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
|
return (
|
|
<div className={cn("relative overflow-hidden", containerClassName)}>
|
|
{isLoading && (
|
|
<Skeleton className="absolute inset-0 h-full w-full animate-pulse" />
|
|
)}
|
|
<Image
|
|
className={cn(
|
|
"duration-700 ease-in-out",
|
|
isLoading
|
|
? "scale-110 blur-2xl grayscale"
|
|
: "blur-0 scale-100 grayscale-0",
|
|
className,
|
|
)}
|
|
onLoad={() => setIsLoading(false)}
|
|
alt={alt}
|
|
{...props}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|