Files
explore/ui/shared/forms/inputs/file/FileSnippet.tsx
T
48b39022d3 Account v2 (#2262)
* simple profile button and auth modal layout

* connect email and code screens to API

* add screens to modal for wallet authentication

* migrate to pin input

* user profile menu

* refactor otp field

* fix passing set-cookie from api response

* add wallet info into profile menu

* add mobile menu

* show connected wallet address in button

* my profile page re-design

* custom behaviour of connect button on dapp page

* style pin input

* add logout

* handle case when account is disabled

* handle case when wc is disabled

* remove old components

* refactoring

* workflow to link wallet or email to account

* link wallet from profile

* show better OTP code errors

* add email alert on watchlist and verified addresses pages

* deprecate env and remove old code

* remove code for unverified email page

* add auth guard to address action items

* move useRedirectForInvalidAuthToken hook

* add mixpanel events

* refetch csrf token after login and fix connect wallet from contract page

* Add NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY env

* migrate to reCAPTCHA v3

* resend code and change email from profile page

* better wallet sign-in message error

* fix demo envs

* update some screenshots

* profile button design fixes

* fix behaviour "connect wallet" button on contract page

* fix linking email and wallet to existing account

* bug fixes

* restore the login page

* update screenshots

* tests for auth modal and user profile

* add name field to profile page and write some tests

* [skip ci] clean up and more tests

* update texts

* change text once more

* fix verified email checkmark behaviour

* pass api error to the toast while signing in with wallet

* [skip ci] disable email field on profile page

* bug fixes

* update screenshot

* Blockscout account V2

Fixes #2029

* fix texts and button paddings

* Form fields refactoring (#2320)

* text and address fields for watchlist form

* checkbox field component

* refactor private tags form

* refactor api keys and custom abi

* refactor verifiy address and token info forms (pt. 1)

* refactor token info forms (pt. 2)

* refactor token info forms (pt. 3)

* refactor public tags form

* refactor contract verification form

* refactor contract audit form

* refactor auth, profile and csv export forms

* renaming and moving

* more refactoring and test fixes

---------

Co-authored-by: aagaev <[email protected]>
2024-10-30 12:56:57 +01:00

108 lines
3.0 KiB
TypeScript

import { Box, Flex, Text, useColorModeValue, IconButton, chakra, Tooltip } from '@chakra-ui/react';
import React from 'react';
import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg';
const FILE_ICONS: Record<string, IconName> = {
'.json': 'files/json',
'.sol': 'files/sol',
'.yul': 'files/yul',
};
function getFileExtension(fileName: string) {
const chunks = fileName.split('.');
if (chunks.length === 1) {
return '';
}
return '.' + chunks[chunks.length - 1];
}
interface Props {
file: File;
className?: string;
index?: number;
onRemove?: (index?: number) => void;
isDisabled?: boolean;
error?: string;
}
const FileSnippet = ({ file, className, index, onRemove, isDisabled, error }: Props) => {
const handleRemove = React.useCallback((event: React.MouseEvent) => {
event.stopPropagation();
onRemove?.(index);
}, [ index, onRemove ]);
const handleErrorHintIconClick = React.useCallback((event: React.MouseEvent) => {
event.stopPropagation();
}, []);
const fileExtension = getFileExtension(file.name);
const fileIcon = FILE_ICONS[fileExtension] || 'files/placeholder';
const iconColor = useColorModeValue('gray.600', 'gray.400');
return (
<Flex
maxW="300px"
overflow="hidden"
className={ className }
alignItems="center"
textAlign="left"
>
<IconSvg
name={ fileIcon }
boxSize="74px"
color={ error ? 'error' : iconColor }
mr={ 2 }
borderWidth="2px"
borderRadius="md"
borderColor={ useColorModeValue('blackAlpha.100', 'whiteAlpha.200') }
p={ 3 }
/>
<Box maxW="calc(100% - 58px - 24px)">
<Flex alignItems="center">
<Text
fontWeight={ 600 }
overflow="hidden"
textOverflow="ellipsis"
whiteSpace="nowrap"
color={ error ? 'error' : 'initial' }
>
{ file.name }
</Text>
{ Boolean(error) && (
<Tooltip
label={ error }
placement="top"
maxW={{ base: 'calc(100vw - 8px)', lg: '320px' }}
>
<Box cursor="pointer" display="inherit" onClick={ handleErrorHintIconClick } ml={ 1 }>
<IconSvg name="info" boxSize={ 5 } color="error"/>
</Box>
</Tooltip>
) }
<IconButton
aria-label="remove"
icon={ <IconSvg name="cross" boxSize={ 6 }/> }
boxSize={ 6 }
variant="simple"
display="inline-block"
flexShrink={ 0 }
ml="auto"
onClick={ handleRemove }
isDisabled={ isDisabled }
alignSelf="flex-start"
/>
</Flex>
<Text variant="secondary" mt={ 1 }>
{ file.size.toLocaleString(undefined, { notation: 'compact', maximumFractionDigits: 2, unit: 'byte', unitDisplay: 'narrow', style: 'unit' }) }
</Text>
</Box>
</Flex>
);
};
export default React.memo(chakra(FileSnippet));