mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-19 05:46:27 +01:00
Start navigator changes
This commit is contained in:
parent
35efd87188
commit
37c53ff062
@ -59,6 +59,11 @@ $nitropedia-height: 400px;
|
||||
$messenger-width: 500px;
|
||||
$messenger-height: 370px;
|
||||
|
||||
$marketplace-post-offer-width: 430px;
|
||||
$marketplace-post-offer-height: 250px;
|
||||
|
||||
$room-info-width: 325px;
|
||||
|
||||
.nitro-app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -2,4 +2,5 @@
|
||||
@import './avatar-editor/AvatarEditorView';
|
||||
@import './catalog/CatalogView';
|
||||
@import './inventory/InventoryView';
|
||||
@import './navigator/NavigatorView';
|
||||
@import './toolbar/ToolbarView';
|
||||
|
@ -4,7 +4,7 @@ import classNames from 'classnames';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetConfiguration, GetSessionDataManager, LocalizeText } from '../../../../api';
|
||||
import { SendMessageHook } from '../../../../hooks/messages';
|
||||
import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
|
||||
import { CurrencyIcon } from '../../../../views/shared/currency-icon/CurrencyIcon';
|
||||
import { useNavigatorContext } from '../../context/NavigatorContext';
|
||||
import { NavigatorRoomCreatorViewProps, NAVIGATOR_ROOM_MODELS } from './NavigatorRoomCreatorView.types';
|
||||
|
@ -1,5 +1,7 @@
|
||||
.nitro-room-info {
|
||||
width: 250px;
|
||||
width: $room-info-width;
|
||||
max-height: 300px;
|
||||
|
||||
|
||||
.gray {
|
||||
filter: grayscale(1);
|
||||
@ -10,12 +12,8 @@
|
||||
position: relative;
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
margin: 0 auto;
|
||||
background-image: url(../../../../assets/images/navigator/thumbnail_placeholder.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background: url("../../../../assets/images/navigator/thumbnail_placeholder.png") no-repeat center;
|
||||
background-color: rgba($black, .125);
|
||||
border-color: $black !important;
|
||||
}
|
||||
|
||||
.group-badge {
|
@ -0,0 +1,203 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, SecurityLevel, UserHomeRoomComposer } from '@nitrots/nitro-renderer';
|
||||
import classNames from 'classnames';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetConfiguration, GetGroupInformation, GetSessionDataManager, LocalizeText } from '../../../../api';
|
||||
import { Button } from '../../../../common/Button';
|
||||
import { Column } from '../../../../common/Column';
|
||||
import { Flex } from '../../../../common/Flex';
|
||||
import { Grid } from '../../../../common/Grid';
|
||||
import { Text } from '../../../../common/Text';
|
||||
import { NavigatorEvent } from '../../../../events';
|
||||
import { FloorplanEditorEvent } from '../../../../events/floorplan-editor/FloorplanEditorEvent';
|
||||
import { RoomWidgetThumbnailEvent } from '../../../../events/room-widgets/thumbnail';
|
||||
import { BatchUpdates } from '../../../../hooks';
|
||||
import { dispatchUiEvent } from '../../../../hooks/events';
|
||||
import { SendMessageHook } from '../../../../hooks/messages';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, UserProfileIconView } from '../../../../layout';
|
||||
import { RoomThumbnailView } from '../../../../layout/room-thumbnail/RoomThumbnailView';
|
||||
import { BadgeImageView } from '../../../../views/shared/badge-image/BadgeImageView';
|
||||
import { useNavigatorContext } from '../../context/NavigatorContext';
|
||||
import { NavigatorActions } from '../../reducers/NavigatorReducer';
|
||||
|
||||
export class NavigatorRoomInfoViewProps
|
||||
{
|
||||
onCloseClick: () => void;
|
||||
}
|
||||
|
||||
export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
||||
{
|
||||
const { onCloseClick = null } = props;
|
||||
const [ roomThumbnail, setRoomThumbnail ] = useState(null);
|
||||
const [ isRoomPicked, setIsRoomPicked ] = useState(false);
|
||||
const [ isRoomMuted, setIsRoomMuted ] = useState(false);
|
||||
const { navigatorState = null, dispatchNavigatorState = null } = useNavigatorContext();
|
||||
const { roomInfoData = null, homeRoomId = null } = navigatorState;
|
||||
|
||||
const hasPermission = (permission: string) =>
|
||||
{
|
||||
switch(permission)
|
||||
{
|
||||
case 'settings':
|
||||
return GetSessionDataManager().securityLevel >= SecurityLevel.MODERATOR || roomInfoData.currentRoomOwner;
|
||||
case 'staff_pick':
|
||||
return GetSessionDataManager().securityLevel >= SecurityLevel.COMMUNITY;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
const processAction = useCallback((action: string, value?: string) =>
|
||||
{
|
||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case 'set_home_room':
|
||||
let newRoomId = -1;
|
||||
|
||||
if(homeRoomId !== roomInfoData.enteredGuestRoom.roomId)
|
||||
{
|
||||
newRoomId = roomInfoData.enteredGuestRoom.roomId;
|
||||
}
|
||||
|
||||
dispatchNavigatorState({
|
||||
type: NavigatorActions.SET_HOME_ROOM_ID,
|
||||
payload: {
|
||||
homeRoomId: newRoomId
|
||||
}
|
||||
});
|
||||
|
||||
SendMessageHook(new UserHomeRoomComposer(newRoomId));
|
||||
return;
|
||||
case 'navigator_search_tag':
|
||||
return;
|
||||
case 'open_room_thumbnail_camera':
|
||||
dispatchUiEvent(new RoomWidgetThumbnailEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL));
|
||||
return;
|
||||
case 'open_group_info':
|
||||
GetGroupInformation(roomInfoData.enteredGuestRoom.habboGroupId);
|
||||
return;
|
||||
case 'toggle_room_link':
|
||||
dispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK));
|
||||
return;
|
||||
case 'open_room_settings':
|
||||
SendMessageHook(new RoomSettingsComposer(roomInfoData.enteredGuestRoom.roomId));
|
||||
return;
|
||||
case 'toggle_pick':
|
||||
setIsRoomPicked(value => !value);
|
||||
SendMessageHook(new RoomStaffPickComposer(roomInfoData.enteredGuestRoom.roomId));
|
||||
return;
|
||||
case 'toggle_mute':
|
||||
setIsRoomMuted(value => !value);
|
||||
SendMessageHook(new RoomMuteComposer());
|
||||
return;
|
||||
case 'open_floorplan_editor':
|
||||
dispatchUiEvent(new FloorplanEditorEvent(FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR));
|
||||
return;
|
||||
case 'close':
|
||||
onCloseClick();
|
||||
return;
|
||||
}
|
||||
|
||||
}, [ onCloseClick, dispatchNavigatorState, roomInfoData, homeRoomId ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
||||
|
||||
let thumbnailUrl: string = null;
|
||||
|
||||
if(roomInfoData.enteredGuestRoom.officialRoomPicRef)
|
||||
{
|
||||
thumbnailUrl = (GetConfiguration<string>('image.library.url') + roomInfoData.enteredGuestRoom.officialRoomPicRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
thumbnailUrl = (GetConfiguration<string>('thumbnails.url').replace('%thumbnail%', roomInfoData.enteredGuestRoom.roomId.toString()));
|
||||
}
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setRoomThumbnail(thumbnailUrl);
|
||||
setIsRoomPicked(roomInfoData.enteredGuestRoom.roomPicker);
|
||||
setIsRoomMuted(roomInfoData.enteredGuestRoom.allInRoomMuted);
|
||||
});
|
||||
}, [ roomInfoData ]);
|
||||
|
||||
if(!roomInfoData) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-room-info" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.roomsettings.roominfo') } onCloseClick={ () => processAction('close') } />
|
||||
<NitroCardContentView className="text-black">
|
||||
{ roomInfoData.enteredGuestRoom &&
|
||||
<>
|
||||
<Flex gap={ 2 } overflow="hidden">
|
||||
<Flex center>
|
||||
<RoomThumbnailView customUrl={ roomInfoData.enteredGuestRoom.officialRoomPicRef }>
|
||||
{ hasPermission('settings') && <i className="icon icon-camera-small position-absolute b-0 r-0 m-1 cursor-pointer" onClick={ () => processAction('open_room_thumbnail_camera') } /> }
|
||||
</RoomThumbnailView>
|
||||
</Flex>
|
||||
<Column grow gap={ 1 } overflow="hidden">
|
||||
<Flex gap={ 1 }>
|
||||
<Column grow gap={ 1 }>
|
||||
<Text bold>{ roomInfoData.enteredGuestRoom.roomName }</Text>
|
||||
{ roomInfoData.enteredGuestRoom.showOwner &&
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text variant="muted">{ LocalizeText('navigator.roomownercaption') }</Text>
|
||||
<Flex alignItems="center">
|
||||
<UserProfileIconView userId={ roomInfoData.enteredGuestRoom.ownerId } />
|
||||
<Text>{ roomInfoData.enteredGuestRoom.ownerName }</Text>
|
||||
</Flex>
|
||||
</Flex> }
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text variant="muted">{ LocalizeText('navigator.roomrating') }</Text>
|
||||
<Text>{ roomInfoData.enteredGuestRoom.score }</Text>
|
||||
</Flex>
|
||||
{ (roomInfoData.enteredGuestRoom.tags.length > 0) &&
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
{ roomInfoData.enteredGuestRoom.tags.map(tag =>
|
||||
{
|
||||
return <Text key={ tag } pointer className="bg-muted rounded p-1" onClick={ event => processAction('navigator_search_tag', tag) }>#{ tag }</Text>
|
||||
}) }
|
||||
</Flex> }
|
||||
</Column>
|
||||
<Grid maxContent columnCount={ 2 } gap={ 1 }>
|
||||
<i onClick={ () => processAction('set_home_room') } className={ 'flex-shrink-0 icon icon-house-small cursor-pointer' + classNames({ ' gray': homeRoomId !== roomInfoData.enteredGuestRoom.roomId }) } />
|
||||
<FontAwesomeIcon icon="link" title={ LocalizeText('navigator.embed.caption') } className="cursor-pointer" onClick={ event => dispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK)) } />
|
||||
{ hasPermission('settings') &&
|
||||
<>
|
||||
<FontAwesomeIcon icon="cogs" title={ LocalizeText('navigator.room.popup.info.room.settings') } className="cursor-pointer" onClick={ event => processAction('open_room_settings') } />
|
||||
<FontAwesomeIcon icon="tools" title={ LocalizeText('open.floor.plan.editor') } className="cursor-pointer" onClick={ event => processAction('open_floorplan_editor') } />
|
||||
</> }
|
||||
</Grid>
|
||||
</Flex>
|
||||
<Text overflow="auto">{ roomInfoData.enteredGuestRoom.description }</Text>
|
||||
{ (roomInfoData.enteredGuestRoom.habboGroupId > 0) &&
|
||||
<Flex pointer alignItems="center" gap={ 1 } onClick={ () => processAction('open_group_info') }>
|
||||
<BadgeImageView className="flex-none" badgeCode={ roomInfoData.enteredGuestRoom.groupBadgeCode } isGroup={ true } />
|
||||
<Text underline>
|
||||
{ LocalizeText('navigator.guildbase', ['groupName'], [roomInfoData.enteredGuestRoom.groupName]) }
|
||||
</Text>
|
||||
</Flex> }
|
||||
</Column>
|
||||
</Flex>
|
||||
<Column gap={ 1 }>
|
||||
{ hasPermission('staff_pick') &&
|
||||
<Button size="sm" onClick={ () => processAction('toggle_pick') }>
|
||||
{ LocalizeText(isRoomPicked ? 'navigator.staffpicks.unpick' : 'navigator.staffpicks.pick') }
|
||||
</Button> }
|
||||
<Button size="sm" variant="danger" disabled>
|
||||
{ LocalizeText('help.emergency.main.report.room') }
|
||||
</Button>
|
||||
{ hasPermission('settings') &&
|
||||
<Button size="sm" onClick={ () => processAction('toggle_mute') }>
|
||||
{ LocalizeText(isRoomMuted ? 'navigator.muteall_on' : 'navigator.muteall_off') }
|
||||
</Button> }
|
||||
</Column>
|
||||
</> }
|
||||
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
@ -0,0 +1,3 @@
|
||||
.nitro-room-link {
|
||||
width: 400px;
|
||||
}
|
@ -1,18 +1,24 @@
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { GetConfiguration, GetNitroInstance, LocalizeText } from '../../../../api';
|
||||
import { Column } from '../../../../common/Column';
|
||||
import { Flex } from '../../../../common/Flex';
|
||||
import { Text } from '../../../../common/Text';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { RoomThumbnailView } from '../../../../layout/room-thumbnail/RoomThumbnailView';
|
||||
import { useNavigatorContext } from '../../context/NavigatorContext';
|
||||
import { NavigatorRoomLinkViewProps } from './NavigatorRoomLinkView.types';
|
||||
|
||||
export class NavigatorRoomLinkViewProps
|
||||
{
|
||||
onCloseClick: () => void;
|
||||
}
|
||||
|
||||
export const NavigatorRoomLinkView: FC<NavigatorRoomLinkViewProps> = props =>
|
||||
{
|
||||
const { onCloseClick = null } = props;
|
||||
const { navigatorState = null } = useNavigatorContext();
|
||||
const { roomInfoData = null } = navigatorState;
|
||||
|
||||
const [ roomThumbnail, setRoomThumbnail ] = useState(null);
|
||||
const [ roomLink, setRoomLink ] = useState(null);
|
||||
|
||||
const { navigatorState = null } = useNavigatorContext();
|
||||
const { roomInfoData = null } = navigatorState;
|
||||
const elementRef = useRef<HTMLInputElement>();
|
||||
|
||||
useEffect(() =>
|
||||
@ -50,18 +56,16 @@ export const NavigatorRoomLinkView: FC<NavigatorRoomLinkViewProps> = props =>
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-room-link" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.embed.title') } onCloseClick={ () => processAction('close') } />
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.embed.title') } onCloseClick={ onCloseClick } />
|
||||
<NitroCardContentView className="text-black d-flex align-items-center">
|
||||
<div className="me-3">
|
||||
<div className="room-thumbnail border">
|
||||
{ roomThumbnail && <img alt="" src={ roomThumbnail } /> }
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="h5 fw-bold m-0">{ LocalizeText('navigator.embed.headline') }</div>
|
||||
<div>{ LocalizeText('navigator.embed.info') }</div>
|
||||
<Flex gap={ 2 }>
|
||||
<RoomThumbnailView customUrl={ roomInfoData.enteredGuestRoom.officialRoomPicRef } />
|
||||
<Column>
|
||||
<Text bold fontSize={ 5 }>{ LocalizeText('navigator.embed.headline') }</Text>
|
||||
<Text>{ LocalizeText('navigator.embed.info') }</Text>
|
||||
{ roomLink && <input ref={ elementRef } type="text" readOnly className="form-control form-control-sm" value={ roomLink } /> }
|
||||
</div>
|
||||
</Column>
|
||||
</Flex>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
@ -1,10 +1,6 @@
|
||||
.nitro-room-settings {
|
||||
width: 400px;
|
||||
|
||||
.content-area {
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.user-rights-container {
|
||||
|
||||
.row {
|
@ -135,15 +135,15 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
|
||||
if(!roomSettingsData) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-room-settings">
|
||||
<NitroCardView uniqueKey="nitro-room-settings" className="nitro-room-settings">
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.roomsettings') } onCloseClick={ () => processAction('close') } />
|
||||
<NitroCardTabsView>
|
||||
{ TABS.map(tab =>
|
||||
{
|
||||
return <NitroCardTabsItemView key={ tab } isActive={ currentTab === tab } onClick={ event => setCurrentTab(tab) }>{ LocalizeText(tab) }</NitroCardTabsItemView>
|
||||
return <NitroCardTabsItemView key={ tab } isActive={ (currentTab === tab) } onClick={ event => setCurrentTab(tab) }>{ LocalizeText(tab) }</NitroCardTabsItemView>
|
||||
}) }
|
||||
</NitroCardTabsView>
|
||||
<NitroCardContentView className="text-black px-4">
|
||||
<NitroCardContentView className="text-black">
|
||||
{ currentTab === TABS[0] && <NavigatorRoomSettingsBasicTabView roomSettingsData={ roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } /> }
|
||||
{ currentTab === TABS[1] && <NavigatorRoomSettingsAccessTabView roomSettingsData={ roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } /> }
|
||||
{ currentTab === TABS[2] && <NavigatorRoomSettingsRightsTabView roomSettingsData= {roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } friends={friends} /> }
|
@ -0,0 +1,102 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { Column } from '../../../../../../common/Column';
|
||||
import { Flex } from '../../../../../../common/Flex';
|
||||
import { Text } from '../../../../../../common/Text';
|
||||
import { NavigatorRoomSettingsTabViewProps } from '../../NavigatorRoomSettingsView.types';
|
||||
|
||||
export const NavigatorRoomSettingsAccessTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, setRoomSettingsData = null, onSave = null } = props;
|
||||
|
||||
const handleChange = useCallback((field: string, value: string | number | boolean) =>
|
||||
{
|
||||
const roomSettings = Object.assign({}, roomSettingsData);
|
||||
|
||||
let save = true;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 'lock_state':
|
||||
roomSettings.lockState = Number(value);
|
||||
|
||||
if(Number(value) === 3) save = false;
|
||||
break;
|
||||
case 'password':
|
||||
roomSettings.password = String(value);
|
||||
save = false;
|
||||
break;
|
||||
case 'confirm_password':
|
||||
roomSettings.confirmPassword = String(value);
|
||||
save = false;
|
||||
break;
|
||||
case 'allow_pets':
|
||||
roomSettings.allowPets = Boolean(value);
|
||||
break;
|
||||
case 'allow_pets_eat':
|
||||
roomSettings.allowPetsEat = Boolean(value);
|
||||
break;
|
||||
}
|
||||
|
||||
setRoomSettingsData(roomSettings);
|
||||
|
||||
if(save) onSave(roomSettings);
|
||||
}, [ roomSettingsData, setRoomSettingsData, onSave ]);
|
||||
|
||||
const isPasswordValid = useCallback(() =>
|
||||
{
|
||||
return (roomSettingsData.password && (roomSettingsData.password.length > 0) && (roomSettingsData.password === roomSettingsData.confirmPassword));
|
||||
}, [ roomSettingsData ]);
|
||||
|
||||
const trySave = useCallback(() =>
|
||||
{
|
||||
if(isPasswordValid()) onSave(roomSettingsData);
|
||||
}, [isPasswordValid, onSave, roomSettingsData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text bold>{LocalizeText('navigator.roomsettings.roomaccess.caption')}</Text>
|
||||
<Text>{ LocalizeText('navigator.roomsettings.roomaccess.info') }</Text>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{ LocalizeText('navigator.roomsettings.doormode') }</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 0 } onChange={ (e) => handleChange('lock_state', 0) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.open') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 1 } onChange={ (e) => handleChange('lock_state', 1) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.doorbell') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 2 } onChange={ (e) => handleChange('lock_state', 2) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.invisible') }</Text>
|
||||
</Flex>
|
||||
<Flex fullWidth gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 3 } onChange={ (e) => handleChange('lock_state', 3) } />
|
||||
{ (roomSettingsData.lockState !== 3) && <Text>{ LocalizeText('navigator.roomsettings.doormode.password') }</Text> }
|
||||
{ roomSettingsData.lockState === 3 &&
|
||||
<Column gap={ 1 }>
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.password') }</Text>
|
||||
<input type="password" className="form-control form-control-sm col-4" value={ roomSettingsData.password ?? '' } onChange={ (e) => handleChange('password', e.target.value) } onBlur={ trySave } placeholder={ LocalizeText('navigator.roomsettings.password') } />
|
||||
<input type="password" className="form-control form-control-sm col-4" value={ roomSettingsData.confirmPassword ?? '' } onChange={ (e) => handleChange('confirm_password', e.target.value) } onBlur={ trySave } placeholder={ LocalizeText('navigator.roomsettings.passwordconfirm') } />
|
||||
{ !isPasswordValid() &&
|
||||
<small className="text-danger fw-bold">
|
||||
{ LocalizeText('navigator.roomsettings.invalidconfirm') }
|
||||
</small> }
|
||||
</Column> }
|
||||
</Flex>
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{ LocalizeText('navigator.roomsettings.pets') }</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPets } onChange={ (e) => handleChange('allow_pets', e.target.checked) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.allowpets') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPetsEat } onChange={ (e) => handleChange('allow_pets_eat', e.target.checked) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.allowfoodconsume') }</Text>
|
||||
</Flex>
|
||||
</Column>
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,9 +1,15 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { Base } from '../../../../../../common/Base';
|
||||
import { Flex } from '../../../../../../common/Flex';
|
||||
import { Text } from '../../../../../../common/Text';
|
||||
import { GetMaxVisitorsList } from '../../../../common/RoomSettingsUtils';
|
||||
import { useNavigatorContext } from '../../../../context/NavigatorContext';
|
||||
import { NavigatorRoomSettingsTabViewProps } from '../../NavigatorRoomSettingsView.types';
|
||||
|
||||
const DESC_MAX_LENGTH = 255;
|
||||
|
||||
export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, setRoomSettingsData = null, onSave = null } = props;
|
||||
@ -48,49 +54,49 @@ export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewP
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.roomname') }</label>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text className="col-3">{ LocalizeText('navigator.roomname') }</Text>
|
||||
<input className="form-control form-control-sm" value={ roomSettingsData.roomName } onChange={ event => handleChange('name', event.target.value) } onBlur={ () => onSave(roomSettingsData) } />
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.roomsettings.desc') }</label>
|
||||
<input className="form-control form-control-sm" value={ roomSettingsData.roomDescription } onChange={ event => handleChange('description', event.target.value) } onBlur={ () => onSave(roomSettingsData) } />
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.category') }</label>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text className="col-3">{ LocalizeText('navigator.roomsettings.desc') }</Text>
|
||||
<textarea className="form-control form-control-sm" value={ roomSettingsData.roomDescription } onChange={ event => handleChange('description', event.target.value) } onBlur={ () => onSave(roomSettingsData) } maxLength={ DESC_MAX_LENGTH } />
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text className="col-3">{ LocalizeText('navigator.category') }</Text>
|
||||
<select className="form-select form-select-sm" value={ roomSettingsData.categoryId } onChange={ event => handleChange('category', event.target.value) }>
|
||||
{ categories && categories.map(category =>
|
||||
{
|
||||
return <option key={ category.id } value={ category.id }>{ LocalizeText(category.name) }</option>
|
||||
}) }
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.maxvisitors') }</label>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text className="col-3">{ LocalizeText('navigator.maxvisitors') }</Text>
|
||||
<select className="form-select form-select-sm" value={ roomSettingsData.userCount } onChange={ event => handleChange('max_visitors', event.target.value) }>
|
||||
{ maxVisitorsList && maxVisitorsList.map(value =>
|
||||
{
|
||||
return <option key={ value } value={ value }>{ value }</option>
|
||||
}) }
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.tradesettings') }</label>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text className="col-3">{ LocalizeText('navigator.tradesettings') }</Text>
|
||||
<select className="form-select form-select-sm" value={ roomSettingsData.tradeState } onChange={ event => handleChange('trade_state', event.target.value) }>
|
||||
<option value="0">{ LocalizeText('navigator.roomsettings.trade_not_allowed') }</option>
|
||||
<option value="1">{ LocalizeText('navigator.roomsettings.trade_not_with_Controller') }</option>
|
||||
<option value="2">{ LocalizeText('navigator.roomsettings.trade_allowed') }</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Base className="col-3" />
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowWalkthrough } onChange={ event => handleChange('allow_walkthrough', event.target.checked) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.allow_walk_through') }</label>
|
||||
</div>
|
||||
<div className="form-group d-flex justify-content-center mt-1">
|
||||
<button type="button" className="btn btn-link btn-sm text-danger fw-bold">
|
||||
<i className="fas fa-times me-1" />
|
||||
{ LocalizeText('navigator.roomsettings.delete') }</button>
|
||||
</div>
|
||||
<Text>{ LocalizeText('navigator.roomsettings.allow_walk_through') }</Text>
|
||||
</Flex>
|
||||
<Text variant="danger" underline bold pointer className="d-flex justify-content-center align-items-center gap-1 mt-2">
|
||||
<FontAwesomeIcon icon="times" />
|
||||
{ LocalizeText('navigator.roomsettings.delete') }
|
||||
</Text>
|
||||
</>
|
||||
);
|
||||
};
|
@ -5,7 +5,6 @@
|
||||
@import "./hotel-view/HotelView";
|
||||
@import "./loading/LoadingView";
|
||||
@import "./main/MainView";
|
||||
@import "./navigator/NavigatorView";
|
||||
@import "./notification-center/NotificationCenterView";
|
||||
@import "./purse/PurseView";
|
||||
@import "./right-side/RightSideView";
|
||||
|
@ -5,6 +5,7 @@ import { AchievementsView } from '../../components/achievements/AchievementsView
|
||||
import { AvatarEditorView } from '../../components/avatar-editor/AvatarEditorView';
|
||||
import { CatalogView } from '../../components/catalog/CatalogView';
|
||||
import { InventoryView } from '../../components/inventory/InventoryView';
|
||||
import { NavigatorView } from '../../components/navigator/NavigatorView';
|
||||
import { ToolbarView } from '../../components/toolbar/ToolbarView';
|
||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||
import { TransitionAnimation, TransitionAnimationTypes } from '../../layout';
|
||||
@ -18,7 +19,6 @@ import { HcCenterView } from '../hc-center/HcCenterView';
|
||||
import { HelpView } from '../help/HelpView';
|
||||
import { HotelView } from '../hotel-view/HotelView';
|
||||
import { ModToolsView } from '../mod-tools/ModToolsView';
|
||||
import { NavigatorView } from '../navigator/NavigatorView';
|
||||
import { NitropediaView } from '../nitropedia/NitropediaView';
|
||||
import { RightSideView } from '../right-side/RightSideView';
|
||||
import { RoomHostView } from '../room-host/RoomHostView';
|
||||
|
@ -1,171 +0,0 @@
|
||||
import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, SecurityLevel, UserHomeRoomComposer } from '@nitrots/nitro-renderer';
|
||||
import classNames from 'classnames';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetConfiguration, GetGroupInformation, GetSessionDataManager, LocalizeText } from '../../../../api';
|
||||
import { NavigatorEvent } from '../../../../events';
|
||||
import { FloorplanEditorEvent } from '../../../../events/floorplan-editor/FloorplanEditorEvent';
|
||||
import { RoomWidgetThumbnailEvent } from '../../../../events/room-widgets/thumbnail';
|
||||
import { dispatchUiEvent } from '../../../../hooks/events';
|
||||
import { SendMessageHook } from '../../../../hooks/messages';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, UserProfileIconView } from '../../../../layout';
|
||||
import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView';
|
||||
import { useNavigatorContext } from '../../context/NavigatorContext';
|
||||
import { NavigatorActions } from '../../reducers/NavigatorReducer';
|
||||
import { NavigatorRoomInfoViewProps } from './NavigatorRoomInfoView.types';
|
||||
|
||||
export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
||||
{
|
||||
const { onCloseClick = null } = props;
|
||||
|
||||
const { navigatorState = null, dispatchNavigatorState = null } = useNavigatorContext();
|
||||
const { roomInfoData = null, homeRoomId = null } = navigatorState;
|
||||
const [ roomThumbnail, setRoomThumbnail ] = useState(null);
|
||||
const [ isRoomPicked, setIsRoomPicked ] = useState(false);
|
||||
const [ isRoomMuted, setIsRoomMuted ] = useState(false);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
||||
|
||||
let thumbnailUrl: string = null;
|
||||
|
||||
if(roomInfoData.enteredGuestRoom.officialRoomPicRef)
|
||||
{
|
||||
thumbnailUrl = (GetConfiguration<string>('image.library.url') + roomInfoData.enteredGuestRoom.officialRoomPicRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
thumbnailUrl = (GetConfiguration<string>('thumbnails.url').replace('%thumbnail%', roomInfoData.enteredGuestRoom.roomId.toString()));
|
||||
}
|
||||
|
||||
setRoomThumbnail(thumbnailUrl);
|
||||
setIsRoomPicked(roomInfoData.enteredGuestRoom.roomPicker);
|
||||
setIsRoomMuted(roomInfoData.enteredGuestRoom.allInRoomMuted);
|
||||
}, [ roomInfoData ]);
|
||||
|
||||
const hasPermission = useCallback((permission: string) =>
|
||||
{
|
||||
switch(permission)
|
||||
{
|
||||
case 'settings': return GetSessionDataManager().securityLevel >= SecurityLevel.MODERATOR || roomInfoData.currentRoomOwner;
|
||||
case 'staff_pick': return GetSessionDataManager().securityLevel >= SecurityLevel.COMMUNITY;
|
||||
default: return false;
|
||||
}
|
||||
}, [ roomInfoData ]);
|
||||
|
||||
const processAction = useCallback((action: string, value?: string) =>
|
||||
{
|
||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case 'set_home_room':
|
||||
let newRoomId = -1;
|
||||
|
||||
if(homeRoomId !== roomInfoData.enteredGuestRoom.roomId)
|
||||
{
|
||||
newRoomId = roomInfoData.enteredGuestRoom.roomId;
|
||||
}
|
||||
|
||||
dispatchNavigatorState({
|
||||
type: NavigatorActions.SET_HOME_ROOM_ID,
|
||||
payload: {
|
||||
homeRoomId: newRoomId
|
||||
}
|
||||
});
|
||||
|
||||
SendMessageHook(new UserHomeRoomComposer(newRoomId));
|
||||
return;
|
||||
case 'navigator_search_tag':
|
||||
return;
|
||||
case 'open_room_thumbnail_camera':
|
||||
dispatchUiEvent(new RoomWidgetThumbnailEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL));
|
||||
return;
|
||||
case 'open_group_info':
|
||||
GetGroupInformation(roomInfoData.enteredGuestRoom.habboGroupId);
|
||||
return;
|
||||
case 'toggle_room_link':
|
||||
dispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK));
|
||||
return;
|
||||
case 'open_room_settings':
|
||||
SendMessageHook(new RoomSettingsComposer(roomInfoData.enteredGuestRoom.roomId));
|
||||
return;
|
||||
case 'toggle_pick':
|
||||
setIsRoomPicked(value => !value);
|
||||
SendMessageHook(new RoomStaffPickComposer(roomInfoData.enteredGuestRoom.roomId));
|
||||
return;
|
||||
case 'toggle_mute':
|
||||
setIsRoomMuted(value => !value);
|
||||
SendMessageHook(new RoomMuteComposer());
|
||||
return;
|
||||
case 'open_floorplan_editor':
|
||||
dispatchUiEvent(new FloorplanEditorEvent(FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR));
|
||||
return;
|
||||
case 'close':
|
||||
onCloseClick();
|
||||
return;
|
||||
}
|
||||
|
||||
}, [ onCloseClick, dispatchNavigatorState, roomInfoData, homeRoomId ]);
|
||||
|
||||
if(!roomInfoData) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-room-info" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.roomsettings.roominfo') } onCloseClick={ () => processAction('close') } />
|
||||
<NitroCardContentView className="text-black">
|
||||
{ roomInfoData.enteredGuestRoom && <>
|
||||
<div className="d-flex justify-content-between align-items-center">
|
||||
<div className="fw-bold">
|
||||
{ roomInfoData.enteredGuestRoom.roomName }
|
||||
</div>
|
||||
<i onClick={ () => processAction('set_home_room') } className={ 'flex-shrink-0 icon icon-house-small cursor-pointer' + classNames({ ' gray': homeRoomId !== roomInfoData.enteredGuestRoom.roomId }) } />
|
||||
</div>
|
||||
<div className="d-flex align-items-center">
|
||||
{ roomInfoData.enteredGuestRoom.showOwner && <>
|
||||
<div className="fw-bold text-muted me-1">{ LocalizeText('navigator.roomownercaption') }</div>
|
||||
<div className="d-flex align-items-center cursor-pointer">
|
||||
<UserProfileIconView userId={ roomInfoData.enteredGuestRoom.ownerId } />
|
||||
<div>{ roomInfoData.enteredGuestRoom.ownerName }</div>
|
||||
</div>
|
||||
</> }
|
||||
</div>
|
||||
<div>
|
||||
<span className="fw-bold text-muted me-1">{ LocalizeText('navigator.roomrating') }</span> { roomInfoData.enteredGuestRoom.score }
|
||||
</div>
|
||||
<div className="d-flex mb-1">
|
||||
{ roomInfoData.enteredGuestRoom.tags.map(tag =>
|
||||
{
|
||||
return <div className="bg-muted p-1 rounded me-1 cursor-pointer" onClick={ () => processAction('navigator_search_tag', tag) }>#{ tag }</div>
|
||||
}) }
|
||||
</div>
|
||||
<div>{ roomInfoData.enteredGuestRoom.description }</div>
|
||||
<div className="room-thumbnail rounded overflow-hidden border mt-1 mb-2">
|
||||
{ hasPermission('settings') && <i className="icon icon-camera-small position-absolute b-0 r-0 m-1 cursor-pointer" onClick={ () => processAction('open_room_thumbnail_camera') } /> }
|
||||
{ roomThumbnail && <img alt="" src={ roomThumbnail } /> }
|
||||
</div>
|
||||
{ roomInfoData.enteredGuestRoom.habboGroupId > 0 && <div className="d-flex align-items-center mb-2 cursor-pointer" onClick={ () => processAction('open_group_info') }>
|
||||
<div className="group-badge flex-shrink-0 me-1">
|
||||
<BadgeImageView badgeCode={ roomInfoData.enteredGuestRoom.groupBadgeCode } isGroup={ true } />
|
||||
</div>
|
||||
<div className="text-decoration-underline small">
|
||||
{ LocalizeText('navigator.guildbase', ['groupName'], [roomInfoData.enteredGuestRoom.groupName]) }
|
||||
</div>
|
||||
</div> }
|
||||
<div className="cursor-pointer text-decoration-underline d-flex align-items-center mb-2" onClick={ () => processAction('toggle_room_link') }>
|
||||
<i className="icon icon-arrows me-1" />
|
||||
<span>{ LocalizeText('navigator.embed.caption') }</span>
|
||||
</div>
|
||||
{ hasPermission('settings') && <>
|
||||
<button className="btn btn-sm btn-primary w-100 mb-1" onClick={ () => processAction('open_room_settings') }>{ LocalizeText('navigator.room.popup.info.room.settings') }</button>
|
||||
<button className="btn btn-sm btn-primary w-100 mb-1" onClick={ () => processAction('open_floorplan_editor') }>{ LocalizeText('open.floor.plan.editor') }</button>
|
||||
</> }
|
||||
{ hasPermission('staff_pick') && <button className="btn btn-sm btn-primary w-100 mb-1" onClick={ () => processAction('toggle_pick') }>{ LocalizeText(isRoomPicked ? 'navigator.staffpicks.unpick' : 'navigator.staffpicks.pick') }</button> }
|
||||
<button className="btn btn-sm btn-danger w-100 mb-1" disabled={ true }>{ LocalizeText('help.emergency.main.report.room') }</button>
|
||||
{ hasPermission('settings') && <button className="btn btn-sm btn-primary w-100" onClick={ () => processAction('toggle_mute') }>{ LocalizeText(isRoomMuted ? 'navigator.muteall_on' : 'navigator.muteall_off') }</button> }
|
||||
</> }
|
||||
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
@ -1,5 +0,0 @@
|
||||
|
||||
export class NavigatorRoomInfoViewProps
|
||||
{
|
||||
onCloseClick: () => void;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
.nitro-room-link {
|
||||
width: 400px;
|
||||
|
||||
.room-thumbnail {
|
||||
position: relative;
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
background-image: url(../../../../assets/images/navigator/thumbnail_placeholder.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-color: rgba($black, .125);
|
||||
border-color: $black !important;
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
|
||||
export class NavigatorRoomLinkViewProps
|
||||
{
|
||||
onCloseClick: () => void;
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { NavigatorRoomSettingsTabViewProps } from '../../NavigatorRoomSettingsView.types';
|
||||
|
||||
export const NavigatorRoomSettingsAccessTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, setRoomSettingsData = null, onSave = null } = props;
|
||||
|
||||
const handleChange = useCallback((field: string, value: string | number | boolean) =>
|
||||
{
|
||||
const roomSettings = Object.assign({}, roomSettingsData);
|
||||
let save = true;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 'lock_state':
|
||||
roomSettings.lockState = Number(value);
|
||||
|
||||
if(Number(value) === 3) save = false;
|
||||
break;
|
||||
case 'password':
|
||||
roomSettings.password = String(value);
|
||||
save = false;
|
||||
break;
|
||||
case 'confirm_password':
|
||||
roomSettings.confirmPassword = String(value);
|
||||
save = false;
|
||||
break;
|
||||
case 'allow_pets':
|
||||
roomSettings.allowPets = Boolean(value);
|
||||
break;
|
||||
case 'allow_pets_eat':
|
||||
roomSettings.allowPetsEat = Boolean(value);
|
||||
break;
|
||||
}
|
||||
|
||||
setRoomSettingsData(roomSettings);
|
||||
|
||||
if(save) onSave(roomSettings);
|
||||
}, [ roomSettingsData, setRoomSettingsData, onSave ]);
|
||||
|
||||
const isPasswordValid = useCallback(() =>
|
||||
{
|
||||
return (roomSettingsData.password && roomSettingsData.password.length > 0 && roomSettingsData.password === roomSettingsData.confirmPassword);
|
||||
}, [ roomSettingsData ]);
|
||||
|
||||
const trySave = useCallback(() =>
|
||||
{
|
||||
if(isPasswordValid()) onSave(roomSettingsData);
|
||||
}, [isPasswordValid, onSave, roomSettingsData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="fw-bold">{LocalizeText('navigator.roomsettings.roomaccess.caption')}</div>
|
||||
<div className="mb-3">{ LocalizeText('navigator.roomsettings.roomaccess.info') }</div>
|
||||
<div className="fw-bold">{ LocalizeText('navigator.roomsettings.doormode') }</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 0 } onChange={ (e) => handleChange('lock_state', 0) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.doormode.open') }</label>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 1 } onChange={ (e) => handleChange('lock_state', 1) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.doormode.doorbell') }</label>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 2 } onChange={ (e) => handleChange('lock_state', 2) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.doormode.invisible') }</label>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 3 } onChange={ (e) => handleChange('lock_state', 3) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.doormode.password') }</label>
|
||||
</div>
|
||||
{ roomSettingsData.lockState === 3 && <>
|
||||
<div className="form-group mt-2">
|
||||
<label>{ LocalizeText('navigator.roomsettings.password') }</label>
|
||||
<input type="password" className="form-control form-control-sm" value={ roomSettingsData.password ?? '' } onChange={ (e) => handleChange('password', e.target.value) } onBlur={ trySave } placeholder="*****" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>{ LocalizeText('navigator.roomsettings.passwordconfirm') }</label>
|
||||
<input type="password" className="form-control form-control-sm" value={ roomSettingsData.confirmPassword ?? '' } onChange={ (e) => handleChange('confirm_password', e.target.value) } onBlur={ trySave } placeholder="*****" />
|
||||
{ !isPasswordValid() && <small className="text-danger fw-bold">
|
||||
{ LocalizeText('navigator.roomsettings.invalidconfirm') }
|
||||
</small> }
|
||||
</div>
|
||||
</> }
|
||||
<div className="fw-bold mt-2">{ LocalizeText('navigator.roomsettings.pets') }</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPets } onChange={ (e) => handleChange('allow_pets', e.target.checked) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.allowpets') }</label>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPetsEat } onChange={ (e) => handleChange('allow_pets_eat', e.target.checked) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.allowfoodconsume') }</label>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
Loading…
Reference in New Issue
Block a user