diff --git a/app/src/components/authentication/AuthForm/index.js b/app/src/components/authentication/AuthForm/index.js
index 85ea1f8ae0..20d2e99024 100644
--- a/app/src/components/authentication/AuthForm/index.js
+++ b/app/src/components/authentication/AuthForm/index.js
@@ -1,6 +1,6 @@
import React, { useState, useEffect, useMemo, useCallback } from "react";
import { useSelector } from "react-redux";
-import { useLocation, useNavigate } from "react-router-dom";
+import { useNavigate } from "react-router-dom";
import { RQButton, RQInput } from "lib/design-system/components";
import { toast } from "utils/Toast";
import { Typography, Row, Col } from "antd";
@@ -17,7 +17,6 @@ import { getAuthErrorMessage, AuthTypes } from "../utils";
//CONSTANTS
import { CONSTANTS as GLOBAL_CONSTANTS } from "@requestly/requestly-core";
import APP_CONSTANTS from "../../../config/constants";
-import PATHS from "config/constants/sub/paths";
//ACTIONS
import {
@@ -54,7 +53,6 @@ const AuthForm = ({
}) => {
const dispatch = useDispatch();
const navigate = useNavigate();
- const location = useLocation();
//LOAD PROPS
const callbackFromProps = callbacks || {};
const { onSignInSuccess, onRequestPasswordResetSuccess } = callbackFromProps;
@@ -440,9 +438,7 @@ const AuthForm = ({
- {location.pathname === PATHS.APPSUMO.RELATIVE
- ? "Signup to redeem your AppSumo code"
- : "Create your Requestly account"}
+ Create your Requestly account
diff --git a/app/src/components/landing/Appsumo/AppSumoWorkspaceDropdown/AppSumoWorkspaceDropdown.tsx b/app/src/components/landing/Appsumo/AppSumoWorkspaceDropdown/AppSumoWorkspaceDropdown.tsx
deleted file mode 100644
index 4877b852af..0000000000
--- a/app/src/components/landing/Appsumo/AppSumoWorkspaceDropdown/AppSumoWorkspaceDropdown.tsx
+++ /dev/null
@@ -1,142 +0,0 @@
-import React, { useCallback, useEffect, useMemo } from "react";
-import { DownOutlined, LockOutlined } from "@ant-design/icons";
-import { Avatar, Dropdown, Typography } from "antd";
-import { RQButton } from "lib/design-system/components";
-import { useSelector } from "react-redux";
-import { getUserAuthDetails } from "store/slices/global/user/selectors";
-import APP_CONSTANTS from "config/constants";
-import "./index.scss";
-import { getActiveWorkspaceId, getAllWorkspaces } from "store/slices/workspaces/selectors";
-import { WorkspaceType } from "features/workspaces/types";
-import WorkspaceAvatar from "features/workspaces/components/WorkspaceAvatar";
-import { isPersonalWorkspace } from "features/workspaces/utils";
-
-const getWorkspaceIcon = (workspaceName: string) => {
- if (workspaceName === APP_CONSTANTS.TEAM_WORKSPACES.NAMES.PRIVATE_WORKSPACE) return ;
- return workspaceName ? workspaceName[0].toUpperCase() : "?";
-};
-
-const AppSumoWorkspaceDropdown: React.FC<{
- isAppSumo?: boolean;
- workspaceToUpgrade: { name: string; id: string; accessCount: number };
- setWorkspaceToUpgrade: (workspaceDetails: any) => void;
- className?: string;
- disabled?: boolean;
-}> = ({ isAppSumo = false, workspaceToUpgrade, setWorkspaceToUpgrade, className, disabled = false }) => {
- const user = useSelector(getUserAuthDetails);
- const availableWorkspaces = useSelector(getAllWorkspaces);
- const activeWorkspaceId = useSelector(getActiveWorkspaceId);
-
- const filteredAvailableTeams = useMemo(() => {
- return (
- availableWorkspaces?.filter(
- (team: any) =>
- !team?.archived &&
- user?.details?.profile?.uid &&
- team.members?.[user?.details?.profile?.uid]?.role === "admin"
- ) ?? []
- );
- }, [availableWorkspaces, user?.details?.profile?.uid]);
-
- const populateWorkspaceDetails = useCallback(
- (workspaceId: string) => {
- return filteredAvailableTeams.find((team: any) => team.id === workspaceId);
- },
- [filteredAvailableTeams]
- );
-
- useEffect(() => {
- if (activeWorkspaceId) {
- setWorkspaceToUpgrade(populateWorkspaceDetails(activeWorkspaceId));
- }
- }, [activeWorkspaceId, populateWorkspaceDetails, setWorkspaceToUpgrade]);
-
- const workspaceMenuItems = {
- items: [
- {
- key: "private_workspace",
- label: APP_CONSTANTS.TEAM_WORKSPACES.NAMES.PRIVATE_WORKSPACE,
- icon: (
-
- ),
- },
- ...filteredAvailableTeams.map((team: any) => ({
- label: team.name,
- key: team.id,
- icon: ,
- })),
- ].filter((items) => (isAppSumo ? items.key !== "private_workspace" : true)),
- onClick: ({ key: teamId }: { key: string }) => {
- if (teamId === "private_workspace") {
- return setWorkspaceToUpgrade({
- name: APP_CONSTANTS.TEAM_WORKSPACES.NAMES.PRIVATE_WORKSPACE,
- id: "private_workspace",
- accessCount: 1,
- });
- } else if (teamId === APP_CONSTANTS.TEAM_WORKSPACES.NEW_WORKSPACE.id) {
- // temporary new workspace for appsumo
- return setWorkspaceToUpgrade({
- ...APP_CONSTANTS.TEAM_WORKSPACES.NEW_WORKSPACE,
- });
- }
-
- setWorkspaceToUpgrade(populateWorkspaceDetails(teamId));
- },
- };
-
- if (isAppSumo) {
- workspaceMenuItems.items.unshift({
- key: APP_CONSTANTS.TEAM_WORKSPACES.NEW_WORKSPACE.id,
- label: APP_CONSTANTS.TEAM_WORKSPACES.NEW_WORKSPACE.name,
- icon: (
-
- ),
- });
- }
-
- return user.loggedIn ? (
-
-
- Select workspace to upgrade
-
-
-
-
- {workspaceToUpgrade?.name}
-
-
-
-
-
- {(isAppSumo || workspaceToUpgrade?.id !== "private_workspace") && (
-
-
- Your workspace has {workspaceToUpgrade?.accessCount} active{" "}
- {workspaceToUpgrade?.accessCount > 1 ? "members" : "member"}.
-
-
- )}
-
- ) : null;
-};
-
-export default AppSumoWorkspaceDropdown;
diff --git a/app/src/components/landing/Appsumo/AppSumoWorkspaceDropdown/index.scss b/app/src/components/landing/Appsumo/AppSumoWorkspaceDropdown/index.scss
deleted file mode 100644
index c26279611e..0000000000
--- a/app/src/components/landing/Appsumo/AppSumoWorkspaceDropdown/index.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-.workspace-selector-container {
- display: flex;
- flex-direction: column;
- margin-bottom: 1rem;
- width: 100%;
-
- .workspace-selector-dropdown-container {
- margin-bottom: 4px;
-
- .workspace-selector-dropdown {
- &.ant-dropdown-menu-root {
- overflow: auto;
- max-height: 15rem;
- }
- }
-
- .workspace-selector-dropdown-btn.ant-btn.rq-btn {
- background-color: var(--requestly-color-surface-1);
- border: none;
- margin-left: 4px;
- padding: 8px;
-
- &:hover {
- border: none;
- }
-
- .workspace-selector-dropdown-icon.anticon {
- margin-left: 2px;
- font-size: 0.7rem;
- }
- }
- }
-}
diff --git a/app/src/components/landing/Appsumo/Appsumo.tsx b/app/src/components/landing/Appsumo/Appsumo.tsx
deleted file mode 100644
index 6bee9c47d5..0000000000
--- a/app/src/components/landing/Appsumo/Appsumo.tsx
+++ /dev/null
@@ -1,348 +0,0 @@
-import React, { useCallback, useEffect, useMemo, useState } from "react";
-import { useDispatch, useSelector } from "react-redux";
-import { getAppMode } from "store/selectors";
-import { Row } from "antd";
-import APP_CONSTANTS from "config/constants";
-import { RQButton, RQInput, RQModal } from "lib/design-system/components";
-import { ImCross } from "@react-icons/all-files/im/ImCross";
-import { MdOutlineVerified } from "@react-icons/all-files/md/MdOutlineVerified";
-import { FiXCircle } from "@react-icons/all-files/fi/FiXCircle";
-import { useNavigate } from "react-router-dom";
-import { redirectToRoot } from "utils/RedirectionUtils";
-import AppSumoWorkspaceDropdown from "components/landing/Appsumo/AppSumoWorkspaceDropdown/AppSumoWorkspaceDropdown";
-import { doc, getDoc, getFirestore, writeBatch } from "firebase/firestore";
-import firebaseApp from "../../../firebase";
-import { toast } from "utils/Toast";
-import { isEmailValid } from "utils/FormattingHelper";
-import { useDebounce } from "hooks/useDebounce";
-import { httpsCallable, getFunctions } from "firebase/functions";
-import { trackNewTeamCreateSuccess } from "modules/analytics/events/features/teams";
-import { trackAppsumoCodeRedeemed } from "modules/analytics/events/misc/business";
-import { switchWorkspace } from "actions/TeamWorkspaceActions";
-import { globalActions } from "store/slices/global/slice";
-import "./index.scss";
-import { getAllWorkspaces } from "store/slices/workspaces/selectors";
-import { WorkspaceType } from "features/workspaces/types";
-
-interface AppSumoCode {
- error: string;
- code: string;
- verified: boolean;
-}
-
-const DEFAULT_APPSUMO_INPUT: AppSumoCode = {
- error: "",
- code: "",
- verified: false,
-};
-
-const AppSumoModal: React.FC = () => {
- const navigate = useNavigate();
- const dispatch = useDispatch();
- const appMode = useSelector(getAppMode);
- const availableWorkspaces = useSelector(getAllWorkspaces);
- const [appsumoCodes, setAppsumoCodes] = useState([{ ...DEFAULT_APPSUMO_INPUT }]);
- const [userEmail, setUserEmail] = useState("");
- const [emailValidationError, setEmailValidationError] = useState(null);
- const [workspaceToUpgrade, setWorkspaceToUpgrade] = useState(APP_CONSTANTS.TEAM_WORKSPACES.NEW_WORKSPACE);
- const [isLoading, setIsLoading] = useState(false);
- const [isUpdatingSubscription, setIsUpdatingSubscription] = useState(false);
- const [showMaxCodesExeceededError, setShowMaxCodesExeceededError] = useState(false);
-
- const db = getFirestore(firebaseApp);
-
- const addAppSumoCodeInput = () => {
- if (appsumoCodes.length >= 10) {
- setShowMaxCodesExeceededError(true);
- return;
- }
- setAppsumoCodes((prev) => [...prev, { ...DEFAULT_APPSUMO_INPUT }]);
- };
-
- const removeAppSumoCodeInput = (index: number) => {
- if (appsumoCodes.length === 1) return;
- setAppsumoCodes((prev) => {
- const codes = [...prev];
- codes.splice(index, 1);
- return codes;
- });
- };
-
- const isAllCodeCheckPassed = useMemo(() => appsumoCodes.every((code) => code.verified), [appsumoCodes]);
-
- const updateAppSumoCode = (index: number, key: keyof AppSumoCode, value: AppSumoCode[typeof key]) => {
- setAppsumoCodes((prev) => {
- const codes: AppSumoCode[] = [...prev];
- if (codes[index]) {
- (codes[index] as any)[key] = value;
- }
- return codes;
- });
- };
-
- const debouncedVerifyCode = useDebounce((enteredCode: string, index: number) => verifyCode(enteredCode, index));
-
- const verifyCode = useCallback(
- async (enteredCode: string, index: number) => {
- if (enteredCode.length < 8) {
- updateAppSumoCode(index, "verified", false);
- return;
- }
-
- const codeOccurence = appsumoCodes.filter((appsumoCode: AppSumoCode) => appsumoCode.code === enteredCode).length;
- if (codeOccurence > 1) {
- updateAppSumoCode(index, "error", "Code already used");
- updateAppSumoCode(index, "verified", false);
- return;
- }
-
- const docRef = doc(db, "appSumoCodes", enteredCode);
- const docSnap = await getDoc(docRef);
-
- if (!docSnap.exists()) {
- updateAppSumoCode(index, "error", "Invalid code");
- updateAppSumoCode(index, "verified", false);
- return;
- }
-
- if (docSnap.data()?.redeemed) {
- updateAppSumoCode(index, "error", "Code already redeemed");
- updateAppSumoCode(index, "verified", false);
- return;
- }
- updateAppSumoCode(index, "error", "");
- updateAppSumoCode(index, "verified", true);
- },
- [db, appsumoCodes]
- );
-
- const redeemSubmittedCodes = useCallback(async () => {
- const batch = writeBatch(db);
- appsumoCodes.forEach((code) => {
- const docRef = doc(db, "appSumoCodes", code.code);
- batch.update(docRef, { redeemed: true });
- });
- await batch.commit();
- }, [db, appsumoCodes]);
-
- const createNewWorkspaceForAppSumo = useCallback(async () => {
- setIsLoading(true);
-
- const newTeamName = "Team Workspace";
- const createTeam = httpsCallable(getFunctions(), "teams-createTeam");
- try {
- const response: any = await createTeam({ teamName: newTeamName });
- trackNewTeamCreateSuccess(response?.data?.teamId, newTeamName, "appsumo", WorkspaceType.SHARED);
- switchWorkspace(
- {
- teamId: response?.data?.teamId,
- teamMembersCount: 1,
- },
- dispatch,
- {
- isWorkspaceMode: false,
- isSyncEnabled: true,
- },
- appMode,
- null,
- "appsumo"
- );
-
- setIsLoading(false);
- return response?.data?.teamId;
- } catch (error) {
- // do nothing
- }
- }, [appMode, dispatch]);
-
- const onSubmit = useCallback(async () => {
- if (!isAllCodeCheckPassed || emailValidationError) {
- toast.warn("Please fill all the fields correctly", 10);
- throw new Error("Please fill all the fields correctly");
- }
- setIsUpdatingSubscription(true);
-
- let teamId = workspaceToUpgrade.id;
- if (workspaceToUpgrade.id === APP_CONSTANTS.TEAM_WORKSPACES.NEW_WORKSPACE.id) {
- teamId = await createNewWorkspaceForAppSumo();
- }
-
- const updateTeamSubscriptionForAppSumo = httpsCallable<{}, { success: boolean; message: string; error?: string }>(
- getFunctions(),
- "subscription-updateTeamSubscriptionForAppSumo"
- );
-
- try {
- await updateTeamSubscriptionForAppSumo({
- teamId: teamId,
- startDate: Date.now(),
- appsumoCodes: appsumoCodes.map((code) => code.code),
- })
- .then((response) => {
- if (!response?.data?.success && response?.data?.error === "max_limit_reached") {
- setShowMaxCodesExeceededError(true);
- } else {
- redeemSubmittedCodes();
- trackAppsumoCodeRedeemed(appsumoCodes.length);
- toast.success(
- `Lifetime access to SessionBook Plus unlocked for ${
- appsumoCodes.length > 1 ? `${appsumoCodes.length} members` : "you"
- }`,
- 10
- );
- redirectToRoot(navigate);
- }
- })
- .finally(() => {
- setIsUpdatingSubscription(false);
- });
- } catch (error) {
- console.error("from appsumo", error);
- }
- }, [
- createNewWorkspaceForAppSumo,
- appsumoCodes,
- emailValidationError,
- isAllCodeCheckPassed,
- redeemSubmittedCodes,
- workspaceToUpgrade?.id,
- navigate,
- ]);
-
- const handleEmailValidation = (email: string) => {
- if (!email) {
- setEmailValidationError("Please add your Appsumo email address");
- return;
- }
- if (!isEmailValid(email)) {
- setEmailValidationError("Please enter a valid email address");
- return;
- }
- setEmailValidationError(null);
- };
-
- const debouncedEmailValidation = useDebounce((email: string) => handleEmailValidation(email));
-
- const handleUnlockDealClick = async () => {
- setShowMaxCodesExeceededError(false);
- try {
- await onSubmit();
- } catch (error) {
- // do nothing
- }
- };
-
- useEffect(() => {
- const appsumoWorkspace = availableWorkspaces?.find((team: any) => team?.appsumo);
- if (appsumoWorkspace) {
- setWorkspaceToUpgrade(appsumoWorkspace as any);
- }
- }, [availableWorkspaces]);
-
- useEffect(() => {
- dispatch(globalActions.updateIsWorkspaceOnboardingCompleted());
- }, [dispatch]);
-
- return (
-
- <>
-
-
-

-
-
Please enter your AppSumo code
-
Unlock lifetime deal for SessionBook Plus
-
-
AppSumo email address
-
-
-
{
- setUserEmail(e.target.value);
- debouncedEmailValidation(e.target.value);
- }}
- placeholder="Enter email address here"
- />
- {emailValidationError}
-
-
-
AppSumo Code(s)
- {appsumoCodes.map((appsumoCode, index) => (
-
-
- {
- updateAppSumoCode(index, "code", e.target.value);
- debouncedVerifyCode(e.target.value, index);
- }}
- suffix={
- appsumoCode.verified ? (
-
- ) : appsumoCode.error ? (
- <>
- {appsumoCode.error}
-
- >
- ) : null
- }
- placeholder="Enter code here"
- />
-
-
-
- {
- removeAppSumoCodeInput(index);
- }}
- />
-
-
- ))}
-
-
- + Add more codes
-
- {showMaxCodesExeceededError && (
-
- {
- "Maximum 10 AppSumo codes can be applied. Please connect with support for further help at contact@requestly.io"
- }
-
- )}
-
-
-
- Unlock Deal
-
-
- >
-
- );
-};
-
-export default AppSumoModal;
diff --git a/app/src/components/landing/Appsumo/index.scss b/app/src/components/landing/Appsumo/index.scss
deleted file mode 100644
index 1e1ddb4bc1..0000000000
--- a/app/src/components/landing/Appsumo/index.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-.rq-modal-content.appsumo-modal {
- overflow: auto;
- max-height: 550px;
-
- .appsumo-code-input-container {
- display: flex;
- flex-direction: column;
- width: 100%;
- margin-top: 4px;
-
- .appsumo-code-error {
- text-align: right;
- padding: 2px 0;
- }
-
- .ant-input-suffix {
- color: var(--requestly-color-success);
- }
- }
-
- .remove-icon {
- margin: auto 6px;
- height: 14px;
- width: 14px;
- }
-
- .appsumo-add-btn {
- font-size: var(--requestly-font-size-sm, 13px);
- padding: 0;
- }
-}
diff --git a/app/src/config/constants/sub/paths.js b/app/src/config/constants/sub/paths.js
index ebe813aa13..892036500a 100644
--- a/app/src/config/constants/sub/paths.js
+++ b/app/src/config/constants/sub/paths.js
@@ -47,11 +47,6 @@ PATHS.HOME = {};
PATHS.HOME.RELATIVE = "/home";
PATHS.HOME.ABSOLUTE = joinPaths(PATHS.DASHBOARD, PATHS.HOME.RELATIVE);
-//Appsumo
-PATHS.APPSUMO = {};
-PATHS.APPSUMO.RELATIVE = "/appsumo";
-PATHS.APPSUMO.ABSOLUTE = joinPaths(PATHS.DASHBOARD, PATHS.APPSUMO.RELATIVE);
-
// Selenium-importer
PATHS.SELENIUM_IMPORTER = {};
PATHS.SELENIUM_IMPORTER.RELATIVE = "/selenium-importer";
diff --git a/app/src/features/onboarding/utils.ts b/app/src/features/onboarding/utils.ts
index 5de73a25db..a07c2ce38e 100644
--- a/app/src/features/onboarding/utils.ts
+++ b/app/src/features/onboarding/utils.ts
@@ -11,7 +11,6 @@ const EXCLUDED_PATHS = [
PATHS.AUTH.EMAIL_ACTION.RELATIVE,
PATHS.AUTH.EMAIL_LINK_SIGNIN.RELATIVE,
PATHS.SESSIONS.SAVED.RELATIVE,
- PATHS.APPSUMO.RELATIVE,
PATHS.PRICING.RELATIVE,
PATHS.AUTH.START.RELATIVE,
PATHS.AUTH.LOGIN.RELATIVE,
diff --git a/app/src/modules/analytics/events/misc/business/index.js b/app/src/modules/analytics/events/misc/business/index.js
index 5b4fea9ad4..dcb95d8079 100644
--- a/app/src/modules/analytics/events/misc/business/index.js
+++ b/app/src/modules/analytics/events/misc/business/index.js
@@ -18,11 +18,6 @@ export const trackViewGithubClicked = () => {
trackEvent(BUSINESS.VIEW_GITHUB_CLICKED);
};
-export const trackAppsumoCodeRedeemed = (number_of_codes) => {
- const params = { number_of_codes };
- trackEvent(BUSINESS.APPSUMO_CODE_REDEEMED, params);
-};
-
export const trackPricingPlanCTAClicked = ({ current_plan, selected_plan, action, quantity }, source) => {
const params = { current_plan, selected_plan, action, source, quantity };
trackEvent(BUSINESS.PRICING_PLAN_CTA_CLICKED, params);
diff --git a/app/src/modules/analytics/events/misc/constants.js b/app/src/modules/analytics/events/misc/constants.js
index a333a1cccd..d2f583e0a5 100644
--- a/app/src/modules/analytics/events/misc/constants.js
+++ b/app/src/modules/analytics/events/misc/constants.js
@@ -48,7 +48,6 @@ export const BUSINESS = {
TRIAL_MODE_EXPIRED_UPGRADE_BUTTON_CLICKED: "trial_mode_expired_upgrade_button_clicked",
UPGRADE_CLICKED: "upgrade_clicked",
VIEW_GITHUB_CLICKED: "view_github_clicked",
- APPSUMO_CODE_REDEEMED: "appsumo_code_redeemed",
PRICING_PLAN_CTA_CLICKED: "pricing_plan_cta_clicked",
PRICING_PLAN_CANCELLATION_REQUESTED: "pricing_plan_cancellation_requested",
PRICING_PLAN_CANCELLED: "pricing_plan_cancelled",
diff --git a/app/src/routes/miscRoutes.tsx b/app/src/routes/miscRoutes.tsx
index 2d062cd9b5..e87f26869d 100644
--- a/app/src/routes/miscRoutes.tsx
+++ b/app/src/routes/miscRoutes.tsx
@@ -8,7 +8,6 @@ import Page403 from "views/misc/ServerResponses/403";
import Page404 from "views/misc/ServerResponses/404";
import AcceptTeamInvite from "components/user/Teams/AcceptTeamInvite";
import ProtectedRoute from "components/authentication/ProtectedRoute";
-import AppSumoModal from "components/landing/Appsumo/Appsumo";
import { Home } from "components/Home";
import { PricingIndexPage } from "features/pricing/components/PricingPage";
import { ImportFromCharlesWrapperView } from "features/rules/screens/rulesList/components/RulesList/components";
@@ -85,10 +84,6 @@ export const miscRoutes: RouteObject[] = [
path: PATHS.HOME.RELATIVE,
element: ,
},
- {
- path: PATHS.APPSUMO.RELATIVE,
- element: ,
- },
{
path: PATHS.SELENIUM_IMPORTER.RELATIVE,
element: ,