Fix copy link

This commit is contained in:
Халимов Рустам
2025-12-27 19:15:22 +03:00
parent 8010c172c7
commit f296db8297

View File

@@ -5,10 +5,10 @@ import * as THREE from 'three';
import JSZip from 'jszip';
import { AppConfig, GeneratedPart, LayoutSplits } from '../types';
import { createBinGeometry, generateSTL, exportSTL } from '../services/geometryGenerator';
import { Download, Package, Info, Loader2, Share2, Check, Ruler } from 'lucide-react';
import { generateShareUrl } from '../utils/share'; // <--- Импорт утилиты
import { Download, Package, Info, Loader2, Share2, Check, Ruler, Copy } from 'lucide-react';
import { generateShareUrl } from '../utils/share';
// ... (DrawerFrame и BinMesh остаются без изменений) ...
// --- DrawerFrame (Каркас) ---
const DrawerFrame = ({ config }: { config: AppConfig }) => {
const { width, depth, height } = config.drawer;
const offset = 0.5;
@@ -22,6 +22,7 @@ const DrawerFrame = ({ config }: { config: AppConfig }) => {
)
}
// --- BinMesh (Ячейка) ---
interface BinMeshProps {
part: GeneratedPart;
thickness: number;
@@ -49,12 +50,11 @@ const BinMesh: React.FC<BinMeshProps> = ({ part, thickness, isSelected, onClick
);
};
// --- Основной компонент ---
// --- PreviewStep (Основной) ---
interface Props {
parts: GeneratedPart[];
config: AppConfig;
splits: LayoutSplits; // <--- Добавили splits в пропсы
splits: LayoutSplits;
}
export const PreviewStep: React.FC<Props> = ({ parts, config, splits }) => {
@@ -100,18 +100,55 @@ export const PreviewStep: React.FC<Props> = ({ parts, config, splits }) => {
}
};
// Логика кнопки "Поделиться"
const handleShare = () => {
// --- Улучшенная функция копирования ---
const handleShare = async () => {
const url = generateShareUrl(config, splits);
navigator.clipboard.writeText(url).then(() => {
let success = false;
try {
// 1. Пробуем современный API (работает только на HTTPS или localhost)
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(url);
success = true;
} else {
throw new Error('Clipboard API unavailable');
}
} catch (err) {
// 2. Если не вышло (например, HTTP), используем Fallback метод
try {
const textArea = document.createElement("textarea");
textArea.value = url;
// Делаем элемент невидимым, но частью DOM
textArea.style.position = "fixed";
textArea.style.left = "-9999px";
textArea.style.top = "0";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
const result = document.execCommand('copy');
document.body.removeChild(textArea);
if (result) success = true;
} catch (e) {
console.error("Copy failed", e);
}
}
if (success) {
setShareUrlCopied(true);
setTimeout(() => setShareUrlCopied(false), 2000);
});
setTimeout(() => setShareUrlCopied(false), 3000);
} else {
// 3. Если совсем ничего не помогло, показываем промпт
prompt("Не удалось скопировать автоматически. Скопируйте ссылку вручную:", url);
}
};
return (
<div className="flex flex-col h-full">
{/* 1. ВЕРХНЯЯ ПАНЕЛЬ С РАЗМЕРАМИ И КНОПКОЙ SHARE */}
{/* Верхняя панель: Размеры + Поделиться */}
<div className="flex flex-col md:flex-row justify-between items-center bg-slate-800/80 p-4 rounded-xl border border-slate-700 mb-4 gap-4 backdrop-blur-sm shadow-lg">
<div className="flex items-center gap-6">
@@ -136,15 +173,15 @@ export const PreviewStep: React.FC<Props> = ({ parts, config, splits }) => {
<button
onClick={handleShare}
className={`
flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold transition-all border
flex items-center gap-2 px-6 py-2 rounded-lg text-sm font-bold transition-all border shadow-md active:scale-95
${shareUrlCopied
? 'bg-green-600/20 border-green-500/50 text-green-400'
: 'bg-slate-700 hover:bg-slate-600 border-slate-600 text-white'
? 'bg-green-600 border-green-500 text-white shadow-green-900/20'
: 'bg-blue-600 hover:bg-blue-500 border-blue-500 text-white shadow-blue-900/20'
}
`}
>
{shareUrlCopied ? <Check size={16} /> : <Share2 size={16} />}
{shareUrlCopied ? 'Ссылка скопирована!' : 'Поделиться проектом'}
{shareUrlCopied ? <Check size={18} /> : <Share2 size={18} />}
{shareUrlCopied ? 'СКОПИРОВАНО!' : 'Поделиться проектом'}
</button>
</div>