mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
username-display-on-settings
Displays username on account settings tab,
This commit is contained in:
parent
af2896efc3
commit
e49e0c3e6e
1 changed files with 255 additions and 255 deletions
|
@ -1,255 +1,255 @@
|
||||||
import { Avatar, Button, SelectField } from "@renderer/components";
|
import { Avatar, Button, SelectField } from "@renderer/components";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useDate, useToast, useUserDetails } from "@renderer/hooks";
|
import { useDate, useToast, useUserDetails } from "@renderer/hooks";
|
||||||
import { useCallback, useContext, useEffect, useState } from "react";
|
import { useCallback, useContext, useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
CloudIcon,
|
CloudIcon,
|
||||||
KeyIcon,
|
KeyIcon,
|
||||||
MailIcon,
|
MailIcon,
|
||||||
XCircleFillIcon,
|
XCircleFillIcon,
|
||||||
} from "@primer/octicons-react";
|
} from "@primer/octicons-react";
|
||||||
import { settingsContext } from "@renderer/context";
|
import { settingsContext } from "@renderer/context";
|
||||||
import { AuthPage } from "@shared";
|
import { AuthPage } from "@shared";
|
||||||
import "./settings-account.scss";
|
import "./settings-account.scss";
|
||||||
|
|
||||||
interface FormValues {
|
interface FormValues {
|
||||||
profileVisibility: "PUBLIC" | "FRIENDS" | "PRIVATE";
|
profileVisibility: "PUBLIC" | "FRIENDS" | "PRIVATE";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SettingsAccount() {
|
export function SettingsAccount() {
|
||||||
const { t } = useTranslation("settings");
|
const { t } = useTranslation("settings");
|
||||||
|
|
||||||
const [isUnblocking, setIsUnblocking] = useState(false);
|
const [isUnblocking, setIsUnblocking] = useState(false);
|
||||||
|
|
||||||
const { showSuccessToast } = useToast();
|
const { showSuccessToast } = useToast();
|
||||||
|
|
||||||
const { blockedUsers, fetchBlockedUsers } = useContext(settingsContext);
|
const { blockedUsers, fetchBlockedUsers } = useContext(settingsContext);
|
||||||
|
|
||||||
const { formatDate } = useDate();
|
const { formatDate } = useDate();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
formState: { isSubmitting },
|
formState: { isSubmitting },
|
||||||
setValue,
|
setValue,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
} = useForm<FormValues>();
|
} = useForm<FormValues>();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
userDetails,
|
userDetails,
|
||||||
hasActiveSubscription,
|
hasActiveSubscription,
|
||||||
patchUser,
|
patchUser,
|
||||||
fetchUserDetails,
|
fetchUserDetails,
|
||||||
updateUserDetails,
|
updateUserDetails,
|
||||||
unblockUser,
|
unblockUser,
|
||||||
} = useUserDetails();
|
} = useUserDetails();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (userDetails?.profileVisibility) {
|
if (userDetails?.profileVisibility) {
|
||||||
setValue("profileVisibility", userDetails.profileVisibility);
|
setValue("profileVisibility", userDetails.profileVisibility);
|
||||||
}
|
}
|
||||||
}, [userDetails, setValue]);
|
}, [userDetails, setValue]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribe = window.electron.onAccountUpdated(() => {
|
const unsubscribe = window.electron.onAccountUpdated(() => {
|
||||||
fetchUserDetails().then((response) => {
|
fetchUserDetails().then((response) => {
|
||||||
if (response) {
|
if (response) {
|
||||||
updateUserDetails(response);
|
updateUserDetails(response);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
showSuccessToast(t("account_data_updated_successfully"));
|
showSuccessToast(t("account_data_updated_successfully"));
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
};
|
};
|
||||||
}, [fetchUserDetails, updateUserDetails, t, showSuccessToast]);
|
}, [fetchUserDetails, updateUserDetails, t, showSuccessToast]);
|
||||||
|
|
||||||
const visibilityOptions = [
|
const visibilityOptions = [
|
||||||
{ value: "PUBLIC", label: t("public") },
|
{ value: "PUBLIC", label: t("public") },
|
||||||
{ value: "FRIENDS", label: t("friends_only") },
|
{ value: "FRIENDS", label: t("friends_only") },
|
||||||
{ value: "PRIVATE", label: t("private") },
|
{ value: "PRIVATE", label: t("private") },
|
||||||
];
|
];
|
||||||
|
|
||||||
const onSubmit = async (values: FormValues) => {
|
const onSubmit = async (values: FormValues) => {
|
||||||
await patchUser(values);
|
await patchUser(values);
|
||||||
showSuccessToast(t("changes_saved"));
|
showSuccessToast(t("changes_saved"));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUnblockClick = useCallback(
|
const handleUnblockClick = useCallback(
|
||||||
(id: string) => {
|
(id: string) => {
|
||||||
setIsUnblocking(true);
|
setIsUnblocking(true);
|
||||||
|
|
||||||
unblockUser(id)
|
unblockUser(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
fetchBlockedUsers();
|
fetchBlockedUsers();
|
||||||
showSuccessToast(t("user_unblocked"));
|
showSuccessToast(t("user_unblocked"));
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setIsUnblocking(false);
|
setIsUnblocking(false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[unblockUser, fetchBlockedUsers, t, showSuccessToast]
|
[unblockUser, fetchBlockedUsers, t, showSuccessToast]
|
||||||
);
|
);
|
||||||
|
|
||||||
const getHydraCloudSectionContent = () => {
|
const getHydraCloudSectionContent = () => {
|
||||||
const hasSubscribedBefore = Boolean(userDetails?.subscription?.expiresAt);
|
const hasSubscribedBefore = Boolean(userDetails?.subscription?.expiresAt);
|
||||||
const isRenewalActive = userDetails?.subscription?.status === "active";
|
const isRenewalActive = userDetails?.subscription?.status === "active";
|
||||||
|
|
||||||
if (!hasSubscribedBefore) {
|
if (!hasSubscribedBefore) {
|
||||||
return {
|
return {
|
||||||
description: <small>{t("no_subscription")}</small>,
|
description: <small>{t("no_subscription")}</small>,
|
||||||
callToAction: t("become_subscriber"),
|
callToAction: t("become_subscriber"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasActiveSubscription) {
|
if (hasActiveSubscription) {
|
||||||
return {
|
return {
|
||||||
description: isRenewalActive ? (
|
description: isRenewalActive ? (
|
||||||
<>
|
<>
|
||||||
<small>
|
<small>
|
||||||
{t("subscription_renews_on", {
|
{t("subscription_renews_on", {
|
||||||
date: formatDate(userDetails.subscription!.expiresAt!),
|
date: formatDate(userDetails.subscription!.expiresAt!),
|
||||||
})}
|
})}
|
||||||
</small>
|
</small>
|
||||||
<small>{t("bill_sent_until")}</small>
|
<small>{t("bill_sent_until")}</small>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<small>{t("subscription_renew_cancelled")}</small>
|
<small>{t("subscription_renew_cancelled")}</small>
|
||||||
<small>
|
<small>
|
||||||
{t("subscription_active_until", {
|
{t("subscription_active_until", {
|
||||||
date: formatDate(userDetails!.subscription!.expiresAt!),
|
date: formatDate(userDetails!.subscription!.expiresAt!),
|
||||||
})}
|
})}
|
||||||
</small>
|
</small>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
callToAction: t("manage_subscription"),
|
callToAction: t("manage_subscription"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: (
|
description: (
|
||||||
<small>
|
<small>
|
||||||
{t("subscription_expired_at", {
|
{t("subscription_expired_at", {
|
||||||
date: formatDate(userDetails!.subscription!.expiresAt!),
|
date: formatDate(userDetails!.subscription!.expiresAt!),
|
||||||
})}
|
})}
|
||||||
</small>
|
</small>
|
||||||
),
|
),
|
||||||
callToAction: t("renew_subscription"),
|
callToAction: t("renew_subscription"),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!userDetails) return null;
|
if (!userDetails) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="settings-account__form" onSubmit={handleSubmit(onSubmit)}>
|
<form className="settings-account__form" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="profileVisibility"
|
name="profileVisibility"
|
||||||
render={({ field }) => {
|
render={({ field }) => {
|
||||||
const handleChange = (
|
const handleChange = (
|
||||||
event: React.ChangeEvent<HTMLSelectElement>
|
event: React.ChangeEvent<HTMLSelectElement>
|
||||||
) => {
|
) => {
|
||||||
field.onChange(event);
|
field.onChange(event);
|
||||||
handleSubmit(onSubmit)();
|
handleSubmit(onSubmit)();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="settings-account__section">
|
<section className="settings-account__section">
|
||||||
<SelectField
|
<SelectField
|
||||||
label={t("profile_visibility")}
|
label={t("profile_visibility")}
|
||||||
value={field.value}
|
value={field.value}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
options={visibilityOptions.map((visiblity) => ({
|
options={visibilityOptions.map((visiblity) => ({
|
||||||
key: visiblity.value,
|
key: visiblity.value,
|
||||||
value: visiblity.value,
|
value: visiblity.value,
|
||||||
label: visiblity.label,
|
label: visiblity.label,
|
||||||
}))}
|
}))}
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<small>{t("profile_visibility_description")}</small>
|
<small>{t("profile_visibility_description")}</small>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<section className="settings-account__section">
|
<section className="settings-account__section">
|
||||||
<h4>{t("current_email")}</h4>
|
<h4>{t("current_email")}</h4>
|
||||||
<p>{userDetails?.email ?? t("no_email_account")}</p>
|
<p>{userDetails?.email ?? t("no_email_account")}</p>
|
||||||
|
<h4>Nome de usuário:</h4>
|
||||||
<div className="settings-account__actions">
|
<p>{userDetails?.username}</p>
|
||||||
<Button
|
<div className="settings-account__actions">
|
||||||
theme="outline"
|
<Button
|
||||||
onClick={() => window.electron.openAuthWindow(AuthPage.UpdateEmail)}
|
theme="outline"
|
||||||
>
|
onClick={() => window.electron.openAuthWindow(AuthPage.UpdateEmail)}
|
||||||
<MailIcon />
|
>
|
||||||
{t("update_email")}
|
<MailIcon />
|
||||||
</Button>
|
{t("update_email")}
|
||||||
|
</Button>
|
||||||
<Button
|
|
||||||
theme="outline"
|
<Button
|
||||||
onClick={() =>
|
theme="outline"
|
||||||
window.electron.openAuthWindow(AuthPage.UpdatePassword)
|
onClick={() =>
|
||||||
}
|
window.electron.openAuthWindow(AuthPage.UpdatePassword)
|
||||||
>
|
}
|
||||||
<KeyIcon />
|
>
|
||||||
{t("update_password")}
|
<KeyIcon />
|
||||||
</Button>
|
{t("update_password")}
|
||||||
</div>
|
</Button>
|
||||||
</section>
|
</div>
|
||||||
|
</section>
|
||||||
<section className="settings-account__section">
|
<section className="settings-account__section">
|
||||||
<h3>Hydra Cloud</h3>
|
<h3>Hydra Cloud</h3>
|
||||||
<div className="settings-account__subscription-info">
|
<div className="settings-account__subscription-info">
|
||||||
{getHydraCloudSectionContent().description}
|
{getHydraCloudSectionContent().description}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="settings-account__subscription-button"
|
className="settings-account__subscription-button"
|
||||||
theme="outline"
|
theme="outline"
|
||||||
onClick={() => window.electron.openCheckout()}
|
onClick={() => window.electron.openCheckout()}
|
||||||
>
|
>
|
||||||
<CloudIcon />
|
<CloudIcon />
|
||||||
{getHydraCloudSectionContent().callToAction}
|
{getHydraCloudSectionContent().callToAction}
|
||||||
</Button>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="settings-account__section">
|
<section className="settings-account__section">
|
||||||
<h3>{t("blocked_users")}</h3>
|
<h3>{t("blocked_users")}</h3>
|
||||||
|
|
||||||
{blockedUsers.length > 0 ? (
|
{blockedUsers.length > 0 ? (
|
||||||
<ul className="settings-account__blocked-users">
|
<ul className="settings-account__blocked-users">
|
||||||
{blockedUsers.map((user) => {
|
{blockedUsers.map((user) => {
|
||||||
return (
|
return (
|
||||||
<li key={user.id} className="settings-account__blocked-user">
|
<li key={user.id} className="settings-account__blocked-user">
|
||||||
<div className="settings-account__user-info">
|
<div className="settings-account__user-info">
|
||||||
<Avatar
|
<Avatar
|
||||||
className="settings-account__user-avatar"
|
className="settings-account__user-avatar"
|
||||||
size={32}
|
size={32}
|
||||||
src={user.profileImageUrl}
|
src={user.profileImageUrl}
|
||||||
alt={user.displayName}
|
alt={user.displayName}
|
||||||
/>
|
/>
|
||||||
<span>{user.displayName}</span>
|
<span>{user.displayName}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="settings-account__unblock-button"
|
className="settings-account__unblock-button"
|
||||||
onClick={() => handleUnblockClick(user.id)}
|
onClick={() => handleUnblockClick(user.id)}
|
||||||
disabled={isUnblocking}
|
disabled={isUnblocking}
|
||||||
>
|
>
|
||||||
<XCircleFillIcon />
|
<XCircleFillIcon />
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
) : (
|
) : (
|
||||||
<small>{t("no_users_blocked")}</small>
|
<small>{t("no_users_blocked")}</small>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue