Files
Nitro-V3/src/components/catalog/views/page/layout/CatalogLayoutRoomAdsView.tsx
T
simoleo89 1d580e6d24 refactor(navigator): migrate all 13 consumers off useNavigator god-hook
Mechanical swap to the new filter hooks landed in the previous commits:
- NavigatorDoorStateView -> useDoorState (snapshot/setSnapshot/reset)
- NavigatorView -> useNavigatorData + useNavigatorUiState +
  useNavigatorActions + direct useNavigatorUiStore.getState() in handlers
  (linkTracker collapsed to a dispatch table; 9 useState gone)
- NavigatorSearchView -> useNavigatorData + useNavigatorActions
  (sendSearch prop drilling removed)
- NavigatorSearchResultItemView -> useDoorState (setSnapshot aliased as
  setDoorData; call sites unchanged - DoorStateSnapshot is compatible)
- 9 bulk consumers (one-line import swap) -> useNavigatorData

Zero behavioural change intended. yarn typecheck + yarn test --run +
yarn lint:hooks all clean on this commit.
2026-05-27 18:58:03 +02:00

121 lines
5.5 KiB
TypeScript

import { GetRoomAdPurchaseInfoComposer, GetUserEventCatsMessageComposer, PurchaseRoomAdMessageComposer, RoomAdPurchaseInfoEvent, RoomEntryData } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { LocalizeText, SendMessageComposer } from '../../../../../api';
import { useNitroQuery } from '../../../../../api/nitro-query';
import { Button, Column, Text } from '../../../../../common';
import { useCatalogUiState, useNavigatorData, useRoomPromote } from '../../../../../hooks';
import { NitroInput } from '../../../../../layout';
import { CatalogLayoutProps } from './CatalogLayout.types';
let isPurchasingAd = false;
export const CatalogLayoutRoomAdsView: FC<CatalogLayoutProps> = props =>
{
const { page = null } = props;
const [ eventName, setEventName ] = useState<string>('');
const [ eventDesc, setEventDesc ] = useState<string>('');
const [ roomId, setRoomId ] = useState<number>(-1);
const [ extended, setExtended ] = useState<boolean>(false);
const [ categoryId, setCategoryId ] = useState<number>(1);
const { categories } = useNavigatorData();
const { setIsVisible = null } = useCatalogUiState();
const { promoteInformation, isExtended, setIsExtended } = useRoomPromote();
const { data: availableRooms = [] } = useNitroQuery<RoomAdPurchaseInfoEvent, RoomEntryData[]>({
key: [ 'nitro', 'catalog', 'room-ad-purchase-info' ],
request: () => new GetRoomAdPurchaseInfoComposer(),
parser: RoomAdPurchaseInfoEvent,
select: e => e.getParser()?.rooms ?? [],
staleTime: 60_000
});
useEffect(() =>
{
if(isExtended)
{
setRoomId(promoteInformation.data.flatId);
setEventName(promoteInformation.data.eventName);
setEventDesc(promoteInformation.data.eventDescription);
setCategoryId(promoteInformation.data.categoryId);
setExtended(isExtended); // This is for sending to packet
setIsExtended(false); // This is from hook useRoomPromotte
}
}, [ isExtended, eventName, eventDesc, categoryId, promoteInformation.data, setIsExtended ]);
const resetData = () =>
{
setRoomId(-1);
setEventName('');
setEventDesc('');
setCategoryId(1);
setIsExtended(false);
setIsVisible(false);
};
const purchaseAd = () =>
{
if(isPurchasingAd) return;
isPurchasingAd = true;
const pageId = page.pageId;
const offerId = page.offers.length >= 1 ? page.offers[0].offerId : -1;
const flatId = roomId;
const name = eventName;
const desc = eventDesc;
const catId = categoryId;
SendMessageComposer(new PurchaseRoomAdMessageComposer(pageId, offerId, flatId, name, extended, desc, catId));
resetData();
};
useEffect(() =>
{
// TODO: someone needs to fix this for morningstar
SendMessageComposer(new GetUserEventCatsMessageComposer());
}, []);
return (<>
<Text bold center>{ LocalizeText('roomad.catalog_header') }</Text>
<Column className="text-black" overflow="hidden" size={ 12 }>
<div>{ LocalizeText('roomad.catalog_text', [ 'duration' ], [ '120' ]) }</div>
<div className="p-1 rounded bg-muted">
<Column gap={ 2 }>
<Text bold>{ LocalizeText('navigator.category') }</Text>
<select className="form-select form-select-sm" disabled={ extended } value={ categoryId } onChange={ event => setCategoryId(parseInt(event.target.value)) }>
{ categories && categories.map((cat, index) => <option key={ index } value={ cat.id }>{ LocalizeText(cat.name) }</option>) }
</select>
</Column>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('roomad.catalog_name') }</Text>
<NitroInput maxLength={ 64 } readOnly={ extended } value={ eventName } onChange={ event => setEventName(event.target.value) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('roomad.catalog_description') }</Text>
<textarea className="min-h-[calc(1.5em+ .5rem+2px)] px-[.5rem] py-[.25rem] rounded-[.2rem] form-control-sm" maxLength={ 64 } readOnly={ extended } value={ eventDesc } onChange={ event => setEventDesc(event.target.value) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('roomad.catalog_roomname') }</Text>
<select className="form-select form-select-sm" disabled={ extended } value={ roomId } onChange={ event => setRoomId(parseInt(event.target.value)) }>
<option disabled value={ -1 }>{ LocalizeText('roomad.catalog_roomname') }</option>
{ availableRooms && availableRooms.map((room, index) => <option key={ index } value={ room.roomId }>{ room.roomName }</option>) }
</select>
</div>
<div className="flex flex-col gap-1">
<Button disabled={ (!eventName || !eventDesc || roomId === -1) } variant={ (!eventName || !eventDesc || roomId === -1) ? 'danger' : 'success' } onClick={ purchaseAd }>{ extended ? LocalizeText('roomad.extend.event') : LocalizeText('buy') }</Button>
</div>
</div>
</Column>
</>
);
};
interface INavigatorCategory
{
id: number;
name: string;
visible: boolean;
}