domain/sidebar logic, new landing for non-logged in

This commit is contained in:
BFlat committed 2024-02-07 01:48:44 +07:00
1 parent eaa6d34730
commit c6830cf9e3
11 files changed
+1705 -1614

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

@@ -53,6 +53,13 @@ export default function SideNav({
const isDevelopmentEnv = fakeYouFrontendEnv.isDevelopment();
const wrapper = document.getElementById("wrapper");
const isMenuOpen = wrapper?.classList.contains("toggled");
const isLoggedIn = sessionWrapper.isLoggedIn();
const isOnLandingPage = window.location.pathname === "/";
const isOnLoginOrSignUpPage =
window.location.pathname === "/login" ||
window.location.pathname === "/login/" ||
window.location.pathname === "/signup" ||
window.location.pathname === "/signup/";
let history = useHistory();
const handleNavLinkClick = () => {
@@ -102,17 +109,25 @@ export default function SideNav({
};
}, []);
const shouldShowSidebar = windowWidth >= 992;
const shouldNotShowSidebar =
!isLoggedIn && (isOnLandingPage || isOnLoginOrSignUpPage);
const shouldShowSidebar = windowWidth >= 992 && !shouldNotShowSidebar;
const sidebarClassName = `sidebar ${
shouldShowSidebar ? "visible" : ""
}`.trim();
useEffect(() => {
const contentWrapper = document.getElementById("page-content-wrapper");
if (windowWidth >= 992) {
if (
(shouldShowSidebar && isLoggedIn) ||
(shouldShowSidebar && !isOnLandingPage)
) {
contentWrapper?.classList.remove("no-padding");
} else {
contentWrapper?.classList.add("no-padding");
}
}, [windowWidth]);
}, [isLoggedIn, isOnLandingPage, shouldShowSidebar]);
const [queueStats, setQueueStats] = useState<GetQueueStatsSuccessResponse>({
success: true,
@@ -256,10 +271,7 @@ export default function SideNav({
return (
<>
<div
id="sidebar-wrapper"
className={`sidebar ${shouldShowSidebar ? "visible" : ""}`}
>
<div id="sidebar-wrapper" className={sidebarClassName}>
<div>
<ul className="sidebar-nav">
<li>
@@ -12,6 +12,7 @@ import { Link, useHistory } from "react-router-dom";
import { WebUrl } from "common/WebUrl";
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
import { Logout } from "@storyteller/components/src/api/session/Logout";
import { useDomainConfig } from "context/DomainConfigContext";
interface TopNavProps {
sessionWrapper: SessionWrapper;
@@ -25,6 +26,7 @@ export default function TopNav({
querySessionCallback,
querySessionSubscriptionsCallback,
}: TopNavProps) {
const domain = useDomainConfig();
let history = useHistory();
const [isMobileSearchBarVisible, setIsMobileSearchBarVisible] =
useState(false);
@@ -181,14 +183,14 @@ export default function TopNav({
<div className="topbar-nav-left">
<Link to="/">
<img
src="/fakeyou/FakeYou-Logo.png"
alt="FakeYou: Cartoon and Celebrity Text to Speech"
src={domain.logo}
alt={`${domain.title}: Cartoon and Celebrity Text to Speech`}
height="34"
className="mb-2 d-none d-lg-block"
/>
<img
src="/fakeyou/FakeYou-Logo-Mobile.png"
alt="FakeYou: Cartoon and Celebrity Text to Speech"
alt={`${domain.title}: Cartoon and Celebrity Text to Speech`}
height="36"
className="mb-0 d-block d-lg-none"
/>
@@ -0,0 +1,22 @@
import React, { createContext, useContext, ReactNode } from "react";
import { getCurrentDomainConfig } from "../utils/domainConfig";
const DomainConfigContext = createContext(getCurrentDomainConfig());
export const useDomainConfig = () => useContext(DomainConfigContext);
interface DomainConfigProviderProps {
children: ReactNode;
}
export default function DomainConfigProvider({
children,
}: DomainConfigProviderProps) {
const domainConfig = getCurrentDomainConfig();
return (
<DomainConfigContext.Provider value={domainConfig}>
{children}
</DomainConfigContext.Provider>
);
}
+8 -1
View File
@@ -2,5 +2,12 @@ import AccountModalContext from "./AccountModalContext";
import InferenceJobsContext from "./InferenceJobsContext";
import ModalContext from "./ModalContext";
import SessionContext from "./SessionContext";
import DomainConfigContext from "./DomainConfigContext";
export { AccountModalContext, InferenceJobsContext, ModalContext, SessionContext };
export {
AccountModalContext,
InferenceJobsContext,
ModalContext,
SessionContext,
DomainConfigContext,
};
+1
View File
@@ -60,6 +60,7 @@ $topbar-height: 66px;
position: relative;
padding-left: 260px;
padding-top: $topbar-height;
transition: all 0.2s ease;
}
/* Sidebar Styles */
@@ -0,0 +1,35 @@
type DomainConfig = Record<string, any>;
const domainConfigs: Record<string, DomainConfig> = {
"storyteller.ai": {
logo: "/fakeyou/Storyteller-Logo.png",
title: "Storyteller AI",
link: "https://storyteller.ai",
},
"fakeyou.com": {
logo: "/fakeyou/FakeYou-Logo.png",
title: "FakeYou",
link: "https://fakeyou.com",
},
// Default to FakeYou.com
default: {
logo: "/fakeyou/FakeYou-Logo.png",
title: "FakeYou",
link: "https://fakeyou.com",
},
};
export const getCurrentDomainConfig = (): DomainConfig => {
const currentHostname = window.location.hostname;
const matchingConfigKey = Object.keys(domainConfigs).find(
key => currentHostname === key || currentHostname.endsWith(`.${key}`)
);
const domainConfig =
matchingConfigKey !== undefined
? domainConfigs[matchingConfigKey]
: domainConfigs["default"];
return domainConfig;
};
File diff suppressed because it is too large. Load diff
@@ -19,12 +19,14 @@ import {
} from "@storyteller/components/src/api/server/GetServerInfo";
import { useLocalize } from "hooks";
import { Container } from "components/common";
import { useDomainConfig } from "context/DomainConfigContext";
interface Props {
sessionWrapper: SessionWrapper;
}
function FooterNav(props: Props) {
const domain = useDomainConfig();
const { t } = useLocalize("Footer");
const [serverInfo, setServerInfo] = useState<
GetServerInfoSuccessResponse | undefined
@@ -84,8 +86,8 @@ function FooterNav(props: Props) {
<div className="col-12 col-lg-3 d-flex flex-column gap-4 align-items-center align-items-lg-start">
<Link to="/">
<img
src="/fakeyou/FakeYou-Logo.png"
alt="FakeYou: Cartoon and Celebrity Text to Speech"
src={domain.logo}
alt={`${domain.title}: Cartoon and Celebrity Text to Speech`}
height="34"
/>
</Link>
@@ -204,12 +206,17 @@ function FooterNav(props: Props) {
</div>
<div className="d-flex flex-column flex-lg-row pt-2 align-items-center gap-2 gap-xl-4 flex-wrap">
<span className="flex-grow-1">
© 2023 FakeYou by{" "}
<a href="https://storyteller.ai" target="_blank" rel="noreferrer">
Storyteller.ai
</a>
</span>
{domain.title === "FakeYou" ? (
<span className="flex-grow-1">
© 2023 {domain.title} by{" "}
<a href={domain.link} target="_blank" rel="noreferrer">
Storyteller.ai
</a>
</span>
) : (
<span className="flex-grow-1">© 2023 {domain.title}</span>
)}
<div className="d-flex flex-column flex-lg-row align-items-center mt-4 mt-lg-0">
{moderationLink}
</div>
@@ -1,9 +1,9 @@
import React, { useMemo } from "react";
import React, { useMemo, useState } from "react";
import { usePrefixedDocumentTitle } from "../../../../common/UsePrefixedDocumentTitle";
import { Link } from "react-router-dom";
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
import { useLocalize } from "hooks";
import { useLocalize, useModal } from "hooks";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faStar,
@@ -15,11 +15,12 @@ import { WebUrl } from "../../../../common/WebUrl";
import {
faFileArrowUp,
faFlask,
faSearch,
faSparkles,
} from "@fortawesome/pro-solid-svg-icons";
import { PosthogClient } from "@storyteller/components/src/analytics/PosthogClient";
import Alert from "components/common/Alert/Alert";
// import { Analytics } from "../../../../../common/Analytics";
import { Button, Container, Panel } from "components/common";
interface Props {
sessionWrapper: SessionWrapper;
@@ -28,10 +29,12 @@ interface Props {
function LandingPage(props: Props) {
usePrefixedDocumentTitle("FakeYou Celebrity Voice Generator");
PosthogClient.recordPageview();
const { t } = useLocalize("LandingPage");
const isLoggedIn = props.sessionWrapper.isLoggedIn();
const isSubscribed = props.sessionSubscriptionsWrapper.hasPaidFeatures();
// const [isFocused, setIsFocused] = useState(false);
const { open, close } = useModal();
let signUpButton = <></>;
let viewPricingButton = <></>;
@@ -39,7 +42,7 @@ function LandingPage(props: Props) {
let myProfileButton = <></>;
let uploadModelSection = <></>;
if (!props.sessionWrapper.isLoggedIn()) {
if (!isLoggedIn) {
signUpButton = (
<>
<Link
@@ -71,7 +74,7 @@ function LandingPage(props: Props) {
</>
);
}
if (props.sessionWrapper.isLoggedIn()) {
if (isLoggedIn) {
let displayName = props.sessionWrapper.getDisplayName() as string; // NB: If logged in, should be string
let url = WebUrl.userProfilePage(displayName);
myProfileButton = (
@@ -118,7 +121,7 @@ function LandingPage(props: Props) {
</>
);
if (!props.sessionSubscriptionsWrapper.hasPaidFeatures()) {
if (!isSubscribed) {
upgradeButton = (
<>
<Link
@@ -154,411 +157,339 @@ function LandingPage(props: Props) {
return images[Math.floor(Math.random() * images.length)];
}, []);
// const onFocusHandler = () => {
// setIsFocused(true);
// };
// const onBlurHandler = () => {
// // Search field blur/Unfocusing hack: needs a little bit of delay for the result click event to register
// setTimeout(() => {
// setIsFocused(false);
// }, 100);
// };
return (
<div>
<div className="container pb-5 pb-lg-0 pt-lg-4 px-md-5 px-lg-5 px-xl-3">
{/* Face Animation Alert Banner */}
<Alert
id="face-animation-alert"
icon={faSparkles}
message="Have you tried our new Face Animator? Turn photos of faces into animated lip-synced videos with just a picture and some audio!"
alertVariant="new"
link="/face-animator"
linkText="Try it now"
/>
<div className="row flex-md-row-reverse">
<div className="col-12 col-lg-5 p-md-0 d-flex justify-content-center">
<img
src={randomHeroImage}
alt="FakeYou Mascot"
height={440}
width={447}
className="img-fluid"
<>
{isLoggedIn ? (
<Container type="panel">
{/* <Panel clear={true}>
<Alert
id="face-animation-alert"
icon={faSparkles}
message="Have you tried our new Face Animator? Turn photos of faces into animated lip-synced videos with just a picture and some audio!"
alertVariant="new"
link="/face-animator"
linkText="Try it now"
/>
</div>
<div className="col-12 col-lg-7 d-flex flex-column justify-content-center flex-reverse px-md-5 px-lg-3">
<h1 className="fw-bold display-5 text-center text-lg-start px-md-5 px-lg-0">
{t("heroTitle")}
</h1>
<p className="lead opacity-75 pb-4 text-center text-lg-start px-md-5 px-lg-0 pe-lg-5">
{t("heroText")}
</p>
<div className="d-flex flex-column flex-md-row gap-3 mt-3 mb-4 w-100 justify-content-center justify-content-lg-start">
{upgradeButton}
{signUpButton}
{viewPricingButton}
{myProfileButton}
</div>
</div>
</div>
</div>
{/* <div className="container-panel pb-5 mb-4">
<div className="panel p-3 py-4 p-md-4">
<form
className="w-100 d-flex flex-column"
// onSubmit={handleFormSubmit}
>
<div className="row gx-5 gy-4">
<div className="col-12 col-md-6 d-flex flex-column gap-4">
<div>
<label className="sub-title">
Pick a Voice (xxx to choose from)
</label>
<div className="input-icon-search pb-4">
<span className="form-control-feedback">
<FontAwesomeIcon icon={faMicrophone} />
</span>
<VcModelListSearch
voiceConversionModels={props.voiceConversionModels}
setVoiceConversionModels={props.setVoiceConversionModels}
maybeSelectedVoiceConversionModel={
props.maybeSelectedVoiceConversionModel
}
setMaybeSelectedVoiceConversionModel={interceptModelChange}
<div className="row flex-md-row-reverse">
<div className="col-12 col-lg-5 p-md-0 d-flex justify-content-center">
<img
src={randomHeroImage}
alt="FakeYou Mascot"
height={440}
width={447}
className="img-fluid"
/>
</div>
</div>
<p className="mt-4">
<span className="opacity-75">
Pick one to get started, or choose from
</span>{" "}
<Link to="/tts">thousands more!</Link>
</p>
</div>
<div className="col-12 col-md-6 d-flex flex-column">
<label className="sub-title">Select Your Input</label>
<div className="d-flex flex-column flex-lg-row gap-3">
<button className="btn btn-primary w-100">
<FontAwesomeIcon icon={faRightLeft} className="me-2" />
Text
</button>
<button className="btn btn-primary w-100">
<FontAwesomeIcon icon={faFileArrowUp} className="me-2" />
Upload
</button>
<button className="btn btn-primary w-100">
<FontAwesomeIcon icon={faMicrophone} className="me-2" />
Microphone
</button>
<div className="col-12 col-lg-7 d-flex flex-column justify-content-center flex-reverse px-md-5 px-lg-3">
<h1 className="fw-bold display-5 text-center text-lg-start px-md-5 px-lg-0">
{t("heroTitle")}
</h1>
<p className="lead opacity-75 pb-4 text-center text-lg-start px-md-5 px-lg-0 pe-lg-5">
{t("heroText")}
</p>
<div className="d-flex flex-column flex-md-row gap-3 mt-3 mb-4 w-100 justify-content-center justify-content-lg-start">
{upgradeButton}
{signUpButton}
{viewPricingButton}
{myProfileButton}
</div>
</div>
</div>
</form>
</div>
</div> */}
</Panel> */}
<div className="container pb-4 px-md-5 px-xl-3">
<h2 className="fw-bold mb-4">{t("productsTitle")}</h2>
<div className="row g-4 position-relative">
<div className="col-12 col-md-4">
<Link
to="/tts"
className="panel panel-select d-flex flex-column align-items-center"
>
<div className="d-flex px-4 pt-4 align-items-start w-100">
<div className="flex-grow-1">
<h3 className="fw-bold text-white mb-1">
{t("productTtsTitle")}
</h3>
<h6 className="fw-normal opacity-75 text-white">
{t("productTtsText")}
</h6>
</div>
<Link to="/tts" className="btn btn-square mt-1">
<FontAwesomeIcon icon={faArrowRight} />
</Link>
</div>
<img
className="img-fluid"
src="/images/landing/select-tts.webp"
alt="Text to speech"
/>
</Link>
</div>
<div className="col-12 col-md-4">
<Link
to="/voice-conversion"
className="panel panel-select d-flex flex-column align-items-center"
>
<div className="d-flex px-4 pt-4 align-items-start w-100">
<div className="flex-grow-1">
<h3 className="fw-bold text-white mb-1">
{t("productVcTitle")}
</h3>
<h6 className="fw-normal opacity-75 text-white">
{t("productVcText")}
</h6>
</div>
<Link to="/voice-conversion" className="btn btn-square mt-1">
<FontAwesomeIcon icon={faArrowRight} />
</Link>
</div>
<img
className="img-fluid"
src="/images/landing/select-vc.webp"
alt="Voice Conversion"
/>
</Link>
</div>
<div className="col-12 col-md-4">
<Link
to="/voice-designer"
className="panel panel-select d-flex flex-column align-items-center"
>
<div className="d-flex px-4 pt-4 align-items-start w-100">
<div className="flex-grow-1">
<div className="mb-1">
<span className="badge-beta d-inline-flex align-items-center mb-2 me-2">
<FontAwesomeIcon icon={faFlask} className="me-1" />
BETA
</span>
<h4 className="fw-bold text-white d-inline-flex align-items-center mb-0">
<span>Voice Designer</span>
</h4>
</div>
<h6 className="fw-normal opacity-75 text-white">
Create your own AI voice
</h6>
</div>
<Link to="/voice-designer" className="btn btn-square mt-1">
<FontAwesomeIcon icon={faArrowRight} />
</Link>
</div>
<img
className="img-fluid"
src="/images/landing/select-vd.webp"
alt="Voice Designer"
/>
</Link>
</div>
<div className="col-12 col-md-4">
<Link
to="/face-animator"
className="panel panel-select d-flex flex-column align-items-center"
>
<div className="d-flex px-4 pt-4 align-items-start w-100">
<div className="flex-grow-1">
<div className="mb-1">
<span className="badge-new d-inline-flex align-items-center mb-2 me-2">
<FontAwesomeIcon icon={faSparkles} className="me-1" />
{t("productNewTag")}
</span>
<h4 className="fw-bold text-white d-inline-flex align-items-center mb-0">
<span>{t("productFaceAnimatorTitle")}</span>
</h4>
</div>
<h6 className="fw-normal opacity-75 text-white">
{t("productFaceAnimatorText")}
</h6>
</div>
<Link to="/face-animator" className="btn btn-square mt-1">
<FontAwesomeIcon icon={faArrowRight} />
</Link>
</div>
<img
className="img-fluid"
src="/images/landing/select-w2l.webp"
alt="Face Animator"
/>
</Link>
</div>
<img
src="/images/landing/bg-dots.webp"
alt="background dots"
className="dots-right-top"
/>
<img
src="/images/landing/bg-dots.webp"
alt="background dots"
className="dots-left-bottom"
/>
</div>
{uploadModelSection}
</div>
<div className="container section px-md-5 px-xl-3">
<div className="row g-4 g-lg-5 flex-row-reverse">
<div className="col-12 col-md-6 col-lg-7">
<div className="position-relative">
<div className="ratio ratio-16x9 video-container">
<video
autoPlay={true}
playsInline={true}
loop={true}
muted={true}
<Panel clear={true} className="mt-5">
<h1 className="fw-bold mb-4">{t("productsTitle")}</h1>
<div className="row g-4 position-relative">
<div className="col-12 col-md-4">
<Link
to="/tts"
className="panel panel-select d-flex flex-column align-items-center"
>
<source src="/videos/tts-video.mp4" type="video/mp4" />
</video>
<div className="d-flex px-4 pt-4 align-items-start w-100">
<div className="flex-grow-1">
<h3 className="fw-bold text-white mb-1">
{t("productTtsTitle")}
</h3>
<h6 className="fw-normal opacity-75 text-white">
{t("productTtsText")}
</h6>
</div>
<Link to="/tts" className="btn btn-square mt-1">
<FontAwesomeIcon icon={faArrowRight} />
</Link>
</div>
<img
className="img-fluid"
src="/images/landing/select-tts.webp"
alt="Text to speech"
/>
</Link>
</div>
<div className="col-12 col-md-4">
<Link
to="/voice-conversion"
className="panel panel-select d-flex flex-column align-items-center"
>
<div className="d-flex px-4 pt-4 align-items-start w-100">
<div className="flex-grow-1">
<h3 className="fw-bold text-white mb-1">
{t("productVcTitle")}
</h3>
<h6 className="fw-normal opacity-75 text-white">
{t("productVcText")}
</h6>
</div>
<Link
to="/voice-conversion"
className="btn btn-square mt-1"
>
<FontAwesomeIcon icon={faArrowRight} />
</Link>
</div>
<img
className="img-fluid"
src="/images/landing/select-vc.webp"
alt="Voice Conversion"
/>
</Link>
</div>
<div className="col-12 col-md-4">
<Link
to="/voice-designer"
className="panel panel-select d-flex flex-column align-items-center"
>
<div className="d-flex px-4 pt-4 align-items-start w-100">
<div className="flex-grow-1">
<div className="mb-1">
<span className="badge-beta d-inline-flex align-items-center mb-2 me-2">
<FontAwesomeIcon icon={faFlask} className="me-1" />
BETA
</span>
<h4 className="fw-bold text-white d-inline-flex align-items-center mb-0">
<span>Voice Designer</span>
</h4>
</div>
<h6 className="fw-normal opacity-75 text-white">
Create your own AI voice
</h6>
</div>
<Link to="/voice-designer" className="btn btn-square mt-1">
<FontAwesomeIcon icon={faArrowRight} />
</Link>
</div>
<img
className="img-fluid"
src="/images/landing/select-vd.webp"
alt="Voice Designer"
/>
</Link>
</div>
<div className="col-12 col-md-4">
<Link
to="/face-animator"
className="panel panel-select d-flex flex-column align-items-center"
>
<div className="d-flex px-4 pt-4 align-items-start w-100">
<div className="flex-grow-1">
<div className="mb-1">
<span className="badge-new d-inline-flex align-items-center mb-2 me-2">
<FontAwesomeIcon icon={faSparkles} className="me-1" />
{t("productNewTag")}
</span>
<h4 className="fw-bold text-white d-inline-flex align-items-center mb-0">
<span>{t("productFaceAnimatorTitle")}</span>
</h4>
</div>
<h6 className="fw-normal opacity-75 text-white">
{t("productFaceAnimatorText")}
</h6>
</div>
<Link to="/face-animator" className="btn btn-square mt-1">
<FontAwesomeIcon icon={faArrowRight} />
</Link>
</div>
<img
className="img-fluid"
src="/images/landing/select-w2l.webp"
alt="Face Animator"
/>
</Link>
</div>
<img
src="/images/landing/bg-dots.webp"
alt="background dots"
className="dots-right-bottom"
className="dots-right-top"
/>
</div>
</div>
<div className="col-12 col-md-6 col-lg-5 d-flex flex-column justify-content-center gap-3">
<h2 className="fw-bold">{t("contextTitle")}</h2>
<p className="opacity-75">{t("contextText")}</p>
<div className="d-flex mt-3 gap-3">
<Link to="/tts" className="btn btn-primary">
{t("contextButtonTts")}
</Link>
<Link to="/voice-conversion" className="btn btn-primary">
{t("contextButtonVc")}
</Link>
</div>
</div>
</div>
</div>
{/* <div className="container section px-md-5 px-xl-3">
<div className="row g-4 g-lg-5">
<div className="col-12 col-md-6 col-lg-7">
<div className="position-relative">
<div className="ratio ratio-16x9 video-container position-relative">
<video
autoPlay={true}
playsInline={true}
loop={true}
muted={true}
>
<source src="/videos/tts-video.webm" type="video/webm" />
</video>
</div>
<img
src="/images/landing/bg-dots.webp"
alt="background dots"
className="dots-left-bottom"
/>
</div>
</div>
<div className="col-12 col-md-6 col-lg-5 d-flex flex-column justify-content-center gap-3">
<h2 className="fw-bold">Speak as your favorite characters</h2>
<p className="opacity-75">
Transform your speaking voice into someone else's voice with our
cutting-edge voice conversion service. Just upload or record your
audio and let our AI-powered technology do the rest. Perfect for
entertainment, voiceovers, and language learning materials.
</p>
<div className="d-flex mt-3">
<Link to="/voice-conversion" className="btn btn-primary">
Convert your voice
</Link>
{uploadModelSection}
</Panel>
</Container>
) : (
<Container type="panel" className="mt-5">
<Panel clear={true} className="py-lg-5">
<div className="row g-5 g-lg-5 flex-row-reverse">
<div className="col-12 col-md-6">
<div className="position-relative">
<div className="ratio ratio-16x9 video-container">
<video
autoPlay={true}
playsInline={true}
loop={true}
muted={true}
>
<source src="/videos/tts-video.mp4" type="video/mp4" />
</video>
</div>
<img
src="/images/landing/bg-dots.webp"
alt="background dots"
className="dots-right-bottom"
/>
</div>
</div>
<div className="col-12 col-md-6 d-flex flex-column justify-content-center text-center text-lg-start gap-2">
<h1 className="fw-bold display-5">
Enabling Anyone to Create Quality Movies with AI
</h1>
<p className="opacity-75">
We are combining generative AI and User Generated Content to
radically democratize both audio and video production.
</p>
<div className="d-flex mt-3 mt-lg-4 gap-3 justify-content-center justify-content-lg-start">
<Button
icon={faArrowRight}
iconFlip={true}
label="Sign Up"
to="/tts"
/>
<Button
icon={faSearch}
label="Search for a weight model..."
variant="secondary"
className="opacity-75 ps-3 pe-5 d-none d-lg-flex"
/>
</div>
</div>
</div>
</Panel>
<div className="d-flex flex-column section align-items-center rounded-0 mb-5">
<div className="d-flex flex-column align-items-center text-center cta-container">
<div className="d-flex d-lg-none align-items-center mb-4 cta-mobile">
<img
src="/images/landing/hanashi-before.webp"
alt="hanashi before"
width={200}
height={200}
/>
<img
src="/images/landing/chevrons-red.webp"
alt="red chevrons"
width={95}
height={80}
/>
<img
src="/images/landing/hanashi-after.webp"
alt="hanashi after"
width={200}
height={200}
/>
</div>
<h2 className="fw-bold">{t("ctaTitle")}</h2>
<p className="mw-300 opacity-75">{t("ctaText")}</p>
<img
src="/images/landing/hanashi-before.webp"
alt="hanashi before"
className="hanashi-before d-none d-lg-block"
width={311}
height={311}
/>
<img
src="/images/landing/chevrons-grey.webp"
alt="grey chevrons"
className="chevrons-grey d-none d-lg-block"
width={127}
height={108}
/>
<img
src="/images/landing/chevrons-red.webp"
alt="red chevrons"
className="chevrons-red d-none d-lg-block"
width={127}
height={108}
/>
<img
src="/images/landing/hanashi-after.webp"
alt="hanashi after"
className="hanashi-after d-none d-lg-block"
width={311}
height={311}
/>
</div>
</div>
</div>
</div> */}
<div className="d-flex flex-column section align-items-center panel rounded-0 my-5">
<div className="d-flex flex-column align-items-center text-center cta-container">
<div className="d-flex d-lg-none align-items-center mb-4 cta-mobile">
<img
src="/images/landing/hanashi-before.webp"
alt="hanashi before"
width={200}
height={200}
/>
<img
src="/images/landing/chevrons-red.webp"
alt="red chevrons"
width={95}
height={80}
/>
<img
src="/images/landing/hanashi-after.webp"
alt="hanashi after"
width={200}
height={200}
/>
</div>
<h2 className="fw-bold">{t("ctaTitle")}</h2>
<p className="mw-300 opacity-75">{t("ctaText")}</p>
<div className="d-flex gap-3 justify-content-center mt-4">
<Link to="/tts" className="btn btn-primary">
{t("ctaButtonTts")}
</Link>
<Link to="/voice-conversion" className="btn btn-primary">
{t("ctaButtonVc")}
</Link>
</div>
<img
src="/images/landing/hanashi-before.webp"
alt="hanashi before"
className="hanashi-before d-none d-lg-block"
width={311}
height={311}
/>
<img
src="/images/landing/chevrons-grey.webp"
alt="grey chevrons"
className="chevrons-grey d-none d-lg-block"
width={127}
height={108}
/>
<img
src="/images/landing/chevrons-red.webp"
alt="red chevrons"
className="chevrons-red d-none d-lg-block"
width={127}
height={108}
/>
<img
src="/images/landing/hanashi-after.webp"
alt="hanashi after"
className="hanashi-after d-none d-lg-block"
width={311}
height={311}
/>
</div>
</div>
<div className="py-4">
<div className="container text-center community-container">
<div className="panel px-4 py-5 d-flex flex-column align-items-center community-container rounded">
<h2 className="fw-bold mb-2">{t("communityTitle")}</h2>
<p className="opacity-75">{t("communityText")}</p>
<div className="d-flex mt-4 gap-3">
<a
href="https://discord.gg/fakeyou"
target="_blank"
rel="noreferrer"
className="btn btn-discord"
>
<FontAwesomeIcon icon={faDiscord} className="me-2" />
{t("communityButtonDiscord")}
</a>
<a
href="https://twitter.com/intent/follow?screen_name=FakeYouApp"
target="_blank"
rel="noreferrer"
className="btn btn-twitter"
>
<FontAwesomeIcon icon={faTwitter} className="me-2" />
{t("communityButtonTwitter")}
</a>
<div className="py-4">
<div className="container text-center community-container">
<div className="panel px-4 py-5 d-flex flex-column align-items-center community-container rounded">
<h2 className="fw-bold mb-2">{t("communityTitle")}</h2>
<p className="opacity-75">{t("communityText")}</p>
<div className="d-flex mt-4 gap-3">
<a
href="https://discord.gg/fakeyou"
target="_blank"
rel="noreferrer"
className="btn btn-discord"
>
<FontAwesomeIcon icon={faDiscord} className="me-2" />
{t("communityButtonDiscord")}
</a>
<a
href="https://twitter.com/intent/follow?screen_name=FakeYouApp"
target="_blank"
rel="noreferrer"
className="btn btn-twitter"
>
<FontAwesomeIcon icon={faTwitter} className="me-2" />
{t("communityButtonTwitter")}
</a>
</div>
</div>
<img
src="/images/landing/bg-dots.webp"
alt="background dots"
className="dots-left-bottom me-3"
/>
</div>
</div>
<img
src="/images/landing/bg-dots.webp"
alt="background dots"
className="dots-left-bottom me-3"
/>
</div>
</div>
</div>
</Container>
)}
</>
);
}
@@ -17,6 +17,7 @@ import { WebUrl } from "../../../../common/WebUrl";
import { BeginStripeCheckoutFlow } from "../../../../common/BeginStripeCheckoutFlow";
import { usePrefixedDocumentTitle } from "../../../../common/UsePrefixedDocumentTitle";
import { PosthogClient } from "@storyteller/components/src/analytics/PosthogClient";
import { Container, Panel } from "components/common";
interface Props {
sessionWrapper: SessionWrapper;
@@ -147,8 +148,8 @@ function PricingPage(props: Props) {
}
return (
<div>
<div className="container pt-5 pb-4 text-center">
<Container type="panel">
<Panel clear={true} className="text-center my-5">
<h1 className=" fw-bold">Pricing</h1>
{/* <p className="fs-5">
By purchasing FakeYou premium, you help us build more!
@@ -157,8 +158,9 @@ function PricingPage(props: Props) {
<FontAwesomeIcon icon={faHeart} className="text-red me-3" />
By purchasing FakeYou premium, you help us build more!
</div>
</div>
<div className="container mb-5">
</Panel>
<Panel clear={true}>
<div className="row gx-3 gy-4">
{/* Starter Tier */}
{/*<div className="col-12 col-sm-6 col-lg-3" >
@@ -712,8 +714,8 @@ function PricingPage(props: Props) {
</div>
</div>
</div> */}
</div>
</div>
</Panel>
</Container>
);
}