deploy
This commit is contained in:
parent
273d7a83ee
commit
084117cea8
48 changed files with 2283 additions and 890 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { PostcodeGeometry, Property } from '../../types';
|
||||
import type { MapFlyToOptions, PostcodeGeometry } from '../../types';
|
||||
import type { SearchedLocation } from './LocationSearch';
|
||||
import { useMapData } from '../../hooks/useMapData';
|
||||
import { usePOIData } from '../../hooks/usePOIData';
|
||||
|
|
@ -19,6 +19,7 @@ import { useFilterCounts } from '../../hooks/useFilterCounts';
|
|||
import { trackEvent } from '../../lib/analytics';
|
||||
import { INITIAL_VIEW_STATE, POSTCODE_SEARCH_ZOOM } from '../../lib/consts';
|
||||
import { useLicense } from '../../hooks/useLicense';
|
||||
import { stateToParams } from '../../lib/url-state';
|
||||
import {
|
||||
AreaPane,
|
||||
Filters,
|
||||
|
|
@ -30,7 +31,7 @@ import { PaneFallback } from './map-page/Fallbacks';
|
|||
import { DesktopMapPage } from './map-page/DesktopMapPage';
|
||||
import { MobileMapPage } from './map-page/MobileMapPage';
|
||||
import { ScreenshotMapPage } from './map-page/ScreenshotMapPage';
|
||||
import { BookmarkToast, ExportToast } from './map-page/Toasts';
|
||||
import { ExportToast } from './map-page/Toasts';
|
||||
import { MobileMapLegend } from './map-page/MobileMapLegend';
|
||||
import { useExportController } from './map-page/useExportController';
|
||||
import {
|
||||
|
|
@ -66,6 +67,7 @@ export default function MapPage({
|
|||
onClearPendingInfoFeature,
|
||||
onNavigateTo,
|
||||
onExportStateChange,
|
||||
onDashboardParamsChange,
|
||||
screenshotMode,
|
||||
ogMode,
|
||||
isMobile = false,
|
||||
|
|
@ -75,10 +77,8 @@ export default function MapPage({
|
|||
user,
|
||||
onLoginClick,
|
||||
onRegisterClick,
|
||||
onSaveProperty,
|
||||
onUnsaveProperty,
|
||||
isPropertySaved,
|
||||
getSavedPropertyId,
|
||||
onCheckoutLoginClick,
|
||||
onCheckoutRegisterClick,
|
||||
deferTutorial = false,
|
||||
onSaveSearch,
|
||||
savingSearch,
|
||||
|
|
@ -92,19 +92,6 @@ export default function MapPage({
|
|||
const [mobileBottomSheetHeight, setMobileBottomSheetHeight] = useState(0);
|
||||
const [poiPaneOpen, setPoiPaneOpen] = useState(false);
|
||||
const [currentLocation, setCurrentLocation] = useState<{ lat: number; lng: number } | null>(null);
|
||||
const [showBookmarkToast, setShowBookmarkToast] = useState(false);
|
||||
const bookmarkToastDismissed = useRef(localStorage.getItem('bookmark_toast_dismissed') === '1');
|
||||
|
||||
const handleSavePropertyWithToast = useCallback(
|
||||
(property: Property) => {
|
||||
onSaveProperty?.(property);
|
||||
if (!bookmarkToastDismissed.current) {
|
||||
setShowBookmarkToast(true);
|
||||
bookmarkToastDismissed.current = true;
|
||||
}
|
||||
},
|
||||
[onSaveProperty]
|
||||
);
|
||||
|
||||
const {
|
||||
filters,
|
||||
|
|
@ -155,6 +142,22 @@ export default function MapPage({
|
|||
const pendingLocationSearchFlyToRef = useRef<PendingFlyTo | null>(null);
|
||||
const mobileDrawerPanelRectRef = useRef<DOMRectReadOnly | null>(null);
|
||||
|
||||
const getMobileMapFlyToOptions = useCallback((): MapFlyToOptions | undefined => {
|
||||
if (!isMobile) return undefined;
|
||||
|
||||
const panelRect = mobileDrawerPanelRectRef.current;
|
||||
if (mobileDrawerOpen && panelRect) {
|
||||
const bottomInset = Math.max(0, window.innerHeight - panelRect.top);
|
||||
if (bottomInset > 0) {
|
||||
return { visibleViewportArea: { bottom: bottomInset } };
|
||||
}
|
||||
}
|
||||
|
||||
return mobileBottomSheetHeight > 0
|
||||
? { visibleArea: { bottom: mobileBottomSheetHeight } }
|
||||
: undefined;
|
||||
}, [isMobile, mobileBottomSheetHeight, mobileDrawerOpen]);
|
||||
|
||||
const mapData = useMapData({
|
||||
filters,
|
||||
features,
|
||||
|
|
@ -209,7 +212,8 @@ export default function MapPage({
|
|||
mapFlyToRef.current?.(
|
||||
destination.lat,
|
||||
destination.lon,
|
||||
mapData.currentView?.zoom ?? INITIAL_VIEW_STATE.zoom
|
||||
mapData.currentView?.zoom ?? INITIAL_VIEW_STATE.zoom,
|
||||
getMobileMapFlyToOptions()
|
||||
);
|
||||
}
|
||||
} catch {
|
||||
|
|
@ -220,6 +224,7 @@ export default function MapPage({
|
|||
activeEntries,
|
||||
fetchAiFilters,
|
||||
filters,
|
||||
getMobileMapFlyToOptions,
|
||||
handleSetEntries,
|
||||
handleSetFilters,
|
||||
mapData.currentView?.zoom,
|
||||
|
|
@ -251,17 +256,22 @@ export default function MapPage({
|
|||
[handleDragEndNoCommit, handleTimeRangeChange]
|
||||
);
|
||||
|
||||
const filterCounts = useFilterCounts(filters, features, mapData.bounds, entries);
|
||||
const filterCounts = useFilterCounts(filters, features, mapData.bounds, entries, shareCode);
|
||||
const license = useLicense();
|
||||
|
||||
const handleTravelTimeSetDestination = useCallback(
|
||||
(index: number, slug: string, label: string, lat: number, lon: number) => {
|
||||
handleSetDestination(index, slug, label);
|
||||
if (slug) {
|
||||
mapFlyToRef.current?.(lat, lon, mapData.currentView?.zoom ?? INITIAL_VIEW_STATE.zoom);
|
||||
mapFlyToRef.current?.(
|
||||
lat,
|
||||
lon,
|
||||
mapData.currentView?.zoom ?? INITIAL_VIEW_STATE.zoom,
|
||||
getMobileMapFlyToOptions()
|
||||
);
|
||||
}
|
||||
},
|
||||
[handleSetDestination, mapData.currentView?.zoom]
|
||||
[getMobileMapFlyToOptions, handleSetDestination, mapData.currentView?.zoom]
|
||||
);
|
||||
|
||||
const journeyDest = useJourneyDestination(entries);
|
||||
|
|
@ -430,9 +440,11 @@ export default function MapPage({
|
|||
useScreenshotReadySignal({
|
||||
screenshotMode,
|
||||
loading: mapData.loading,
|
||||
boundsReady: mapData.bounds != null,
|
||||
dataLength: mapData.data.length,
|
||||
postcodeDataLength: mapData.postcodeData.length,
|
||||
usePostcodeView: mapData.usePostcodeView,
|
||||
licenseRequired: mapData.licenseRequired,
|
||||
});
|
||||
|
||||
const handleMobileHexagonClick = useCallback(
|
||||
|
|
@ -462,10 +474,42 @@ export default function MapPage({
|
|||
bounds: mapData.bounds,
|
||||
filters,
|
||||
features,
|
||||
travelTimeEntries: entries,
|
||||
shareCode,
|
||||
t,
|
||||
onExportStateChange,
|
||||
});
|
||||
|
||||
const dashboardParams = useMemo(
|
||||
() =>
|
||||
stateToParams(
|
||||
mapData.currentView,
|
||||
filters,
|
||||
features,
|
||||
selectedPOICategories,
|
||||
rightPaneTab,
|
||||
entries,
|
||||
shareCode
|
||||
).toString(),
|
||||
[
|
||||
entries,
|
||||
features,
|
||||
filters,
|
||||
mapData.currentView,
|
||||
rightPaneTab,
|
||||
selectedPOICategories,
|
||||
shareCode,
|
||||
]
|
||||
);
|
||||
const checkoutReturnPath = useMemo(
|
||||
() => `/dashboard${dashboardParams ? `?${dashboardParams}` : ''}`,
|
||||
[dashboardParams]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
onDashboardParamsChange?.(dashboardParams);
|
||||
}, [dashboardParams, onDashboardParamsChange]);
|
||||
|
||||
useEffect(() => {
|
||||
if (mapData.licenseRequired) trackEvent('Upgrade Modal Shown');
|
||||
}, [mapData.licenseRequired]);
|
||||
|
|
@ -501,6 +545,7 @@ export default function MapPage({
|
|||
statsUseFilters={areaStatsUseFilters}
|
||||
onStatsUseFiltersChange={setAreaStatsUseFilters}
|
||||
travelTimeEntries={activeEntries}
|
||||
shareCode={shareCode}
|
||||
isGroupExpanded={isAreaGroupExpanded}
|
||||
onToggleGroup={toggleAreaGroup}
|
||||
/>
|
||||
|
|
@ -515,10 +560,6 @@ export default function MapPage({
|
|||
loading={loadingProperties}
|
||||
hexagonId={selectedHexagon?.id || null}
|
||||
onLoadMore={handleLoadMoreProperties}
|
||||
onSaveProperty={onSaveProperty ? handleSavePropertyWithToast : undefined}
|
||||
onUnsaveProperty={onUnsaveProperty}
|
||||
isPropertySaved={isPropertySaved}
|
||||
getSavedPropertyId={getSavedPropertyId}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
|
|
@ -589,40 +630,25 @@ export default function MapPage({
|
|||
}
|
||||
};
|
||||
|
||||
const bookmarkToast = (
|
||||
<BookmarkToast
|
||||
show={showBookmarkToast}
|
||||
onViewSaved={() => {
|
||||
setShowBookmarkToast(false);
|
||||
onNavigateTo('saved', 'properties');
|
||||
}}
|
||||
onDismissForever={() => {
|
||||
setShowBookmarkToast(false);
|
||||
localStorage.setItem('bookmark_toast_dismissed', '1');
|
||||
}}
|
||||
/>
|
||||
);
|
||||
const exportToast = (
|
||||
<ExportToast
|
||||
notice={exportNotice}
|
||||
offsetForBookmark={showBookmarkToast}
|
||||
closeLabel={t('common.close')}
|
||||
onClose={clearExportNotice}
|
||||
/>
|
||||
);
|
||||
const toasts = (
|
||||
<>
|
||||
{bookmarkToast}
|
||||
{exportToast}
|
||||
</>
|
||||
);
|
||||
const toasts = exportToast;
|
||||
const upgradeModal = mapData.licenseRequired ? (
|
||||
<Suspense fallback={null}>
|
||||
<UpgradeModal
|
||||
isLoggedIn={!!user}
|
||||
onLoginClick={onLoginClick}
|
||||
onRegisterClick={onRegisterClick}
|
||||
onStartCheckout={() => license.startCheckout()}
|
||||
onLoginClick={() =>
|
||||
onCheckoutLoginClick ? onCheckoutLoginClick(checkoutReturnPath) : onLoginClick()
|
||||
}
|
||||
onRegisterClick={() =>
|
||||
onCheckoutRegisterClick ? onCheckoutRegisterClick(checkoutReturnPath) : onRegisterClick()
|
||||
}
|
||||
onStartCheckout={() => license.startCheckout(checkoutReturnPath)}
|
||||
onZoomToFreeZone={handleZoomToFreeZone}
|
||||
isShareReturn={!!shareReturnViewRef.current}
|
||||
/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue