update
This commit is contained in:
97
frontend/src/components/chat/NewChatDialog.tsx
Normal file
97
frontend/src/components/chat/NewChatDialog.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import React, { useState } from 'react';
|
||||
import Dialog from '@mui/material/Dialog';
|
||||
import DialogTitle from '@mui/material/DialogTitle';
|
||||
import DialogContent from '@mui/material/DialogContent';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import List from '@mui/material/List';
|
||||
import ListItem from '@mui/material/ListItem';
|
||||
import ListItemButton from '@mui/material/ListItemButton';
|
||||
import ListItemAvatar from '@mui/material/ListItemAvatar';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import Avatar from '@mui/material/Avatar';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import Box from '@mui/material/Box';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { nextcloudApi } from '../../services/nextcloud';
|
||||
|
||||
interface NewChatDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onRoomCreated: (token: string) => void;
|
||||
}
|
||||
|
||||
const NewChatDialog: React.FC<NewChatDialogProps> = ({ open, onClose, onRoomCreated }) => {
|
||||
const [search, setSearch] = useState('');
|
||||
const [creating, setCreating] = useState(false);
|
||||
|
||||
const { data: users, isLoading } = useQuery({
|
||||
queryKey: ['nextcloud', 'users', search],
|
||||
queryFn: () => nextcloudApi.searchUsers(search),
|
||||
enabled: open && search.length >= 2,
|
||||
staleTime: 30_000,
|
||||
});
|
||||
|
||||
const handleSelect = async (userId: string, displayName: string) => {
|
||||
setCreating(true);
|
||||
try {
|
||||
const { token } = await nextcloudApi.createRoom(1, userId, displayName);
|
||||
onRoomCreated(token);
|
||||
onClose();
|
||||
} catch {
|
||||
// ignore
|
||||
} finally {
|
||||
setCreating(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setSearch('');
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={handleClose} maxWidth="xs" fullWidth>
|
||||
<DialogTitle>Neues Gespr\u00E4ch</DialogTitle>
|
||||
<DialogContent sx={{ pb: 1 }}>
|
||||
<TextField
|
||||
autoFocus
|
||||
fullWidth
|
||||
size="small"
|
||||
placeholder="Benutzer suchen..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
sx={{ mb: 1 }}
|
||||
/>
|
||||
{(isLoading || creating) && (
|
||||
<Box sx={{ display: 'flex', justifyContent: 'center', py: 1 }}>
|
||||
<CircularProgress size={24} />
|
||||
</Box>
|
||||
)}
|
||||
{!isLoading && !creating && search.length >= 2 && (!users || users.length === 0) && (
|
||||
<Typography variant="body2" color="text.secondary" sx={{ py: 1, textAlign: 'center' }}>
|
||||
Keine Benutzer gefunden
|
||||
</Typography>
|
||||
)}
|
||||
{!creating && users && users.length > 0 && (
|
||||
<List disablePadding>
|
||||
{users.map((user) => (
|
||||
<ListItem key={user.id} disablePadding>
|
||||
<ListItemButton onClick={() => handleSelect(user.id, user.label)}>
|
||||
<ListItemAvatar sx={{ minWidth: 40 }}>
|
||||
<Avatar sx={{ width: 32, height: 32, fontSize: '0.75rem' }}>
|
||||
{user.label.substring(0, 2).toUpperCase()}
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={user.label} secondary={user.id} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewChatDialog;
|
||||
Reference in New Issue
Block a user