import Title from "@/components/Title"; import Header from "../../components/Header"; import { images } from "../../data"; import styles from "./styles.module.scss"; import { useTranslations } from "@/hooks/translations"; import { ELocalesPlacement } from "@/locales"; import { useEffect, useState, useRef } from "react"; import { useDispatch, useSelector } from "react-redux"; import { actions, selectors } from "@/store"; import Loader, { LoaderColor } from "@/components/Loader"; import { useNavigate } from "react-router-dom"; import routes from "@/routes"; import { IPalmistryFinger } from "@/api/resources/Palmistry"; import { ICompatibilityV2FingerLocal } from "@/store/compatibilityV2"; import { useApi } from "@/api"; import { DataURIToBlob } from "@/services/data"; function ScanHand() { const api = useApi(); const dispatch = useDispatch(); const navigate = useNavigate(); const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2); const [isLoading, setIsLoading] = useState(false); const imageRef = useRef(null); const gender = (useSelector(selectors.selectQuestionnaire)?.gender || "female"); const handleNext = () => { navigate(`${routes.client.compatibilityV2ScannedPhoto()}?fromScanHand=true`) } useEffect(() => { const timer = setTimeout(() => { handleHandOn() }, 6000); return () => clearTimeout(timer); }, []); const convertImageToBase64 = (img: HTMLImageElement): Promise => { return new Promise((resolve, reject) => { const canvas = document.createElement('canvas'); const padding = 100; canvas.width = img.width * 1.4 + padding * 2; canvas.height = img.height * 1.4; const ctx = canvas.getContext('2d'); if (!ctx) { reject(new Error('Не удалось получить контекст canvas')); return; } ctx.fillStyle = '#272727'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, padding, 0, img.width * 1.4, canvas.height); const base64String = canvas.toDataURL('image/png'); resolve(base64String); }); }; const fingersNames = { thumb: translate("thumb"), index_finger: translate("index_finger"), middle_finger: translate("middle_finger"), ring_finger: translate("ring_finger"), pinky: translate("pinky"), }; const setFingersNames = ( fingers: IPalmistryFinger[] ): ICompatibilityV2FingerLocal[] => { if (!fingers) return []; return fingers.map((finger) => { return { ...finger, fingerName: fingersNames[finger.name as keyof typeof fingersNames], }; }); }; const getLines = async (file: File | Blob) => { const formData = new FormData(); formData.append("file", file); try { const result = await api.getPalmistryLines({ formData, gender: gender as "male" | "female" }); const fingers = setFingersNames(result?.fingers); dispatch( actions.compatibilityV2.update({ lines: result?.lines, fingers, }) ); return result; } catch (error) { dispatch( actions.compatibilityV2.update({ lines: [], fingers: [], }) ); return null; } }; const handleHandOn = async () => { if (isLoading || !imageRef.current) return; setIsLoading(true); try { const photo = await convertImageToBase64(imageRef.current); const file = DataURIToBlob(photo); await getLines(file); URL.revokeObjectURL(URL.createObjectURL(file)); dispatch( actions.compatibilityV2.update({ photo, }) ); handleNext() } catch (error) { console.error('Ошибка при конвертации изображения:', error); } finally { setIsLoading(false); } } return (
{ e.preventDefault(); handleHandOn(); }} > {!isLoading && <>
Palm-tach-A {translate("/scan-hand.title")} } hand {isLoading && }
) } export default ScanHand