diff --git a/packages/web/components/templates/article/HighlightNoteModal.tsx b/packages/web/components/templates/article/HighlightNoteModal.tsx
index e94213733..a39209a0c 100644
--- a/packages/web/components/templates/article/HighlightNoteModal.tsx
+++ b/packages/web/components/templates/article/HighlightNoteModal.tsx
@@ -17,7 +17,7 @@ import { readableUpdatedAtMessage } from './../../../lib/dateFormatting'
import { useConfirmListener } from '../../../lib/keyboardShortcuts/useKeyboardShortcuts'
import { createHighlight } from '../../../lib/highlights/createHighlight'
import { createHighlightMutation } from '../../../lib/networking/mutations/createHighlightMutation'
-import toast from 'react-hot-toast'
+import { showErrorToast } from '../../../lib/toastHelpers'
type HighlightNoteModalProps = {
author: string
@@ -59,14 +59,14 @@ export function HighlightNoteModal(
props.onUpdate({ ...props.highlight, annotation: noteContent })
props.onOpenChange(false)
} else {
- toast.error('Error updating your note', { position: 'bottom-right' })
+ showErrorToast('Error updating your note', { position: 'bottom-right' })
}
} if (!props.highlight && props.createHighlightForNote) {
const result = await props.createHighlightForNote(noteContent)
if (result) {
props.onOpenChange(true)
} else {
- toast.error('Error saving highlight', { position: 'bottom-right' })
+ showErrorToast('Error saving highlight', { position: 'bottom-right' })
}
} else {
props.onOpenChange(false)
diff --git a/packages/web/components/templates/article/HighlightsLayer.tsx b/packages/web/components/templates/article/HighlightsLayer.tsx
index be622a01f..b25cc0937 100644
--- a/packages/web/components/templates/article/HighlightsLayer.tsx
+++ b/packages/web/components/templates/article/HighlightsLayer.tsx
@@ -18,7 +18,7 @@ import { ShareHighlightModal } from './ShareHighlightModal'
import { HighlightPostToFeedModal } from './HighlightPostToFeedModal'
import { HighlightsModal } from './HighlightsModal'
import { useCanShareNative } from '../../../lib/hooks/useCanShareNative'
-import toast from 'react-hot-toast'
+import { showErrorToast } from '../../../lib/toastHelpers'
import { ArticleMutations } from '../../../lib/articleActions'
type HighlightsLayerProps = {
@@ -220,7 +220,7 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
annotation
)
if (!result) {
- toast.error('Error saving highlight', { position: 'bottom-right' })
+ showErrorToast('Error saving highlight', { position: 'bottom-right' })
}
// if (successAction === 'share' && canShareNative) {
// handleNativeShare(highlight.shortId)
diff --git a/packages/web/components/templates/article/SnoozeLinkModal.tsx b/packages/web/components/templates/article/SnoozeLinkModal.tsx
index c13958803..68167820e 100644
--- a/packages/web/components/templates/article/SnoozeLinkModal.tsx
+++ b/packages/web/components/templates/article/SnoozeLinkModal.tsx
@@ -4,7 +4,7 @@ import { Button } from '../../elements/Button'
import { StyledText } from '../../elements/StyledText'
import { X, Check } from 'phosphor-react'
import { useState } from 'react'
-import toast from 'react-hot-toast'
+import { showErrorToast } from '../../../lib/toastHelpers'
type ShareArticleModalProps = {
onOpenChange: (open: boolean) => void
@@ -149,7 +149,7 @@ export function SnoozeLinkModal(
props.submit(snoozeOption, sendReminder, msg)
props.onOpenChange(false)
} else {
- toast.error('No option selected', { position: 'bottom-right' })
+ showErrorToast('No option selected', { position: 'bottom-right' })
}
}}
>Save
@@ -158,4 +158,4 @@ export function SnoozeLinkModal(
)
-}
\ No newline at end of file
+}
diff --git a/packages/web/components/templates/homeFeed/AddLinkModal.tsx b/packages/web/components/templates/homeFeed/AddLinkModal.tsx
index 1246b0341..162eb147c 100644
--- a/packages/web/components/templates/homeFeed/AddLinkModal.tsx
+++ b/packages/web/components/templates/homeFeed/AddLinkModal.tsx
@@ -13,6 +13,7 @@ import { useState, useCallback } from 'react'
import { createArticleFromURLMutation } from '../../../lib/networking/mutations/createArticleFromURLMutation'
import { saveUrlMutation } from '../../../lib/networking/mutations/saveUrlMutation'
import toast from 'react-hot-toast'
+import { showErrorToast } from '../../../lib/toastHelpers'
type AddLinkModalProps = {
onOpenChange: (open: boolean) => void
@@ -42,7 +43,7 @@ export function AddLinkModal(props: AddLinkModalProps): JSX.Element {
), { position: 'bottom-right' })
} else {
- toast.error('Error saving link', { position: 'bottom-right' })
+ showErrorToast('Error saving link', { position: 'bottom-right' })
}
}, [link])
@@ -100,7 +101,7 @@ export function AddLinkModal(props: AddLinkModalProps): JSX.Element {
// `https` to give the link a protocol.
const newLink = `https://${link}`
if (!validateLink(newLink)) {
- toast.error('Invalid link', { position: 'bottom-right' })
+ showErrorToast('Invalid link', { position: 'bottom-right' })
return
}
setLink(newLink)
diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
index 36c2371c4..7fe8339df 100644
--- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
+++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
@@ -27,7 +27,7 @@ import { ShareArticleModal } from '../article/ShareArticleModal'
import { userPersonalizationMutation } from '../../../lib/networking/mutations/userPersonalizationMutation'
import { useGetUserPreferences } from '../../../lib/networking/queries/useGetUserPreferences'
import { webBaseURL } from '../../../lib/appConfig'
-import toast, { Toaster } from 'react-hot-toast'
+import { Toaster } from 'react-hot-toast'
import { SnoozeLinkModal } from '../article/SnoozeLinkModal'
import {
createReminderMutation,
@@ -35,6 +35,7 @@ import {
} from '../../../lib/networking/mutations/createReminderMutation'
import { useFetchMoreScroll } from '../../../lib/hooks/useFetchMoreScroll'
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
+import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers'
export type LayoutType = 'LIST_LAYOUT' | 'GRID_LAYOUT'
@@ -675,10 +676,10 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
return props.actionHandler('archive', props.snoozeTarget)
})
.then(() => {
- toast.success(msg, { position: 'bottom-right' })
+ showSuccessToast(msg, { position: 'bottom-right' })
})
.catch((error) => {
- toast.error('There was an error snoozing your link.', {
+ showErrorToast('There was an error snoozing your link.', {
position: 'bottom-right',
})
})
diff --git a/packages/web/lib/toastHelpers.tsx b/packages/web/lib/toastHelpers.tsx
new file mode 100644
index 000000000..ea76bb39b
--- /dev/null
+++ b/packages/web/lib/toastHelpers.tsx
@@ -0,0 +1,64 @@
+import { toast, ToastOptions } from 'react-hot-toast'
+import { CheckCircle, WarningCircle, X } from 'phosphor-react'
+import { Box, HStack } from '../components/elements/LayoutPrimitives'
+import { styled } from '@stitches/react'
+
+const toastStyles = {
+ minWidth: 265,
+ height: 56,
+ borderRadius: 4,
+ boxShadow: '0px 2px 8px rgba(32, 31, 29, 0.33)',
+ margin: 0,
+ paddingLeft: 6,
+ paddingRight: 6,
+ paddingTop: 12,
+ paddingBottom: 12,
+}
+
+const messageStyles = {
+ fontSize: 16,
+ fontWeight: 'bolder',
+ color: 'white',
+ flex: 1,
+ marginLeft: 16,
+}
+
+const MessageContainer = styled(Box, messageStyles)
+const FullWidthContainer = styled(HStack, {
+ width: '100%',
+})
+
+type ToastType = 'success' | 'error'
+
+const showToast = (
+ message: string,
+ background: string,
+ type: ToastType,
+ options?: ToastOptions
+) => {
+ return toast(
+ ({ id }) => (
+
+ {type === 'success' ? : }
+ {message}
+
+ toast.dismiss(id)} />
+
+
+ ),
+ {
+ style: {
+ ...toastStyles,
+ background: background,
+ },
+ ...options,
+ })
+}
+
+export const showSuccessToast = (message: string, options?: ToastOptions) => {
+ return showToast(message, '#55B938', 'success', options)
+}
+
+export const showErrorToast = (message: string, options?: ToastOptions) => {
+ return showToast(message, '#cc0000', 'error', options)
+}
diff --git a/packages/web/pages/settings/emails.tsx b/packages/web/pages/settings/emails.tsx
index befc50bf9..76e4697f7 100644
--- a/packages/web/pages/settings/emails.tsx
+++ b/packages/web/pages/settings/emails.tsx
@@ -22,6 +22,7 @@ import { toast, Toaster } from 'react-hot-toast'
import { useCallback } from 'react'
import { StyledText } from '../../components/elements/StyledText'
import { applyStoredTheme } from '../../lib/themeUpdater'
+import { showSuccessToast } from '../../lib/toastHelpers'
import Link from 'next/link'
enum TextType {
@@ -165,11 +166,7 @@ function CopyTextButton(props: CopyTextButtonProps): JSX.Element {
const copy = useCallback(() => {
copyLink()
- toast(
- props.type == TextType.EmailAddress
- ? 'Email Address Copied'
- : 'Confirmation Code Copied'
- )
+ showSuccessToast(props.type == TextType.EmailAddress ? 'Email Address Copied' : 'Confirmation Code Copied');
}, [])
return (
@@ -186,14 +183,14 @@ export default function EmailsPage(): JSX.Element {
applyStoredTheme(false)
async function createEmail(): Promise {
+ showSuccessToast('Email Created!')
await createNewsletterEmailMutation()
revalidate()
- toast.success('Email Created')
}
async function deleteEmail(id: string): Promise {
await deleteNewsletterEmailMutation(id)
revalidate()
- toast.success('Email Deleted!')
+ showSuccessToast('Email Deleted!')
}
return (
diff --git a/packages/web/pages/settings/labels.tsx b/packages/web/pages/settings/labels.tsx
index 4254fbdfa..64f0916ad 100644
--- a/packages/web/pages/settings/labels.tsx
+++ b/packages/web/pages/settings/labels.tsx
@@ -1,12 +1,13 @@
import { PrimaryLayout } from '../../components/templates/PrimaryLayout'
import { Button } from '../../components/elements/Button'
import { Box, VStack } from '../../components/elements/LayoutPrimitives'
-import { toast, Toaster } from 'react-hot-toast'
+import { Toaster } from 'react-hot-toast'
import { useGetLabelsQuery } from '../../lib/networking/queries/useGetLabelsQuery'
import { createLabelMutation } from '../../lib/networking/mutations/createLabelMutation'
import { deleteLabelMutation } from '../../lib/networking/mutations/deleteLabelMutation'
import { useState } from 'react'
import { applyStoredTheme } from '../../lib/themeUpdater'
+import { showErrorToast, showSuccessToast } from '../../lib/toastHelpers'
export default function LabelsPage(): JSX.Element {
const { labels, revalidate, isValidating } = useGetLabelsQuery()
@@ -20,16 +21,16 @@ export default function LabelsPage(): JSX.Element {
const res = await createLabelMutation(name, color, description)
if (res) {
if (res.createLabel.errorCodes && res.createLabel.errorCodes.length > 0) {
- toast.error(res.createLabel.errorCodes[0])
+ showErrorToast(res.createLabel.errorCodes[0])
} else {
- toast.success('Label created')
+ showSuccessToast('Label created')
setName('')
setColor('')
setDescription('')
revalidate()
}
} else {
- toast.error('Failed to create label')
+ showErrorToast('Failed to create label')
}
}