diff --git a/src/pages/PersonalizationAI/AuditoryLink.tsx b/src/pages/PersonalizationAI/AuditoryLink.tsx
index 0e17653f..8b4b9727 100644
--- a/src/pages/PersonalizationAI/AuditoryLink.tsx
+++ b/src/pages/PersonalizationAI/AuditoryLink.tsx
@@ -1,12 +1,11 @@
import { AuditoryItem } from "@/api/auditory";
-import CopyIcon from "@/assets/icons/CopyIcon";
import Trash from "@/assets/icons/trash";
import { useCurrentQuiz } from "@/stores/quizes/hooks";
import { InfoPopover } from "@/ui_kit/InfoPopover";
import TooltipClickInfo from "@/ui_kit/Toolbars/TooltipClickInfo";
import { useDomainDefine } from "@/utils/hooks/useDomainDefine";
-import { IconButton, ListItem, Skeleton, Typography, useTheme } from "@mui/material";
-import { useEffect, useMemo, useState } from "react";
+import { IconButton, ListItem, Typography, useTheme } from "@mui/material";
+import { CopyButton } from "./CopyButton";
interface AuditoryLinkProps {
item: AuditoryItem;
@@ -20,66 +19,7 @@ export const AuditoryLink = ({ utmParams, item, index, onDelete }: AuditoryLinkP
const quiz = useCurrentQuiz();
const { isTestServer } = useDomainDefine();
- const getCreatedTime = (timestamp: number) => {
- // Если timestamp в секундах (10 цифр)
- if (timestamp.toString().length === 10) {
- return new Date(timestamp * 1000).getTime();
- }
- // Если timestamp в миллисекундах (13 цифр)
- return new Date(timestamp).getTime();
- };
-
- const [isLoading, setIsLoading] = useState(() => {
- if (!item.created_at) return false;
- const now = new Date().getTime();
- const created = getCreatedTime(item.created_at);
- const diffInMinutes = (now - created) / (1000 * 60);
- console.log('Initial state:', {
- created_at: item.created_at,
- format: item.created_at.toString().length === 10 ? 'seconds' : 'milliseconds',
- now,
- created,
- diffInMinutes,
- isLoading: diffInMinutes < 2
- });
- return diffInMinutes < 2;
- });
-
- useEffect(() => {
- if (!item.created_at) return;
-
- const now = new Date().getTime();
- const created = getCreatedTime(item.created_at);
- const diffInMinutes = (now - created) / (1000 * 60);
-
- console.log('Effect check:', {
- created_at: item.created_at,
- format: item.created_at.toString().length === 10 ? 'seconds' : 'milliseconds',
- now,
- created,
- diffInMinutes,
- timeDiff: now - created
- });
-
- if (now - created < 1000) {
- console.log('Setting loading to true for new link');
- setIsLoading(true);
- }
-
- if (diffInMinutes < 2) {
- const timeLeft = Math.ceil((2 - diffInMinutes) * 60 * 1000);
- console.log('Setting timer for:', timeLeft, 'ms');
- const timer = setTimeout(() => {
- console.log('Timer finished, setting loading to false');
- setIsLoading(false);
- }, timeLeft);
-
- return () => clearTimeout(timer);
- }
- }, [item.created_at]);
-
const handleCopy = (text: string) => {
- if (isLoading) return;
navigator.clipboard.writeText(text);
};
@@ -127,32 +67,11 @@ export const AuditoryLink = ({ utmParams, item, index, onDelete }: AuditoryLinkP
- {isLoading ? (
-
- ) : (
- handleCopy(linkText)}
- >
-
-
- )}
+
>
}
>
diff --git a/src/pages/PersonalizationAI/CopyButton.tsx b/src/pages/PersonalizationAI/CopyButton.tsx
new file mode 100644
index 00000000..9bcf0fe6
--- /dev/null
+++ b/src/pages/PersonalizationAI/CopyButton.tsx
@@ -0,0 +1,161 @@
+import { IconButton, Skeleton, useTheme, Tooltip, ClickAwayListener } from "@mui/material";
+import { useEffect, useState } from "react";
+import CopyIcon from "@/assets/icons/CopyIcon";
+import { useSnackbar } from "notistack";
+
+interface CopyButtonProps {
+ created_at: number;
+ onCopy: (text: string) => void;
+ text: string;
+}
+
+export const CopyButton = ({ created_at, onCopy, text }: CopyButtonProps) => {
+ const theme = useTheme();
+ const { enqueueSnackbar } = useSnackbar();
+ const [open, setOpen] = useState(false);
+ const [timeLeft, setTimeLeft] = useState("");
+
+ const getCreatedTime = (timestamp: number) => {
+ // Если timestamp в секундах (10 цифр)
+ if (timestamp.toString().length === 10) {
+ return new Date(timestamp * 1000).getTime();
+ }
+ // Если timestamp в миллисекундах (13 цифр)
+ return new Date(timestamp).getTime();
+ };
+
+ const formatTimeLeft = (milliseconds: number) => {
+ const minutes = Math.floor(milliseconds / (1000 * 60));
+ const seconds = Math.floor((milliseconds % (1000 * 60)) / 1000);
+ return `${minutes}:${seconds.toString().padStart(2, '0')}`;
+ };
+
+ const [isLoading, setIsLoading] = useState(() => {
+ if (!created_at) return false;
+ const now = new Date().getTime();
+ const created = getCreatedTime(created_at);
+ const diffInMinutes = (now - created) / (1000 * 60);
+ return diffInMinutes < 2;
+ });
+
+ useEffect(() => {
+ if (!created_at) return;
+
+ const now = new Date().getTime();
+ const created = getCreatedTime(created_at);
+ const diffInMinutes = (now - created) / (1000 * 60);
+
+ if (now - created < 1000) {
+ setIsLoading(true);
+ }
+
+ if (diffInMinutes < 2) {
+ const timeLeft = Math.ceil((2 - diffInMinutes) * 60 * 1000);
+ setTimeLeft(formatTimeLeft(timeLeft));
+
+ const timer = setInterval(() => {
+ const currentTime = new Date().getTime();
+ const elapsed = currentTime - created;
+ const remaining = 2 * 60 * 1000 - elapsed;
+
+ if (remaining <= 0) {
+ setIsLoading(false);
+ clearInterval(timer);
+ return;
+ }
+
+ setTimeLeft(formatTimeLeft(remaining));
+ }, 1000);
+
+ return () => clearInterval(timer);
+ }
+ }, [created_at]);
+
+ const handleClick = () => {
+ if (isLoading) return;
+ onCopy(text);
+ enqueueSnackbar("Ссылка успешно скопирована", { variant: "success" });
+ };
+
+ const handleTooltipClose = () => {
+ setOpen(false);
+ };
+
+ const handleTooltipOpen = () => {
+ setOpen(true);
+ };
+
+ if (isLoading) {
+ return (
+
+
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+
+ );
+};
\ No newline at end of file