refactor: update Next.js, React.js and Node.js (#815)
* refactor: update Next.js and React.js * refactor: update Next.js images * refactor: update ESLint rules and fix warnings/errors * fix: remove old intl polyfill * fix: add proper size to next/image components * fix: adjust full-size for next/image components * fix: temporary allow all domains for image optimization * build: fixes an issue where dev env could lead to javascript heap out of memory * fix: resolve webpack cache issue with country-flag-icons * refactor: switch compiler from Babel to SWC * fix: resize logo in sidebar * fix: break word on long path to avoid text overflow * chore: added sharp for production image optimisation * fix: change extract script for i18n to a custom script * fix: resolve GitHub CodeQL alert * chore: temporarily remove builds for ARMv7 * fix: resize avatar images * refactor: update Node.js to v20 * fix: resolve various UI issues * build: migrate yarn to pnpm and restrict engine to node@^20.0.0 * ci: specify the pnpm version to use in workflow actions * ci: fix typo in pnpm action-setup for cypress workflow * test(cypress): use pnpm instead of yarn * style: ran prettier on pnpm-lock * ci(cypress): setup nodejs v20 in cypress workflow * ci: pnpm cache to reduce install time * ci: use sh shell to get pnpm store directory * build(dockerfile): migrate to pnpm from yarn in docker builds * build(dockerfile): copy the proper pnpm lockfile * build: install pnpm for all platforms * build(dockerfile): remove unnecessary `&&` on apk installation steps * build: migrate pnpm 8 to 9 * build(dockerfile): add node-gyp back in * build(dockerfile): install node-gyp through npm * build(dockerfile): ignore scripts to not run husky install when devdependencies are pruned * build: migrate to pnpm from yarn * chore: remove a section that is no longer relevant --------- Co-authored-by: fallenbagel <98979876+Fallenbagel@users.noreply.github.com>
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
import Button from '@app/components/Common/Button';
|
||||
import type { User } from '@app/hooks/useUser';
|
||||
import { Permission, useUser } from '@app/hooks/useUser';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { CogIcon, UserIcon } from '@heroicons/react/24/solid';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
const messages = defineMessages('components.UserProfile.ProfileHeader', {
|
||||
settings: 'Edit Settings',
|
||||
profile: 'View Profile',
|
||||
joindate: 'Joined {joindate}',
|
||||
@@ -40,10 +42,12 @@ const ProfileHeader = ({ user, isSettingsPage }: ProfileHeaderProps) => {
|
||||
<div className="flex items-end justify-items-end space-x-5">
|
||||
<div className="flex-shrink-0">
|
||||
<div className="relative">
|
||||
<img
|
||||
<Image
|
||||
className="h-24 w-24 rounded-full bg-gray-600 object-cover ring-1 ring-gray-700"
|
||||
src={user.avatar}
|
||||
alt=""
|
||||
width={96}
|
||||
height={96}
|
||||
/>
|
||||
<span
|
||||
className="absolute inset-0 rounded-full shadow-inner"
|
||||
@@ -57,10 +61,9 @@ const ProfileHeader = ({ user, isSettingsPage }: ProfileHeaderProps) => {
|
||||
href={
|
||||
user.id === loggedInUser?.id ? '/profile' : `/users/${user.id}`
|
||||
}
|
||||
className="text-overseerr text-lg font-bold hover:to-purple-200 sm:text-2xl"
|
||||
>
|
||||
<a className="text-overseerr text-lg font-bold hover:to-purple-200 sm:text-2xl">
|
||||
{user.displayName}
|
||||
</a>
|
||||
{user.displayName}
|
||||
</Link>
|
||||
{user.email && user.displayName.toLowerCase() !== user.email && (
|
||||
<span className="text-sm text-gray-400 sm:ml-2 sm:text-lg">
|
||||
@@ -88,6 +91,7 @@ const ProfileHeader = ({ user, isSettingsPage }: ProfileHeaderProps) => {
|
||||
: `/users/${user.id}/settings`
|
||||
}
|
||||
passHref
|
||||
legacyBehavior
|
||||
>
|
||||
<Button as="a">
|
||||
<CogIcon />
|
||||
@@ -101,6 +105,7 @@ const ProfileHeader = ({ user, isSettingsPage }: ProfileHeaderProps) => {
|
||||
loggedInUser?.id === user.id ? `/profile` : `/users/${user.id}`
|
||||
}
|
||||
passHref
|
||||
legacyBehavior
|
||||
>
|
||||
<Button as="a">
|
||||
<UserIcon />
|
||||
|
||||
@@ -12,6 +12,7 @@ import useSettings from '@app/hooks/useSettings';
|
||||
import { Permission, UserType, useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
|
||||
import type { UserSettingsGeneralResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import axios from 'axios';
|
||||
@@ -19,50 +20,53 @@ import { Field, Form, Formik } from 'formik';
|
||||
import getConfig from 'next/config';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const messages = defineMessages({
|
||||
general: 'General',
|
||||
generalsettings: 'General Settings',
|
||||
displayName: 'Display Name',
|
||||
email: 'Email',
|
||||
save: 'Save Changes',
|
||||
saving: 'Saving…',
|
||||
mediaServerUser: '{mediaServerName} User',
|
||||
accounttype: 'Account Type',
|
||||
plexuser: 'Plex User',
|
||||
localuser: 'Local User',
|
||||
role: 'Role',
|
||||
owner: 'Owner',
|
||||
admin: 'Admin',
|
||||
user: 'User',
|
||||
toastSettingsSuccess: 'Settings saved successfully!',
|
||||
toastSettingsFailure: 'Something went wrong while saving settings.',
|
||||
region: 'Discover Region',
|
||||
regionTip: 'Filter content by regional availability',
|
||||
originallanguage: 'Discover Language',
|
||||
originallanguageTip: 'Filter content by original language',
|
||||
movierequestlimit: 'Movie Request Limit',
|
||||
seriesrequestlimit: 'Series Request Limit',
|
||||
enableOverride: 'Override Global Limit',
|
||||
applanguage: 'Display Language',
|
||||
languageDefault: 'Default ({language})',
|
||||
discordId: 'Discord User ID',
|
||||
discordIdTip:
|
||||
'The <FindDiscordIdLink>multi-digit ID number</FindDiscordIdLink> associated with your Discord user account',
|
||||
validationemailrequired: 'Email required',
|
||||
validationemailformat: 'Valid email required',
|
||||
validationDiscordId: 'You must provide a valid Discord user ID',
|
||||
plexwatchlistsyncmovies: 'Auto-Request Movies',
|
||||
plexwatchlistsyncmoviestip:
|
||||
'Automatically request movies on your <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink>',
|
||||
plexwatchlistsyncseries: 'Auto-Request Series',
|
||||
plexwatchlistsyncseriestip:
|
||||
'Automatically request series on your <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink>',
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserGeneralSettings',
|
||||
{
|
||||
general: 'General',
|
||||
generalsettings: 'General Settings',
|
||||
displayName: 'Display Name',
|
||||
email: 'Email',
|
||||
save: 'Save Changes',
|
||||
saving: 'Saving…',
|
||||
mediaServerUser: '{mediaServerName} User',
|
||||
accounttype: 'Account Type',
|
||||
plexuser: 'Plex User',
|
||||
localuser: 'Local User',
|
||||
role: 'Role',
|
||||
owner: 'Owner',
|
||||
admin: 'Admin',
|
||||
user: 'User',
|
||||
toastSettingsSuccess: 'Settings saved successfully!',
|
||||
toastSettingsFailure: 'Something went wrong while saving settings.',
|
||||
region: 'Discover Region',
|
||||
regionTip: 'Filter content by regional availability',
|
||||
originallanguage: 'Discover Language',
|
||||
originallanguageTip: 'Filter content by original language',
|
||||
movierequestlimit: 'Movie Request Limit',
|
||||
seriesrequestlimit: 'Series Request Limit',
|
||||
enableOverride: 'Override Global Limit',
|
||||
applanguage: 'Display Language',
|
||||
languageDefault: 'Default ({language})',
|
||||
discordId: 'Discord User ID',
|
||||
discordIdTip:
|
||||
'The <FindDiscordIdLink>multi-digit ID number</FindDiscordIdLink> associated with your Discord user account',
|
||||
validationemailrequired: 'Email required',
|
||||
validationemailformat: 'Valid email required',
|
||||
validationDiscordId: 'You must provide a valid Discord user ID',
|
||||
plexwatchlistsyncmovies: 'Auto-Request Movies',
|
||||
plexwatchlistsyncmoviestip:
|
||||
'Automatically request movies on your <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink>',
|
||||
plexwatchlistsyncseries: 'Auto-Request Series',
|
||||
plexwatchlistsyncseriestip:
|
||||
'Automatically request series on your <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink>',
|
||||
}
|
||||
);
|
||||
|
||||
const UserGeneralSettings = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -3,24 +3,28 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
|
||||
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
|
||||
import { useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
|
||||
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import axios from 'axios';
|
||||
import { Field, Form, Formik } from 'formik';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const messages = defineMessages({
|
||||
discordsettingssaved: 'Discord notification settings saved successfully!',
|
||||
discordsettingsfailed: 'Discord notification settings failed to save.',
|
||||
discordId: 'User ID',
|
||||
discordIdTip:
|
||||
'The <FindDiscordIdLink>multi-digit ID number</FindDiscordIdLink> associated with your user account',
|
||||
validationDiscordId: 'You must provide a valid user ID',
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserNotificationSettings',
|
||||
{
|
||||
discordsettingssaved: 'Discord notification settings saved successfully!',
|
||||
discordsettingsfailed: 'Discord notification settings failed to save.',
|
||||
discordId: 'User ID',
|
||||
discordIdTip:
|
||||
'The <FindDiscordIdLink>multi-digit ID number</FindDiscordIdLink> associated with your user account',
|
||||
validationDiscordId: 'You must provide a valid user ID',
|
||||
}
|
||||
);
|
||||
|
||||
const UserNotificationsDiscord = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -8,24 +8,28 @@ import { OpenPgpLink } from '@app/components/Settings/Notifications/Notification
|
||||
import SettingsBadge from '@app/components/Settings/SettingsBadge';
|
||||
import { useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
|
||||
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import axios from 'axios';
|
||||
import { Form, Formik } from 'formik';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const messages = defineMessages({
|
||||
emailsettingssaved: 'Email notification settings saved successfully!',
|
||||
emailsettingsfailed: 'Email notification settings failed to save.',
|
||||
pgpPublicKey: 'PGP Public Key',
|
||||
pgpPublicKeyTip:
|
||||
'Encrypt email messages using <OpenPgpLink>OpenPGP</OpenPgpLink>',
|
||||
validationPgpPublicKey: 'You must provide a valid PGP public key',
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserNotificationSettings',
|
||||
{
|
||||
emailsettingssaved: 'Email notification settings saved successfully!',
|
||||
emailsettingsfailed: 'Email notification settings failed to save.',
|
||||
pgpPublicKey: 'PGP Public Key',
|
||||
pgpPublicKeyTip:
|
||||
'Encrypt email messages using <OpenPgpLink>OpenPGP</OpenPgpLink>',
|
||||
validationPgpPublicKey: 'You must provide a valid PGP public key',
|
||||
}
|
||||
);
|
||||
|
||||
const UserEmailSettings = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -4,24 +4,29 @@ import SensitiveInput from '@app/components/Common/SensitiveInput';
|
||||
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
|
||||
import { useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import axios from 'axios';
|
||||
import { Form, Formik } from 'formik';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const messages = defineMessages({
|
||||
pushbulletsettingssaved:
|
||||
'Pushbullet notification settings saved successfully!',
|
||||
pushbulletsettingsfailed: 'Pushbullet notification settings failed to save.',
|
||||
pushbulletAccessToken: 'Access Token',
|
||||
pushbulletAccessTokenTip:
|
||||
'Create a token from your <PushbulletSettingsLink>Account Settings</PushbulletSettingsLink>',
|
||||
validationPushbulletAccessToken: 'You must provide an access token',
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserNotificationSettings',
|
||||
{
|
||||
pushbulletsettingssaved:
|
||||
'Pushbullet notification settings saved successfully!',
|
||||
pushbulletsettingsfailed:
|
||||
'Pushbullet notification settings failed to save.',
|
||||
pushbulletAccessToken: 'Access Token',
|
||||
pushbulletAccessTokenTip:
|
||||
'Create a token from your <PushbulletSettingsLink>Account Settings</PushbulletSettingsLink>',
|
||||
validationPushbulletAccessToken: 'You must provide an access token',
|
||||
}
|
||||
);
|
||||
|
||||
const UserPushbulletSettings = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -4,31 +4,35 @@ import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
|
||||
import useSettings from '@app/hooks/useSettings';
|
||||
import { useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import type { PushoverSound } from '@server/api/pushover';
|
||||
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import axios from 'axios';
|
||||
import { Field, Form, Formik } from 'formik';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const messages = defineMessages({
|
||||
pushoversettingssaved: 'Pushover notification settings saved successfully!',
|
||||
pushoversettingsfailed: 'Pushover notification settings failed to save.',
|
||||
pushoverApplicationToken: 'Application API Token',
|
||||
pushoverApplicationTokenTip:
|
||||
'<ApplicationRegistrationLink>Register an application</ApplicationRegistrationLink> for use with {applicationTitle}',
|
||||
pushoverUserKey: 'User or Group Key',
|
||||
pushoverUserKeyTip:
|
||||
'Your 30-character <UsersGroupsLink>user or group identifier</UsersGroupsLink>',
|
||||
sound: 'Notification Sound',
|
||||
deviceDefault: 'Device Default',
|
||||
validationPushoverApplicationToken:
|
||||
'You must provide a valid application token',
|
||||
validationPushoverUserKey: 'You must provide a valid user or group key',
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserNotificationSettings',
|
||||
{
|
||||
pushoversettingssaved: 'Pushover notification settings saved successfully!',
|
||||
pushoversettingsfailed: 'Pushover notification settings failed to save.',
|
||||
pushoverApplicationToken: 'Application API Token',
|
||||
pushoverApplicationTokenTip:
|
||||
'<ApplicationRegistrationLink>Register an application</ApplicationRegistrationLink> for use with {applicationTitle}',
|
||||
pushoverUserKey: 'User or Group Key',
|
||||
pushoverUserKeyTip:
|
||||
'Your 30-character <UsersGroupsLink>user or group identifier</UsersGroupsLink>',
|
||||
sound: 'Notification Sound',
|
||||
deviceDefault: 'Device Default',
|
||||
validationPushoverApplicationToken:
|
||||
'You must provide a valid application token',
|
||||
validationPushoverUserKey: 'You must provide a valid user or group key',
|
||||
}
|
||||
);
|
||||
|
||||
const UserPushoverSettings = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -3,26 +3,30 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
|
||||
import NotificationTypeSelector from '@app/components/NotificationTypeSelector';
|
||||
import { useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
|
||||
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import axios from 'axios';
|
||||
import { Field, Form, Formik } from 'formik';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const messages = defineMessages({
|
||||
telegramsettingssaved: 'Telegram notification settings saved successfully!',
|
||||
telegramsettingsfailed: 'Telegram notification settings failed to save.',
|
||||
telegramChatId: 'Chat ID',
|
||||
telegramChatIdTipLong:
|
||||
'<TelegramBotLink>Start a chat</TelegramBotLink>, add <GetIdBotLink>@get_id_bot</GetIdBotLink>, and issue the <code>/my_id</code> command',
|
||||
sendSilently: 'Send Silently',
|
||||
sendSilentlyDescription: 'Send notifications with no sound',
|
||||
validationTelegramChatId: 'You must provide a valid chat ID',
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserNotificationSettings',
|
||||
{
|
||||
telegramsettingssaved: 'Telegram notification settings saved successfully!',
|
||||
telegramsettingsfailed: 'Telegram notification settings failed to save.',
|
||||
telegramChatId: 'Chat ID',
|
||||
telegramChatIdTipLong:
|
||||
'<TelegramBotLink>Start a chat</TelegramBotLink>, add <GetIdBotLink>@get_id_bot</GetIdBotLink>, and issue the <code>/my_id</code> command',
|
||||
sendSilently: 'Send Silently',
|
||||
sendSilentlyDescription: 'Send notifications with no sound',
|
||||
validationTelegramChatId: 'You must provide a valid chat ID',
|
||||
}
|
||||
);
|
||||
|
||||
const UserTelegramSettings = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -5,19 +5,23 @@ import NotificationTypeSelector, {
|
||||
} from '@app/components/NotificationTypeSelector';
|
||||
import { useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
|
||||
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import axios from 'axios';
|
||||
import { Form, Formik } from 'formik';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR, { mutate } from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
webpushsettingssaved: 'Web push notification settings saved successfully!',
|
||||
webpushsettingsfailed: 'Web push notification settings failed to save.',
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserNotificationSettings',
|
||||
{
|
||||
webpushsettingssaved: 'Web push notification settings saved successfully!',
|
||||
webpushsettingsfailed: 'Web push notification settings failed to save.',
|
||||
}
|
||||
);
|
||||
|
||||
const UserWebPushSettings = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -9,18 +9,22 @@ import SettingsTabs from '@app/components/Common/SettingsTabs';
|
||||
import { useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { CloudIcon, EnvelopeIcon } from '@heroicons/react/24/solid';
|
||||
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
notifications: 'Notifications',
|
||||
notificationsettings: 'Notification Settings',
|
||||
email: 'Email',
|
||||
webpush: 'Web Push',
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserNotificationSettings',
|
||||
{
|
||||
notifications: 'Notifications',
|
||||
notificationsettings: 'Notification Settings',
|
||||
email: 'Email',
|
||||
webpush: 'Web Push',
|
||||
}
|
||||
);
|
||||
|
||||
type UserNotificationSettingsProps = {
|
||||
children: React.ReactNode;
|
||||
|
||||
@@ -6,37 +6,41 @@ import SensitiveInput from '@app/components/Common/SensitiveInput';
|
||||
import { Permission, useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
|
||||
import axios from 'axios';
|
||||
import { Form, Formik } from 'formik';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const messages = defineMessages({
|
||||
password: 'Password',
|
||||
currentpassword: 'Current Password',
|
||||
newpassword: 'New Password',
|
||||
confirmpassword: 'Confirm Password',
|
||||
toastSettingsSuccess: 'Password saved successfully!',
|
||||
toastSettingsFailure: 'Something went wrong while saving the password.',
|
||||
toastSettingsFailureVerifyCurrent:
|
||||
'Something went wrong while saving the password. Was your current password entered correctly?',
|
||||
validationCurrentPassword: 'You must provide your current password',
|
||||
validationNewPassword: 'You must provide a new password',
|
||||
validationNewPasswordLength:
|
||||
'Password is too short; should be a minimum of 8 characters',
|
||||
validationConfirmPassword: 'You must confirm the new password',
|
||||
validationConfirmPasswordSame: 'Passwords must match',
|
||||
noPasswordSet:
|
||||
'This user account currently does not have a password set. Configure a password below to enable this account to sign in as a "local user."',
|
||||
noPasswordSetOwnAccount:
|
||||
'Your account currently does not have a password set. Configure a password below to enable sign-in as a "local user" using your email address.',
|
||||
nopermissionDescription:
|
||||
"You do not have permission to modify this user's password.",
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserPasswordChange',
|
||||
{
|
||||
password: 'Password',
|
||||
currentpassword: 'Current Password',
|
||||
newpassword: 'New Password',
|
||||
confirmpassword: 'Confirm Password',
|
||||
toastSettingsSuccess: 'Password saved successfully!',
|
||||
toastSettingsFailure: 'Something went wrong while saving the password.',
|
||||
toastSettingsFailureVerifyCurrent:
|
||||
'Something went wrong while saving the password. Was your current password entered correctly?',
|
||||
validationCurrentPassword: 'You must provide your current password',
|
||||
validationNewPassword: 'You must provide a new password',
|
||||
validationNewPasswordLength:
|
||||
'Password is too short; should be a minimum of 8 characters',
|
||||
validationConfirmPassword: 'You must confirm the new password',
|
||||
validationConfirmPasswordSame: 'Passwords must match',
|
||||
noPasswordSet:
|
||||
'This user account currently does not have a password set. Configure a password below to enable this account to sign in as a "local user."',
|
||||
noPasswordSetOwnAccount:
|
||||
'Your account currently does not have a password set. Configure a password below to enable sign-in as a "local user" using your email address.',
|
||||
nopermissionDescription:
|
||||
"You do not have permission to modify this user's password.",
|
||||
}
|
||||
);
|
||||
|
||||
const UserPasswordChange = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -6,20 +6,24 @@ import PermissionEdit from '@app/components/PermissionEdit';
|
||||
import { useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { ArrowDownOnSquareIcon } from '@heroicons/react/24/outline';
|
||||
import axios from 'axios';
|
||||
import { Form, Formik } from 'formik';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
toastSettingsSuccess: 'Permissions saved successfully!',
|
||||
toastSettingsFailure: 'Something went wrong while saving settings.',
|
||||
permissions: 'Permissions',
|
||||
unauthorizedDescription: 'You cannot modify your own permissions.',
|
||||
});
|
||||
const messages = defineMessages(
|
||||
'components.UserProfile.UserSettings.UserPermissions',
|
||||
{
|
||||
toastSettingsSuccess: 'Permissions saved successfully!',
|
||||
toastSettingsFailure: 'Something went wrong while saving settings.',
|
||||
permissions: 'Permissions',
|
||||
unauthorizedDescription: 'You cannot modify your own permissions.',
|
||||
}
|
||||
);
|
||||
|
||||
const UserPermissions = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -8,13 +8,14 @@ import useSettings from '@app/hooks/useSettings';
|
||||
import { useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces';
|
||||
import { hasPermission, Permission } from '@server/lib/permissions';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
const messages = defineMessages('components.UserProfile.UserSettings', {
|
||||
menuGeneralSettings: 'General',
|
||||
menuChangePass: 'Password',
|
||||
menuNotifications: 'Notifications',
|
||||
|
||||
@@ -8,6 +8,7 @@ import TmdbTitleCard from '@app/components/TitleCard/TmdbTitleCard';
|
||||
import ProfileHeader from '@app/components/UserProfile/ProfileHeader';
|
||||
import { Permission, UserType, useUser } from '@app/hooks/useUser';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { ArrowRightCircleIcon } from '@heroicons/react/24/outline';
|
||||
import type { WatchlistResponse } from '@server/interfaces/api/discoverInterfaces';
|
||||
import type {
|
||||
@@ -20,10 +21,10 @@ import type { TvDetails } from '@server/models/Tv';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
const messages = defineMessages('components.UserProfile', {
|
||||
recentrequests: 'Recent Requests',
|
||||
limit: '{remaining} of {limit}',
|
||||
requestsperdays: '{limit} remaining',
|
||||
@@ -164,7 +165,7 @@ const UserProfile = () => {
|
||||
: `/users/${user?.id}/requests?filter=all`
|
||||
}
|
||||
>
|
||||
<a>{intl.formatNumber(user.requestCount)}</a>
|
||||
{intl.formatNumber(user.requestCount)}
|
||||
</Link>
|
||||
</dd>
|
||||
</div>
|
||||
@@ -296,11 +297,10 @@ const UserProfile = () => {
|
||||
? '/profile/requests?filter=all'
|
||||
: `/users/${user?.id}/requests?filter=all`
|
||||
}
|
||||
className="slider-title"
|
||||
>
|
||||
<a className="slider-title">
|
||||
<span>{intl.formatMessage(messages.recentrequests)}</span>
|
||||
<ArrowRightCircleIcon />
|
||||
</a>
|
||||
<span>{intl.formatMessage(messages.recentrequests)}</span>
|
||||
<ArrowRightCircleIcon />
|
||||
</Link>
|
||||
</div>
|
||||
<Slider
|
||||
@@ -336,11 +336,10 @@ const UserProfile = () => {
|
||||
? '/profile/watchlist'
|
||||
: `/users/${user.id}/watchlist`
|
||||
}
|
||||
className="slider-title"
|
||||
>
|
||||
<a className="slider-title">
|
||||
<span>{watchlistSliderTitle}</span>
|
||||
<ArrowRightCircleIcon />
|
||||
</a>
|
||||
<span>{watchlistSliderTitle}</span>
|
||||
<ArrowRightCircleIcon />
|
||||
</Link>
|
||||
</div>
|
||||
<Slider
|
||||
|
||||
Reference in New Issue
Block a user