add new space modal

This commit is contained in:
Ajay Bura 2025-08-04 14:22:16 +05:30
parent b14c5290e0
commit 87c25dc5bf
7 changed files with 147 additions and 3 deletions

View file

@ -0,0 +1,95 @@
import React from 'react';
import {
Box,
config,
Header,
Icon,
IconButton,
Icons,
Modal,
Overlay,
OverlayBackdrop,
OverlayCenter,
Scroll,
Text,
} from 'folds';
import FocusTrap from 'focus-trap-react';
import { useAllJoinedRoomsSet, useGetRoom } from '../../hooks/useGetRoom';
import { SpaceProvider } from '../../hooks/useSpace';
import { CreateSpaceForm } from './CreateSpace';
import {
useCloseCreateSpaceModal,
useCreateSpaceModalState,
} from '../../state/hooks/createSpaceModal';
import { CreateSpaceModalState } from '../../state/createSpaceModal';
import { stopPropagation } from '../../utils/keyboard';
type CreateSpaceModalProps = {
state: CreateSpaceModalState;
};
function CreateSpaceModal({ state }: CreateSpaceModalProps) {
const { spaceId } = state;
const closeDialog = useCloseCreateSpaceModal();
const allJoinedRooms = useAllJoinedRoomsSet();
const getRoom = useGetRoom(allJoinedRooms);
const space = spaceId ? getRoom(spaceId) : undefined;
return (
<SpaceProvider value={space ?? null}>
<Overlay open backdrop={<OverlayBackdrop />}>
<OverlayCenter>
<FocusTrap
focusTrapOptions={{
initialFocus: false,
clickOutsideDeactivates: true,
onDeactivate: closeDialog,
escapeDeactivates: stopPropagation,
}}
>
<Modal size="300" flexHeight>
<Box direction="Column">
<Header
size="500"
style={{
padding: config.space.S200,
paddingLeft: config.space.S400,
borderBottomWidth: config.borderWidth.B300,
}}
>
<Box grow="Yes">
<Text size="H4">New Space</Text>
</Box>
<Box shrink="No">
<IconButton size="300" radii="300" onClick={closeDialog}>
<Icon src={Icons.Cross} />
</IconButton>
</Box>
</Header>
<Scroll size="300" hideTrack>
<Box
style={{
padding: config.space.S400,
paddingRight: config.space.S200,
}}
direction="Column"
gap="500"
>
<CreateSpaceForm space={space} onCreate={closeDialog} />
</Box>
</Scroll>
</Box>
</Modal>
</FocusTrap>
</OverlayCenter>
</Overlay>
</SpaceProvider>
);
}
export function CreateSpaceModalRenderer() {
const state = useCreateSpaceModalState();
if (!state) return null;
return <CreateSpaceModal state={state} />;
}

View file

@ -1 +1,2 @@
export * from './CreateSpace';
export * from './CreateSpaceModal';

View file

@ -30,11 +30,12 @@ import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import * as css from './SpaceItem.css';
import * as styleCss from './style.css';
import { useDraggableItem } from './DnD';
import { openCreateRoom, openSpaceAddExisting } from '../../../client/action/navigation';
import { openSpaceAddExisting } from '../../../client/action/navigation';
import { stopPropagation } from '../../utils/keyboard';
import { mxcUrlToHttp } from '../../utils/matrix';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { useOpenCreateRoomModal } from '../../state/hooks/createRoomModal';
import { useOpenCreateSpaceModal } from '../../state/hooks/createSpaceModal';
function SpaceProfileLoading() {
return (
@ -305,13 +306,14 @@ function AddRoomButton({ item }: { item: HierarchyItem }) {
function AddSpaceButton({ item }: { item: HierarchyItem }) {
const [cords, setCords] = useState<RectCords>();
const openCreateSpaceModal = useOpenCreateSpaceModal();
const handleAddSpace: MouseEventHandler<HTMLButtonElement> = (evt) => {
setCords(evt.currentTarget.getBoundingClientRect());
};
const handleCreateSpace = () => {
openCreateRoom(true, item.roomId as any);
openCreateSpaceModal(item.roomId as any);
setCords(undefined);
};

View file

@ -65,6 +65,7 @@ import { SpaceSettingsRenderer } from '../features/space-settings';
import { CreateRoomModalRenderer } from '../features/create-room';
import { HomeCreateRoom } from './client/home/CreateRoom';
import { Create } from './client/create';
import { CreateSpaceModalRenderer } from '../features/create-space';
export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize) => {
const { hashRouter } = clientConfig;
@ -130,6 +131,7 @@ export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize)
<Outlet />
</ClientLayout>
<CreateRoomModalRenderer />
<CreateSpaceModalRenderer />
<RoomSettingsRenderer />
<SpaceSettingsRenderer />
<ReceiveSelfDeviceVerification />

View file

@ -8,8 +8,11 @@ import {
PageHeroSection,
} from '../../../components/page';
import { CreateSpaceForm } from '../../../features/create-space';
import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
export function Create() {
const { navigateSpace } = useRoomNavigate();
return (
<Page>
<Box grow="Yes">
@ -23,7 +26,7 @@ export function Create() {
title="Create Space"
subTitle="Build a space for your community."
/>
<CreateSpaceForm />
<CreateSpaceForm onCreate={navigateSpace} />
</Box>
</PageHeroSection>
</PageContentCenter>

View file

@ -0,0 +1,7 @@
import { atom } from 'jotai';
export type CreateSpaceModalState = {
spaceId?: string;
};
export const createSpaceModalAtom = atom<CreateSpaceModalState | undefined>(undefined);

View file

@ -0,0 +1,34 @@
import { useCallback } from 'react';
import { useAtomValue, useSetAtom } from 'jotai';
import { createSpaceModalAtom, CreateSpaceModalState } from '../createSpaceModal';
export const useCreateSpaceModalState = (): CreateSpaceModalState | undefined => {
const data = useAtomValue(createSpaceModalAtom);
return data;
};
type CloseCallback = () => void;
export const useCloseCreateSpaceModal = (): CloseCallback => {
const setSettings = useSetAtom(createSpaceModalAtom);
const close: CloseCallback = useCallback(() => {
setSettings(undefined);
}, [setSettings]);
return close;
};
type OpenCallback = (space?: string) => void;
export const useOpenCreateSpaceModal = (): OpenCallback => {
const setSettings = useSetAtom(createSpaceModalAtom);
const open: OpenCallback = useCallback(
(spaceId) => {
setSettings({ spaceId });
},
[setSettings]
);
return open;
};