Develop
This commit is contained in:
parent
2700408741
commit
6c4acb9588
@ -1,12 +1,69 @@
|
||||
import Title from "@/components/Title";
|
||||
import styles from "./styles.module.scss";
|
||||
import { palmistryV1Prefix } from "@/routes";
|
||||
import PointRing from "./PointRing";
|
||||
import { ELocalesPlacement } from "@/locales";
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import PhotoReady from "../PhotoReady";
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectors } from "@/store";
|
||||
import { useMemo } from "react";
|
||||
import { palmistryV1Prefix } from "@/routes";
|
||||
import { IPalmistryLine } from "@/api/resources/Palmistry";
|
||||
import { IPalmistryFingerLocal } from "@/store/palmistry";
|
||||
import { useMetricABFlags } from "@/services/metric/metricService";
|
||||
|
||||
function PalmsSayAbout() {
|
||||
const { translate } = useTranslations(ELocalesPlacement.PalmistryV1);
|
||||
const lines = useSelector(selectors.selectPalmistryLines);
|
||||
const fingers = useSelector(selectors.selectPalmistryFingers);
|
||||
|
||||
const { flags } = useMetricABFlags();
|
||||
const isReal = flags?.palmOnPayment?.[0] === "real";
|
||||
|
||||
const filterByName = (
|
||||
array: Array<IPalmistryLine | IPalmistryFingerLocal>,
|
||||
name: string
|
||||
) => {
|
||||
return array.filter((value: IPalmistryLine | IPalmistryFingerLocal) => value.name === name);
|
||||
};
|
||||
|
||||
const love = useMemo(() => {
|
||||
return {
|
||||
lines: filterByName(lines, "heart") as IPalmistryLine[],
|
||||
fingers: filterByName(fingers, "thumb") as IPalmistryFingerLocal[],
|
||||
};
|
||||
}, [fingers, lines]);
|
||||
|
||||
const head = useMemo(() => {
|
||||
return {
|
||||
lines: filterByName(lines, "head") as IPalmistryLine[],
|
||||
fingers: filterByName(fingers, "index_finger") as IPalmistryFingerLocal[],
|
||||
};
|
||||
}, [fingers, lines]);
|
||||
|
||||
const life = useMemo(() => {
|
||||
return {
|
||||
lines: filterByName(lines, "life") as IPalmistryLine[],
|
||||
fingers: filterByName(
|
||||
fingers,
|
||||
"middle_finger"
|
||||
) as IPalmistryFingerLocal[],
|
||||
};
|
||||
}, [fingers, lines]);
|
||||
|
||||
const fate = useMemo(() => {
|
||||
return {
|
||||
lines: filterByName(lines, "fate") as IPalmistryLine[],
|
||||
fingers: filterByName(fingers, "ring_finger") as IPalmistryFingerLocal[],
|
||||
};
|
||||
}, [fingers, lines]);
|
||||
|
||||
const pinky = useMemo(() => {
|
||||
return {
|
||||
lines: [],
|
||||
fingers: filterByName(fingers, "pinky") as IPalmistryFingerLocal[],
|
||||
};
|
||||
}, [fingers]);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@ -15,10 +72,19 @@ function PalmsSayAbout() {
|
||||
</Title>
|
||||
<div className={styles.rows}>
|
||||
<div className={styles.row}>
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/love-line.svg`}
|
||||
alt="Hand with love line"
|
||||
/>
|
||||
{!!love.lines.length && !!love.fingers.length && isReal && (
|
||||
<PhotoReady
|
||||
className={styles["photo-ready"]}
|
||||
lines={love.lines}
|
||||
fingers={love.fingers}
|
||||
/>
|
||||
)}
|
||||
{(!love.lines.length || !love.fingers.length || !isReal) && (
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/love-line.svg`}
|
||||
alt="Hand with love line"
|
||||
/>
|
||||
)}
|
||||
<div className={styles.points}>
|
||||
<div className={styles.point}>
|
||||
<PointRing />
|
||||
@ -41,10 +107,19 @@ function PalmsSayAbout() {
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.row}>
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/head-line.svg`}
|
||||
alt="Hand with head line"
|
||||
/>
|
||||
{!!head.lines.length && !!head.fingers.length && isReal && (
|
||||
<PhotoReady
|
||||
className={styles["photo-ready"]}
|
||||
lines={head.lines}
|
||||
fingers={head.fingers}
|
||||
/>
|
||||
)}
|
||||
{(!head.lines.length || !head.fingers.length || !isReal) && (
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/head-line.svg`}
|
||||
alt="Hand with head line"
|
||||
/>
|
||||
)}
|
||||
<div className={styles.points}>
|
||||
<div className={styles.point}>
|
||||
<PointRing gradientColor={["#34DF3D", "#27A72D"]} />
|
||||
@ -67,10 +142,19 @@ function PalmsSayAbout() {
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.row}>
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/life-line.svg`}
|
||||
alt="Hand with life line"
|
||||
/>
|
||||
{!!life.lines.length && !!life.fingers.length && isReal && (
|
||||
<PhotoReady
|
||||
className={styles["photo-ready"]}
|
||||
lines={life.lines}
|
||||
fingers={life.fingers}
|
||||
/>
|
||||
)}
|
||||
{(!life.lines.length || !life.fingers.length || !isReal) && (
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/life-line.svg`}
|
||||
alt="Hand with life line"
|
||||
/>
|
||||
)}
|
||||
<div className={styles.points}>
|
||||
<div className={styles.point}>
|
||||
<PointRing gradientColor={["#363AB0", "#282C84"]} />
|
||||
@ -93,10 +177,19 @@ function PalmsSayAbout() {
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.row}>
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/fate-line.svg`}
|
||||
alt="Hand with fate line"
|
||||
/>
|
||||
{!!fate.lines.length && !!fate.fingers.length && isReal && (
|
||||
<PhotoReady
|
||||
className={styles["photo-ready"]}
|
||||
lines={fate.lines}
|
||||
fingers={fate.fingers}
|
||||
/>
|
||||
)}
|
||||
{(!fate.lines.length || !fate.fingers.length || !isReal) && (
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/fate-line.svg`}
|
||||
alt="Hand with fate line"
|
||||
/>
|
||||
)}
|
||||
<div className={styles.points}>
|
||||
<div className={styles.point}>
|
||||
<PointRing gradientColor={["#DF38E4", "#922595"]} />
|
||||
@ -119,10 +212,19 @@ function PalmsSayAbout() {
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.row}>
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/hand-little-finger.svg`}
|
||||
alt="Hand with little finger"
|
||||
/>
|
||||
{!!pinky.fingers.length && isReal && (
|
||||
<PhotoReady
|
||||
className={styles["photo-ready"]}
|
||||
lines={[]}
|
||||
fingers={pinky.fingers}
|
||||
/>
|
||||
)}
|
||||
{(!pinky.fingers.length || !isReal) && (
|
||||
<img
|
||||
src={`${palmistryV1Prefix}/hand-little-finger.svg`}
|
||||
alt="Hand with little finger"
|
||||
/>
|
||||
)}
|
||||
<div className={styles.points}>
|
||||
<div className={styles.point}>
|
||||
<PointRing gradientColor={["#E9453A", "#922B25"]} />
|
||||
|
||||
@ -52,3 +52,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.photo-ready {
|
||||
max-width: 90px;
|
||||
}
|
||||
|
||||
105
src/components/PalmistryV1/components/PhotoReady/index.tsx
Normal file
105
src/components/PalmistryV1/components/PhotoReady/index.tsx
Normal file
@ -0,0 +1,105 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import styles from "./styles.module.scss";
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectors } from "@/store";
|
||||
import { IPalmistryLine, IPalmistryPoint } from "@/api/resources/Palmistry";
|
||||
import { IPalmistryFingerLocal } from "@/store/palmistry";
|
||||
|
||||
interface IPhotoReadyProps {
|
||||
className?: string;
|
||||
lines: IPalmistryLine[];
|
||||
fingers: IPalmistryFingerLocal[];
|
||||
}
|
||||
|
||||
function PhotoReady({ className = "", lines, fingers }: IPhotoReadyProps) {
|
||||
const photo = useSelector(selectors.selectPalmistryPhoto);
|
||||
|
||||
const imageRef = useRef<HTMLImageElement>(null);
|
||||
const [isImageLoaded, setIsImageLoaded] = useState(false);
|
||||
const [imageWidth, setImageWidth] = useState(0);
|
||||
const [imageHeight, setImageHeight] = useState(0);
|
||||
const linesRef = useRef<SVGPathElement[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isImageLoaded && imageRef.current) {
|
||||
setImageWidth(imageRef.current.width || 0);
|
||||
setImageHeight(imageRef.current.height || 0);
|
||||
}
|
||||
}, [isImageLoaded]);
|
||||
|
||||
const getCoordinatesString = useCallback(
|
||||
(points: IPalmistryPoint[]) => {
|
||||
const coordinatesString = `M ${points[0]?.x * imageWidth} ${
|
||||
points[0]?.y * imageHeight
|
||||
}`;
|
||||
return points.reduce(
|
||||
(acc, point) =>
|
||||
`${acc} L ${point?.x * imageWidth} ${point?.y * imageHeight}`,
|
||||
coordinatesString
|
||||
);
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[lines, isImageLoaded, imageWidth, imageHeight]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={`${styles.container} ${className}`}>
|
||||
<img
|
||||
className="scanned-photo__image"
|
||||
alt="PalmIcon"
|
||||
src={photo}
|
||||
ref={imageRef}
|
||||
onLoad={() => setIsImageLoaded(true)}
|
||||
/>
|
||||
{!!imageHeight && !!imageWidth && (
|
||||
<svg
|
||||
viewBox={`0 0 ${imageWidth} ${imageHeight}`}
|
||||
className={styles["svg-objects"]}
|
||||
>
|
||||
{!!fingers.length &&
|
||||
fingers?.map((finger, index) => {
|
||||
return (
|
||||
<svg
|
||||
x={finger.point.x * imageWidth - 12}
|
||||
y={finger.point.y * imageHeight - 12}
|
||||
height="24px"
|
||||
width="24px"
|
||||
key={index}
|
||||
>
|
||||
{/* <circle
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
r="11"
|
||||
fill="white"
|
||||
opacity="0.3"
|
||||
className="scanned-photo__finger-point"
|
||||
/> */}
|
||||
<circle
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
r="4"
|
||||
fill="#066FDE"
|
||||
stroke="white"
|
||||
strokeWidth="0.3"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
})}
|
||||
|
||||
<>
|
||||
{lines.map((line, index) => (
|
||||
<path
|
||||
key={index}
|
||||
className={`${styles.line} ${styles[`line-${line?.name}`]}`}
|
||||
d={getCoordinatesString(line?.points)}
|
||||
ref={(el) => (linesRef.current[index] = el as SVGPathElement)}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PhotoReady;
|
||||
@ -0,0 +1,43 @@
|
||||
.container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.svg-objects {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.line {
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 2px;
|
||||
fill-rule: evenodd;
|
||||
clip-rule: evenodd;
|
||||
stroke-miterlimit: 1.5;
|
||||
stroke-dasharray: 500;
|
||||
stroke: #fff;
|
||||
fill: none;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
|
||||
.line-heart {
|
||||
stroke: #f8d90f;
|
||||
/* animation-delay: 4.5s; */
|
||||
}
|
||||
|
||||
.line-life {
|
||||
stroke: #e51c39;
|
||||
}
|
||||
|
||||
.line-head {
|
||||
stroke: #00d114;
|
||||
/* animation-delay: 1.5s; */
|
||||
}
|
||||
|
||||
.line-fate {
|
||||
stroke: #05ced8;
|
||||
/* animation-delay: 3s; */
|
||||
}
|
||||
@ -2,7 +2,7 @@ import { useDispatch, useSelector } from "react-redux";
|
||||
import EmailSubstrate from "../../components/EmailSubstrate";
|
||||
import styles from "./styles.module.scss";
|
||||
import { actions, selectors } from "@/store";
|
||||
import Title from "@/components/Title";
|
||||
// import Title from "@/components/Title";
|
||||
import PriceList from "@/components/pages/ABDesign/v1/components/PriceList";
|
||||
import { usePaywall } from "@/hooks/paywall/usePaywall";
|
||||
import { EPlacementKeys } from "@/api/resources/Paywall";
|
||||
@ -17,7 +17,7 @@ import routes from "@/routes";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Loader from "@/components/Loader";
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import { useMetricABFlags } from "@/services/metric/metricService";
|
||||
// import { useMetricABFlags } from "@/services/metric/metricService";
|
||||
import { getLongText } from "./abText";
|
||||
|
||||
function TrialChoice() {
|
||||
@ -31,8 +31,8 @@ function TrialChoice() {
|
||||
|
||||
const locale = getDefaultLocaleByLanguage(language);
|
||||
|
||||
const { flags } = useMetricABFlags();
|
||||
const isLongText = flags?.text?.[0] === "on";
|
||||
// const { flags } = useMetricABFlags();
|
||||
// const isLongText = flags?.text?.[0] === "on";
|
||||
|
||||
const [isDisabled, setIsDisabled] = useState(true);
|
||||
|
||||
@ -61,12 +61,12 @@ function TrialChoice() {
|
||||
{!isLoading && (
|
||||
<>
|
||||
<EmailSubstrate className={styles["email-substrate"]} email={email} />
|
||||
{!isLongText && (
|
||||
{/* {!isLongText && (
|
||||
<Title className={styles.title} variant="h2">
|
||||
{getText("text.0")}
|
||||
</Title>
|
||||
)}
|
||||
{isLongText && <p className={styles.text}>{getLongText(locale)}</p>}
|
||||
)} */}
|
||||
<p className={styles.text}>{getLongText(locale)}</p>
|
||||
|
||||
<div className={styles["price-container"]}>
|
||||
<PriceList
|
||||
|
||||
@ -150,6 +150,7 @@ type TABFlags = {
|
||||
auraVideoTrial: "on";
|
||||
auraPalmistry: "on";
|
||||
esFlag: "hiCopy" | "standard";
|
||||
palmOnPayment: "graphical" | "real"
|
||||
}
|
||||
|
||||
export const useMetricABFlags = () => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user