@@ -26,7 +35,7 @@ export function SidebarSection({ title, children }: SidebarSectionProps) {
();
+
+ const {
+ userDetails,
+ hasActiveSubscription,
+ patchUser,
+ fetchUserDetails,
+ updateUserDetails,
+ unblockUser,
+ } = useUserDetails();
+
+ useEffect(() => {
+ if (userDetails?.profileVisibility) {
+ setValue("profileVisibility", userDetails.profileVisibility);
+ }
+ }, [userDetails, setValue]);
+
+ useEffect(() => {
+ const unsubscribe = window.electron.onAccountUpdated(() => {
+ fetchUserDetails().then((response) => {
+ if (response) {
+ updateUserDetails(response);
+ }
+ });
+ showSuccessToast(t("account_data_updated_successfully"));
+ });
+
+ return () => {
+ unsubscribe();
+ };
+ }, [fetchUserDetails, updateUserDetails]);
+
+ const visibilityOptions = [
+ { value: "PUBLIC", label: t("public") },
+ { value: "FRIENDS", label: t("friends_only") },
+ { value: "PRIVATE", label: t("private") },
+ ];
+
+ const onSubmit = async (values: FormValues) => {
+ await patchUser(values);
+ showSuccessToast(t("changes_saved"));
+ };
+
+ const handleUnblockClick = useCallback(
+ (id: string) => {
+ setIsUnblocking(true);
+
+ unblockUser(id)
+ .then(() => {
+ fetchBlockedUsers();
+ showSuccessToast(t("user_unblocked"));
+ })
+ .finally(() => {
+ setIsUnblocking(false);
+ });
+ },
+ [unblockUser, fetchBlockedUsers, t, showSuccessToast]
+ );
+
+ const getHydraCloudSectionContent = () => {
+ const hasSubscribedBefore = Boolean(userDetails?.subscription?.expiresAt);
+ const isRenewalActive = userDetails?.subscription?.status === "active";
+
+ if (!hasSubscribedBefore) {
+ return {
+ description:
{t("no_subscription")},
+ callToAction: t("become_subscriber"),
+ };
+ }
+
+ if (hasActiveSubscription) {
+ return {
+ description: isRenewalActive ? (
+ <>
+
+ {t("subscription_renews_on", {
+ date: formatDate(userDetails.subscription!.expiresAt!),
+ })}
+
+
{t("bill_sent_until")}
+ >
+ ) : (
+ <>
+
{t("subscription_renew_cancelled")}
+
+ {t("subscription_active_until", {
+ date: formatDate(userDetails!.subscription!.expiresAt!),
+ })}
+
+ >
+ ),
+ callToAction: t("manage_subscription"),
+ };
+ }
+
+ return {
+ description: (
+
+ {t("subscription_expired_at", {
+ date: formatDate(userDetails!.subscription!.expiresAt!),
+ })}
+
+ ),
+ callToAction: t("renew_subscription"),
+ };
+ };
+
+ if (!userDetails) return null;
+
+ return (
+
+ );
+}
diff --git a/src/renderer/src/pages/settings/settings-privacy.tsx b/src/renderer/src/pages/settings/settings-privacy.tsx
deleted file mode 100644
index b93d1d07d..000000000
--- a/src/renderer/src/pages/settings/settings-privacy.tsx
+++ /dev/null
@@ -1,139 +0,0 @@
-import { SelectField } from "@renderer/components";
-import { SPACING_UNIT } from "@renderer/theme.css";
-import { Controller, useForm } from "react-hook-form";
-import { useTranslation } from "react-i18next";
-
-import * as styles from "./settings-privacy.css";
-import { useToast, useUserDetails } from "@renderer/hooks";
-import { useCallback, useContext, useEffect, useState } from "react";
-import { XCircleFillIcon } from "@primer/octicons-react";
-import { settingsContext } from "@renderer/context";
-
-interface FormValues {
- profileVisibility: "PUBLIC" | "FRIENDS" | "PRIVATE";
-}
-
-export function SettingsPrivacy() {
- const { t } = useTranslation("settings");
-
- const [isUnblocking, setIsUnblocking] = useState(false);
-
- const { showSuccessToast } = useToast();
-
- const { blockedUsers, fetchBlockedUsers } = useContext(settingsContext);
-
- const {
- control,
- formState: { isSubmitting },
- setValue,
- handleSubmit,
- } = useForm
();
-
- const { patchUser, userDetails } = useUserDetails();
-
- const { unblockUser } = useUserDetails();
-
- useEffect(() => {
- if (userDetails?.profileVisibility) {
- setValue("profileVisibility", userDetails.profileVisibility);
- }
- }, [userDetails, setValue]);
-
- const visibilityOptions = [
- { value: "PUBLIC", label: t("public") },
- { value: "FRIENDS", label: t("friends_only") },
- { value: "PRIVATE", label: t("private") },
- ];
-
- const onSubmit = async (values: FormValues) => {
- await patchUser(values);
- showSuccessToast(t("changes_saved"));
- };
-
- const handleUnblockClick = useCallback(
- (id: string) => {
- setIsUnblocking(true);
-
- unblockUser(id)
- .then(() => {
- fetchBlockedUsers();
- showSuccessToast(t("user_unblocked"));
- })
- .finally(() => {
- setIsUnblocking(false);
- });
- },
- [unblockUser, fetchBlockedUsers, t, showSuccessToast]
- );
-
- return (
-
- );
-}
diff --git a/src/renderer/src/pages/settings/settings.tsx b/src/renderer/src/pages/settings/settings.tsx
index dffdfbaeb..5fba6c5df 100644
--- a/src/renderer/src/pages/settings/settings.tsx
+++ b/src/renderer/src/pages/settings/settings.tsx
@@ -11,7 +11,7 @@ import {
SettingsContextConsumer,
SettingsContextProvider,
} from "@renderer/context";
-import { SettingsPrivacy } from "./settings-privacy";
+import { SettingsAccount } from "./settings-account";
import { useUserDetails } from "@renderer/hooks";
import { useMemo } from "react";
@@ -28,7 +28,7 @@ export default function Settings() {
"Real-Debrid",
];
- if (userDetails) return [...categories, t("privacy")];
+ if (userDetails) return [...categories, t("account")];
return categories;
}, [userDetails, t]);
@@ -53,7 +53,7 @@ export default function Settings() {
return ;
}
- return ;
+ return ;
};
return (
diff --git a/src/shared/constants.ts b/src/shared/constants.ts
index 6b332d40a..f2bcc7939 100644
--- a/src/shared/constants.ts
+++ b/src/shared/constants.ts
@@ -42,3 +42,9 @@ export enum Cracker {
rle = "RLE",
razor1911 = "RAZOR1911",
}
+
+export enum AuthPage {
+ SignIn = "/",
+ UpdateEmail = "/update-email",
+ UpdatePassword = "/update-password",
+}