turboci-admin/src/components/general/ttyd-iframe.tsx
2026-03-14 13:33:35 +01:00

113 lines
3.8 KiB
TypeScript

import Border from "@/twui/components/elements/Border";
import Loading from "@/twui/components/elements/Loading";
import LucideIcon from "@/twui/components/elements/lucide-icon";
import useStatus from "@/twui/components/hooks/useStatus";
import Button from "@/twui/components/layout/Button";
import Center from "@/twui/components/layout/Center";
import Row from "@/twui/components/layout/Row";
import Span from "@/twui/components/layout/Span";
import Stack from "@/twui/components/layout/Stack";
import {
ComponentProps,
DetailedHTMLProps,
Fragment,
IframeHTMLAttributes,
ReactNode,
} from "react";
import { twMerge } from "tailwind-merge";
type Props = Omit<
DetailedHTMLProps<
IframeHTMLAttributes<HTMLIFrameElement>,
HTMLIFrameElement
>,
"title"
> & {
url: string;
wrapperProps?: ComponentProps<typeof Border>;
title?: string | ReactNode;
};
export default function TtydIframe({
url,
wrapperProps,
title,
...props
}: Props) {
const { loading, setLoading } = useStatus();
return (
<Border
{...wrapperProps}
className={twMerge("p-0", wrapperProps?.className)}
>
<Stack className="gap-0">
<Row className="p-4 w-full justify-between">
<Row>
{title ? (
<Fragment>
<Span size="small" variant="faded">
{title}
</Span>
{/* <LucideIcon
name="ChevronRight"
size={15}
opacity={0.3}
/> */}
</Fragment>
) : null}
{/* <Span size="small" variant="faded">
<a
href={url}
target="_blank"
className="dotted-link"
>
{url}
</a>
</Span> */}
</Row>
<Row>
<Button
title="Open Full Screen"
variant="ghost"
className="p-1!"
href={url}
target="_blank"
>
<LucideIcon name="ArrowUpRight" size={20} />
</Button>
<Button
title="Refresh Iframe"
variant="ghost"
className="p-1!"
loading={loading}
onClick={() => {
setLoading(true);
setTimeout(() => {
setLoading(false);
}, 2000);
}}
loadingProps={{ size: "smaller" }}
>
<LucideIcon name="RotateCcw" size={18} />
</Button>
</Row>
</Row>
<hr />
{loading ? (
<Center className="w-full p-10 h-[400px]">
<Loading />
</Center>
) : (
<iframe
{...props}
src={url}
className={twMerge("w-full h-[400px]", props.className)}
/>
)}
</Stack>
</Border>
);
}