Update help component

This commit is contained in:
Bill 2022-02-16 04:06:50 -05:00
parent 88853ada48
commit 2d5afea712
7 changed files with 217 additions and 229 deletions

View File

@ -1,6 +1,7 @@
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react';
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../api';
import { Base, Column, Grid } from '../../common';
import { HelpReportUserEvent } from '../../events/help/HelpReportUserEvent';
import { useUiEvent } from '../../hooks';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../layout';
@ -112,7 +113,14 @@ export const HelpView: FC<{}> = props =>
<NitroCardView className="nitro-help">
<NitroCardHeaderView headerText={ LocalizeText('help.button.cfh') } onCloseClick={ event => setIsVisible(false) } />
<NitroCardContentView className="text-black">
<CurrentStepView />
<Grid>
<Column center size={ 5 } overflow="hidden">
<Base className="index-image" />
</Column>
<Column justifyContent="between" size={ 7 } overflow="hidden">
<CurrentStepView />
</Column>
</Grid>
</NitroCardContentView>
</NitroCardView> }
<SanctionSatusView />

View File

@ -1,49 +1,44 @@
import { CallForHelpMessageComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react';
import { FC, useState } from 'react';
import { CreateLinkEvent, LocalizeText } from '../../../api';
import { Button, Column, Text } from '../../../common';
import { SendMessageHook } from '../../../hooks';
import { useHelpContext } from '../HelpContext';
export const DescribeReportView: FC<{}> = props =>
{
const [ message, setMessage ] = useState('');
const { helpReportState = null, setHelpReportState = null } = useHelpContext();
const [message, setMessage] = useState('');
const { reportedChats, cfhTopic, reportedUserId } = helpReportState;
const submitReport = useCallback(() =>
const submitReport = () =>
{
if(message.length < 15) return;
const reportState = Object.assign({}, helpReportState);
reportState.message = message;
setHelpReportState(reportState);
const roomId = reportState.reportedChats[0].roomId;
const roomId = reportedChats[0].roomId;
const chats: (string | number )[] = [];
reportState.reportedChats.forEach(entry =>
reportedChats.forEach(entry =>
{
chats.push(entry.entityId);
chats.push(entry.message);
});
SendMessageHook(new CallForHelpMessageComposer(message, reportState.cfhTopic, reportState.reportedUserId, roomId, chats));
SendMessageHook(new CallForHelpMessageComposer(message, cfhTopic, reportedUserId, roomId, chats));
CreateLinkEvent('help/hide');
}, [helpReportState, message, setHelpReportState]);
}
return (
<>
<div className="d-grid col-12 mx-auto justify-content-center">
<div className="col-12"><h3 className="fw-bold">{LocalizeText('help.emergency.chat_report.subtitle')}</h3></div>
<div className="text-wrap">{LocalizeText('help.cfh.input.text')}</div>
</div>
<div className="form-group mb-2">
<textarea className="form-control" value={message} onChange={event => setMessage(event.target.value)} />
</div>
<button className="btn btn-danger mt-2" type="button" disabled={message.length < 15} onClick={submitReport}>{LocalizeText('help.bully.submit')}</button>
<Column gap={ 1 }>
<Text fontSize={ 3 }>{ LocalizeText('help.emergency.chat_report.subtitle') }</Text>
<Text>{ LocalizeText('help.cfh.input.text') }</Text>
</Column>
<textarea className="form-control" value={ message } onChange={ event => setMessage(event.target.value) } />
<Button variant="success" disabled={ (message.length < 15) } onClick={ submitReport }>
{ LocalizeText('help.bully.submit') }
</Button>
</>
);
}

View File

@ -3,7 +3,6 @@ import { FC, useCallback } from 'react';
import { LocalizeText } from '../../../api';
import { Button } from '../../../common/Button';
import { Column } from '../../../common/Column';
import { Grid } from '../../../common/Grid';
import { Text } from '../../../common/Text';
import { SendMessageHook } from '../../../hooks';
import { useHelpContext } from '../HelpContext';
@ -25,22 +24,17 @@ export const HelpIndexView: FC<{}> = props =>
}, []);
return (
<Grid>
<Column center size={ 5 } overflow="hidden">
<div className="index-image" />
<>
<Column gap={ 1 }>
<Text fontSize={ 3 }>{ LocalizeText('help.main.frame.title') }</Text>
<Text>{ LocalizeText('help.main.self.description') }</Text>
</Column>
<Column justifyContent="center" size={ 7 } overflow="hidden">
<Column gap={ 1 }>
<Text fontSize={ 3 }>{ LocalizeText('help.main.frame.title') }</Text>
<Text>{ LocalizeText('help.main.self.description') }</Text>
</Column>
<Column gap={ 1 }>
<Button onClick={ onReportClick }>{ LocalizeText('help.main.bully.subtitle') }</Button>
<Button disabled={ true }>{ LocalizeText('help.main.help.title') }</Button>
<Button disabled={ true }>{ LocalizeText('help.main.self.tips.title') }</Button>
<Button variant="link" className="text-black" onClick={ onRequestMySanctionStatusClick }>{ LocalizeText('help.main.my.sanction.status') }</Button>
</Column>
<Column gap={ 1 }>
<Button onClick={ onReportClick }>{ LocalizeText('help.main.bully.subtitle') }</Button>
<Button disabled={ true }>{ LocalizeText('help.main.help.title') }</Button>
<Button disabled={ true }>{ LocalizeText('help.main.self.tips.title') }</Button>
<Button variant="link" className="text-black" onClick={ onRequestMySanctionStatusClick }>{ LocalizeText('help.main.my.sanction.status') }</Button>
</Column>
</Grid>
</>
)
}

