index.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright 2017-2020 @polkadot/app-accounts authors & contributors
  2. // This software may be modified and distributed under the terms
  3. // of the Apache-2.0 license. See the LICENSE file for details.
  4. import { ComponentProps as Props } from '../types';
  5. import React, { useEffect, useState } from 'react';
  6. import styled from 'styled-components';
  7. import { Button, Input, Table } from '@polkadot/react-components';
  8. import { useAddresses, useFavorites, useToggle } from '@polkadot/react-hooks';
  9. import CreateModal from './modals/Create';
  10. import Address from './Address';
  11. import { useTranslation } from '../translate';
  12. type SortedAddress = { address: string; isFavorite: boolean };
  13. const STORE_FAVS = 'accounts:favorites';
  14. function Overview ({ className, onStatusChange }: Props): React.ReactElement<Props> {
  15. const { t } = useTranslation();
  16. const { allAddresses } = useAddresses();
  17. const [isCreateOpen, toggleCreate] = useToggle(false);
  18. const [favorites, toggleFavorite] = useFavorites(STORE_FAVS);
  19. const [sortedAddresses, setSortedAddresses] = useState<SortedAddress[]>([]);
  20. const [filter, setFilter] = useState<string>('');
  21. useEffect((): void => {
  22. setSortedAddresses(
  23. allAddresses
  24. .map((address): SortedAddress => ({ address, isFavorite: favorites.includes(address) }))
  25. .sort((a, b): number =>
  26. a.isFavorite === b.isFavorite
  27. ? 0
  28. : b.isFavorite
  29. ? 1
  30. : -1
  31. )
  32. );
  33. }, [allAddresses, favorites]);
  34. return (
  35. <div className={className}>
  36. <Button.Group>
  37. <Button
  38. icon='add'
  39. label={t('Add contact')}
  40. onClick={toggleCreate}
  41. />
  42. </Button.Group>
  43. {isCreateOpen && (
  44. <CreateModal
  45. onClose={toggleCreate}
  46. onStatusChange={onStatusChange}
  47. />
  48. )}
  49. <Table>
  50. <Table.Head filter={
  51. <div className='filter--tags'>
  52. <Input
  53. autoFocus
  54. isFull
  55. label={t('filter by name or tags')}
  56. onChange={setFilter}
  57. value={filter}
  58. />
  59. </div>
  60. }>
  61. <th
  62. className='start'
  63. colSpan={2}
  64. >
  65. <h1>{t('contacts')}</h1>
  66. </th>
  67. <th className='start'>{t('tags')}</th>
  68. <th>{t('transactions')}</th>
  69. <th>{t('balances')}</th>
  70. <th colSpan={2}>&nbsp;</th>
  71. </Table.Head>
  72. <Table.Body empty={t('no addresses saved yet, add any existing address')}>
  73. {sortedAddresses.map(({ address, isFavorite }): React.ReactNode => (
  74. <Address
  75. address={address}
  76. filter={filter}
  77. isFavorite={isFavorite}
  78. key={address}
  79. toggleFavorite={toggleFavorite}
  80. />
  81. ))}
  82. </Table.Body>
  83. </Table>
  84. </div>
  85. );
  86. }
  87. export default React.memo(styled(Overview)`
  88. .filter--tags {
  89. .ui--Dropdown {
  90. padding-left: 0;
  91. label {
  92. left: 1.55rem;
  93. }
  94. }
  95. }
  96. `);