react-router#useNavigate TypeScript Examples
The following examples show how to use
react-router#useNavigate.
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: EntityOrphanWarning.tsx From backstage with Apache License 2.0 | 6 votes |
/**
* Displays a warning alert if the entity is marked as orphan with the ability
* to delete said entity.
*
* @public
*/
export function EntityOrphanWarning() {
const navigate = useNavigate();
const catalogLink = useRouteRef(rootRouteRef);
const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);
const { entity } = useEntity();
const cleanUpAfterRemoval = async () => {
setConfirmationDialogOpen(false);
navigate(catalogLink());
};
return (
<>
<Alert severity="warning" onClick={() => setConfirmationDialogOpen(true)}>
This entity is not referenced by any location and is therefore not
receiving updates. Click here to delete.
</Alert>
<DeleteEntityDialog
open={confirmationDialogOpen}
entity={entity!}
onConfirm={cleanUpAfterRemoval}
onClose={() => setConfirmationDialogOpen(false)}
/>
</>
);
}
Example #2
Source File: CreatePostageStampPage.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 6 votes |
export function CreatePostageStampPage(): ReactElement {
const navigate = useNavigate()
function onFinished() {
navigate(ROUTES.STAMPS)
}
return (
<div>
<HistoryHeader>Buy new postage stamp</HistoryHeader>
<PostageStampCreation onFinished={onFinished} />
</div>
)
}
Example #3
Source File: RoutedTabs.tsx From backstage with Apache License 2.0 | 6 votes |
export function RoutedTabs(props: { routes: SubRoute[] }) {
const { routes } = props;
const navigate = useNavigate();
const { index, route, element } = useSelectedSubRoute(routes);
const headerTabs = useMemo(
() =>
routes.map(t => ({
id: t.path,
label: t.title,
tabProps: t.tabProps,
})),
[routes],
);
const onTabChange = (tabIndex: number) =>
// Remove trailing /*
// And remove leading / for relative navigation
// Note! route resolves relative to the position in the React tree,
// not relative to current location
navigate(routes[tabIndex].path.replace(/\/\*$/, '').replace(/^\//, ''));
return (
<>
<HeaderTabs
tabs={headerTabs}
selectedIndex={index}
onChange={onTabChange}
/>
<Content>
<Helmet title={route.title} />
{element}
</Content>
</>
);
}
Example #4
Source File: index.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 6 votes |
export default function Index({ header, title, p, next }: Props): ReactElement {
const { nodeAddresses, balance } = useContext(Context)
const navigate = useNavigate()
if (!balance || !nodeAddresses) {
return <Loading />
}
const disabled = balance.dai.toDecimal.lte(1)
return (
<>
<HistoryHeader>{header}</HistoryHeader>
<Box mb={4}>
<TopUpProgressIndicator index={0} />
</Box>
<Box mb={2}>
<Typography style={{ fontWeight: 'bold' }}>{title}</Typography>
</Box>
<Box mb={4}>{p}</Box>
<SwarmDivider mb={4} />
<Box mb={0.25}>
<ExpandableListItemKey label="Funding wallet address" value={balance.address} expanded />
</Box>
<Box mb={4}>
<ExpandableListItem label="xDAI balance" value={balance.dai.toSignificantDigits(4)} />
</Box>
<Grid container direction="row" justifyContent="space-between">
<SwarmButton iconType={Check} onClick={() => navigate(next)} disabled={disabled}>
Proceed
</SwarmButton>
{disabled ? <Typography>Please deposit xDAI to the address above in order to proceed.</Typography> : null}
</Grid>
</>
)
}
Example #5
Source File: useCharSelectionCallback.tsx From genshin-optimizer with MIT License | 6 votes |
/**
* Basically a history hook to go to the dedicated character page. Will create the character if it doesn't exist.
* @returns
*/
export default function useCharSelectionCallback() {
const { database } = useContext(DatabaseContext)
const navigate = useNavigate()
// Used to maintain the previous tab, if there is one
let { params: { tab = "" } } = useMatch({ path: "/characters/:charKey/:tab", end: false }) ?? { params: { tab: "" } }
const cb = useCallback(
async (characterKey: CharacterKey) => {
const character = database._getChar(characterKey)
let navTab = tab
// Create a new character + weapon, with linking if char isnt in db.
if (!character) {
const newChar = initialCharacter(characterKey)
database.updateChar(newChar)
const characterSheet = await CharacterSheet.get(characterKey)
if (!characterSheet) return
const weapon = defaultInitialWeapon(characterSheet.weaponTypeKey)
const weaponId = database.createWeapon(weapon)
database.setWeaponLocation(weaponId, characterKey)
// If we are navigating to a new character,
// redirect to Overview, regardless of previous tab.
// Trying to enforce a certain UI flow when building new characters
navTab = ""
}
navigate(`/characters/${characterKey}/${navTab}`)
},
[navigate, database, tab],
)
return cb
}
Example #6
Source File: useRedirectMigratedContent.ts From atlas with GNU General Public License v3.0 | 6 votes |
useRedirectMigratedContent = ({ type }: { type: 'channel' | 'video' | 'embedded-video' }) => {
const { id } = useParams() as { id?: string }
const navigate = useNavigate()
useEffect(() => {
if (type !== 'channel' || !id || BUILD_ENV !== 'production') return
const mapping = migratedContentIdMappings.channelIdsMapEntries
const migratedId = mapping[id as keyof typeof mapping]
if (!migratedId) return
navigate(absoluteRoutes.viewer.channel(migratedId))
}, [id, navigate, type])
useEffect(() => {
if ((type !== 'video' && type !== 'embedded-video') || !id || BUILD_ENV !== 'production') return
const mapping = migratedContentIdMappings.videoIdsMapEntries
const migratedId = mapping[id as keyof typeof mapping]
if (!migratedId) return
if (type === 'embedded-video') {
navigate(absoluteRoutes.embedded.video(migratedId))
} else {
navigate(absoluteRoutes.viewer.video(migratedId))
}
}, [id, navigate, type])
}
Example #7
Source File: useEntityFromUrl.ts From backstage with Apache License 2.0 | 6 votes |
useEntityFromUrl = (): EntityLoadingStatus => {
const { kind, namespace, name } = useRouteRefParams(entityRouteRef);
const navigate = useNavigate();
const errorApi = useApi(errorApiRef);
const catalogApi = useApi(catalogApiRef);
const {
value: entity,
error,
loading,
retry: refresh,
} = useAsyncRetry(
() => catalogApi.getEntityByRef({ kind, namespace, name }),
[catalogApi, kind, namespace, name],
);
useEffect(() => {
if (!name) {
errorApi.post(new Error('No name provided!'));
navigate('/');
}
}, [errorApi, navigate, error, loading, entity, name]);
return { entity, loading, error, refresh };
}
Example #8
Source File: Restart.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 6 votes |
export default function Settings(): ReactElement {
const [waited, setWaited] = useState(false)
const { apiHealth } = useContext(Context)
const navigate = useNavigate()
useEffect(() => {
if (waited) {
return
}
const timeout = setTimeout(() => setWaited(true), 5_000)
return () => clearTimeout(timeout)
}, [waited])
useEffect(() => {
if (!waited) {
return
}
if (apiHealth) {
navigate(ROUTES.INFO)
}
}, [navigate, waited, apiHealth])
return (
<>
<Box mb={4}>
<Loading />
</Box>
<Typography>You will be redirected automatically once your node is up and running.</Typography>
</>
)
}
Example #9
Source File: useMetadataField.tsx From contracts-ui with GNU General Public License v3.0 | 6 votes |
useMetadataField = (): UseMetadataField => {
const navigate = useNavigate();
const { codeHash: codeHashUrlParam } = useParams<{ codeHash: string }>();
const [file, setFile] = useState<OrFalsy<FileState>>(null);
const codeBundleQuery = useCodeBundle(codeHashUrlParam || '');
const codeBundle = codeBundleQuery.data;
const metadata = useMetadata(codeBundle?.document?.abi, {
isWasmRequired: !codeBundle,
onChange: setFile,
});
const isLoading = useMemo(
() => !!codeHashUrlParam && codeBundleQuery.isLoading,
[codeHashUrlParam, codeBundleQuery.isLoading]
);
const isStored = useMemo((): boolean => !!codeBundle?.document, [codeBundle?.document]);
useEffect((): void => {
if (codeHashUrlParam && !codeBundleQuery.isValid) {
navigate(`/instantiate/${codeHashUrlParam}`);
}
}, [codeHashUrlParam, codeBundleQuery.isValid, navigate]);
return {
file,
isLoading,
isStored,
...metadata,
};
}
Example #10
Source File: LightModeRestart.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 6 votes |
export default function Settings(): ReactElement {
const [startedAt] = useState(Date.now())
const { apiHealth, nodeInfo } = useContext(Context)
const navigate = useNavigate()
useEffect(() => {
if (Date.now() - startedAt < 45_000) {
return
}
if (apiHealth && nodeInfo?.beeMode === BeeModes.LIGHT) {
navigate(ROUTES.INFO)
}
}, [startedAt, navigate, nodeInfo, apiHealth])
return (
<>
<Box mb={4}>
<Loading />
</Box>
<Typography>Your node is being upgraded to light mode... postage syncing may take up to 10 minutes.</Typography>
</>
)
}
Example #11
Source File: ExtensionStep.tsx From atlas with GNU General Public License v3.0 | 6 votes |
ExtensionStep: React.FC<ExtensionStepProps> = ({ nextStepPath }) => {
const navigate = useNavigate()
const step = useRouterQuery(QUERY_PARAMS.LOGIN)
const { extensionConnected } = useUser()
const [openEnableExtensionDialog, closeEnableExtensionDialog] = useConfirmationModal({
children: <PolkadotExtensionRejected />,
onExitClick: () => closeEnableExtensionDialog(),
})
useEffect(() => {
if (extensionConnected && step === '1') {
navigate({ search: nextStepPath })
}
}, [extensionConnected, navigate, nextStepPath, step])
return (
<StepWrapper>
<StyledPolkadotLogo />
<StepTitle variant="h500">Add Polkadot extension</StepTitle>
<StepSubTitle secondary variant="t200">
To manage your blockchain account, you will need a Polkadot browser extension. Please install it using the
following link:
</StepSubTitle>
<StyledButton icon={<SvgActionNewTab />} to="https://polkadot.js.org/extension/">
Install extension
</StyledButton>
<Button variant="tertiary" size="small" onClick={() => openEnableExtensionDialog()}>
Polkadot extension already installed? Click here
</Button>
<StyledStepFooter>
<BottomBarIcon />
<Text variant="t200" secondary>
Please reload the page and allow access after installing the extension
</Text>
</StyledStepFooter>
</StepWrapper>
)
}
Example #12
Source File: NetworkAndUser.tsx From contracts-ui with GNU General Public License v3.0 | 6 votes |
export function NetworkAndUser() {
const { endpoint, status } = useApi();
const navigate = useNavigate();
return (
<div className="network-and-user">
<Dropdown
className={classes(
'chain',
status === 'READY' ? 'isConnected' : '',
status === 'CONNECTING' ? 'isConnecting' : '',
status === 'ERROR' ? 'isError' : ''
)}
onChange={e => {
navigate(`/?rpc=${e}`);
}}
options={options}
value={options.find(o => o.value === endpoint)?.value || 'ws://127.0.0.1:9944'}
/>
</div>
);
}
Example #13
Source File: index.tsx From shippo with MIT License | 6 votes |
Page_setting = () => {
const history = useNavigate()
return (
<Container direction="vertical">
<Header
style={{
height: '45px',
lineHeight: '45px',
backgroundColor: '#fff',
textAlign: 'center',
fontSize: '18px',
}}
>
设置
</Header>
<WhiteSpace size={15} />
<Main>
<List>
<List.Item onClick={() => {}}>编辑资料</List.Item>
<List.Item onClick={() => {}}>账号与安全</List.Item>
</List>
<WhiteSpace size={15} />
<Button
block
size="large"
style={{ '--border-radius': '0px' }}
onClick={() => {
localStorage.removeItem('__PASSPORT')
history('/')
}}
>
退出登录
</Button>
</Main>
</Container>
)
}
Example #14
Source File: NotFound.tsx From contracts-ui with GNU General Public License v3.0 | 6 votes |
export function NotFound() {
const navigate = useNavigate();
return (
<div className="w-full overflow-y-auto overflow-x-hidden px-5 py-3 m-2 flex justify-center items-center">
<div className=" w-7/12 h-60 border dark:border-gray-700 grid place-content-center">
<EmojiSadIcon className="w-10 h-10 text-green-400 mb-1 justify-self-center" />
<p className="text-sm text-gray-300 mb-6">This page does not exist.</p>
<Button onClick={() => navigate('/')} variant="primary" className="justify-self-center">
Go Home
</Button>
</div>
</div>
);
}
Example #15
Source File: index.tsx From shippo with MIT License | 6 votes |
My = () => {
const history = useNavigate()
return (
<Container direction="vertical">
<Header
style={{
height: '45px',
lineHeight: '45px',
backgroundColor: '#fff',
textAlign: 'center',
fontSize: '18px',
}}
>
我
</Header>
<WhiteSpace size={15} />
<Main>
<UserInfoCard />
<WhiteSpace size={15} />
<List>
<List.Item prefix={<BellOutlined />} onClick={() => {}}>
通知
</List.Item>
<List.Item prefix={<ProfileOutlined />} onClick={() => {}}>
我的作品
</List.Item>
<List.Item prefix={<SettingOutlined />} onClick={() => history('/setting')}>
设置
</List.Item>
</List>
</Main>
</Container>
)
}
Example #16
Source File: ConfirmModal.tsx From raspiblitz-web with MIT License | 6 votes |
ConfirmModal: FC<Props> = ({ confirmText, confirmEndpoint, onClose }) => {
const { t } = useTranslation();
const { setIsLoggedIn } = useContext(AppContext);
const navigate = useNavigate();
const shutdownHandler = async () => {
const resp = await instance.post(confirmEndpoint);
if (resp.status === 200) {
setIsLoggedIn(false);
navigate("/login");
}
};
return createPortal(
<ModalDialog close={onClose}>
{confirmText}
<div className="flex flex-col p-3 xl:flex-row">
<button className={btnClasses} onClick={onClose}>
{t("settings.cancel")}
</button>
<button className={btnClasses} onClick={shutdownHandler}>
{t("settings.confirm")}
</button>
</div>
</ModalDialog>,
MODAL_ROOT
);
}
Example #17
Source File: GiftCardTopUpIndex.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 5 votes |
export function GiftCardTopUpIndex(): ReactElement {
const [loading, setLoading] = useState(false)
const [giftCode, setGiftCode] = useState('')
const { enqueueSnackbar } = useSnackbar()
const navigate = useNavigate()
async function onProceed() {
setLoading(true)
try {
const wallet = getWalletFromPrivateKeyString(giftCode)
const dai = new DaiToken(await Rpc._eth_getBalance(wallet.getAddressString()))
const bzz = new BzzToken(await Rpc._eth_getBalanceERC20(wallet.getAddressString()))
if (dai.toDecimal.lt(0.001) || bzz.toDecimal.lt(0.001)) {
throw Error('Gift wallet does not have enough funds')
}
enqueueSnackbar('Successfully verified gift wallet', { variant: 'success' })
navigate(ROUTES.TOP_UP_GIFT_CODE_FUND.replace(':privateKeyString', giftCode))
} catch (error) {
enqueueSnackbar(`Gift wallet could not be verified: ${error}`, { variant: 'error' })
} finally {
setLoading(false)
}
}
return (
<>
<HistoryHeader>Top-up with gift code</HistoryHeader>
<Box mb={4}>
<ProgressIndicator index={0} steps={['Paste gift code', 'Fund your node']} />
</Box>
<Box mb={2}>
<Typography style={{ fontWeight: 'bold' }}>Please paste your gift code below</Typography>
</Box>
<Box mb={4}>
A gift code is a unique key to a gift wallet that you can use to fund your node. Please don't share your
gift code as it can only be used once.
</Box>
<SwarmDivider mb={4} />
<Box mb={2}>
<SwarmTextInput
label="Gift code"
name="gift-code"
onChange={event => {
setGiftCode(event.target.value)
}}
/>
</Box>
<SwarmButton iconType={ArrowRight} loading={loading} disabled={loading} onClick={onProceed}>
Proceed
</SwarmButton>
</>
)
}
Example #18
Source File: VersioningStrategy.tsx From backstage with Apache License 2.0 | 5 votes |
export function VersioningStrategy() {
const navigate = useNavigate();
const { project } = useProjectContext();
const { getParsedQuery, getQueryParamsWithUpdates } = useQueryHandler();
useEffect(() => {
const { parsedQuery } = getParsedQuery();
if (!parsedQuery.versioningStrategy && !project.isProvidedViaProps) {
const { queryParams } = getQueryParamsWithUpdates({
updates: [
{ key: 'versioningStrategy', value: project.versioningStrategy },
],
});
navigate(`?${queryParams}`, { replace: true });
}
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return (
<FormControl
component="fieldset"
required
disabled={project.isProvidedViaProps}
>
<FormLabel component="legend">Versioning strategy</FormLabel>
<RadioGroup
data-testid={TEST_IDS.form.versioningStrategy.radioGroup}
aria-label="calendar-strategy"
name="calendar-strategy"
value={project.versioningStrategy}
onChange={event => {
const { queryParams } = getQueryParamsWithUpdates({
updates: [{ key: 'versioningStrategy', value: event.target.value }],
});
navigate(`?${queryParams}`, { replace: true });
}}
>
<FormControlLabel
value={VERSIONING_STRATEGIES.semver}
control={<Radio />}
label="Semantic versioning"
/>
<FormControlLabel
value={VERSIONING_STRATEGIES.calver}
control={<Radio />}
label="Calendar versioning"
/>
</RadioGroup>
</FormControl>
);
}
Example #19
Source File: ExpandableListItemLink.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 5 votes |
export default function ExpandableListItemLink({
label,
value,
link,
navigationType = 'NEW_WINDOW',
allowClipboard = true,
}: Props): ReactElement | null {
const classes = useStyles()
const [copied, setCopied] = useState(false)
const navigate = useNavigate()
const tooltipClickHandler = () => setCopied(true)
const tooltipCloseHandler = () => setCopied(false)
const displayValue = value.length > 22 ? value.slice(0, 19) + '...' : value
function onNavigation() {
if (navigationType === 'NEW_WINDOW') {
window.open(link || value)
} else {
navigate(link || value)
}
}
return (
<ListItem className={classes.header}>
<Grid container direction="column" justifyContent="space-between" alignItems="stretch">
<Grid container direction="row" justifyContent="space-between" alignItems="center">
{label && <Typography variant="body1">{label}</Typography>}
<Typography variant="body2">
<div>
{allowClipboard && (
<span className={classes.copyValue}>
<Tooltip title={copied ? 'Copied' : 'Copy'} placement="top" arrow onClose={tooltipCloseHandler}>
<CopyToClipboard text={value}>
<span onClick={tooltipClickHandler}>{displayValue}</span>
</CopyToClipboard>
</Tooltip>
</span>
)}
{!allowClipboard && <span onClick={onNavigation}>{displayValue}</span>}
<IconButton size="small" className={classes.openLinkIcon}>
{navigationType === 'NEW_WINDOW' && <OpenInNewSharp onClick={onNavigation} strokeWidth={1} />}
{navigationType === 'HISTORY_PUSH' && <ArrowForward onClick={onNavigation} strokeWidth={1} />}
</IconButton>
</div>
</Typography>
</Grid>
</Grid>
</ListItem>
)
}
Example #20
Source File: SignInStepsStepper.tsx From atlas with GNU General Public License v3.0 | 5 votes |
SignInStepsStepper: React.FC = () => {
const headTags = useHeadTags('Sign in')
const [selectedAccountAddress, setSelectedAccountAddress] = useState<undefined | string>()
const navigate = useNavigate()
const step = useRouterQuery(QUERY_PARAMS.LOGIN)
const stepNumber = Number(step)
const { extensionConnected, signIn, isLoading } = useUser()
const steps = [
{
title: 'Add Polkadot extension',
element: <ExtensionStep nextStepPath={urlParams({ [QUERY_PARAMS.LOGIN]: 2 })} />,
},
{
title: 'Connect account',
element: (
<AccountStep
nextStepPath={urlParams({ [QUERY_PARAMS.LOGIN]: 3 })}
selectedAccountAddress={selectedAccountAddress}
setSelectedAccountAddress={setSelectedAccountAddress}
/>
),
},
{
title: 'Accept ToS',
element: <TermsStep />,
},
]
useEffect(() => {
if (extensionConnected === null && stepNumber >= 1) {
signIn()
}
}, [extensionConnected, signIn, stepNumber])
const showStepper = stepNumber >= 1 && !isLoading
const showCreateMemberModal = step === 'member'
return (
<>
{(showStepper || showCreateMemberModal) && headTags}
<StepperModal
currentStepIdx={stepNumber <= 0 ? 0 : stepNumber - 1}
steps={steps}
show={showStepper}
onExitClick={() => {
navigate({ search: '' })
}}
/>
<CreateMemberModal show={showCreateMemberModal} selectedAccountAddress={selectedAccountAddress} />
</>
)
}
Example #21
Source File: pager.tsx From UsTaxes with GNU Affero General Public License v3.0 | 5 votes |
PagerProvider = <A extends Page>({
children,
pages
}: PropsWithChildren<PagerProviderProps<A>>): ReactElement => {
const lookup = new Map(pages.map((p, i) => [p.url, i]))
const currentLoc = useLocation()
const currentPage = lookup.get(currentLoc.pathname) ?? 0
const navigate = useNavigate()
const onAdvance: (() => void) | undefined = (() => {
if (currentPage < pages.length - 1) {
return () => navigate(pages[currentPage + 1].url)
}
})()
const prev = currentPage > 0 ? pages[currentPage - 1] : undefined
const navButtons: ReactElement = (
<PagerButtons
previousUrl={prev?.url}
submitText={onAdvance !== undefined ? 'Save and Continue' : undefined}
/>
)
return (
<PagerContext.Provider
value={{
onAdvance:
onAdvance ??
(() => {
// end of pages
}),
navButtons
}}
>
{children}
</PagerContext.Provider>
)
}
Example #22
Source File: ResultWrapper.tsx From atlas with GNU General Public License v3.0 | 5 votes |
ResultWrapper: React.FC<SearchItemProps> = ({
to,
onDelete,
children,
onClick,
selected,
handleSelectedItem,
variant = 'default',
selectedItem,
}) => {
const wrapperRef = useRef<HTMLAnchorElement>(null)
const navigate = useNavigate()
useEffect(() => {
const onKeyPress = (event: KeyboardEvent) => {
if (event.key === 'Enter' && selected && to) {
event.preventDefault()
navigate(to)
}
}
window.addEventListener('keydown', onKeyPress)
return () => {
window.removeEventListener('keydown', onKeyPress)
}
}, [navigate, selected, to])
useEffect(() => {
if (selected && wrapperRef.current) {
handleSelectedItem(wrapperRef.current.offsetTop)
}
}, [handleSelectedItem, selected])
return (
<SearchItemWrapper
to={to}
onClick={onClick}
selected={selected}
ref={wrapperRef}
variant={variant}
selectedItem={selectedItem}
>
<SearchItemContent>{children}</SearchItemContent>
<Shortcut>
<Text secondary variant="t100">
Select
</Text>
<ShortcutIndicator>↩</ShortcutIndicator>
</Shortcut>
{onDelete && (
<DeleteButton
size="small"
onClick={(event) => {
event.preventDefault()
event.stopPropagation()
onDelete()
}}
variant="tertiary"
>
<SvgActionClose />
</DeleteButton>
)}
</SearchItemWrapper>
)
}
Example #23
Source File: LookUpCodeHash.tsx From contracts-ui with GNU General Public License v3.0 | 5 votes |
export function LookUpCodeHash() {
const navigate = useNavigate();
const { api } = useApi();
const [searchString, setSearchString] = useState('');
const [codeHash, setCodeHash] = useState('');
const { data: searchResults } = useCodeBundleSearch(searchString);
const { data, error, isLoading, isValid } = useCodeBundle(codeHash);
const { document } = data || { document: null };
useEffect((): void => {
if (codeHash !== searchString) {
if (searchString === '' || isValidCodeHash(searchString)) {
checkOnChainCode(api, searchString)
.then(isOnChain => (isOnChain ? setCodeHash(searchString) : setCodeHash('')))
.catch(console.error);
} else {
setCodeHash('');
}
}
}, [api, codeHash, searchString]);
useEffect((): void => {
codeHash && setSearchString(codeHash);
}, [codeHash]);
return (
<FormField className="h-36 relative" label="Look Up Code Hash">
<Input
className={classes('relative flex items-center')}
onChange={setSearchString}
placeholder="Paste a code hash or search for existing code bundles already on-chain"
value={searchString}
>
{document && (
<button className="absolute right-2" onClick={() => setSearchString('')}>
<XCircleIcon className="w-5 h-5 text-gray-500" aria-hidden="true" />
</button>
)}
</Input>
<SearchResults
codeBundles={searchResults}
isOpen={!codeHash && searchString.length > 0}
onSelectCodeBundle={document => {
setCodeHash(document.codeHash);
}}
/>
{codeHash && !isLoading && document && (
<CodeHash
className="mt-1"
codeHash={codeHash}
error={error}
isError={!isValid}
isSuccess={isValid}
name={document?.name || 'On-chain Code Exists'}
onClick={isValid ? () => navigate(`/instantiate/${codeHash}`) : undefined}
/>
)}
</FormField>
);
}
Example #24
Source File: MemberActivity.tsx From atlas with GNU General Public License v3.0 | 5 votes |
MemberActivity: React.FC<MemberActivityProps> = ({ memberId, sort = 'createdAt_DESC' }) => {
const { activities, loading, activitiesTotalCounts } = useActivities(memberId, sort)
const navigate = useNavigate()
const placeholderItems = Array.from({ length: PLACEHOLDERS_COUNT }, () => ({ id: undefined }))
const items = activities && !loading ? activities : (placeholderItems as ActivitiesRecord[])
return (
<section>
{activities?.length === 0 ? (
<EmptyFallback title="No activity" subtitle="Go out there and explore!" variant="small" />
) : (
<LayoutGrid>
<GridItem colSpan={{ base: 12, sm: 8 }} rowStart={{ base: 2, sm: 1 }}>
<LayoutGrid>
{items?.map((activity, i) => (
<GridItem key={i} colSpan={{ base: 12 }}>
<ActivityItemWithResolvedAsset
loading={!activities || loading}
onItemClick={() => navigate(absoluteRoutes.viewer.video(activity.video?.id))}
date={activity?.date}
type={activity?.type}
title={activity?.video?.title}
description={getDescription(activity)}
thumbnailPhoto={activity.video?.thumbnailPhoto}
/>
</GridItem>
))}
</LayoutGrid>
</GridItem>
{!loading && activitiesTotalCounts && (
<GridItem colSpan={{ base: 12, sm: 3 }} colStart={{ sm: -4 }}>
<Text variant="h500">Overview</Text>
<OverviewContainer>
<OverviewItem>
<StyledIconWrapper icon={<SvgActionBuyNow />} size="large" />
<OverviewTextContainer>
<Text variant="t100" secondary>
NFTs bought
</Text>
<Text variant="t300">{activitiesTotalCounts.nftsBoughts}</Text>
</OverviewTextContainer>
</OverviewItem>
<OverviewItem>
<StyledIconWrapper icon={<SvgActionSell />} size="large" />
<OverviewTextContainer>
<Text variant="t100" secondary>
NFTs sold
</Text>
<Text variant="t300">{activitiesTotalCounts.nftsSold}</Text>
</OverviewTextContainer>
</OverviewItem>
<GridRowWrapper>
<OverviewItem>
<StyledIconWrapper icon={<SvgActionMint />} size="large" />
<OverviewTextContainer>
<Text variant="t100" secondary>
NFTs created
</Text>
<Text variant="t300">{activitiesTotalCounts.nftsIssued}</Text>
</OverviewTextContainer>
</OverviewItem>
<OverviewItem>
<StyledIconWrapper icon={<SvgActionBid />} size="large" />
<OverviewTextContainer>
<Text variant="t100" secondary>
Bid placed
</Text>
<Text variant="t300">{activitiesTotalCounts.nftsBidded}</Text>
</OverviewTextContainer>
</OverviewItem>
</GridRowWrapper>
</OverviewContainer>
</GridItem>
)}
</LayoutGrid>
)}
</section>
)
}
Example #25
Source File: AppWrapper.tsx From flood with GNU General Public License v3.0 | 5 votes |
AppWrapper: FC<AppWrapperProps> = observer(({children, className}: AppWrapperProps) => {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
useEffectOnce(() => {
AuthActions.verify().then(
({initialUser}: {initialUser?: boolean}): void => {
if (initialUser) {
navigate('/register', {replace: true});
} else {
navigate('/overview', {replace: true});
}
},
(): void => {
navigate('/login', {replace: true});
},
);
});
if (searchParams.has('action')) {
if (searchParams.get('action') === 'add-urls') {
if (searchParams.has('url')) {
UIStore.setActiveModal({
id: 'add-torrents',
tab: 'by-url',
urls: [{id: 0, value: searchParams.get('url') as string}],
});
}
}
}
let overlay: ReactNode = null;
if (!AuthStore.isAuthenticating || (AuthStore.isAuthenticated && !UIStore.haveUIDependenciesResolved)) {
overlay = <LoadingOverlay dependencies={UIStore.dependencies} />;
}
if (AuthStore.isAuthenticated && !ClientStatusStore.isConnected && ConfigStore.authMethod !== 'none') {
overlay = (
<div className="application__loading-overlay">
<div className="application__entry-barrier">
<LogoutButton className={css({position: 'absolute', left: '5px', top: '5px'})} />
<ClientConnectionInterruption />
</div>
</div>
);
}
return (
<div className={classnames('application', className)}>
<WindowTitle />
<TransitionGroup>
{overlay != null ? (
<CSSTransition timeout={{enter: 1000, exit: 1000}} classNames="application__loading-overlay">
{overlay}
</CSSTransition>
) : null}
</TransitionGroup>
{children}
</div>
);
})
Example #26
Source File: VideoTileViewer.tsx From atlas with GNU General Public License v3.0 | 5 votes |
VideoTileViewer: React.FC<VideoTileViewerProps> = ({ id, onClick, detailsVariant, direction }) => {
const { copyToClipboard } = useClipboard()
const navigate = useNavigate()
const { video, loading } = useBasicVideo(id ?? '', {
skip: !id,
onError: (error) => SentryLogger.error('Failed to fetch video', 'VideoTile', error, { video: { id } }),
})
const { avatarPhotoUrl, isLoadingAvatar, isLoadingThumbnail, thumbnailPhotoUrl, videoHref } =
useVideoTileSharedLogic(video)
const handleCopyVideoURLClick = useCallback(() => {
copyToClipboard(videoHref ? location.origin + videoHref : '', 'Video URL copied to clipboard')
}, [videoHref, copyToClipboard])
const channelHref = absoluteRoutes.viewer.channel(video?.channel.id)
return (
<VideoTile
onClick={onClick}
detailsVariant={detailsVariant}
videoHref={videoHref}
channelHref={channelHref}
onChannelAvatarClick={() => navigate(channelHref)}
loadingDetails={loading || !video}
loadingThumbnail={isLoadingThumbnail}
thumbnailUrl={thumbnailPhotoUrl}
views={video?.views}
createdAt={video?.createdAt}
slots={{
bottomRight: {
element: video?.duration ? (
<Pill variant="overlay" label={formatDurationShort(video?.duration)} title="Video duration" />
) : null,
},
bottomLeft:
video && video?.nft
? {
element: <Pill label="NFT" variant="overlay" title="NFT" />,
}
: undefined,
center: {
element: <SvgIllustrativePlay />,
type: 'hover',
},
}}
channelAvatarUrl={avatarPhotoUrl}
loadingAvatar={isLoadingAvatar}
channelTitle={video?.channel?.title}
videoTitle={video?.title}
kebabMenuItems={[
{
icon: <SvgActionCopy />,
onClick: handleCopyVideoURLClick,
title: 'Copy video URL',
},
]}
direction={direction}
/>
)
}
Example #27
Source File: index.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 5 votes |
export default function Stamp(): ReactElement {
const classes = useStyles()
const navigate = useNavigate()
const { stamps, isLoading, error, start, stop } = useContext(StampsContext)
const { status } = useContext(BeeContext)
useEffect(() => {
if (!status.all) return
start()
return () => stop()
}, [status]) // eslint-disable-line react-hooks/exhaustive-deps
if (status.all === CheckState.ERROR) return <TroubleshootConnectionCard />
function navigateToNewStamp() {
navigate(ROUTES.STAMPS_NEW)
}
return (
<div className={classes.root}>
{error && (
<Container style={{ textAlign: 'center', padding: '50px' }}>
Error loading postage stamps details: {error.message}
</Container>
)}
{!error && (
<>
<div className={classes.actions}>
<SwarmButton onClick={navigateToNewStamp} iconType={PlusSquare}>
Buy New Postage Stamp
</SwarmButton>
<div style={{ height: '5px' }}>{isLoading && <CircularProgress />}</div>
</div>
<StampsTable postageStamps={stamps} />
</>
)}
</div>
)
}
Example #28
Source File: AuthForm.tsx From flood with GNU General Public License v3.0 | 4 votes |
AuthForm: FC<AuthFormProps> = ({mode}: AuthFormProps) => {
const {i18n} = useLingui();
const formRef = useRef<Form>(null);
const clientConnectionSettingsRef = useRef<ClientConnectionSettings | null>(null);
const [errorMessage, setErrorMessage] = useState<string | {id: string} | undefined>(undefined);
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
const navigate = useNavigate();
const isLoginMode = mode === 'login';
return (
<div className="application__entry-barrier">
<Panel spacing="large">
<Form
onSubmit={(submission) => {
submission.event.preventDefault();
setIsSubmitting(true);
const formData = submission.formData as Partial<LoginFormData> | Partial<RegisterFormData>;
if (formData.username == null || formData.username === '') {
setIsSubmitting(false);
setErrorMessage({id: 'auth.error.username.empty'});
return;
}
if (formData.password == null || formData.password === '') {
setIsSubmitting(false);
setErrorMessage({id: 'auth.error.password.empty'});
return;
}
if (isLoginMode) {
const credentials = formData as LoginFormData;
AuthActions.authenticate({
username: credentials.username,
password: credentials.password,
})
.then(() => {
setIsSubmitting(false);
navigate('/overview', {replace: true});
})
.catch((error: Error) => {
setIsSubmitting(false);
setErrorMessage(error.message);
navigate('/login', {replace: true});
});
} else {
const config = formData as RegisterFormData;
if (clientConnectionSettingsRef.current == null) {
setIsSubmitting(false);
setErrorMessage({id: 'connection.settings.error.empty'});
return;
}
const connectionSettings = clientConnectionSettingsRef.current;
if (connectionSettings == null) {
setIsSubmitting(false);
setErrorMessage({id: 'connection.settings.error.empty'});
return;
}
AuthActions.register({
username: config.username,
password: config.password,
client: connectionSettings,
level: AccessLevel.ADMINISTRATOR,
}).then(
() => {
setIsSubmitting(false);
navigate('/overview', {replace: true});
},
(error: Error) => {
setIsSubmitting(false);
setErrorMessage(error.message);
},
);
}
}}
ref={formRef}
>
<PanelHeader>
<h1>{isLoginMode ? i18n._('auth.login') : i18n._('auth.create.an.account')}</h1>
</PanelHeader>
<PanelContent>
<p className="copy--lead">
{isLoginMode ? i18n._('auth.login.intro') : i18n._('auth.create.an.account.intro')}
</p>
{errorMessage != null ? (
<FormRow>
<FormError isLoading={isSubmitting}>
{typeof errorMessage === 'string' ? errorMessage : i18n._(errorMessage)}
</FormError>
</FormRow>
) : null}
<FormRow>
<Textbox placeholder={i18n._('auth.username')} id="username" autoComplete="username" />
</FormRow>
<FormRow>
<Textbox
placeholder={i18n._('auth.password')}
id="password"
type="password"
autoComplete={isLoginMode ? 'current-password' : 'new-password'}
/>
</FormRow>
</PanelContent>
{isLoginMode ? null : (
<PanelContent hasBorder>
<ClientConnectionSettingsForm
onSettingsChange={(settings) => {
clientConnectionSettingsRef.current = settings;
}}
/>
</PanelContent>
)}
<PanelFooter hasBorder>
<FormRow justify="end">
<Button
priority="tertiary"
onClick={() => {
if (formRef.current != null) {
formRef.current.resetForm();
}
}}
>
{i18n._('auth.input.clear')}
</Button>
<Button isLoading={isSubmitting} type="submit">
{isLoginMode ? i18n._('auth.log.in') : i18n._('auth.create.account')}
</Button>
</FormRow>
</PanelFooter>
</Form>
</Panel>
</div>
);
}
Example #29
Source File: Swap.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 4 votes |
export function Swap({ header }: Props): ReactElement {
const [loading, setLoading] = useState(false)
const [hasSwapped, setSwapped] = useState(false)
const { jsonRpcProvider } = useContext(TopUpContext)
const { balance } = useContext(BeeContext)
const navigate = useNavigate()
const { enqueueSnackbar } = useSnackbar()
if (!balance) {
return <Loading />
}
const daiToSwap = balance.dai.minusBaseUnits('1')
const daiAfterSwap = new DaiToken(balance.dai.toBigNumber.minus(daiToSwap.toBigNumber))
const bzzAfterSwap = new BzzToken(daiToSwap.toBigNumber.dividedToIntegerBy(200))
async function onSwap() {
if (hasSwapped) {
return
}
setLoading(true)
setSwapped(true)
try {
await performSwap(daiToSwap.toString)
enqueueSnackbar('Successfully swapped, restarting...', { variant: 'success' })
await sleepMs(5_000)
await upgradeToLightNode(jsonRpcProvider)
await restartBeeNode()
navigate(ROUTES.RESTART_LIGHT)
enqueueSnackbar('Upgraded to light node', { variant: 'success' })
} catch (error) {
enqueueSnackbar(`Failed to swap: ${error}`, { variant: 'error' })
} finally {
setLoading(false)
}
}
return (
<>
<HistoryHeader>{header}</HistoryHeader>
<Box mb={4}>
<TopUpProgressIndicator index={1} />
</Box>
<Box mb={2}>
<Typography style={{ fontWeight: 'bold' }}>Swap some xDAI to BZZ</Typography>
</Box>
<Box mb={4}>
<Typography>
You need to swap xDAI to BZZ in order to use Swarm. Make sure to keep at least 1 xDAI in order to pay for
transaction costs on the network.
</Typography>
</Box>
<SwarmDivider mb={4} />
<Box mb={4}>
<Typography>
Your current balance is {balance.dai.toSignificantDigits(4)} xDAI and {balance.bzz.toSignificantDigits(4)}{' '}
BZZ.
</Typography>
</Box>
<Box mb={4}>
<SwarmTextInput
label="Amount to swap"
defaultValue={`${daiToSwap.toSignificantDigits(4)} XDAI`}
name="x"
onChange={() => false}
/>
</Box>
<Box mb={4}>
<ArrowDown size={24} color="#aaaaaa" />
</Box>
<Box mb={0.25}>
<ExpandableListItemKey label="Funding wallet address" value={balance.address} expanded />
</Box>
<Box mb={0.25}>
<ExpandableListItem
label="Resulting XDAI balance after swap"
value={`${daiAfterSwap.toSignificantDigits(4)} XDAI`}
/>
</Box>
<Box mb={2}>
<ExpandableListItem
label="Resulting BZZ balance after swap"
value={`${bzzAfterSwap.toSignificantDigits(4)} BZZ`}
/>
</Box>
<ExpandableListItemActions>
<SwarmButton
iconType={Check}
onClick={onSwap}
disabled={hasSwapped || loading || balance.dai.toDecimal.lte(1)}
loading={loading}
>
Swap Now
</SwarmButton>
</ExpandableListItemActions>
</>
)
}