Merge branch 'preview/advisors' into 'develop'

Preview/advisors

See merge request witapp/aura-webapp!75
This commit is contained in:
Daniil Chemerkin 2024-04-06 20:40:38 +00:00
commit d381440556
10 changed files with 143 additions and 9 deletions

View File

@ -26,7 +26,7 @@ import {
AIRequestsV2, AIRequestsV2,
Assistants, Assistants,
OpenAI, OpenAI,
SinglePayment SinglePayment,
} from './resources' } from './resources'
const api = { const api = {

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { import {
Routes, Routes,
Route, Route,
@ -109,6 +109,7 @@ import AdvisorChatPage from "../pages/AdvisorChat";
import PaymentWithEmailPage from "../pages/PaymentWithEmailPage"; import PaymentWithEmailPage from "../pages/PaymentWithEmailPage";
import SuccessPaymentPage from "../pages/PaymentWithEmailPage/ResultPayment/SuccessPaymentPage"; import SuccessPaymentPage from "../pages/PaymentWithEmailPage/ResultPayment/SuccessPaymentPage";
import FailPaymentPage from "../pages/PaymentWithEmailPage/ResultPayment/FailPaymentPage"; import FailPaymentPage from "../pages/PaymentWithEmailPage/ResultPayment/FailPaymentPage";
import { useSchemeColorByElement } from "@/hooks/useSchemeColorByElement";
import GetInformationPartnerPage from "../pages/GetInformationPartner"; import GetInformationPartnerPage from "../pages/GetInformationPartner";
const isProduction = import.meta.env.MODE === "production"; const isProduction = import.meta.env.MODE === "production";
@ -228,6 +229,26 @@ function App(): JSX.Element {
} }
}, [dispatch]); }, [dispatch]);
// useEffect(() => {
// const motion = window.matchMedia("(prefers-reduced-motion: no-preference)");
// if (motion.matches) {
// const scheme = document.querySelector('meta[name="theme-color"]');
// console.log(document.querySelectorAll("section.page")[0]);
// let hue = 0;
// let color;
// const backgroundColor =
// window.getComputedStyle(document.querySelectorAll("section.page")[0])
// .backgroundColor || "#ffffff";
// scheme?.setAttribute("content", backgroundColor);
// setInterval(() => {
// color = `hsl(${(hue += 5)} 50% 30%)`;
// document.body.style.background = color;
// scheme?.setAttribute("content", color);
// }, 50);
// }
// }, []);
return ( return (
<Routes> <Routes>
<Route element={<Layout setIsSpecialOfferOpen={setIsSpecialOfferOpen} />}> <Route element={<Layout setIsSpecialOfferOpen={setIsSpecialOfferOpen} />}>
@ -550,6 +571,19 @@ function Layout({ setIsSpecialOfferOpen }: LayoutProps): JSX.Element {
const changeIsSpecialOfferOpen = () => setIsSpecialOfferOpen(true); const changeIsSpecialOfferOpen = () => setIsSpecialOfferOpen(true);
const homeConfig = useSelector(selectors.selectHome); const homeConfig = useSelector(selectors.selectHome);
const showNavbarFooter = homeConfig.isShowNavbar; const showNavbarFooter = homeConfig.isShowNavbar;
const mainRef = useRef<HTMLDivElement>(null);
// console.log(
// mainRef.current?.querySelectorAll("section.page, .page, section")
// );
useSchemeColorByElement(mainRef.current, "section.page, .page, section", [
location,
]);
// useEffect(() => {
// console.log(
// "###$",
// mainRef.current?.querySelectorAll("section.page, .page, section")[0]
// );
// }, [location]);
const birthdate = useSelector(selectors.selectBirthdate); const birthdate = useSelector(selectors.selectBirthdate);
const dataItems = useMemo(() => [birthdate], [birthdate]); const dataItems = useMemo(() => [birthdate], [birthdate]);
@ -644,7 +678,7 @@ function Layout({ setIsSpecialOfferOpen }: LayoutProps): JSX.Element {
<FullDataModal onClose={onCloseFullDataModal} /> <FullDataModal onClose={onCloseFullDataModal} />
</Modal> </Modal>
)} )}
<main className="content"> <main className="content" ref={mainRef}>
<Outlet /> <Outlet />
</main> </main>
{showFooter ? <Footer color={showNavbar ? "black" : "white"} /> : null} {showFooter ? <Footer color={showNavbar ? "black" : "white"} /> : null}

View File

@ -29,3 +29,12 @@
.page-responsive { .page-responsive {
width: 100%; width: 100%;
} }
#color-pointer {
position: fixed;
background: transparent;
z-index: 12323423;
width: 100%;
height: 2px;
pointer-events: none;
}

View File

