diff --git a/web/config/tailwind.config.js b/web/config/tailwind.config.js index 65d8507..831c5b9 100644 --- a/web/config/tailwind.config.js +++ b/web/config/tailwind.config.js @@ -6,6 +6,22 @@ export const theme = { syne: ['Syne', 'sans-serif'], inter: ['Inter', 'sans-serif'], }, + animation: { + enter: 'enter 200ms ease-out', + leave: 'leave 200ms ease-in forwards', + }, + keyframes: { + enter: { + '0%': { transform: 'scale(0.75) translateY(-110%)', opacity: 0 }, + '25%': { opacity: 0 }, + '100%': { transform: 'scale(1) translateX(0)', opacity: 1 }, + }, + leave: { + '0%': { transform: 'scale(1) translateX(0)', opacity: 1 }, + '75%': { opacity: 0 }, + '100%': { transform: 'scale(0.75) translateY(-110%)', opacity: 0 }, + }, + }, }, } diff --git a/web/src/components/ToastNotification/ToastNotification.stories.tsx b/web/src/components/ToastNotification/ToastNotification.stories.tsx new file mode 100644 index 0000000..270318f --- /dev/null +++ b/web/src/components/ToastNotification/ToastNotification.stories.tsx @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import ToastNotification from './ToastNotification' + +const meta: Meta = { + component: ToastNotification, + tags: ['autodocs'], +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/web/src/components/ToastNotification/ToastNotification.test.tsx b/web/src/components/ToastNotification/ToastNotification.test.tsx new file mode 100644 index 0000000..d87dfb3 --- /dev/null +++ b/web/src/components/ToastNotification/ToastNotification.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import ToastNotification from './ToastNotification' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('Toast', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/web/src/components/ToastNotification/ToastNotification.tsx b/web/src/components/ToastNotification/ToastNotification.tsx new file mode 100644 index 0000000..25d28a7 --- /dev/null +++ b/web/src/components/ToastNotification/ToastNotification.tsx @@ -0,0 +1,60 @@ +import { mdiCloseCircle, mdiCheckCircle, mdiClose } from '@mdi/js' +import { Icon } from '@mdi/react' + +import { Toast, toast, ToastType } from '@redwoodjs/web/toast' + +interface Props { + t: Toast + type: ToastType + message: string +} + +const ToastNotification = ({ t, type, message }: Props) => { + let iconElement: React.JSX.Element + + if (type === 'blank' || type === 'custom') iconElement = <> + else if (type === 'loading') + iconElement = + else { + let icon: string + let color: string + + switch (type) { + case 'success': + icon = mdiCheckCircle + color = 'text-success' + break + case 'error': + icon = mdiCloseCircle + color = 'text-error' + break + } + + iconElement = + } + + return ( +
+ {iconElement} +

{message}

+ {type !== 'loading' ? ( + + ) : ( + <> + )} +
+ ) +} + +export default ToastNotification diff --git a/web/src/layouts/NavbarLayout/NavbarLayout.tsx b/web/src/layouts/NavbarLayout/NavbarLayout.tsx index 9f62814..f888d04 100644 --- a/web/src/layouts/NavbarLayout/NavbarLayout.tsx +++ b/web/src/layouts/NavbarLayout/NavbarLayout.tsx @@ -2,8 +2,10 @@ import { mdiMenu } from '@mdi/js' import Icon from '@mdi/react' import { Link, routes } from '@redwoodjs/router' +import { Toaster } from '@redwoodjs/web/toast' import ThemeToggle from 'src/components/ThemeToggle/ThemeToggle' +import ToastNotification from 'src/components/ToastNotification/ToastNotification' interface NavbarRoute { name: string @@ -32,6 +34,22 @@ const NavbarLayout = ({ children }: NavbarLayoutProps) => { return ( <> + + {(t) => ( + + )} +
diff --git a/web/src/pages/HomePage/HomePage.tsx b/web/src/pages/HomePage/HomePage.tsx index 75f04f0..a30969e 100644 --- a/web/src/pages/HomePage/HomePage.tsx +++ b/web/src/pages/HomePage/HomePage.tsx @@ -1,19 +1,53 @@ -import { Link, routes } from '@redwoodjs/router' import { Metadata } from '@redwoodjs/web' +import { toast } from '@redwoodjs/web/toast' const HomePage = () => { return ( <> -

HomePage

-

- Find me in ./web/src/pages/HomePage/HomePage.tsx -

-

- My default route is named home, link to me with ` - Home` -

+ + + + + + ) }