react-toastify#toast TypeScript Examples
The following examples show how to use
react-toastify#toast.
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: utils.tsx From posthog-foss with MIT License | 7 votes |
export function editingToast(
item: string,
setItemMode:
| ((mode: DashboardMode | null, source: DashboardEventSource) => void)
| ((mode: ItemMode | null, source: DashboardEventSource) => void)
): any {
return toast(
<>
<h1>{item} edit mode</h1>
<p>Tap below when finished.</p>
<div className="text-right">
<Button>Finish editing</Button>
</div>
</>,
{
type: 'info',
autoClose: false,
onClick: () => setItemMode(null, DashboardEventSource.Toast),
closeButton: false,
className: 'drag-items-toast accent-border',
}
)
}
Example #2
Source File: ErrorToast.tsx From dxvote with GNU Affero General Public License v3.0 | 6 votes |
export default function ErrorToast(toastText, modalText) {
return toast.error(
<div>
{toastText}
<ErrorToastButton>More</ErrorToastButton>
<Modal
header={<h1>Error</h1>}
isOpen={true}
onDismiss={() => console.log(1)}
onConfirm={() => navigator.clipboard.writeText(modalText)}
onCancel={() => console.log(1)}
confirmText={'Copy to Clipboard'}
cancelText={'Contact'}
>
<p>{modalText}</p>
</Modal>
</div>,
{
position: 'bottom-right',
autoClose: 50000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
}
);
}
Example #3
Source File: Base.tsx From mail-my-ballot with Apache License 2.0 | 6 votes |
SignatureBase = <Info extends StateInfo>( {enrichValues, children}: Props<NoSignature<Info>> ) => { const [signature, setSignature] = React.useState<string | null>() const enrichValuesWithSignature = (baseInfo: StatelessInfo): Info | null => { const values = enrichValues(baseInfo) if (!values) return null if (!signature) { // Do not dismiss previous errors which may give more details on bad fields toast.error('Please fill out the signature field') return null } return { ...baseInfo, ...values, signature, } as Info // hack b/c it cannot understand how to distribute over types } return <Base<Info> enrichValues={enrichValuesWithSignature} > { children } <Signature setSignature={setSignature}/> </Base> }
Example #4
Source File: AlertContainer.tsx From lightning-terminal with MIT License | 6 votes |
AlertToast: React.FC<AlertToastProps> = ({ alert, onClose }) => {
// use useEffect to only run the side-effect one time
useEffect(() => {
const { id, type, message, title, ms: autoClose } = alert;
// create a component to display inside of the toast
const { Body, Title, Message } = Styled;
const body = (
<Body>
{title && <Title>{title}</Title>}
<Message>{message}</Message>
</Body>
);
// display the toast popup containing the styled body
toast(body, { type, autoClose, onClose: () => onClose(id) });
}, [alert, onClose]);
// do not render anything to the dom. the toast() func will display the content
return null;
}
Example #5
Source File: newsFeedSaga.ts From foodie with MIT License | 6 votes |
function* newsFeedSaga({ type, payload }: INewsFeedSaga) {
switch (type) {
case GET_FEED_START:
try {
yield put(isGettingFeed(true));
yield put(setNewsFeedErrorMessage(null));
const posts: IPost[] = yield call(getNewsFeed, payload);
yield put(isGettingFeed(false));
yield put(getNewsFeedSuccess(posts));
} catch (e) {
console.log(e);
yield put(isGettingFeed(false));
yield put(setNewsFeedErrorMessage(e))
}
break;
case CREATE_POST_START:
try {
yield put(isCreatingPost(true));
const post: IPost = yield call(createPost, payload);
yield put(createPostSuccess(post));
yield put(isCreatingPost(false));
toast.dismiss();
toast.dark('Post succesfully created.');
} catch (e) {
yield put(isCreatingPost(false));
console.log(e);
}
break;
default:
throw new Error('Unexpected action type.')
}
}
Example #6
Source File: index.tsx From freedeck-configurator with GNU General Public License v3.0 | 6 votes |
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
register({
onUpdate: (registration) => {
toast("There is an Update! Click here to update.", {
autoClose: false,
position: "bottom-right",
onClick: () => {
if (registration && registration.waiting) {
registration.waiting.postMessage({ type: "SKIP_WAITING" });
}
window.location.reload();
},
});
},
});
Example #7
Source File: store.ts From polkabtc-ui with Apache License 2.0 | 6 votes |
saveState = (store: AppState): void => {
try {
const preparedState = {
...store,
issue: {
...store.issue,
issueRequests: mapToArray(store.issue.issueRequests)
},
redeem: {
...store.redeem,
redeemRequests: mapToArray(store.redeem.redeemRequests)
}
};
const serializedState = JSON.stringify(preparedState);
localStorage.setItem(constants.STORE_NAME, serializedState);
} catch (error) {
setTimeout(
() => toast.error('Local storage is disabled. In order to use platform please enable local storage'),
2000
);
}
}
Example #8
Source File: usePromoToast.ts From index-ui with MIT License | 6 votes |
usePromoToast = (component: React.ReactElement, toastId: string) => {
const [hasBeenDismissed, setHasBeenDismissed] = useLocalStorage(
toastId,
false
)
useEffect(() => {
!hasBeenDismissed &&
toast.success(component, {
position: 'bottom-right',
autoClose: false,
closeOnClick: false,
draggable: false,
closeButton: true,
toastId,
onClose: () => setHasBeenDismissed(true),
})
}, [])
return null
}
Example #9
Source File: store.ts From polkabtc-ui with Apache License 2.0 | 6 votes |
loadState = (): StoreType => {
try {
const serializedState = localStorage.getItem(constants.STORE_NAME);
if (serializedState === null) {
const initialState = getInitialState();
return initialState;
}
const rawStore = JSON.parse(serializedState);
const deserializedState = {
...rawStore,
general: {
...rawStore.general,
polkaBtcLoaded: false,
relayerLoaded: false
}
};
return {
...deserializedState,
issue: {
...deserializedState.issue,
issueRequests: arrayToMap(deserializedState.issue.issueRequests)
},
redeem: {
...deserializedState.redeem,
redeemRequests: arrayToMap(deserializedState.redeem.redeemRequests)
}
};
} catch (error) {
setTimeout(
() => toast.error('Local storage is disabled. In order to use platform please enable local storage'),
2000
);
const initialState = getInitialState();
return initialState;
}
}
Example #10
Source File: useCopyClipboardToast.tsx From tsplay.dev with MIT License | 6 votes |
useCopyClipboardToast = (): ShowToast => {
const [toastId, setToastId] = React.useState<string | number>('')
const showToast = React.useCallback<ShowToast>(
(content, options = {}, isError) => {
const toastFc = isError ? toast.error : toast
if (toastId) {
toast.dismiss(toastId)
options.delay = 270
}
const newToastId = toastFc(content, options)
setToastId(newToastId)
},
[toastId]
)
return showToast
}
Example #11
Source File: fetcher.ts From yasd with MIT License | 6 votes |
fetcher = <T>(requestConfig: AxiosRequestConfig): Promise<T> => {
return client
.request<T>(requestConfig)
.then((res) => res.data)
.catch((error) => {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.error(error.response.data)
console.error(error.response.status)
toast.error('请求错误: ' + error.message + `(${error.response.status})`)
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.error(error.request)
toast.error('无法连接服务器: ' + error.message, {
toastId: error.message,
})
} else {
// Something happened in setting up the request that triggered an Error
console.error('Error', error.message)
toast.error('发生错误: ' + error.message)
}
throw error
})
}
Example #12
Source File: index.tsx From Next.js_GraphQL_Express_Apollo_Boilerplate with MIT License | 6 votes |
handleSubmit = async (updateUser: any, event: any) => {
try {
event.preventDefault();
const { state, props } = this;
if (validateEmail(state.email)) {
await updateUser({
variables: {
userId: props.userId,
updateUser: { ...state },
},
});
toast.success('Profile Updated');
props.history.push('/welcome');
} else {
toast.error('Invalid Email');
}
} catch (error) {
toast.error('Check your connection');
}
};
Example #13
Source File: requestJSON.ts From Hybooru with MIT License | 6 votes |
export default async function requestJSON<Res, Req extends Record<string, any> = Record<string, any>>(options: RequestOptions<Req> = {}): Promise<Res> {
if(isNode) return new Promise(() => {});
let { method, href, host, pathname, search, cancelCb, data } = options;
host = host || location.host;
pathname = pathname || location.pathname;
if(search && typeof search !== "string") {
search = qs.stringify(search);
}
search = search ? "?" + search : location.search;
href = href || `//${host}${pathname}${search}`;
method = method || "GET";
let response;
try {
response = await axios({
method,
url: href,
data,
cancelToken: cancelCb ? new CancelToken(cancelCb) : undefined,
});
} catch(err) {
if(!(err instanceof axios.Cancel)) toast.error(err.response?.data?._error?.message || err.message);
throw err;
}
return response.data;
}
Example #14
Source File: LogoutButton.tsx From frontend with Apache License 2.0 | 6 votes |
LogoutButton: FunctionComponent = () => {
const { t } = useTranslation()
// Using state to prevent user repeatedly initating fetches
const [clicked, setClicked] = useState(false)
const dispatch = useUserDispatch()
// Only make a request on first click
useEffect(() => {
if (clicked) {
logout(dispatch)
.catch(err => {
toast.error(t(err))
setClicked(false)
})
}
}, [dispatch, clicked, t])
return (
<Button onClick={() => setClicked(true)} type='primary'>
{t('log-out')}
</Button>
)
}
Example #15
Source File: personalAPIKeysLogic.ts From posthog-foss with MIT License | 6 votes |
personalAPIKeysLogic = kea<personalAPIKeysLogicType>({
path: ['lib', 'components', 'PersonalAPIKeys', 'personalAPIKeysLogic'],
loaders: ({ values }) => ({
keys: [
[] as PersonalAPIKeyType[],
{
loadKeys: async () => {
const response: PersonalAPIKeyType[] = await api.get('api/personal_api_keys/')
return response
},
createKey: async (label: string) => {
const newKey: PersonalAPIKeyType = await api.create('api/personal_api_keys/', {
label,
})
return [newKey, ...values.keys]
},
deleteKey: async (key: PersonalAPIKeyType) => {
await api.delete(`api/personal_api_keys/${key.id}/`)
return (values.keys as PersonalAPIKeyType[]).filter((filteredKey) => filteredKey.id != key.id)
},
},
],
}),
listeners: () => ({
createKeySuccess: ({ keys }: { keys: PersonalAPIKeyType[] }) => {
keys[0]?.value && copyToClipboard(keys[0].value, 'personal API key value')
},
deleteKeySuccess: ({}: { keys: PersonalAPIKeyType[] }) => {
toast.success(`Personal API key deleted.`)
},
}),
events: ({ actions }) => ({
afterMount: [actions.loadKeys],
}),
})
Example #16
Source File: index.ts From sdc-ide with MIT License | 6 votes |
showToast = (type: 'success' | 'error', error?: OperationOutcome, index?: number) => {
if (type === 'success') {
return toast.success('New mapper created');
}
if (type === 'error') {
return toast.error(
formatError(error, {
mapping: { conflict: 'Please reload page' },
format: (errorCode, errorDescription) =>
`An error occurred: ${error?.issue[index as number]?.diagnostics || errorDescription} ${
error?.issue[index as number]?.expression?.[0] || ''
} (${errorCode}).`,
}),
);
}
}
Example #17
Source File: groups.ts From abrechnung with GNU Affero General Public License v3.0 | 6 votes |
groupLog = atomFamily<Array<GroupLog>, number>({
key: "groupLog",
effects_UNSTABLE: (groupID) => [
({ setSelf }) => {
setSelf(
fetchLog({ groupID: groupID }).catch((err) => toast.error(`error when fetching group log: ${err}`))
);
ws.subscribe("group_log", groupID, (subscription_type, { log_id, element_id }) => {
if (element_id === groupID) {
fetchLog({ groupID: element_id }).then((result) => setSelf(result));
}
});
// TODO: handle registration errors
return () => {
ws.unsubscribe("group_log", groupID);
};
},
],
})
Example #18
Source File: experimentsLogic.tsx From posthog-foss with MIT License | 6 votes |
experimentsLogic = kea<experimentsLogicType>({
path: ['scenes', 'experiments', 'experimentsLogic'],
connect: { values: [teamLogic, ['currentTeamId']] },
actions: {},
loaders: ({ values }) => ({
experiments: [
[] as Experiment[],
{
loadExperiments: async () => {
const response = await api.get(`api/projects/${values.currentTeamId}/experiments`)
return response.results as Experiment[]
},
deleteExperiment: async (id: number) => {
await api.delete(`api/projects/${values.currentTeamId}/experiments/${id}`)
toast(
<div>
<h1 className="text-success">
<CheckCircleOutlined /> Experiment removed
</h1>
</div>
)
return values.experiments.filter((experiment) => experiment.id !== id)
},
},
],
}),
events: ({ actions }) => ({
afterMount: () => {
actions.loadExperiments()
},
}),
})
Example #19
Source File: GroupDeleteModal.tsx From abrechnung with GNU Affero General Public License v3.0 | 6 votes |
export default function GroupDeleteModal({ show, onClose, groupToDelete }) {
const confirmDeleteGroup = () => {
deleteGroup({ groupID: groupToDelete.id })
.then((res) => {
onClose();
})
.catch((err) => {
toast.error(err);
});
};
return (
<Dialog open={show} onClose={onClose}>
<DialogTitle>Delete Group</DialogTitle>
<DialogContent>
<DialogContentText>
{groupToDelete ? <span>Are you sure you want to delete group {groupToDelete.name}</span> : null}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button color="primary" onClick={onClose}>
No
</Button>
<Button color="error" onClick={confirmDeleteGroup}>
Yes pls
</Button>
</DialogActions>
</Dialog>
);
}
Example #20
Source File: Toast.tsx From game-store-monorepo-app with MIT License | 5 votes |
toastWarn = (params: ToastParams) => {
toast.warn(params.content, {
...defaultToastOptions,
...params.options,
});
}
Example #21
Source File: Blurb.tsx From mail-my-ballot with Apache License 2.0 | 5 votes |
Blurb: React.FC<{}> = () => {
const { path, pushAddress } = useAppHistory()
const { address } = AddressContainer.useContainer()
const zipRef = React.useRef<HTMLInputElement>(null)
const { fetchingData, setFetchingData } = FetchingDataContainer.useContainer()
// mobile browsers don't support 100vh, so use this trick instead
// https://chanind.github.io/javascript/2019/09/28/avoid-100vh-on-mobile-web.html
// Also, need to use a state variable instead of a simpler ts variable
// https://stackoverflow.com/a/56156394/8930600
const [height, setHeight] = React.useState('100vh')
React.useEffect(() => {
setHeight(`${window.innerHeight}px`)
}, [])
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.persist() // allow async function call
event.preventDefault()
const zip = zipRef?.current?.value
if (!zip) return
setFetchingData(true)
const resp = await client.fetchState(zip)
if (resp.type === 'error') {
toast.error('Error finding the ZIP code')
} else {
pushAddress(resp.data, zip)
}
setFetchingData(false)
}
const defaultValue = () => {
if (path?.type === 'address' && path.zip) {
return path.zip
} else {
return address?.postcode ?? undefined
}
}
return <Background style={{height}}>
<StyleContainer>
<FlexBox style={{height}}>
<Title>Vote by Mail</Title>
<Text>
Voting by mail is a secure, time-tested, and easy way to vote. Your ballot arrives safely in the mail weeks before the election and can be filled out and returned at your convenience.
</Text>
<Text>Sign up today in <b>2 minutes</b> before your state deadline expires.
</Text>
<AppForm onSubmit={handleSubmit}>
<Text><b>Enter your ZIP code</b> to get started</Text>
<FlexContainer>
{/* id is used by WarningMsg to fill out zipcode */}
<ZipInput
id='start-zip'
data-testid='start-zip'
type='text'
pattern='[0-9]{5}'
placeholder='ZIP code'
defaultValue={defaultValue()}
ref={zipRef} />
<SubmitButton
id='start-submit'
data-testid='start-submit'
variant='raised'
disabled={fetchingData}
>
Start
</SubmitButton>
</FlexContainer>
</AppForm>
</FlexBox>
</StyleContainer>
</Background>
}
Example #22
Source File: skill-details.tsx From liferay-grow with MIT License | 5 votes |
ProfileSkillDetails = () => {
const i18n = useLang();
const [onUpdateGrowMapSkills] = useMutation(UpdateGrowMapSkillDetails);
const onSave = async (selectedSkills: SelectedSkills[], refetch) => {
const knowledgeSkillDetails = selectedSkills.map(
({ isMentor, knowledgeMatrizId, knowledgeSkillId }) => ({
isMentor,
knowledgeMatrizId,
knowledgeSkillId,
}),
);
try {
await onUpdateGrowMapSkills({
variables: {
data: {
knowledgeSkillDetails,
},
},
});
await refetch();
toast.info(i18n.get('your-request-completed-successfully'));
} catch (error) {
toast.error(i18n.get('an-unexpected-error-occurred'));
}
};
return (
<WrappedSafeComponent<RequestProps> query={getMe}>
{({ data: { me }, refetch }) => {
const knowledgeSkillDetails = me.growMap?.knowledgeSkillDetails || [];
const selectedSkills: SelectedSkills[] = knowledgeSkillDetails.map(
({ isMentor = false, knowledgeMatriz, knowledgeSkill }) => ({
isMentor,
knowledgeMatrizId: knowledgeMatriz.id,
knowledgeSkillId: knowledgeSkill.id,
}),
);
return (
<UserSkillTemplate title={i18n.get('skills-details')} me={me}>
<SkillContextProvider defaultState={{ selectedSkills }}>
<SkillDetails onSave={(skills) => onSave(skills, refetch)} />
</SkillContextProvider>
</UserSkillTemplate>
);
}}
</WrappedSafeComponent>
);
}
Example #23
Source File: useFileHandler.tsx From foodie with MIT License | 5 votes |
useFileHandler = <T extends unknown>(type = "multiple", initState: T): IFileHandler<T> => {
const [imageFile, setImageFile] = useState<T>(initState);
const [isFileLoading, setFileLoading] = useState(false);
const removeImage = (id: string) => {
if (!Array.isArray(imageFile)) return;
const items = imageFile.filter(item => item.id !== id);
setImageFile(items as T);
};
const clearFiles = () => {
setImageFile(initState as T);
}
const onFileChange = (event: React.ChangeEvent<HTMLInputElement>, callback?: (file?: IImage) => void) => {
if (!event.target.files) return;
if ((event.target.files.length + (imageFile as IImage[]).length) > 5) {
return toast.error('Maximum of 5 photos per post allowed.', { hideProgressBar: true });
}
// TODO === FILTER OUT DUPLICATE IMAGES
const val = event.target.value;
const img = event.target.files[0] as File;
if (!img) return;
const size = img.size / 1024 / 1024;
const regex = /(\.jpg|\.jpeg|\.png)$/i;
setFileLoading(true);
if (!regex.exec(val)) {
toast.error('File type must be JPEG or PNG', { hideProgressBar: true });
setFileLoading(false);
} else if (size > 2) {
toast.error('File size exceeded 2mb', { hideProgressBar: true });
setFileLoading(false);
} else if (type === 'single') {
const file = event.target.files[0] as File;
const url = URL.createObjectURL(file);
setImageFile({
file,
url,
id: file.name
} as T);
if (callback) callback(imageFile as IImage);
} else {
Array.from(event.target.files).forEach((file) => {
const url = URL.createObjectURL(file);
setImageFile((oldFiles) => ([...oldFiles as any, {
file,
url,
id: file.name
}] as T));
});
if (callback) callback(imageFile as IImage);
setFileLoading(false);
}
};
return {
imageFile,
setImageFile,
isFileLoading,
onFileChange,
removeImage,
clearFiles
};
}
Example #24
Source File: index.tsx From polkabtc-ui with Apache License 2.0 | 5 votes |
Layout = ({ children }: Props): JSX.Element => {
const address = useSelector((state: StoreType) => state.general.address);
const location = useLocation();
const [ref, { height: footerHeight }] = useMeasure<HTMLDivElement>();
const handleRequestDotFromFaucet = async (): Promise<void> => {
// TODO: should show a descriptive warning
if (!address) return;
try {
const receiverId = window.polkaBTC.api.createType(ACCOUNT_ID_TYPE_NAME, address);
await window.faucet.fundAccount(receiverId);
toast.success('Your account has been funded.');
} catch (error) {
toast.error(`Funding failed. ${error.message}`);
}
};
/**
* TODO: a hack for now.
* - Should apply the gradient on the landing page
*/
const isHomePage = location.pathname === PAGES.home;
return (
<div
style={{
// TODO: should avoid hard-coding colors (https://tailwindcss.com/docs/gradient-color-stops)
backgroundImage:
isHomePage ?
// eslint-disable-next-line max-len
'linear-gradient(to right bottom, #e1106d, #e52766, #e83761, #ea445b, #eb5157, #ed5952, #ef624e, #f06a4a, #f37143, #f4783c, #f58035, #f5882d)' :
'unset'
}}
className={clsx(
'relative',
'min-h-screen'
)}>
<main
style={{ paddingBottom: footerHeight }}
className={clsx(
'flex',
'flex-col'
)}>
{!checkStaticPage() && (
<Topbar
address={address}
requestDOT={handleRequestDotFromFaucet} />
)}
{!isHomePage && <TestnetBanner />}
{!isHomePage && <MaintenanceBanner />}
{children}
</main>
<Footer
ref={ref}
className={clsx(
'absolute',
'bottom-0',
'w-full',
'shadow',
'border-t'
)} />
</div>
);
}
Example #25
Source File: message-container.component.tsx From hive-keychain-extension with MIT License | 5 votes |
MessageContainer = ({ errorMessage, resetMessage }: PropsFromRedux) => {
const [timeoutId, setTimeoutId] = useState<any>();
useEffect(() => {
if (errorMessage.key) {
switch (errorMessage.type) {
case MessageType.ERROR:
toast.error(
chrome.i18n.getMessage(errorMessage.key, errorMessage.params),
);
break;
case MessageType.SUCCESS:
toast.success(
chrome.i18n.getMessage(errorMessage.key, errorMessage.params),
);
break;
case MessageType.WARNING:
toast.warning(
chrome.i18n.getMessage(errorMessage.key, errorMessage.params),
);
break;
case MessageType.INFO:
toast.info(
chrome.i18n.getMessage(errorMessage.key, errorMessage.params),
);
break;
}
const id = setTimeout(() => {
close();
}, DURATION);
setTimeoutId(id);
}
}, [errorMessage]);
const close = () => {
resetMessage();
clearTimeout(timeoutId);
};
return (
<ToastContainer
position="bottom-center"
autoClose={DURATION}
pauseOnHover
theme="dark"
onClick={() => close()}
closeOnClick={true}
draggable={false}
bodyStyle={{ fontSize: '16px', fontFamily: 'Futura', fontWeight: '400' }}
/>
);
}
Example #26
Source File: LinkCreator.tsx From tsplay.dev with MIT License | 5 votes |
useLinkInput = ({ setShortened, setShortenedCreated, showToast, setLinks }: Props) => {
const [inputValue, setInputValue] = React.useState('')
const [loading, setLoading] = React.useState(false)
const [customLink, setCustomLink] = React.useState('')
const createLink = async () => {
if (!inputValue) return
if (!isTSLink(inputValue)) {
toast(
<div>
<span role="img" aria-label="warning" className="prevent-hue-rotate">
⚠️{' '}
</span>
Not a TypeScript Playground URL
</div>
)
return
}
if (customLink) {
const [isValid, msg] = validateCustomLink(customLink)
if (!isValid) {
toast(msg)
return
}
}
try {
setLoading(true)
const body: CreatePayload = {
url: inputValue,
createdOn: 'client',
expires: false,
...(customLink && { short: customLink }),
}
const { shortened } = await api<CreateResponse>('short', { body })
setShortenedCreated(shortened)
handleLinksList(shortened, setLinks)
setCustomLink('')
toast(
<div>
<span role="img" aria-label="warning" className="prevent-hue-rotate">
?{' '}
</span>
Short link created successfully!
</div>
)
copyToClipboard(shortened.replace(/^https?:\/\//, ''), shortened, showToast)
setInputValue('')
setShortened(prev => (prev ? prev + 1 : 1))
} catch (e) {
// eslint-disable-next-line no-console
console.log('Error trying to shorten URL', e)
toast(
<div>
<span role="img" aria-label="warning" className="prevent-hue-rotate">
?️{' '}
</span>
Opps, something went wrong.
</div>
)
} finally {
setLoading(false)
}
}
return { inputValue, loading, setInputValue, createLink, customLink, setCustomLink }
}
Example #27
Source File: index.tsx From yasd with MIT License | 5 votes |
Page: React.FC = () => {
const { t } = useTranslation()
const { data: modules, error: modulesError } = useSWR<Modules>(
'/modules',
fetcher,
)
const [isLoading, setIsLoading] = useState(false)
const isChecked = (name: string): boolean => {
return modules?.enabled.includes(name) === true
}
const toggle = useCallback(
(name: string, newVal: boolean) => {
setIsLoading(true)
fetcher({
url: '/modules',
method: 'POST',
data: {
[name]: newVal,
},
})
.then(() => {
toast.success(t('common.success_interaction'))
return mutate('/modules')
})
.catch((err) => {
toast.success(t('common.failed_interaction'))
console.error(err)
})
.finally(() => {
setIsLoading(false)
})
},
[setIsLoading, t],
)
return (
<PageContainer>
<PageTitle title={t('home.modules')} />
<div tw="divide-y divide-gray-200">
{modules &&
modules.available.map((mod) => {
return (
<div key={mod} tw="flex items-center justify-between p-3">
<div tw="truncate leading-normal text-gray-700">{mod}</div>
<div tw="flex items-center">
<Toggle
noMargin
label=""
labelChecked="on"
labelUnchecked="off"
disabled={isLoading}
checked={isChecked(mod)}
onChange={() => toggle(mod, !isChecked(mod))}
/>
</div>
</div>
)
})}
</div>
</PageContainer>
)
}
Example #28
Source File: DeleteButton.tsx From frontend with Apache License 2.0 | 5 votes |
DeleteButton: FunctionComponent = () => {
const { t } = useTranslation()
// Using state to prevent user repeatedly initating fetches
const [clicked, setClicked] = useState(false)
const [waiting, setWaiting] = useState(false)
const [token, setToken] = useState('')
const dispatch = useUserDispatch()
// Only make a request on first click
useEffect(() => {
if (clicked) {
requestDeletion(
setWaiting,
msg_id => {
toast.error(t(msg_id));
setClicked(false);
},
setToken
)
}
}, [dispatch, clicked, t])
if (waiting) {
return <Spinner size={30} />
}
if (token) {
// Callbacks must clear the token to hide the dialog
return <ConfirmDialog
prompt='Delete your account?'
entry='I wish to delete my account'
action={t('delete-account')}
onConfirmed={() => {
setWaiting(true)
deleteAccount(dispatch, token)
.catch(err => {
toast.error(t(err))
setClicked(false)
})
.finally(() => {
setWaiting(false)
})
setToken('')
}}
onCancelled={() => {
// Hide dialog and allow reuse of button
setToken('')
setClicked(false)
}}
/>
}
return (
<Button onClick={() => setClicked(true)} type='secondary'>
{t('delete-account')}
</Button>
)
}
Example #29
Source File: index.tsx From houston with MIT License | 5 votes |
static info(content: React.ReactNode, options?: IToastOptions): void {
const theme = getCurrentTheme();
toast.info(content, {
...options,
style: { ...(theme ? { background: theme.feedbackColor.informative.pure } : {}) }
});
}