View File

@ -1,6 +1,7 @@
import { SanctionStatusEvent, SanctionStatusMessageParser } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react';
import { LocalizeText } from '../../../api';
import { Base, Button, Column, Grid } from '../../../common';
import { CreateMessageHook } from '../../../hooks';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../layout';
@ -49,36 +50,39 @@ export const SanctionSatusView:FC<{}> = props =>
if(!sanctionInfo) return null;
return (
<NitroCardView className="nitro-cfh-sanction-status">
<NitroCardView className="nitro-help">
<NitroCardHeaderView headerText={LocalizeText('help.sanction.info.title')} onCloseClick={() => setSanctionInfo(null)} />
<NitroCardContentView className="text-black">
<div className="d-grid gap-2 col-12 mx-auto justify-content-start">
{(sanctionInfo.sanctionReason === 'cfh.reason.EMPTY')
? <div className="col-12 fw-bold">{LocalizeText('help.sanction.current.none')}</div>
: <>
{((sanctionInfo.probationHoursLeft > 0) || (sanctionInfo.isSanctionActive)) &&
<div className="col-12 fw-bold">{LocalizeText('help.sanction.probation.reminder')}</div>
}
<div className={`col-12 fw-bold ${sanctionInfo.isSanctionNew ? 'text-danger' : ''}`}>
{LocalizeText('help.sanction.last.sanction')} {sanctionLocalization('current', sanctionInfo.sanctionName, sanctionInfo.sanctionLengthHours)}
</div>
<div className="col-12">{LocalizeText('generic.start.time')} {sanctionInfo.sanctionCreationTime}</div>
<div className="col-12">{LocalizeText('generic.reason')} {sanctionInfo.sanctionReason}</div>
<div className="col-12">{LocalizeText('help.sanction.probation.days.left')} {Math.trunc((sanctionInfo.probationHoursLeft / 24)) + 1}</div>
</>
}
{ ((sanctionInfo.hasCustomMute) && (!(sanctionInfo.isSanctionActive))) &&
<Grid>
<Column center size={ 5 } overflow="hidden">
<Base className="index-image" />
</Column>
<Column justifyContent="between" size={ 7 } overflow="hidden">
{ (sanctionInfo.sanctionReason === 'cfh.reason.EMPTY')
? <div className="col-12 fw-bold">{LocalizeText('help.sanction.current.none')}</div>
: <>
{((sanctionInfo.probationHoursLeft > 0) || (sanctionInfo.isSanctionActive)) &&
<div className="col-12 fw-bold">{LocalizeText('help.sanction.probation.reminder')}</div>
}
<div className={`col-12 fw-bold ${sanctionInfo.isSanctionNew ? 'text-danger' : ''}`}>
{LocalizeText('help.sanction.last.sanction')} {sanctionLocalization('current', sanctionInfo.sanctionName, sanctionInfo.sanctionLengthHours)}
</div>
<div className="col-12">{LocalizeText('generic.start.time')} {sanctionInfo.sanctionCreationTime}</div>
<div className="col-12">{LocalizeText('generic.reason')} {sanctionInfo.sanctionReason}</div>
<div className="col-12">{LocalizeText('help.sanction.probation.days.left')} {Math.trunc((sanctionInfo.probationHoursLeft / 24)) + 1}</div>
</>
}
{ ((sanctionInfo.hasCustomMute) && (!(sanctionInfo.isSanctionActive))) &&
<div className="col-12 fw-bold">{LocalizeText('help.sanction.custom.mute')}</div>
}
{ (sanctionInfo.tradeLockExpiryTime && sanctionInfo.tradeLockExpiryTime.length > 0) &&
<div className="col-12 fw-bold">{LocalizeText('trade.locked.until')} {sanctionInfo.tradeLockExpiryTime}</div>
}
}
{ (sanctionInfo.tradeLockExpiryTime && sanctionInfo.tradeLockExpiryTime.length > 0) &&
<div className="col-12 fw-bold">{LocalizeText('trade.locked.until')} {sanctionInfo.tradeLockExpiryTime}</div>
}
<div className="col-12">{sanctionLocalization('next', sanctionInfo.nextSanctionName, sanctionInfo.nextSanctionLengthHours)}</div>
</div>
<div className="d-grid gap-2 col-8 mx-auto mt-2">
<button className="btn btn-success" type="button" onClick={() => setSanctionInfo(null)}>{LocalizeText('habbo.way.ok.button')}</button>
</div>
<div className="col-12">{sanctionLocalization('next', sanctionInfo.nextSanctionName, sanctionInfo.nextSanctionLengthHours)}</div>
<Button variant="success" onClick={ event => setSanctionInfo(null) }>{LocalizeText('habbo.way.ok.button')}</Button>
</Column>
</Grid>
</NitroCardContentView>
</NitroCardView>
)

