From f33ebb04978cdf4b8fd290db5194c6550d9ff303 Mon Sep 17 00:00:00 2001 From: Kar Rui Lau Date: Fri, 4 Aug 2023 13:43:34 +0800 Subject: [PATCH] feat: twitter clone pivot app (#96) * feat: add username to user schema * feat: generate username on account creation * feat: rename /dashboard route to /home * wip: tweet on dashboard * feat: update to design system alpha.12 * refactor: move /profile to /profile/[id] route * feat: separate profile page and edit profile page * fix: import set * feat: add profile router and add error handling for update profile * feat: update app layouts * feat: add update profile page according to new design * refactor: move `me` and `settings` related files into own feature dir * refactor: rename user.* to me.* since we now have profiles, should distinguish between procedures and services relating to currently logged in user vs other users * feat: clean up redundant Avatar component props * feat: fetch and display user profiles * feat: add NavigationalTab component * feat: add ProfileLayout and profile tabs * feat: add initial profile tweet view * feat: add TweetActions component placeholder * feat: add procedure to handle liking of posts * refactor: rename tweet -> post to better align with purpose * feat: enable replying in profile view * fix: only fetch posts without parent posts * feat: add procedure for retrieving liked posts * feat: use local state instead of invalidating query * feat: enable delete * fix: relative date calculation * feat: add handling of navigation to thread view * feat: extract BackBannerLink component * feat: rename PROFILE_ grid column constants to APP_ * feat: update styling for app's navbar and sidebar * feat: add thread view * feat: remove old feedback routes not needed in new app anymore, but cannot post anymore haha * feat: add new post functionality on profile and home page * feat: remove unused files and functions * feat: fetch all posts user has replied * feat: add custom image upload button * feat: add images field to Post table in db * feat: update r2 bucket hierarchy and env vars, add image upload feat now using single-bucket architecture to reduce number of env vars needed for each feature (avatars, images). The images uploaded will be nested under the single bucket. Some drawbacks though: No more finer grained access control, but should be ok for our use case, since all images should be public. * feat: render images in posts * fix: correctly hide deleted posts in thread replies * feat: stop retrying 404s * feat: return to home page on 404 in thread * fix: properly check image types of uploaded files * feat: remove ssr on index page * fix: lint fix * fix: swc autofix swc packages * fix: render AppNavbar correctly * feat: generate username for sgid login if not set * feat: clean up exports, import from feature's /component directory * fix: correct landing page styling after merge AppGrid padding has changed in this branch * fix: clear session on SGID route call regardless * feat: display SGID errors in email field * fix: AppNavbar stickiness * feat: add responsive sidebar * feat: add mobile app layout * feat: add mobile styling to post view * feat: add mobile responsiveness to profile page * feat: add responsiveness to profile settings * feat: allow updating of email address in profile * feat: remove mock repost button (for now) * feat: add link copy functionality * feat: remove unused ogp-logo asset * feat: remove unused imports * fix: add cuid2 package left out from branch merge * fix: remove now-unneeded ts-expect-error directive * feat: remove read post feature unneeded, cutting down complexity * fix(profile): styling * feat: update padding again * feat: use suspense for profile fetch, add post skeletons * feat: add empty states for profile * feat: add empty state for home page * refactor: move SkeletonPostList to common component * feat: add empty and skeleton states for home page * feat: add skeleton state to thread view * feat: remove default useErrorBoundary on trpc query client it will be automatically set when users use `useSuspenseQuery` hook * feat: update storybook * fix(FileButton): incorrect displayname * fix: correctly mock trpc-msw with superjson * feat: update storybook preview for new suspense setup * feat: add initial empty homepage story * feat(story): add mockdate decorator, posts and mobile story * fix: await or void promises with new lint rule * feat(PostActions): set empty box if not owner of post * feat(PostActions): use tooltip to denote copy action * feat: synchronise avatar display in posts with navbar * feat: extract NewPostModal to own component and add story * feat: correctly hide upload button if image uploads are not enabled * feat: move feature available in application into a provider * fix(storybook): add feature flag decorator allows setting of features to rendered stories * feat(signin): add story to show sgID login * feat: update empty post text * feat: remove avatar display on create modal * feat: update and lock tiptap packages to 2.0.3 * feat: focus on rich text editor in compose modals * feat: disable buttons if no content is entered yet * fix: incorrect margins when replying to comment * fix(ComposePost): avatar colouring consistency * feat: add ResponsiveModal, use in post modals * feat: add fontFeatureSettings to tiptap editor * feat: update toast description when creating post * feat: add back all Restricted components * feat: update layout of application * feat: update reply post toast copy * fix(ResponsiveModal): remove isCentered prop * fix: zIndex of adminlayout fixed areas * feat: add breathing space to app outlet * feat: use chakra image for non-caching image load * feat: add better spacing for profile tabs * fix(RichText): prevent editor from focusing if is readonly was causing content jumps due to focusing when the editor is created * feat: appnavbar logo to return to homepage instead of landing * fix: update alignment of post body * feat: update mobile views of modals * feat: clamp upload image preview to 1 column on mobile * feat: move bottom padding into the pages themselves * fix: modal styling * fix: correct padding of postview on mobile * feat: fix image sizing according to design * fix: update modal buttons for add comment modal too * feat: remove govtmasthead on admin layout * feat(editProfile): fill white bg to whole of page * feat: remove logout button on side dashbar * feat(AddCommentModal): add missing close button * feat(ResponsiveModal): add isCentered, set scroll behavior to inside * fix: correctly add back stack divider when rendering post list * feat: add missing dividers in thread view * feat: add app-specific modal styling example * feat: clean up and update PostSkeleton, rename to SkeletonPost * fix: correct rendering of PostList * feat: add skeleton for thread view * fix: remove react component spreading in skeletons * feat: change sgid login button variant to clear --- .env.example | 2 + .storybook/preview.tsx | 88 +- package-lock.json | 2783 ++++++++--------- package.json | 32 +- .../20230411055801_add_username/migration.sql | 11 + .../migration.sql | 2 + .../migration.sql | 14 + prisma/schema.prisma | 17 +- src/components/AppNavbar.tsx | 36 +- .../AppProviders/FeatureProvider.tsx | 53 + src/components/AppProviders/index.ts | 1 + src/components/Avatar.tsx | 17 +- src/components/BackBannerButton.tsx | 17 + src/components/BackBannerLink.tsx | 20 + src/components/Breadcrumb/Crumb.tsx | 41 - src/components/Breadcrumb/index.ts | 1 - src/components/ChevronMenuButton.tsx | 41 - src/components/DashSidebar.tsx | 81 +- src/components/ErrorBoundary/index.ts | 1 + src/components/FileButton.tsx | 131 + .../AttachmentFileInfo.tsx | 88 + .../ImageAttachmentButton.tsx | 75 + .../ImageAttachmentButtonContext.tsx | 6 + src/components/ImageAttachmentButton/index.ts | 1 + .../NavigationalTabs/NavigationalTab.tsx | 43 + .../NavigationalTabs/NavigationalTabList.tsx | 37 + src/components/NavigationalTabs/index.ts | 2 + src/components/NextImage.tsx | 74 - src/components/ResponsiveButton.tsx | 11 + src/components/ResponsiveModal.tsx | 31 + src/components/ResponsiveModalButtonGroup.tsx | 17 + src/components/RichText/RichText.tsx | 275 +- src/components/RichText/RichTextMenu.tsx | 3 - src/components/RichText/constants.tsx | 1 + src/components/Sidebar/NestedSidebarItem.tsx | 68 - src/components/Sidebar/Sidebar.tsx | 59 - .../Sidebar/SidebarCollapseButton.tsx | 45 - src/components/Sidebar/SidebarContainer.tsx | 29 - src/components/Sidebar/SidebarContext.tsx | 94 - src/components/Sidebar/SidebarItem.tsx | 48 - src/components/Sidebar/SidebarSection.tsx | 32 - .../Sidebar/SidebarStylesContext.tsx | 5 - src/components/Sidebar/index.ts | 1 - src/components/Sidebar/types.ts | 20 - src/components/SkeletonPostList.tsx | 33 + src/components/Svg/BusStop.tsx | 136 + src/components/Svg/index.ts | 1 + src/constants/layouts.ts | 19 + src/constants/routes.ts | 2 - src/env.mjs | 8 +- src/features/feedback/api/actionState.ts | 18 - src/features/feedback/api/types.ts | 1 - .../feedback/api/useFilterFeedback.ts | 89 - .../DeleteFeedbackContent.tsx | 58 - .../EditFeedbackContent.tsx | 91 - .../FeedbackActionsModal.tsx | 21 - .../components/FeedbackActionsModal/index.ts | 1 - .../feedback/components/FeedbackComment.tsx | 43 - .../components/FeedbackCommentRichText.tsx | 84 - .../feedback/components/FeedbackHeader.tsx | 31 - .../feedback/components/FeedbackNavbar.tsx | 41 - .../feedback/components/FeedbackRowMenu.tsx | 61 - .../feedback/components/FeedbackUncleSvgr.tsx | 146 - .../components/TeamFeedbackFilterBar.tsx | 66 - .../feedback/components/TeamFeedbackList.tsx | 17 - .../components/TeamFeedbackListSkeleton.tsx | 38 - .../feedback/components/TeamFeedbackRow.tsx | 50 - src/features/feedback/components/index.ts | 5 - .../home/components/EmptyPostList.tsx | 11 + .../home/components/NewPostBanner.tsx | 13 + src/features/home/components/PostList.tsx | 25 + src/features/home/components/index.ts | 2 + .../landing/components/AppPublicHeader.tsx | 4 +- .../landing/components/FeatureGridItem.tsx | 12 +- .../landing/components/LandingSection.tsx | 3 +- src/features/me/api/index.ts | 1 + .../api/useUser.ts => me/api/useMe.ts} | 11 +- src/features/posts/api/index.ts | 1 + .../posts/api/useUploadImagesMutation.ts | 40 + .../AddCommentModal/AddCommentModal.tsx | 149 + .../posts/components/AddCommentModal/index.ts | 1 + src/features/posts/components/ComposePost.tsx | 70 + .../posts/components/DeletePostModal.tsx | 73 + .../NewPostModal/NewPostModal.stories.tsx | 45 + .../components/NewPostModal/NewPostModal.tsx | 107 + .../NewPostModal/NewPostModalButton.tsx | 21 + .../posts/components/NewPostModal/index.ts | 1 + src/features/posts/components/Post/Post.tsx | 38 + .../posts/components/Post/PostImages.tsx | 39 + .../posts/components/Post/PostView.tsx | 73 + .../posts/components/Post/SkeletonPost.tsx | 48 + src/features/posts/components/Post/index.ts | 4 + .../PostActions/AddCommentAction.tsx | 46 + .../components/PostActions/CopyAction.tsx | 38 + .../PostActions/DeletePostAction.tsx | 33 + .../components/PostActions/PostActions.tsx | 95 + .../PostActions/ReplyToPostAction.tsx | 49 + .../posts/components/PostActions/index.ts | 2 + src/features/posts/components/index.ts | 4 + .../posts/schemas/clientAddPostSchema.ts | 27 + src/features/profile/assets/profile-aunty.svg | 36 - .../profile/components/EmptyPostList.tsx | 30 + .../profile/components/ProfileAuntySvgr.tsx | 159 - .../profile/components/ProfileDescription.tsx | 76 + .../profile/components/ProfileTabs.tsx | 54 + src/features/profile/components/index.ts | 3 + .../{profile => settings}/api/index.ts | 1 - .../api/useUploadAvatarMutation.ts | 14 +- .../components/AvatarUpload.tsx | 56 +- src/features/settings/components/index.ts | 1 + src/features/sign-in/components/Emailnput.tsx | 11 + .../sign-in/components/GridLayout.tsx | 6 +- .../sign-in/components/SgidLoginButton.tsx | 7 +- .../sign-in/components/VerificationInput.tsx | 5 +- src/features/sign-in/components/index.ts | 2 + .../thread/components/SkeletonThreadPost.tsx | 54 + .../components/SkeletonThreadPostList.tsx | 33 + .../thread/components/SkeletonThreadView.tsx | 24 + src/features/thread/components/ThreadPost.tsx | 98 + src/features/thread/components/ThreadView.tsx | 41 + src/features/thread/components/index.ts | 2 + src/lib/dates.ts | 34 + src/lib/form.ts | 13 +- src/lib/routes.ts | 4 + src/lib/types/index.ts | 8 +- src/lib/types/iron-session.d.ts | 4 +- src/lib/types/trpc.ts | 5 - src/lib/withSession.ts | 17 - src/pages/404.tsx | 7 +- src/pages/_app.tsx | 29 +- src/pages/dashboard.tsx | 52 - src/pages/feedback/[id].tsx | 100 - src/pages/feedback/new.tsx | 121 - src/pages/home.tsx | 40 + src/pages/index.tsx | 33 +- src/pages/profile.tsx | 110 - src/pages/profile/[username]/index.tsx | 47 + src/pages/profile/[username]/liked.tsx | 47 + src/pages/profile/[username]/replies.tsx | 47 + src/pages/settings/profile.tsx | 192 ++ src/pages/sign-in/index.tsx | 15 +- src/pages/thread/[postId].tsx | 42 + src/schemas/me.ts | 8 +- src/schemas/post.ts | 24 +- src/schemas/presign.ts | 12 + src/schemas/thread.ts | 7 +- src/server/modules/_app.ts | 2 + src/server/modules/auth/email/email.router.ts | 10 +- src/server/modules/auth/sgid/sgid.router.ts | 34 +- src/server/modules/me/me.router.ts | 41 +- .../{user/user.select.ts => me/me.select.ts} | 5 +- src/server/modules/me/me.service.ts | 8 + src/server/modules/post/post.router.ts | 413 ++- src/server/modules/post/post.select.ts | 30 +- src/server/modules/post/post.util.ts | 18 - src/server/modules/profile/profile.router.ts | 42 + src/server/modules/profile/profile.select.ts | 13 + src/server/modules/storage/storage.router.ts | 56 +- src/server/modules/thread/thread.router.ts | 7 +- src/stories/Page/HomePage.stories.tsx | 46 + src/stories/Page/SignInPage.stories.ts | 28 +- src/templates/AppGrid.tsx | 1 - src/templates/layouts/AdminLayout.tsx | 24 +- src/templates/layouts/ProfileLayout.tsx | 42 + src/templates/layouts/ThreadLayout.tsx | 3 + src/templates/layouts/nestLayout.ts | 6 + src/theme/components/Accordion.ts | 52 - src/theme/components/Modal.ts | 22 + src/theme/components/Sidebar.ts | 98 - src/theme/components/index.ts | 6 +- src/theme/index.ts | 5 +- src/theme/layerStyles.ts | 9 + src/utils/image.ts | 8 + src/utils/registerWithDebounce.ts | 37 + src/utils/trpc.ts | 5 +- tests/msw/handlers/me.ts | 33 + tests/msw/handlers/post.ts | 76 + {src/stories/utils => tests/msw}/mockTrpc.ts | 7 +- 178 files changed, 5303 insertions(+), 4215 deletions(-) create mode 100644 prisma/migrations/20230411055801_add_username/migration.sql create mode 100644 prisma/migrations/20230523090610_add_images_to_posts/migration.sql create mode 100644 prisma/migrations/20230626092920_remove_read_post_feature/migration.sql create mode 100644 src/components/AppProviders/FeatureProvider.tsx create mode 100644 src/components/AppProviders/index.ts create mode 100644 src/components/BackBannerButton.tsx create mode 100644 src/components/BackBannerLink.tsx delete mode 100644 src/components/Breadcrumb/Crumb.tsx delete mode 100644 src/components/Breadcrumb/index.ts delete mode 100644 src/components/ChevronMenuButton.tsx create mode 100644 src/components/ErrorBoundary/index.ts create mode 100644 src/components/FileButton.tsx create mode 100644 src/components/ImageAttachmentButton/AttachmentFileInfo.tsx create mode 100644 src/components/ImageAttachmentButton/ImageAttachmentButton.tsx create mode 100644 src/components/ImageAttachmentButton/ImageAttachmentButtonContext.tsx create mode 100644 src/components/ImageAttachmentButton/index.ts create mode 100644 src/components/NavigationalTabs/NavigationalTab.tsx create mode 100644 src/components/NavigationalTabs/NavigationalTabList.tsx create mode 100644 src/components/NavigationalTabs/index.ts delete mode 100644 src/components/NextImage.tsx create mode 100644 src/components/ResponsiveButton.tsx create mode 100644 src/components/ResponsiveModal.tsx create mode 100644 src/components/ResponsiveModalButtonGroup.tsx delete mode 100644 src/components/Sidebar/NestedSidebarItem.tsx delete mode 100644 src/components/Sidebar/Sidebar.tsx delete mode 100644 src/components/Sidebar/SidebarCollapseButton.tsx delete mode 100644 src/components/Sidebar/SidebarContainer.tsx delete mode 100644 src/components/Sidebar/SidebarContext.tsx delete mode 100644 src/components/Sidebar/SidebarItem.tsx delete mode 100644 src/components/Sidebar/SidebarSection.tsx delete mode 100644 src/components/Sidebar/SidebarStylesContext.tsx delete mode 100644 src/components/Sidebar/index.ts delete mode 100644 src/components/Sidebar/types.ts create mode 100644 src/components/SkeletonPostList.tsx create mode 100644 src/components/Svg/BusStop.tsx create mode 100644 src/constants/layouts.ts delete mode 100644 src/constants/routes.ts delete mode 100644 src/features/feedback/api/actionState.ts delete mode 100644 src/features/feedback/api/types.ts delete mode 100644 src/features/feedback/api/useFilterFeedback.ts delete mode 100644 src/features/feedback/components/FeedbackActionsModal/DeleteFeedbackContent.tsx delete mode 100644 src/features/feedback/components/FeedbackActionsModal/EditFeedbackContent.tsx delete mode 100644 src/features/feedback/components/FeedbackActionsModal/FeedbackActionsModal.tsx delete mode 100644 src/features/feedback/components/FeedbackActionsModal/index.ts delete mode 100644 src/features/feedback/components/FeedbackComment.tsx delete mode 100644 src/features/feedback/components/FeedbackCommentRichText.tsx delete mode 100644 src/features/feedback/components/FeedbackHeader.tsx delete mode 100644 src/features/feedback/components/FeedbackNavbar.tsx delete mode 100644 src/features/feedback/components/FeedbackRowMenu.tsx delete mode 100644 src/features/feedback/components/FeedbackUncleSvgr.tsx delete mode 100644 src/features/feedback/components/TeamFeedbackFilterBar.tsx delete mode 100644 src/features/feedback/components/TeamFeedbackList.tsx delete mode 100644 src/features/feedback/components/TeamFeedbackListSkeleton.tsx delete mode 100644 src/features/feedback/components/TeamFeedbackRow.tsx delete mode 100644 src/features/feedback/components/index.ts create mode 100644 src/features/home/components/EmptyPostList.tsx create mode 100644 src/features/home/components/NewPostBanner.tsx create mode 100644 src/features/home/components/PostList.tsx create mode 100644 src/features/home/components/index.ts create mode 100644 src/features/me/api/index.ts rename src/features/{profile/api/useUser.ts => me/api/useMe.ts} (66%) create mode 100644 src/features/posts/api/index.ts create mode 100644 src/features/posts/api/useUploadImagesMutation.ts create mode 100644 src/features/posts/components/AddCommentModal/AddCommentModal.tsx create mode 100644 src/features/posts/components/AddCommentModal/index.ts create mode 100644 src/features/posts/components/ComposePost.tsx create mode 100644 src/features/posts/components/DeletePostModal.tsx create mode 100644 src/features/posts/components/NewPostModal/NewPostModal.stories.tsx create mode 100644 src/features/posts/components/NewPostModal/NewPostModal.tsx create mode 100644 src/features/posts/components/NewPostModal/NewPostModalButton.tsx create mode 100644 src/features/posts/components/NewPostModal/index.ts create mode 100644 src/features/posts/components/Post/Post.tsx create mode 100644 src/features/posts/components/Post/PostImages.tsx create mode 100644 src/features/posts/components/Post/PostView.tsx create mode 100644 src/features/posts/components/Post/SkeletonPost.tsx create mode 100644 src/features/posts/components/Post/index.ts create mode 100644 src/features/posts/components/PostActions/AddCommentAction.tsx create mode 100644 src/features/posts/components/PostActions/CopyAction.tsx create mode 100644 src/features/posts/components/PostActions/DeletePostAction.tsx create mode 100644 src/features/posts/components/PostActions/PostActions.tsx create mode 100644 src/features/posts/components/PostActions/ReplyToPostAction.tsx create mode 100644 src/features/posts/components/PostActions/index.ts create mode 100644 src/features/posts/components/index.ts create mode 100644 src/features/posts/schemas/clientAddPostSchema.ts delete mode 100644 src/features/profile/assets/profile-aunty.svg create mode 100644 src/features/profile/components/EmptyPostList.tsx delete mode 100644 src/features/profile/components/ProfileAuntySvgr.tsx create mode 100644 src/features/profile/components/ProfileDescription.tsx create mode 100644 src/features/profile/components/ProfileTabs.tsx create mode 100644 src/features/profile/components/index.ts rename src/features/{profile => settings}/api/index.ts (61%) rename src/features/{profile => settings}/api/useUploadAvatarMutation.ts (71%) rename src/features/{profile => settings}/components/AvatarUpload.tsx (74%) create mode 100644 src/features/settings/components/index.ts create mode 100644 src/features/thread/components/SkeletonThreadPost.tsx create mode 100644 src/features/thread/components/SkeletonThreadPostList.tsx create mode 100644 src/features/thread/components/SkeletonThreadView.tsx create mode 100644 src/features/thread/components/ThreadPost.tsx create mode 100644 src/features/thread/components/ThreadView.tsx create mode 100644 src/features/thread/components/index.ts create mode 100644 src/lib/dates.ts create mode 100644 src/lib/routes.ts delete mode 100644 src/lib/types/trpc.ts delete mode 100644 src/lib/withSession.ts delete mode 100644 src/pages/dashboard.tsx delete mode 100644 src/pages/feedback/[id].tsx delete mode 100644 src/pages/feedback/new.tsx create mode 100644 src/pages/home.tsx delete mode 100644 src/pages/profile.tsx create mode 100644 src/pages/profile/[username]/index.tsx create mode 100644 src/pages/profile/[username]/liked.tsx create mode 100644 src/pages/profile/[username]/replies.tsx create mode 100644 src/pages/settings/profile.tsx create mode 100644 src/pages/thread/[postId].tsx create mode 100644 src/schemas/presign.ts rename src/server/modules/{user/user.select.ts => me/me.select.ts} (68%) create mode 100644 src/server/modules/me/me.service.ts delete mode 100644 src/server/modules/post/post.util.ts create mode 100644 src/server/modules/profile/profile.router.ts create mode 100644 src/server/modules/profile/profile.select.ts create mode 100644 src/stories/Page/HomePage.stories.tsx create mode 100644 src/templates/layouts/ProfileLayout.tsx create mode 100644 src/templates/layouts/ThreadLayout.tsx create mode 100644 src/templates/layouts/nestLayout.ts delete mode 100644 src/theme/components/Accordion.ts create mode 100644 src/theme/components/Modal.ts delete mode 100644 src/theme/components/Sidebar.ts create mode 100644 src/theme/layerStyles.ts create mode 100644 src/utils/image.ts create mode 100644 src/utils/registerWithDebounce.ts create mode 100644 tests/msw/handlers/me.ts create mode 100644 tests/msw/handlers/post.ts rename {src/stories/utils => tests/msw}/mockTrpc.ts (89%) diff --git a/.env.example b/.env.example index 476237ce..b0211256 100644 --- a/.env.example +++ b/.env.example @@ -36,6 +36,8 @@ SENDGRID_FROM_ADDRESS= NEXT_PUBLIC_ENABLE_STORAGE= R2_ACCOUNT_ID= R2_BUCKET_NAME= +R2_AVATARS_DIRECTORY=avatars +R2_IMAGES_DIRECTORY=images R2_ACCESS_KEY_ID= R2_SECRET_ACCESS_KEY= R2_PUBLIC_HOSTNAME= diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 87833af0..1e7de912 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,19 +1,26 @@ import '@fontsource/ibm-plex-mono' import 'inter-ui/inter.css' -import type { Preview, Decorator } from '@storybook/react' import { withThemeFromJSXProvider } from '@storybook/addon-styling' +import type { Args, Decorator, Preview } from '@storybook/react' +import mockdate from 'mockdate' +import { ThemeProvider } from '@opengovsg/design-system-react' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { httpBatchLink } from '@trpc/client' -import { PropsWithChildren, useState } from 'react' import { createTRPCReact } from '@trpc/react-query' -import { AppRouter } from '~/server/modules/_app' +import { useMemo, useState } from 'react' import superjson from 'superjson' -import { ThemeProvider } from '@opengovsg/design-system-react' +import { AppRouter } from '~/server/modules/_app' import { theme } from '~/theme' +import { Box, Skeleton } from '@chakra-ui/react' import { initialize, mswDecorator } from 'msw-storybook-addon' +import ErrorBoundary from '~/components/ErrorBoundary' +import Suspense from '~/components/Suspense' +import { format } from 'date-fns' +import { FeatureContext } from '~/components/AppProviders' +import { z } from 'zod' // Initialize MSW initialize({ @@ -22,7 +29,7 @@ initialize({ const trpc = createTRPCReact() -const StorybookTrpcProvider = ({ children }: PropsWithChildren) => { +const SetupDecorator: Decorator = (page) => { const [queryClient] = useState( new QueryClient({ defaultOptions: { @@ -41,9 +48,66 @@ const StorybookTrpcProvider = ({ children }: PropsWithChildren) => { }) ) return ( - - {children} - + + }> + + + {page()} + + + + + ) +} + +export const mockFeatureFlagsDecorator: Decorator = ( + storyFn, + { parameters } +) => { + const featureSchema = z + .object({ + storage: z.boolean().default(false), + sgid: z.boolean().default(false), + }) + .default({}) + const features = useMemo(() => { + return featureSchema.parse(parameters.features) + }, []) + + return ( + + {storyFn()} + + ) +} + +export const mockDateDecorator: Decorator = (storyFn, { parameters }) => { + mockdate.reset() + + if (!parameters.mockdate) { + return storyFn() + } + + mockdate.set(parameters.mockdate) + + const mockedDate = format(parameters.mockdate, 'dd-mm-yyyy HH:mma') + + return ( + + + Mocking date: {mockedDate} + + {storyFn()} + ) } @@ -55,11 +119,9 @@ const decorators: Decorator[] = [ }, Provider: ThemeProvider, }), - (Story) => ( - - - - ), + mockDateDecorator, + mockFeatureFlagsDecorator, + SetupDecorator, ] const preview: Preview = { diff --git a/package-lock.json b/package-lock.json index e0dd63b1..3713fe45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,16 +15,17 @@ "@hookform/resolvers": "^3.1.1", "@opengovsg/design-system-react": "^1.2.0", "@opengovsg/sgid-client": "^2.0.0", + "@paralleldrive/cuid2": "^2.2.1", "@prisma/client": "4.15.0", "@sendgrid/mail": "^7.7.0", "@storybook/jest": "^0.1.0", "@tanstack/react-query": "^4.29.1", "@tanstack/react-query-devtools": "^4.32.0", - "@tiptap/extension-link": "^2.0.0-beta.220", - "@tiptap/extension-placeholder": "^2.0.3", - "@tiptap/pm": "^2.0.0-beta.220", - "@tiptap/react": "^2.0.0-beta.220", - "@tiptap/starter-kit": "^2.0.0-beta.220", + "@tiptap/extension-link": "2.0.3", + "@tiptap/extension-placeholder": "2.0.3", + "@tiptap/pm": "2.0.3", + "@tiptap/react": "2.0.3", + "@tiptap/starter-kit": "2.0.3", "@trpc/client": "^10.31.0", "@trpc/next": "^10.31.0", "@trpc/react-query": "^10.31.0", @@ -51,14 +52,14 @@ "devDependencies": { "@chakra-ui/cli": "^2.4.1", "@playwright/test": "^1.33.0", - "@storybook/addon-essentials": "^7.0.18", - "@storybook/addon-interactions": "^7.0.18", - "@storybook/addon-links": "^7.0.18", - "@storybook/addon-styling": "^1.0.8", - "@storybook/blocks": "^7.0.18", - "@storybook/nextjs": "^7.0.18", - "@storybook/react": "^7.0.18", - "@storybook/testing-library": "^0.0.14-next.2", + "@storybook/addon-essentials": "^7.0.24", + "@storybook/addon-interactions": "^7.0.24", + "@storybook/addon-links": "^7.0.24", + "@storybook/addon-styling": "^1.3.1", + "@storybook/blocks": "^7.0.24", + "@storybook/nextjs": "^7.0.24", + "@storybook/react": "^7.0.24", + "@storybook/testing-library": "^0.2.0", "@types/eslint": "^8.40.0", "@types/node": "^18.15.11", "@types/react": "^18.0.34", @@ -73,6 +74,7 @@ "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-storybook": "^0.6.12", + "mockdate": "^3.0.5", "msw": "^1.2.2", "msw-storybook-addon": "^1.8.0", "msw-trpc": "^1.3.3", @@ -80,7 +82,7 @@ "prettier": "^2.8.7", "prisma": "4.15.0", "start-server-and-test": "^2.0.0", - "storybook": "^7.0.18", + "storybook": "^7.0.24", "tsx": "^3.12.7", "typescript": "^4.8.3", "vite": "^4.1.5", @@ -1071,12 +1073,12 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1268,11 +1270,11 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dependencies": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1310,9 +1312,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz", - "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1390,25 +1392,25 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1888,12 +1890,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz", - "integrity": "sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz", + "integrity": "sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1957,12 +1959,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", - "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2360,13 +2362,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz", - "integrity": "sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz", + "integrity": "sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-flow": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-flow": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2732,12 +2734,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", + "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2747,16 +2749,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.3.tgz", - "integrity": "sha512-JEulRWG2f04a7L8VWaOngWiK6p+JOSpB+DAtwfJgOaej1qdbNxqtK7MwTBHjUA10NeFcszlFNqCdbRcirzh2uQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", + "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/plugin-syntax-jsx": "^7.21.4", - "@babel/types": "^7.22.3" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2766,12 +2768,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", "dev": true, "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.18.6" + "@babel/plugin-transform-react-jsx": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -2781,13 +2783,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz", + "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -3117,14 +3119,14 @@ } }, "node_modules/@babel/preset-flow": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.21.4.tgz", - "integrity": "sha512-F24cSq4DIBmhq4OzK3dE63NHagb27OPE3eWR+HLekt4Z3Y5MzIIUGF3LlLgV0gN8vzbDViSY7HnrReNVCJXTeA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.22.5.tgz", + "integrity": "sha512-ta2qZ+LSiGCrP5pgcGt8xMnnkXQrq8Sa4Ulhy06BOlF5QbLw9q5hIx7bn5MrsvyTGAfh6kTOo07Q+Pfld/8Y5Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-transform-flow-strip-types": "^7.21.0" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-transform-flow-strip-types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -3150,17 +3152,17 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.3.tgz", - "integrity": "sha512-lxDz1mnZ9polqClBCVBjIVUypoB4qV3/tZUDb/IlYbW1kiiLaXaX+bInbRjl+lNQ/iUZraQ3+S8daEmoELMWug==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.5.tgz", + "integrity": "sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.22.3", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-transform-react-display-name": "^7.22.5", + "@babel/plugin-transform-react-jsx": "^7.22.5", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -3189,9 +3191,9 @@ } }, "node_modules/@babel/register": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.21.0.tgz", - "integrity": "sha512-9nKsPmYDi5DidAqJaQooxIhsLJiNMkGr8ypQ8Uic7cIox7UCDsM7HuUGxdGT7mSDTYbqzIdsOWzfBton/YJrMw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.5.tgz", + "integrity": "sha512-vV6pm/4CijSQ8Y47RH5SopXzursN35RQINfGJkmOlcpAtGuf94miFvIPhCKGQN7WGIcsgG1BHEX2KVdTYwTwUQ==", "dev": true, "dependencies": { "clone-deep": "^4.0.1", @@ -3387,12 +3389,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.4.tgz", - "integrity": "sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -5736,6 +5738,17 @@ "node": ">= 10" } }, + "node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -5838,6 +5851,14 @@ "openid-client": "5.4.0" } }, + "node_modules/@paralleldrive/cuid2": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.1.tgz", + "integrity": "sha512-GJhHYlMhyT2gWemDL7BGMWfTNhspJKkikLKh9wAy3z4GTTINvTYALkUd+eGQK7aLeVkVzPuSA0VCT3H5eEWbbw==", + "dependencies": { + "@noble/hashes": "^1.1.5" + } + }, "node_modules/@peculiar/asn1-schema": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz", @@ -6728,19 +6749,19 @@ } }, "node_modules/@storybook/addon-actions": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.0.18.tgz", - "integrity": "sha512-3M5AU/ZD79YP88vKlFezIJbIoG/II7wCixUBTmwiC3BeQZDuVsqPNl8eiP6MGT70xwyx7a993lSM5f5N5W93vg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.0.24.tgz", + "integrity": "sha512-sIPY6uH8I26KBWUb5fMYBB9xCKB02oSM8gIHzqPZ0DnW8zl+p6+dX3tAdX+XQvb9YOLJihxZ1GF1tOxFduc3Pw==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "dequal": "^2.0.2", "lodash": "^4.17.21", "polished": "^4.2.2", @@ -6777,19 +6798,19 @@ } }, "node_modules/@storybook/addon-backgrounds": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.18.tgz", - "integrity": "sha512-cPQy1Ot7Urf4hQz+xnF1YKrqSyR0DRwozBmF+sGzceACWmueFl0CifYZC8RSmaiIyVh0RyWPxZ9F/eT67NX2lA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.24.tgz", + "integrity": "sha512-vThKkrSj+J7matGowxIJ4eV+kAF8iUHGQjlaW0J7vhzmVkNnxBvNn/DGOWWQLAJPCTmLVelLaBZEWcMNoKJiVA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "memoizerific": "^1.11.3", "ts-dedent": "^2.0.0" }, @@ -6811,20 +6832,20 @@ } }, "node_modules/@storybook/addon-controls": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.0.18.tgz", - "integrity": "sha512-mD6DE52CCMKugXk2Uab0QxwgfE76kFJroxASmnePnXUNWfP9EZJpJXYE3cyyBbmZuxa46VHDGGEGXQWRl4+Eog==", - "dev": true, - "dependencies": { - "@storybook/blocks": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/manager-api": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.0.24.tgz", + "integrity": "sha512-x05Ng4wyBRkrupgSkBHKZSGPyUbvIDGiBseA/AjA/BNAMUMWy3t8ll9f7tlKzyDPaUeBSv8peP21r/Ry26Eqhw==", + "dev": true, + "dependencies": { + "@storybook/blocks": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/manager-api": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "lodash": "^4.17.21", "ts-dedent": "^2.0.0" }, @@ -6846,28 +6867,28 @@ } }, "node_modules/@storybook/addon-docs": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.0.18.tgz", - "integrity": "sha512-oq+ZN5809gIRdTZQIpeK1F8BJtL1/VWo9rWvl6ymVOL/Xzdgd7AOfKf9Y99X35RcxAGysRIHLGJjF4bgLoY1Aw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.0.24.tgz", + "integrity": "sha512-O5S+E6+8c/EHEQc5WcrNQ8dOVg9Q2ONIOYxlbSAcfMUA/d+tRR9xXTZog7nv1tj4U0G29+Vr4pKgsGh3Ya5qcw==", "dev": true, "dependencies": { "@babel/core": "^7.20.2", "@babel/plugin-transform-react-jsx": "^7.19.0", "@jest/transform": "^29.3.1", "@mdx-js/react": "^2.1.5", - "@storybook/blocks": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/csf-plugin": "7.0.18", - "@storybook/csf-tools": "7.0.18", + "@storybook/blocks": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/csf-plugin": "7.0.24", + "@storybook/csf-tools": "7.0.24", "@storybook/global": "^5.0.0", "@storybook/mdx2-csf": "^1.0.0", - "@storybook/node-logger": "7.0.18", - "@storybook/postinstall": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/react-dom-shim": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/node-logger": "7.0.24", + "@storybook/postinstall": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/react-dom-shim": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "fs-extra": "^11.1.0", "remark-external-links": "^8.0.0", "remark-slug": "^6.0.0", @@ -6883,24 +6904,24 @@ } }, "node_modules/@storybook/addon-essentials": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.0.18.tgz", - "integrity": "sha512-0XXu7xhtRefA1WxxorKk6BWeeB+7gQ+r2+bG1zQEfBgDYPR06YbPw4H79IZ8JiR97aJRsZBK5UUhOZMDrc5zcQ==", - "dev": true, - "dependencies": { - "@storybook/addon-actions": "7.0.18", - "@storybook/addon-backgrounds": "7.0.18", - "@storybook/addon-controls": "7.0.18", - "@storybook/addon-docs": "7.0.18", - "@storybook/addon-highlight": "7.0.18", - "@storybook/addon-measure": "7.0.18", - "@storybook/addon-outline": "7.0.18", - "@storybook/addon-toolbars": "7.0.18", - "@storybook/addon-viewport": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/manager-api": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preview-api": "7.0.18", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.0.24.tgz", + "integrity": "sha512-OL27TNQYUJv/FprFCU7Q9RQYrgGdM+4SH+XmsQCcuQuGa67s6/eRKyERwOdy4Pli3Payo76+Vz1DAeJZJ0F8oA==", + "dev": true, + "dependencies": { + "@storybook/addon-actions": "7.0.24", + "@storybook/addon-backgrounds": "7.0.24", + "@storybook/addon-controls": "7.0.24", + "@storybook/addon-docs": "7.0.24", + "@storybook/addon-highlight": "7.0.24", + "@storybook/addon-measure": "7.0.24", + "@storybook/addon-outline": "7.0.24", + "@storybook/addon-toolbars": "7.0.24", + "@storybook/addon-viewport": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/manager-api": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preview-api": "7.0.24", "ts-dedent": "^2.0.0" }, "funding": { @@ -6913,14 +6934,14 @@ } }, "node_modules/@storybook/addon-highlight": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.0.18.tgz", - "integrity": "sha512-a3nfUhbu6whoDclIZSV/fzLj132tNNjV05ENTpuN3JpLoMd3+obDUWzeQUs9TetK4RBRN3ewM7sIMEI4oBpgmg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.0.24.tgz", + "integrity": "sha512-IoCJHiX5Ai+7S08isxt7BH4baNF2RsjuGUA/iMoJtto/rMc5u0xftVeIjh6oVqV3tjckowXpezI3oStnrLWuRw==", "dev": true, "dependencies": { - "@storybook/core-events": "7.0.18", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.0.18" + "@storybook/preview-api": "7.0.24" }, "funding": { "type": "opencollective", @@ -6928,21 +6949,21 @@ } }, "node_modules/@storybook/addon-interactions": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-7.0.18.tgz", - "integrity": "sha512-V3OD5lSj6Te6Kzc//2k2S79dLPk6Zu1pAbqWAN4RrdXyKj6YCiZ666GmVdiaG+24Qp5UuMeAkd1D05osJlOteA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-7.0.24.tgz", + "integrity": "sha512-N0BWt13T8lA+L0pAcC3xwhVMWQhrwHaXFqC6aJ1OxJb9pkA85S6Pk7VJRATDpmu9C3JO0OU3EOBB2YVVwcmD0A==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "7.0.18", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/instrumenter": "7.0.24", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "jest-mock": "^27.0.6", "polished": "^4.2.2", "ts-dedent": "^2.2.0" @@ -7003,19 +7024,19 @@ } }, "node_modules/@storybook/addon-links": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.0.18.tgz", - "integrity": "sha512-xEwflt7bp9FRoZVeqPGb6d3s2Gh+/jaSmnyIxMxrBy2oovKIqu9ptolqz1AhjFOXfaLs9c2RAmJUuFZJtETLxA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.0.24.tgz", + "integrity": "sha512-/Hse4IC3ov2dVzpZiIpf2QNFczi4pxdjZdmR0FhKeRlFldEJyywgT8a/gzeEahXO9v1jsEDa7j7f8JQcu/+04w==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/router": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/router": "7.0.24", + "@storybook/types": "7.0.24", "prop-types": "^15.7.2", "ts-dedent": "^2.0.0" }, @@ -7037,18 +7058,18 @@ } }, "node_modules/@storybook/addon-measure": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.0.18.tgz", - "integrity": "sha512-iu8vQpGOA+CFYbWR6QNshj20o33OQ/xcTbp5P4U6xGYDUliUBbwJ2KLxcKlmIeBanBrBdz0jPFtHwY4dM1ZdKw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.0.24.tgz", + "integrity": "sha512-4VNs4rjdz+YFiJCz9DfCmBJwFuoa3pLhcEsAAdT3B+Hrkae+hvLtnQWIvAMsOlSWdl4tiuEWssDf4cjCEne87w==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/types": "7.0.18" + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/types": "7.0.24" }, "funding": { "type": "opencollective", @@ -7068,18 +7089,18 @@ } }, "node_modules/@storybook/addon-outline": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.0.18.tgz", - "integrity": "sha512-3vNWO7ezo6GIvidbz8JxFrKtfVEoTQN7tnZx+wpqmCF8ihBORewkpeMUnvgb9ZKjD0X7gE8eQvvG8KKWcyHDBQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.0.24.tgz", + "integrity": "sha512-YwSfs8bsmh7mEF+rlmL7zBsebWA5e/Rsf09vVqt6/k3fpopgBrq44zQlMwo1dCWV/0YhhXQF21OGzeJ1dSb8fA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/types": "7.0.24", "ts-dedent": "^2.0.0" }, "funding": { @@ -7100,22 +7121,27 @@ } }, "node_modules/@storybook/addon-styling": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@storybook/addon-styling/-/addon-styling-1.0.8.tgz", - "integrity": "sha512-Ubi75gHNFO60Sjti2n/i3f0utERNOYcpsRkWHdzV+C26kUemLG+2riKHUt8zVbNskyJxA0EZxh84HYItRe4coA==", - "dev": true, - "dependencies": { - "@storybook/api": "^7.0.2", - "@storybook/components": "^7.0.2", - "@storybook/core-events": "^7.0.2", - "@storybook/manager-api": "^7.0.2", - "@storybook/node-logger": "^7.0.7", - "@storybook/preview-api": "^7.0.2", - "@storybook/theming": "^7.0.2", - "@storybook/types": "^7.0.2", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-styling/-/addon-styling-1.3.1.tgz", + "integrity": "sha512-5ofDihi4LxOGXFFIU5D7eGLKtK8wzNH19h58QFa1w8kCrZmARYYjiZXVB0bJrMQxU9TMy+B6aOg04vV+IGX2OA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.5", + "@storybook/api": "^7.0.12", + "@storybook/components": "^7.0.12", + "@storybook/core-common": "^7.0.12", + "@storybook/core-events": "^7.0.12", + "@storybook/csf-tools": "^7.0.12", + "@storybook/manager-api": "^7.0.12", + "@storybook/node-logger": "^7.0.12", + "@storybook/preview-api": "^7.0.12", + "@storybook/theming": "^7.0.12", + "@storybook/types": "^7.0.12", "css-loader": "^6.7.3", "less-loader": "^11.1.0", "postcss-loader": "^7.2.4", + "recast": "^0.23.2", "resolve-url-loader": "^5.0.0", "sass-loader": "^13.2.2", "style-loader": "^3.3.2" @@ -7172,16 +7198,16 @@ } }, "node_modules/@storybook/addon-toolbars": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.0.18.tgz", - "integrity": "sha512-mwhq962o0WloHAeFjJ6BXO2nzdTo5KE2fqawPpqcB2lwXP6tvaA2tDWwgntjPCHejqWTS+ZTdO4/1xrMhWYt/g==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.0.24.tgz", + "integrity": "sha512-+nDVahs2kAojzF6RbChowJmN0z7cyD/5BGMEhBemhBWSuMVnQLLEgtQi/kOY5fUxq3z1BkqcE4LV98u5CIKgKg==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24" }, "funding": { "type": "opencollective", @@ -7201,18 +7227,18 @@ } }, "node_modules/@storybook/addon-viewport": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.0.18.tgz", - "integrity": "sha512-aVVLBsWXfGDX3z1pc93LWWdG5RUoJbGL/JJPMZGwXdwWpP8V3OBl8D8bgPymyg+MgwhSRZZDDGgnJaVGGwZ6bQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.0.24.tgz", + "integrity": "sha512-bc3TR+feemGxVP1QQT6OsFSldHjLToJNuQAGd5EEBsDFhcMTsmitiGVoxIylqIhfioL9zauLIsk5eLZ/TYxuXQ==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", "memoizerific": "^1.11.3", "prop-types": "^15.7.2" }, @@ -7234,14 +7260,14 @@ } }, "node_modules/@storybook/addons": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-7.0.18.tgz", - "integrity": "sha512-+j9ItxWoVzarbllaV4WRaJpDM3P2aC5O6F3cPn4YkG/unb6HOs11WLAqFbzZnLYZNAFvWS8PYEAtqs1BxG66YQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-7.0.24.tgz", + "integrity": "sha512-e15hORnOD0ugvOVOTyZyLJhbDTWa4G1OHVUlboazy8O4TSvAXNBdLV1wOdY5RGoGD6Z5A4iR/gZXM0qc6Fh9xg==", "dev": true, "dependencies": { - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/types": "7.0.18" + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/types": "7.0.24" }, "funding": { "type": "opencollective", @@ -7253,13 +7279,13 @@ } }, "node_modules/@storybook/api": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-7.0.18.tgz", - "integrity": "sha512-gikVJBR2z7LdepljmbvbsrYgywQm3jNEEEmjG0OwYDeYNjWPuoQSffT+LoyouaaCK90d1osJLl3062OkwlIG8g==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-7.0.24.tgz", + "integrity": "sha512-rjWZgBbt43Ma5Vg2RwK9FtiF9ZkLRT+vOfDFtRL1PQkOIUlYlm33dOdPTh+HrW5QMO9cj/cchqmzU2AtgEZCyw==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/manager-api": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/manager-api": "7.0.24" }, "funding": { "type": "opencollective", @@ -7279,22 +7305,22 @@ } }, "node_modules/@storybook/blocks": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.0.18.tgz", - "integrity": "sha512-HLsuzmUdVIeFXEP5v5vyjnEePRNYjzltwTjCKQhHAlt8/aQZmREiIMOfoMoAa1Rd+On8Ib2DUd2cN10VS18H8A==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.0.24.tgz", + "integrity": "sha512-76pe4QC3WZBVxBt/RomGubW5xzbh4uF7LVn1Vonfujf4GaHgIDzu7KtLIjgM3NmDJCsp3PNfbgA1EKzWrPQz2A==", "dev": true, "dependencies": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", - "@storybook/docs-tools": "7.0.18", + "@storybook/docs-tools": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "@types/lodash": "^4.14.167", "color-convert": "^2.0.1", "dequal": "^2.0.2", @@ -7317,15 +7343,15 @@ } }, "node_modules/@storybook/builder-manager": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.0.18.tgz", - "integrity": "sha512-yFMm3xuYkyg2hS1uz3CkvyvLzK7qJsDPVEh7lew8GiJK1Xx8cc+FnAOlRTjWNxvhfiT296wAMCTPWv7LeoSgqQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.0.24.tgz", + "integrity": "sha512-qSehfB1yS1ch/XSUdqNaTXitboNry4aKASte+kFhM5wSJcAgGBeB5akz8pc+JiRPWozqyceYkIdTG/KcRDeojg==", "dev": true, "dependencies": { "@fal-works/esbuild-plugin-global-externals": "^2.1.2", - "@storybook/core-common": "7.0.18", - "@storybook/manager": "7.0.18", - "@storybook/node-logger": "7.0.18", + "@storybook/core-common": "7.0.24", + "@storybook/manager": "7.0.24", + "@storybook/node-logger": "7.0.24", "@types/ejs": "^3.1.1", "@types/find-cache-dir": "^3.2.1", "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", @@ -7345,31 +7371,31 @@ } }, "node_modules/@storybook/builder-webpack5": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-7.0.18.tgz", - "integrity": "sha512-ciDOHrnChHWjikQwsM+xGz70PGfWurcezCyRPPRY0zimyHWtlug6V1Q9dJAdEAFsxqFSZA/qg7gEcZyqdlTMaA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-7.0.24.tgz", + "integrity": "sha512-gA4otfsq9yTRT2IdYKkyqUdy+60a09CRDUtM1JB8a1eLmyL4az02qZv/l6D9Ccj/w5JNcJndtJX+3thOowOWOQ==", "dev": true, "dependencies": { "@babel/core": "^7.12.10", - "@storybook/addons": "7.0.18", - "@storybook/api": "7.0.18", - "@storybook/channel-postmessage": "7.0.18", - "@storybook/channel-websocket": "7.0.18", - "@storybook/channels": "7.0.18", - "@storybook/client-api": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/core-events": "7.0.18", - "@storybook/core-webpack": "7.0.18", + "@storybook/addons": "7.0.24", + "@storybook/api": "7.0.24", + "@storybook/channel-postmessage": "7.0.24", + "@storybook/channel-websocket": "7.0.24", + "@storybook/channels": "7.0.24", + "@storybook/client-api": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/core-events": "7.0.24", + "@storybook/core-webpack": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preview": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/router": "7.0.18", - "@storybook/store": "7.0.18", - "@storybook/theming": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preview": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/router": "7.0.24", + "@storybook/store": "7.0.24", + "@storybook/theming": "7.0.24", "@types/node": "^16.0.0", "@types/semver": "^7.3.4", "babel-loader": "^9.0.0", @@ -7409,19 +7435,19 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true }, "node_modules/@storybook/channel-postmessage": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-7.0.18.tgz", - "integrity": "sha512-rpwBH5ANdPnugS6+7xG9qHSoS+aPSEnBxDKsONWFubfMTTXQuFkf/793rBbxGkoINdqh8kSdKOM2rIty6e9cmQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-7.0.24.tgz", + "integrity": "sha512-QLtLXjEeTEwBN/7pB888mBaykmRU9Jy2BitvZuLJWyHHygTYm3vYZOaGR37DT+q/6Ob5GaZ0tURZmCSNDe8IIA==", "dependencies": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.0.3" @@ -7432,13 +7458,13 @@ } }, "node_modules/@storybook/channel-websocket": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-7.0.18.tgz", - "integrity": "sha512-QYsZIfe23NN4i+oIdPKHaYBehk3a/HYk57a+M2oR3Frmv8IOqc/e31uH+xx5NxnjHrTJj7Y80ZJw6EKB682S6w==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-7.0.24.tgz", + "integrity": "sha512-GKSlWx5FgMQM0TKRCSGNTxLh0YU7xmg7m6FH8b/mvhH0Uido487qcJap2Ma/WOLe8aRiZo9jJpfcbUsKBWhuMg==", "dev": true, "dependencies": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", "@storybook/global": "^5.0.0", "telejson": "^7.0.3" }, @@ -7448,32 +7474,31 @@ } }, "node_modules/@storybook/channels": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.0.18.tgz", - "integrity": "sha512-rkA7ea0M3+dWS+71iHJdiZ5R2QuIdiVg0CgyLJHDagc1qej7pEVNhMWtppeq+X5Pwp9nkz8ZTQ7aCjTf6th0/A==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.0.24.tgz", + "integrity": "sha512-NZVLwMhtzy6cZrNRjshFvMAD9mQTmJDNwhohodSkM/YFCDVFhmxQk9tgizVGh9MwY3CYGJ1SI96RUejGosb49Q==", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" } }, "node_modules/@storybook/cli": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.0.18.tgz", - "integrity": "sha512-9n4J4thiCUsGSXiRc6ZysqYUaCMCrpu0/qgC+5ngfFRuMmZgUV0y5+0fmaOhT2XjsonTTgucizO82i7+ottCVg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.0.24.tgz", + "integrity": "sha512-TmHPJrcqUMAGpPKqw0PHI82m+Tyh6J8LgWjyZENpOGJlQH6SJ5caA/ho9R3pqVuMRRcnGgWt0xq1YJtDlYBN9g==", "dev": true, "dependencies": { "@babel/core": "^7.20.2", "@babel/preset-env": "^7.20.2", "@ndelangen/get-tarball": "^3.0.7", - "@storybook/codemod": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/core-server": "7.0.18", - "@storybook/csf-tools": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/telemetry": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/codemod": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/core-server": "7.0.24", + "@storybook/csf-tools": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/telemetry": "7.0.24", + "@storybook/types": "7.0.24", "@types/semver": "^7.3.4", - "boxen": "^5.1.2", "chalk": "^4.1.0", "commander": "^6.2.1", "cross-spawn": "^7.0.3", @@ -7521,13 +7546,13 @@ } }, "node_modules/@storybook/client-api": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.0.18.tgz", - "integrity": "sha512-EdgE4om6nXZf/sDZcVMGMeKv4BPX+P3EKUfMHCHjlrbbeL0eeY8Ynf+u/wYrIYZPUodS8TEV5XchHVB8F7rLBQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.0.24.tgz", + "integrity": "sha512-D9brib29aET1peRq6Nu7iBFgE+9W7ia3KCua5/AS980RFnXgGPE9x07knTbaAOuiHxHFrmQpdFF9BvVms1GS4A==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/preview-api": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/preview-api": "7.0.24" }, "funding": { "type": "opencollective", @@ -7535,9 +7560,9 @@ } }, "node_modules/@storybook/client-logger": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.0.18.tgz", - "integrity": "sha512-uKgFdVedYoRDZBVrE1IBdWNHDFln1IxWEeI+7ZiNSQwREG9swHpU5Fa8DceclM/oLjJRuzG1jFzv+XZY8894+Q==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.0.24.tgz", + "integrity": "sha512-4zRTb+QQ1hWaRqad/UufZNRfi2d/cf5a40My72Ct97VwjhJFE6aQ3K+hl1Xt6hh8dncDL2JK3cgziw6ElqjT0w==", "dependencies": { "@storybook/global": "^5.0.0" }, @@ -7547,18 +7572,18 @@ } }, "node_modules/@storybook/codemod": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.0.18.tgz", - "integrity": "sha512-+9XFns29e8FpPLsqA8ZCQ3mNnIIKD3QnqGYkbkCVKi/G1fomvVQsIfsnkrYv5SobTbz29B4aNWxAaeSnO7/OGg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.0.24.tgz", + "integrity": "sha512-PukV4GRPIISuVxpMMlTilwlGXdZ7E+JZWHNVb1tTwntmxMNcby8UxyWSHjbOpA2fxXGeUCjgCpcfTymJ+hxoYw==", "dev": true, "dependencies": { "@babel/core": "~7.21.0", "@babel/preset-env": "~7.21.0", "@babel/types": "~7.21.2", "@storybook/csf": "^0.1.0", - "@storybook/csf-tools": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/csf-tools": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/types": "7.0.24", "cross-spawn": "^7.0.3", "globby": "^11.0.2", "jscodeshift": "^0.14.0", @@ -7783,16 +7808,16 @@ } }, "node_modules/@storybook/components": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.0.18.tgz", - "integrity": "sha512-Jn1CbF9UAKt8BVaZtuhmthpcZ02VMaCFXR0ISfDXCpiMKnylmpP0+WfXcoKLzz6yS+EW8EW5S9+Qq8xgQY8H7A==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.0.24.tgz", + "integrity": "sha512-Pu7zGurCyWyiuFl2Pb5gybHA0f4blmHuVqccbMqnUw4Ew80BRu8AqfhNqN2hNdxFCx0mmy0baRGVftx76rNZ0w==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", + "@storybook/client-logger": "7.0.24", "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "memoizerific": "^1.11.3", "use-resize-observer": "^9.1.0", "util-deprecate": "^1.0.2" @@ -7807,13 +7832,13 @@ } }, "node_modules/@storybook/core-client": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-7.0.18.tgz", - "integrity": "sha512-ueExRZx6fd9LRssgdhDJ0bL4Ir2RrbXzJz/kjIT2KgYY3l7jkhe0dpT3bOgGKjQt0f7XMFU24t/r7aDLGMB+2Q==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-7.0.24.tgz", + "integrity": "sha512-uToMHbi5EnOk+8Z941j0hrRE1h9u/QWqCmqS2FBIWrBOeREwy0AAib1/hqihzhO7OzekY5mtLTANiCpIpLHAHQ==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/preview-api": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/preview-api": "7.0.24" }, "funding": { "type": "opencollective", @@ -7821,25 +7846,27 @@ } }, "node_modules/@storybook/core-common": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.0.18.tgz", - "integrity": "sha512-HZAB1NIK/Yv0x9poyzqYcue2tx39+MAF1mbHgGy+JJZRerO2fRShgo8f8VPH9ChbFCoJ7isL5wNhgGdg9kp2kA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.0.24.tgz", + "integrity": "sha512-FHjL2dpwDHnicLTePkiZMfO5eFxJxpTP2xmGWFQnWFTyEgh+ipcWnLVoYYXiKcc6EzKED0yebk8rAIalbzpICg==", "dev": true, "dependencies": { - "@storybook/node-logger": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/node-logger": "7.0.24", + "@storybook/types": "7.0.24", "@types/node": "^16.0.0", + "@types/node-fetch": "^2.6.4", "@types/pretty-hrtime": "^1.0.0", "chalk": "^4.1.0", "esbuild": "^0.17.0", "esbuild-register": "^3.4.0", - "file-system-cache": "^2.0.0", + "file-system-cache": "2.3.0", "find-up": "^5.0.0", "fs-extra": "^11.1.0", "glob": "^8.1.0", "glob-promise": "^6.0.2", "handlebars": "^4.7.7", "lazy-universal-dotenv": "^4.0.0", + "node-fetch": "^2.0.0", "picomatch": "^2.3.0", "pkg-dir": "^5.0.0", "pretty-hrtime": "^1.0.3", @@ -7938,41 +7965,40 @@ } }, "node_modules/@storybook/core-events": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.0.18.tgz", - "integrity": "sha512-7gxHBQDezdKOeq/u1LL80Bwjfcwsv7XOS3yWQElcgqp+gLaYB6OwwgtkCB2yV6a6l4nep9IdPWE8G3TxIzn9xw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.0.24.tgz", + "integrity": "sha512-xkf/rihCkhqMeh5EA8lVp90/mzbb2gcg6I3oeFWw2hognVcTnPXg6llhWdU4Spqd0cals7GEFmQugIILCmH8GA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" } }, "node_modules/@storybook/core-server": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.0.18.tgz", - "integrity": "sha512-zGSGYSoCaSXM28OYKW7zsmpo8VU1icubXLRgdF21fbMhFN1WVS+bPA5+gSkAMf8acq5RNM8uSKskh7E2YDVEqA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.0.24.tgz", + "integrity": "sha512-FJgdbtLgppFMd/RedF728I+v45TRG7s5/3RJfwgRgbq4ZEhKFzZN66MwWFeq3i5Q8ETHVwAxyVvC/JrRqAJxoA==", "dev": true, "dependencies": { "@aw-web-design/x-default-browser": "1.4.88", "@discoveryjs/json-ext": "^0.5.3", - "@storybook/builder-manager": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/builder-manager": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", - "@storybook/csf-tools": "7.0.18", + "@storybook/csf-tools": "7.0.24", "@storybook/docs-mdx": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/telemetry": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/telemetry": "7.0.24", + "@storybook/types": "7.0.24", "@types/detect-port": "^1.3.0", "@types/node": "^16.0.0", "@types/node-fetch": "^2.5.7", "@types/pretty-hrtime": "^1.0.0", "@types/semver": "^7.3.4", "better-opn": "^2.1.1", - "boxen": "^5.1.2", "chalk": "^4.1.0", "cli-table3": "^0.6.1", "compression": "^1.7.4", @@ -8001,20 +8027,20 @@ } }, "node_modules/@storybook/core-server/node_modules/@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true }, "node_modules/@storybook/core-webpack": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-7.0.18.tgz", - "integrity": "sha512-U5e1r8cgZZzd/Lw9StIrACMVINCvucKm8ZfcFpPh0bjEv4+2qjo9tL3dLNh4OwKznvbzSE6pEO6cBjaphjTe1A==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-7.0.24.tgz", + "integrity": "sha512-sM0hX55uNFXfQdRMthFdY6luWmi9MG+dIj6bNPiVY2SxNenxj62P/0/R/1Ime27X/vzFbi12pqUijzPNUwiwQw==", "dev": true, "dependencies": { - "@storybook/core-common": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/core-common": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/types": "7.0.24", "@types/node": "^16.0.0", "ts-dedent": "^2.0.0" }, @@ -8024,9 +8050,9 @@ } }, "node_modules/@storybook/core-webpack/node_modules/@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true }, "node_modules/@storybook/csf": { @@ -8038,12 +8064,12 @@ } }, "node_modules/@storybook/csf-plugin": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.0.18.tgz", - "integrity": "sha512-Cr/Qr4/H4JIYgbbmDjQIYuqjp6nOaZga73R3KZcuClk27B90sI2ADegMYvORgbFgSkwweNQjgak6hLoOyogAhw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.0.24.tgz", + "integrity": "sha512-+oIZCIhrRFbvplXUwJn671ZM0kgNqZ59jM9RmehJGgu5N5h1JSbBcz1edXgStNsMk9e2NJopuOKrzZGTGyi0XA==", "dev": true, "dependencies": { - "@storybook/csf-tools": "7.0.18", + "@storybook/csf-tools": "7.0.24", "unplugin": "^0.10.2" }, "funding": { @@ -8052,9 +8078,9 @@ } }, "node_modules/@storybook/csf-tools": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.0.18.tgz", - "integrity": "sha512-0IJ2qdrxleTl67FUzsEvGcy96CY0OKyERE33tAsLNbvWcabdJKpLHP+rJwbsCw4z6IlS+kkmEffeFf5qRPTwkQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.0.24.tgz", + "integrity": "sha512-RBNiXY3ht6XpcIyVgxBo7mK2t32tJuC93OO/HgcoRFClcdA8HUnlva297XpJpMqCgrcF8fPqRo+ZcLeC7vjzvw==", "dev": true, "dependencies": { "@babel/generator": "~7.21.1", @@ -8062,7 +8088,7 @@ "@babel/traverse": "~7.21.2", "@babel/types": "~7.21.2", "@storybook/csf": "^0.1.0", - "@storybook/types": "7.0.18", + "@storybook/types": "7.0.24", "fs-extra": "^11.1.0", "recast": "^0.23.1", "ts-dedent": "^2.0.0" @@ -8150,15 +8176,15 @@ "dev": true }, "node_modules/@storybook/docs-tools": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.0.18.tgz", - "integrity": "sha512-H95dW2DquGQ75ZVrFjvznPdCxT0eW6esDnemzLJB61KitcYZrWRavfrZzFtUcpzIa84OgY5pllFYt636v11LHQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.0.24.tgz", + "integrity": "sha512-vmDHmHB1B5CWsYQ7CEtfz4vdf36VK/EZdNQUox9kdN935Dks7KSuGcDdXiRlWc78e94/A9+1mJQpyfwtn3E8fQ==", "dev": true, "dependencies": { "@babel/core": "^7.12.10", - "@storybook/core-common": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/core-common": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/types": "7.0.24", "@types/doctrine": "^0.0.3", "doctrine": "^3.0.0", "lodash": "^4.17.21" @@ -8182,15 +8208,15 @@ "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==" }, "node_modules/@storybook/instrumenter": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-7.0.18.tgz", - "integrity": "sha512-fyQxeuVC0H+w3oyTuByE95xnAQ+l/WhUBVkHV2X+PWjg9vg9Y9JmrbNWynlvz5HLFlsY3qAWJh+ciVRVSvY5Jw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-7.0.24.tgz", + "integrity": "sha512-XQ4Whq0rqW9eFMTtRpLxcl6bCf+KO3UZYcm+H63EDn9TstDyopmqv1fDg2tmJOpqLo143F8qLVC89rI7M/lO6w==", "dependencies": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.0.18" + "@storybook/preview-api": "7.0.24" }, "funding": { "type": "opencollective", @@ -8244,9 +8270,9 @@ } }, "node_modules/@storybook/manager": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.0.18.tgz", - "integrity": "sha512-hasb8XDmkT9lyX2cwb3Xg0ngcNQ1QCNHKurl2YJtXowb1CvawGKokhnVUTso15NCnurolDyw/Wqka1sagfm+Mg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.0.24.tgz", + "integrity": "sha512-LsQd2cFJViwoPJ7K0A/XBWrBBhJv7F0J6+aa7qHszNmIZHVbMXyZfiX7JS3RHVs4I2kLuNpSk4X+iDG0QAafEQ==", "dev": true, "funding": { "type": "opencollective", @@ -8254,19 +8280,19 @@ } }, "node_modules/@storybook/manager-api": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.0.18.tgz", - "integrity": "sha512-anQkm09twL96YkKGXHa+LI0+yMaY6Jxs1lRaetHdMlIqN4VHBHhizHaMgtGfH6xCTuO3WdrKTN7cZii5RH7PBQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.0.24.tgz", + "integrity": "sha512-cBpgDWq8reFgyrv4fBZlZJQyWYb9cDW0LDe476rWn/29uXNvYMNsHRwveLNgSA8Oy1NdyQCgf4ZgcYvY3wpvMA==", "dev": true, "dependencies": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/router": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/router": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", @@ -8291,9 +8317,9 @@ "dev": true }, "node_modules/@storybook/nextjs": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/nextjs/-/nextjs-7.0.18.tgz", - "integrity": "sha512-+iLHPmfoI6sIfm8NhDqWaMYJ9UVycdfYbqN9qqpoYHwvh77GmqzKxNmkqdB3AQlicXBCUvabyV5A7lX9cdEHug==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/nextjs/-/nextjs-7.0.24.tgz", + "integrity": "sha512-SQqqeSyshs58Gluc+EZrjaSWAspOZ0YRRmZK3+cepomFsm22m1phInoFi1Zcvsf5CirjIjWUbYzxgYO6OUyhKw==", "dev": true, "dependencies": { "@babel/plugin-proposal-class-properties": "^7.18.6", @@ -8308,13 +8334,13 @@ "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@babel/runtime": "^7.21.0", - "@storybook/addon-actions": "7.0.18", - "@storybook/builder-webpack5": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preset-react-webpack": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/react": "7.0.18", + "@storybook/addon-actions": "7.0.24", + "@storybook/builder-webpack5": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preset-react-webpack": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/react": "7.0.24", "@types/node": "^16.0.0", "css-loader": "^6.7.3", "find-up": "^5.0.0", @@ -8446,9 +8472,9 @@ } }, "node_modules/@storybook/node-logger": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.0.18.tgz", - "integrity": "sha512-cIeKEBvELtoVP/5UeQ01GJWZ7wM69/9Q+R5uOtNQBlwWFcCD6AVFWMRqq7ObMvdJG/okhXSF+sDetb+BF3zvdw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.0.24.tgz", + "integrity": "sha512-gjcYnreYBBtZVF6p/cHMas4FEafPddjsLMrAfB+0lLGoRdUwWVto46BZTHQ9seY5gPW0JQydAdDGHko8/kEOXA==", "dev": true, "dependencies": { "@types/npmlog": "^4.1.2", @@ -8462,9 +8488,9 @@ } }, "node_modules/@storybook/postinstall": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.0.18.tgz", - "integrity": "sha512-ObIwAK2UiYhXN/7UifISQgBoH5jnyxh6T8kvCw83YhC78SDOPNgIGjToJECizJ7iubtqAWtCfCT5TrGEpyLGbg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.0.24.tgz", + "integrity": "sha512-UYMXyEU4nVIKyrlUdIs3NHQmILzrN+EkEDbmeQC2WMMPw+t4GY2cDVmpx90JYYZcn7gY+cNDgQ55iiqbvlamLQ==", "dev": true, "funding": { "type": "opencollective", @@ -8472,18 +8498,18 @@ } }, "node_modules/@storybook/preset-react-webpack": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-7.0.18.tgz", - "integrity": "sha512-ISqq+DWzxHrQUHt83+tq7TKQETQcwekUnNYKgFzN8dVgZWqRS+/PqX+7c07Qa3h/QIWgMjPA6SPN4Z12tV4qpA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-7.0.24.tgz", + "integrity": "sha512-9BI243TMv5f+CjzGVB3CFA82E2kWYhQTaRoeNKxxk7NvgiascFMATkgBjIwtGYVXL9umk8mytzulOq/oXPnscQ==", "dev": true, "dependencies": { "@babel/preset-flow": "^7.18.6", "@babel/preset-react": "^7.18.6", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5", - "@storybook/core-webpack": "7.0.18", - "@storybook/docs-tools": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/react": "7.0.18", + "@storybook/core-webpack": "7.0.24", + "@storybook/docs-tools": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/react": "7.0.24", "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", "@types/node": "^16.0.0", "@types/semver": "^7.3.4", @@ -8516,15 +8542,15 @@ } }, "node_modules/@storybook/preset-react-webpack/node_modules/@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true }, "node_modules/@storybook/preview": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.0.18.tgz", - "integrity": "sha512-L53p2eo8G12U6tp7hD3mk5tdWFXLvdEyV9e7a1x9bw1LfH15K/bp8lO6U/W1kkpse7+rqWBqoTjJC1Ktm5Sxog==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.0.24.tgz", + "integrity": "sha512-rej4Wz8Qy4gVuyvg4cpQGkR4wJc3b+0Uv6EYylbmpdj2585cOhFtRBykagDVZteVU4xaLMT7YHIZRnoLmJKIgw==", "dev": true, "funding": { "type": "opencollective", @@ -8532,17 +8558,17 @@ } }, "node_modules/@storybook/preview-api": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.0.18.tgz", - "integrity": "sha512-xxtC0gPGMn/DbwvS4ZuJaBwfFNsjUCf0yLYHFrNe6fxncbvcLZ550RuyUwYuIRfsiKrlgfa3QmmCa4JM/JesHQ==", - "dependencies": { - "@storybook/channel-postmessage": "7.0.18", - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.0.24.tgz", + "integrity": "sha512-psycU07tuB5nyJvfAJiDN/9e8cjOdJ+5lrCSYC3vPzH86LxADDIN0/8xFb1CaQWcXZsADEFJGpHKWbRhjym5ew==", + "dependencies": { + "@storybook/channel-postmessage": "7.0.24", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/types": "7.0.18", + "@storybook/types": "7.0.24", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -8558,18 +8584,18 @@ } }, "node_modules/@storybook/react": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-7.0.18.tgz", - "integrity": "sha512-lumUbHYeuL3qa4SZR9K2YC4UIt1hwW19GuI/6f2HEV5gR9QHHSJHg9HD9pjcxv4fQaiG81ACZ0Sg6lyUkcJvuQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-7.0.24.tgz", + "integrity": "sha512-JAgSs8ANysBl3+cOAjFSVG3bA2V/wP6jyu7oK0jSATRQhHRjRS/tHFMA82j0j98G2sr3JXQUxNt55Qq3k2mUcg==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/core-client": "7.0.18", - "@storybook/docs-tools": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/core-client": "7.0.24", + "@storybook/docs-tools": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.0.18", - "@storybook/react-dom-shim": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/preview-api": "7.0.24", + "@storybook/react-dom-shim": "7.0.24", + "@storybook/types": "7.0.24", "@types/escodegen": "^0.0.6", "@types/estree": "^0.0.51", "@types/node": "^16.0.0", @@ -8622,9 +8648,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.0.18.tgz", - "integrity": "sha512-O1FRypR8q1katjbznnxI+NtALd2gaWa7KnTwbIDf+ddZltXHMZ8xMiEGEtAMrfXlIuqIr9UvmLRfKZC/ysuA+g==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.0.24.tgz", + "integrity": "sha512-YOP1C3dWTLYP5mPb7hNuDRIhADzz+ppfb+S22JNJ3kqm+tsyE/YtAbRf80k6QIG1LzukMpGoEnjjOPOsWsyvFQ==", "dev": true, "funding": { "type": "opencollective", @@ -8642,9 +8668,9 @@ "dev": true }, "node_modules/@storybook/react/node_modules/@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true }, "node_modules/@storybook/react/node_modules/acorn": { @@ -8669,12 +8695,12 @@ } }, "node_modules/@storybook/router": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.0.18.tgz", - "integrity": "sha512-Mue4s/BnKgdYcsiW9yuvW3qL9k3AgYn5HIhnkBExAteyiUGdAca4IJFhArmGgFktgeLc4ecBQ7sgaCljApnbgg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.0.24.tgz", + "integrity": "sha512-SRCV+srCZUbko/V0phVN8jY8ilrxQWWAY/gegwNlIYaNqLJSyYqIj739VDmX+deXl6rOEpFLZreClVXWiDU9+w==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", + "@storybook/client-logger": "7.0.24", "memoizerific": "^1.11.3", "qs": "^6.10.0" }, @@ -8688,13 +8714,13 @@ } }, "node_modules/@storybook/store": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/store/-/store-7.0.18.tgz", - "integrity": "sha512-rvQOG7R1+r77Y9jwNqQB3EKW6D5kzIGoxqzFHd1oDqeY5+vqPXHC/J5iDrl8TZ4GES7ZMAHpkTySbY+rRQK7Ng==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/store/-/store-7.0.24.tgz", + "integrity": "sha512-T6BOXpiIAiGpQcfe0Hyu3d+8Gd0sUaVTSDXJLadfr7tqC6qmMpOuyApFu1qRfgJqh4aykUb75ESCvYWoEjwm+A==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/preview-api": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/preview-api": "7.0.24" }, "funding": { "type": "opencollective", @@ -8702,13 +8728,13 @@ } }, "node_modules/@storybook/telemetry": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.0.18.tgz", - "integrity": "sha512-JP5Z7lGU+oKjNmz2cZW5J7EerwyWBBPOU+NvvooZsymIx02ZvJ4ClmFtolJnBM7m4KoAy50JxV5NQWi+q8PicQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.0.24.tgz", + "integrity": "sha512-mLGwm3yeWlM9Srrcecrpce4m8uyazIMkHIYcBC0cD2L/JzIRzeRS3Na8QlLKz4/+Hxawm7K/pE/DBrVjvBbm8A==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.18", - "@storybook/core-common": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/core-common": "7.0.24", "chalk": "^4.1.0", "detect-package-manager": "^2.0.1", "fetch-retry": "^5.0.2", @@ -8741,26 +8767,24 @@ } }, "node_modules/@storybook/testing-library": { - "version": "0.0.14-next.2", - "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.0.14-next.2.tgz", - "integrity": "sha512-i/SLSGm0o978ELok/SB4Qg1sZ3zr+KuuCkzyFqcCD0r/yf+bG35aQGkFqqxfSAdDxuQom0NO02FE+qys5Eapdg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.0.tgz", + "integrity": "sha512-Ff6jNnrsosmDshgCf0Eb5Cz7IA34p/1Ps5N3Kp3598kfXpBSccSkQQvVFUXC3kIHw/isIXWPqntZuKqnWUz7Gw==", "dev": true, "dependencies": { - "@storybook/client-logger": "^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0", - "@storybook/instrumenter": "^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0", - "@testing-library/dom": "^8.3.0", - "@testing-library/user-event": "^13.2.1", + "@testing-library/dom": "^9.0.0", + "@testing-library/user-event": "^14.0.0", "ts-dedent": "^2.2.0" } }, "node_modules/@storybook/theming": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.0.18.tgz", - "integrity": "sha512-P1gMKa/mKQHIMq0sxBIwTzAcF6v/6hrc62YmkuV62vXu+8zNV2YWbRwywqm3Q6faZEadmb/bL9+z8whaKhCL/g==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.0.24.tgz", + "integrity": "sha512-CMeCCfqffJ/D5rBl1HpAM/e5Vw0h7ucT+CLzP0ALtLrguz9ZzOiIZYgMj17KpfvWqje7HT+DwEtNkSrnJ01FNQ==", "dev": true, "dependencies": { "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.0.18", + "@storybook/client-logger": "7.0.24", "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3" }, @@ -8774,35 +8798,20 @@ } }, "node_modules/@storybook/types": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.0.18.tgz", - "integrity": "sha512-qPop2CbvmX42/BX29YT9jIzW2TlMcMjAE+KCpcKLBiD1oT5DJ1fhMzpe6RW9HkMegkBxjWx54iamN4oHM/pwcQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.0.24.tgz", + "integrity": "sha512-SZh/XBHP1TT5bmEk0W52nT0v6fUnYwmZVls3da5noutdgOAiwL7TANtl41XrNjG+UDr8x0OE3PVVJi+LhwUaNA==", "dependencies": { - "@storybook/channels": "7.0.18", + "@storybook/channels": "7.0.24", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", - "file-system-cache": "^2.0.0" + "file-system-cache": "2.3.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" } }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.3.63", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.63.tgz", - "integrity": "sha512-EAB5gkgDvStJofvdQU40hqEqjtSvtPs3PR0WupZtbLKWWCTWg76uTXQZEKNYx9r60Pt7sx1BAa3XnqgXjmcjDg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/helpers": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", @@ -8881,22 +8890,22 @@ } }, "node_modules/@testing-library/dom": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.0.tgz", - "integrity": "sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", + "integrity": "sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==", "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", - "aria-query": "^5.0.0", + "aria-query": "5.1.3", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", + "lz-string": "^1.5.0", "pretty-format": "^27.0.2" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/@testing-library/jest-dom": { @@ -8933,15 +8942,12 @@ } }, "node_modules/@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "version": "14.4.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz", + "integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==", "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.5" - }, "engines": { - "node": ">=10", + "node": ">=12", "npm": ">=6" }, "peerDependencies": { @@ -8961,35 +8967,34 @@ } }, "node_modules/@tiptap/extension-blockquote": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.220.tgz", - "integrity": "sha512-uE1VRU/doQzXsfsZ/JqsbSbXeZYTJnyQkSfHYA2ZYhbEM2XqDEsYkgcmZEJgunUZJpERf+3ZTfTpqaHq29iMMg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.0.3.tgz", + "integrity": "sha512-rkUcFv2iL6f86DBBHoa4XdKNG2StvkJ7tfY9GoMpT46k3nxOaMTqak9/qZOo79TWxMLYtXzoxtKIkmWsbbcj4A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.1" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-bold": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.220.tgz", - "integrity": "sha512-KcEuKI85Drug/cCWbDy+HxhYrD+rLXHEBG10DmKPvgPpKHG/2wOau6LwUwyV4muWR8CR2mIO+mEc3yVBD8nNwQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.0.3.tgz", + "integrity": "sha512-OGT62fMRovSSayjehumygFWTg2Qn0IDbqyMpigg/RUAsnoOI2yBZFVrdM2gk1StyoSay7gTn2MLw97IUfr7FXg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-bubble-menu": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.220.tgz", - "integrity": "sha512-wthyec7s0vZlTSEAAZEgoFfx/1Arwg1zxDUrrE+YAost/Yn+w4xQksz/ts5Bx90iOk2qsJ+jzzttLRV17Ku7lA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.3.tgz", + "integrity": "sha512-lPt1ELrYCuoQrQEUukqjp9xt38EwgPUwaKHI3wwt2Rbv+C6q1gmRsK1yeO/KqCNmFxNqF2p9ZF9srOnug/RZDQ==", "dependencies": { - "lodash": "^4.17.21", "tippy.js": "^6.3.7" }, "funding": { @@ -8997,76 +9002,76 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209", - "@tiptap/pm": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.220.tgz", - "integrity": "sha512-QQ/0ZlYy6Hgb+UAc79V+fxvI+AaQf20cbKtBXaR8TIZ0x4FotSma89bKh+CIXMhFiBGXTcYBaYhl7OwACsKtxw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.3.tgz", + "integrity": "sha512-RtaLiRvZbMTOje+FW5bn+mYogiIgNxOm065wmyLPypnTbLSeHeYkoqVSqzZeqUn+7GLnwgn1shirUe6csVE/BA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-code": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.0.0-beta.220.tgz", - "integrity": "sha512-JKKDZoceagqVXeC1XF/gOkKhLtsbYJYV+MRDorLnQVz4tXcg/SMs5Ez7OM9MxSSior8fIbUFMNsj1/UNlG+tFw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.0.3.tgz", + "integrity": "sha512-LsVCKVxgBtkstAr1FjxN8T3OjlC76a2X8ouoZpELMp+aXbjqyanCKzt+sjjUhE4H0yLFd4v+5v6UFoCv4EILiw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-code-block": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.220.tgz", - "integrity": "sha512-fgA7yTfHqhBtMJF7I9FPJ6UWuZPtxOQiN45Iv9LNmFIB6YRucdpmF+daZ27sElu0a+eICZyXwVn4w4iJphifuw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.0.3.tgz", + "integrity": "sha512-F4xMy18EwgpyY9f5Te7UuF7UwxRLptOtCq1p2c2DfxBvHDWhAjQqVqcW/sq/I/WuED7FwCnPLyyAasPiVPkLPw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209", - "@tiptap/pm": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" } }, "node_modules/@tiptap/extension-document": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.0.0-beta.220.tgz", - "integrity": "sha512-2sja4ZvOb4iynHrzinnclCSFgLyo6fJc1fBV5fIYaOgZOYcvz9KK8fgKiq+wIpG58sJEmQ5kcwwBlkXv+NTK+g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.0.3.tgz", + "integrity": "sha512-PsYeNQQBYIU9ayz1R11Kv/kKNPFNIV8tApJ9pxelXjzcAhkjncNUazPN/dyho60mzo+WpsmS3ceTj/gK3bCtWA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.220.tgz", - "integrity": "sha512-BIaA4Lvb3xL9KFN+K6SO2IHqLO6hDmGN2/rGKHFaU3Eh+oiXM2G73KTSS5KIP1u872zY1RpAtswSc4kjv3cuVw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.3.tgz", + "integrity": "sha512-McthMrfusn6PjcaynJLheZJcXto8TaIW5iVitYh8qQrDXr31MALC/5GvWuiswmQ8bAXiWPwlLDYE/OJfwtggaw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209", - "@tiptap/pm": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" } }, "node_modules/@tiptap/extension-floating-menu": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.220.tgz", - "integrity": "sha512-+WfcBEedm82ntaVIEQAGz0Om96Rpav7a+4f7e8N4PrLKm6nZ3gBaEkZVQ6vjJ6S/1htiWCv1XosYIwRboPBG0w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.3.tgz", + "integrity": "sha512-zN1vRGRvyK3pO2aHRmQSOTpl4UJraXYwKYM009n6WviYKUNm0LPGo+VD4OAtdzUhPXyccnlsTv2p6LIqFty6Bg==", "dependencies": { "tippy.js": "^6.3.7" }, @@ -9075,89 +9080,89 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209", - "@tiptap/pm": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.220.tgz", - "integrity": "sha512-W5N2Ey+thufUOrs2TFGpEGBGue7ZEhcUXvxcsZlGbrjVa9Y+4rEp68Du4y7yM0hCeSj2GGwiV+uPzkc0CSDE/g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.3.tgz", + "integrity": "sha512-6I9EzzsYOyyqDvDvxIK6Rv3EXB+fHKFj8ntHO8IXmeNJ6pkhOinuXVsW6Yo7TcDYoTj4D5I2MNFAW2rIkgassw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209", - "@tiptap/pm": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" } }, "node_modules/@tiptap/extension-hard-break": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.220.tgz", - "integrity": "sha512-oY3454o53YNFbuokzyGzG4PdMHkIYreY3nrALioZ0SwYeoFNcGA6Zcn4rDRfdp+QvbbiHfeBTR/CpWF13HZYTg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.0.3.tgz", + "integrity": "sha512-RCln6ARn16jvKTjhkcAD5KzYXYS0xRMc0/LrHeV8TKdCd4Yd0YYHe0PU4F9gAgAfPQn7Dgt4uTVJLN11ICl8sQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-heading": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.220.tgz", - "integrity": "sha512-7mrHRj++UaZ26C2Gjwb0WKWAzpiKb8TOYkVC2uMaCwaNhLDXpFEwZ7RtJRSTNBHkIGnMO46BH8Z0qlkFMmk9Jw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.0.3.tgz", + "integrity": "sha512-f0IEv5ms6aCzL80WeZ1qLCXTkRVwbpRr1qAETjg3gG4eoJN18+lZNOJYpyZy3P92C5KwF2T3Av00eFyVLIbb8Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-history": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.0.0-beta.220.tgz", - "integrity": "sha512-qNL2a9UhnlmCs4y2iQYrfeMB8vEX3bHozBJanHu0PWNQJcj90R5xqorBp/bRcqZdi0kuQfxcTnGHtLUpN/U0TA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.0.3.tgz", + "integrity": "sha512-00KHIcJ8kivn2ARI6NQYphv2LfllVCXViHGm0EhzDW6NQxCrriJKE3tKDcTFCu7LlC5doMpq9Z6KXdljc4oVeQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209", - "@tiptap/pm": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.220.tgz", - "integrity": "sha512-XMIs4R+4BoH5LpIxey513mZuus0XLHqjVayqtf03enmjBTLWzkixvvWLPLw4a47FJL5Q8l4REFHxjNifRzOKkg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.3.tgz", + "integrity": "sha512-SZRUSh07b/M0kJHNKnfBwBMWrZBEm/E2LrK1NbluwT3DBhE+gvwiEdBxgB32zKHNxaDEXUJwUIPNC3JSbKvPUA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209", - "@tiptap/pm": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" } }, "node_modules/@tiptap/extension-italic": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.220.tgz", - "integrity": "sha512-aWAgqoR8fql9fJ7T/ZrEqovkEjZXbUpvlvWEvdBDMG3id8ZTGNDpdDKdvI6J/Rl5ZGPIg1TpHJtd+UixheWQsQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.0.3.tgz", + "integrity": "sha512-cfS5sW0gu7qf4ihwnLtW/QMTBrBEXaT0sJl3RwkhjIBg/65ywJKE5Nz9ewnQHmDeT18hvMJJ1VIb4j4ze9jj9A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-link": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.0.0-beta.220.tgz", - "integrity": "sha512-vjEA8cE37ZZVVgPHSpttw3kbJoClb+ya/BVukDtJ1h6C7mIR1rqzNxTgpbnXJuA8xww0JOjpa5dpzEgcs294fA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.0.3.tgz", + "integrity": "sha512-H72tXQ5rkVCkAhFaf08fbEU7EBUCK0uocsqOF+4th9sOlrhfgyJtc8Jv5EXPDpxNgG5jixSqWBo0zKXQm9s9eg==", "dependencies": { "linkifyjs": "^4.1.0" }, @@ -9166,44 +9171,44 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209", - "@tiptap/pm": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" } }, "node_modules/@tiptap/extension-list-item": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.220.tgz", - "integrity": "sha512-+O0ivwxPP2l/m9PAowb2ytDT/cM5kwu0s1W5MUsHPIqf+M6ahnl4ESjhWZfDHUzvjqPq6MTbqoQLHbB1KS/N7w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.0.3.tgz", + "integrity": "sha512-p7cUsk0LpM1PfdAuFE8wYBNJ3gvA0UhNGR08Lo++rt9UaCeFLSN1SXRxg97c0oa5+Ski7SrCjIJ5Ynhz0viTjQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.220.tgz", - "integrity": "sha512-j3DmxJfwmNxFfMnvO7glmGlhYeZSIUnRrKnZu2KkpD6OcGJSh9y/yfnYwcuK80XbzEG/jKKIw0M2yRveOvyVwA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.3.tgz", + "integrity": "sha512-ZB3MpZh/GEy1zKgw7XDQF4FIwycZWNof1k9WbDZOI063Ch4qHZowhVttH2mTCELuyvTMM/o9a8CS7qMqQB48bw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-paragraph": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.220.tgz", - "integrity": "sha512-ZGCzNGFYV4wa3l1nXtDIaYp7O6f0DrGTSl3alKkDTQe3SOmzXS2HjgWl9yPw8VXpU9W5mMGhXd+nGn/jUk+f/A==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.0.3.tgz", + "integrity": "sha512-a+tKtmj4bU3GVCH1NE8VHWnhVexxX5boTVxsHIr4yGG3UoKo1c5AO7YMaeX2W5xB5iIA+BQqOPCDPEAx34dd2A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-placeholder": { @@ -9220,27 +9225,27 @@ } }, "node_modules/@tiptap/extension-strike": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.220.tgz", - "integrity": "sha512-cIM2ma6mzk08pijOn+KS3ZoHWaUVsVT+OF3m6xewjwJdC0ILg9nApEOhPFrhbeDcxcPmJMlgBl/xeUrEu1HQMg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.0.3.tgz", + "integrity": "sha512-RO4/EYe2iPD6ifDHORT8fF6O9tfdtnzxLGwZIKZXnEgtweH+MgoqevEzXYdS+54Wraq4TUQGNcsYhe49pv7Rlw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/extension-text": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.0.0-beta.220.tgz", - "integrity": "sha512-3tnffc2YMjNyv7Lbad6fx9wYDE/Buz8vhx76M2AOSrjYbzmTJf7mLkgdlPM0VTy7FGZD5CGgHJAgYNt5HIqPkQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.0.3.tgz", + "integrity": "sha512-LvzChcTCcPSMNLUjZe/A9SHXWGDHtvk73fR7CBqAeNU0MxhBPEBI03GFQ6RzW3xX0CmDmjpZoDxFMB+hDEtW1A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209" + "@tiptap/core": "^2.0.0" } }, "node_modules/@tiptap/pm": { @@ -9276,48 +9281,48 @@ } }, "node_modules/@tiptap/react": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.0.0-beta.220.tgz", - "integrity": "sha512-AZWaCGjm2FcJWNl1dxRCHOjGYvUV8R39L7tAcnKxHGajOHdFk8JQHc0XbVZhdBi2YgwvwEr7Tw9G2lzi9e6/fg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.0.3.tgz", + "integrity": "sha512-fiAh8Lk+/NBPAR/PE4Kc/aLiBUbUYI/CpAopz8DI9eInNyV8h8LAGa9uFILJQF/TNu0tclJ4rV0sWc7Se0FZMw==", "dependencies": { - "@tiptap/extension-bubble-menu": "^2.0.0-beta.220", - "@tiptap/extension-floating-menu": "^2.0.0-beta.220" + "@tiptap/extension-bubble-menu": "^2.0.3", + "@tiptap/extension-floating-menu": "^2.0.3" }, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0-beta.209", - "@tiptap/pm": "^2.0.0-beta.209", + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" } }, "node_modules/@tiptap/starter-kit": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.0.0-beta.220.tgz", - "integrity": "sha512-3992NxY5sEp5xmLE/qv/yt1YkgpSpJiUlDRj02isJ0Xsxa4G6bNq+N+tN2rHB0Y8dtYVBSX2vV/DZYVX8O+Gpg==", - "dependencies": { - "@tiptap/core": "^2.0.0-beta.220", - "@tiptap/extension-blockquote": "^2.0.0-beta.220", - "@tiptap/extension-bold": "^2.0.0-beta.220", - "@tiptap/extension-bullet-list": "^2.0.0-beta.220", - "@tiptap/extension-code": "^2.0.0-beta.220", - "@tiptap/extension-code-block": "^2.0.0-beta.220", - "@tiptap/extension-document": "^2.0.0-beta.220", - "@tiptap/extension-dropcursor": "^2.0.0-beta.220", - "@tiptap/extension-gapcursor": "^2.0.0-beta.220", - "@tiptap/extension-hard-break": "^2.0.0-beta.220", - "@tiptap/extension-heading": "^2.0.0-beta.220", - "@tiptap/extension-history": "^2.0.0-beta.220", - "@tiptap/extension-horizontal-rule": "^2.0.0-beta.220", - "@tiptap/extension-italic": "^2.0.0-beta.220", - "@tiptap/extension-list-item": "^2.0.0-beta.220", - "@tiptap/extension-ordered-list": "^2.0.0-beta.220", - "@tiptap/extension-paragraph": "^2.0.0-beta.220", - "@tiptap/extension-strike": "^2.0.0-beta.220", - "@tiptap/extension-text": "^2.0.0-beta.220" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.0.3.tgz", + "integrity": "sha512-t4WG4w93zTpL2VxhVyJJvl3kdLF001ZrhpOuEiZqEMBMUMbM56Uiigv1CnUQpTFrjDAh3IM8hkqzAh20TYw2iQ==", + "dependencies": { + "@tiptap/core": "^2.0.3", + "@tiptap/extension-blockquote": "^2.0.3", + "@tiptap/extension-bold": "^2.0.3", + "@tiptap/extension-bullet-list": "^2.0.3", + "@tiptap/extension-code": "^2.0.3", + "@tiptap/extension-code-block": "^2.0.3", + "@tiptap/extension-document": "^2.0.3", + "@tiptap/extension-dropcursor": "^2.0.3", + "@tiptap/extension-gapcursor": "^2.0.3", + "@tiptap/extension-hard-break": "^2.0.3", + "@tiptap/extension-heading": "^2.0.3", + "@tiptap/extension-history": "^2.0.3", + "@tiptap/extension-horizontal-rule": "^2.0.3", + "@tiptap/extension-italic": "^2.0.3", + "@tiptap/extension-list-item": "^2.0.3", + "@tiptap/extension-ordered-list": "^2.0.3", + "@tiptap/extension-paragraph": "^2.0.3", + "@tiptap/extension-strike": "^2.0.3", + "@tiptap/extension-text": "^2.0.3" }, "funding": { "type": "github", @@ -10666,15 +10671,6 @@ "ajv": "^6.9.1" } }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "dependencies": { - "string-width": "^4.1.0" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -11127,9 +11123,9 @@ "dev": true }, "node_modules/babel-loader/node_modules/schema-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", - "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", @@ -11516,52 +11512,6 @@ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" }, - "node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bplist-parser": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", @@ -12147,18 +12097,6 @@ "integrity": "sha512-OL/7wZpNy9x0GBSzz3poWja84Nr7iaH8aYNsJ5Uet2BVLj6Lm1zvWpZN/yH46Vv3ae7YfHmLLMmfHj911fshJg==", "dev": true }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-check-node": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/cli-check-node/-/cli-check-node-1.3.4.tgz", @@ -12748,9 +12686,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.30.2.tgz", - "integrity": "sha512-p/npFUJXXBkCCTIlEGBdghofn00jWG6ZOtdoIXSJmAu2QBvN0IqpZXWweOytcwE6cfx8ZvVUy1vw8zxhe4Y2vg==", + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.31.0.tgz", + "integrity": "sha512-/AnE9Y4OsJZicCzIe97JP5XoPKQJfTuEG43aEVLFJGOJpyqELod+pE6LEl63DfG1Mp8wX97LDaDpy1GmLEUxlg==", "dev": true, "hasInstallScript": true, "funding": { @@ -13715,9 +13653,9 @@ } }, "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", + "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", "dev": true, "bin": { "envinfo": "dist/cli.js" @@ -15132,9 +15070,9 @@ "dev": true }, "node_modules/flow-parser": { - "version": "0.207.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.207.0.tgz", - "integrity": "sha512-s90OlXqzWj1xc4yUtqD1Gr8pGVx0/5rk9gsqPrOYF1kBAPMH4opkmzdWgQ8aNe3Pckqtwr8DlYGbfE2GnW+zsg==", + "version": "0.210.1", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.210.1.tgz", + "integrity": "sha512-M0SdOwD0wZHhk6K/AOaPReBnw2vB7p9KUFUFZHJRsU3ZMl/+WVrMpmb8AfEM6GXZ5mEssCx9vHugxxJg1ieoew==", "dev": true, "engines": { "node": ">=0.4.0" @@ -15977,10 +15915,20 @@ "dev": true }, "node_modules/html-entities": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.4.tgz", - "integrity": "sha512-TtiHkpRBqP40OzizVWjwBPBsiqchEZxAg/nys6D6lIpdoVLo7sWZ/5Sf/s4UaBHQ6pzUzEr3NiItvEoO46sPtQ==", - "dev": true + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] }, "node_modules/html-escaper": { "version": "2.0.2", @@ -16031,9 +15979,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz", - "integrity": "sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -18734,6 +18682,16 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", @@ -18749,12 +18707,12 @@ } }, "node_modules/memfs": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.2.tgz", - "integrity": "sha512-4kbWXbVZ+LU4XFDS2CuA7frnwz2HxCMB/0yOXc86q7aCQrfWKkL11t6al1e2CsVC7uhnBNTQ1TfUsAxVauO9IQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "dependencies": { - "fs-monkey": "^1.0.3" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" @@ -18985,6 +18943,12 @@ "ufo": "^1.1.1" } }, + "node_modules/mockdate": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", + "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", + "dev": true + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -19303,9 +19267,9 @@ } }, "node_modules/node-fetch-native": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.1.1.tgz", - "integrity": "sha512-9VvspTSUp2Sxbl+9vbZTlFGq9lHwE8GDVVekxx6YsNd1YH59sb3Ba8v3Y3cD8PkLNcileGGcA21PFjVl0jzDaw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.2.0.tgz", + "integrity": "sha512-5IAMBTl9p6PaAjYCnMv5FmqIF6GcZnawAVnzaCG0rX2aYZJ4CxEkZNtVPuTRug7fL7wyM5BQYTlAzcyMPi6oTQ==", "dev": true }, "node_modules/node-int64": { @@ -21355,9 +21319,9 @@ } }, "node_modules/react-inspector": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.1.tgz", - "integrity": "sha512-cxKSeFTf7jpSSVddm66sKdolG90qURAX3g1roTeaN6x0YEbtWc8JpmFN9+yIqLNH2uEkYerWLtJZIXRIFuBKrg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", + "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==", "dev": true, "peerDependencies": { "react": "^16.8.4 || ^17.0.0 || ^18.0.0" @@ -21845,16 +21809,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/remark-slug/node_modules/mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/remove-accents": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", @@ -22727,12 +22681,12 @@ "dev": true }, "node_modules/storybook": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.0.18.tgz", - "integrity": "sha512-FXMmTiomSlLPTHty7vGLr0prPf6pCV07EwAmNOYYYTskitEYV0R7hlhawByd7HuobjIhHvSTKesa1Whl86zLNA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.0.24.tgz", + "integrity": "sha512-ilQDM4+KaNO8s5jU4EnS68JWb9KaLR0+xTNa/BEXQa18SnSt/qZYORXtqispwkyuL/9xwaMVwtS+st7JOucNWA==", "dev": true, "dependencies": { - "@storybook/cli": "7.0.18" + "@storybook/cli": "7.0.24" }, "bin": { "sb": "index.js", @@ -24575,9 +24529,9 @@ "dev": true }, "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", - "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", @@ -24594,9 +24548,9 @@ } }, "node_modules/webpack-hot-middleware": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.3.tgz", - "integrity": "sha512-IK/0WAHs7MTu1tzLTjio73LjS3Ov+VvBKQmE8WPlJutgG5zT6Urgq/BbAdRrHTRpyzK0dvAvFh1Qg98akxgZpA==", + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.4.tgz", + "integrity": "sha512-IRmTspuHM06aZh98OhBJtqLpeWFM8FXJS5UYpKYxCJzyFoyWj1w6VGFfomZU7OPA55dMLrQK0pRT1eQ3PACr4w==", "dev": true, "dependencies": { "ansi-html-community": "0.0.8", @@ -24726,18 +24680,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/winston": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.9.0.tgz", @@ -25811,12 +25753,12 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { @@ -25965,11 +25907,11 @@ } }, "@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "requires": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-transforms": { @@ -25998,9 +25940,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz", - "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true }, "@babel/helper-remap-async-to-generator": { @@ -26057,19 +25999,19 @@ } }, "@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==" + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" }, "@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true }, "@babel/helper-wrap-function": { @@ -26395,12 +26337,12 @@ } }, "@babel/plugin-syntax-flow": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz", - "integrity": "sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz", + "integrity": "sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-syntax-import-assertions": { @@ -26440,12 +26382,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", - "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -26704,13 +26646,13 @@ } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz", - "integrity": "sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz", + "integrity": "sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-flow": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-flow": "^7.22.5" } }, "@babel/plugin-transform-for-of": { @@ -26938,44 +26880,44 @@ } }, "@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", + "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.3.tgz", - "integrity": "sha512-JEulRWG2f04a7L8VWaOngWiK6p+JOSpB+DAtwfJgOaej1qdbNxqtK7MwTBHjUA10NeFcszlFNqCdbRcirzh2uQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", + "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/plugin-syntax-jsx": "^7.21.4", - "@babel/types": "^7.22.3" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/types": "^7.22.5" } }, "@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", "dev": true, "requires": { - "@babel/plugin-transform-react-jsx": "^7.18.6" + "@babel/plugin-transform-react-jsx": "^7.22.5" } }, "@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz", + "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-regenerator": { @@ -27213,14 +27155,14 @@ } }, "@babel/preset-flow": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.21.4.tgz", - "integrity": "sha512-F24cSq4DIBmhq4OzK3dE63NHagb27OPE3eWR+HLekt4Z3Y5MzIIUGF3LlLgV0gN8vzbDViSY7HnrReNVCJXTeA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.22.5.tgz", + "integrity": "sha512-ta2qZ+LSiGCrP5pgcGt8xMnnkXQrq8Sa4Ulhy06BOlF5QbLw9q5hIx7bn5MrsvyTGAfh6kTOo07Q+Pfld/8Y5Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-transform-flow-strip-types": "^7.21.0" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-transform-flow-strip-types": "^7.22.5" } }, "@babel/preset-modules": { @@ -27237,17 +27179,17 @@ } }, "@babel/preset-react": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.3.tgz", - "integrity": "sha512-lxDz1mnZ9polqClBCVBjIVUypoB4qV3/tZUDb/IlYbW1kiiLaXaX+bInbRjl+lNQ/iUZraQ3+S8daEmoELMWug==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.5.tgz", + "integrity": "sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.22.3", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-transform-react-display-name": "^7.22.5", + "@babel/plugin-transform-react-jsx": "^7.22.5", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.22.5" } }, "@babel/preset-typescript": { @@ -27264,9 +27206,9 @@ } }, "@babel/register": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.21.0.tgz", - "integrity": "sha512-9nKsPmYDi5DidAqJaQooxIhsLJiNMkGr8ypQ8Uic7cIox7UCDsM7HuUGxdGT7mSDTYbqzIdsOWzfBton/YJrMw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.5.tgz", + "integrity": "sha512-vV6pm/4CijSQ8Y47RH5SopXzursN35RQINfGJkmOlcpAtGuf94miFvIPhCKGQN7WGIcsgG1BHEX2KVdTYwTwUQ==", "dev": true, "requires": { "clone-deep": "^4.0.1", @@ -27415,12 +27357,12 @@ } }, "@babel/types": { - "version": "7.22.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.4.tgz", - "integrity": "sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", "requires": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" } }, @@ -29208,6 +29150,11 @@ "integrity": "sha512-sW9Yt36Db1nXJL+mTr2Wo0y+VkPWeYhygvcHj1FF0srVtV+VoDjxleKtny21QHaG05zdeZnw2fCtf2+dEqgwqA==", "optional": true }, + "@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==" + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -29284,6 +29231,14 @@ "openid-client": "5.4.0" } }, + "@paralleldrive/cuid2": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.1.tgz", + "integrity": "sha512-GJhHYlMhyT2gWemDL7BGMWfTNhspJKkikLKh9wAy3z4GTTINvTYALkUd+eGQK7aLeVkVzPuSA0VCT3H5eEWbbw==", + "requires": { + "@noble/hashes": "^1.1.5" + } + }, "@peculiar/asn1-schema": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz", @@ -29967,19 +29922,19 @@ } }, "@storybook/addon-actions": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.0.18.tgz", - "integrity": "sha512-3M5AU/ZD79YP88vKlFezIJbIoG/II7wCixUBTmwiC3BeQZDuVsqPNl8eiP6MGT70xwyx7a993lSM5f5N5W93vg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.0.24.tgz", + "integrity": "sha512-sIPY6uH8I26KBWUb5fMYBB9xCKB02oSM8gIHzqPZ0DnW8zl+p6+dX3tAdX+XQvb9YOLJihxZ1GF1tOxFduc3Pw==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "dequal": "^2.0.2", "lodash": "^4.17.21", "polished": "^4.2.2", @@ -29999,65 +29954,65 @@ } }, "@storybook/addon-backgrounds": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.18.tgz", - "integrity": "sha512-cPQy1Ot7Urf4hQz+xnF1YKrqSyR0DRwozBmF+sGzceACWmueFl0CifYZC8RSmaiIyVh0RyWPxZ9F/eT67NX2lA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.24.tgz", + "integrity": "sha512-vThKkrSj+J7matGowxIJ4eV+kAF8iUHGQjlaW0J7vhzmVkNnxBvNn/DGOWWQLAJPCTmLVelLaBZEWcMNoKJiVA==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "memoizerific": "^1.11.3", "ts-dedent": "^2.0.0" } }, "@storybook/addon-controls": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.0.18.tgz", - "integrity": "sha512-mD6DE52CCMKugXk2Uab0QxwgfE76kFJroxASmnePnXUNWfP9EZJpJXYE3cyyBbmZuxa46VHDGGEGXQWRl4+Eog==", - "dev": true, - "requires": { - "@storybook/blocks": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/manager-api": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.0.24.tgz", + "integrity": "sha512-x05Ng4wyBRkrupgSkBHKZSGPyUbvIDGiBseA/AjA/BNAMUMWy3t8ll9f7tlKzyDPaUeBSv8peP21r/Ry26Eqhw==", + "dev": true, + "requires": { + "@storybook/blocks": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/manager-api": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "lodash": "^4.17.21", "ts-dedent": "^2.0.0" } }, "@storybook/addon-docs": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.0.18.tgz", - "integrity": "sha512-oq+ZN5809gIRdTZQIpeK1F8BJtL1/VWo9rWvl6ymVOL/Xzdgd7AOfKf9Y99X35RcxAGysRIHLGJjF4bgLoY1Aw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.0.24.tgz", + "integrity": "sha512-O5S+E6+8c/EHEQc5WcrNQ8dOVg9Q2ONIOYxlbSAcfMUA/d+tRR9xXTZog7nv1tj4U0G29+Vr4pKgsGh3Ya5qcw==", "dev": true, "requires": { "@babel/core": "^7.20.2", "@babel/plugin-transform-react-jsx": "^7.19.0", "@jest/transform": "^29.3.1", "@mdx-js/react": "^2.1.5", - "@storybook/blocks": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/csf-plugin": "7.0.18", - "@storybook/csf-tools": "7.0.18", + "@storybook/blocks": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/csf-plugin": "7.0.24", + "@storybook/csf-tools": "7.0.24", "@storybook/global": "^5.0.0", "@storybook/mdx2-csf": "^1.0.0", - "@storybook/node-logger": "7.0.18", - "@storybook/postinstall": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/react-dom-shim": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/node-logger": "7.0.24", + "@storybook/postinstall": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/react-dom-shim": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "fs-extra": "^11.1.0", "remark-external-links": "^8.0.0", "remark-slug": "^6.0.0", @@ -30065,54 +30020,54 @@ } }, "@storybook/addon-essentials": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.0.18.tgz", - "integrity": "sha512-0XXu7xhtRefA1WxxorKk6BWeeB+7gQ+r2+bG1zQEfBgDYPR06YbPw4H79IZ8JiR97aJRsZBK5UUhOZMDrc5zcQ==", - "dev": true, - "requires": { - "@storybook/addon-actions": "7.0.18", - "@storybook/addon-backgrounds": "7.0.18", - "@storybook/addon-controls": "7.0.18", - "@storybook/addon-docs": "7.0.18", - "@storybook/addon-highlight": "7.0.18", - "@storybook/addon-measure": "7.0.18", - "@storybook/addon-outline": "7.0.18", - "@storybook/addon-toolbars": "7.0.18", - "@storybook/addon-viewport": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/manager-api": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preview-api": "7.0.18", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.0.24.tgz", + "integrity": "sha512-OL27TNQYUJv/FprFCU7Q9RQYrgGdM+4SH+XmsQCcuQuGa67s6/eRKyERwOdy4Pli3Payo76+Vz1DAeJZJ0F8oA==", + "dev": true, + "requires": { + "@storybook/addon-actions": "7.0.24", + "@storybook/addon-backgrounds": "7.0.24", + "@storybook/addon-controls": "7.0.24", + "@storybook/addon-docs": "7.0.24", + "@storybook/addon-highlight": "7.0.24", + "@storybook/addon-measure": "7.0.24", + "@storybook/addon-outline": "7.0.24", + "@storybook/addon-toolbars": "7.0.24", + "@storybook/addon-viewport": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/manager-api": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preview-api": "7.0.24", "ts-dedent": "^2.0.0" } }, "@storybook/addon-highlight": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.0.18.tgz", - "integrity": "sha512-a3nfUhbu6whoDclIZSV/fzLj132tNNjV05ENTpuN3JpLoMd3+obDUWzeQUs9TetK4RBRN3ewM7sIMEI4oBpgmg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.0.24.tgz", + "integrity": "sha512-IoCJHiX5Ai+7S08isxt7BH4baNF2RsjuGUA/iMoJtto/rMc5u0xftVeIjh6oVqV3tjckowXpezI3oStnrLWuRw==", "dev": true, "requires": { - "@storybook/core-events": "7.0.18", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.0.18" + "@storybook/preview-api": "7.0.24" } }, "@storybook/addon-interactions": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-7.0.18.tgz", - "integrity": "sha512-V3OD5lSj6Te6Kzc//2k2S79dLPk6Zu1pAbqWAN4RrdXyKj6YCiZ666GmVdiaG+24Qp5UuMeAkd1D05osJlOteA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-7.0.24.tgz", + "integrity": "sha512-N0BWt13T8lA+L0pAcC3xwhVMWQhrwHaXFqC6aJ1OxJb9pkA85S6Pk7VJRATDpmu9C3JO0OU3EOBB2YVVwcmD0A==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "7.0.18", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/instrumenter": "7.0.24", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "jest-mock": "^27.0.6", "polished": "^4.2.2", "ts-dedent": "^2.2.0" @@ -30153,71 +30108,76 @@ } }, "@storybook/addon-links": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.0.18.tgz", - "integrity": "sha512-xEwflt7bp9FRoZVeqPGb6d3s2Gh+/jaSmnyIxMxrBy2oovKIqu9ptolqz1AhjFOXfaLs9c2RAmJUuFZJtETLxA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.0.24.tgz", + "integrity": "sha512-/Hse4IC3ov2dVzpZiIpf2QNFczi4pxdjZdmR0FhKeRlFldEJyywgT8a/gzeEahXO9v1jsEDa7j7f8JQcu/+04w==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/router": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/router": "7.0.24", + "@storybook/types": "7.0.24", "prop-types": "^15.7.2", "ts-dedent": "^2.0.0" } }, "@storybook/addon-measure": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.0.18.tgz", - "integrity": "sha512-iu8vQpGOA+CFYbWR6QNshj20o33OQ/xcTbp5P4U6xGYDUliUBbwJ2KLxcKlmIeBanBrBdz0jPFtHwY4dM1ZdKw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.0.24.tgz", + "integrity": "sha512-4VNs4rjdz+YFiJCz9DfCmBJwFuoa3pLhcEsAAdT3B+Hrkae+hvLtnQWIvAMsOlSWdl4tiuEWssDf4cjCEne87w==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/types": "7.0.18" + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/types": "7.0.24" } }, "@storybook/addon-outline": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.0.18.tgz", - "integrity": "sha512-3vNWO7ezo6GIvidbz8JxFrKtfVEoTQN7tnZx+wpqmCF8ihBORewkpeMUnvgb9ZKjD0X7gE8eQvvG8KKWcyHDBQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.0.24.tgz", + "integrity": "sha512-YwSfs8bsmh7mEF+rlmL7zBsebWA5e/Rsf09vVqt6/k3fpopgBrq44zQlMwo1dCWV/0YhhXQF21OGzeJ1dSb8fA==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/types": "7.0.24", "ts-dedent": "^2.0.0" } }, "@storybook/addon-styling": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@storybook/addon-styling/-/addon-styling-1.0.8.tgz", - "integrity": "sha512-Ubi75gHNFO60Sjti2n/i3f0utERNOYcpsRkWHdzV+C26kUemLG+2riKHUt8zVbNskyJxA0EZxh84HYItRe4coA==", - "dev": true, - "requires": { - "@storybook/api": "^7.0.2", - "@storybook/components": "^7.0.2", - "@storybook/core-events": "^7.0.2", - "@storybook/manager-api": "^7.0.2", - "@storybook/node-logger": "^7.0.7", - "@storybook/preview-api": "^7.0.2", - "@storybook/theming": "^7.0.2", - "@storybook/types": "^7.0.2", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-styling/-/addon-styling-1.3.1.tgz", + "integrity": "sha512-5ofDihi4LxOGXFFIU5D7eGLKtK8wzNH19h58QFa1w8kCrZmARYYjiZXVB0bJrMQxU9TMy+B6aOg04vV+IGX2OA==", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.5", + "@storybook/api": "^7.0.12", + "@storybook/components": "^7.0.12", + "@storybook/core-common": "^7.0.12", + "@storybook/core-events": "^7.0.12", + "@storybook/csf-tools": "^7.0.12", + "@storybook/manager-api": "^7.0.12", + "@storybook/node-logger": "^7.0.12", + "@storybook/preview-api": "^7.0.12", + "@storybook/theming": "^7.0.12", + "@storybook/types": "^7.0.12", "css-loader": "^6.7.3", "less-loader": "^11.1.0", "postcss-loader": "^7.2.4", + "recast": "^0.23.2", "resolve-url-loader": "^5.0.0", "sass-loader": "^13.2.2", "style-loader": "^3.3.2" @@ -30236,73 +30196,73 @@ } }, "@storybook/addon-toolbars": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.0.18.tgz", - "integrity": "sha512-mwhq962o0WloHAeFjJ6BXO2nzdTo5KE2fqawPpqcB2lwXP6tvaA2tDWwgntjPCHejqWTS+ZTdO4/1xrMhWYt/g==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.0.24.tgz", + "integrity": "sha512-+nDVahs2kAojzF6RbChowJmN0z7cyD/5BGMEhBemhBWSuMVnQLLEgtQi/kOY5fUxq3z1BkqcE4LV98u5CIKgKg==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24" } }, "@storybook/addon-viewport": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.0.18.tgz", - "integrity": "sha512-aVVLBsWXfGDX3z1pc93LWWdG5RUoJbGL/JJPMZGwXdwWpP8V3OBl8D8bgPymyg+MgwhSRZZDDGgnJaVGGwZ6bQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.0.24.tgz", + "integrity": "sha512-bc3TR+feemGxVP1QQT6OsFSldHjLToJNuQAGd5EEBsDFhcMTsmitiGVoxIylqIhfioL9zauLIsk5eLZ/TYxuXQ==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", "memoizerific": "^1.11.3", "prop-types": "^15.7.2" } }, "@storybook/addons": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-7.0.18.tgz", - "integrity": "sha512-+j9ItxWoVzarbllaV4WRaJpDM3P2aC5O6F3cPn4YkG/unb6HOs11WLAqFbzZnLYZNAFvWS8PYEAtqs1BxG66YQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-7.0.24.tgz", + "integrity": "sha512-e15hORnOD0ugvOVOTyZyLJhbDTWa4G1OHVUlboazy8O4TSvAXNBdLV1wOdY5RGoGD6Z5A4iR/gZXM0qc6Fh9xg==", "dev": true, "requires": { - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/types": "7.0.18" + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/types": "7.0.24" } }, "@storybook/api": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-7.0.18.tgz", - "integrity": "sha512-gikVJBR2z7LdepljmbvbsrYgywQm3jNEEEmjG0OwYDeYNjWPuoQSffT+LoyouaaCK90d1osJLl3062OkwlIG8g==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-7.0.24.tgz", + "integrity": "sha512-rjWZgBbt43Ma5Vg2RwK9FtiF9ZkLRT+vOfDFtRL1PQkOIUlYlm33dOdPTh+HrW5QMO9cj/cchqmzU2AtgEZCyw==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/manager-api": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/manager-api": "7.0.24" } }, "@storybook/blocks": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.0.18.tgz", - "integrity": "sha512-HLsuzmUdVIeFXEP5v5vyjnEePRNYjzltwTjCKQhHAlt8/aQZmREiIMOfoMoAa1Rd+On8Ib2DUd2cN10VS18H8A==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.0.24.tgz", + "integrity": "sha512-76pe4QC3WZBVxBt/RomGubW5xzbh4uF7LVn1Vonfujf4GaHgIDzu7KtLIjgM3NmDJCsp3PNfbgA1EKzWrPQz2A==", "dev": true, "requires": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", - "@storybook/docs-tools": "7.0.18", + "@storybook/docs-tools": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "@types/lodash": "^4.14.167", "color-convert": "^2.0.1", "dequal": "^2.0.2", @@ -30317,15 +30277,15 @@ } }, "@storybook/builder-manager": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.0.18.tgz", - "integrity": "sha512-yFMm3xuYkyg2hS1uz3CkvyvLzK7qJsDPVEh7lew8GiJK1Xx8cc+FnAOlRTjWNxvhfiT296wAMCTPWv7LeoSgqQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.0.24.tgz", + "integrity": "sha512-qSehfB1yS1ch/XSUdqNaTXitboNry4aKASte+kFhM5wSJcAgGBeB5akz8pc+JiRPWozqyceYkIdTG/KcRDeojg==", "dev": true, "requires": { "@fal-works/esbuild-plugin-global-externals": "^2.1.2", - "@storybook/core-common": "7.0.18", - "@storybook/manager": "7.0.18", - "@storybook/node-logger": "7.0.18", + "@storybook/core-common": "7.0.24", + "@storybook/manager": "7.0.24", + "@storybook/node-logger": "7.0.24", "@types/ejs": "^3.1.1", "@types/find-cache-dir": "^3.2.1", "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", @@ -30341,31 +30301,31 @@ } }, "@storybook/builder-webpack5": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-7.0.18.tgz", - "integrity": "sha512-ciDOHrnChHWjikQwsM+xGz70PGfWurcezCyRPPRY0zimyHWtlug6V1Q9dJAdEAFsxqFSZA/qg7gEcZyqdlTMaA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-7.0.24.tgz", + "integrity": "sha512-gA4otfsq9yTRT2IdYKkyqUdy+60a09CRDUtM1JB8a1eLmyL4az02qZv/l6D9Ccj/w5JNcJndtJX+3thOowOWOQ==", "dev": true, "requires": { "@babel/core": "^7.12.10", - "@storybook/addons": "7.0.18", - "@storybook/api": "7.0.18", - "@storybook/channel-postmessage": "7.0.18", - "@storybook/channel-websocket": "7.0.18", - "@storybook/channels": "7.0.18", - "@storybook/client-api": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/components": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/core-events": "7.0.18", - "@storybook/core-webpack": "7.0.18", + "@storybook/addons": "7.0.24", + "@storybook/api": "7.0.24", + "@storybook/channel-postmessage": "7.0.24", + "@storybook/channel-websocket": "7.0.24", + "@storybook/channels": "7.0.24", + "@storybook/client-api": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/components": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/core-events": "7.0.24", + "@storybook/core-webpack": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preview": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/router": "7.0.18", - "@storybook/store": "7.0.18", - "@storybook/theming": "7.0.18", + "@storybook/manager-api": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preview": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/router": "7.0.24", + "@storybook/store": "7.0.24", + "@storybook/theming": "7.0.24", "@types/node": "^16.0.0", "@types/semver": "^7.3.4", "babel-loader": "^9.0.0", @@ -30392,61 +30352,60 @@ }, "dependencies": { "@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true } } }, "@storybook/channel-postmessage": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-7.0.18.tgz", - "integrity": "sha512-rpwBH5ANdPnugS6+7xG9qHSoS+aPSEnBxDKsONWFubfMTTXQuFkf/793rBbxGkoINdqh8kSdKOM2rIty6e9cmQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-7.0.24.tgz", + "integrity": "sha512-QLtLXjEeTEwBN/7pB888mBaykmRU9Jy2BitvZuLJWyHHygTYm3vYZOaGR37DT+q/6Ob5GaZ0tURZmCSNDe8IIA==", "requires": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.0.3" } }, "@storybook/channel-websocket": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-7.0.18.tgz", - "integrity": "sha512-QYsZIfe23NN4i+oIdPKHaYBehk3a/HYk57a+M2oR3Frmv8IOqc/e31uH+xx5NxnjHrTJj7Y80ZJw6EKB682S6w==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-7.0.24.tgz", + "integrity": "sha512-GKSlWx5FgMQM0TKRCSGNTxLh0YU7xmg7m6FH8b/mvhH0Uido487qcJap2Ma/WOLe8aRiZo9jJpfcbUsKBWhuMg==", "dev": true, "requires": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", "@storybook/global": "^5.0.0", "telejson": "^7.0.3" } }, "@storybook/channels": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.0.18.tgz", - "integrity": "sha512-rkA7ea0M3+dWS+71iHJdiZ5R2QuIdiVg0CgyLJHDagc1qej7pEVNhMWtppeq+X5Pwp9nkz8ZTQ7aCjTf6th0/A==" + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.0.24.tgz", + "integrity": "sha512-NZVLwMhtzy6cZrNRjshFvMAD9mQTmJDNwhohodSkM/YFCDVFhmxQk9tgizVGh9MwY3CYGJ1SI96RUejGosb49Q==" }, "@storybook/cli": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.0.18.tgz", - "integrity": "sha512-9n4J4thiCUsGSXiRc6ZysqYUaCMCrpu0/qgC+5ngfFRuMmZgUV0y5+0fmaOhT2XjsonTTgucizO82i7+ottCVg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.0.24.tgz", + "integrity": "sha512-TmHPJrcqUMAGpPKqw0PHI82m+Tyh6J8LgWjyZENpOGJlQH6SJ5caA/ho9R3pqVuMRRcnGgWt0xq1YJtDlYBN9g==", "dev": true, "requires": { "@babel/core": "^7.20.2", "@babel/preset-env": "^7.20.2", "@ndelangen/get-tarball": "^3.0.7", - "@storybook/codemod": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/core-server": "7.0.18", - "@storybook/csf-tools": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/telemetry": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/codemod": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/core-server": "7.0.24", + "@storybook/csf-tools": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/telemetry": "7.0.24", + "@storybook/types": "7.0.24", "@types/semver": "^7.3.4", - "boxen": "^5.1.2", "chalk": "^4.1.0", "commander": "^6.2.1", "cross-spawn": "^7.0.3", @@ -30485,36 +30444,36 @@ } }, "@storybook/client-api": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.0.18.tgz", - "integrity": "sha512-EdgE4om6nXZf/sDZcVMGMeKv4BPX+P3EKUfMHCHjlrbbeL0eeY8Ynf+u/wYrIYZPUodS8TEV5XchHVB8F7rLBQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.0.24.tgz", + "integrity": "sha512-D9brib29aET1peRq6Nu7iBFgE+9W7ia3KCua5/AS980RFnXgGPE9x07knTbaAOuiHxHFrmQpdFF9BvVms1GS4A==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/preview-api": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/preview-api": "7.0.24" } }, "@storybook/client-logger": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.0.18.tgz", - "integrity": "sha512-uKgFdVedYoRDZBVrE1IBdWNHDFln1IxWEeI+7ZiNSQwREG9swHpU5Fa8DceclM/oLjJRuzG1jFzv+XZY8894+Q==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.0.24.tgz", + "integrity": "sha512-4zRTb+QQ1hWaRqad/UufZNRfi2d/cf5a40My72Ct97VwjhJFE6aQ3K+hl1Xt6hh8dncDL2JK3cgziw6ElqjT0w==", "requires": { "@storybook/global": "^5.0.0" } }, "@storybook/codemod": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.0.18.tgz", - "integrity": "sha512-+9XFns29e8FpPLsqA8ZCQ3mNnIIKD3QnqGYkbkCVKi/G1fomvVQsIfsnkrYv5SobTbz29B4aNWxAaeSnO7/OGg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.0.24.tgz", + "integrity": "sha512-PukV4GRPIISuVxpMMlTilwlGXdZ7E+JZWHNVb1tTwntmxMNcby8UxyWSHjbOpA2fxXGeUCjgCpcfTymJ+hxoYw==", "dev": true, "requires": { "@babel/core": "~7.21.0", "@babel/preset-env": "~7.21.0", "@babel/types": "~7.21.2", "@storybook/csf": "^0.1.0", - "@storybook/csf-tools": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/csf-tools": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/types": "7.0.24", "cross-spawn": "^7.0.3", "globby": "^11.0.2", "jscodeshift": "^0.14.0", @@ -30700,51 +30659,53 @@ } }, "@storybook/components": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.0.18.tgz", - "integrity": "sha512-Jn1CbF9UAKt8BVaZtuhmthpcZ02VMaCFXR0ISfDXCpiMKnylmpP0+WfXcoKLzz6yS+EW8EW5S9+Qq8xgQY8H7A==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.0.24.tgz", + "integrity": "sha512-Pu7zGurCyWyiuFl2Pb5gybHA0f4blmHuVqccbMqnUw4Ew80BRu8AqfhNqN2hNdxFCx0mmy0baRGVftx76rNZ0w==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", + "@storybook/client-logger": "7.0.24", "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "memoizerific": "^1.11.3", "use-resize-observer": "^9.1.0", "util-deprecate": "^1.0.2" } }, "@storybook/core-client": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-7.0.18.tgz", - "integrity": "sha512-ueExRZx6fd9LRssgdhDJ0bL4Ir2RrbXzJz/kjIT2KgYY3l7jkhe0dpT3bOgGKjQt0f7XMFU24t/r7aDLGMB+2Q==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-7.0.24.tgz", + "integrity": "sha512-uToMHbi5EnOk+8Z941j0hrRE1h9u/QWqCmqS2FBIWrBOeREwy0AAib1/hqihzhO7OzekY5mtLTANiCpIpLHAHQ==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/preview-api": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/preview-api": "7.0.24" } }, "@storybook/core-common": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.0.18.tgz", - "integrity": "sha512-HZAB1NIK/Yv0x9poyzqYcue2tx39+MAF1mbHgGy+JJZRerO2fRShgo8f8VPH9ChbFCoJ7isL5wNhgGdg9kp2kA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.0.24.tgz", + "integrity": "sha512-FHjL2dpwDHnicLTePkiZMfO5eFxJxpTP2xmGWFQnWFTyEgh+ipcWnLVoYYXiKcc6EzKED0yebk8rAIalbzpICg==", "dev": true, "requires": { - "@storybook/node-logger": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/node-logger": "7.0.24", + "@storybook/types": "7.0.24", "@types/node": "^16.0.0", + "@types/node-fetch": "^2.6.4", "@types/pretty-hrtime": "^1.0.0", "chalk": "^4.1.0", "esbuild": "^0.17.0", "esbuild-register": "^3.4.0", - "file-system-cache": "^2.0.0", + "file-system-cache": "2.3.0", "find-up": "^5.0.0", "fs-extra": "^11.1.0", "glob": "^8.1.0", "glob-promise": "^6.0.2", "handlebars": "^4.7.7", "lazy-universal-dotenv": "^4.0.0", + "node-fetch": "^2.0.0", "picomatch": "^2.3.0", "pkg-dir": "^5.0.0", "pretty-hrtime": "^1.0.3", @@ -30816,37 +30777,36 @@ } }, "@storybook/core-events": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.0.18.tgz", - "integrity": "sha512-7gxHBQDezdKOeq/u1LL80Bwjfcwsv7XOS3yWQElcgqp+gLaYB6OwwgtkCB2yV6a6l4nep9IdPWE8G3TxIzn9xw==" + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.0.24.tgz", + "integrity": "sha512-xkf/rihCkhqMeh5EA8lVp90/mzbb2gcg6I3oeFWw2hognVcTnPXg6llhWdU4Spqd0cals7GEFmQugIILCmH8GA==" }, "@storybook/core-server": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.0.18.tgz", - "integrity": "sha512-zGSGYSoCaSXM28OYKW7zsmpo8VU1icubXLRgdF21fbMhFN1WVS+bPA5+gSkAMf8acq5RNM8uSKskh7E2YDVEqA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.0.24.tgz", + "integrity": "sha512-FJgdbtLgppFMd/RedF728I+v45TRG7s5/3RJfwgRgbq4ZEhKFzZN66MwWFeq3i5Q8ETHVwAxyVvC/JrRqAJxoA==", "dev": true, "requires": { "@aw-web-design/x-default-browser": "1.4.88", "@discoveryjs/json-ext": "^0.5.3", - "@storybook/builder-manager": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/builder-manager": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", - "@storybook/csf-tools": "7.0.18", + "@storybook/csf-tools": "7.0.24", "@storybook/docs-mdx": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/telemetry": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/manager": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/telemetry": "7.0.24", + "@storybook/types": "7.0.24", "@types/detect-port": "^1.3.0", "@types/node": "^16.0.0", "@types/node-fetch": "^2.5.7", "@types/pretty-hrtime": "^1.0.0", "@types/semver": "^7.3.4", "better-opn": "^2.1.1", - "boxen": "^5.1.2", "chalk": "^4.1.0", "cli-table3": "^0.6.1", "compression": "^1.7.4", @@ -30871,30 +30831,30 @@ }, "dependencies": { "@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true } } }, "@storybook/core-webpack": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-7.0.18.tgz", - "integrity": "sha512-U5e1r8cgZZzd/Lw9StIrACMVINCvucKm8ZfcFpPh0bjEv4+2qjo9tL3dLNh4OwKznvbzSE6pEO6cBjaphjTe1A==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-7.0.24.tgz", + "integrity": "sha512-sM0hX55uNFXfQdRMthFdY6luWmi9MG+dIj6bNPiVY2SxNenxj62P/0/R/1Ime27X/vzFbi12pqUijzPNUwiwQw==", "dev": true, "requires": { - "@storybook/core-common": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/core-common": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/types": "7.0.24", "@types/node": "^16.0.0", "ts-dedent": "^2.0.0" }, "dependencies": { "@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true } } @@ -30908,19 +30868,19 @@ } }, "@storybook/csf-plugin": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.0.18.tgz", - "integrity": "sha512-Cr/Qr4/H4JIYgbbmDjQIYuqjp6nOaZga73R3KZcuClk27B90sI2ADegMYvORgbFgSkwweNQjgak6hLoOyogAhw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.0.24.tgz", + "integrity": "sha512-+oIZCIhrRFbvplXUwJn671ZM0kgNqZ59jM9RmehJGgu5N5h1JSbBcz1edXgStNsMk9e2NJopuOKrzZGTGyi0XA==", "dev": true, "requires": { - "@storybook/csf-tools": "7.0.18", + "@storybook/csf-tools": "7.0.24", "unplugin": "^0.10.2" } }, "@storybook/csf-tools": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.0.18.tgz", - "integrity": "sha512-0IJ2qdrxleTl67FUzsEvGcy96CY0OKyERE33tAsLNbvWcabdJKpLHP+rJwbsCw4z6IlS+kkmEffeFf5qRPTwkQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.0.24.tgz", + "integrity": "sha512-RBNiXY3ht6XpcIyVgxBo7mK2t32tJuC93OO/HgcoRFClcdA8HUnlva297XpJpMqCgrcF8fPqRo+ZcLeC7vjzvw==", "dev": true, "requires": { "@babel/generator": "~7.21.1", @@ -30928,7 +30888,7 @@ "@babel/traverse": "~7.21.2", "@babel/types": "~7.21.2", "@storybook/csf": "^0.1.0", - "@storybook/types": "7.0.18", + "@storybook/types": "7.0.24", "fs-extra": "^11.1.0", "recast": "^0.23.1", "ts-dedent": "^2.0.0" @@ -30996,15 +30956,15 @@ "dev": true }, "@storybook/docs-tools": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.0.18.tgz", - "integrity": "sha512-H95dW2DquGQ75ZVrFjvznPdCxT0eW6esDnemzLJB61KitcYZrWRavfrZzFtUcpzIa84OgY5pllFYt636v11LHQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.0.24.tgz", + "integrity": "sha512-vmDHmHB1B5CWsYQ7CEtfz4vdf36VK/EZdNQUox9kdN935Dks7KSuGcDdXiRlWc78e94/A9+1mJQpyfwtn3E8fQ==", "dev": true, "requires": { "@babel/core": "^7.12.10", - "@storybook/core-common": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/core-common": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/types": "7.0.24", "@types/doctrine": "^0.0.3", "doctrine": "^3.0.0", "lodash": "^4.17.21" @@ -31024,15 +30984,15 @@ "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==" }, "@storybook/instrumenter": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-7.0.18.tgz", - "integrity": "sha512-fyQxeuVC0H+w3oyTuByE95xnAQ+l/WhUBVkHV2X+PWjg9vg9Y9JmrbNWynlvz5HLFlsY3qAWJh+ciVRVSvY5Jw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-7.0.24.tgz", + "integrity": "sha512-XQ4Whq0rqW9eFMTtRpLxcl6bCf+KO3UZYcm+H63EDn9TstDyopmqv1fDg2tmJOpqLo143F8qLVC89rI7M/lO6w==", "requires": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.0.18" + "@storybook/preview-api": "7.0.24" } }, "@storybook/jest": { @@ -31078,25 +31038,25 @@ } }, "@storybook/manager": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.0.18.tgz", - "integrity": "sha512-hasb8XDmkT9lyX2cwb3Xg0ngcNQ1QCNHKurl2YJtXowb1CvawGKokhnVUTso15NCnurolDyw/Wqka1sagfm+Mg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.0.24.tgz", + "integrity": "sha512-LsQd2cFJViwoPJ7K0A/XBWrBBhJv7F0J6+aa7qHszNmIZHVbMXyZfiX7JS3RHVs4I2kLuNpSk4X+iDG0QAafEQ==", "dev": true }, "@storybook/manager-api": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.0.18.tgz", - "integrity": "sha512-anQkm09twL96YkKGXHa+LI0+yMaY6Jxs1lRaetHdMlIqN4VHBHhizHaMgtGfH6xCTuO3WdrKTN7cZii5RH7PBQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.0.24.tgz", + "integrity": "sha512-cBpgDWq8reFgyrv4fBZlZJQyWYb9cDW0LDe476rWn/29uXNvYMNsHRwveLNgSA8Oy1NdyQCgf4ZgcYvY3wpvMA==", "dev": true, "requires": { - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/router": "7.0.18", - "@storybook/theming": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/router": "7.0.24", + "@storybook/theming": "7.0.24", + "@storybook/types": "7.0.24", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", @@ -31113,9 +31073,9 @@ "dev": true }, "@storybook/nextjs": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/nextjs/-/nextjs-7.0.18.tgz", - "integrity": "sha512-+iLHPmfoI6sIfm8NhDqWaMYJ9UVycdfYbqN9qqpoYHwvh77GmqzKxNmkqdB3AQlicXBCUvabyV5A7lX9cdEHug==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/nextjs/-/nextjs-7.0.24.tgz", + "integrity": "sha512-SQqqeSyshs58Gluc+EZrjaSWAspOZ0YRRmZK3+cepomFsm22m1phInoFi1Zcvsf5CirjIjWUbYzxgYO6OUyhKw==", "dev": true, "requires": { "@babel/plugin-proposal-class-properties": "^7.18.6", @@ -31130,13 +31090,13 @@ "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@babel/runtime": "^7.21.0", - "@storybook/addon-actions": "7.0.18", - "@storybook/builder-webpack5": "7.0.18", - "@storybook/core-common": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/preset-react-webpack": "7.0.18", - "@storybook/preview-api": "7.0.18", - "@storybook/react": "7.0.18", + "@storybook/addon-actions": "7.0.24", + "@storybook/builder-webpack5": "7.0.24", + "@storybook/core-common": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/preset-react-webpack": "7.0.24", + "@storybook/preview-api": "7.0.24", + "@storybook/react": "7.0.24", "@types/node": "^16.0.0", "css-loader": "^6.7.3", "find-up": "^5.0.0", @@ -31200,9 +31160,9 @@ } }, "@storybook/node-logger": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.0.18.tgz", - "integrity": "sha512-cIeKEBvELtoVP/5UeQ01GJWZ7wM69/9Q+R5uOtNQBlwWFcCD6AVFWMRqq7ObMvdJG/okhXSF+sDetb+BF3zvdw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.0.24.tgz", + "integrity": "sha512-gjcYnreYBBtZVF6p/cHMas4FEafPddjsLMrAfB+0lLGoRdUwWVto46BZTHQ9seY5gPW0JQydAdDGHko8/kEOXA==", "dev": true, "requires": { "@types/npmlog": "^4.1.2", @@ -31212,24 +31172,24 @@ } }, "@storybook/postinstall": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.0.18.tgz", - "integrity": "sha512-ObIwAK2UiYhXN/7UifISQgBoH5jnyxh6T8kvCw83YhC78SDOPNgIGjToJECizJ7iubtqAWtCfCT5TrGEpyLGbg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.0.24.tgz", + "integrity": "sha512-UYMXyEU4nVIKyrlUdIs3NHQmILzrN+EkEDbmeQC2WMMPw+t4GY2cDVmpx90JYYZcn7gY+cNDgQ55iiqbvlamLQ==", "dev": true }, "@storybook/preset-react-webpack": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-7.0.18.tgz", - "integrity": "sha512-ISqq+DWzxHrQUHt83+tq7TKQETQcwekUnNYKgFzN8dVgZWqRS+/PqX+7c07Qa3h/QIWgMjPA6SPN4Z12tV4qpA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-7.0.24.tgz", + "integrity": "sha512-9BI243TMv5f+CjzGVB3CFA82E2kWYhQTaRoeNKxxk7NvgiascFMATkgBjIwtGYVXL9umk8mytzulOq/oXPnscQ==", "dev": true, "requires": { "@babel/preset-flow": "^7.18.6", "@babel/preset-react": "^7.18.6", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5", - "@storybook/core-webpack": "7.0.18", - "@storybook/docs-tools": "7.0.18", - "@storybook/node-logger": "7.0.18", - "@storybook/react": "7.0.18", + "@storybook/core-webpack": "7.0.24", + "@storybook/docs-tools": "7.0.24", + "@storybook/node-logger": "7.0.24", + "@storybook/react": "7.0.24", "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", "@types/node": "^16.0.0", "@types/semver": "^7.3.4", @@ -31242,31 +31202,31 @@ }, "dependencies": { "@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true } } }, "@storybook/preview": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.0.18.tgz", - "integrity": "sha512-L53p2eo8G12U6tp7hD3mk5tdWFXLvdEyV9e7a1x9bw1LfH15K/bp8lO6U/W1kkpse7+rqWBqoTjJC1Ktm5Sxog==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.0.24.tgz", + "integrity": "sha512-rej4Wz8Qy4gVuyvg4cpQGkR4wJc3b+0Uv6EYylbmpdj2585cOhFtRBykagDVZteVU4xaLMT7YHIZRnoLmJKIgw==", "dev": true }, "@storybook/preview-api": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.0.18.tgz", - "integrity": "sha512-xxtC0gPGMn/DbwvS4ZuJaBwfFNsjUCf0yLYHFrNe6fxncbvcLZ550RuyUwYuIRfsiKrlgfa3QmmCa4JM/JesHQ==", - "requires": { - "@storybook/channel-postmessage": "7.0.18", - "@storybook/channels": "7.0.18", - "@storybook/client-logger": "7.0.18", - "@storybook/core-events": "7.0.18", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.0.24.tgz", + "integrity": "sha512-psycU07tuB5nyJvfAJiDN/9e8cjOdJ+5lrCSYC3vPzH86LxADDIN0/8xFb1CaQWcXZsADEFJGpHKWbRhjym5ew==", + "requires": { + "@storybook/channel-postmessage": "7.0.24", + "@storybook/channels": "7.0.24", + "@storybook/client-logger": "7.0.24", + "@storybook/core-events": "7.0.24", "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/types": "7.0.18", + "@storybook/types": "7.0.24", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -31278,18 +31238,18 @@ } }, "@storybook/react": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-7.0.18.tgz", - "integrity": "sha512-lumUbHYeuL3qa4SZR9K2YC4UIt1hwW19GuI/6f2HEV5gR9QHHSJHg9HD9pjcxv4fQaiG81ACZ0Sg6lyUkcJvuQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-7.0.24.tgz", + "integrity": "sha512-JAgSs8ANysBl3+cOAjFSVG3bA2V/wP6jyu7oK0jSATRQhHRjRS/tHFMA82j0j98G2sr3JXQUxNt55Qq3k2mUcg==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/core-client": "7.0.18", - "@storybook/docs-tools": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/core-client": "7.0.24", + "@storybook/docs-tools": "7.0.24", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.0.18", - "@storybook/react-dom-shim": "7.0.18", - "@storybook/types": "7.0.18", + "@storybook/preview-api": "7.0.24", + "@storybook/react-dom-shim": "7.0.24", + "@storybook/types": "7.0.24", "@types/escodegen": "^0.0.6", "@types/estree": "^0.0.51", "@types/node": "^16.0.0", @@ -31313,9 +31273,9 @@ "dev": true }, "@types/node": { - "version": "16.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", - "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", + "version": "16.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.37.tgz", + "integrity": "sha512-ql+4dw4PlPFBP495k8JzUX/oMNRI2Ei4PrMHgj8oT4VhGlYUzF4EYr0qk2fW+XBVGIrq8Zzk13m4cvyXZuv4pA==", "dev": true }, "acorn": { @@ -31348,41 +31308,41 @@ } }, "@storybook/react-dom-shim": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.0.18.tgz", - "integrity": "sha512-O1FRypR8q1katjbznnxI+NtALd2gaWa7KnTwbIDf+ddZltXHMZ8xMiEGEtAMrfXlIuqIr9UvmLRfKZC/ysuA+g==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.0.24.tgz", + "integrity": "sha512-YOP1C3dWTLYP5mPb7hNuDRIhADzz+ppfb+S22JNJ3kqm+tsyE/YtAbRf80k6QIG1LzukMpGoEnjjOPOsWsyvFQ==", "dev": true, "requires": {} }, "@storybook/router": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.0.18.tgz", - "integrity": "sha512-Mue4s/BnKgdYcsiW9yuvW3qL9k3AgYn5HIhnkBExAteyiUGdAca4IJFhArmGgFktgeLc4ecBQ7sgaCljApnbgg==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.0.24.tgz", + "integrity": "sha512-SRCV+srCZUbko/V0phVN8jY8ilrxQWWAY/gegwNlIYaNqLJSyYqIj739VDmX+deXl6rOEpFLZreClVXWiDU9+w==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", + "@storybook/client-logger": "7.0.24", "memoizerific": "^1.11.3", "qs": "^6.10.0" } }, "@storybook/store": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/store/-/store-7.0.18.tgz", - "integrity": "sha512-rvQOG7R1+r77Y9jwNqQB3EKW6D5kzIGoxqzFHd1oDqeY5+vqPXHC/J5iDrl8TZ4GES7ZMAHpkTySbY+rRQK7Ng==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/store/-/store-7.0.24.tgz", + "integrity": "sha512-T6BOXpiIAiGpQcfe0Hyu3d+8Gd0sUaVTSDXJLadfr7tqC6qmMpOuyApFu1qRfgJqh4aykUb75ESCvYWoEjwm+A==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/preview-api": "7.0.18" + "@storybook/client-logger": "7.0.24", + "@storybook/preview-api": "7.0.24" } }, "@storybook/telemetry": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.0.18.tgz", - "integrity": "sha512-JP5Z7lGU+oKjNmz2cZW5J7EerwyWBBPOU+NvvooZsymIx02ZvJ4ClmFtolJnBM7m4KoAy50JxV5NQWi+q8PicQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.0.24.tgz", + "integrity": "sha512-mLGwm3yeWlM9Srrcecrpce4m8uyazIMkHIYcBC0cD2L/JzIRzeRS3Na8QlLKz4/+Hxawm7K/pE/DBrVjvBbm8A==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.18", - "@storybook/core-common": "7.0.18", + "@storybook/client-logger": "7.0.24", + "@storybook/core-common": "7.0.24", "chalk": "^4.1.0", "detect-package-manager": "^2.0.1", "fetch-retry": "^5.0.2", @@ -31401,47 +31361,39 @@ } }, "@storybook/testing-library": { - "version": "0.0.14-next.2", - "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.0.14-next.2.tgz", - "integrity": "sha512-i/SLSGm0o978ELok/SB4Qg1sZ3zr+KuuCkzyFqcCD0r/yf+bG35aQGkFqqxfSAdDxuQom0NO02FE+qys5Eapdg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.0.tgz", + "integrity": "sha512-Ff6jNnrsosmDshgCf0Eb5Cz7IA34p/1Ps5N3Kp3598kfXpBSccSkQQvVFUXC3kIHw/isIXWPqntZuKqnWUz7Gw==", "dev": true, "requires": { - "@storybook/client-logger": "^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0", - "@storybook/instrumenter": "^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0", - "@testing-library/dom": "^8.3.0", - "@testing-library/user-event": "^13.2.1", + "@testing-library/dom": "^9.0.0", + "@testing-library/user-event": "^14.0.0", "ts-dedent": "^2.2.0" } }, "@storybook/theming": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.0.18.tgz", - "integrity": "sha512-P1gMKa/mKQHIMq0sxBIwTzAcF6v/6hrc62YmkuV62vXu+8zNV2YWbRwywqm3Q6faZEadmb/bL9+z8whaKhCL/g==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.0.24.tgz", + "integrity": "sha512-CMeCCfqffJ/D5rBl1HpAM/e5Vw0h7ucT+CLzP0ALtLrguz9ZzOiIZYgMj17KpfvWqje7HT+DwEtNkSrnJ01FNQ==", "dev": true, "requires": { "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.0.18", + "@storybook/client-logger": "7.0.24", "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3" } }, "@storybook/types": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.0.18.tgz", - "integrity": "sha512-qPop2CbvmX42/BX29YT9jIzW2TlMcMjAE+KCpcKLBiD1oT5DJ1fhMzpe6RW9HkMegkBxjWx54iamN4oHM/pwcQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.0.24.tgz", + "integrity": "sha512-SZh/XBHP1TT5bmEk0W52nT0v6fUnYwmZVls3da5noutdgOAiwL7TANtl41XrNjG+UDr8x0OE3PVVJi+LhwUaNA==", "requires": { - "@storybook/channels": "7.0.18", + "@storybook/channels": "7.0.24", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", - "file-system-cache": "^2.0.0" + "file-system-cache": "2.3.0" } }, - "@swc/core-linux-x64-gnu": { - "version": "1.3.63", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.63.tgz", - "integrity": "sha512-EAB5gkgDvStJofvdQU40hqEqjtSvtPs3PR0WupZtbLKWWCTWg76uTXQZEKNYx9r60Pt7sx1BAa3XnqgXjmcjDg==", - "optional": true - }, "@swc/helpers": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", @@ -31483,18 +31435,18 @@ } }, "@testing-library/dom": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.0.tgz", - "integrity": "sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", + "integrity": "sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", - "aria-query": "^5.0.0", + "aria-query": "5.1.3", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", + "lz-string": "^1.5.0", "pretty-format": "^27.0.2" } }, @@ -31526,13 +31478,11 @@ } }, "@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "version": "14.4.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz", + "integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==", "dev": true, - "requires": { - "@babel/runtime": "^7.12.5" - } + "requires": {} }, "@tiptap/core": { "version": "2.0.3", @@ -31541,124 +31491,123 @@ "requires": {} }, "@tiptap/extension-blockquote": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.220.tgz", - "integrity": "sha512-uE1VRU/doQzXsfsZ/JqsbSbXeZYTJnyQkSfHYA2ZYhbEM2XqDEsYkgcmZEJgunUZJpERf+3ZTfTpqaHq29iMMg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.0.3.tgz", + "integrity": "sha512-rkUcFv2iL6f86DBBHoa4XdKNG2StvkJ7tfY9GoMpT46k3nxOaMTqak9/qZOo79TWxMLYtXzoxtKIkmWsbbcj4A==", "requires": {} }, "@tiptap/extension-bold": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.220.tgz", - "integrity": "sha512-KcEuKI85Drug/cCWbDy+HxhYrD+rLXHEBG10DmKPvgPpKHG/2wOau6LwUwyV4muWR8CR2mIO+mEc3yVBD8nNwQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.0.3.tgz", + "integrity": "sha512-OGT62fMRovSSayjehumygFWTg2Qn0IDbqyMpigg/RUAsnoOI2yBZFVrdM2gk1StyoSay7gTn2MLw97IUfr7FXg==", "requires": {} }, "@tiptap/extension-bubble-menu": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.220.tgz", - "integrity": "sha512-wthyec7s0vZlTSEAAZEgoFfx/1Arwg1zxDUrrE+YAost/Yn+w4xQksz/ts5Bx90iOk2qsJ+jzzttLRV17Ku7lA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.3.tgz", + "integrity": "sha512-lPt1ELrYCuoQrQEUukqjp9xt38EwgPUwaKHI3wwt2Rbv+C6q1gmRsK1yeO/KqCNmFxNqF2p9ZF9srOnug/RZDQ==", "requires": { - "lodash": "^4.17.21", "tippy.js": "^6.3.7" } }, "@tiptap/extension-bullet-list": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.220.tgz", - "integrity": "sha512-QQ/0ZlYy6Hgb+UAc79V+fxvI+AaQf20cbKtBXaR8TIZ0x4FotSma89bKh+CIXMhFiBGXTcYBaYhl7OwACsKtxw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.3.tgz", + "integrity": "sha512-RtaLiRvZbMTOje+FW5bn+mYogiIgNxOm065wmyLPypnTbLSeHeYkoqVSqzZeqUn+7GLnwgn1shirUe6csVE/BA==", "requires": {} }, "@tiptap/extension-code": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.0.0-beta.220.tgz", - "integrity": "sha512-JKKDZoceagqVXeC1XF/gOkKhLtsbYJYV+MRDorLnQVz4tXcg/SMs5Ez7OM9MxSSior8fIbUFMNsj1/UNlG+tFw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.0.3.tgz", + "integrity": "sha512-LsVCKVxgBtkstAr1FjxN8T3OjlC76a2X8ouoZpELMp+aXbjqyanCKzt+sjjUhE4H0yLFd4v+5v6UFoCv4EILiw==", "requires": {} }, "@tiptap/extension-code-block": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.220.tgz", - "integrity": "sha512-fgA7yTfHqhBtMJF7I9FPJ6UWuZPtxOQiN45Iv9LNmFIB6YRucdpmF+daZ27sElu0a+eICZyXwVn4w4iJphifuw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.0.3.tgz", + "integrity": "sha512-F4xMy18EwgpyY9f5Te7UuF7UwxRLptOtCq1p2c2DfxBvHDWhAjQqVqcW/sq/I/WuED7FwCnPLyyAasPiVPkLPw==", "requires": {} }, "@tiptap/extension-document": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.0.0-beta.220.tgz", - "integrity": "sha512-2sja4ZvOb4iynHrzinnclCSFgLyo6fJc1fBV5fIYaOgZOYcvz9KK8fgKiq+wIpG58sJEmQ5kcwwBlkXv+NTK+g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.0.3.tgz", + "integrity": "sha512-PsYeNQQBYIU9ayz1R11Kv/kKNPFNIV8tApJ9pxelXjzcAhkjncNUazPN/dyho60mzo+WpsmS3ceTj/gK3bCtWA==", "requires": {} }, "@tiptap/extension-dropcursor": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.220.tgz", - "integrity": "sha512-BIaA4Lvb3xL9KFN+K6SO2IHqLO6hDmGN2/rGKHFaU3Eh+oiXM2G73KTSS5KIP1u872zY1RpAtswSc4kjv3cuVw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.3.tgz", + "integrity": "sha512-McthMrfusn6PjcaynJLheZJcXto8TaIW5iVitYh8qQrDXr31MALC/5GvWuiswmQ8bAXiWPwlLDYE/OJfwtggaw==", "requires": {} }, "@tiptap/extension-floating-menu": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.220.tgz", - "integrity": "sha512-+WfcBEedm82ntaVIEQAGz0Om96Rpav7a+4f7e8N4PrLKm6nZ3gBaEkZVQ6vjJ6S/1htiWCv1XosYIwRboPBG0w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.3.tgz", + "integrity": "sha512-zN1vRGRvyK3pO2aHRmQSOTpl4UJraXYwKYM009n6WviYKUNm0LPGo+VD4OAtdzUhPXyccnlsTv2p6LIqFty6Bg==", "requires": { "tippy.js": "^6.3.7" } }, "@tiptap/extension-gapcursor": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.220.tgz", - "integrity": "sha512-W5N2Ey+thufUOrs2TFGpEGBGue7ZEhcUXvxcsZlGbrjVa9Y+4rEp68Du4y7yM0hCeSj2GGwiV+uPzkc0CSDE/g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.3.tgz", + "integrity": "sha512-6I9EzzsYOyyqDvDvxIK6Rv3EXB+fHKFj8ntHO8IXmeNJ6pkhOinuXVsW6Yo7TcDYoTj4D5I2MNFAW2rIkgassw==", "requires": {} }, "@tiptap/extension-hard-break": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.220.tgz", - "integrity": "sha512-oY3454o53YNFbuokzyGzG4PdMHkIYreY3nrALioZ0SwYeoFNcGA6Zcn4rDRfdp+QvbbiHfeBTR/CpWF13HZYTg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.0.3.tgz", + "integrity": "sha512-RCln6ARn16jvKTjhkcAD5KzYXYS0xRMc0/LrHeV8TKdCd4Yd0YYHe0PU4F9gAgAfPQn7Dgt4uTVJLN11ICl8sQ==", "requires": {} }, "@tiptap/extension-heading": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.220.tgz", - "integrity": "sha512-7mrHRj++UaZ26C2Gjwb0WKWAzpiKb8TOYkVC2uMaCwaNhLDXpFEwZ7RtJRSTNBHkIGnMO46BH8Z0qlkFMmk9Jw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.0.3.tgz", + "integrity": "sha512-f0IEv5ms6aCzL80WeZ1qLCXTkRVwbpRr1qAETjg3gG4eoJN18+lZNOJYpyZy3P92C5KwF2T3Av00eFyVLIbb8Q==", "requires": {} }, "@tiptap/extension-history": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.0.0-beta.220.tgz", - "integrity": "sha512-qNL2a9UhnlmCs4y2iQYrfeMB8vEX3bHozBJanHu0PWNQJcj90R5xqorBp/bRcqZdi0kuQfxcTnGHtLUpN/U0TA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.0.3.tgz", + "integrity": "sha512-00KHIcJ8kivn2ARI6NQYphv2LfllVCXViHGm0EhzDW6NQxCrriJKE3tKDcTFCu7LlC5doMpq9Z6KXdljc4oVeQ==", "requires": {} }, "@tiptap/extension-horizontal-rule": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.220.tgz", - "integrity": "sha512-XMIs4R+4BoH5LpIxey513mZuus0XLHqjVayqtf03enmjBTLWzkixvvWLPLw4a47FJL5Q8l4REFHxjNifRzOKkg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.3.tgz", + "integrity": "sha512-SZRUSh07b/M0kJHNKnfBwBMWrZBEm/E2LrK1NbluwT3DBhE+gvwiEdBxgB32zKHNxaDEXUJwUIPNC3JSbKvPUA==", "requires": {} }, "@tiptap/extension-italic": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.220.tgz", - "integrity": "sha512-aWAgqoR8fql9fJ7T/ZrEqovkEjZXbUpvlvWEvdBDMG3id8ZTGNDpdDKdvI6J/Rl5ZGPIg1TpHJtd+UixheWQsQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.0.3.tgz", + "integrity": "sha512-cfS5sW0gu7qf4ihwnLtW/QMTBrBEXaT0sJl3RwkhjIBg/65ywJKE5Nz9ewnQHmDeT18hvMJJ1VIb4j4ze9jj9A==", "requires": {} }, "@tiptap/extension-link": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.0.0-beta.220.tgz", - "integrity": "sha512-vjEA8cE37ZZVVgPHSpttw3kbJoClb+ya/BVukDtJ1h6C7mIR1rqzNxTgpbnXJuA8xww0JOjpa5dpzEgcs294fA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.0.3.tgz", + "integrity": "sha512-H72tXQ5rkVCkAhFaf08fbEU7EBUCK0uocsqOF+4th9sOlrhfgyJtc8Jv5EXPDpxNgG5jixSqWBo0zKXQm9s9eg==", "requires": { "linkifyjs": "^4.1.0" } }, "@tiptap/extension-list-item": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.220.tgz", - "integrity": "sha512-+O0ivwxPP2l/m9PAowb2ytDT/cM5kwu0s1W5MUsHPIqf+M6ahnl4ESjhWZfDHUzvjqPq6MTbqoQLHbB1KS/N7w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.0.3.tgz", + "integrity": "sha512-p7cUsk0LpM1PfdAuFE8wYBNJ3gvA0UhNGR08Lo++rt9UaCeFLSN1SXRxg97c0oa5+Ski7SrCjIJ5Ynhz0viTjQ==", "requires": {} }, "@tiptap/extension-ordered-list": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.220.tgz", - "integrity": "sha512-j3DmxJfwmNxFfMnvO7glmGlhYeZSIUnRrKnZu2KkpD6OcGJSh9y/yfnYwcuK80XbzEG/jKKIw0M2yRveOvyVwA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.3.tgz", + "integrity": "sha512-ZB3MpZh/GEy1zKgw7XDQF4FIwycZWNof1k9WbDZOI063Ch4qHZowhVttH2mTCELuyvTMM/o9a8CS7qMqQB48bw==", "requires": {} }, "@tiptap/extension-paragraph": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.220.tgz", - "integrity": "sha512-ZGCzNGFYV4wa3l1nXtDIaYp7O6f0DrGTSl3alKkDTQe3SOmzXS2HjgWl9yPw8VXpU9W5mMGhXd+nGn/jUk+f/A==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.0.3.tgz", + "integrity": "sha512-a+tKtmj4bU3GVCH1NE8VHWnhVexxX5boTVxsHIr4yGG3UoKo1c5AO7YMaeX2W5xB5iIA+BQqOPCDPEAx34dd2A==", "requires": {} }, "@tiptap/extension-placeholder": { @@ -31668,15 +31617,15 @@ "requires": {} }, "@tiptap/extension-strike": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.220.tgz", - "integrity": "sha512-cIM2ma6mzk08pijOn+KS3ZoHWaUVsVT+OF3m6xewjwJdC0ILg9nApEOhPFrhbeDcxcPmJMlgBl/xeUrEu1HQMg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.0.3.tgz", + "integrity": "sha512-RO4/EYe2iPD6ifDHORT8fF6O9tfdtnzxLGwZIKZXnEgtweH+MgoqevEzXYdS+54Wraq4TUQGNcsYhe49pv7Rlw==", "requires": {} }, "@tiptap/extension-text": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.0.0-beta.220.tgz", - "integrity": "sha512-3tnffc2YMjNyv7Lbad6fx9wYDE/Buz8vhx76M2AOSrjYbzmTJf7mLkgdlPM0VTy7FGZD5CGgHJAgYNt5HIqPkQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.0.3.tgz", + "integrity": "sha512-LvzChcTCcPSMNLUjZe/A9SHXWGDHtvk73fR7CBqAeNU0MxhBPEBI03GFQ6RzW3xX0CmDmjpZoDxFMB+hDEtW1A==", "requires": {} }, "@tiptap/pm": { @@ -31705,38 +31654,38 @@ } }, "@tiptap/react": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.0.0-beta.220.tgz", - "integrity": "sha512-AZWaCGjm2FcJWNl1dxRCHOjGYvUV8R39L7tAcnKxHGajOHdFk8JQHc0XbVZhdBi2YgwvwEr7Tw9G2lzi9e6/fg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.0.3.tgz", + "integrity": "sha512-fiAh8Lk+/NBPAR/PE4Kc/aLiBUbUYI/CpAopz8DI9eInNyV8h8LAGa9uFILJQF/TNu0tclJ4rV0sWc7Se0FZMw==", "requires": { - "@tiptap/extension-bubble-menu": "^2.0.0-beta.220", - "@tiptap/extension-floating-menu": "^2.0.0-beta.220" + "@tiptap/extension-bubble-menu": "^2.0.3", + "@tiptap/extension-floating-menu": "^2.0.3" } }, "@tiptap/starter-kit": { - "version": "2.0.0-beta.220", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.0.0-beta.220.tgz", - "integrity": "sha512-3992NxY5sEp5xmLE/qv/yt1YkgpSpJiUlDRj02isJ0Xsxa4G6bNq+N+tN2rHB0Y8dtYVBSX2vV/DZYVX8O+Gpg==", - "requires": { - "@tiptap/core": "^2.0.0-beta.220", - "@tiptap/extension-blockquote": "^2.0.0-beta.220", - "@tiptap/extension-bold": "^2.0.0-beta.220", - "@tiptap/extension-bullet-list": "^2.0.0-beta.220", - "@tiptap/extension-code": "^2.0.0-beta.220", - "@tiptap/extension-code-block": "^2.0.0-beta.220", - "@tiptap/extension-document": "^2.0.0-beta.220", - "@tiptap/extension-dropcursor": "^2.0.0-beta.220", - "@tiptap/extension-gapcursor": "^2.0.0-beta.220", - "@tiptap/extension-hard-break": "^2.0.0-beta.220", - "@tiptap/extension-heading": "^2.0.0-beta.220", - "@tiptap/extension-history": "^2.0.0-beta.220", - "@tiptap/extension-horizontal-rule": "^2.0.0-beta.220", - "@tiptap/extension-italic": "^2.0.0-beta.220", - "@tiptap/extension-list-item": "^2.0.0-beta.220", - "@tiptap/extension-ordered-list": "^2.0.0-beta.220", - "@tiptap/extension-paragraph": "^2.0.0-beta.220", - "@tiptap/extension-strike": "^2.0.0-beta.220", - "@tiptap/extension-text": "^2.0.0-beta.220" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.0.3.tgz", + "integrity": "sha512-t4WG4w93zTpL2VxhVyJJvl3kdLF001ZrhpOuEiZqEMBMUMbM56Uiigv1CnUQpTFrjDAh3IM8hkqzAh20TYw2iQ==", + "requires": { + "@tiptap/core": "^2.0.3", + "@tiptap/extension-blockquote": "^2.0.3", + "@tiptap/extension-bold": "^2.0.3", + "@tiptap/extension-bullet-list": "^2.0.3", + "@tiptap/extension-code": "^2.0.3", + "@tiptap/extension-code-block": "^2.0.3", + "@tiptap/extension-document": "^2.0.3", + "@tiptap/extension-dropcursor": "^2.0.3", + "@tiptap/extension-gapcursor": "^2.0.3", + "@tiptap/extension-hard-break": "^2.0.3", + "@tiptap/extension-heading": "^2.0.3", + "@tiptap/extension-history": "^2.0.3", + "@tiptap/extension-horizontal-rule": "^2.0.3", + "@tiptap/extension-italic": "^2.0.3", + "@tiptap/extension-list-item": "^2.0.3", + "@tiptap/extension-ordered-list": "^2.0.3", + "@tiptap/extension-paragraph": "^2.0.3", + "@tiptap/extension-strike": "^2.0.3", + "@tiptap/extension-text": "^2.0.3" } }, "@trpc/client": { @@ -32851,15 +32800,6 @@ "dev": true, "requires": {} }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "requires": { - "string-width": "^4.1.0" - } - }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -33215,9 +33155,9 @@ "dev": true }, "schema-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", - "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", @@ -33517,36 +33457,6 @@ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" }, - "boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } - } - }, "bplist-parser": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", @@ -33985,12 +33895,6 @@ "integrity": "sha512-OL/7wZpNy9x0GBSzz3poWja84Nr7iaH8aYNsJ5Uet2BVLj6Lm1zvWpZN/yH46Vv3ae7YfHmLLMmfHj911fshJg==", "dev": true }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true - }, "cli-check-node": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/cli-check-node/-/cli-check-node-1.3.4.tgz", @@ -34495,9 +34399,9 @@ } }, "core-js-pure": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.30.2.tgz", - "integrity": "sha512-p/npFUJXXBkCCTIlEGBdghofn00jWG6ZOtdoIXSJmAu2QBvN0IqpZXWweOytcwE6cfx8ZvVUy1vw8zxhe4Y2vg==", + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.31.0.tgz", + "integrity": "sha512-/AnE9Y4OsJZicCzIe97JP5XoPKQJfTuEG43aEVLFJGOJpyqELod+pE6LEl63DfG1Mp8wX97LDaDpy1GmLEUxlg==", "dev": true }, "core-util-is": { @@ -35244,9 +35148,9 @@ "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==" }, "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", + "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", "dev": true }, "errno": { @@ -36365,9 +36269,9 @@ "dev": true }, "flow-parser": { - "version": "0.207.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.207.0.tgz", - "integrity": "sha512-s90OlXqzWj1xc4yUtqD1Gr8pGVx0/5rk9gsqPrOYF1kBAPMH4opkmzdWgQ8aNe3Pckqtwr8DlYGbfE2GnW+zsg==", + "version": "0.210.1", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.210.1.tgz", + "integrity": "sha512-M0SdOwD0wZHhk6K/AOaPReBnw2vB7p9KUFUFZHJRsU3ZMl/+WVrMpmb8AfEM6GXZ5mEssCx9vHugxxJg1ieoew==", "dev": true }, "fn.name": { @@ -37000,9 +36904,9 @@ "dev": true }, "html-entities": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.4.tgz", - "integrity": "sha512-TtiHkpRBqP40OzizVWjwBPBsiqchEZxAg/nys6D6lIpdoVLo7sWZ/5Sf/s4UaBHQ6pzUzEr3NiItvEoO46sPtQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", "dev": true }, "html-escaper": { @@ -37041,9 +36945,9 @@ "dev": true }, "html-webpack-plugin": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz", - "integrity": "sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", "dev": true, "requires": { "@types/html-minifier-terser": "^6.0.0", @@ -39060,6 +38964,12 @@ "unist-util-visit": "^2.0.0" } }, + "mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "dev": true + }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", @@ -39072,12 +38982,12 @@ "devOptional": true }, "memfs": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.2.tgz", - "integrity": "sha512-4kbWXbVZ+LU4XFDS2CuA7frnwz2HxCMB/0yOXc86q7aCQrfWKkL11t6al1e2CsVC7uhnBNTQ1TfUsAxVauO9IQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "requires": { - "fs-monkey": "^1.0.3" + "fs-monkey": "^1.0.4" } }, "memoizerific": { @@ -39258,6 +39168,12 @@ "ufo": "^1.1.1" } }, + "mockdate": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", + "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", + "dev": true + }, "mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -39479,9 +39395,9 @@ } }, "node-fetch-native": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.1.1.tgz", - "integrity": "sha512-9VvspTSUp2Sxbl+9vbZTlFGq9lHwE8GDVVekxx6YsNd1YH59sb3Ba8v3Y3cD8PkLNcileGGcA21PFjVl0jzDaw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.2.0.tgz", + "integrity": "sha512-5IAMBTl9p6PaAjYCnMv5FmqIF6GcZnawAVnzaCG0rX2aYZJ4CxEkZNtVPuTRug7fL7wyM5BQYTlAzcyMPi6oTQ==", "dev": true }, "node-int64": { @@ -41051,9 +40967,9 @@ } }, "react-inspector": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.1.tgz", - "integrity": "sha512-cxKSeFTf7jpSSVddm66sKdolG90qURAX3g1roTeaN6x0YEbtWc8JpmFN9+yIqLNH2uEkYerWLtJZIXRIFuBKrg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", + "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==", "dev": true, "requires": {} }, @@ -41400,14 +41316,6 @@ "github-slugger": "^1.0.0", "mdast-util-to-string": "^1.0.0", "unist-util-visit": "^2.0.0" - }, - "dependencies": { - "mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", - "dev": true - } } }, "remove-accents": { @@ -42072,12 +41980,12 @@ "dev": true }, "storybook": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.0.18.tgz", - "integrity": "sha512-FXMmTiomSlLPTHty7vGLr0prPf6pCV07EwAmNOYYYTskitEYV0R7hlhawByd7HuobjIhHvSTKesa1Whl86zLNA==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.0.24.tgz", + "integrity": "sha512-ilQDM4+KaNO8s5jU4EnS68JWb9KaLR0+xTNa/BEXQa18SnSt/qZYORXtqispwkyuL/9xwaMVwtS+st7JOucNWA==", "dev": true, "requires": { - "@storybook/cli": "7.0.18" + "@storybook/cli": "7.0.24" } }, "stream-browserify": { @@ -43397,9 +43305,9 @@ "dev": true }, "schema-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", - "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", @@ -43411,9 +43319,9 @@ } }, "webpack-hot-middleware": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.3.tgz", - "integrity": "sha512-IK/0WAHs7MTu1tzLTjio73LjS3Ov+VvBKQmE8WPlJutgG5zT6Urgq/BbAdRrHTRpyzK0dvAvFh1Qg98akxgZpA==", + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.4.tgz", + "integrity": "sha512-IRmTspuHM06aZh98OhBJtqLpeWFM8FXJS5UYpKYxCJzyFoyWj1w6VGFfomZU7OPA55dMLrQK0pRT1eQ3PACr4w==", "dev": true, "requires": { "ansi-html-community": "0.0.8", @@ -43513,15 +43421,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - } - }, "winston": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.9.0.tgz", diff --git a/package.json b/package.json index e39ce6a5..a35d8c04 100644 --- a/package.json +++ b/package.json @@ -44,16 +44,17 @@ "@hookform/resolvers": "^3.1.1", "@opengovsg/design-system-react": "^1.2.0", "@opengovsg/sgid-client": "^2.0.0", + "@paralleldrive/cuid2": "^2.2.1", "@prisma/client": "4.15.0", "@sendgrid/mail": "^7.7.0", "@storybook/jest": "^0.1.0", "@tanstack/react-query": "^4.29.1", "@tanstack/react-query-devtools": "^4.32.0", - "@tiptap/extension-link": "^2.0.0-beta.220", - "@tiptap/extension-placeholder": "^2.0.3", - "@tiptap/pm": "^2.0.0-beta.220", - "@tiptap/react": "^2.0.0-beta.220", - "@tiptap/starter-kit": "^2.0.0-beta.220", + "@tiptap/extension-link": "2.0.3", + "@tiptap/extension-placeholder": "2.0.3", + "@tiptap/pm": "2.0.3", + "@tiptap/react": "2.0.3", + "@tiptap/starter-kit": "2.0.3", "@trpc/client": "^10.31.0", "@trpc/next": "^10.31.0", "@trpc/react-query": "^10.31.0", @@ -64,8 +65,8 @@ "iron-session": "^6.3.1", "jotai": "^2.2.0", "lodash": "^4.17.21", - "next": "^13.4.7", "nanoid": "^4.0.2", + "next": "^13.4.7", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.45.2", @@ -80,14 +81,14 @@ "devDependencies": { "@chakra-ui/cli": "^2.4.1", "@playwright/test": "^1.33.0", - "@storybook/addon-essentials": "^7.0.18", - "@storybook/addon-interactions": "^7.0.18", - "@storybook/addon-links": "^7.0.18", - "@storybook/addon-styling": "^1.0.8", - "@storybook/blocks": "^7.0.18", - "@storybook/nextjs": "^7.0.18", - "@storybook/react": "^7.0.18", - "@storybook/testing-library": "^0.0.14-next.2", + "@storybook/addon-essentials": "^7.0.24", + "@storybook/addon-interactions": "^7.0.24", + "@storybook/addon-links": "^7.0.24", + "@storybook/addon-styling": "^1.3.1", + "@storybook/blocks": "^7.0.24", + "@storybook/nextjs": "^7.0.24", + "@storybook/react": "^7.0.24", + "@storybook/testing-library": "^0.2.0", "@types/eslint": "^8.40.0", "@types/node": "^18.15.11", "@types/react": "^18.0.34", @@ -102,6 +103,7 @@ "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-storybook": "^0.6.12", + "mockdate": "^3.0.5", "msw": "^1.2.2", "msw-storybook-addon": "^1.8.0", "msw-trpc": "^1.3.3", @@ -109,7 +111,7 @@ "prettier": "^2.8.7", "prisma": "4.15.0", "start-server-and-test": "^2.0.0", - "storybook": "^7.0.18", + "storybook": "^7.0.24", "tsx": "^3.12.7", "typescript": "^4.8.3", "vite": "^4.1.5", diff --git a/prisma/migrations/20230411055801_add_username/migration.sql b/prisma/migrations/20230411055801_add_username/migration.sql new file mode 100644 index 00000000..9c1abd3c --- /dev/null +++ b/prisma/migrations/20230411055801_add_username/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - A unique constraint covering the columns `[username]` on the table `User` will be added. If there are existing duplicate values, this will fail. + +*/ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "username" STRING; + +-- CreateIndex +CREATE UNIQUE INDEX "User_username_key" ON "User"("username"); diff --git a/prisma/migrations/20230523090610_add_images_to_posts/migration.sql b/prisma/migrations/20230523090610_add_images_to_posts/migration.sql new file mode 100644 index 00000000..5e79343f --- /dev/null +++ b/prisma/migrations/20230523090610_add_images_to_posts/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Post" ADD COLUMN "images" STRING[]; diff --git a/prisma/migrations/20230626092920_remove_read_post_feature/migration.sql b/prisma/migrations/20230626092920_remove_read_post_feature/migration.sql new file mode 100644 index 00000000..aad627b6 --- /dev/null +++ b/prisma/migrations/20230626092920_remove_read_post_feature/migration.sql @@ -0,0 +1,14 @@ +/* + Warnings: + + - You are about to drop the `ReadPosts` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- DropForeignKey +ALTER TABLE "ReadPosts" DROP CONSTRAINT "ReadPosts_post_id_fkey"; + +-- DropForeignKey +ALTER TABLE "ReadPosts" DROP CONSTRAINT "ReadPosts_user_id_fkey"; + +-- DropTable +DROP TABLE "ReadPosts"; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 2d7b5a2e..aeebe24e 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -8,7 +8,7 @@ datasource db { generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextSearch", "filteredRelationCount"] + previewFeatures = ["fullTextSearch"] } model VerificationToken { @@ -25,8 +25,8 @@ model Post { contentHtml String @map("content_html") @db.Text authorId String @map("author_id") author User @relation(fields: [authorId], references: [id], onDelete: Cascade) + images String[] likes LikedPosts[] - readBy ReadPosts[] // This features the self-relation Prisma concept, specifically a one-to-many self relation. // https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations parentPostId String? @map("parent_post_id") @@ -49,17 +49,6 @@ model Post { @@index([createdAt]) } -model ReadPosts { - post Post @relation(fields: [postId], references: [id], onDelete: NoAction, onUpdate: NoAction) - postId String @map("post_id") - user User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction) - userId String @map("user_id") - updatedAt DateTime @default(now()) @updatedAt @map("updated_at") - - @@id([postId, userId]) - @@index([postId]) -} - model LikedPosts { post Post @relation(fields: [postId], references: [id], onDelete: NoAction, onUpdate: NoAction) postId String @map("post_id") @@ -73,13 +62,13 @@ model LikedPosts { model User { id String @id @default(cuid()) name String? + username String? @unique email String? @unique emailVerified DateTime? @map("email_verified") image String? bio String? posts Post[] likedPosts LikedPosts[] - readPosts ReadPosts[] accounts Accounts[] } diff --git a/src/components/AppNavbar.tsx b/src/components/AppNavbar.tsx index a674c537..1282be41 100644 --- a/src/components/AppNavbar.tsx +++ b/src/components/AppNavbar.tsx @@ -5,53 +5,51 @@ import { Link, Menu, } from '@opengovsg/design-system-react' +import Image from 'next/image' import NextLink from 'next/link' -import { useRouter } from 'next/router' - -import { useUser } from '~/features/profile/api' +import { ADMIN_NAVBAR_HEIGHT } from '~/constants/layouts' +import { useMe } from '~/features/me/api' +import { SETTINGS_PROFILE } from '~/lib/routes' export const AppNavbar = (): JSX.Element => { - const { user, logout } = useUser() - const { pathname } = useRouter() + const { me, logout } = useMe() return ( - <> + - - Starter Kit - {/* + OGP Logo */} + /> - + Edit profile @@ -59,6 +57,6 @@ export const AppNavbar = (): JSX.Element => { - + ) } diff --git a/src/components/AppProviders/FeatureProvider.tsx b/src/components/AppProviders/FeatureProvider.tsx new file mode 100644 index 00000000..957ea6f9 --- /dev/null +++ b/src/components/AppProviders/FeatureProvider.tsx @@ -0,0 +1,53 @@ +import { + createContext, + type FC, + type PropsWithChildren, + useContext, +} from 'react' +import { env } from '~/env.mjs' + +type FeatureContextProps = { + storage: boolean + sgid: boolean +} + +// Exported for testing. +export const FeatureContext = createContext( + undefined +) + +/** + * Provider component that wraps your app and makes the available features available to any + * child component that calls `useFeatures()`. + */ +export const FeatureProvider: FC = ({ children }) => { + const features = useProvideFeatures() + + return ( + + {children} + + ) +} + +/** + * Hook for components nested in FeatureProvider component to get the current feature object. + */ +export const useFeatures = (): FeatureContextProps => { + const context = useContext(FeatureContext) + if (!context) { + throw new Error( + `useFeatures must be used within a FeatureProvider component` + ) + } + return context +} + +// Provider hook that creates auth object and handles state +const useProvideFeatures = () => { + // Return the user object and auth methods + return { + storage: !!env.NEXT_PUBLIC_ENABLE_STORAGE, + sgid: !!env.NEXT_PUBLIC_ENABLE_SGID, + } +} diff --git a/src/components/AppProviders/index.ts b/src/components/AppProviders/index.ts new file mode 100644 index 00000000..876c78bd --- /dev/null +++ b/src/components/AppProviders/index.ts @@ -0,0 +1 @@ +export * from './FeatureProvider' diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 2f979047..183e6fb3 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -3,6 +3,19 @@ import { Avatar as ChakraAvatar, } from '@chakra-ui/react' -export const Avatar = (props: ChakraAvatarProps) => { - return +interface AvatarProps extends Omit { + src?: string | null + name?: string | null +} + +export const Avatar = ({ src, name, ...props }: AvatarProps) => { + return ( + + ) } diff --git a/src/components/BackBannerButton.tsx b/src/components/BackBannerButton.tsx new file mode 100644 index 00000000..4a167e95 --- /dev/null +++ b/src/components/BackBannerButton.tsx @@ -0,0 +1,17 @@ +import { Icon } from '@chakra-ui/react' +import { Link, type LinkProps } from '@opengovsg/design-system-react' +import { BiLeftArrowAlt } from 'react-icons/bi' + +export type BackBannerButtonProps = Omit + +export const BackBannerButton = ({ + children, + ...props +}: BackBannerButtonProps): JSX.Element => { + return ( + + + {children} + + ) +} diff --git a/src/components/BackBannerLink.tsx b/src/components/BackBannerLink.tsx new file mode 100644 index 00000000..a1fa3f31 --- /dev/null +++ b/src/components/BackBannerLink.tsx @@ -0,0 +1,20 @@ +import { Icon } from '@chakra-ui/react' +import { Link, type LinkProps } from '@opengovsg/design-system-react' +import NextLink, { type LinkProps as NextLinkProps } from 'next/link' +import { BiLeftArrowAlt } from 'react-icons/bi' + +export interface BackBannerLinkProps + extends Omit, + Omit {} + +export const BackBannerLink = ({ + children, + ...props +}: BackBannerLinkProps): JSX.Element => { + return ( + + + {children} + + ) +} diff --git a/src/components/Breadcrumb/Crumb.tsx b/src/components/Breadcrumb/Crumb.tsx deleted file mode 100644 index 3f84ddd4..00000000 --- a/src/components/Breadcrumb/Crumb.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { - BreadcrumbItem, - type BreadcrumbItemProps, - BreadcrumbLink, -} from '@chakra-ui/react' -import Link from 'next/link' - -export interface CrumbProps extends BreadcrumbItemProps { - href: string - label: string - last?: boolean -} -// Props are required as Breadcrumb parent injects props into its crumb children. -export const Crumb = ({ href, label, last = false, ...props }: CrumbProps) => { - if (last) { - return ( - - - {label} - - - ) - } - - return ( - - - {label} - - - ) -} diff --git a/src/components/Breadcrumb/index.ts b/src/components/Breadcrumb/index.ts deleted file mode 100644 index b0d1ecaf..00000000 --- a/src/components/Breadcrumb/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Crumb' diff --git a/src/components/ChevronMenuButton.tsx b/src/components/ChevronMenuButton.tsx deleted file mode 100644 index 8a40b0bd..00000000 --- a/src/components/ChevronMenuButton.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { MenuButton, type MenuButtonProps } from '@chakra-ui/react' -import { - Button, - type ButtonProps, - BxChevronDown, - BxChevronUp, -} from '@opengovsg/design-system-react' -import { useMemo } from 'react' - -export interface ChevronMenuButtonProps extends MenuButtonProps, ButtonProps { - isOpen?: boolean - showChevron?: boolean -} - -export const ChevronMenuButton = ({ - showChevron = true, - isOpen, - ...props -}: ChevronMenuButtonProps): JSX.Element => { - const rightIcon = useMemo(() => { - if (!showChevron) { - return undefined - } - - return isOpen ? ( - - ) : ( - - ) - }, [isOpen, showChevron]) - - return ( - - ) -} diff --git a/src/components/DashSidebar.tsx b/src/components/DashSidebar.tsx index 039e42ea..b0882329 100644 --- a/src/components/DashSidebar.tsx +++ b/src/components/DashSidebar.tsx @@ -1,27 +1,70 @@ -import { Flex } from '@chakra-ui/react' +import { Box, Flex } from '@chakra-ui/react' +import { + SidebarContainer, + SidebarItem, + useIsMobile, +} from '@opengovsg/design-system-react' import Link from 'next/link' import { useRouter } from 'next/router' -import { BiMessageSquareEdit } from 'react-icons/bi' -import { Sidebar } from './Sidebar' +import { useMemo } from 'react' +import { BiFace, BiHomeSmile } from 'react-icons/bi' +import { ADMIN_DASHBAR_WIDTHS, ADMIN_NAVBAR_HEIGHT } from '~/constants/layouts' +import { useMe } from '~/features/me/api' +import { HOME, PROFILE, SETTINGS_PROFILE } from '~/lib/routes' export const DashSidebar = () => { - const { pathname } = useRouter() + const isMobile = useIsMobile() + const { me } = useMe() + const { pathname, query } = useRouter() + + const isProfileActive = useMemo(() => { + if (pathname === SETTINGS_PROFILE) return true + if ( + pathname.startsWith(`${PROFILE}/[username]`) && + query.username === me?.username + ) + return true + }, [pathname, query.username, me?.username]) return ( - - , - props: { - isActive: pathname === '/dashboard', - as: Link, - href: '/dashboard', - }, - }, - ]} - /> - + + + + + {isMobile ? '' : 'Home'} + + + {isMobile ? '' : 'Profile'} + + + + ) } diff --git a/src/components/ErrorBoundary/index.ts b/src/components/ErrorBoundary/index.ts new file mode 100644 index 00000000..42897517 --- /dev/null +++ b/src/components/ErrorBoundary/index.ts @@ -0,0 +1 @@ +export { default } from './ErrorBoundary' diff --git a/src/components/FileButton.tsx b/src/components/FileButton.tsx new file mode 100644 index 00000000..069e9132 --- /dev/null +++ b/src/components/FileButton.tsx @@ -0,0 +1,131 @@ +import { assignRef, useMergeRefs } from '@chakra-ui/react' +import { + useRef, + forwardRef, + type ComponentPropsWithoutRef, + type ReactNode, + type ForwardedRef, + type ReactElement, + type ChangeEventHandler, +} from 'react' + +export interface FileButtonProps { + value: Multiple extends true ? File[] : File | null + /** Called when files are picked */ + onChange(payload: Multiple extends true ? File[] : File | null): void + + /** Function that receives button props and returns react node that should be rendered */ + children(props: { onClick(): void }): ReactNode + + /** Determines whether user can pick more than one file */ + multiple?: Multiple + + /** Determines whether picked files should be appended to existing value instead of replacing */ + append?: Multiple extends boolean ? boolean : never + + /** File input accept attribute, for example, "image/png,image/jpeg" */ + accept?: string + + /** Input name attribute */ + name?: string + + /** Input form attribute */ + form?: string + + /** Function that should be called when value changes to null or empty array */ + resetRef?: ForwardedRef<() => void> + + /** Disables file picker */ + disabled?: boolean + + /** + * Specifies that, optionally, a new file should be captured, + * and which device should be used to capture that new media of a type defined + * by the accept attribute. */ + capture?: boolean | 'user' | 'environment' + + /** Spreads props to input element used to capture files */ + inputProps?: ComponentPropsWithoutRef<'input'> +} + +type FileButtonComponent = (( + props: FileButtonProps +) => ReactElement) & { displayName?: string } + +export const FileButton: FileButtonComponent = forwardRef< + HTMLInputElement, + FileButtonProps +>( + ( + { + onChange, + children, + multiple = false, + accept, + name, + form, + resetRef, + disabled, + capture, + inputProps, + value, + append, + ...others + }, + ref + ) => { + const inputRef = useRef() + + const onClick = () => { + !disabled && inputRef?.current?.click() + } + + const handleChange: ChangeEventHandler = (event) => { + if (multiple) { + const nextFiles = Array.from(event.currentTarget.files || []) + if (append) { + // @ts-expect-error type inference is not working here + onChange([...(value || []), ...nextFiles]) + } else { + // @ts-expect-error type inference is not working here + onChange(Array.from(event.currentTarget.files || [])) + } + } else { + onChange(event.currentTarget.files?.[0] || null) + } + } + + const reset = () => { + if (inputRef.current) { + inputRef.current.value = '' + } + } + + assignRef(resetRef, reset) + const mergedRefs = useMergeRefs(ref, inputRef) + + return ( + <> + {children({ onClick, ...others })} + + ((event.target as HTMLInputElement).value = '')} + onChange={handleChange} + ref={mergedRefs} + name={name} + form={form} + capture={capture} + {...inputProps} + /> + + ) + } +) as any + +FileButton.displayName = 'FileButton' diff --git a/src/components/ImageAttachmentButton/AttachmentFileInfo.tsx b/src/components/ImageAttachmentButton/AttachmentFileInfo.tsx new file mode 100644 index 00000000..eb8fd1f2 --- /dev/null +++ b/src/components/ImageAttachmentButton/AttachmentFileInfo.tsx @@ -0,0 +1,88 @@ +import { useEffect, useMemo, useState } from 'react' +import { + Flex, + forwardRef, + Image, + Stack, + Text, + VisuallyHidden, +} from '@chakra-ui/react' +import { dataAttr } from '@chakra-ui/utils' +import { useImageAttachmentButtonStyles } from './ImageAttachmentButtonContext' +import { getReadableFileSize, IconButton } from '@opengovsg/design-system-react' +import { BiTrash } from 'react-icons/bi' + +export interface AttachmentFileInfoProps { + file: File + handleRemoveFile: () => void + imagePreview?: 'small' | 'large' + isDisabled?: boolean + isReadOnly?: boolean +} + +export const AttachmentFileInfo = forwardRef( + ({ file, handleRemoveFile, imagePreview, isDisabled, isReadOnly }, ref) => { + const [previewSrc, setPreviewSrc] = useState('') + const styles = useImageAttachmentButtonStyles() + const readableFileSize = useMemo( + () => getReadableFileSize(file.size), + [file.size] + ) + + useEffect(() => { + let objectUrl = '' + // create the preview + if (file.type.startsWith('image/')) { + objectUrl = URL.createObjectURL(file) + setPreviewSrc(objectUrl) + } + + // free memory when ever this component is unmounted + return () => URL.revokeObjectURL(objectUrl) + }, [file]) + + return ( + + + File attached: {file.name} with file size of {readableFileSize} + + {imagePreview && previewSrc && ( + uploaded image preview + )} + + + + {file.name} + + + {readableFileSize} + + + } + onClick={handleRemoveFile} + isDisabled={isDisabled || isReadOnly} + /> + + + ) + } +) + +AttachmentFileInfo.displayName = 'AttachmentFileInfo' diff --git a/src/components/ImageAttachmentButton/ImageAttachmentButton.tsx b/src/components/ImageAttachmentButton/ImageAttachmentButton.tsx new file mode 100644 index 00000000..eb88528f --- /dev/null +++ b/src/components/ImageAttachmentButton/ImageAttachmentButton.tsx @@ -0,0 +1,75 @@ +import { + Box, + forwardRef, + SimpleGrid, + Stack, + useMultiStyleConfig, +} from '@chakra-ui/react' +import { Button } from '@opengovsg/design-system-react' +import { BiImageAdd } from 'react-icons/bi' +import { FileButton } from '~/components/FileButton' +import { ACCEPTED_FILE_TYPES } from '~/utils/image' +import { AttachmentFileInfo } from './AttachmentFileInfo' +import { ImageAttachmentButtonStylesProvider } from './ImageAttachmentButtonContext' + +export interface ImageAttachmentButtonProps { + onChange: (value: File[]) => void + value?: File[] +} + +export const ImageAttachmentButton = forwardRef< + ImageAttachmentButtonProps, + 'button' +>(({ onChange, value = [] }, ref): JSX.Element => { + const styles = useMultiStyleConfig('Attachment', { imagePreview: 'large' }) + + return ( + + + + {value.map((file, index) => ( + { + onChange(value.filter((_, i) => i !== index)) + }} + /> + ))} + + + {(fileButtonProps) => { + return ( + + + + ) + }} + + + + ) +}) + +ImageAttachmentButton.displayName = 'ImageAttachmentButton' diff --git a/src/components/ImageAttachmentButton/ImageAttachmentButtonContext.tsx b/src/components/ImageAttachmentButton/ImageAttachmentButtonContext.tsx new file mode 100644 index 00000000..284e55f4 --- /dev/null +++ b/src/components/ImageAttachmentButton/ImageAttachmentButtonContext.tsx @@ -0,0 +1,6 @@ +import { createStylesContext } from '@chakra-ui/react' + +export const [ + ImageAttachmentButtonStylesProvider, + useImageAttachmentButtonStyles, +] = createStylesContext('Attachment') diff --git a/src/components/ImageAttachmentButton/index.ts b/src/components/ImageAttachmentButton/index.ts new file mode 100644 index 00000000..e27aaeb4 --- /dev/null +++ b/src/components/ImageAttachmentButton/index.ts @@ -0,0 +1 @@ +export * from './ImageAttachmentButton' diff --git a/src/components/NavigationalTabs/NavigationalTab.tsx b/src/components/NavigationalTabs/NavigationalTab.tsx new file mode 100644 index 00000000..b8946b99 --- /dev/null +++ b/src/components/NavigationalTabs/NavigationalTab.tsx @@ -0,0 +1,43 @@ +import type { ComponentProps } from 'react' +import { chakra } from '@chakra-ui/react' +import NextLink from 'next/link' +import { useNavigationalTabListStyles } from './NavigationalTabList' + +interface NavigationTabProps extends ComponentProps { + isActive?: boolean + isDisabled?: boolean +} + +/** Must be nested inside NavigationTabList component, uses styles provided by that component. */ +export const NavigationTab = ({ + isActive, + isDisabled, + children, + ...props +}: NavigationTabProps) => { + const styles = useNavigationalTabListStyles() + + if (isDisabled) { + return ( + + {children} + + ) + } + + return ( + + {children} + + ) +} diff --git a/src/components/NavigationalTabs/NavigationalTabList.tsx b/src/components/NavigationalTabs/NavigationalTabList.tsx new file mode 100644 index 00000000..cc703c58 --- /dev/null +++ b/src/components/NavigationalTabs/NavigationalTabList.tsx @@ -0,0 +1,37 @@ +import { + createStylesContext, + forwardRef, + Stack, + type StackProps, + type TabsProps, + useMultiStyleConfig, +} from '@chakra-ui/react' + +interface NavigationTabListProps extends StackProps { + variant?: TabsProps['variant'] +} + +export const [NavigationalTabListStylesProvider, useNavigationalTabListStyles] = + createStylesContext('NavigationalTabList') + +/** Component to be styled as a tab list, but used for routing instead of conditionally showing tab panels. */ +export const NavigationTabList = forwardRef( + ({ onMouseDown, children, variant, ...props }, ref): JSX.Element => { + const styles = useMultiStyleConfig('Tabs', { ...props, variant }) + + return ( + + + {children} + + + ) + } +) diff --git a/src/components/NavigationalTabs/index.ts b/src/components/NavigationalTabs/index.ts new file mode 100644 index 00000000..5367aa51 --- /dev/null +++ b/src/components/NavigationalTabs/index.ts @@ -0,0 +1,2 @@ +export * from './NavigationalTab' +export * from './NavigationalTabList' diff --git a/src/components/NextImage.tsx b/src/components/NextImage.tsx deleted file mode 100644 index c51a3f4f..00000000 --- a/src/components/NextImage.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { type FC, useState } from 'react' - -import Image, { type ImageProps } from 'next/image' - -import { Skeleton, Box, type BoxProps } from '@chakra-ui/react' - -type Props = Omit & - BoxProps & { - alt: string - fallbackSrc?: string - } - -export const NextImage: FC = (props) => { - const { - src, - alt, - width, - height, - fallbackSrc = '', - bgGradient, - priority, - quality, - ...rest - } = props - const [isLoaded, setIsLoaded] = useState(false) - const [isError, setIsError] = useState(false) - const handleLoad = (result: { - naturalWidth: number - naturalHeight: number - }) => { - if (result.naturalWidth === 0) setIsError(true) - else setIsLoaded(true) - } - const handleError = () => setIsError(true) - return ( - - - {alt} - - - - ) -} diff --git a/src/components/ResponsiveButton.tsx b/src/components/ResponsiveButton.tsx new file mode 100644 index 00000000..2cca860a --- /dev/null +++ b/src/components/ResponsiveButton.tsx @@ -0,0 +1,11 @@ +import { useBreakpointValue } from '@chakra-ui/react' +import { type ButtonProps, Button } from '@opengovsg/design-system-react' + +export const ResponsiveButton = (props: ButtonProps): JSX.Element => { + const isFullWidth = useBreakpointValue({ + base: true, + md: false, + }) + + return - - ) -} diff --git a/src/components/Sidebar/SidebarContainer.tsx b/src/components/Sidebar/SidebarContainer.tsx deleted file mode 100644 index acaac167..00000000 --- a/src/components/Sidebar/SidebarContainer.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { type FC, type PropsWithChildren } from 'react' -import { Flex, type FlexProps, useMultiStyleConfig } from '@chakra-ui/react' - -import { SidebarProvider } from './SidebarContext' -import { SidebarStylesProvider } from './SidebarStylesContext' - -export interface SidebarContainerProps extends FlexProps { - /** - * If true, the sidebar will be collapsed and the label text will be hidden. - * @note If value is not `undefined`, the label text will be clamped to a single line for smoother expansion animation. - */ - collapsed?: boolean -} - -export const SidebarContainer: FC> = ({ - children, - collapsed, - ...flexProps -}) => { - const styles = useMultiStyleConfig('Sidebar', {}) - - return ( - - - {children} - - - ) -} diff --git a/src/components/Sidebar/SidebarContext.tsx b/src/components/Sidebar/SidebarContext.tsx deleted file mode 100644 index 9dae6434..00000000 --- a/src/components/Sidebar/SidebarContext.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import { createContext, useContext, useMemo } from 'react' -import { - type SystemStyleObject, - useControllableState, - useDisclosure, -} from '@chakra-ui/react' - -export interface SidebarContextProps { - collapsed?: boolean - onToggleCollapse?: (collapsed: boolean) => void - children?: - | React.ReactNode - | ((props: SidebarContextReturn) => React.ReactNode) -} - -export interface SidebarContextReturn { - collapsed: boolean - onToggleCollapse: () => void - labelStyles: SystemStyleObject - containerStyles: SystemStyleObject -} - -const SidebarContext = createContext( - undefined -) - -export const SidebarProvider = ({ - children, - ...props -}: SidebarContextProps) => { - const value = useProvideSidebar(props) - return ( - - {typeof children === 'function' ? children(value) : children} - - ) -} - -export const useSidebarContext = () => { - const context = useContext(SidebarContext) - if (!context) { - throw new Error('useSidebar must be used within a SidebarProvider') - } - return context -} - -export const useProvideSidebar = ({ - collapsed: collapsedProp, - onToggleCollapse: onToggleCollapseProp, -}: SidebarContextProps): SidebarContextReturn => { - const [_collapsed, _onSetCollapsed] = useControllableState({ - value: onToggleCollapseProp ? collapsedProp : undefined, - onChange: onToggleCollapseProp, - defaultValue: collapsedProp, - }) - - const { isOpen: expanded, onToggle: onToggleCollapse } = useDisclosure({ - id: 'sidebar', - isOpen: !_collapsed, - onOpen: () => _onSetCollapsed(false), - onClose: () => _onSetCollapsed(true), - }) - - const labelStyles: SystemStyleObject = useMemo(() => { - if (!expanded) { - return { - opacity: 0, - } - } - return { - opacity: 1, - } - }, [expanded]) - - const containerStyles: SystemStyleObject = useMemo(() => { - if (!expanded) { - return { - transition: 'width 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms', - width: '3.5rem', - } - } - return { - width: '100%', - transition: 'width 225ms cubic-bezier(0.4, 0, 0.6, 1) 0ms', - } - }, [expanded]) - - return { - labelStyles, - containerStyles, - collapsed: !expanded, - onToggleCollapse, - } -} diff --git a/src/components/Sidebar/SidebarItem.tsx b/src/components/Sidebar/SidebarItem.tsx deleted file mode 100644 index 3553388d..00000000 --- a/src/components/Sidebar/SidebarItem.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { useMemo } from 'react' -import { forwardRef, Text } from '@chakra-ui/react' -import { dataAttr } from '@chakra-ui/utils' -import { cloneDeep, mergeWith } from 'lodash' - -import { useSidebarContext } from './SidebarContext' -import { useSidebarStyles } from './SidebarStylesContext' -import type { BaseSidebarItem } from './types' -import { Button, type ButtonProps } from '@opengovsg/design-system-react' - -export interface SidebarItemProps extends BaseSidebarItem, ButtonProps { - isActive?: boolean - root?: boolean -} - -export const SidebarItem = forwardRef( - ({ isActive, label, icon, as, root, ...props }, ref): JSX.Element => { - const styles = useSidebarStyles() - const { labelStyles, collapsed } = useSidebarContext() - - const itemStyles = useMemo(() => { - return mergeWith( - cloneDeep(styles.item), - cloneDeep(root ? styles.parent : styles.child) - ) - }, [root, styles.child, styles.item, styles.parent]) - - return ( - - ) - } -) diff --git a/src/components/Sidebar/SidebarSection.tsx b/src/components/Sidebar/SidebarSection.tsx deleted file mode 100644 index 1854bfc1..00000000 --- a/src/components/Sidebar/SidebarSection.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { type FC, type PropsWithChildren } from 'react' -import { type StackProps, VStack } from '@chakra-ui/react' -import { merge } from 'lodash' - -import { useSidebarContext } from './SidebarContext' - -export interface SidebarSectionProps extends StackProps { - /** - * If true, the sidebar will be collapsed and the label text will be hidden. - * @note If value is not `undefined`, the label text will be clamped to a single line for smoother expansion animation. - */ - collapsed?: boolean -} - -export const SidebarSection: FC> = ({ - children, - sx, - ...props -}) => { - const { containerStyles } = useSidebarContext() - - return ( - - {children} - - ) -} diff --git a/src/components/Sidebar/SidebarStylesContext.tsx b/src/components/Sidebar/SidebarStylesContext.tsx deleted file mode 100644 index 32495d81..00000000 --- a/src/components/Sidebar/SidebarStylesContext.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { createStylesContext } from '@chakra-ui/react' - -const [SidebarStylesProvider, useSidebarStyles] = createStylesContext('Sidebar') - -export { SidebarStylesProvider, useSidebarStyles } diff --git a/src/components/Sidebar/index.ts b/src/components/Sidebar/index.ts deleted file mode 100644 index 9130e633..00000000 --- a/src/components/Sidebar/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Sidebar' diff --git a/src/components/Sidebar/types.ts b/src/components/Sidebar/types.ts deleted file mode 100644 index f25e115c..00000000 --- a/src/components/Sidebar/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { AccordionProps } from '@chakra-ui/react' -import { type ButtonProps } from '@opengovsg/design-system-react' - -export type BaseSidebarItem = { - label: string - icon?: JSX.Element -} - -export interface SidebarChildItem extends BaseSidebarItem { - props?: ButtonProps -} - -export interface SidebarNestableItem extends BaseSidebarItem { - subItems: SidebarItemType[] - props?: AccordionProps & { - [key: string]: any - } -} - -export type SidebarItemType = SidebarNestableItem | SidebarChildItem diff --git a/src/components/SkeletonPostList.tsx b/src/components/SkeletonPostList.tsx new file mode 100644 index 00000000..063af7c0 --- /dev/null +++ b/src/components/SkeletonPostList.tsx @@ -0,0 +1,33 @@ +import { Stack, StackDivider } from '@chakra-ui/react' +import { useMemo } from 'react' +import { APP_GRID_COLUMN } from '~/constants/layouts' +import { SkeletonPost } from '~/features/posts/components' + +interface SkeletonPostListProps { + /** + * Number of skeleton posts to render + * @default 10 + */ + count?: number +} + +export const SkeletonPostList = ({ + count = 10, +}: SkeletonPostListProps): JSX.Element => { + const skeletonPosts = useMemo(() => { + return Array.from({ length: count }, (_, index) => ( + + )) + }, [count]) + + return ( + } + gridColumn={APP_GRID_COLUMN} + flexDir="column" + > + {skeletonPosts} + + ) +} diff --git a/src/components/Svg/BusStop.tsx b/src/components/Svg/BusStop.tsx new file mode 100644 index 00000000..731b58e2 --- /dev/null +++ b/src/components/Svg/BusStop.tsx @@ -0,0 +1,136 @@ +import { chakra } from '@chakra-ui/react' +import { type SVGProps } from 'react' + +export const BusStop = chakra((props: SVGProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + +)) diff --git a/src/components/Svg/index.ts b/src/components/Svg/index.ts index 942345df..cd2d15d1 100644 --- a/src/components/Svg/index.ts +++ b/src/components/Svg/index.ts @@ -1 +1,2 @@ export * from './OgpLogo' +export * from './BusStop' diff --git a/src/constants/layouts.ts b/src/constants/layouts.ts new file mode 100644 index 00000000..5e1a7047 --- /dev/null +++ b/src/constants/layouts.ts @@ -0,0 +1,19 @@ +export const APP_GRID_TEMPLATE_COLUMN = { + base: 'repeat(4, 1fr)', + md: 'repeat(10, 1fr)', +} +export const APP_GRID_COLUMN = { base: '1 / 5', md: '1 / 12', lg: '3 / 8' } + +export const ADMIN_NAVBAR_HEIGHT = '3.5rem' + +export const ADMIN_DASHBAR_WIDTHS = { + base: '2.75rem', + md: '10.5rem', + lg: '13.5rem', +} + +export const APP_GRID_TEMPLATE_AREA = { + base: `${ADMIN_NAVBAR_HEIGHT} 1fr / ${ADMIN_DASHBAR_WIDTHS.base} 1fr`, + md: `${ADMIN_NAVBAR_HEIGHT} 1fr / ${ADMIN_DASHBAR_WIDTHS.md} 1fr`, + lg: `${ADMIN_NAVBAR_HEIGHT} 1fr / ${ADMIN_DASHBAR_WIDTHS.lg} 1fr`, +} diff --git a/src/constants/routes.ts b/src/constants/routes.ts deleted file mode 100644 index aee11f89..00000000 --- a/src/constants/routes.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const FEEDBACK = '/feedback' -export const SIGN_IN = '/sign-in' diff --git a/src/env.mjs b/src/env.mjs index efbebc0b..42e3b997 100644 --- a/src/env.mjs +++ b/src/env.mjs @@ -26,7 +26,9 @@ const baseR2Schema = z.object({ R2_ACCOUNT_ID: z.string().optional(), R2_SECRET_ACCESS_KEY: z.string().optional(), R2_PUBLIC_HOSTNAME: z.string().optional(), - R2_AVATARS_BUCKET_NAME: z.string().optional(), + R2_BUCKET_NAME: z.string().optional(), + R2_AVATARS_DIRECTORY: z.string().optional(), + R2_IMAGES_DIRECTORY: z.string().optional(), }) const r2ServerSchema = z.discriminatedUnion('NEXT_PUBLIC_ENABLE_STORAGE', [ @@ -137,7 +139,9 @@ const processEnv = { SESSION_SECRET: process.env.SESSION_SECRET, R2_ACCESS_KEY_ID: process.env.R2_ACCESS_KEY_ID, R2_ACCOUNT_ID: process.env.R2_ACCOUNT_ID, - R2_AVATARS_BUCKET_NAME: process.env.R2_AVATARS_BUCKET_NAME, + R2_BUCKET_NAME: process.env.R2_BUCKET_NAME, + R2_AVATARS_DIRECTORY: process.env.R2_AVATARS_DIRECTORY, + R2_IMAGES_DIRECTORY: process.env.R2_IMAGES_DIRECTORY, R2_PUBLIC_HOSTNAME: process.env.R2_PUBLIC_HOSTNAME, R2_SECRET_ACCESS_KEY: process.env.R2_SECRET_ACCESS_KEY, SGID_CLIENT_ID: process.env.SGID_CLIENT_ID, diff --git a/src/features/feedback/api/actionState.ts b/src/features/feedback/api/actionState.ts deleted file mode 100644 index 099269e3..00000000 --- a/src/features/feedback/api/actionState.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { atom } from 'jotai' -import { type RouterOutput } from '~/utils/trpc' - -type ActionState = { - post: RouterOutput['post']['byId'] | null - state: 'edit' | 'delete' | null -} - -const INITIAL_STATE: ActionState = { - post: null, - state: null, -} - -export const actionStateAtom = atom(INITIAL_STATE) - -export const resetActionAtom = atom(null, (_get, set) => { - set(actionStateAtom, INITIAL_STATE) -}) diff --git a/src/features/feedback/api/types.ts b/src/features/feedback/api/types.ts deleted file mode 100644 index 7ed17595..00000000 --- a/src/features/feedback/api/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type FeedbackRole = 'owner' | 'viewer' diff --git a/src/features/feedback/api/useFilterFeedback.ts b/src/features/feedback/api/useFilterFeedback.ts deleted file mode 100644 index 4bc2a27b..00000000 --- a/src/features/feedback/api/useFilterFeedback.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { useRouter } from 'next/router' -import { useCallback, useMemo } from 'react' -import { z } from 'zod' -import { listPostsInputSchema } from '~/schemas/post' -import { trpc } from '~/utils/trpc' - -const LIST_POSTS_PARAMS_SCHEMA = z.object({ - order: listPostsInputSchema.shape.order.catch( - listPostsInputSchema.shape.order._def.defaultValue() - ), - filter: listPostsInputSchema.shape.filter.catch( - listPostsInputSchema.shape.filter._def.defaultValue() - ), - limit: listPostsInputSchema.shape.limit.catch(null), - cursor: listPostsInputSchema.shape.cursor.catch(null), -}) - -const FILTER_VAL_TO_LABEL = { - all: 'All feedback', - draft: 'Draft', - unread: 'Unread', - replied: 'Replied', - repliedByMe: 'Replied by me', - unreplied: 'Unreplied', - unrepliedByMe: 'Unreplied by me', -} -const FILTER_OPTIONS = Object.entries(FILTER_VAL_TO_LABEL).map( - ([value, label]) => ({ - value, - label, - }) -) - -const ORDER_VAL_TO_LABEL = { - asc: 'Newest', - desc: 'Oldest', -} - -const ORDER_OPTIONS = Object.entries(ORDER_VAL_TO_LABEL).map( - ([value, label]) => ({ - value, - label, - }) -) - -export const useFilterFeedback = () => { - const router = useRouter() - - const { order, filter, cursor, limit } = useMemo(() => { - return LIST_POSTS_PARAMS_SCHEMA.parse(router.query) - }, [router.query]) - - const handleFilterChange = useCallback( - async (filter: string | string[]) => { - router.query.filter = filter - await router.push(router) - }, - [router] - ) - - const handleOrderChange = useCallback( - async (order: string | string[]) => { - router.query.order = order - await router.push(router) - }, - [router] - ) - - const [filteredFeedback] = trpc.post.list.useSuspenseQuery( - { order, filter, cursor, limit }, - { keepPreviousData: true } - ) - - return { - filteredFeedback, - filter: { - value: filter, - label: FILTER_VAL_TO_LABEL[filter], - options: FILTER_OPTIONS, - }, - handleFilterChange, - order: { - value: order, - label: ORDER_VAL_TO_LABEL[order], - options: ORDER_OPTIONS, - }, - handleOrderChange, - } -} diff --git a/src/features/feedback/components/FeedbackActionsModal/DeleteFeedbackContent.tsx b/src/features/feedback/components/FeedbackActionsModal/DeleteFeedbackContent.tsx deleted file mode 100644 index 35141d5d..00000000 --- a/src/features/feedback/components/FeedbackActionsModal/DeleteFeedbackContent.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { - Button, - ButtonGroup, - ModalBody, - ModalContent, - ModalFooter, - ModalHeader, -} from '@chakra-ui/react' -import { ModalCloseButton } from '@opengovsg/design-system-react' -import { useAtomValue } from 'jotai' -import { useCallback } from 'react' -import { trpc } from '~/utils/trpc' -import { actionStateAtom } from '../../api/actionState' - -interface FeedbackContentProps { - onClose: () => void -} - -export const DeleteFeedbackContent = ({ onClose }: FeedbackContentProps) => { - const { post } = useAtomValue(actionStateAtom) - const utils = trpc.useContext() - const deleteMutation = trpc.post.delete.useMutation({ - onSuccess: async () => { - await utils.post.list.invalidate() - onClose() - }, - }) - - const handleDelete = useCallback(() => { - if (!post) return - return deleteMutation.mutate({ - id: post.id, - }) - }, [deleteMutation, post]) - - return ( - - - Delete feedback? - This action cannot be undone - - - - - - - - ) -} diff --git a/src/features/feedback/components/FeedbackActionsModal/EditFeedbackContent.tsx b/src/features/feedback/components/FeedbackActionsModal/EditFeedbackContent.tsx deleted file mode 100644 index 290ee94b..00000000 --- a/src/features/feedback/components/FeedbackActionsModal/EditFeedbackContent.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { - ModalContent, - ModalHeader, - ModalBody, - ModalFooter, - Button, - FormControl, -} from '@chakra-ui/react' -import { - FormErrorMessage, - ModalCloseButton, -} from '@opengovsg/design-system-react' -import { useAtomValue } from 'jotai' -import { Controller } from 'react-hook-form' -import { RichText } from '~/components/RichText' -import { useZodForm } from '~/lib/form' -import { editPostSchema } from '~/schemas/post' -import { trpc } from '~/utils/trpc' -import { actionStateAtom } from '../../api/actionState' - -interface FeedbackContentProps { - onClose: () => void -} - -export const EditFeedbackContent = ({ onClose }: FeedbackContentProps) => { - const { post } = useAtomValue(actionStateAtom) - const utils = trpc.useContext() - - const editMutation = trpc.post.edit.useMutation({ - onSuccess: async () => { - await utils.post.list.invalidate() - onClose() - }, - }) - - const { - formState: { errors }, - handleSubmit, - setValue, - control, - } = useZodForm({ - schema: editPostSchema.omit({ id: true }), - defaultValues: { - contentHtml: post?.contentHtml, - content: post?.content, - }, - }) - - const handleEditFeedback = handleSubmit((values) => { - if (!post) return - return editMutation.mutate({ - id: post.id, - ...values, - }) - }) - - return ( - - - Edit feedback - - - ( - { - onChange(value) - setValue('content', rawValue ?? '') - }} - /> - )} - /> - {errors.contentHtml?.message} - - - - - - - ) -} diff --git a/src/features/feedback/components/FeedbackActionsModal/FeedbackActionsModal.tsx b/src/features/feedback/components/FeedbackActionsModal/FeedbackActionsModal.tsx deleted file mode 100644 index b9bade08..00000000 --- a/src/features/feedback/components/FeedbackActionsModal/FeedbackActionsModal.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Modal, ModalOverlay } from '@chakra-ui/react' -import { useAtomValue, useSetAtom } from 'jotai' -import { useCallback } from 'react' -import { actionStateAtom, resetActionAtom } from '../../api/actionState' -import { DeleteFeedbackContent } from './DeleteFeedbackContent' -import { EditFeedbackContent } from './EditFeedbackContent' - -export const FeedbackActionsModal = (): JSX.Element | null => { - const { post, state } = useAtomValue(actionStateAtom) - const resetState = useSetAtom(resetActionAtom) - - const handleClose = useCallback(() => resetState(), [resetState]) - - return ( - - - {state === 'delete' && } - {state === 'edit' && } - - ) -} diff --git a/src/features/feedback/components/FeedbackActionsModal/index.ts b/src/features/feedback/components/FeedbackActionsModal/index.ts deleted file mode 100644 index e5d3eb8d..00000000 --- a/src/features/feedback/components/FeedbackActionsModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { FeedbackActionsModal } from './FeedbackActionsModal' diff --git a/src/features/feedback/components/FeedbackComment.tsx b/src/features/feedback/components/FeedbackComment.tsx deleted file mode 100644 index 4d5d095a..00000000 --- a/src/features/feedback/components/FeedbackComment.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Avatar, Box, Stack, Text } from '@chakra-ui/react' -import { useMemo } from 'react' -import { RichText } from '~/components/RichText' -import type { RouterOutput } from '~/utils/trpc' -import { format } from 'date-fns' - -type PostByIdOutput = Pick< - RouterOutput['post']['byId'], - 'author' | 'contentHtml' | 'createdAt' -> - -interface FeedbackCommentProps { - post?: PostByIdOutput -} - -export const FeedbackComment = ({ post }: FeedbackCommentProps) => { - const prettyDate = useMemo(() => { - if (!post) return '' - return format(new Date(post.createdAt), 'dd MMM yyyy, hh:mmaaa') - }, [post]) - - return ( - - - - - - - {`${post?.author.name}, ${prettyDate}`} - - - - - ) -} diff --git a/src/features/feedback/components/FeedbackCommentRichText.tsx b/src/features/feedback/components/FeedbackCommentRichText.tsx deleted file mode 100644 index f7df4e12..00000000 --- a/src/features/feedback/components/FeedbackCommentRichText.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { RichText } from '~/components/RichText' -import { useZodForm } from '~/lib/form' -import { trpc } from '~/utils/trpc' - -import { - Box, - ButtonGroup, - FormControl, - FormErrorMessage, -} from '@chakra-ui/react' -import { Button, useToast } from '@opengovsg/design-system-react' -import { Controller } from 'react-hook-form' -import { addReplySchema } from '~/schemas/thread' -import { BiSend } from 'react-icons/bi' - -interface FeedbackCommentRichTextProps { - postId: string -} - -export const FeedbackCommentRichText = ({ - postId, -}: FeedbackCommentRichTextProps): JSX.Element => { - const toast = useToast({ - status: 'error', - }) - - const utils = trpc.useContext() - const mutation = trpc.thread.reply.useMutation({ - onSuccess: async () => { - reset() - // refetches posts after a comment is added - await utils.post.list.invalidate() - await utils.post.byId.invalidate({ id: postId }) - }, - onError: (error) => { - toast({ description: error.message }) - }, - }) - - const { - formState: { errors }, - handleSubmit, - setValue, - control, - reset, - } = useZodForm({ - schema: addReplySchema.omit({ postId: true }), - }) - - const handleSubmitFeedback = handleSubmit((values) => { - return mutation.mutateAsync({ ...values, postId }) - }) - - return ( - - - ( - { - onChange(value) - setValue('content', rawValue ?? '') - }} - /> - )} - /> - {errors.contentHtml?.message} - - - - - - ) -} diff --git a/src/features/feedback/components/FeedbackHeader.tsx b/src/features/feedback/components/FeedbackHeader.tsx deleted file mode 100644 index 78736125..00000000 --- a/src/features/feedback/components/FeedbackHeader.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Stack, Text, Icon } from '@chakra-ui/react' -import { BiPlus } from 'react-icons/bi' -import { trpc } from '~/utils/trpc' -import { Button } from '@opengovsg/design-system-react' -import NextLink from 'next/link' -import { FeedbackUncleSvgr } from './FeedbackUncleSvgr' - -export const FeedbackHeader = () => { - const [counts] = trpc.post.unreadCount.useSuspenseQuery() - - return ( - - - - - - {counts?.unreadCount ?? 0} - {' '} - unread feedback of {counts?.totalCount ?? 0} - - - - - ) -} diff --git a/src/features/feedback/components/FeedbackNavbar.tsx b/src/features/feedback/components/FeedbackNavbar.tsx deleted file mode 100644 index 28917f74..00000000 --- a/src/features/feedback/components/FeedbackNavbar.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Breadcrumb, Flex } from '@chakra-ui/react' - -import { Crumb, type CrumbProps } from '~/components/Breadcrumb' - -const DEFAULT_FEEDBACK_CRUMBS: CrumbProps[] = [ - { - label: 'All feedback', - href: '/dashboard', - }, - { - label: 'New feedback', - last: true, - href: '/feedback/new', - }, -] - -interface FeedbackNavbarProps { - crumbs?: CrumbProps[] -} - -export const FeedbackNavbar = ({ - crumbs = DEFAULT_FEEDBACK_CRUMBS, -}: FeedbackNavbarProps): JSX.Element => { - return ( - - - {crumbs.map((crumb, index) => ( - - ))} - - - ) -} diff --git a/src/features/feedback/components/FeedbackRowMenu.tsx b/src/features/feedback/components/FeedbackRowMenu.tsx deleted file mode 100644 index dd26d0c1..00000000 --- a/src/features/feedback/components/FeedbackRowMenu.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { MenuButton, MenuItem, MenuList } from '@chakra-ui/react' -import { IconButton, Menu } from '@opengovsg/design-system-react' -import { useSetAtom } from 'jotai' -import { BiDotsHorizontal } from 'react-icons/bi' -import { type RouterOutput } from '~/utils/trpc' -import { actionStateAtom } from '../api/actionState' -import { type FeedbackRole } from '../api/types' - -interface FeedbackRowMenuProps { - role: FeedbackRole - feedback: RouterOutput['post']['list']['items'][number] -} - -const FeedbackRowMenuItems = ({ - role, - feedback, -}: FeedbackRowMenuProps): JSX.Element => { - const setState = useSetAtom(actionStateAtom) - - if (role === 'owner') { - return ( - - { - setState({ - post: feedback, - state: 'edit', - }) - }} - > - Edit - - { - setState({ - post: feedback, - state: 'delete', - }) - }} - > - Delete - - - ) - } - return -} - -export const FeedbackRowMenu = (props: FeedbackRowMenuProps): JSX.Element => { - return ( - - } - /> - - - ) -} diff --git a/src/features/feedback/components/FeedbackUncleSvgr.tsx b/src/features/feedback/components/FeedbackUncleSvgr.tsx deleted file mode 100644 index be925f4b..00000000 --- a/src/features/feedback/components/FeedbackUncleSvgr.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { chakra } from '@chakra-ui/react' -import { type SVGProps } from 'react' - -export const FeedbackUncleSvgr = chakra((props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - -)) diff --git a/src/features/feedback/components/TeamFeedbackFilterBar.tsx b/src/features/feedback/components/TeamFeedbackFilterBar.tsx deleted file mode 100644 index 5b974838..00000000 --- a/src/features/feedback/components/TeamFeedbackFilterBar.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { - Box, - MenuItemOption, - MenuList, - MenuOptionGroup, - Menu, -} from '@chakra-ui/react' -import { ChevronMenuButton } from '~/components/ChevronMenuButton' -import { useFilterFeedback } from '../api/useFilterFeedback' - -interface FilterSelectProps { - selection: { - value: string - label: string - options: { label: string; value: string }[] - } - onChange: (value: string | string[]) => void - isDisabled?: boolean -} -const FilterSelect = ({ - selection, - onChange, - isDisabled, -}: FilterSelectProps) => { - return ( - - {({ isOpen }) => ( - <> - - {selection.label} - - - - {selection.options.map((option) => ( - - {option.label} - - ))} - - - - )} - - ) -} - -export const TeamFeedbackFilterBar = (): JSX.Element => { - const { filter, order, handleFilterChange, handleOrderChange } = - useFilterFeedback() - - return ( - - - - - ) -} diff --git a/src/features/feedback/components/TeamFeedbackList.tsx b/src/features/feedback/components/TeamFeedbackList.tsx deleted file mode 100644 index 3eb19e2e..00000000 --- a/src/features/feedback/components/TeamFeedbackList.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Box, Stack, StackDivider } from '@chakra-ui/react' -import { useFilterFeedback } from '../api/useFilterFeedback' -import { TeamFeedbackRow } from './TeamFeedbackRow' - -export const TeamFeedbackList = (): JSX.Element => { - const { filteredFeedback } = useFilterFeedback() - - return ( - } spacing={0}> - {filteredFeedback?.items.map((feedback) => ( - - - - ))} - - ) -} diff --git a/src/features/feedback/components/TeamFeedbackListSkeleton.tsx b/src/features/feedback/components/TeamFeedbackListSkeleton.tsx deleted file mode 100644 index 9117eaab..00000000 --- a/src/features/feedback/components/TeamFeedbackListSkeleton.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { - Box, - Flex, - Skeleton, - SkeletonCircle, - SkeletonText, - Stack, - StackDivider, -} from '@chakra-ui/react' - -const TeamFeedbackRowSkeleton = () => { - return ( - - - - - - - - ) -} - -export const TeamFeedbackListSkeleton = (): JSX.Element => { - return ( - }> - - - - - - - ) -} diff --git a/src/features/feedback/components/TeamFeedbackRow.tsx b/src/features/feedback/components/TeamFeedbackRow.tsx deleted file mode 100644 index 88820258..00000000 --- a/src/features/feedback/components/TeamFeedbackRow.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Avatar, Box, Flex, Grid, Text } from '@chakra-ui/react' -import Link from 'next/link' -import { FEEDBACK } from '~/constants/routes' -import { type RouterOutput } from '~/utils/trpc' -import { FeedbackRowMenu } from './FeedbackRowMenu' - -interface TeamFeedbackRowProps { - feedback: RouterOutput['post']['list']['items'][number] -} - -export const TeamFeedbackRow = ({ feedback }: TeamFeedbackRowProps) => { - return ( - - {!feedback.read && ( - - )} - - - - - {feedback.author.name} - - - - {feedback.content} - - - - {feedback.createdAt.toDateString()} - - - {`${feedback._count.replies} replies` || 'No replies yet'} - - - - ) -} diff --git a/src/features/feedback/components/index.ts b/src/features/feedback/components/index.ts deleted file mode 100644 index 0a70325d..00000000 --- a/src/features/feedback/components/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './FeedbackNavbar' -export * from './TeamFeedbackList' -export * from './FeedbackComment' -export * from './FeedbackActionsModal' -export * from './FeedbackUncleSvgr' diff --git a/src/features/home/components/EmptyPostList.tsx b/src/features/home/components/EmptyPostList.tsx new file mode 100644 index 00000000..e37a02b4 --- /dev/null +++ b/src/features/home/components/EmptyPostList.tsx @@ -0,0 +1,11 @@ +import { Stack, Text } from '@chakra-ui/react' +import { BusStop } from '~/components/Svg' + +export const EmptyPostList = (): JSX.Element => { + return ( + + There aren't any posts yet + + + ) +} diff --git a/src/features/home/components/NewPostBanner.tsx b/src/features/home/components/NewPostBanner.tsx new file mode 100644 index 00000000..53efdbe0 --- /dev/null +++ b/src/features/home/components/NewPostBanner.tsx @@ -0,0 +1,13 @@ +import { Stack, Text } from '@chakra-ui/react' +import { NewPostModalButton } from '~/features/posts/components' + +export const NewPostBanner = (): JSX.Element => { + return ( + + + What’s on your mind? + + + + ) +} diff --git a/src/features/home/components/PostList.tsx b/src/features/home/components/PostList.tsx new file mode 100644 index 00000000..d384661b --- /dev/null +++ b/src/features/home/components/PostList.tsx @@ -0,0 +1,25 @@ +import { Post } from '~/features/posts/components' +import { trpc } from '~/utils/trpc' +import { EmptyPostList } from './EmptyPostList' +import { Stack, StackDivider } from '@chakra-ui/react' +import { APP_GRID_COLUMN } from '~/constants/layouts' + +export const PostList = (): JSX.Element => { + const [data] = trpc.post.list.useSuspenseQuery({}) + + if (data.items.length === 0) { + return + } + return ( + } + gridColumn={APP_GRID_COLUMN} + flexDir="column" + > + {data.items.map((post) => ( + + ))} + + ) +} diff --git a/src/features/home/components/index.ts b/src/features/home/components/index.ts new file mode 100644 index 00000000..924adff4 --- /dev/null +++ b/src/features/home/components/index.ts @@ -0,0 +1,2 @@ +export * from './NewPostBanner' +export * from './PostList' diff --git a/src/features/landing/components/AppPublicHeader.tsx b/src/features/landing/components/AppPublicHeader.tsx index 3bbba641..fd948933 100644 --- a/src/features/landing/components/AppPublicHeader.tsx +++ b/src/features/landing/components/AppPublicHeader.tsx @@ -6,7 +6,7 @@ import { useIsMobile, } from '@opengovsg/design-system-react' import NextLink from 'next/link' -import { SIGN_IN } from '~/constants/routes' +import { SIGN_IN } from '~/lib/routes' import { AppGrid } from '~/templates/AppGrid' type PublicHeaderLinkProps = { @@ -63,7 +63,7 @@ export const AppPublicHeader = ({ publicHeaderLinks, }: AppPublicHeaderProps): JSX.Element => { return ( - + { return ( - {image && ( - {description} - )} + {image && {description}} {title} diff --git a/src/features/landing/components/LandingSection.tsx b/src/features/landing/components/LandingSection.tsx index bfc87eec..f81e99dd 100644 --- a/src/features/landing/components/LandingSection.tsx +++ b/src/features/landing/components/LandingSection.tsx @@ -4,10 +4,9 @@ import { AppGrid } from '~/templates/AppGrid' export const LandingSection: FC = ({ bg, children, ...props }) => { return ( - + { - const [user] = trpc.me.get.useSuspenseQuery(undefined, { +export const useMe = ({ redirectTo = '', redirectIfFound = false } = {}) => { + const [me] = trpc.me.get.useSuspenseQuery(undefined, { onSuccess: async () => { if (redirectIfFound) { await Router.push(redirectTo) } }, }) - const logoutMutation = trpc.auth.logout.useMutation() const logout = useCallback( (redirectToSignIn = true) => { return logoutMutation.mutate(undefined, { onSuccess: async () => { - if (redirectToSignIn) await Router.push('/sign-in') + if (redirectToSignIn) { + await Router.push('/sign-in') + } }, }) }, [logoutMutation] ) - return { user, logout } + return { me, logout } } diff --git a/src/features/posts/api/index.ts b/src/features/posts/api/index.ts new file mode 100644 index 00000000..98be6903 --- /dev/null +++ b/src/features/posts/api/index.ts @@ -0,0 +1 @@ +export * from './useUploadImagesMutation' diff --git a/src/features/posts/api/useUploadImagesMutation.ts b/src/features/posts/api/useUploadImagesMutation.ts new file mode 100644 index 00000000..0ec513c2 --- /dev/null +++ b/src/features/posts/api/useUploadImagesMutation.ts @@ -0,0 +1,40 @@ +import { useMutation } from '@tanstack/react-query' +import { trpc } from '~/utils/trpc' +import wretch from 'wretch' +import { type AcceptedImageFileTypes, ACCEPTED_FILE_TYPES } from '~/utils/image' + +export const useUploadImagesMutation = () => { + // Pre-upload: Create a mutation to presign the upload request + const presignImageUploadMutation = trpc.storage.presignPostImage.useMutation() + + const uploadImagesMutation = useMutation(async (images?: File[]) => { + if (!images) return + const presignMetadata = await Promise.all( + images.map((image) => { + if (!ACCEPTED_FILE_TYPES.some((type) => type === image.type)) { + throw new Error( + `File type ${image.type} is not supported. Please upload an image.` + ) + } + return presignImageUploadMutation.mutateAsync({ + fileContentType: image.type as AcceptedImageFileTypes, + }) + }) + ) + + // Upload all images in parallel + const keys = await Promise.all( + images.map(async (image, index) => { + const presign = presignMetadata[index] + if (!presign) throw new Error('No presign generated') + const { url, key } = presign + + await wretch(url).content(image.type).put(image).res() + return key + }) + ) + return keys + }) + + return uploadImagesMutation +} diff --git a/src/features/posts/components/AddCommentModal/AddCommentModal.tsx b/src/features/posts/components/AddCommentModal/AddCommentModal.tsx new file mode 100644 index 00000000..5a571aba --- /dev/null +++ b/src/features/posts/components/AddCommentModal/AddCommentModal.tsx @@ -0,0 +1,149 @@ +import { + ModalBody, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Stack, + type ModalProps, +} from '@chakra-ui/react' +import { + Button, + ModalCloseButton, + useToast, +} from '@opengovsg/design-system-react' +import { ResponsiveModal } from '~/components/ResponsiveModal' +import { useZodForm } from '~/lib/form' +import { trpc, type RouterOutput } from '~/utils/trpc' +import { useUploadImagesMutation } from '../../api' +import { clientAddReplySchema } from '../../schemas/clientAddPostSchema' +import { ComposePost } from '../ComposePost' +import { PostView } from '../Post/PostView' +import { ResponsiveModalButtonGroup } from '~/components/ResponsiveModalButtonGroup' +import { ResponsiveButton } from '~/components/ResponsiveButton' + +interface AddCommentModalProps extends Pick { + parentPost: RouterOutput['post']['byUser']['posts'][number] + onSuccess?: () => void + allowImageUpload?: boolean +} + +export const AddCommentModal = ({ + isOpen, + onClose: onCloseProp, + parentPost, + allowImageUpload, + onSuccess, +}: AddCommentModalProps) => { + const toast = useToast({ + status: 'success', + }) + + const utils = trpc.useContext() + + const uploadImagesMutation = useUploadImagesMutation() + + const formMethods = useZodForm({ + schema: clientAddReplySchema, + }) + const { handleSubmit, reset, watch } = formMethods + + const watchedContent = watch('content') + + const replyThreadMutation = trpc.thread.reply.useMutation({ + onSuccess: async () => { + toast({ description: 'Your reply was sent' }) + onSuccess?.() + reset() + onClose() + await utils.post.byId.invalidate({ id: parentPost.id }) + }, + }) + + const handleSubmitReply = handleSubmit(async ({ images, ...rest }) => { + return uploadImagesMutation.mutate(images, { + onSuccess: (uploadedImageKeys) => { + return replyThreadMutation.mutate({ + ...rest, + imageKeys: uploadedImageKeys, + postId: parentPost.id, + }) + }, + }) + }) + + const areMutationsLoading = + replyThreadMutation.isLoading || uploadImagesMutation.isLoading + + const onClose = () => { + reset() + onCloseProp?.() + } + + return ( + + + + + Reply post + + + + + + + + + + + Reply to post + + + {/* + + + */} + + + + ) +} diff --git a/src/features/posts/components/AddCommentModal/index.ts b/src/features/posts/components/AddCommentModal/index.ts new file mode 100644 index 00000000..63fb5b21 --- /dev/null +++ b/src/features/posts/components/AddCommentModal/index.ts @@ -0,0 +1 @@ +export * from './AddCommentModal' diff --git a/src/features/posts/components/ComposePost.tsx b/src/features/posts/components/ComposePost.tsx new file mode 100644 index 00000000..b4c961ed --- /dev/null +++ b/src/features/posts/components/ComposePost.tsx @@ -0,0 +1,70 @@ +import { FormControl, Stack } from '@chakra-ui/react' +import { FormErrorMessage } from '@opengovsg/design-system-react' +import { Controller, type UseFormReturn } from 'react-hook-form' +import { Avatar } from '~/components/Avatar' +import { ImageAttachmentButton } from '~/components/ImageAttachmentButton' +import { RichText } from '~/components/RichText' +import { useMe } from '~/features/me/api' +import { type ClientAddPostSchema } from '../schemas/clientAddPostSchema' +export interface ComposePostProps extends UseFormReturn { + placeholder?: string + allowImageUpload?: boolean + showAvatar?: boolean +} + +export const ComposePost = ({ + placeholder, + allowImageUpload, + showAvatar, + ...props +}: ComposePostProps): JSX.Element => { + const { + control, + setValue, + formState: { errors }, + } = props + + const { me } = useMe() + + return ( + + {showAvatar && ( + + )} + + + ( + { + onChange(value) + setValue('content', rawValue ?? '') + }} + /> + )} + /> + {errors.contentHtml?.message} + + {allowImageUpload && ( + + } + /> + + )} + + + ) +} diff --git a/src/features/posts/components/DeletePostModal.tsx b/src/features/posts/components/DeletePostModal.tsx new file mode 100644 index 00000000..e854bad6 --- /dev/null +++ b/src/features/posts/components/DeletePostModal.tsx @@ -0,0 +1,73 @@ +import { + ModalBody, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + type ModalProps, +} from '@chakra-ui/react' +import { Button, ModalCloseButton } from '@opengovsg/design-system-react' +import { ResponsiveButton } from '~/components/ResponsiveButton' +import { ResponsiveModal } from '~/components/ResponsiveModal' +import { ResponsiveModalButtonGroup } from '~/components/ResponsiveModalButtonGroup' +import { trpc, type RouterOutput } from '~/utils/trpc' + +interface DeletePostModalProps extends Pick { + postId: RouterOutput['post']['byUser']['posts'][number]['id'] +} + +export const DeletePostModal = ({ + isOpen, + onClose, + postId, +}: DeletePostModalProps) => { + const utils = trpc.useContext() + const deletePostMutation = trpc.post.delete.useMutation({ + onSuccess: async () => { + await utils.post.invalidate() + onClose() + }, + }) + + const handleDelete = () => { + return deletePostMutation.mutate({ id: postId }) + } + + return ( + + + + + Delete post + + This cannot be undone, and it will be removed from your profile and + search results. + + + + + + Delete post + + + + + + ) +} diff --git a/src/features/posts/components/NewPostModal/NewPostModal.stories.tsx b/src/features/posts/components/NewPostModal/NewPostModal.stories.tsx new file mode 100644 index 00000000..4632243f --- /dev/null +++ b/src/features/posts/components/NewPostModal/NewPostModal.stories.tsx @@ -0,0 +1,45 @@ +import { useDisclosure } from '@chakra-ui/react' + +import { NewPostModal } from './NewPostModal' +import { type Meta, type StoryObj } from '@storybook/react' +import { meHandlers } from 'tests/msw/handlers/me' + +const meta: Meta = { + title: 'Features/Posts/NewPostModal', + component: NewPostModal, + parameters: { + layout: 'fullscreen', + // Prevent flaky tests due to modal animating in. + chromatic: { pauseAnimationAtEnd: true }, + msw: { + handlers: [meHandlers.me()], + }, + }, +} + +export default meta +type Story = StoryObj + +const defaultRenderFn: Story['render'] = (args) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const modalProps = useDisclosure({ defaultIsOpen: true }) + + return ( + console.log('close modal')} + /> + ) +} + +export const NoImageUpload: Story = { + render: defaultRenderFn, +} + +export const WithImageUpload: Story = { + args: { + allowImageUpload: true, + }, + render: defaultRenderFn, +} diff --git a/src/features/posts/components/NewPostModal/NewPostModal.tsx b/src/features/posts/components/NewPostModal/NewPostModal.tsx new file mode 100644 index 00000000..5d5e43a2 --- /dev/null +++ b/src/features/posts/components/NewPostModal/NewPostModal.tsx @@ -0,0 +1,107 @@ +import { + ModalBody, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + type ModalProps, +} from '@chakra-ui/react' +import { + Button, + ModalCloseButton, + useToast, +} from '@opengovsg/design-system-react' +import { ResponsiveButton } from '~/components/ResponsiveButton' +import { ResponsiveModal } from '~/components/ResponsiveModal' +import { ResponsiveModalButtonGroup } from '~/components/ResponsiveModalButtonGroup' +import { ComposePost } from '~/features/posts/components' +import { useZodForm } from '~/lib/form' +import { trpc } from '~/utils/trpc' +import { useUploadImagesMutation } from '../../api' +import { clientAddPostSchema } from '../../schemas/clientAddPostSchema' + +export interface NewPostModalProps + extends Pick { + allowImageUpload?: boolean +} + +export const NewPostModal = ({ + allowImageUpload, + onClose: onCloseProp, + isOpen, +}: NewPostModalProps) => { + const toast = useToast({ + status: 'success', + }) + const utils = trpc.useContext() + + const uploadImagesMutation = useUploadImagesMutation() + + const formMethods = useZodForm({ + schema: clientAddPostSchema, + }) + const { handleSubmit, reset, watch } = formMethods + + const watchedContent = watch('content') + + const addPostMutation = trpc.post.add.useMutation({ + async onSuccess() { + toast({ description: 'You’ve created a post successfully' }) + reset() + onClose() + await utils.post.invalidate() + }, + }) + + const handleSubmitPost = handleSubmit(async ({ images, ...rest }) => { + return uploadImagesMutation.mutate(images, { + onSuccess: (uploadedImageKeys) => { + return addPostMutation.mutate({ ...rest, imageKeys: uploadedImageKeys }) + }, + }) + }) + + const areMutationsLoading = + addPostMutation.isLoading || uploadImagesMutation.isLoading + + const onClose = () => { + reset() + onCloseProp?.() + } + + return ( + + + + + Create post + + + + + + + + Create post + + + + + + ) +} diff --git a/src/features/posts/components/NewPostModal/NewPostModalButton.tsx b/src/features/posts/components/NewPostModal/NewPostModalButton.tsx new file mode 100644 index 00000000..00cda299 --- /dev/null +++ b/src/features/posts/components/NewPostModal/NewPostModalButton.tsx @@ -0,0 +1,21 @@ +import { useDisclosure } from '@chakra-ui/react' +import { Button } from '@opengovsg/design-system-react' +import { NewPostModal } from './NewPostModal' +import { useFeatures } from '~/components/AppProviders' + +export const NewPostModalButton = (): JSX.Element => { + const { isOpen, onOpen, onClose } = useDisclosure() + const { storage } = useFeatures() + return ( + <> + + + + ) +} diff --git a/src/features/posts/components/NewPostModal/index.ts b/src/features/posts/components/NewPostModal/index.ts new file mode 100644 index 00000000..8fa4a3da --- /dev/null +++ b/src/features/posts/components/NewPostModal/index.ts @@ -0,0 +1 @@ +export * from './NewPostModalButton' diff --git a/src/features/posts/components/Post/Post.tsx b/src/features/posts/components/Post/Post.tsx new file mode 100644 index 00000000..27328824 --- /dev/null +++ b/src/features/posts/components/Post/Post.tsx @@ -0,0 +1,38 @@ +import { useRouter } from 'next/router' +import { type ReactEventHandler } from 'react' +import { type RouterOutput } from '~/utils/trpc' +import { PostView } from './PostView' + +export interface PostProps { + post: RouterOutput['post']['byUser']['posts'][number] + hideActions?: boolean +} + +export const Post = ({ post, hideActions }: PostProps): JSX.Element => { + const router = useRouter() + + const onClick: ReactEventHandler = async (e) => { + // data-values are added to all post actions so that we can distinguish + // between clicking on the post itself and clicking on an action, and only + // navigate to the thread if the post itself is clicked + const isAction = !!(e.target as HTMLElement).getAttribute('data-value') + if (!isAction) { + await router.push(`/thread/${post.id}`) + } + } + + return ( + + ) +} diff --git a/src/features/posts/components/Post/PostImages.tsx b/src/features/posts/components/Post/PostImages.tsx new file mode 100644 index 00000000..df0755db --- /dev/null +++ b/src/features/posts/components/Post/PostImages.tsx @@ -0,0 +1,39 @@ +import { Box, Image, SimpleGrid } from '@chakra-ui/react' +import { useMemo } from 'react' +import { type RouterOutput } from '~/utils/trpc' + +export interface PostImagesProps { + images: RouterOutput['post']['byUser']['posts'][number]['images'] +} + +export const PostImages = ({ images }: PostImagesProps): JSX.Element | null => { + const imageContainerHeight = useMemo(() => { + // Height = 16 rem if below 2 images, 8 rem if above 2 images + return images.length <= 2 ? '16rem' : '8rem' + }, [images.length]) + + if (images.length === 0) { + return null + } + + return ( + + {images.map((url, index) => ( + + Uploaded image + + ))} + + ) +} diff --git a/src/features/posts/components/Post/PostView.tsx b/src/features/posts/components/Post/PostView.tsx new file mode 100644 index 00000000..f4df0747 --- /dev/null +++ b/src/features/posts/components/Post/PostView.tsx @@ -0,0 +1,73 @@ +import { Avatar, Stack, type StackProps, Text } from '@chakra-ui/react' +import { Link } from '@opengovsg/design-system-react' +import NextLink from 'next/link' +import { useMemo } from 'react' +import { RichText } from '~/components/RichText' +import { formatRelativeTime } from '~/lib/dates' +import { PROFILE } from '~/lib/routes' +import { type RouterOutput } from '~/utils/trpc' +import { PostActions } from '../PostActions' +import { PostImages } from './PostImages' + +export interface PostViewProps { + post: RouterOutput['post']['byUser']['posts'][number] + hideActions?: boolean + containerProps?: StackProps +} + +export const PostView = ({ + post, + hideActions, + containerProps, +}: PostViewProps): JSX.Element => { + const relativeDate = useMemo(() => formatRelativeTime(post.createdAt), [post]) + return ( + + + + + + {post.author.name} + + + + @{post.author.username} + + + {relativeDate} + + + + + + + + {!hideActions && } + + + ) +} diff --git a/src/features/posts/components/Post/SkeletonPost.tsx b/src/features/posts/components/Post/SkeletonPost.tsx new file mode 100644 index 00000000..15de0a68 --- /dev/null +++ b/src/features/posts/components/Post/SkeletonPost.tsx @@ -0,0 +1,48 @@ +import { + Skeleton, + SkeletonCircle, + SkeletonText, + Stack, + Text, +} from '@chakra-ui/react' +import { type PostViewProps } from './PostView' + +type SkeletonPostProps = Omit + +export const SkeletonPost = ({ + containerProps, + hideActions, +}: SkeletonPostProps): JSX.Element => { + return ( + + + + + + + Loading... + + + + + @loading... + + + + Ldg 18 + + + + + + + + {!hideActions && } + + + ) +} diff --git a/src/features/posts/components/Post/index.ts b/src/features/posts/components/Post/index.ts new file mode 100644 index 00000000..6190c310 --- /dev/null +++ b/src/features/posts/components/Post/index.ts @@ -0,0 +1,4 @@ +export * from './Post' +export * from './PostView' +export * from './PostImages' +export * from './SkeletonPost' diff --git a/src/features/posts/components/PostActions/AddCommentAction.tsx b/src/features/posts/components/PostActions/AddCommentAction.tsx new file mode 100644 index 00000000..487a4585 --- /dev/null +++ b/src/features/posts/components/PostActions/AddCommentAction.tsx @@ -0,0 +1,46 @@ +import { useDisclosure } from '@chakra-ui/react' +import { Button } from '@opengovsg/design-system-react' +import { type MouseEventHandler } from 'react' +import { BiMessageRounded } from 'react-icons/bi' +import { type RouterOutput } from '~/utils/trpc' +import { AddCommentModal } from '../AddCommentModal' +import { useFeatures } from '~/components/AppProviders' + +interface AddCommentActionProps { + post: RouterOutput['post']['byUser']['posts'][number] + onSuccess?: () => void +} + +export const AddCommentAction = ({ + post, + onSuccess, +}: AddCommentActionProps): JSX.Element => { + const { isOpen, onOpen, onClose } = useDisclosure() + const { storage } = useFeatures() + + const handleOpenModal: MouseEventHandler = (e) => { + e.stopPropagation() + onOpen() + } + + return ( + <> + + + + ) +} diff --git a/src/features/posts/components/PostActions/CopyAction.tsx b/src/features/posts/components/PostActions/CopyAction.tsx new file mode 100644 index 00000000..51a8fa35 --- /dev/null +++ b/src/features/posts/components/PostActions/CopyAction.tsx @@ -0,0 +1,38 @@ +import { Tooltip } from '@chakra-ui/react' +import { IconButton } from '@opengovsg/design-system-react' +import { useState, type MouseEventHandler, useEffect } from 'react' +import { BiLink } from 'react-icons/bi' + +interface CopyActionProps { + postId: string +} + +export const CopyAction = ({ postId }: CopyActionProps): JSX.Element => { + const [isOpen, setIsOpen] = useState(false) + + useEffect(() => { + const timer = setTimeout(() => { + setIsOpen(false) + }, 2000) + return () => clearTimeout(timer) + }, [isOpen]) + + const handleCopyLink: MouseEventHandler = async (e) => { + setIsOpen(true) + e.stopPropagation() + const url = `${window.location.origin}/thread/${postId}` + await navigator.clipboard.writeText(url) + } + + return ( + + setIsOpen(false)} + data-value="post-action" + aria-label="Link to post" + icon={} + onClick={handleCopyLink} + /> + + ) +} diff --git a/src/features/posts/components/PostActions/DeletePostAction.tsx b/src/features/posts/components/PostActions/DeletePostAction.tsx new file mode 100644 index 00000000..655f6e0b --- /dev/null +++ b/src/features/posts/components/PostActions/DeletePostAction.tsx @@ -0,0 +1,33 @@ +import { useDisclosure } from '@chakra-ui/react' +import { IconButton } from '@opengovsg/design-system-react' +import { type MouseEventHandler } from 'react' +import { BiTrash } from 'react-icons/bi' +import { type RouterOutput } from '~/utils/trpc' +import { DeletePostModal } from '../DeletePostModal' + +interface DeletePostActionProps { + postId: RouterOutput['post']['byUser']['posts'][number]['id'] +} +export const DeletePostAction = ({ + postId, +}: DeletePostActionProps): JSX.Element => { + const { isOpen, onOpen, onClose } = useDisclosure() + + const handleOpenModal: MouseEventHandler = (e) => { + e.stopPropagation() + onOpen() + } + + return ( + <> + } + /> + + + ) +} diff --git a/src/features/posts/components/PostActions/PostActions.tsx b/src/features/posts/components/PostActions/PostActions.tsx new file mode 100644 index 00000000..8b76107d --- /dev/null +++ b/src/features/posts/components/PostActions/PostActions.tsx @@ -0,0 +1,95 @@ +import { Box, ButtonGroup } from '@chakra-ui/react' +import { Button, BxsHeart } from '@opengovsg/design-system-react' +import { useState, type MouseEventHandler } from 'react' +import { BiHeart } from 'react-icons/bi' +import { useMe } from '~/features/me/api' +import { trpc, type RouterOutput } from '~/utils/trpc' +import { AddCommentAction } from './AddCommentAction' +import { CopyAction } from './CopyAction' +import { DeletePostAction } from './DeletePostAction' + +export interface PostActionsProps { + post: RouterOutput['post']['byUser']['posts'][number] +} + +export const PostActions = ({ + post: postProp, +}: PostActionsProps): JSX.Element => { + const { me } = useMe() + + // Use local state to update the UI immediately on like/unlike + const [post, setPost] = useState(postProp) + const isOwnPost = me?.username === post.author.username + + const toggleLikeMutation = trpc.post.toggleLikePost.useMutation({ + onMutate: async () => { + const previousPost = post + const nextPost = post + nextPost.likedByMe = !post.likedByMe + nextPost._count.likes = post.likedByMe + ? post._count.likes + 1 + : post._count.likes - 1 + setPost(nextPost) + // return will pass the function or the value to the onError third argument: + return previousPost + }, + onError: (_error, _variables, previousPost) => { + // If there is an errror, then we will rollback + if (previousPost) { + setPost(previousPost) + } + }, + }) + + const incrementReplyCount = () => { + setPost((prevPost) => ({ + ...prevPost, + _count: { + ...prevPost._count, + replies: prevPost._count.replies + 1, + }, + })) + } + + const handleLikeClick: MouseEventHandler = (e) => { + e.stopPropagation() + if (!me) return + return toggleLikeMutation.mutate({ + postId: post.id, + }) + } + + return ( + + + + + {isOwnPost ? ( + + ) : ( + + )} + + ) +} diff --git a/src/features/posts/components/PostActions/ReplyToPostAction.tsx b/src/features/posts/components/PostActions/ReplyToPostAction.tsx new file mode 100644 index 00000000..89db3e44 --- /dev/null +++ b/src/features/posts/components/PostActions/ReplyToPostAction.tsx @@ -0,0 +1,49 @@ +// Almost the same as AddCommentAction, but rendering is different + +import { Box, useDisclosure } from '@chakra-ui/react' +import { Button } from '@opengovsg/design-system-react' +import { type MouseEventHandler } from 'react' +import { type RouterOutput } from '~/utils/trpc' +import { AddCommentModal } from '../AddCommentModal' +import { useFeatures } from '~/components/AppProviders' + +interface ReplyToPostActionProps { + post: RouterOutput['post']['byUser']['posts'][number] + onSuccess?: () => void +} + +export const ReplyToPostAction = ({ + post, + onSuccess, +}: ReplyToPostActionProps): JSX.Element => { + const { isOpen, onOpen, onClose } = useDisclosure() + const { storage } = useFeatures() + + const handleOpenModal: MouseEventHandler = (e) => { + e.stopPropagation() + onOpen() + } + + return ( + <> + + + + + + ) +} diff --git a/src/features/posts/components/PostActions/index.ts b/src/features/posts/components/PostActions/index.ts new file mode 100644 index 00000000..f7865fa4 --- /dev/null +++ b/src/features/posts/components/PostActions/index.ts @@ -0,0 +1,2 @@ +export * from './PostActions' +export * from './ReplyToPostAction' diff --git a/src/features/posts/components/index.ts b/src/features/posts/components/index.ts new file mode 100644 index 00000000..198f5025 --- /dev/null +++ b/src/features/posts/components/index.ts @@ -0,0 +1,4 @@ +export * from './Post' +export * from './NewPostModal' +export * from './ComposePost' +export * from './PostActions' diff --git a/src/features/posts/schemas/clientAddPostSchema.ts b/src/features/posts/schemas/clientAddPostSchema.ts new file mode 100644 index 00000000..03e211e6 --- /dev/null +++ b/src/features/posts/schemas/clientAddPostSchema.ts @@ -0,0 +1,27 @@ +import { z } from 'zod' +import { addPostSchema } from '~/schemas/post' +import { addReplySchema } from '~/schemas/thread' + +const clientImageSchema = { + images: + typeof window === 'undefined' + ? z.undefined() + : z.array(z.instanceof(File)).optional(), +} + +export const clientAddPostSchema = addPostSchema + .omit({ + imageKeys: true, + }) + .extend(clientImageSchema) + +export type ClientAddPostSchema = z.infer + +export const clientAddReplySchema = addReplySchema + .omit({ + postId: true, + imageKeys: true, + }) + .extend(clientImageSchema) + +export type ClientAddReplySchema = z.infer diff --git a/src/features/profile/assets/profile-aunty.svg b/src/features/profile/assets/profile-aunty.svg deleted file mode 100644 index 46591931..00000000 --- a/src/features/profile/assets/profile-aunty.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/features/profile/components/EmptyPostList.tsx b/src/features/profile/components/EmptyPostList.tsx new file mode 100644 index 00000000..ef67f21c --- /dev/null +++ b/src/features/profile/components/EmptyPostList.tsx @@ -0,0 +1,30 @@ +import { Stack, Text } from '@chakra-ui/react' +import { useRouter } from 'next/router' +import { BusStop } from '~/components/Svg/BusStop' +import { useMe } from '~/features/me/api' + +interface EmptyPostListProps { + currentUserText: string + readOnlyText: string +} + +export const EmptyPostList = ({ + currentUserText, + readOnlyText, +}: EmptyPostListProps): JSX.Element => { + const { query } = useRouter() + const username = String(query.username) + + const { me } = useMe() + + const isLoggedInProfile = me?.username === username + + return ( + + + {isLoggedInProfile ? currentUserText : readOnlyText} + + + + ) +} diff --git a/src/features/profile/components/ProfileAuntySvgr.tsx b/src/features/profile/components/ProfileAuntySvgr.tsx deleted file mode 100644 index 95c09f6f..00000000 --- a/src/features/profile/components/ProfileAuntySvgr.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import { type SVGProps } from 'react' - -export const ProfileAuntySvgr = (props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -) diff --git a/src/features/profile/components/ProfileDescription.tsx b/src/features/profile/components/ProfileDescription.tsx new file mode 100644 index 00000000..d7a32520 --- /dev/null +++ b/src/features/profile/components/ProfileDescription.tsx @@ -0,0 +1,76 @@ +import { Flex, Grid, Stack, Text } from '@chakra-ui/react' +import { Button } from '@opengovsg/design-system-react' +import Link from 'next/link' +import { useMemo } from 'react' +import { Avatar } from '~/components/Avatar' +import { useMe } from '~/features/me/api' +import { SETTINGS_PROFILE } from '~/lib/routes' +import { trpc } from '~/utils/trpc' + +export interface ProfileDescriptionProps { + username: string +} + +export const ProfileDescription = ({ + username, +}: ProfileDescriptionProps): JSX.Element => { + const { me } = useMe() + const [data] = trpc.profile.byUsername.useSuspenseQuery({ username }) + + const isOwnProfile = useMemo( + () => me?.username === username, + [me?.username, username] + ) + + return ( + + + + + + {data?.name || data?.username} + + + @{data?.username} + + + {isOwnProfile && ( + + )} + + {data?.bio} + + + + ) +} diff --git a/src/features/profile/components/ProfileTabs.tsx b/src/features/profile/components/ProfileTabs.tsx new file mode 100644 index 00000000..9ab3841d --- /dev/null +++ b/src/features/profile/components/ProfileTabs.tsx @@ -0,0 +1,54 @@ +import { Stack } from '@chakra-ui/react' +import { useRouter } from 'next/router' +import { NavigationTab, NavigationTabList } from '~/components/NavigationalTabs' +import { useMe } from '~/features/me/api' +import { NewPostModalButton } from '~/features/posts/components' + +export interface ProfileTabsProps { + username: string +} + +export const ProfileTabs = ({ username }: ProfileTabsProps): JSX.Element => { + const { pathname } = useRouter() + const { me } = useMe() + + const isLoggedInProfile = me?.username === username + + return ( + + + + Posts + + + Liked + + + Replies + + + {isLoggedInProfile && } + + ) +} diff --git a/src/features/profile/components/index.ts b/src/features/profile/components/index.ts new file mode 100644 index 00000000..18e7c0c0 --- /dev/null +++ b/src/features/profile/components/index.ts @@ -0,0 +1,3 @@ +export * from './ProfileDescription' +export * from './ProfileTabs' +export * from './EmptyPostList' diff --git a/src/features/profile/api/index.ts b/src/features/settings/api/index.ts similarity index 61% rename from src/features/profile/api/index.ts rename to src/features/settings/api/index.ts index 6b823afe..918d5caf 100644 --- a/src/features/profile/api/index.ts +++ b/src/features/settings/api/index.ts @@ -1,2 +1 @@ export * from './useUploadAvatarMutation' -export * from './useUser' diff --git a/src/features/profile/api/useUploadAvatarMutation.ts b/src/features/settings/api/useUploadAvatarMutation.ts similarity index 71% rename from src/features/profile/api/useUploadAvatarMutation.ts rename to src/features/settings/api/useUploadAvatarMutation.ts index 109e510e..8deed5e8 100644 --- a/src/features/profile/api/useUploadAvatarMutation.ts +++ b/src/features/settings/api/useUploadAvatarMutation.ts @@ -1,10 +1,11 @@ import { useMutation } from '@tanstack/react-query' +import { useMe } from '~/features/me/api' +import { type AcceptedImageFileTypes, ACCEPTED_FILE_TYPES } from '~/utils/image' import { trpc } from '~/utils/trpc' -import { useUser } from './useUser' export const useUploadAvatarMutation = () => { const utils = trpc.useContext() - const { user } = useUser() + const { me } = useMe() // Pre-upload: Create a mutation to presign the upload request const presignImageUploadMutation = trpc.storage.presignAvatar.useMutation() @@ -15,10 +16,15 @@ export const useUploadAvatarMutation = () => { return useMutation( async (image: File) => { - if (!user?.id) throw new Error('No user found') + if (!me?.id) throw new Error('No user found') + if (!ACCEPTED_FILE_TYPES.some((type) => type === image.type)) { + throw new Error( + `File type ${image.type} is not supported. Please upload an image.` + ) + } const presign = await presignImageUploadMutation.mutateAsync({ - fileContentType: image.type, + fileContentType: image.type as AcceptedImageFileTypes, }) if (!presign) throw new Error('No presign generated') diff --git a/src/features/profile/components/AvatarUpload.tsx b/src/features/settings/components/AvatarUpload.tsx similarity index 74% rename from src/features/profile/components/AvatarUpload.tsx rename to src/features/settings/components/AvatarUpload.tsx index c2184260..9d9120dd 100644 --- a/src/features/profile/components/AvatarUpload.tsx +++ b/src/features/settings/components/AvatarUpload.tsx @@ -1,26 +1,19 @@ -import { - Avatar, - Box, - Flex, - Icon, - Image, - SkeletonCircle, - Spinner, -} from '@chakra-ui/react' +import { Box, Flex, Icon, SkeletonCircle, Spinner } from '@chakra-ui/react' import { Input, useToast } from '@opengovsg/design-system-react' import { type ChangeEventHandler, useMemo, useState } from 'react' import { BiImageAdd } from 'react-icons/bi' -import { env } from '~/env.mjs' +import { Avatar } from '~/components/Avatar' +import { ACCEPTED_FILE_TYPES } from '~/utils/image' import { useUploadAvatarMutation } from '../api' +import { useFeatures } from '~/components/AppProviders' interface AvatarUploadProps { name?: string | null url?: string | null } -const CAN_UPLOAD = !!env.NEXT_PUBLIC_ENABLE_STORAGE - export const AvatarUpload = ({ url, name }: AvatarUploadProps): JSX.Element => { + const { storage } = useFeatures() // Will load this over `url` if provided for UX. const [isHover, setIsHover] = useState(false) @@ -53,14 +46,14 @@ export const AvatarUpload = ({ url, name }: AvatarUploadProps): JSX.Element => { } const hoverProps = useMemo(() => { - if (!CAN_UPLOAD) { + if (!storage) { return {} } return { onMouseOver: () => setIsHover(true), onMouseLeave: () => setIsHover(false), } - }, []) + }, [storage]) return ( @@ -81,16 +74,16 @@ export const AvatarUpload = ({ url, name }: AvatarUploadProps): JSX.Element => { align="center" justify="center" cursor={ - !CAN_UPLOAD || uploadAvatarMutation.isLoading ? 'default' : 'pointer' + !storage || uploadAvatarMutation.isLoading ? 'default' : 'pointer' } w="7rem" h="7rem" > @@ -102,25 +95,16 @@ export const AvatarUpload = ({ url, name }: AvatarUploadProps): JSX.Element => { isLoaded={url !== undefined} pos="relative" > - {url ? ( - profile picture - ) : ( - - )} + {uploadAvatarMutation.isLoading && ( = ({ onSuccess }) => { formState: { errors }, } = useZodForm({ schema: emailSignInSchema, + mode: 'onTouched', }) + const router = useRouter() + const loginMutation = trpc.auth.email.login.useMutation({ onSuccess, onError: (error) => setError('email', { message: error.message }), }) + useEffect(() => { + if (router.query.error) { + setError('email', { message: String(router.query.error) }) + } + }, [router.query.error, setError]) + const handleSignIn = handleSubmit(({ email }) => { return loginMutation.mutate({ email }) }) diff --git a/src/features/sign-in/components/GridLayout.tsx b/src/features/sign-in/components/GridLayout.tsx index 44c959c1..e7af2210 100644 --- a/src/features/sign-in/components/GridLayout.tsx +++ b/src/features/sign-in/components/GridLayout.tsx @@ -24,7 +24,11 @@ export const BackgroundBox: FC = ({ children }) => ( // Component that controls the various grid areas according to responsive breakpoints. export const BaseGridLayout = (props: GridProps) => ( - + ) // Grid area styling for the login form. diff --git a/src/features/sign-in/components/SgidLoginButton.tsx b/src/features/sign-in/components/SgidLoginButton.tsx index 1760b3c2..e24f2914 100644 --- a/src/features/sign-in/components/SgidLoginButton.tsx +++ b/src/features/sign-in/components/SgidLoginButton.tsx @@ -1,10 +1,11 @@ import { Button } from '@opengovsg/design-system-react' import { useRouter } from 'next/router' -import { env } from '~/env.mjs' +import { useFeatures } from '~/components/AppProviders' import { trpc } from '~/utils/trpc' export const SgidLoginButton = (): JSX.Element | null => { const router = useRouter() + const { sgid } = useFeatures() const sgidLoginMutation = trpc.auth.sgid.login.useMutation({ onSuccess: async ({ redirectUrl }) => { await router.push(redirectUrl) @@ -15,13 +16,13 @@ export const SgidLoginButton = (): JSX.Element | null => { return sgidLoginMutation.mutate({}) } - if (!env.NEXT_PUBLIC_ENABLE_SGID) { + if (!sgid) { return null } return ( + + + + ) +} diff --git a/src/features/thread/components/ThreadPost.tsx b/src/features/thread/components/ThreadPost.tsx new file mode 100644 index 00000000..a76b5789 --- /dev/null +++ b/src/features/thread/components/ThreadPost.tsx @@ -0,0 +1,98 @@ +import { Avatar, Stack, type StackProps, Text } from '@chakra-ui/react' +import { Link } from '@opengovsg/design-system-react' +import NextLink from 'next/link' +import { useRouter } from 'next/router' +import { type ReactEventHandler, useMemo } from 'react' +import { RichText } from '~/components/RichText' +import { PostActions, PostImages } from '~/features/posts/components' +import { formatRelativeTime } from '~/lib/dates' +import { PROFILE } from '~/lib/routes' +import { type RouterOutput } from '~/utils/trpc' + +export interface ThreadPostProps { + post: RouterOutput['post']['byUser']['posts'][number] + hideActions?: boolean + containerProps?: StackProps +} + +export const ThreadPost = ({ + post: reply, + hideActions, + containerProps, +}: ThreadPostProps): JSX.Element => { + const router = useRouter() + + const onClick: ReactEventHandler = async (e) => { + // data-values are added to all post actions so that we can distinguish + // between clicking on the post itself and clicking on an action, and only + // navigate to the thread if the post itself is clicked + const isAction = !!(e.target as HTMLElement).getAttribute('data-value') + if (!isAction) { + await router.push(`/thread/${reply.id}`) + } + } + + const relativeDate = useMemo( + () => formatRelativeTime(reply.createdAt), + [reply] + ) + return ( + + + + + + {reply.author.name} + + + + @{reply.author.username} + + + {relativeDate} + + + + + + + {!hideActions && } + + + + ) +} diff --git a/src/features/thread/components/ThreadView.tsx b/src/features/thread/components/ThreadView.tsx new file mode 100644 index 00000000..cfb4b58e --- /dev/null +++ b/src/features/thread/components/ThreadView.tsx @@ -0,0 +1,41 @@ +import { Divider, Stack, StackDivider } from '@chakra-ui/react' +import { useRouter } from 'next/router' +import { APP_GRID_COLUMN } from '~/constants/layouts' +import { ReplyToPostAction } from '~/features/posts/components' +import { trpc } from '~/utils/trpc' +import { ThreadPost } from './ThreadPost' +import { SkeletonThreadView } from './SkeletonThreadView' + +export const ThreadView = (): JSX.Element | null => { + const router = useRouter() + const postId = String(router.query.postId) + + const { data, isLoading, isError } = trpc.post.byId.useQuery( + { id: postId }, + { + enabled: router.isReady, + } + ) + + if (isLoading) { + return + } + + if (isError) { + void router.push('/404') + return null + } + + return ( + + + + + } py="1rem"> + {data.replies.map((r) => ( + + ))} + + + ) +} diff --git a/src/features/thread/components/index.ts b/src/features/thread/components/index.ts new file mode 100644 index 00000000..5b561f5f --- /dev/null +++ b/src/features/thread/components/index.ts @@ -0,0 +1,2 @@ +export * from './SkeletonThreadView' +export * from './ThreadView' diff --git a/src/lib/dates.ts b/src/lib/dates.ts new file mode 100644 index 00000000..3114b034 --- /dev/null +++ b/src/lib/dates.ts @@ -0,0 +1,34 @@ +import { format } from 'date-fns' + +export const formatRelativeTime = ( + date?: Date | null, + baseDate?: Date | null, + formatStr = 'MMM dd' +) => { + if (date === null || date === undefined) return + + if (!baseDate) { + baseDate = new Date() + } + + let deltaSeconds = (date.getTime() - baseDate.getTime()) / 1000 + const isFuture = deltaSeconds > 0 ? true : false + + let t + deltaSeconds = Math.abs(deltaSeconds) + + if (deltaSeconds < 60) { + t = `${Math.floor(deltaSeconds)}s` + } else if (deltaSeconds < 3600) { + t = `${Math.floor(deltaSeconds / 60)}m` + } else if (deltaSeconds < 86400) { + t = `${Math.floor(deltaSeconds / 3600)}h` + } else { + t = format(date, formatStr) + } + if (isFuture) { + return 'in ' + t + } else { + return t + } +} diff --git a/src/lib/form.ts b/src/lib/form.ts index 297111e6..b73fdfad 100644 --- a/src/lib/form.ts +++ b/src/lib/form.ts @@ -2,14 +2,15 @@ import { useForm, type UseFormProps } from 'react-hook-form' import { type z } from 'zod' import { zodResolver } from '@hookform/resolvers/zod' -export const useZodForm = ( - props: Omit, 'resolver'> & { - schema: TSchema - } -) => { +export const useZodForm = ({ + schema, + ...props +}: Omit, 'resolver'> & { + schema: TSchema +}) => { const form = useForm({ ...props, - resolver: zodResolver(props.schema, undefined), + resolver: zodResolver(schema, undefined), }) return form diff --git a/src/lib/routes.ts b/src/lib/routes.ts new file mode 100644 index 00000000..52b41454 --- /dev/null +++ b/src/lib/routes.ts @@ -0,0 +1,4 @@ +export const SIGN_IN = '/sign-in' +export const HOME = '/home' +export const PROFILE = '/profile' +export const SETTINGS_PROFILE = '/settings/profile' diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts index a2b64a84..aa69577d 100644 --- a/src/lib/types/index.ts +++ b/src/lib/types/index.ts @@ -1,11 +1,11 @@ import type { NextPage } from 'next' -import type { ReactElement, ReactNode } from 'react' +import type { ReactNode } from 'react' + +export type GetLayout = (page: ReactNode) => ReactNode export type NextPageWithLayout< TProps = Record, TInitialProps = TProps > = NextPage & { - getLayout?: (page: ReactElement) => ReactNode + getLayout?: GetLayout } - -export * from './trpc' diff --git a/src/lib/types/iron-session.d.ts b/src/lib/types/iron-session.d.ts index 3da70b49..99357fda 100644 --- a/src/lib/types/iron-session.d.ts +++ b/src/lib/types/iron-session.d.ts @@ -1,9 +1,9 @@ import { type User } from '@prisma/client' -import { type defaultUserSelect } from '~/server/modules/user/user.select' +import { type defaultMeSelect } from '~/server/modules/me/me.select' declare module 'iron-session' { interface IronSessionData { - user?: Pick + user?: Pick sgidSessionState?: { codeVerifier: string nonce?: string diff --git a/src/lib/types/trpc.ts b/src/lib/types/trpc.ts deleted file mode 100644 index ae9c2342..00000000 --- a/src/lib/types/trpc.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { type UseTRPCMutationResult } from '@trpc/react-query/shared' - -export type InferMutationInput< - T extends UseTRPCMutationResult -> = NonNullable diff --git a/src/lib/withSession.ts b/src/lib/withSession.ts deleted file mode 100644 index 5f6df63b..00000000 --- a/src/lib/withSession.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { withIronSessionSsr } from 'iron-session/next' -import { - type GetServerSidePropsContext, - type GetServerSidePropsResult, -} from 'next' -import { sessionOptions } from './auth' - -// Theses types are compatible with InferGetStaticPropsType https://nextjs.org/docs/basic-features/data-fetching#typescript-use-getstaticprops -export function withSessionSsr< - P extends { [key: string]: unknown } = { [key: string]: unknown } ->( - handler: ( - context: GetServerSidePropsContext - ) => GetServerSidePropsResult

| Promise> -) { - return withIronSessionSsr(handler, sessionOptions) -} diff --git a/src/pages/404.tsx b/src/pages/404.tsx index bb9bd253..be3dbf75 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -2,6 +2,7 @@ import { Flex, Stack, Text } from '@chakra-ui/react' import { Button } from '@opengovsg/design-system-react' import Image from 'next/image' import { useRouter } from 'next/router' +import { RestrictedMiniFooter } from '~/components/RestrictedMiniFooter' // https://nextjs.org/docs/advanced-features/custom-error-page const Custom404 = () => { @@ -41,9 +42,9 @@ const Custom404 = () => { Go back - {/* */} + ) diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index cb171140..f2cca48e 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,17 +1,18 @@ import '@fontsource/ibm-plex-mono' // Import if using code textStyles. import 'inter-ui/inter.css' // Strongly recommended. -import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import { Skeleton } from '@chakra-ui/react' import { ThemeProvider } from '@opengovsg/design-system-react' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import { Provider } from 'jotai' import type { AppProps, AppType } from 'next/app' +import ErrorBoundary from '~/components/ErrorBoundary' +import Suspense from '~/components/Suspense' import { type NextPageWithLayout } from '~/lib/types' import { DefaultLayout } from '~/templates/layouts/DefaultLayout' import { theme } from '~/theme' import { trpc } from '~/utils/trpc' -import { Provider } from 'jotai' -import Suspense from '~/components/Suspense' -import ErrorBoundary from '~/components/ErrorBoundary/ErrorBoundary' -import { Skeleton } from '@chakra-ui/react' +import { FeatureProvider } from '~/components/AppProviders' type AppPropsWithAuthAndLayout = AppProps & { Component: NextPageWithLayout @@ -22,14 +23,16 @@ const MyApp = ((props: AppPropsWithAuthAndLayout) => { // Must wrap Jotai's provider in SSR context, see https://jotai.org/docs/guides/nextjs#provider. - - }> - - {process.env.NODE_ENV !== 'production' && ( - - )} - - + + + }> + + {process.env.NODE_ENV !== 'production' && ( + + )} + + + ) diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx deleted file mode 100644 index f12ff8b7..00000000 --- a/src/pages/dashboard.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { Box, Skeleton } from '@chakra-ui/react' -import { - FeedbackActionsModal, - TeamFeedbackList, -} from '~/features/feedback/components' -import type { NextPageWithLayout } from '~/lib/types' -import { AdminLayout } from '~/templates/layouts/AdminLayout' -import { TeamFeedbackFilterBar } from '~/features/feedback/components/TeamFeedbackFilterBar' -import Suspense from '~/components/Suspense' -import { TeamFeedbackListSkeleton } from '~/features/feedback/components/TeamFeedbackListSkeleton' -import ErrorBoundary from '~/components/ErrorBoundary/ErrorBoundary' -import { FeedbackHeader } from '~/features/feedback/components/FeedbackHeader' - -const Dashboard: NextPageWithLayout = () => { - return ( - - - }> - - - - - - - ) -} - -const DashboardContainer = () => { - return ( - <> - }> - - - - }> - - - - - - - ) -} - -Dashboard.getLayout = AdminLayout - -export default Dashboard diff --git a/src/pages/feedback/[id].tsx b/src/pages/feedback/[id].tsx deleted file mode 100644 index 0736856b..00000000 --- a/src/pages/feedback/[id].tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { Container, Flex, Spinner, Stack, Text } from '@chakra-ui/react' -import { useRouter } from 'next/router' -import { useEffect, useMemo } from 'react' -import ErrorBoundary from '~/components/ErrorBoundary/ErrorBoundary' -import Suspense from '~/components/Suspense' -import { FeedbackComment, FeedbackNavbar } from '~/features/feedback/components' -import { FeedbackCommentRichText } from '~/features/feedback/components/FeedbackCommentRichText' -import { type NextPageWithLayout } from '~/lib/types' -import { trpc } from '~/utils/trpc' - -const PostViewPage: NextPageWithLayout = () => { - return ( - - - }> - - - - - ) -} - -const PostViewContainer = () => { - const router = useRouter() - - const id = String(router.query.id) - - const utils = trpc.useContext() - - const [data] = trpc.post.byId.useSuspenseQuery({ id }) - - const { mutate } = trpc.post.setRead.useMutation() - - const viewPostCrumbs = useMemo(() => { - return [ - { - label: 'All feedback', - href: '/dashboard', - }, - { - label: data?.author.name ?? 'loading', - last: true, - href: `/feedback/${id}`, - }, - ] - }, [data?.author.name, id]) - - useEffect(() => { - if (router.isReady) { - mutate( - { id }, - { - onSuccess: async () => { - await utils.post.list.invalidate() - await utils.post.unreadCount.invalidate() - }, - } - ) - } - // Only want to run once on mount. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [router.isReady]) - - return ( - <> - - - - - - Feedback from {data.author.name} - - - Reply to share your concerns and ideas directly. - - - - - - {data.replies.map((reply) => ( - - ))} - - - - - - ) -} - -export default PostViewPage diff --git a/src/pages/feedback/new.tsx b/src/pages/feedback/new.tsx deleted file mode 100644 index 64e39020..00000000 --- a/src/pages/feedback/new.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import { - Container, - Flex, - FormControl, - FormLabel, - HStack, - Stack, - Text, - VStack, -} from '@chakra-ui/react' -import { - Button, - FormErrorMessage, - useToast, -} from '@opengovsg/design-system-react' -import { useRouter } from 'next/router' -import { Controller } from 'react-hook-form' -import { - FeedbackNavbar, - FeedbackUncleSvgr, -} from '~/features/feedback/components' -import { useZodForm } from '~/lib/form' -import { type NextPageWithLayout } from '~/lib/types' -import { addPostSchema } from '~/schemas/post' -import { trpc } from '~/utils/trpc' - -import { RichText } from '~/components/RichText' -import { FEEDBACK } from '~/constants/routes' - -const PostFeedbackPage: NextPageWithLayout = () => { - const utils = trpc.useContext() - const toast = useToast({ - status: 'error', - }) - - const router = useRouter() - - const mutation = trpc.post.add.useMutation({ - async onSuccess({ id }) { - // refetches posts after a post is added - await utils.post.list.invalidate() - await router.push(`${FEEDBACK}/${id}`) - }, - onError: (error) => { - toast({ description: error.message }) - }, - }) - - const { - formState: { errors }, - handleSubmit, - setValue, - control, - } = useZodForm({ - schema: addPostSchema, - }) - - const handleSubmitFeedback = handleSubmit((values) => mutation.mutate(values)) - - return ( - - - - - - - Write feedback - - - Share your concerns and ideas directly with your organization. - - - - - - - What's on your mind? - ( - { - onChange(value) - setValue('content', rawValue ?? '') - }} - /> - )} - /> - {errors.contentHtml?.message} - - - - - - ) -} - -export default PostFeedbackPage diff --git a/src/pages/home.tsx b/src/pages/home.tsx new file mode 100644 index 00000000..1a0c389c --- /dev/null +++ b/src/pages/home.tsx @@ -0,0 +1,40 @@ +import { Box, Flex } from '@chakra-ui/react' +import { SkeletonPostList } from '~/components/SkeletonPostList' +import Suspense from '~/components/Suspense' +import { APP_GRID_COLUMN, APP_GRID_TEMPLATE_COLUMN } from '~/constants/layouts' +import { NewPostBanner, PostList } from '~/features/home/components' +import { type NextPageWithLayout } from '~/lib/types' +import { AppGrid } from '~/templates/AppGrid' +import { AdminLayout } from '~/templates/layouts/AdminLayout' + +const Home: NextPageWithLayout = () => { + return ( + + + + + + + + }> + + + + + ) +} + +Home.getLayout = AdminLayout + +export default Home diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 643d20b2..869d823a 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,10 +1,14 @@ import { Box, Flex, Icon, SimpleGrid, Stack, Text } from '@chakra-ui/react' -import { Button, Link, useIsMobile } from '@opengovsg/design-system-react' +import { + Button, + Link, + RestrictedFooter, + useIsMobile, +} from '@opengovsg/design-system-react' import Image from 'next/image' import NextLink from 'next/link' import { BiRightArrowAlt } from 'react-icons/bi' import { OgpLogo } from '~/components/Svg/OgpLogo' -import { SIGN_IN } from '~/constants/routes' import { AppPublicHeader, FeatureGridItem, @@ -13,6 +17,8 @@ import { SectionBodyText, SectionHeadingText, } from '~/features/landing/components' +import { SIGN_IN } from '~/lib/routes' +import { AppGrid } from '~/templates/AppGrid' const LandingPage = () => { const isMobile = useIsMobile() @@ -29,11 +35,7 @@ const LandingPage = () => { align="center" spacing={{ base: '1.5rem', md: '3.125rem', lg: '7.5rem' }} > - + { - {/* */} + + + + + ) } diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx deleted file mode 100644 index 4427eea4..00000000 --- a/src/pages/profile.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import { - Box, - Button, - ButtonGroup, - Flex, - FormControl, - FormErrorMessage, - FormLabel, - Input, - Stack, - Text, - Textarea, -} from '@chakra-ui/react' -import { useMemo } from 'react' -import { useUser } from '~/features/profile/api' -import { AvatarUpload } from '~/features/profile/components/AvatarUpload' -import { useZodForm } from '~/lib/form' -import { type NextPageWithLayout } from '~/lib/types' -import { updateMeSchema } from '~/schemas/me' -import { AdminLayout } from '~/templates/layouts/AdminLayout' -import { trpc } from '~/utils/trpc' - -import { useToast } from '@opengovsg/design-system-react' -import { ProfileAuntySvgr } from '~/features/profile/components/ProfileAuntySvgr' - -const Profile: NextPageWithLayout = () => { - const { user: me } = useUser() - const utils = trpc.useContext() - const toast = useToast({ - status: 'success', - }) - - const mutation = trpc.me.update.useMutation({ - async onSuccess() { - toast({ - description: 'Profile updated successfully.', - }) - await utils.me.get.invalidate() - }, - }) - - const { - formState: { errors }, - handleSubmit, - register, - } = useZodForm({ - schema: updateMeSchema, - values: useMemo(() => { - return { - name: me?.name ?? '', - bio: me?.bio ?? '', - } - }, [me]), - }) - - const handleProfileUpdate = handleSubmit((values) => { - return mutation.mutate(values) - }) - - return ( - - - - User profile - - - - - - - - - Email - - - - Name - - {errors.name?.message} - - - Bio -