index.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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, useMemo, 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 [filterOn, 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. const header = useMemo(() => [
  35. [t('contacts'), 'start', 2],
  36. [t('tags'), 'start'],
  37. [t('transactions'), 'ui--media-1500'],
  38. [t('balances')],
  39. [],
  40. [undefined, 'mini ui--media-1400']
  41. ], [t]);
  42. const filter = useMemo(() => (
  43. <div className='filter--tags'>
  44. <Input
  45. autoFocus
  46. isFull
  47. label={t<string>('filter by name or tags')}
  48. onChange={setFilter}
  49. value={filterOn}
  50. />
  51. </div>
  52. ), [filterOn, t]);
  53. return (
  54. <div className={className}>
  55. <Button.Group>
  56. <Button
  57. icon='plus'
  58. label={t<string>('Add contact')}
  59. onClick={toggleCreate}
  60. />
  61. </Button.Group>
  62. {isCreateOpen && (
  63. <CreateModal
  64. onClose={toggleCreate}
  65. onStatusChange={onStatusChange}
  66. />
  67. )}
  68. <Table
  69. empty={t<string>('no addresses saved yet, add any existing address')}
  70. filter={filter}
  71. header={header}
  72. >
  73. {sortedAddresses.map(({ address, isFavorite }): React.ReactNode => (
  74. <Address
  75. address={address}
  76. filter={filterOn}
  77. isFavorite={isFavorite}
  78. key={address}
  79. toggleFavorite={toggleFavorite}
  80. />
  81. ))}
  82. </Table>
  83. </div>
  84. );
  85. }
  86. export default React.memo(styled(Overview)`
  87. .filter--tags {
  88. .ui--Dropdown {
  89. padding-left: 0;
  90. label {
  91. left: 1.55rem;
  92. }
  93. }
  94. }
  95. `);