5180 fichiers 38.5 Mo 0 téléchargements 482 vues mis à jour il y a 7 heures ui
nitro-v36-with-renderer-v36 / src / components / housekeeping / views / rooms / HousekeepingRoomSettingsForm.tsx
HousekeepingRoomSettingsForm.tsx 7.6 Ko Télécharger le fichier
import { FC, useMemo, useState } from 'react';
import { FaSave, FaSlidersH, FaUndo } from 'react-icons/fa';
import {
    HK_ROOM_DESCRIPTION_MAX,
    HK_ROOM_MAX_USERS,
    HK_ROOM_MIN_USERS,
    HK_ROOM_NAME_MAX,
    HousekeepingErrorKey,
    IHousekeepingRoom,
    IHousekeepingRoomSettingsInput,
    LocalizeText,
    parseRoomTags,
    validateRoomSettings
} from '../../../../api';
import { useNavigatorData } from '../../../../hooks';
import { HOUSEKEEPING_INPUT_CLASS, HousekeepingButton, HousekeepingField, HousekeepingSection } from '../common/HousekeepingParts';
import { Select } from '../../../../common/Select';
import { NumberInput } from '../../../../common/NumberInput';
import { NativeTextTree } from '../../../../common/native-text/NativeTextTree';

interface HousekeepingRoomSettingsFormProps {
    room: IHousekeepingRoom;
    disabled: boolean;
    onSave: (input: IHousekeepingRoomSettingsInput) => void;
}

const draftFromRoom = (room: IHousekeepingRoom) => ({
    name: room.name,
    description: room.description,
    maxUsers: room.maxUsers,
    categoryId: room.settings?.categoryId ?? 0,
    tradeMode: room.settings?.tradeMode ?? 0,
    tags: (room.settings?.tags ?? []).join(', ')
});

/**
 * Editable name, description, capacity, category, trade mode and tags of the
 * selected room. The parent remounts it (by key) when the room changes, so the
 * draft always starts from what the server last sent.
 */
export const HousekeepingRoomSettingsForm: FC<HousekeepingRoomSettingsFormProps> = ({ room, disabled, onSave }) => {
    const initial = useMemo(() => draftFromRoom(room), [room]);
    const [draft, setDraft] = useState(initial);
    const { categories = null } = useNavigatorData();

    const input: IHousekeepingRoomSettingsInput = {
        name: draft.name.trim(),
        description: draft.description.trim(),
        maxUsers: draft.maxUsers,
        categoryId: draft.categoryId,
        tradeMode: draft.tradeMode,
        tags: parseRoomTags(draft.tags)
    };
    const error = validateRoomSettings(input);
    const isDirty = JSON.stringify(draft) !== JSON.stringify(initial);
    const categoryKnown = !!categories?.some((category) => category.id === draft.categoryId);

    const update = <K extends keyof typeof draft>(key: K, value: (typeof draft)[K]) => setDraft((previous) => ({ ...previous, [key]: value }));

    return (
        <NativeTextTree>
            <HousekeepingSection icon={<FaSlidersH className="text-sky-600" size={9} />} title={LocalizeText('housekeeping.room.settings.title')} tone="info">
                <div className="grid grid-cols-2 gap-1.5">
                    <HousekeepingField
                        className="col-span-2"
                        hint={`${draft.name.length}/${HK_ROOM_NAME_MAX}`}
                        label={LocalizeText('housekeeping.room.settings.name')}
                    >
                        <input
                            className={HOUSEKEEPING_INPUT_CLASS}
                            maxLength={HK_ROOM_NAME_MAX}
                            value={draft.name}
                            onChange={(event) => update('name', event.target.value)}
                        />
                    </HousekeepingField>
                    <HousekeepingField
                        className="col-span-2"
                        hint={`${draft.description.length}/${HK_ROOM_DESCRIPTION_MAX}`}
                        label={LocalizeText('housekeeping.room.settings.description')}
                    >
                        <textarea
                            className={`${HOUSEKEEPING_INPUT_CLASS} min-h-[40px] resize-y`}
                            maxLength={HK_ROOM_DESCRIPTION_MAX}
                            value={draft.description}
                            onChange={(event) => update('description', event.target.value)}
                        />
                    </HousekeepingField>
                    <HousekeepingField label={LocalizeText('navigator.category')}>
                        <Select
                            className={HOUSEKEEPING_INPUT_CLASS}
                            value={draft.categoryId}
                            onChange={(event) => update('categoryId', parseInt(event.target.value) || 0)}
                        >
                            {!categoryKnown && (
                                <option value={draft.categoryId}>
                                    {LocalizeText('housekeeping.room.settings.category_unknown', ['id'], [String(draft.categoryId)])}
                                </option>
                            )}
                            {(categories ?? []).map((category) => (
                                <option key={category.id} value={category.id}>
                                    {LocalizeText(category.name)}
                                </option>
                            ))}
                        </Select>
                    </HousekeepingField>
                    <HousekeepingField hint={`${HK_ROOM_MIN_USERS}-${HK_ROOM_MAX_USERS}`} label={LocalizeText('navigator.maxvisitors')}>
                        <NumberInput className={`${HOUSEKEEPING_INPUT_CLASS} tabular-nums`} max={HK_ROOM_MAX_USERS} min={HK_ROOM_MIN_USERS} value={draft.maxUsers || ''} onChange={(event) => update('maxUsers', parseInt(event.target.value) || 0)} />
                    </HousekeepingField>
                    <HousekeepingField label={LocalizeText('navigator.tradesettings')}>
                        <Select
                            className={HOUSEKEEPING_INPUT_CLASS}
                            value={draft.tradeMode}
                            onChange={(event) => update('tradeMode', parseInt(event.target.value) || 0)}
                        >
                            <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>
                    </HousekeepingField>
                    <HousekeepingField hint={LocalizeText('housekeeping.room.settings.tags_hint')} label={LocalizeText('housekeeping.room.settings.tags')}>
                        <input className={HOUSEKEEPING_INPUT_CLASS} value={draft.tags} onChange={(event) => update('tags', event.target.value)} />
                    </HousekeepingField>
                </div>
                <div className="flex items-center gap-1.5">
                    {error !== HousekeepingErrorKey.NONE && isDirty && (
                        <span className="text-[10px] font-semibold text-rose-600">{LocalizeText(`housekeeping.validation.${error}`)}</span>
                    )}
                    <HousekeepingButton classNames={['ml-auto']} disabled={disabled || !isDirty} gap={1} variant="secondary" onClick={() => setDraft(initial)}>
                        <FaUndo size={9} />
                        <span>{LocalizeText('housekeeping.room.settings.reset')}</span>
                    </HousekeepingButton>
                    <HousekeepingButton
                        disabled={disabled || !isDirty || error !== HousekeepingErrorKey.NONE}
                        gap={1}
                        variant="success"
                        onClick={() => onSave(input)}
                    >
                        <FaSave size={9} />
                        <span>{LocalizeText('housekeeping.room.settings.save')}</span>
                    </HousekeepingButton>
                </div>
            </HousekeepingSection>
        </NativeTextTree>
    );
};
15Sujets
1Dépôts
20Membres
3En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser