From e55d08279bce7362957673fee9f76bda03342f47 Mon Sep 17 00:00:00 2001 From: Yangshun Tay Date: Sat, 22 Oct 2022 17:46:35 +0800 Subject: [PATCH] [ui] add toasts --- apps/portal/src/pages/_app.tsx | 9 +- apps/portal/src/pages/index.tsx | 23 +---- apps/portal/src/pages/test__.tsx | 51 +++++++++++ packages/ui/src/Toast/Toast.tsx | 108 +++++++++++++++++++++++ packages/ui/src/Toast/ToastsProvider.tsx | 72 +++++++++++++++ packages/ui/src/index.tsx | 6 ++ 6 files changed, 244 insertions(+), 25 deletions(-) create mode 100644 apps/portal/src/pages/test__.tsx create mode 100644 packages/ui/src/Toast/Toast.tsx create mode 100644 packages/ui/src/Toast/ToastsProvider.tsx diff --git a/apps/portal/src/pages/_app.tsx b/apps/portal/src/pages/_app.tsx index 11606124..9914942e 100644 --- a/apps/portal/src/pages/_app.tsx +++ b/apps/portal/src/pages/_app.tsx @@ -3,6 +3,7 @@ import type { Session } from 'next-auth'; import { SessionProvider } from 'next-auth/react'; import React from 'react'; import superjson from 'superjson'; +import { ToastsProvider } from '@tih/ui'; import { httpBatchLink } from '@trpc/client/links/httpBatchLink'; import { loggerLink } from '@trpc/client/links/loggerLink'; import { withTRPC } from '@trpc/next'; @@ -19,9 +20,11 @@ const MyApp: AppType<{ session: Session | null }> = ({ }) => { return ( - - - + + + + + ); }; diff --git a/apps/portal/src/pages/index.tsx b/apps/portal/src/pages/index.tsx index 360c81e8..51f58469 100644 --- a/apps/portal/src/pages/index.tsx +++ b/apps/portal/src/pages/index.tsx @@ -1,32 +1,11 @@ -import { useState } from 'react'; -import type { TypeaheadOption } from '@tih/ui'; -import { HorizontalDivider } from '@tih/ui'; - -import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead'; -import type { Month, MonthYear } from '~/components/shared/MonthYearPicker'; -import MonthYearPicker from '~/components/shared/MonthYearPicker'; - export default function HomePage() { - const [selectedCompany, setSelectedCompany] = - useState(null); - const [monthYear, setMonthYear] = useState({ - month: (new Date().getMonth() + 1) as Month, - year: new Date().getFullYear(), - }); - return (

- Homepage + Tech Interview Handbook Portal

- setSelectedCompany(option)} - /> -
{JSON.stringify(selectedCompany, null, 2)}
- -
diff --git a/apps/portal/src/pages/test__.tsx b/apps/portal/src/pages/test__.tsx new file mode 100644 index 00000000..26859c56 --- /dev/null +++ b/apps/portal/src/pages/test__.tsx @@ -0,0 +1,51 @@ +import { useState } from 'react'; +import type { TypeaheadOption } from '@tih/ui'; +import { Button } from '@tih/ui'; +import { useToast } from '@tih/ui'; +import { HorizontalDivider } from '@tih/ui'; + +import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead'; +import type { Month, MonthYear } from '~/components/shared/MonthYearPicker'; +import MonthYearPicker from '~/components/shared/MonthYearPicker'; + +export default function HomePage() { + const [selectedCompany, setSelectedCompany] = + useState(null); + const [monthYear, setMonthYear] = useState({ + month: (new Date().getMonth() + 1) as Month, + year: new Date().getFullYear(), + }); + + const { showToast } = useToast(); + + return ( +
+
+
+

+ Test Page +

+ setSelectedCompany(option)} + /> +
{JSON.stringify(selectedCompany, null, 2)}
+ + + +
+
+
+ ); +} diff --git a/packages/ui/src/Toast/Toast.tsx b/packages/ui/src/Toast/Toast.tsx new file mode 100644 index 00000000..4d6efe51 --- /dev/null +++ b/packages/ui/src/Toast/Toast.tsx @@ -0,0 +1,108 @@ +import { Fragment, useEffect, useRef } from 'react'; +import { Transition } from '@headlessui/react'; +import { CheckIcon } from '@heroicons/react/24/outline'; +import { XMarkIcon } from '@heroicons/react/24/solid'; + +type ToastVariant = 'failure' | 'success'; + +export type ToastMessage = { + duration?: number; + subtitle?: string; + title: string; + variant: ToastVariant; +}; + +type Props = Readonly<{ + duration?: number; + onClose: () => void; + subtitle?: string; + title: string; + variant: ToastVariant; +}>; + +const DEFAULT_DURATION = 5000; + +function ToastIcon({ variant }: Readonly<{ variant: ToastVariant }>) { + switch (variant) { + case 'success': + return ( +