View File

@ -1,88 +1,84 @@
import { RoomObjectType } from '@nitrots/nitro-renderer';
import { FC, useCallback, useMemo, useState } from 'react';
import { FC, useMemo, useState } from 'react';
import { LocalizeText } from '../../../api';
import { NitroCardGridItemView, NitroCardGridView } from '../../../layout';
import { Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../common';
import { GetChatHistory } from '../../../views/chat-history/common/GetChatHistory';
import { ChatEntryType, IChatEntry } from '../../../views/chat-history/context/ChatHistoryContext.types';
import { useHelpContext } from '../HelpContext';
export const SelectReportedChatsView: FC<{}> = props =>
{
const { helpReportState = null, setHelpReportState = null } = useHelpContext();
const [ selectedChats, setSelectedChats ] = useState<Map<number, IChatEntry>>(new Map());
const { helpReportState = null, setHelpReportState = null } = useHelpContext();
const { reportedUserId = -1 } = helpReportState;
const userChats = useMemo(() =>
{
return GetChatHistory().chats.filter(chat => (chat.type === ChatEntryType.TYPE_CHAT) && (chat.entityId === helpReportState.reportedUserId) && (chat.entityType === RoomObjectType.USER))
}, [helpReportState.reportedUserId]);
return GetChatHistory().chats.filter(chat => (chat.type === ChatEntryType.TYPE_CHAT) && (chat.entityId === reportedUserId) && (chat.entityType === RoomObjectType.USER));
}, [ reportedUserId ]);
const selectChat = useCallback((chatEntry: IChatEntry) =>
const selectChat = (chatEntry: IChatEntry) =>
{
const chats = new Map(selectedChats);
if(chats.has(chatEntry.id))
{
chats.delete(chatEntry.id);
}
else
{
chats.set(chatEntry.id, chatEntry);
}
if(chats.has(chatEntry.id)) chats.delete(chatEntry.id);
else chats.set(chatEntry.id, chatEntry);
setSelectedChats(chats);
}
}, [selectedChats]);
const submitChats = useCallback(() =>
const submitChats = () =>
{
if(!selectedChats || selectedChats.size <= 0) return;
if(!selectedChats || (selectedChats.size <= 0)) return;
const reportState = Object.assign({}, helpReportState);
setHelpReportState(prevValue =>
{
const reportedChats = Array.from(selectedChats.values());
const currentStep = 3;
reportState.reportedChats = Array.from(selectedChats.values());
reportState.currentStep = 3;
setHelpReportState(reportState);
return { ...prevValue, reportedChats, currentStep };
});
}
}, [helpReportState, selectedChats, setHelpReportState]);
const back = useCallback(() =>
const back = () =>
{
const reportState = Object.assign({}, helpReportState);
reportState.currentStep = --reportState.currentStep;
setHelpReportState(reportState);
}, [helpReportState, setHelpReportState]);
setHelpReportState(prevValue =>
{
const currentStep = (prevValue.currentStep - 1);
return { ...prevValue, currentStep };
});
}
return (
<>
<div className="d-grid col-12 mx-auto justify-content-center">
<div className="col-12"><h3 className="fw-bold">{LocalizeText('help.emergency.chat_report.subtitle')}</h3></div>
{ userChats.length > 0 &&
<div className="text-wrap">{LocalizeText('help.emergency.chat_report.description')}</div>
}
</div>
{
(userChats.length === 0) && <div>{LocalizeText('help.cfh.error.no_user_data')}</div>
}
{ userChats.length > 0 &&
<>
<NitroCardGridView columns={1}>
{userChats.map((chat, index) =>
{
return (
<NitroCardGridItemView key={chat.id} onClick={() => selectChat(chat)} itemActive={selectedChats.has(chat.id)}>
<span>{chat.message}</span>
</NitroCardGridItemView>
)
})}
</NitroCardGridView>
<div className="d-flex gap-2 justify-content-between mt-auto">
<button className="btn btn-secondary mt-2" type="button" onClick={back}>{LocalizeText('generic.back')}</button>
<button className="btn btn-primary mt-2" type="button" disabled={selectedChats.size <= 0} onClick={submitChats}>{LocalizeText('help.emergency.main.submit.button')}</button>
</div>
</>
}
<Column gap={ 1 }>
<Text fontSize={ 3 }>{ LocalizeText('help.emergency.chat_report.subtitle') }</Text>
<Text>{ LocalizeText('help.emergency.chat_report.description') }</Text>
</Column>
<Column gap={ 1 }>
{ !!!userChats.length &&
<Text>{ LocalizeText('help.cfh.error.no_user_data') }</Text> }
{ (userChats.length > 0) &&
<Grid gap={ 1 } columnCount={ 1 } overflow="auto">
{ userChats.map((chat, index) =>
{
return (
<LayoutGridItem key={ chat.id } onClick={ event => selectChat(chat) } itemActive={ selectedChats.has(chat.id) }>
<Text>{ chat.message }</Text>
</LayoutGridItem>
);
}) }
</Grid> }
</Column>
<Flex gap={ 2 } justifyContent="between">
<Button variant="secondary" onClick={ back }>
{ LocalizeText('generic.back') }
</Button>
<Button disabled={ (selectedChats.size <= 0) } onClick={ submitChats }>
{ LocalizeText('help.emergency.main.submit.button') }
</Button>
</Flex>
</>
);
}

