Merge branch 'develop' into 'main'
Develop See merge request witapp/aura-webapp!492
This commit is contained in:
commit
bbcbcaec1a
@ -1,12 +1,69 @@
|
|||||||
import Title from "@/components/Title";
|
import Title from "@/components/Title";
|
||||||
import styles from "./styles.module.scss";
|
import styles from "./styles.module.scss";
|
||||||
import { palmistryV1Prefix } from "@/routes";
|
|
||||||
import PointRing from "./PointRing";
|
import PointRing from "./PointRing";
|
||||||
import { ELocalesPlacement } from "@/locales";
|
import { ELocalesPlacement } from "@/locales";
|
||||||
import { useTranslations } from "@/hooks/translations";
|
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() {
|
function PalmsSayAbout() {
|
||||||
const { translate } = useTranslations(ELocalesPlacement.PalmistryV1);
|
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 (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
@ -15,10 +72,19 @@ function PalmsSayAbout() {
|
|||||||
</Title>
|
</Title>
|
||||||
<div className={styles.rows}>
|
<div className={styles.rows}>
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
<img
|
{!!love.lines.length && !!love.fingers.length && isReal && (
|
||||||
src={`${palmistryV1Prefix}/love-line.svg`}
|
<PhotoReady
|
||||||
alt="Hand with love line"
|
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.points}>
|
||||||
<div className={styles.point}>
|
<div className={styles.point}>
|
||||||
<PointRing />
|
<PointRing />
|
||||||
@ -41,10 +107,19 @@ function PalmsSayAbout() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
<img
|
{!!head.lines.length && !!head.fingers.length && isReal && (
|
||||||
src={`${palmistryV1Prefix}/head-line.svg`}
|
<PhotoReady
|
||||||
alt="Hand with head line"
|
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.points}>
|
||||||
<div className={styles.point}>
|
<div className={styles.point}>
|
||||||
<PointRing gradientColor={["#34DF3D", "#27A72D"]} />
|
<PointRing gradientColor={["#34DF3D", "#27A72D"]} />
|
||||||
@ -67,10 +142,19 @@ function PalmsSayAbout() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
<img
|
{!!life.lines.length && !!life.fingers.length && isReal && (
|
||||||
src={`${palmistryV1Prefix}/life-line.svg`}
|
<PhotoReady
|
||||||
alt="Hand with life line"
|
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.points}>
|
||||||
<div className={styles.point}>
|
<div className={styles.point}>
|
||||||
<PointRing gradientColor={["#363AB0", "#282C84"]} />
|
<PointRing gradientColor={["#363AB0", "#282C84"]} />
|
||||||
@ -93,10 +177,19 @@ function PalmsSayAbout() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
<img
|
{!!fate.lines.length && !!fate.fingers.length && isReal && (
|
||||||
src={`${palmistryV1Prefix}/fate-line.svg`}
|
<PhotoReady
|
||||||
alt="Hand with fate line"
|
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.points}>
|
||||||
<div className={styles.point}>
|
<div className={styles.point}>
|
||||||
<PointRing gradientColor={["#DF38E4", "#922595"]} />
|
<PointRing gradientColor={["#DF38E4", "#922595"]} />
|
||||||
@ -119,10 +212,19 @@ function PalmsSayAbout() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
<img
|
{!!pinky.fingers.length && isReal && (
|
||||||
src={`${palmistryV1Prefix}/hand-little-finger.svg`}
|
<PhotoReady
|
||||||
alt="Hand with little finger"
|
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.points}>
|
||||||
<div className={styles.point}>
|
<div className={styles.point}>
|
||||||
<PointRing gradientColor={["#E9453A", "#922B25"]} />
|
<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 EmailSubstrate from "../../components/EmailSubstrate";
|
||||||
import styles from "./styles.module.scss";
|
import styles from "./styles.module.scss";
|
||||||
import { actions, selectors } from "@/store";
|
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 PriceList from "@/components/pages/ABDesign/v1/components/PriceList";
|
||||||
import { usePaywall } from "@/hooks/paywall/usePaywall";
|
import { usePaywall } from "@/hooks/paywall/usePaywall";
|
||||||
import { EPlacementKeys } from "@/api/resources/Paywall";
|
import { EPlacementKeys } from "@/api/resources/Paywall";
|
||||||
@ -17,7 +17,7 @@ import routes from "@/routes";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Loader from "@/components/Loader";
|
import Loader from "@/components/Loader";
|
||||||
import { useTranslations } from "@/hooks/translations";
|
import { useTranslations } from "@/hooks/translations";
|
||||||
import { useMetricABFlags } from "@/services/metric/metricService";
|
// import { useMetricABFlags } from "@/services/metric/metricService";
|
||||||
import { getLongText } from "./abText";
|
import { getLongText } from "./abText";
|
||||||
|
|
||||||
function TrialChoice() {
|
function TrialChoice() {
|
||||||
@ -31,8 +31,8 @@ function TrialChoice() {
|
|||||||
|
|
||||||
const locale = getDefaultLocaleByLanguage(language);
|
const locale = getDefaultLocaleByLanguage(language);
|
||||||
|
|
||||||
const { flags } = useMetricABFlags();
|
// const { flags } = useMetricABFlags();
|
||||||
const isLongText = flags?.text?.[0] === "on";
|
// const isLongText = flags?.text?.[0] === "on";
|
||||||
|
|
||||||
const [isDisabled, setIsDisabled] = useState(true);
|
const [isDisabled, setIsDisabled] = useState(true);
|
||||||
|
|
||||||
@ -61,12 +61,12 @@ function TrialChoice() {
|
|||||||
{!isLoading && (
|
{!isLoading && (
|
||||||
<>
|
<>
|
||||||
<EmailSubstrate className={styles["email-substrate"]} email={email} />
|
<EmailSubstrate className={styles["email-substrate"]} email={email} />
|
||||||
{!isLongText && (
|
{/* {!isLongText && (
|
||||||
<Title className={styles.title} variant="h2">
|
<Title className={styles.title} variant="h2">
|
||||||
{getText("text.0")}
|
{getText("text.0")}
|
||||||
</Title>
|
</Title>
|
||||||
)}
|
)} */}
|
||||||
{isLongText && <p className={styles.text}>{getLongText(locale)}</p>}
|
<p className={styles.text}>{getLongText(locale)}</p>
|
||||||
|
|
||||||
<div className={styles["price-container"]}>
|
<div className={styles["price-container"]}>
|
||||||
<PriceList
|
<PriceList
|
||||||
|
|||||||
@ -150,6 +150,7 @@ type TABFlags = {
|
|||||||
auraVideoTrial: "on";
|
auraVideoTrial: "on";
|
||||||
auraPalmistry: "on";
|
auraPalmistry: "on";
|
||||||
esFlag: "hiCopy" | "standard";
|
esFlag: "hiCopy" | "standard";
|
||||||
|
palmOnPayment: "graphical" | "real"
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useMetricABFlags = () => {
|
export const useMetricABFlags = () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user