2022-01-16 05:56:31 +01:00
|
|
|
import { FrontPageItem, GetCatalogIndexComposer, GetCatalogPageComposer, GetClubGiftInfo, GetGiftWrappingConfigurationComposer, GetMarketplaceConfigurationMessageComposer, ILinkEventTracker, RoomPreviewer } from '@nitrots/nitro-renderer';
|
2021-05-05 09:14:54 +02:00
|
|
|
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
2021-08-17 05:38:07 +02:00
|
|
|
import { AddEventLinkTracker, GetRoomEngine, LocalizeText, RemoveLinkEventTracker } from '../../api';
|
2021-11-26 06:16:00 +01:00
|
|
|
import { CREDITS, PlaySound } from '../../api/utils/PlaySound';
|
2021-12-04 07:28:34 +01:00
|
|
|
import { Column } from '../../common/Column';
|
|
|
|
import { Grid } from '../../common/Grid';
|
2021-04-22 05:26:30 +02:00
|
|
|
import { CatalogEvent } from '../../events';
|
2022-01-19 21:34:23 +01:00
|
|
|
import { BatchUpdates } from '../../hooks';
|
2021-04-22 05:26:30 +02:00
|
|
|
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
2021-05-05 09:14:54 +02:00
|
|
|
import { SendMessageHook } from '../../hooks/messages/message-event';
|
2022-01-20 09:03:21 +01:00
|
|
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../layout';
|
2021-04-22 05:26:30 +02:00
|
|
|
import { CatalogMessageHandler } from './CatalogMessageHandler';
|
2022-01-16 05:56:31 +01:00
|
|
|
import { CatalogPage } from './common/CatalogPage';
|
|
|
|
import { CatalogType } from './common/CatalogType';
|
|
|
|
import { ICatalogNode } from './common/ICatalogNode';
|
|
|
|
import { ICatalogPage } from './common/ICatalogPage';
|
|
|
|
import { IPageLocalization } from './common/IPageLocalization';
|
|
|
|
import { IPurchasableOffer } from './common/IPurchasableOffer';
|
|
|
|
import { RequestedPage } from './common/RequestedPage';
|
2022-01-19 21:34:23 +01:00
|
|
|
import { SearchResult } from './common/SearchResult';
|
2021-05-05 09:14:54 +02:00
|
|
|
import { CatalogContextProvider } from './context/CatalogContext';
|
2021-07-28 02:01:37 +02:00
|
|
|
import { CatalogReducer, initialCatalog } from './reducers/CatalogReducer';
|
2021-09-17 08:39:58 +02:00
|
|
|
import { CatalogGiftView } from './views/gift/CatalogGiftView';
|
2022-01-16 05:56:31 +01:00
|
|
|
import { CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
2021-05-05 09:14:54 +02:00
|
|
|
import { CatalogPageView } from './views/page/CatalogPageView';
|
2022-01-06 07:32:44 +01:00
|
|
|
import { MarketplacePostOfferView } from './views/page/layout/marketplace/MarketplacePostOfferView';
|
2022-01-16 05:56:31 +01:00
|
|
|
|
|
|
|
const DUMMY_PAGE_ID_FOR_OFFER_SEARCH: number = -12345678;
|
2022-01-19 08:22:30 +01:00
|
|
|
const REQUESTED_PAGE = new RequestedPage();
|
2021-04-22 05:26:30 +02:00
|
|
|
|
2022-01-06 04:07:33 +01:00
|
|
|
export const CatalogView: FC<{}> = props =>
|
2021-04-22 05:26:30 +02:00
|
|
|
{
|
|
|
|
const [ isVisible, setIsVisible ] = useState(false);
|
2022-01-20 09:03:21 +01:00
|
|
|
|
2022-01-16 05:56:31 +01:00
|
|
|
const [ isBusy, setIsBusy ] = useState(false);
|
|
|
|
const [ forceRefresh, setForceRefresh ] = useState(false);
|
|
|
|
const [ pageId, setPageId ] = useState(-1);
|
|
|
|
const [ previousPageId, setPreviousPageId ] = useState(-1);
|
|
|
|
const [ currentType, setCurrentType ] = useState(CatalogType.NORMAL);
|
2022-01-19 00:12:48 +01:00
|
|
|
const [ rootNode, setRootNode ] = useState<ICatalogNode>(null);
|
2022-01-20 09:03:21 +01:00
|
|
|
const [ offersToNodes, setOffersToNodes ] = useState<Map<number, ICatalogNode[]>>(null);
|
2022-01-16 05:56:31 +01:00
|
|
|
const [ currentPage, setCurrentPage ] = useState<ICatalogPage>(null);
|
|
|
|
const [ currentOffer, setCurrentOffer ] = useState<IPurchasableOffer>(null);
|
|
|
|
const [ purchasableOffer, setPurchasableOffer ] = useState<IPurchasableOffer>(null);
|
|
|
|
const [ currentTab, setCurrentTab ] = useState<ICatalogNode>(null);
|
|
|
|
const [ activeNodes, setActiveNodes ] = useState<ICatalogNode[]>([]);
|
2022-01-19 21:34:23 +01:00
|
|
|
const [ searchResult, setSearchResult ] = useState<SearchResult>(null);
|
2022-01-16 05:56:31 +01:00
|
|
|
const [ frontPageItems, setFrontPageItems ] = useState<FrontPageItem[]>([]);
|
2021-05-10 19:11:16 +02:00
|
|
|
const [ roomPreviewer, setRoomPreviewer ] = useState<RoomPreviewer>(null);
|
2021-05-05 09:14:54 +02:00
|
|
|
const [ catalogState, dispatchCatalogState ] = useReducer(CatalogReducer, initialCatalog);
|
2021-04-22 05:26:30 +02:00
|
|
|
|
2022-01-19 00:12:48 +01:00
|
|
|
const resetState = useCallback(() =>
|
|
|
|
{
|
|
|
|
BatchUpdates(() =>
|
|
|
|
{
|
|
|
|
setPageId(-1);
|
|
|
|
setPreviousPageId(-1);
|
|
|
|
setRootNode(null);
|
2022-01-20 09:03:21 +01:00
|
|
|
setOffersToNodes(null);
|
2022-01-19 00:12:48 +01:00
|
|
|
setCurrentPage(null);
|
|
|
|
setCurrentOffer(null);
|
|
|
|
setPurchasableOffer(null);
|
|
|
|
setCurrentTab(null);
|
|
|
|
setActiveNodes([]);
|
2022-01-19 21:34:23 +01:00
|
|
|
setSearchResult(null);
|
2022-01-19 00:12:48 +01:00
|
|
|
setFrontPageItems([]);
|
|
|
|
setIsVisible(true);
|
|
|
|
});
|
|
|
|
}, []);
|
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
const getNodesByOfferId = useCallback((offerId: number, flag: boolean = false) =>
|
|
|
|
{
|
|
|
|
if(!offersToNodes || !offersToNodes.size) return null;
|
|
|
|
|
|
|
|
if(flag)
|
|
|
|
{
|
|
|
|
const nodes: ICatalogNode[] = [];
|
|
|
|
const offers = offersToNodes.get(offerId);
|
|
|
|
|
|
|
|
if(offers && offers.length) for(const offer of offers) (offer.isVisible && nodes.push(offer));
|
|
|
|
|
|
|
|
if(nodes.length) return nodes;
|
|
|
|
}
|
|
|
|
|
|
|
|
return offersToNodes.get(offerId);
|
|
|
|
}, [ offersToNodes ]);
|
|
|
|
|
2022-01-19 08:22:30 +01:00
|
|
|
const loadCatalogPage = useCallback((pageId: number, offerId: number) =>
|
2022-01-16 05:56:31 +01:00
|
|
|
{
|
|
|
|
if(pageId < 0) return;
|
|
|
|
|
|
|
|
BatchUpdates(() =>
|
|
|
|
{
|
|
|
|
setIsBusy(true);
|
|
|
|
setPageId(pageId);
|
|
|
|
});
|
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
if(pageId > -1) SendMessageHook(new GetCatalogPageComposer(pageId, offerId, currentType));
|
2022-01-16 05:56:31 +01:00
|
|
|
}, [ currentType ]);
|
|
|
|
|
|
|
|
const selectOffer = useCallback((offerId: number) =>
|
2021-07-29 08:03:30 +02:00
|
|
|
{
|
2022-01-19 21:34:23 +01:00
|
|
|
if(!currentPage || !currentPage.offers || offerId < 0) return;
|
2022-01-16 05:56:31 +01:00
|
|
|
|
2022-01-19 21:34:23 +01:00
|
|
|
for(const offer of currentPage.offers)
|
|
|
|
{
|
|
|
|
if(offer.offerId !== offerId) continue;
|
|
|
|
|
|
|
|
setCurrentOffer(offer)
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}, [ currentPage ]);
|
2021-07-29 08:03:30 +02:00
|
|
|
|
2022-01-16 05:56:31 +01:00
|
|
|
const showCatalogPage = useCallback((pageId: number, layoutCode: string, localization: IPageLocalization, offers: IPurchasableOffer[], offerId: number, acceptSeasonCurrencyAsCredits: boolean) =>
|
|
|
|
{
|
|
|
|
if(currentPage)
|
|
|
|
{
|
|
|
|
if(!forceRefresh && (currentPage.pageId === pageId))
|
|
|
|
{
|
|
|
|
if(offerId > -1) selectOffer(offerId);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const catalogPage = (new CatalogPage(pageId, layoutCode, localization, offers, acceptSeasonCurrencyAsCredits) as ICatalogPage);
|
|
|
|
|
|
|
|
BatchUpdates(() =>
|
|
|
|
{
|
|
|
|
setCurrentPage(catalogPage);
|
|
|
|
setPreviousPageId(prevValue => ((pageId > DUMMY_PAGE_ID_FOR_OFFER_SEARCH) ? pageId : prevValue));
|
|
|
|
setForceRefresh(false);
|
|
|
|
|
|
|
|
selectOffer(offerId);
|
|
|
|
});
|
|
|
|
}, [ currentPage, forceRefresh, selectOffer ]);
|
|
|
|
|
2022-01-19 21:34:23 +01:00
|
|
|
const activateNode = useCallback((targetNode: ICatalogNode, offerId: number = -1) =>
|
2022-01-19 00:12:48 +01:00
|
|
|
{
|
2022-01-20 09:03:21 +01:00
|
|
|
if(targetNode.parent.pageName === 'root')
|
|
|
|
{
|
|
|
|
if(targetNode.children.length)
|
|
|
|
{
|
|
|
|
for(const child of targetNode.children)
|
|
|
|
{
|
|
|
|
if(!child.isVisible) continue;
|
|
|
|
|
|
|
|
targetNode = child;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const nodes: ICatalogNode[] = [];
|
|
|
|
|
|
|
|
let node = targetNode;
|
|
|
|
|
|
|
|
while(node && node.pageName !== 'root')
|
|
|
|
{
|
|
|
|
nodes.push(node);
|
|
|
|
|
|
|
|
node = node.parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
nodes.reverse();
|
|
|
|
|
2022-01-19 00:12:48 +01:00
|
|
|
setActiveNodes(prevValue =>
|
|
|
|
{
|
|
|
|
const isActive = (prevValue.indexOf(targetNode) >= 0);
|
|
|
|
const isOpen = targetNode.isOpen;
|
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
for(const existing of prevValue)
|
2022-01-19 00:12:48 +01:00
|
|
|
{
|
2022-01-20 09:03:21 +01:00
|
|
|
existing.deactivate();
|
2022-01-19 00:12:48 +01:00
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
if(nodes.indexOf(existing) === -1) existing.close();
|
2022-01-19 00:12:48 +01:00
|
|
|
}
|
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
for(const n of nodes)
|
|
|
|
{
|
|
|
|
n.activate();
|
|
|
|
|
|
|
|
if(n === targetNode.parent) n.open();
|
|
|
|
}
|
2022-01-19 00:12:48 +01:00
|
|
|
|
|
|
|
if(isActive && isOpen) targetNode.close();
|
|
|
|
else targetNode.open();
|
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
return nodes;
|
2022-01-19 00:12:48 +01:00
|
|
|
});
|
|
|
|
|
2022-01-19 21:34:23 +01:00
|
|
|
if(targetNode.pageId > -1) loadCatalogPage(targetNode.pageId, offerId);
|
2022-01-19 00:12:48 +01:00
|
|
|
}, [ setActiveNodes, loadCatalogPage ]);
|
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
const openPageByOfferId = useCallback((offerId: number) =>
|
|
|
|
{
|
|
|
|
BatchUpdates(() =>
|
|
|
|
{
|
|
|
|
setSearchResult(null);
|
|
|
|
|
|
|
|
if(!isVisible)
|
|
|
|
{
|
|
|
|
REQUESTED_PAGE.requestedByOfferId = offerId;
|
|
|
|
|
|
|
|
setIsVisible(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const nodes = getNodesByOfferId(offerId);
|
|
|
|
|
|
|
|
if(!nodes || !nodes.length) return;
|
|
|
|
|
|
|
|
activateNode(nodes[0], offerId);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}, [ isVisible, getNodesByOfferId, activateNode ]);
|
|
|
|
|
2021-04-22 05:26:30 +02:00
|
|
|
const onCatalogEvent = useCallback((event: CatalogEvent) =>
|
|
|
|
{
|
|
|
|
switch(event.type)
|
|
|
|
{
|
2021-11-26 04:32:51 +01:00
|
|
|
case CatalogEvent.PURCHASE_SUCCESS:
|
2021-11-26 06:16:00 +01:00
|
|
|
PlaySound(CREDITS);
|
2021-11-26 04:32:51 +01:00
|
|
|
return;
|
2021-04-22 05:26:30 +02:00
|
|
|
}
|
2022-01-16 05:56:31 +01:00
|
|
|
}, []);
|
2021-04-22 05:26:30 +02:00
|
|
|
|
2021-11-26 04:32:51 +01:00
|
|
|
useUiEvent(CatalogEvent.PURCHASE_SUCCESS, onCatalogEvent);
|
2021-04-22 05:26:30 +02:00
|
|
|
|
2021-07-23 07:04:12 +02:00
|
|
|
const linkReceived = useCallback((url: string) =>
|
|
|
|
{
|
|
|
|
const parts = url.split('/');
|
|
|
|
|
|
|
|
if(parts.length < 2) return;
|
|
|
|
|
|
|
|
switch(parts[1])
|
|
|
|
{
|
2022-01-19 21:34:23 +01:00
|
|
|
case 'show':
|
|
|
|
setIsVisible(true);
|
|
|
|
return;
|
|
|
|
case 'hide':
|
|
|
|
setIsVisible(false);
|
|
|
|
return;
|
|
|
|
case 'toggle':
|
|
|
|
setIsVisible(prevValue => !prevValue);
|
|
|
|
return;
|
2021-07-23 07:04:12 +02:00
|
|
|
case 'open':
|
|
|
|
if(parts.length > 2)
|
|
|
|
{
|
2021-07-29 02:13:40 +02:00
|
|
|
if(parts.length === 4)
|
|
|
|
{
|
|
|
|
switch(parts[2])
|
|
|
|
{
|
|
|
|
case 'offerId':
|
2022-01-20 09:03:21 +01:00
|
|
|
openPageByOfferId(parseInt(parts[3]));
|
2021-07-29 02:13:40 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-07-23 07:04:12 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setIsVisible(true);
|
|
|
|
}
|
2021-07-29 02:13:40 +02:00
|
|
|
|
2021-07-23 07:04:12 +02:00
|
|
|
return;
|
|
|
|
}
|
2022-01-20 09:03:21 +01:00
|
|
|
}, [ openPageByOfferId ]);
|
2021-07-23 07:04:12 +02:00
|
|
|
|
|
|
|
useEffect(() =>
|
|
|
|
{
|
|
|
|
const linkTracker: ILinkEventTracker = {
|
|
|
|
linkReceived,
|
|
|
|
eventUrlPrefix: 'catalog/'
|
|
|
|
};
|
|
|
|
|
|
|
|
AddEventLinkTracker(linkTracker);
|
|
|
|
|
|
|
|
return () => RemoveLinkEventTracker(linkTracker);
|
2021-07-29 08:03:30 +02:00
|
|
|
}, [ linkReceived ]);
|
2021-07-23 07:04:12 +02:00
|
|
|
|
2021-05-05 09:14:54 +02:00
|
|
|
useEffect(() =>
|
2021-04-22 05:26:30 +02:00
|
|
|
{
|
2022-01-16 05:56:31 +01:00
|
|
|
setRoomPreviewer(new RoomPreviewer(GetRoomEngine(), ++RoomPreviewer.PREVIEW_COUNTER));
|
2021-07-23 19:23:31 +02:00
|
|
|
|
2022-01-16 05:56:31 +01:00
|
|
|
return () =>
|
2021-05-05 09:14:54 +02:00
|
|
|
{
|
2022-01-16 05:56:31 +01:00
|
|
|
setRoomPreviewer(prevValue =>
|
|
|
|
{
|
|
|
|
prevValue.dispose();
|
2021-07-28 02:01:37 +02:00
|
|
|
|
2022-01-16 05:56:31 +01:00
|
|
|
return null;
|
|
|
|
});
|
2021-05-05 09:14:54 +02:00
|
|
|
}
|
2022-01-16 05:56:31 +01:00
|
|
|
}, []);
|
2021-07-23 07:04:12 +02:00
|
|
|
|
2022-01-16 05:56:31 +01:00
|
|
|
useEffect(() =>
|
|
|
|
{
|
2022-01-20 09:03:21 +01:00
|
|
|
if(!isVisible || rootNode) return;
|
2022-01-19 00:12:48 +01:00
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
SendMessageHook(new GetMarketplaceConfigurationMessageComposer());
|
|
|
|
SendMessageHook(new GetGiftWrappingConfigurationComposer());
|
|
|
|
SendMessageHook(new GetClubGiftInfo());
|
|
|
|
SendMessageHook(new GetCatalogIndexComposer(currentType));
|
|
|
|
}, [ isVisible, rootNode, currentType ]);
|
2022-01-19 00:12:48 +01:00
|
|
|
|
|
|
|
useEffect(() =>
|
|
|
|
{
|
2022-01-20 09:03:21 +01:00
|
|
|
if(!isVisible || !rootNode) return;
|
2022-01-19 00:12:48 +01:00
|
|
|
|
2022-01-19 08:22:30 +01:00
|
|
|
switch(REQUESTED_PAGE.requestType)
|
|
|
|
{
|
|
|
|
case RequestedPage.REQUEST_TYPE_NONE:
|
2022-01-20 09:03:21 +01:00
|
|
|
if(activeNodes && activeNodes.length) return;
|
2022-01-19 08:22:30 +01:00
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
if(rootNode.isBranch)
|
|
|
|
{
|
|
|
|
for(const child of rootNode.children)
|
2022-01-19 00:12:48 +01:00
|
|
|
{
|
2022-01-20 09:03:21 +01:00
|
|
|
if(child && child.isVisible)
|
2022-01-19 08:22:30 +01:00
|
|
|
{
|
2022-01-20 09:03:21 +01:00
|
|
|
activateNode(child);
|
2022-01-19 00:12:48 +01:00
|
|
|
|
2022-01-20 09:03:21 +01:00
|
|
|
return;
|
2022-01-19 08:22:30 +01:00
|
|
|
}
|
2022-01-19 00:12:48 +01:00
|
|
|
}
|
2022-01-20 09:03:21 +01:00
|
|
|
}
|
2022-01-19 08:22:30 +01:00
|
|
|
return;
|
2022-01-16 05:56:31 +01:00
|
|
|
case RequestedPage.REQUEST_TYPE_ID:
|
2022-01-19 08:22:30 +01:00
|
|
|
REQUESTED_PAGE.resetRequest();
|
2021-07-23 19:23:31 +02:00
|
|
|
return;
|
2022-01-20 09:03:21 +01:00
|
|
|
case RequestedPage.REQUEST_TYPE_OFFER:
|
|
|
|
openPageByOfferId(REQUESTED_PAGE.requestedByOfferId);
|
2022-01-19 08:22:30 +01:00
|
|
|
REQUESTED_PAGE.resetRequest();
|
2022-01-16 05:56:31 +01:00
|
|
|
return;
|
2022-01-20 09:03:21 +01:00
|
|
|
case RequestedPage.REQUEST_TYPE_NAME:
|
|
|
|
REQUESTED_PAGE.resetRequest();
|
2022-01-19 00:12:48 +01:00
|
|
|
return;
|
|
|
|
}
|
2022-01-20 09:03:21 +01:00
|
|
|
}, [ isVisible, rootNode, activeNodes, activateNode, openPageByOfferId ]);
|
2021-05-10 19:11:16 +02:00
|
|
|
|
2021-06-12 04:53:56 +02:00
|
|
|
useEffect(() =>
|
|
|
|
{
|
2022-01-16 05:56:31 +01:00
|
|
|
if(!currentPage) return;
|
2021-06-12 04:53:56 +02:00
|
|
|
|
2022-01-16 05:56:31 +01:00
|
|
|
setCurrentOffer(null);
|
|
|
|
}, [ currentPage ]);
|
2021-06-12 04:53:56 +02:00
|
|
|
|
2021-04-22 05:26:30 +02:00
|
|
|
return (
|
2022-01-20 09:03:21 +01:00
|
|
|
<CatalogContextProvider value={ { isVisible, isBusy, setIsBusy, pageId, currentType, setCurrentType, rootNode, setRootNode, currentOffers: offersToNodes, setCurrentOffers: setOffersToNodes, currentPage, setCurrentPage, currentOffer, setCurrentOffer, purchasableOffer, setPurchasableOffer, activeNodes, setActiveNodes, searchResult, setSearchResult, frontPageItems, setFrontPageItems, roomPreviewer, resetState, loadCatalogPage, showCatalogPage, activateNode, catalogState, dispatchCatalogState } }>
|
2021-06-12 04:53:56 +02:00
|
|
|
<CatalogMessageHandler />
|
2021-05-05 09:14:54 +02:00
|
|
|
{ isVisible &&
|
2021-08-09 18:15:08 +02:00
|
|
|
<NitroCardView uniqueKey="catalog" className="nitro-catalog">
|
2022-01-16 05:56:31 +01:00
|
|
|
<NitroCardHeaderView headerText={ LocalizeText('catalog.title') } onCloseClick={ event => { setIsVisible(false); } } />
|
2021-05-05 09:14:54 +02:00
|
|
|
<NitroCardTabsView>
|
2022-01-20 09:03:21 +01:00
|
|
|
{ rootNode && (rootNode.children.length > 0) && rootNode.children.map(child =>
|
|
|
|
{
|
|
|
|
if(!child.isVisible) return null;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<NitroCardTabsItemView key={ child.pageId } isActive={ child.isActive } onClick={ event =>
|
|
|
|
{
|
|
|
|
if(searchResult) setSearchResult(null);
|
|
|
|
|
|
|
|
activateNode(child);
|
|
|
|
} }>
|
|
|
|
{ child.localization }
|
|
|
|
</NitroCardTabsItemView>
|
|
|
|
);
|
|
|
|
}) }
|
2021-05-05 09:14:54 +02:00
|
|
|
</NitroCardTabsView>
|
|
|
|
<NitroCardContentView>
|
2021-12-04 07:28:34 +01:00
|
|
|
<Grid>
|
2022-01-16 05:56:31 +01:00
|
|
|
<Column size={ 3 } overflow="hidden">
|
2022-01-20 09:03:21 +01:00
|
|
|
{ activeNodes && (activeNodes.length > 0) &&
|
|
|
|
<CatalogNavigationView node={ activeNodes[0] } /> }
|
2022-01-16 05:56:31 +01:00
|
|
|
</Column>
|
|
|
|
<Column size={ 9 } overflow="hidden">
|
|
|
|
<CatalogPageView page={ currentPage } roomPreviewer={ roomPreviewer } />
|
2021-12-04 07:28:34 +01:00
|
|
|
</Column>
|
|
|
|
</Grid>
|
2021-05-05 09:14:54 +02:00
|
|
|
</NitroCardContentView>
|
|
|
|
</NitroCardView> }
|
2021-09-17 08:39:58 +02:00
|
|
|
<CatalogGiftView />
|
2021-12-23 02:48:01 +01:00
|
|
|
<MarketplacePostOfferView />
|
2021-05-05 09:14:54 +02:00
|
|
|
</CatalogContextProvider>
|
2021-04-22 05:26:30 +02:00
|
|
|
);
|
|
|
|
}
|