View File

@ -1,13 +1,7 @@
import { RoomObjectType } from '@nitrots/nitro-renderer';
import { FC, useCallback, useMemo, useState } from 'react';
import { FC, useMemo, useState } from 'react';
import { GetSessionDataManager, LocalizeText } from '../../../api';
import { Base } from '../../../common/Base';
import { Button } from '../../../common/Button';
import { Column } from '../../../common/Column';
import { Flex } from '../../../common/Flex';
import { Grid } from '../../../common/Grid';
import { LayoutGridItem } from '../../../common/layout/LayoutGridItem';
import { Text } from '../../../common/Text';
import { Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../common';
import { GetChatHistory } from '../../../views/chat-history/common/GetChatHistory';
import { ChatEntryType } from '../../../views/chat-history/context/ChatHistoryContext.types';
import { IReportedUser } from '../common/IReportedUser';
@ -22,8 +16,7 @@ export const SelectReportedUserView: FC<{}> = props =>
{
const users: Map<number, IReportedUser> = new Map();
GetChatHistory().chats
.forEach(chat =>
GetChatHistory().chats.forEach(chat =>
{
if((chat.type === ChatEntryType.TYPE_CHAT) && (chat.entityType === RoomObjectType.USER) && (chat.entityId !== GetSessionDataManager().userId))
{
@ -37,64 +30,65 @@ export const SelectReportedUserView: FC<{}> = props =>
return Array.from(users.values());
}, []);
const submitUser = useCallback(() =>
const submitUser = () =>
{
if(selectedUserId <= 0) return;
const reportState = Object.assign({}, helpReportState);
reportState.reportedUserId = selectedUserId;
reportState.currentStep = 2;
setHelpReportState(reportState);
}, [helpReportState, selectedUserId, setHelpReportState]);
setHelpReportState(prevValue =>
{
const reportedUserId = selectedUserId;
const currentStep = 2;
const selectUser = useCallback((userId: number) =>
return { ...prevValue, reportedUserId, currentStep };
});
}
const selectUser = (userId: number) =>
{
if(selectedUserId === userId) setSelectedUserId(-1);
else setSelectedUserId(userId);
}, [selectedUserId]);
}
const back = useCallback(() =>
const back = () =>
{
const reportState = Object.assign({}, helpReportState);
reportState.currentStep = --reportState.currentStep;
setHelpReportState(reportState);
}, [helpReportState, setHelpReportState]);
setHelpReportState(prevValue =>
{
const currentStep = (prevValue.currentStep - 1);
return { ...prevValue, currentStep };
});
}
return (
<Grid>
<Column center size={ 5 } overflow="hidden">
<Base className="index-image" />
<>
<Column gap={ 1 }>
<Text fontSize={ 3 }>{ LocalizeText('help.emergency.main.step.two.title') }</Text>
{ (availableUsers.length > 0) &&
<Text>{ LocalizeText('report.user.pick.user') }</Text> }
</Column>
<Column justifyContent="center" size={ 7 } overflow="hidden">
<Column gap={ 1 }>
<Text fontSize={ 3 }>{ LocalizeText('help.emergency.main.step.two.title') }</Text>
{ (availableUsers.length > 0) &&
<Text>{ LocalizeText('report.user.pick.user') }</Text> }
</Column>
<Column gap={ 1 }>
{ !!!availableUsers.length &&
<Text>{ LocalizeText('report.user.error.nolist') }</Text> }
{ (availableUsers.length > 0) &&
<Grid grow columnCount={ 1 } gap={ 1 } overflow="auto">
{ availableUsers.map((user, index) =>
{
return (
<LayoutGridItem key={ user.id } onClick={ event => selectUser(user.id) } itemActive={ (selectedUserId === user.id) }>
<span dangerouslySetInnerHTML={{ __html: (user.username) }} />
</LayoutGridItem>
);
}) }
</Grid> }
</Column>
<Flex gap={ 2 } justifyContent="between">
<Button variant="secondary" onClick={ back }>
{ LocalizeText('generic.back') }
</Button>
<Button disabled={ (selectedUserId <= 0) } onClick={ submitUser }>
{ LocalizeText('help.emergency.main.submit.button') }
</Button>
</Flex>
<Column gap={ 1 }>
{ !!!availableUsers.length &&
<Text>{ LocalizeText('report.user.error.nolist') }</Text> }
{ (availableUsers.length > 0) &&
<Grid gap={ 1 } columnCount={ 1 } overflow="auto">
{ availableUsers.map((user, index) =>
{
return (
<LayoutGridItem key={ user.id } onClick={ event => selectUser(user.id) } itemActive={ (selectedUserId === user.id) }>
<span dangerouslySetInnerHTML={{ __html: (user.username) }} />
</LayoutGridItem>
);
}) }
</Grid> }
</Column>
</Grid>
)
<Flex gap={ 2 } justifyContent="between">
<Button variant="secondary" onClick={ back }>
{ LocalizeText('generic.back') }
</Button>
<Button disabled={ (selectedUserId <= 0) } onClick={ submitUser }>
{ LocalizeText('help.emergency.main.submit.button') }
</Button>
</Flex>
</>
);
}

