7a1ab18657
Align the next-intl message schema across components, hooks, and locale files so the frontend uses one canonical structure instead of compile-first workarounds. Restore Spanish, French, German, Japanese, and Korean translations to the new schema while narrowing clipboard hook dependencies to translation contracts.
108 lines
2.8 KiB
TypeScript
108 lines
2.8 KiB
TypeScript
import React from "react";
|
|
import { Clipboard, FileText, Check } from "lucide-react";
|
|
import { useTranslations } from "next-intl";
|
|
import { Button } from "@/components/ui/button";
|
|
import { useClipboardActions } from "@/hooks/useClipboardActions";
|
|
|
|
interface WriteClipboardButtonProps {
|
|
title?: string; // Made title optional, can use default from messages
|
|
textToCopy: string;
|
|
}
|
|
|
|
interface ReadClipboardButtonProps {
|
|
title?: string; // Made title optional
|
|
onRead: (text: string) => void;
|
|
}
|
|
|
|
export const WriteClipboardButton: React.FC<WriteClipboardButtonProps> = ({
|
|
title,
|
|
textToCopy,
|
|
}) => {
|
|
const tButtons = useTranslations("text.common.buttons");
|
|
const { copyText, isCopied, isLoadingMessages, clipboardMessages, error } =
|
|
useClipboardActions();
|
|
|
|
const buttonText = title || tButtons("copy");
|
|
|
|
if (isLoadingMessages && !clipboardMessages.copiedSuccess) {
|
|
// Only show loading if messages truly not ready
|
|
return (
|
|
<Button variant="outline" disabled>
|
|
{clipboardMessages.loading}
|
|
</Button>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => copyText(textToCopy)}
|
|
disabled={isCopied || isLoadingMessages}
|
|
>
|
|
{isCopied ? (
|
|
<>
|
|
<Check className="w-4 h-4 mr-2" />
|
|
{clipboardMessages.copiedSuccess}
|
|
</>
|
|
) : (
|
|
<>
|
|
<FileText className="mr-2 h-4 w-4" /> {buttonText}
|
|
</>
|
|
)}
|
|
{/* Optionally display error */}
|
|
{/* {error && <span className="ml-2 text-red-500">{error}</span>} */}
|
|
</Button>
|
|
);
|
|
};
|
|
|
|
export const ReadClipboardButton: React.FC<ReadClipboardButtonProps> = ({
|
|
title,
|
|
onRead,
|
|
}) => {
|
|
const tButtons = useTranslations("text.common.buttons");
|
|
const {
|
|
readClipboard,
|
|
isPasted,
|
|
isLoadingMessages,
|
|
clipboardMessages,
|
|
error,
|
|
} = useClipboardActions();
|
|
|
|
const handleRead = async () => {
|
|
const text = await readClipboard();
|
|
onRead(text); // Pass null if read failed or no suitable content
|
|
};
|
|
|
|
const buttonText = title || tButtons("paste");
|
|
|
|
if (isLoadingMessages && !clipboardMessages.pastedSuccess) {
|
|
// Only show loading if messages truly not ready
|
|
return (
|
|
<Button variant="outline" disabled>
|
|
{clipboardMessages.loading}
|
|
</Button>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Button
|
|
variant="outline"
|
|
onClick={handleRead}
|
|
disabled={isPasted || isLoadingMessages}
|
|
>
|
|
{isPasted ? (
|
|
<>
|
|
<Check className="w-4 h-4 mr-2" />
|
|
{clipboardMessages.pastedSuccess}
|
|
</>
|
|
) : (
|
|
<>
|
|
<Clipboard className="w-4 h-4 mr-2" /> {buttonText}
|
|
</>
|
|
)}
|
|
{/* Optionally display error */}
|
|
{/* {error && <span className="ml-2 text-red-500">{error}</span>} */}
|
|
</Button>
|
|
);
|
|
};
|