@mui/material#ListItemAvatar TypeScript Examples

The following examples show how to use @mui/material#ListItemAvatar. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AccountClearingListEntry.tsx    From abrechnung with GNU Affero General Public License v3.0 6 votes vote down vote up
export default function AccountClearingListEntry({ group, account, accountID }) {
    const balances = useRecoilValue(accountBalances(group.id));

    return (
        <ListItemLink to={`/groups/${group.id}/accounts/${account.id}`}>
            <ListItemAvatar sx={{ minWidth: { xs: "40px", md: "56px" } }}>
                <Tooltip title="Clearing Account">
                    <ClearingAccountIcon color="primary" />
                </Tooltip>
            </ListItemAvatar>
            <ListItemText
                primary={
                    <Typography variant="body1" component="span">
                        {account.name}
                    </Typography>
                }
                secondary={account.description}
            />
            <ListItemText>
                <Typography align="right" variant="body2">
                    <Typography
                        component="span"
                        sx={{
                            color: (theme) => balanceColor(balances[account.id].clearingResolution[accountID], theme),
                        }}
                    >
                        {balances[account.id].clearingResolution[accountID].toFixed(2)} {group.currency_symbol}
                    </Typography>
                    <br />
                    <Typography component="span" sx={{ typography: "body2", color: "text.secondary" }}>
                        last changed: {DateTime.fromISO(account.last_changed).toLocaleString(DateTime.DATETIME_FULL)}
                    </Typography>
                </Typography>
            </ListItemText>
        </ListItemLink>
    );
}
Example #2
Source File: FileList.tsx    From frontend with MIT License 6 votes vote down vote up
function FileList({ files, onDelete }: Props) {
  return (
    <List dense>
      {files.map((file, key) => (
        <ListItem
          key={key}
          secondaryAction={
            <IconButton edge="end" aria-label="delete" onClick={() => onDelete && onDelete(file)}>
              <Delete />
            </IconButton>
          }>
          <ListItemAvatar>
            <Avatar>
              <UploadFile />
            </Avatar>
          </ListItemAvatar>
          <ListItemText primary={file.type} />
          <ListItemText primary={file.name} />
        </ListItem>
      ))}
    </List>
  )
}
Example #3
Source File: AccountTransactionListEntry.tsx    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function AccountTransactionListEntry({ group, transaction, accountID }) {
    return (
        <ListItemLink to={`/groups/${group.id}/transactions/${transaction.id}`}>
            <ListItemAvatar sx={{ minWidth: { xs: "40px", md: "56px" } }}>
                {transaction.type === "purchase" ? (
                    <Tooltip title="Purchase">
                        <PurchaseIcon color="primary" />
                    </Tooltip>
                ) : transaction.type === "transfer" ? (
                    <Tooltip title="Money Transfer">
                        <TransferIcon color="primary" />
                    </Tooltip>
                ) : (
                    <Tooltip title="Unknown Transaction Type">
                        <HelpOutline color="primary" />
                    </Tooltip>
                )}
            </ListItemAvatar>
            <ListItemText
                primary={
                    <>
                        {transaction.is_wip && (
                            <Chip color="info" variant="outlined" label="WIP" size="small" sx={{ mr: 3 }} />
                        )}
                        <Typography variant="body1" component="span">
                            {transaction.description}
                        </Typography>
                    </>
                }
                secondary={DateTime.fromISO(transaction.billed_at).toLocaleString(DateTime.DATE_FULL)}
            />
            <ListItemText>
                <Typography align="right" variant="body2">
                    <Typography
                        component="span"
                        sx={{ color: (theme) => balanceColor(transaction.account_balances[accountID].total, theme) }}
                    >
                        {transaction.account_balances[accountID].total.toFixed(2)} {group.currency_symbol}
                    </Typography>
                    <br />
                    <Typography component="span" sx={{ typography: "body2", color: "text.secondary" }}>
                        last changed:{" "}
                        {DateTime.fromISO(transaction.last_changed).toLocaleString(DateTime.DATETIME_FULL)}
                    </Typography>
                </Typography>
            </ListItemText>
        </ListItemLink>
    );
}
Example #4
Source File: TransactionListEntry.tsx    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
export function TransactionListEntry({ group, transaction }) {
    const accounts = useRecoilValue(accountsSeenByUser(group.id));
    const accountNamesFromShares = (shares) => {
        return shares.map((s) => accounts.find((a) => a.id === parseInt(s))?.name).join(", ");
    };

    return (
        <>
            <ListItemLink to={`/groups/${group.id}/transactions/${transaction.id}`}>
                <ListItemAvatar sx={{ minWidth: { xs: "40px", md: "56px" } }}>
                    {transaction.type === "purchase" ? (
                        <Tooltip title="Purchase">
                            <PurchaseIcon color="primary" />
                        </Tooltip>
                    ) : transaction.type === "transfer" ? (
                        <Tooltip title="Money Transfer">
                            <TransferIcon color="primary" />
                        </Tooltip>
                    ) : (
                        <Tooltip title="Unknown Transaction Type">
                            <HelpOutline color="primary" />
                        </Tooltip>
                    )}
                </ListItemAvatar>
                <ListItemText
                    primary={
                        <>
                            {transaction.is_wip && (
                                <Chip color="info" variant="outlined" label="WIP" size="small" sx={{ mr: 1 }} />
                            )}
                            <Typography variant="body1" component="span">
                                {transaction.description}
                            </Typography>
                        </>
                    }
                    secondary={
                        <>
                            <Typography variant="body2" component="span" sx={{ color: "text.primary" }}>
                                by {accountNamesFromShares(Object.keys(transaction.creditor_shares))}, for{" "}
                                {accountNamesFromShares(Object.keys(transaction.debitor_shares))}
                            </Typography>
                            <br />
                            {DateTime.fromISO(transaction.billed_at).toLocaleString(DateTime.DATE_FULL)}
                        </>
                    }
                />
                <ListItemText>
                    <Typography align="right" variant="body2">
                        {transaction.value.toFixed(2)} {transaction.currency_symbol}
                        <br />
                        <Typography component="span" sx={{ typography: "body2", color: "text.secondary" }}>
                            last changed:{" "}
                            {DateTime.fromISO(transaction.last_changed).toLocaleString(DateTime.DATETIME_FULL)}
                        </Typography>
                    </Typography>
                </ListItemText>
            </ListItemLink>
            <Divider sx={{ display: { lg: "none" } }} component="li" />
        </>
    );
}
Example #5
Source File: ListConversation.tsx    From airmessage-web with Apache License 2.0 5 votes vote down vote up
export default function ListConversation(props: {conversation: Conversation, selected?: boolean, highlighted?: boolean, onSelected: () => void, flippedProps?: Record<string, unknown>}) {
	//Getting the conversation title
	const [title, setConversationTitle] = useState(ConversationUtils.getFallbackTitle(props.conversation));
	useEffect(() => {
		//Updating the conversation's name if it has one
		if(props.conversation.name) {
			setConversationTitle(props.conversation.name);
			return;
		}
		
		//Building the conversation title
		ConversationUtils.getMemberTitle(props.conversation.members).then((title) => setConversationTitle(title));
	}, [props.conversation.name, props.conversation.members]);
	
	const primaryStyle: TypographyProps = props.highlighted ? {
		color: "primary",
		sx: {
			fontSize: "1rem",
			fontWeight: "bold"
		}
	} : {
		sx: {
			fontSize: "1rem",
			fontWeight: 500
		}
	};
	
	const secondaryStyle: TypographyProps = props.highlighted ? {
		color: "textPrimary",
		sx: {
			fontWeight: "bold"
		}
	} : {};
	
	return (
		<div className={styles.containerOuter} {...props.flippedProps}>
			<ListItemButton
				className={styles.containerInner}
				key={props.conversation.localID}
				onClick={props.onSelected}
				selected={props.selected}
				sx={{
					"&&.Mui-selected, &&.Mui-selected:hover": {
						backgroundColor: "action.selected"
					},
					"&&:hover": {
						backgroundColor: "action.hover"
					}
				}}>
				<ListItemAvatar>
					<GroupAvatar members={props.conversation.members} />
				</ListItemAvatar>
				<ListItemText className={styles.textPreview} primary={title} primaryTypographyProps={primaryStyle} secondary={previewString(props.conversation.preview)} secondaryTypographyProps={secondaryStyle} />
				<Typography className={styles.textTime} variant="body2" color="textSecondary">{getLastUpdateStatusTime(props.conversation.preview.date)}</Typography>
			</ListItemButton>
		</div>
	);
}
Example #6
Source File: TLSCertificate.tsx    From console with GNU Affero General Public License v3.0 5 votes vote down vote up
TLSCertificate = ({
  classes,
  certificateInfo,
  onDelete = () => {},
}: ITLSCertificate) => {
  const certificates = certificateInfo.domains || [];
  return (
    <Chip
      key={certificateInfo.name}
      variant="outlined"
      color="primary"
      className={classes.certificateWrapper}
      label={
        <Container>
          <Grid item xs={1} className={classes.certificateIcon}>
            <CertificateIcon />
          </Grid>
          <Grid item xs={11} className={classes.certificateInfo}>
            <Typography variant="subtitle1" display="block" gutterBottom>
              {certificateInfo.name}
            </Typography>
            <Box className={classes.certificateExpiry}>
              <EventBusyIcon color="inherit" fontSize="small" />
              &nbsp;
              <span className={"label"}>Expiry:&nbsp;</span>
              <span>
                <Moment format="YYYY/MM/DD">{certificateInfo.expiry}</Moment>
              </span>
            </Box>
            <Divider />
            <br />
            <Box className={classes.certificateDomains}>
              <span className="label">{`${certificates.length} Domain (s):`}</span>
            </Box>
            <List className={classes.certificatesList}>
              {certificates.map((dom) => (
                <ListItem className={classes.certificatesListItem}>
                  <ListItemAvatar>
                    <LanguageIcon />
                  </ListItemAvatar>
                  <ListItemText primary={dom} />
                </ListItem>
              ))}
            </List>
          </Grid>
        </Container>
      }
      onDelete={onDelete}
    />
  );
}
Example #7
Source File: Loading.tsx    From NekoMaid with MIT License 5 votes vote down vote up
LoadingList: React.FC<{ count?: number }> = ({ count = 3 }) => <>{Array.from({ length: count }, (_, i) => <ListItem key={i}>
  <ListItemAvatar><Skeleton animation='wave' variant='circular' width={40} height={40} /></ListItemAvatar>
  <ListItemText primary={<Skeleton animation='wave' />} />
</ListItem>)}</>
Example #8
Source File: Dashboard.tsx    From NekoMaid with MIT License 5 votes vote down vote up
Players: React.FC<{ players?: CurrentStatus['players'] }> = React.memo(({ players }) => {
  const his = useHistory()
  const plugin = usePlugin()
  const globalData = useGlobalData()
  const [page, setPage] = useState(1)
  const [id, update] = useState(0)
  return <Card>
    <CardHeader title={lang.dashboard.onlinePlayers} />
    <Divider />
    <CardContent>
      {players?.length === 0
        ? <Empty />
        : <>
        <List sx={{ paddingTop: 0 }}>
          {players
            ? players.slice((page - 1) * 8, page * 8).map(p => {
              const name = typeof p === 'string' ? p : p.name
              return <Tooltip key={name} title={'IP: ' + ((p as any).ip || lang.unknown)}>
                <ListItem
                  secondaryAction={<>
                    <IconButton
                      edge='end'
                      size='small'
                      onClick={() => dialog(lang.dashboard.confirmKick(<span className='bold'>{name}</span>), lang.reason)
                        .then(it => it != null && plugin.emit('dashboard:kick', (res: boolean) => {
                          action(res)
                          if (!players) return
                          players.splice(players.indexOf(it!), 1)
                          update(id + 1)
                        }, name, it || null))
                      }
                    ><ExitToApp /></IconButton>
                    <IconButton edge='end' onClick={() => his.push('/NekoMaid/playerList/' + name)} size='small'><MoreHoriz /></IconButton>
                  </>
                  }
                >
                  <ListItemAvatar>
                    <Avatar
                      src={getSkin(globalData, name, true)}
                      imgProps={{ crossOrigin: 'anonymous', onClick () { his.push('/NekoMaid/playerList/' + name) }, style: { width: 40, height: 40 } }}
                      sx={{ cursor: 'pointer' }}
                      variant='rounded'
                    />
                  </ListItemAvatar>
                  <ListItemText primary={name} />
                </ListItem>
              </Tooltip>
            })
            : <LoadingList />
          }
        </List>
        {players && <Pagination
          page={page}
          onChange={(_, it) => setPage(it)}
          count={Math.max(Math.ceil(players.length / 8), 1)}
          sx={{ display: 'flex', justifyContent: 'flex-end' }}
        />}
      </>}
    </CardContent>
  </Card>
})
Example #9
Source File: FileList.tsx    From frontend with MIT License 5 votes vote down vote up
function FileList({ files, onDelete, onSetFileRole, filesRole = [] }: Props) {
  const setFileRole = (file: File) => {
    return (event: SelectChangeEvent<CampaignFileRole>) => {
      if (Object.values(CampaignFileRole).includes(event.target.value as CampaignFileRole)) {
        onSetFileRole(file, event.target.value as CampaignFileRole)
      }
    }
  }

  return (
    <List dense>
      {files.map((file, key) => (
        <ListItem
          key={key}
          secondaryAction={
            <IconButton edge="end" aria-label="delete" onClick={() => onDelete && onDelete(file)}>
              <Delete />
            </IconButton>
          }>
          <ListItemAvatar>
            <Avatar>
              <UploadFile />
            </Avatar>
          </ListItemAvatar>
          <ListItemText primary={file.type} />
          <ListItemText primary={file.name} />
          <FormControl>
            <InputLabel id="choose-type-label">{'Избери роля'}</InputLabel>
            <Select<CampaignFileRole>
              id="choose-type"
              label="Избери роля"
              labelId="choose-type-label"
              value={
                filesRole.find((f) => f.file === file.name)?.role ?? CampaignFileRole.background
              }
              onChange={setFileRole(file)}>
              {Object.values(CampaignFileRole).map((role) => (
                <MenuItem key={role} value={role}>
                  {role}
                </MenuItem>
              ))}
            </Select>
          </FormControl>
        </ListItem>
      ))}
    </List>
  )
}
Example #10
Source File: IrregularityFile.tsx    From frontend with MIT License 5 votes vote down vote up
export default function IrregularityFile({ file, irregularityId }: Props) {
  const { t } = useTranslation('irregularity')
  const queryClient = useQueryClient()
  const router = useRouter()

  const mutation = useMutation<AxiosResponse<IrregularityFileResponse>, AxiosError<ApiErrors>>({
    mutationFn: deleteIrregularityFile(file.id),
    onError: () => AlertStore.show(t('admin.alerts.error'), 'error'),
    onSuccess: () => {
      AlertStore.show(t('admin.alerts.delete-file'), 'success')
      queryClient.invalidateQueries(endpoints.irregularity.viewIrregularity(irregularityId).url)
      router.push(routes.admin.irregularity.index)
    },
  })

  const deleteFileHandler = () => {
    mutation.mutate()
  }

  return (
    <ListItem key={file.id}>
      <ListItemAvatar>
        <Avatar>
          <FilePresentIcon />
        </Avatar>
      </ListItemAvatar>
      <ListItemText primary={file.filename} />
      <></>
      <Tooltip
        title={
          'Note: This link is public on the API side! Need to correct before official release!'
        }>
        <Button>
          {/* TODO: to be discussed. Tracked in issue: https://github.com/podkrepi-bg/frontend/issues/811 */}
          <a style={{ color: 'red' }} href={API_URL + `/irregularity-file/${file.id}`}>
            {t('admin.cta.download') + '*'}
          </a>
        </Button>
      </Tooltip>
      <Button onClick={deleteFileHandler}>{t('admin.cta.delete')}</Button>
    </ListItem>
  )
}
Example #11
Source File: Config.tsx    From NekoMaid with MIT License 4 votes vote down vote up
configs.push({
  title: lang.config.serverConfig,
  component () {
    const plugin = usePlugin()
    const globalData = useGlobalData()
    const [flag, update] = useState(0)
    const [info, setInfo] = useState<Record<string, string>>({ })
    const [open, setOpen] = useState(false)
    const [canGetData, setCanGetData] = useState(true)
    const [loading, setLoading] = useState(false)
    const setValue = (field: string, value: any, isGlobal = true) => {
      plugin.emit('server:set', field, value)
      success()
      if (isGlobal) {
        (globalData as any)[field] = value
        update(flag + 1)
        location.reload()
      }
    }
    const createEditButtom = (field: string, isGlobal?: boolean, isInt = true) => <IconButton
      onClick={() => dialog(
        {
          content: lang.inputValue,
          input: isInt
            ? {
                error: true,
                type: 'number',
                helperText: lang.invalidValue,
                validator: (it: string) => /^\d+$/.test(it) && +it >= 0
              }
            : { }
        }).then(res => res != null && setValue(field, isInt ? parseInt(res as any) : (res || null), isGlobal))}
    ><Edit /></IconButton>

    const infoElm: JSX.Element[] = []
    for (const key in info) {
      const name = (lang.config as any)[key]
      infoElm.push(<ListItem key={key} sx={{ pl: 4 }}>
        <ListItemText
          primary={key === 'isAikarFlags' ? <Link href='https://mcflags.emc.gs' target='_blank' rel='noopener'>{name}</Link> : name}
          secondary={info[key].toString()}
        />
      </ListItem>)
    }

    return <List>
      <CircularLoading loading={loading} />
      <ListItem secondaryAction={globalData.canSetMaxPlayers
        ? createEditButtom('maxPlayers')
        : undefined}>
        <ListItemText primary={lang.config.maxPlayers + ': ' + globalData.maxPlayers} />
      </ListItem>
      <ListItem secondaryAction={createEditButtom('spawnRadius')}>
        <ListItemText primary={lang.config.spawnRadius + ': ' + globalData.spawnRadius} />
      </ListItem>
      <ListItem secondaryAction={createEditButtom('motd', false, false)}>
        <ListItemText primary={lang.config.motd} />
      </ListItem>
      <ListItem secondaryAction={<Switch checked={globalData.hasWhitelist} onChange={e => setValue('hasWhitelist', e.target.checked)} />}>
        <ListItemText primary={lang.config.whitelist} />
      </ListItem>
      {canGetData && <>
        <ListItemButton onClick={() => {
          if (infoElm.length) setOpen(!open)
          else {
            setLoading(true)
            plugin.emit('server:fetchInfo', (data: any) => {
              setLoading(false)
              if (!data) {
                failed(lang.unsupported)
                setCanGetData(false)
                return
              }
              setInfo(data)
              setOpen(true)
            })
          }
        }}>
        <ListItemIcon><Equalizer /></ListItemIcon>
          <ListItemText primary={lang.info} />
          {open ? <ExpandLess /> : <ExpandMore />}
        </ListItemButton>
        <Collapse in={open} timeout='auto' unmountOnExit>
          <List component='div' dense disablePadding>{infoElm}</List>
        </Collapse>
      </>}
    </List>
  }
},
{
  title: lang.history,
  component () {
    const [cur, update] = useState(0)
    const list: ServerRecord[] = JSON.parse(localStorage.getItem('NekoMaid:servers') || '[]')
    return <List>
      {list.sort((a, b) => b.time - a.time).map(it => {
        const i = it.address.indexOf('?')
        return <ListItem
          disablePadding
          key={it.address}
          secondaryAction={<IconButton edge='end' size='small' onClick={() => {
            localStorage.setItem('NekoMaid:servers', JSON.stringify(list.filter(s => s.address !== it.address)))
            success()
            update(cur + 1)
          }}><Delete /></IconButton>}
        >
          <ListItemButton onClick={() => {
            location.hash = ''
            location.search = it.address
          }} dense>
            <ListItemAvatar><Avatar src={it.icon} variant='rounded'><HelpOutline /></Avatar></ListItemAvatar>
            <ListItemText primary={<Tooltip title={it.address.slice(i + 1)}>
              <span>{it.address.slice(0, i)}</span></Tooltip>} secondary={dayjs(it.time).fromNow()} />
          </ListItemButton>
        </ListItem>
      })}
    </List>
  }
},
{
  title: lang.config.theme,
  component () {
    const color = localStorage.getItem('NekoMaid:color') || 'blue'
    return <CardContent sx={{ textAlign: 'center' }}>
      <Box>
        <ToggleButtonGroup exclusive value={localStorage.getItem('NekoMaid:colorMode') || ''} onChange={(_, it) => {
          localStorage.setItem('NekoMaid:colorMode', it)
          location.reload()
        }}>
          <ToggleButton value='light'><Brightness7 /> {lang.config.light}</ToggleButton>
          <ToggleButton value=''><SettingsBrightness /> {lang.config.system}</ToggleButton>
          <ToggleButton value='dark'><Brightness4 /> {lang.config.dark}</ToggleButton>
        </ToggleButtonGroup>
      </Box>
      <Paper sx={{ marginTop: 2, width: '176px', overflow: 'hidden', display: 'inline-block' }}>
        {Object.keys(colors).slice(1, 17).map((key, i) => {
          const checked = color === key
          const elm = <Box
            key={key}
            onClick={() => {
              localStorage.setItem('NekoMaid:color', key)
              location.reload()
            }}
            sx={{
              backgroundColor: (colors as any)[key][600],
              width: '44px',
              height: '44px',
              display: 'inline-block',
              cursor: 'pointer'
            }}
          ><Check htmlColor='white' sx={{ top: '10px', position: 'relative', opacity: checked ? 1 : 0 }} /></Box>
          return (i + 1) % 4 === 0 ? <React.Fragment key={key}>{elm}<br /></React.Fragment> : elm
        })}
      </Paper>
    </CardContent>
  }
})