feat: creating subscribe modal

This commit is contained in:
Zamitto 2024-10-21 17:26:15 -03:00
parent 44131fe831
commit 49ee05770a
4 changed files with 157 additions and 1 deletions

View File

@ -357,5 +357,15 @@
"unlocked_at": "Unlocked at:",
"subscription_needed": "A Hydra Cloud subscription is needed to see this content",
"new_achievements_unlocked": "Unlocked {{achievementCount}} new achievements from {{gameCount}} games"
},
"tour": {
"subscription_tour_title": "Hydra Cloud Subscription",
"subscribe_now": "Subscribe now",
"cloud_saving": "Cloud saving (up to {{gameCount}} games)",
"cloud_achievements": "Save your achievements on the cloud",
"animated_profile_picture": "Animated profile pictures",
"premium_support": "Premium Support",
"show_and_compare_achievements": "Show and compare your achievements to other users",
"animated_profile_banner": "Animated profile banner"
}
}

View File

@ -359,5 +359,14 @@
"unlocked_at": "Desbloqueado em:",
"subscription_needed": "Você precisa de uma assinatura Hydra Cloud para visualizar este conteúdo",
"new_achievements_unlocked": "{{achievementCount}} novas conquistas de {{gameCount}} jogos"
},
"tour": {
"subscription_tour_title": "Assinatura Hydra Cloud",
"subscribe_now": "Inscreva-se agora",
"cloud_achievements": "Salvamento de conquistas em nuvem",
"animated_profile_picture": "Fotos de perfil animadas",
"premium_support": "Suporte Premium",
"show_and_compare_achievements": "Exiba e compare suas conquistas com outros usuários",
"animated_profile_banner": "Banner animado no perfil"
}
}

View File

@ -1,4 +1,4 @@
import { useCallback, useContext, useEffect, useRef } from "react";
import { useCallback, useContext, useEffect, useRef, useState } from "react";
import { Sidebar, BottomPanel, Header, Toast } from "@renderer/components";
@ -29,6 +29,11 @@ import { UserFriendModal } from "./pages/shared-modals/user-friend-modal";
import { downloadSourcesWorker } from "./workers";
import { repacksContext } from "./context";
import { logger } from "./logger";
import { SubscriptionTourModal } from "./pages/shared-modals/subscription-tour-modal";
interface TourModals {
subscriptionModal?: boolean;
}
export interface AppProps {
children: React.ReactNode;
@ -72,6 +77,9 @@ export function App() {
const { showSuccessToast } = useToast();
const [showSubscritionTourModal, setShowSubscritionTourModal] =
useState(false);
useEffect(() => {
Promise.all([window.electron.getUserPreferences(), updateLibrary()]).then(
([preferences]) => {
@ -117,6 +125,16 @@ export function App() {
});
}, [fetchUserDetails, syncFriendRequests, updateUserDetails, dispatch]);
useEffect(() => {
const tourModalsString = window.localStorage.getItem("tourModals") || "{}";
const tourModals = JSON.parse(tourModalsString) as TourModals;
if (!tourModals.subscriptionModal) {
setShowSubscritionTourModal(true);
}
}, []);
const onSignIn = useCallback(() => {
fetchUserDetails().then((response) => {
if (response) {
@ -262,6 +280,14 @@ export function App() {
});
}, [indexRepacks]);
const handleCloseSubscriptionTourModal = () => {
setShowSubscritionTourModal(false);
window.localStorage.setItem(
"tourModals",
JSON.stringify({ subscriptionModal: true } as TourModals)
);
};
const handleToastClose = useCallback(() => {
dispatch(closeToast());
}, [dispatch]);
@ -281,6 +307,13 @@ export function App() {
onClose={handleToastClose}
/>
{showSubscritionTourModal && (
<SubscriptionTourModal
visible={showSubscritionTourModal}
onClose={handleCloseSubscriptionTourModal}
/>
)}
{userDetails && (
<UserFriendModal
visible={isFriendsModalVisible}

View File

@ -0,0 +1,104 @@
import { useTranslation } from "react-i18next";
import { Button, Modal } from "../../components";
import { SPACING_UNIT } from "../../theme.css";
export interface UserFriendsModalProps {
visible: boolean;
onClose: () => void;
}
export const SubscriptionTourModal = ({
visible,
onClose,
}: UserFriendsModalProps) => {
const { t } = useTranslation("tour");
const handleSubscribeClick = () => {
window.electron.openCheckout().finally(onClose);
};
return (
<Modal
visible={visible}
title={t("subscription_tour_title")}
large={true}
onClose={onClose}
>
<div
style={{
display: "flex",
flexDirection: "column",
gap: `${SPACING_UNIT * 2}px`,
}}
>
<div
style={{
display: "flex",
width: "100%",
flexDirection: "row",
gap: `${SPACING_UNIT * 2}px`,
justifyContent: "space-around",
}}
>
<div
style={{
display: "flex",
flexDirection: "column",
gap: `${SPACING_UNIT * 2}px`,
}}
>
<h2>Hydra Cloud</h2>
<ul style={{ margin: "0", padding: "0" }}>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("cloud_saving", { gameCount: 15 })}
</li>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("cloud_achievements")}
</li>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("show_and_compare_achievements")}
</li>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("animated_profile_picture")}
</li>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("premium_support")}
</li>
</ul>
</div>
<div
style={{
display: "flex",
flexDirection: "column",
gap: `${SPACING_UNIT * 2}px`,
}}
>
<h2>Hydra Cloud+</h2>
<ul style={{ margin: "0", padding: "0" }}>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("cloud_saving", { gameCount: 30 })}
</li>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("cloud_achievements")}
</li>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("show_and_compare_achievements")}
</li>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("animated_profile_banner")}
</li>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("animated_profile_picture")}
</li>
<li style={{ margin: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px` }}>
{t("premium_support")}
</li>
</ul>
</div>
</div>
<Button onClick={handleSubscribeClick}>{t("subscribe_now")}</Button>
</div>
</Modal>
);
};