From 8081af7a35a34930ae210a948376fbde3ff8ed0e Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Wed, 27 Nov 2024 17:21:57 -0800 Subject: [PATCH] Intersection checkout hook (#947) * special geo layer * fix checkout redirect from intersection --- src/editor/components/Main.js | 5 +- .../AddLayerPanel/AddLayerPanel.component.jsx | 5 +- .../GeoPanel/GeoPanel.component.jsx | 45 --------- .../components/GeoPanel/GeoPanel.module.scss | 29 ------ .../components/components/GeoPanel/index.js | 1 - src/editor/components/components/index.js | 1 - .../PaymentModal/PaymentModal.component.jsx | 28 ++++-- src/editor/components/scenegraph/GeoLayer.js | 94 +++++++++++++++++++ .../components/scenegraph/SceneGraph.js | 13 ++- src/editor/contexts/Auth.context.js | 5 +- src/store.js | 6 ++ 11 files changed, 135 insertions(+), 97 deletions(-) delete mode 100644 src/editor/components/components/GeoPanel/GeoPanel.component.jsx delete mode 100644 src/editor/components/components/GeoPanel/GeoPanel.module.scss delete mode 100644 src/editor/components/components/GeoPanel/index.js create mode 100644 src/editor/components/scenegraph/GeoLayer.js diff --git a/src/editor/components/Main.js b/src/editor/components/Main.js index be497e3db..f48a274ee 100644 --- a/src/editor/components/Main.js +++ b/src/editor/components/Main.js @@ -1,4 +1,4 @@ -import { HelpButton, GeoPanel, ZoomButtons } from './components'; +import { HelpButton, ZoomButtons } from './components'; import { useState, useEffect } from 'react'; import ComponentsSidebar from './components/Sidebar'; import Events from '../lib/Events'; @@ -155,9 +155,6 @@ export default function Main() { {isInspectorEnabled && ( <> -
- -
diff --git a/src/editor/components/components/AddLayerPanel/AddLayerPanel.component.jsx b/src/editor/components/components/AddLayerPanel/AddLayerPanel.component.jsx index fbc5f36bb..a6140b37d 100644 --- a/src/editor/components/components/AddLayerPanel/AddLayerPanel.component.jsx +++ b/src/editor/components/components/AddLayerPanel/AddLayerPanel.component.jsx @@ -10,7 +10,6 @@ import CardPlaceholder from '../../../../../ui_assets/card-placeholder.svg'; import LockedCard from '../../../../../ui_assets/locked-card.svg'; import mixinCatalog from '../../../../catalog.json'; import posthog from 'posthog-js'; -import Events from '../../../lib/Events'; import pickPointOnGroundPlane from '../../../lib/pick-point-on-ground-plane'; import { customLayersData, streetLayersData } from './layersData.js'; import { LayersOptions } from './LayersOptions.js'; @@ -270,6 +269,7 @@ const cardMouseLeave = (mixinId) => { const AddLayerPanel = () => { const setModal = useStore((state) => state.setModal); const isOpen = useStore((state) => state.modal === 'addlayer'); + const startCheckout = useStore((state) => state.startCheckout); // set the first Layers option when opening the panel const [selectedOption, setSelectedOption] = useState(LayersOptions[0].value); const [groupedMixins, setGroupedMixins] = useState([]); @@ -311,8 +311,7 @@ const AddLayerPanel = () => { isProUser: isProUser }); if (card.requiresPro && !isProUser) { - Events.emit('hideAddLayerPanel'); - Events.emit('openpaymentmodal'); + startCheckout('addlayer'); } else if (card.mixinId) { createEntity(card.mixinId); } else if (card.handlerFunction) { diff --git a/src/editor/components/components/GeoPanel/GeoPanel.component.jsx b/src/editor/components/components/GeoPanel/GeoPanel.component.jsx deleted file mode 100644 index 67f984235..000000000 --- a/src/editor/components/components/GeoPanel/GeoPanel.component.jsx +++ /dev/null @@ -1,45 +0,0 @@ -import GeoImg from '../../../../../ui_assets/geo.png'; -import styles from './GeoPanel.module.scss'; -import { useAuthContext, useGeoContext } from '../../../contexts/index.js'; -import posthog from 'posthog-js'; -import useStore from '@/store'; -/** - * GeoPanel component. - * - * @author Rostyslav Nahornyi - * @category Components. - */ -const GeoPanel = () => { - const { currentUser } = useAuthContext(); - const setModal = useStore((state) => state.setModal); - - const onClick = () => { - posthog.capture('geo_panel_clicked'); - if (!currentUser) { - setModal('signin'); - } else if (currentUser.isPro) { - setModal('geo'); - } else { - setModal('payment'); - } - }; - - const streetGeo = useGeoContext(); - let coordinateInfo = null; - - if (streetGeo) { - coordinateInfo = `Latitude: ${streetGeo.latitude}, Longitude: ${streetGeo.longitude}, Elevation: ${streetGeo.ellipsoidalHeight}m`; - } - - return ( -
- geo - {coordinateInfo ? ( - {coordinateInfo} - ) : ( - Click to set location - )} -
- ); -}; -export { GeoPanel }; diff --git a/src/editor/components/components/GeoPanel/GeoPanel.module.scss b/src/editor/components/components/GeoPanel/GeoPanel.module.scss deleted file mode 100644 index be62c0564..000000000 --- a/src/editor/components/components/GeoPanel/GeoPanel.module.scss +++ /dev/null @@ -1,29 +0,0 @@ -@use '../../../style/variables.scss'; - -.geo { - display: flex; - column-gap: 24px; - position: absolute; - bottom: 32px; - left: 32px; - - & > img { - cursor: pointer; - } - - & > p, - & > a { - margin-top: 8px; - font-size: 16px !important; - max-width: 80vw; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - } - & > a { - filter: brightness(90%); - } - & > a:hover { - filter: brightness(100%); - } -} diff --git a/src/editor/components/components/GeoPanel/index.js b/src/editor/components/components/GeoPanel/index.js deleted file mode 100644 index ddf027699..000000000 --- a/src/editor/components/components/GeoPanel/index.js +++ /dev/null @@ -1 +0,0 @@ -export { GeoPanel } from './GeoPanel.component.jsx'; diff --git a/src/editor/components/components/index.js b/src/editor/components/components/index.js index 31d0f68d6..46fc13f6d 100644 --- a/src/editor/components/components/index.js +++ b/src/editor/components/components/index.js @@ -10,4 +10,3 @@ export { Logo } from './Logo'; export { ProfileButton } from './ProfileButton'; export { SceneCard } from './SceneCard'; export { SceneEditTitle } from './SceneEditTitle'; -export { GeoPanel } from './GeoPanel'; diff --git a/src/editor/components/modals/PaymentModal/PaymentModal.component.jsx b/src/editor/components/modals/PaymentModal/PaymentModal.component.jsx index 8f9a18c63..aa4923a38 100644 --- a/src/editor/components/modals/PaymentModal/PaymentModal.component.jsx +++ b/src/editor/components/modals/PaymentModal/PaymentModal.component.jsx @@ -20,14 +20,23 @@ const getStripe = () => { return stripePromise; }; +const resetPaymentQueryParam = () => { + const newUrl = window.location.href.replace(/\?payment=(success|cancel)/, ''); + window.history.replaceState({}, '', newUrl); +}; + const PaymentModal = () => { const { currentUser } = useAuthContext(); const [isLoading, setIsLoading] = useState(false); const setModal = useStore((state) => state.setModal); const modal = useStore((state) => state.modal); + const postCheckout = useStore((state) => state.postCheckout); + const checkoutSuccess = location.hash.includes('success'); - if (location.hash.includes('success')) { + if (checkoutSuccess) { posthog.capture('checkout_finished'); + } else if (location.hash.includes('cancel')) { + posthog.capture('checkout_canceled'); } const startCheckout = async () => { @@ -63,8 +72,12 @@ const PaymentModal = () => { }; const onClose = () => { - window.location.hash = '#'; - setModal(null); + resetPaymentQueryParam(); + if (checkoutSuccess && postCheckout) { + setModal(postCheckout); + } else { + setModal(null); + } }; return ( @@ -74,11 +87,8 @@ const PaymentModal = () => { onClose={onClose} >
-

Unlock Geospatial Features with a free 30 day trial

-

- Create with geospatial maps and share your vision in augmented reality - with 3DStreet Pro. -

+

Unlock Pro features with a free 30 day trial

+

Create with intersections and geospatial maps.

-
{this.renderEntities()}
+
+ +
{this.renderEntities()}
+
); diff --git a/src/editor/contexts/Auth.context.js b/src/editor/contexts/Auth.context.js index 5d349a147..6ca14de8a 100644 --- a/src/editor/contexts/Auth.context.js +++ b/src/editor/contexts/Auth.context.js @@ -1,7 +1,7 @@ import { createContext, useContext, useEffect, useState } from 'react'; import { auth } from '../services/firebase'; import PropTypes from 'prop-types'; -import { isUserPro, isUserBeta } from '../api/user'; +import { isUserPro } from '../api/user'; import posthog from 'posthog-js'; const AuthContext = createContext({ @@ -23,8 +23,7 @@ const AuthProvider = ({ children }) => { localStorage.setItem('token', await user.getIdToken()); const isPro = await isUserPro(user); - const isBeta = await isUserBeta(user); - const enrichedUser = { ...user, isPro, isBeta }; + const enrichedUser = { ...user, isPro }; posthog.identify(user.uid, { email: user.email, diff --git a/src/store.js b/src/store.js index f5f7b5e18..8da62d955 100644 --- a/src/store.js +++ b/src/store.js @@ -38,6 +38,12 @@ const useStore = create( } set({ modal: newModal }); }, + startCheckout: (postCheckout) => { + posthog.capture('modal_opened', { modal: 'payment' }); + posthog.capture('start_checkout'); + set({ modal: 'payment', postCheckout }); + }, + postCheckout: null, isInspectorEnabled: true, setIsInspectorEnabled: (newIsInspectorEnabled) => { if (newIsInspectorEnabled) {