@ -13,6 +13,7 @@ import { IMessage, ResponseRunThread } from "@/api/resources/OpenAI";
import Message from "./components/Message"; import Message from "./components/Message";
import LoaderDots from "./components/LoaderDots"; import LoaderDots from "./components/LoaderDots";
import useDetectScroll from "@smakss/react-scroll-direction"; import useDetectScroll from "@smakss/react-scroll-direction";
import { getZodiacSignByDate } from "@/services/zodiac-sign";
function AdvisorChatPage() { function AdvisorChatPage() {
const { id } = useParams(); const { id } = useParams();
@ -21,6 +22,10 @@ function AdvisorChatPage() {
const { scrollDir, scrollPosition } = useDetectScroll(); const { scrollDir, scrollPosition } = useDetectScroll();
const token = useSelector(selectors.selectToken); const token = useSelector(selectors.selectToken);
const openAiToken = useSelector(selectors.selectOpenAiToken); const openAiToken = useSelector(selectors.selectOpenAiToken);
const birthdate = useSelector(selectors.selectBirthdate);
const zodiacSign = getZodiacSignByDate(birthdate);
const { username } = useSelector(selectors.selectUser);
const { gender } = useSelector(selectors.selectQuestionnaire);
const [assistant, setAssistant] = useState<IAssistant>(); const [assistant, setAssistant] = useState<IAssistant>();
const [messageText, setMessageText] = useState(""); const [messageText, setMessageText] = useState("");
const [textareaRows, setTextareaRows] = useState(1); const [textareaRows, setTextareaRows] = useState(1);
@ -192,12 +197,15 @@ function AdvisorChatPage() {
}; };
const createMessage = async (messageText: string, threadId: string) => { const createMessage = async (messageText: string, threadId: string) => {
const content = `#USER INFO: zodiac sign - ${zodiacSign}; gender - ${gender}; birthdate - ${birthdate}; name - ${
username || "unknown"
};# ${messageText}`;
const message = await api.createMessage({ const message = await api.createMessage({
token: openAiToken, token: openAiToken,
method: "POST", method: "POST",
path: routes.openAi.createMessage(threadId), path: routes.openAi.createMessage(threadId),
role: "user", role: "user",
content: messageText, content: content,
}); });
return message; return message;
}; };
@ -294,6 +302,14 @@ function AdvisorChatPage() {
const getIsSelfMessage = (role: string) => role === "user"; const getIsSelfMessage = (role: string) => role === "user";
const deleteDataFromMessage = (messageText: string) => {
const splittedText = messageText.split("#");
if (splittedText.length > 2) {
return splittedText.slice(2).join("#");
}
return messageText;
};
return ( return (
<section className={`${styles.page} page`}> <section className={`${styles.page} page`}>
{isLoading && ( {isLoading && (
@ -322,7 +338,7 @@ function AdvisorChatPage() {
message.content.map((content) => ( message.content.map((content) => (
<Message <Message
avatar={assistant?.photo?.th2x || ""} avatar={assistant?.photo?.th2x || ""}
text={content.text.value} text={deleteDataFromMessage(content.text.value)}
advisorName={assistant?.name || ""} advisorName={assistant?.name || ""}
backgroundTextColor={ backgroundTextColor={
getIsSelfMessage(message.role) ? "#0080ff" : "#c9c9c9" getIsSelfMessage(message.role) ? "#0080ff" : "#c9c9c9"

View File

@ -27,7 +27,7 @@ function AssistantCard({
</Title> </Title>
</div> </div>
<div className={styles.footer}> <div className={styles.footer}>
<span className={styles.expirience}>{expirience}</span> <span className={styles.experience}>{expirience}</span>
<div className={styles["rating-container"]}> <div className={styles["rating-container"]}>
<div className={styles.stars}> <div className={styles.stars}>
{Array(stars) {Array(stars)

View File

@ -70,10 +70,11 @@
margin-top: 8px; margin-top: 8px;
} }
.expirience { .experience {
white-space: nowrap; white-space: nowrap;
display: block; display: block;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
width: 100%; width: 100%;
line-height: 150%;
} }

View File

@ -25,7 +25,7 @@ function Advisors() {
setAssistants(ai_assistants); setAssistants(ai_assistants);
setIsLoading(false); setIsLoading(false);
return { ai_assistants }; return { ai_assistants };
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [api, dispatch, token]); }, [api, dispatch, token]);
useApiCall<Assistants.Response>(loadData); useApiCall<Assistants.Response>(loadData);

View File

@ -13,7 +13,7 @@ function SuccessPaymentPage(): JSX.Element {
style={{ minHeight: "98px" }} style={{ minHeight: "98px" }}
/> />
<div className={styles.text}> <div className={styles.text}>
<Title variant="h1">The information has been sent to your e-mail</Title> <Title variant="h1">The information has been sent to your email</Title>
<p>{t("auweb.pay_good.text1")}</p> <p>{t("auweb.pay_good.text1")}</p>
</div> </div>
</section> </section>

View File

@ -0,0 +1,30 @@
import { getValuesFromRGBString } from "@/services/color-formatter";
import { useEffect } from "react";
export const useSchemeColorByElement = (
element: Element | null,
searchSelectors: string,
dependencies: ReadonlyArray<unknown> = []
) => {
useEffect(() => {
const pageElement = element?.querySelectorAll(searchSelectors)[0];
console.log("pageElement", pageElement);
const scheme = document.querySelector('meta[name="theme-color"]');
if (scheme && !pageElement) {
return scheme.setAttribute("content", "#ffffff");
}
if (!pageElement) return;
let backgroundColor = window.getComputedStyle(pageElement)?.backgroundColor;
const colorScheme = getValuesFromRGBString(backgroundColor);
if (colorScheme?.a === 0) {
backgroundColor = "#ffffff";
}
console.log("backgroundColor", backgroundColor);
if (scheme && backgroundColor.length) {
return scheme.setAttribute("content", backgroundColor);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [element, ...dependencies]);
return null;
};

View File

@ -0,0 +1,44 @@
const hexToRgb = (hex: string) => {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function (_m, r, g, b) {
return r + r + g + g + b + b;
});
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
}
: null;
};
interface IRGBValues {
r: number;
g: number;
b: number;
}
const rgbToHex = ({ r, g, b }: IRGBValues) => {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
};
export const getValuesFromRGBString = (rgb: string) => {
const rgbValues = rgb.match(/\d+/g);
if (rgbValues) {
return {
r: Number(rgbValues[0]),
g: Number(rgbValues[1]),
b: Number(rgbValues[2]),
a: Number(rgbValues[3] || 1),
};
}
return null;
};
export class ColorFormatter {
public static rgbToHex = rgbToHex;
public static hexToRgb = hexToRgb;
}