View File

@ -1,64 +1,61 @@
import { FC, useCallback, useMemo, useState } from 'react';
import { FC, useMemo, useState } from 'react';
import { LocalizeText } from '../../../api';
import { Button, Column, Flex, Text } from '../../../common';
import { GetCfhCategories } from '../../../views/mod-tools/common/GetCFHCategories';
import { useHelpContext } from '../HelpContext';
export const SelectTopicView: FC<{}> = props =>
{
const { helpReportState = null, setHelpReportState = null } = useHelpContext();
const [selectedCategory, setSelectedCategory] = useState(-1);
const [selectedTopic, setSelectedTopic] = useState(-1);
const { setHelpReportState = null } = useHelpContext();
const [ selectedCategory, setSelectedCategory ] = useState(-1);
const [ selectedTopic, setSelectedTopic ] = useState(-1);
const cfhCategories = useMemo(() =>
const cfhCategories = useMemo(() => GetCfhCategories(), []);
const submitTopic = () =>
{
return GetCfhCategories();
}, []);
if((selectedCategory < 0) || (selectedTopic < 0)) return;
const submitTopic = useCallback(() =>
setHelpReportState(prevValue =>
{
const cfhCategory = selectedCategory;
const cfhTopic = cfhCategories[selectedCategory].topics[selectedTopic].id;
const currentStep = 4;
return { ...prevValue, cfhCategory, cfhTopic, currentStep };
});
}
const back = () =>
{
if(selectedCategory < 0) return;
if(selectedTopic < 0) return;
setHelpReportState(prevValue =>
{
const currentStep = (prevValue.currentStep - 1);
const reportState = Object.assign({}, helpReportState);
reportState.cfhCategory = selectedCategory;
reportState.cfhTopic = cfhCategories[selectedCategory].topics[selectedTopic].id;
reportState.currentStep = 4;
setHelpReportState(reportState);
}, [cfhCategories, helpReportState, selectedCategory, selectedTopic, setHelpReportState]);
const back = useCallback(() =>
{
const reportState = Object.assign({}, helpReportState);
reportState.currentStep = --reportState.currentStep;
setHelpReportState(reportState);
}, [helpReportState, setHelpReportState]);
return { ...prevValue, currentStep };
});
}
return (
<>
<div className="d-grid col-12 mx-auto justify-content-center">
<div className="col-12"><h3 className="fw-bold">{LocalizeText('help.emergency.chat_report.subtitle')}</h3></div>
<div className="text-wrap">{LocalizeText('help.cfh.pick.topic')}</div>
</div>
<div className="d-grid gap-2 col-8 mx-auto">
{(selectedCategory < 0) &&
cfhCategories.map((category, index) =>
{
return <button key={index} className="btn btn-danger" type="button" onClick={() => setSelectedCategory(index)}>{LocalizeText(`help.cfh.reason.${category.name}`)}</button>
})
}
{(selectedCategory >= 0) &&
cfhCategories[selectedCategory].topics.map((topic, index) =>
{
return <button key={index} className="btn btn-danger" type="button" onClick={() => setSelectedTopic(index)}>{LocalizeText('help.cfh.topic.' + topic.id)}</button>
})
}
</div>
<div className="d-flex gap-2 justify-content-between mt-auto">
<button className="btn btn-secondary mt-2" type="button" onClick={back}>{LocalizeText('generic.back')}</button>
<button className="btn btn-primary mt-2" type="button" disabled={selectedTopic < 0} onClick={submitTopic}>{LocalizeText('help.emergency.main.submit.button')}</button>
</div>
<Column gap={ 1 }>
<Text fontSize={ 3 }>{ LocalizeText('help.emergency.chat_report.subtitle') }</Text>
<Text>{ LocalizeText('help.cfh.pick.topic') }</Text>
</Column>
<Column gap={ 1 } overflow="auto">
{ (selectedCategory < 0) &&
cfhCategories.map((category, index) => <Button key={ index } variant="danger" onClick={ event => setSelectedCategory(index) }>{ LocalizeText(`help.cfh.reason.${ category.name }`) }</Button>) }
{ (selectedCategory >= 0) &&
cfhCategories[selectedCategory].topics.map((topic, index) => <Button key={ index } variant="danger" onClick={ event => setSelectedTopic(index) } active={ (selectedTopic === index) }>{ LocalizeText(`help.cfh.topic.${ topic.id }`) }</Button>) }
</Column>
<Flex gap={ 2 } justifyContent="between">
<Button variant="secondary" onClick={ back }>
{ LocalizeText('generic.back') }
</Button>
<Button disabled={ (selectedTopic < 0) } onClick={ submitTopic }>
{ LocalizeText('help.emergency.main.submit.button') }
</Button>
</Flex>
</>
);
}