diff --git a/packages/shared/src/components/ProfileMenu/sections/ExtensionSection.tsx b/packages/shared/src/components/ProfileMenu/sections/ExtensionSection.tsx
index 2b33380290..7f2188bb79 100644
--- a/packages/shared/src/components/ProfileMenu/sections/ExtensionSection.tsx
+++ b/packages/shared/src/components/ProfileMenu/sections/ExtensionSection.tsx
@@ -10,15 +10,11 @@ import { useLazyModal } from '../../../hooks/useLazyModal';
import { LazyModal } from '../../modals/common/types';
import { checkIsExtension } from '../../../lib/func';
-export const ExtensionSection = (): ReactElement | null => {
+const ExtensionSectionContent = (): ReactElement => {
const { openModal } = useLazyModal();
const { isActive: isDndActive, setShowDnd } = useDndContext();
const { optOutCompanion, toggleOptOutCompanion } = useSettingsContext();
- if (!checkIsExtension()) {
- return null;
- }
-
return (
<>
@@ -33,7 +29,7 @@ export const ExtensionSection = (): ReactElement | null => {
{
title: `${isDndActive ? 'Resume' : 'Pause'} new tab`,
icon: isDndActive ? PlayIcon : PauseIcon,
- onClick: () => setShowDnd?.(true),
+ onClick: () => setShowDnd(true),
},
{
title: `${optOutCompanion ? 'Enable' : 'Disable'} companion widget`,
@@ -45,3 +41,11 @@ export const ExtensionSection = (): ReactElement | null => {
>
);
};
+
+export const ExtensionSection = (): ReactElement | null => {
+ if (!checkIsExtension()) {
+ return null;
+ }
+
+ return ;
+};
diff --git a/packages/shared/src/contexts/AlertContext.tsx b/packages/shared/src/contexts/AlertContext.tsx
index ab31232653..3126578948 100644
--- a/packages/shared/src/contexts/AlertContext.tsx
+++ b/packages/shared/src/contexts/AlertContext.tsx
@@ -2,7 +2,7 @@ import type { ReactNode, ReactElement } from 'react';
import React, { useMemo, useContext } from 'react';
import type { UseMutateAsyncFunction } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
-import type { Alerts, AlertsUpdate } from '../graphql/alerts';
+import type { Alerts } from '../graphql/alerts';
import {
UPDATE_ALERTS,
UPDATE_LAST_BOOT_POPUP,
@@ -13,36 +13,33 @@ import { gqlClient } from '../graphql/common';
export const ALERT_DEFAULTS: Alerts = {
filter: true,
- rankLastSeen: null,
- myFeed: null,
+ rankLastSeen: undefined,
+ myFeed: undefined,
squadTour: true,
showGenericReferral: false,
showStreakMilestone: false,
showAchievementUnlock: null,
- lastBootPopup: null,
- briefBannerLastSeen: null,
+ lastBootPopup: undefined,
+ briefBannerLastSeen: undefined,
};
export interface AlertContextData {
alerts: Alerts;
isFetched?: boolean;
loadedAlerts?: boolean;
- updateAlerts?: UseMutateAsyncFunction<
+ updateAlerts: UseMutateAsyncFunction;
+ updateLastReferralReminder?: UseMutateAsyncFunction;
+ updateLastBootPopup?: UseMutateAsyncFunction;
+ updateHasSeenOpportunity?: UseMutateAsyncFunction<
unknown,
unknown,
- AlertsUpdate,
- () => Promise
+ boolean | void
>;
- updateLastReferralReminder?: UseMutateAsyncFunction;
- updateLastBootPopup?: UseMutateAsyncFunction;
- updateHasSeenOpportunity?: UseMutateAsyncFunction;
- clearOpportunityAlert?: UseMutateAsyncFunction;
+ clearOpportunityAlert?: UseMutateAsyncFunction;
}
-const AlertContext = React.createContext({
- alerts: ALERT_DEFAULTS,
- loadedAlerts: false,
-});
+// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+const AlertContext = React.createContext(null!);
export interface AlertContextProviderProps {
children: ReactNode;
@@ -60,6 +57,10 @@ export const AlertContextProvider = ({
isFetched,
updateAlerts,
}: AlertContextProviderProps): ReactElement => {
+ const applyUpdatedAlerts = (updatedAlerts: Alerts): void => {
+ updateAlerts?.(updatedAlerts);
+ };
+
const { mutateAsync: updateRemoteAlerts } = useMutation<
unknown,
unknown,
@@ -69,15 +70,15 @@ export const AlertContextProvider = ({
gqlClient.request(UPDATE_ALERTS, {
data: params,
}),
- onMutate: (params) => updateAlerts({ ...alerts, ...params }),
+ onMutate: (params) => applyUpdatedAlerts({ ...alerts, ...params }),
onError: (_, params) => {
- const rollback = Object.keys(params).reduce(
+ const rollback = (Object.keys(params) as Array).reduce(
(values, key) => ({ ...values, [key]: alerts[key] }),
- {},
+ {} as Alerts,
);
- updateAlerts({ ...alerts, ...rollback });
+ applyUpdatedAlerts({ ...alerts, ...rollback });
},
});
@@ -89,16 +90,16 @@ export const AlertContextProvider = ({
mutationFn: () => gqlClient.request(UPDATE_LAST_BOOT_POPUP),
onMutate: () =>
- updateAlerts({
+ applyUpdatedAlerts({
...alerts,
lastBootPopup: new Date(),
bootPopup: false,
}),
onError: () => {
- updateAlerts({
+ applyUpdatedAlerts({
...alerts,
- lastBootPopup: null,
+ lastBootPopup: undefined,
bootPopup: true,
});
},
diff --git a/packages/shared/src/contexts/AuthContext.tsx b/packages/shared/src/contexts/AuthContext.tsx
index b9386a03d0..e3df5d2ce4 100644
--- a/packages/shared/src/contexts/AuthContext.tsx
+++ b/packages/shared/src/contexts/AuthContext.tsx
@@ -51,7 +51,7 @@ export interface AuthContextData {
shouldShowLogin: boolean;
showLogin: ({ trigger, options }: ShowLoginParams) => void;
closeLogin: () => void;
- loginState?: LoginState;
+ loginState?: LoginState | null;
logout: (reason: string) => Promise;
updateUser: (user: LoggedUser) => Promise;
loadingUser?: boolean;
@@ -75,7 +75,8 @@ export interface AuthContextData {
}
const isExtension = checkIsExtension();
-const AuthContext = React.createContext(null);
+// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+const AuthContext = React.createContext(null!);
export const useAuthContext = (): AuthContextData => useContext(AuthContext);
export default AuthContext;
@@ -93,10 +94,11 @@ export const REGISTRATION_PATH = '/register';
export const logout = async (reason: string): Promise => {
await dispatchLogout(reason);
const params = getQueryParams();
- if (params.redirect_uri) {
- window.location.replace(params.redirect_uri);
+ const redirectUri = params.redirect_uri;
+ if (redirectUri) {
+ window.location.replace(redirectUri);
} else if (window.location.pathname === REGISTRATION_PATH) {
- window.location.replace(process.env.NEXT_PUBLIC_WEBAPP_URL);
+ window.location.replace(process.env.NEXT_PUBLIC_WEBAPP_URL ?? '/');
}
if (isExtension) {
@@ -107,9 +109,15 @@ export const logout = async (reason: string): Promise => {
};
export function checkIfGdprCovered(geo?: Boot['geo']): boolean {
+ const region = geo?.region;
+
+ if (!region) {
+ return true;
+ }
+
return (
geo?.continent === Continent.Europe ||
- !outsideGdpr.includes(geo?.region) ||
+ !outsideGdpr.includes(region) ||
isIOSNative()
);
}
@@ -152,7 +160,7 @@ export const AuthContextProvider = ({
isAndroidApp,
}: AuthContextProviderProps): ReactElement => {
const [loginState, setLoginState] = useState(null);
- const endUser = user && 'providers' in user ? user : null;
+ const endUser = user && 'providers' in user ? user : undefined;
const referral = user?.referralId || user?.referrer;
const referralOrigin = user?.referralOrigin;
const router = useRouter();
@@ -169,10 +177,15 @@ export const AuthContextProvider = ({
logout(LogoutReason.IncomleteOnboarding);
}
- const isValidRegion = useMemo(
- () => !invalidPlusRegions.includes(geo?.region),
- [geo?.region],
- );
+ const isValidRegion = useMemo(() => {
+ const region = geo?.region;
+
+ if (!region) {
+ return true;
+ }
+
+ return !invalidPlusRegions.includes(region);
+ }, [geo?.region]);
return (
{
const hasCompanion = !!isCompanionActivated();
diff --git a/packages/shared/src/contexts/BootProvider.spec.tsx b/packages/shared/src/contexts/BootProvider.spec.tsx
index aba2441505..7bdee76c37 100644
--- a/packages/shared/src/contexts/BootProvider.spec.tsx
+++ b/packages/shared/src/contexts/BootProvider.spec.tsx
@@ -53,7 +53,7 @@ beforeEach(() => {
localStorage.clear();
});
-const defaultAlerts: Alerts = { filter: true, rankLastSeen: null };
+const defaultAlerts: Alerts = { filter: true, rankLastSeen: undefined };
const defaultSettings: RemoteSettings = {
theme: 'bright',
@@ -162,7 +162,13 @@ const SettingsMock = ({
Sidebar