JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr{ gilour

File "select-user-dialog.tsx"

Full Path: /home/markqprx/iniasli.pro/common/resources/client/users/select-user-dialog.tsx
File size: 3.29 KB
MIME-type: text/plain
Charset: utf-8

import {Dialog} from '../ui/overlays/dialog/dialog';
import {DialogHeader} from '../ui/overlays/dialog/dialog-header';
import {Trans} from '../i18n/trans';
import {DialogBody} from '../ui/overlays/dialog/dialog-body';
import {TextField} from '../ui/forms/input-field/text-field/text-field';
import {SearchIcon} from '../icons/material/Search';
import {useState} from 'react';
import {useTrans} from '../i18n/use-trans';
import {message} from '../i18n/message';
import {Avatar} from '../ui/images/avatar';
import {NormalizedModel} from '../datatable/filters/normalized-model';
import {IllustratedMessage} from '../ui/images/illustrated-message';
import {SvgImage} from '../ui/images/svg-image/svg-image';
import teamSvg from '../admin/roles/team.svg';
import {useDialogContext} from '../ui/overlays/dialog/dialog-context';
import {useNormalizedModels} from './queries/use-normalized-models';

interface SelectUserDialogProps {
  onUserSelected: (user: NormalizedModel) => void;
}

export function SelectUserDialog({onUserSelected}: SelectUserDialogProps) {
  const {close} = useDialogContext();
  const [searchTerm, setSearchTerm] = useState<string>('');
  const {trans} = useTrans();
  const query = useNormalizedModels('normalized-models/user', {
    query: searchTerm,
    perPage: 14,
  });
  const users = query.data?.results || [];

  const emptyStateMessage = (
    <IllustratedMessage
      className="pt-20"
      size="sm"
      title={<Trans message="No matching users" />}
      description={<Trans message="Try another search query" />}
      image={<SvgImage src={teamSvg} />}
    />
  );

  const selectUser = (user: NormalizedModel) => {
    close();
    onUserSelected(user);
  };

  return (
    <Dialog>
      <DialogHeader>
        <Trans message="Select a user" />
      </DialogHeader>
      <DialogBody>
        <TextField
          autoFocus
          className="mb-20"
          startAdornment={<SearchIcon />}
          placeholder={trans(message('Search for user by name or email'))}
          value={searchTerm}
          onChange={e => {
            setSearchTerm(e.target.value);
          }}
        />
        {!query.isLoading && !users.length && emptyStateMessage}
        <div className="grid grid-cols-2 gap-x-10">
          {users.map(user => (
            <UserListItem
              key={user.id}
              user={user}
              onUserSelected={selectUser}
            />
          ))}
        </div>
      </DialogBody>
    </Dialog>
  );
}

interface UserListItemProps {
  user: NormalizedModel;
  onUserSelected: (user: NormalizedModel) => void;
}
function UserListItem({user, onUserSelected}: UserListItemProps) {
  return (
    <div
      key={user.id}
      className="flex items-center gap-10 rounded p-10 outline-none ring-offset-4 hover:bg-hover focus-visible:ring"
      role="button"
      tabIndex={0}
      onClick={() => {
        onUserSelected(user);
      }}
      onKeyDown={e => {
        if (e.key === 'Enter' || e.key === ' ') {
          e.preventDefault();
          onUserSelected(user);
        }
      }}
    >
      <Avatar src={user.image} />
      <div className="overflow-hidden">
        <div className="overflow-hidden text-ellipsis">{user.name}</div>
        <div className="overflow-hidden text-ellipsis text-muted">
          {user.description}
        </div>
      </div>
    </div>
  );
}