diff --git a/package.json b/package.json index 0d8ac32..5e4a755 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "storybook": "pnpm recursive --filter tools-frontend run storybook" }, "devDependencies": { - "turbo": "^1.9.3" + "turbo": "^1.9.9" }, - "packageManager": "pnpm@8.3.1" + "packageManager": "pnpm@8.5.1" } diff --git a/packages/backend/src/libs/prisma.ts b/packages/backend/src/libs/prisma.ts index 4259aae..56bdbd3 100644 --- a/packages/backend/src/libs/prisma.ts +++ b/packages/backend/src/libs/prisma.ts @@ -3,4 +3,6 @@ import { PrismaClient } from '@prisma/client'; /** * Prisma ORMクライアント */ -export const prisma = new PrismaClient(); +export const prisma = new PrismaClient({ + log: ['query', 'info', 'warn', 'error'], +}); diff --git a/packages/backend/src/server/controllers/callback-miauth.ts b/packages/backend/src/server/controllers/callback-miauth.ts index c53d06a..519fbf7 100644 --- a/packages/backend/src/server/controllers/callback-miauth.ts +++ b/packages/backend/src/server/controllers/callback-miauth.ts @@ -23,6 +23,7 @@ export const callbackMiauthController: RouteHandler<{Querystring: {session: stri return; } + const url = `https://${host}/api/miauth/${session}/check`; const res = await axios.post(url, {}); const { token, user } = res.data; @@ -34,6 +35,7 @@ export const callbackMiauthController: RouteHandler<{Querystring: {session: stri return; } + console.log(`Try to get a Misskey access token from ${host} with session ${session}...`); const accessToken = await processLogin(user, host, token); await reply.view('frontend', { token: accessToken }); }; diff --git a/packages/backend/src/services/accounts/generate-access-token.ts b/packages/backend/src/services/accounts/generate-access-token.ts index 2be677a..056bcf4 100644 --- a/packages/backend/src/services/accounts/generate-access-token.ts +++ b/packages/backend/src/services/accounts/generate-access-token.ts @@ -13,6 +13,6 @@ export const generateAccessToken = async (): Promise => { do { token = rndstr(32); used = await prisma.usedToken.findUnique({ where: { token } }); - } while (used !== undefined); + } while (used != null); return token; }; diff --git a/packages/backend/src/services/schedule-note/get.ts b/packages/backend/src/services/schedule-note/get.ts index b7ec7fa..0328576 100644 --- a/packages/backend/src/services/schedule-note/get.ts +++ b/packages/backend/src/services/schedule-note/get.ts @@ -8,7 +8,7 @@ export const getScheduledNotes = async (account: Account) => { const notes = await prisma.scheduledNote.findMany({ where: { misskeySessionId: { in: sessionIds } }, - orderBy: { date: 'asc' }, + orderBy: { date: 'desc' }, select: { id: true, misskeySessionId: true, diff --git a/packages/frontend/package.json b/packages/frontend/package.json index a9f5553..55ee651 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -14,6 +14,7 @@ "dependencies": { "@babel/preset-react": "^7.18.6", "@radix-ui/colors": "^0.1.8", + "@radix-ui/react-alert-dialog": "^1.0.3", "@radix-ui/react-dropdown-menu": "^2.0.4", "@radix-ui/react-label": "^2.0.1", "@radix-ui/react-radio-group": "^1.1.2", @@ -72,7 +73,7 @@ "tools-backend": "workspace:*", "tools-tsconfig": "workspace:*", "typescript": "5.0.4", - "vite": "^4.3.3", + "vite": "^4.3.8", "vite-tsconfig-paths": "^4.2.0", "vitest": "^0.30.1" } diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 377dc62..ac26488 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -17,6 +17,7 @@ const AnnouncementsPage = lazy(() => import('@/pages/announcements')); const AboutPage = lazy(() => import('@/pages/about')); const AppsNoteScheduler = lazy(() => import('@/pages/apps/note-scheduler')); const AppsNoteSchedulerNew = lazy(() => import('@/pages/apps/note-scheduler.new')); +const AppsNoteSchedulerEdit = lazy(() => import('@/pages/apps/note-scheduler.edit')); const NotFound = lazy(() => import('@/pages/not-found')); export const App : React.FC = () => { @@ -37,6 +38,7 @@ export const App : React.FC = () => { }/> }/> }/> + }/> }/> diff --git a/packages/frontend/src/components/domains/note-scheduler/NoteSchedulerForm.tsx b/packages/frontend/src/components/domains/note-scheduler/NoteSchedulerForm.tsx index afee602..635d456 100644 --- a/packages/frontend/src/components/domains/note-scheduler/NoteSchedulerForm.tsx +++ b/packages/frontend/src/components/domains/note-scheduler/NoteSchedulerForm.tsx @@ -21,6 +21,7 @@ import { trpc } from '@/libs/trpc'; export type NoteSchedulerFormProp = { id?: string; disabled?: boolean; + initialNote?: Draft; onSubmit?: (draft: Draft) => void; }; @@ -50,6 +51,7 @@ export const NoteSchedulerForm: React.FC = (p) => { }), [sessions]); const [draft, setDraft] = useState(draftDefault); + const [dateError, setDateError] = useState(null); useEffect(() => { if (!p.id) { @@ -69,6 +71,11 @@ export const NoteSchedulerForm: React.FC = (p) => { }); }, [draftDefault, notes, p.id]); + useEffect(() => { + if (!p.initialNote) return; + setDraft(p.initialNote); + }, [p.initialNote]); + const updateDraft = useCallback((key: T, value: Draft[T]) => { setDraft({ ...draft, @@ -76,6 +83,17 @@ export const NoteSchedulerForm: React.FC = (p) => { }); }, [draft]); + const onChangeDate = useCallback((e: React.ChangeEvent) => { + updateDraft('dateString', e.target.value); + if (Date.now() >= Date.parse(e.target.value)) { + setDateError('過去の時間を指定することはできません。'); + return; + } + setDateError(null); + }, [updateDraft]); + + const canPost = draft.text.length > 0 && draft.text.length <= 3000 && !dateError; + return ( @@ -138,11 +156,12 @@ export const NoteSchedulerForm: React.FC = (p) => { {t('datetime')} - updateDraft('dateString', e.target.value)}> + + {dateError && {dateError}} - diff --git a/packages/frontend/src/components/primitives/Alert.tsx b/packages/frontend/src/components/primitives/Alert.tsx new file mode 100644 index 0000000..8e9334c --- /dev/null +++ b/packages/frontend/src/components/primitives/Alert.tsx @@ -0,0 +1,98 @@ +import * as $ from '@radix-ui/react-alert-dialog'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { HStack } from '../layouts/HStack'; + +import { Button } from './Button'; + +import { styled, keyframes } from '@/libs/stitches'; + +export type AlertProp = { + open: boolean; + onOpenChange: (state: boolean) => void; + title?: string; + description: string; + cancelText?: string; + okText?: string; + danger?: boolean; + onOkClick?: () => void; +}; + +export const Alert: React.FC = (p) => { + const { t } = useTranslation(); + + return ( + <$.Root open={p.open} onOpenChange={p.onOpenChange}> + <$.Portal> + + + {p.title && {p.title}} + + {p.description} + + + <$.Cancel asChild> + + + <$.Action asChild> + + + + + + + ); +}; + +const overlayShow = keyframes({ + '0%': { opacity: 0 }, + '100%': { opacity: 1 }, +}); + +const contentShow = keyframes({ + '0%': { opacity: 0, transform: 'translate(-50%, -48%) scale(.96)' }, + '100%': { opacity: 1, transform: 'translate(-50%, -50%) scale(1)' }, +}); + +const AlertDialogOverlay = styled($.Overlay, { + backgroundColor: '$overlayBg', + position: 'fixed', + inset: 0, + animation: `${overlayShow} 0.2s $timingFunction$default`, +}); + +const AlertDialogContent = styled($.Content, { + position: 'fixed', + top: '50%', + left: '50%', + width: '90vw', + maxWidth: '500px', + maxHeight: '85vh', + backgroundColor: '$card', + color: '$fg', + borderRadius: '$2', + boxShadow: '$l', + transform: 'translate(-50%, -50%)', + padding: '$m $l', + animation: `${contentShow} 0.2s $timingFunction$default`, + + '&:focus': { outline: 'none' }, +}); + +const AlertDialogTitle = styled($.Title, { + margin: 0, + color: '$fg', + fontSize: '$xl', + fontWeight: 'bold', + paddingBottom: '$xs', +}); + +const AlertDialogDescription = styled($.Description, { + color: '$muted', + fontSize: '$m', +}); diff --git a/packages/frontend/src/components/primitives/Button.ts b/packages/frontend/src/components/primitives/Button.ts index 0ba9a5f..0e4632f 100644 --- a/packages/frontend/src/components/primitives/Button.ts +++ b/packages/frontend/src/components/primitives/Button.ts @@ -94,7 +94,7 @@ export const Button = styled('button', { }, size: { small: { - padding: '$xxs $s', + padding: '$2xs $s', fontSize: '$xs', }, medium: { @@ -131,5 +131,22 @@ export const Button = styled('button', { }, }, }, + { + danger: true, + flat: true, + css: { + color: '$danger', + borderColor: 'transparent', + background: 'transparent', + '&:not(:disabled):hover': { + background: '$flatHover', + borderColor: 'transparent', + }, + '&:not(:disabled):active': { + background: '$flatActive', + borderColor: 'transparent', + }, + }, + }, ], }); diff --git a/packages/frontend/src/components/primitives/Input.ts b/packages/frontend/src/components/primitives/Input.ts index c2fbc49..e60df8a 100644 --- a/packages/frontend/src/components/primitives/Input.ts +++ b/packages/frontend/src/components/primitives/Input.ts @@ -10,7 +10,7 @@ export const Input = styled('input', { color: '$fg', fontSize: '$m', border: '1px solid $divider', - transition: 'all 0.2s $timingFunction$default', + transition: 'all 0.2s ', '&:focus': { borderColor: '$primary', diff --git a/packages/frontend/src/langs/ja-JP.json b/packages/frontend/src/langs/ja-JP.json index 8699a6b..303770e 100644 --- a/packages/frontend/src/langs/ja-JP.json +++ b/packages/frontend/src/langs/ja-JP.json @@ -33,6 +33,7 @@ "ok": "OK", "yes": "はい", "no": "いいえ", + "cancel": "キャンセル", "termsOfService": "利用規約", "resetToDefault": "初期値に戻す", "error": "エラー", @@ -188,7 +189,9 @@ "_noteScheduler": { "createNew": "新規作成", "edit": "編集", + "delete": "削除", "noNotes": "予約投稿はまだ作成されていません。", + "deleteConfirm": "本当に予約投稿「{{note}}」を削除しますか?", "accountToNote": "投稿するアカウント", "schedule": "投稿を予約" } diff --git a/packages/frontend/src/libs/stitches.ts b/packages/frontend/src/libs/stitches.ts index 88cf14d..b69edfa 100644 --- a/packages/frontend/src/libs/stitches.ts +++ b/packages/frontend/src/libs/stitches.ts @@ -46,6 +46,7 @@ export const { switchBg: olive.olive7, switchBgOn: '$primary', switchThumb: olive.olive1, + overlayBg: blackA.blackA9, }, space: { none: '0', @@ -123,6 +124,7 @@ export const darkTheme = createTheme('dark', { flatHover: whiteA.whiteA6, flatActive: whiteA.whiteA5, switchBg: oliveDark.olive8, + overlayBg: whiteA.whiteA9, }, }); diff --git a/packages/frontend/src/pages/apps/note-scheduler.edit.tsx b/packages/frontend/src/pages/apps/note-scheduler.edit.tsx new file mode 100644 index 0000000..ea0fa1c --- /dev/null +++ b/packages/frontend/src/pages/apps/note-scheduler.edit.tsx @@ -0,0 +1,60 @@ +import dayjs from 'dayjs'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router'; +import { useParams } from 'react-router-dom'; + +import type { Draft } from '@/components/domains/note-scheduler/NoteSchedulerForm'; + +import { NoteSchedulerForm } from '@/components/domains/note-scheduler/NoteSchedulerForm'; +import { PageRoot } from '@/components/PageRoot'; +import { Heading } from '@/components/primitives/Heading'; +import { trpc } from '@/libs/trpc'; + +const NoteSchedulerEditPage: React.FC = () => { + const { t } = useTranslation(); + const navigate = useNavigate(); + const { mutateAsync: createAsync, isLoading: isCreating } = trpc.scheduleNote.create.useMutation(); + const { mutateAsync: deleteAsync, isLoading: isDeleting } = trpc.scheduleNote.delete.useMutation(); + const [list] = trpc.scheduleNote.list.useSuspenseQuery(); + const { id } = useParams(); + + const note = list.find(n => n.id === id); + + if (!id || !note) throw new Error('no such note'); + + const onSubmit = async (draft: Draft) => { + await deleteAsync(id); + await createAsync({ + note: { + cw: draft.isCwEnabled ? draft.cw : null, + localOnly: draft.localOnly, + text: draft.text, + visibility: draft.visibility as any, + visibleUserIds: [], + }, + timestamp: dayjs.tz(draft.dateString).utc().toDate(), + sessionId: draft.sessionId, + }); + navigate('/apps/note-scheduler'); + }; + + const initialNote: Draft = { + text: note.text, + isCwEnabled: note.cw != null, + cw: note.cw ?? '', + dateString: dayjs(note.date).tz().format('YYYY-MM-DDTHH:mm'), + visibility: note.visibility, + localOnly: note.localOnly, + sessionId: note.misskeySessionId, + }; + + return ( + + {t('_noteScheduler.edit')} + + + ); +}; + +export default NoteSchedulerEditPage; diff --git a/packages/frontend/src/pages/apps/note-scheduler.tsx b/packages/frontend/src/pages/apps/note-scheduler.tsx index 6b918a0..1d9b4cd 100644 --- a/packages/frontend/src/pages/apps/note-scheduler.tsx +++ b/packages/frontend/src/pages/apps/note-scheduler.tsx @@ -1,14 +1,132 @@ -import React from 'react'; +import dayjs from 'dayjs'; +import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; +import type { RouterOutput } from '@/libs/trpc'; + +import { HStack } from '@/components/layouts/HStack'; import { VStack } from '@/components/layouts/VStack'; import { PageRoot } from '@/components/PageRoot'; +import { Alert } from '@/components/primitives/Alert'; import { Button } from '@/components/primitives/Button'; import { Heading } from '@/components/primitives/Heading'; import { Text } from '@/components/primitives/Text'; +import { styled } from '@/libs/stitches'; import { trpc } from '@/libs/trpc'; +const NoteCardContainer = styled('div', { + padding: '$m', + borderRadius: '$3', + background: '$card', + color: '$fg', + boxShadow: '$s', + + small: { + color: '$muted', + }, + + variants: { + pale: { + true: { + background: '$cardPale', + boxShadow: 'none', + }, + }, + }, +}); + +const Header = styled('div', { + display: 'flex', + color: '$muted', +}); + +const Visibility = styled('div', { + marginLeft: 'auto', +}); + +const MarginRight = styled('div', { + marginRight: '$2xs', +}); + +const NoteCard: React.FC<{ note: RouterOutput['scheduleNote']['list'][number] }> = ({ note }) => { + const [deleteConfirmDialogOpened, setDeleteConfirmDialogOpened] = useState(false); + + const { t } = useTranslation(); + const [sessions] = trpc.account.getMisskeySessions.useSuspenseQuery(); + const { mutateAsync: deleteAsync } = trpc.scheduleNote.delete.useMutation(); + const [_, { refetch }] = trpc.scheduleNote.list.useSuspenseQuery(); + + const date = dayjs(note.date); + const session = sessions.find(s => s.id === note.misskeySessionId); + + const deleteConfirm = () => { + setDeleteConfirmDialogOpened(true); + }; + + const del = async () => { + await deleteAsync(note.id); + refetch(); + }; + + const sent = date.isBefore(dayjs()); + + return ( + + +
+ @{session?.username}@{session?.host} + + + {note.localOnly && } + +
+ {note.cw ? ( +
+ {note.cw} + {note.text} +
+ ) :
{note.text}
} + + + + + + + {' '}に + { sent ? '送信済み' : '送信予定' } + + + + + {!sent && ( + + )} + + +
+ +
+ ); +}; + +const visibilityIcon: Record = { + public: 'ti ti-world', + home: 'ti ti-home', + followers: 'ti ti-lock', + specified: 'ti ti-mail', +}; + const NoteSchedulerPage: React.FC = () => { const [notes] = trpc.scheduleNote.list.useSuspenseQuery(); const { t } = useTranslation(); @@ -27,7 +145,7 @@ const NoteSchedulerPage: React.FC = () => { 予約投稿はまだ作成されていません。 - ) : (notes.map(n =>

{n.text}

))} + ) : (notes.map(n => ))}
diff --git a/packages/frontend/src/style.scss b/packages/frontend/src/style.scss index 9e113f8..305b97b 100644 --- a/packages/frontend/src/style.scss +++ b/packages/frontend/src/style.scss @@ -6,10 +6,10 @@ @font-face { font-family: "Koruri"; - src: url("./fonts/koruri-regular.eot"); - src: url("./fonts/koruri-regular.eot?#iefix") format("embedded-opentype"), - url("./fonts/koruri-regular.woff") format("woff"), - url("./fonts/koruri-regular.ttf") format("truetype"); + src: url("/fonts/koruri-regular.eot"); + src: url("/fonts/koruri-regular.eot?#iefix") format("embedded-opentype"), + url("/fonts/koruri-regular.woff") format("woff"), + url("/fonts/koruri-regular.ttf") format("truetype"); font-style: normal; font-weight: 400; font-display: swap; @@ -17,10 +17,10 @@ @font-face { font-family: "Koruri"; - src: url("./fonts/koruri-semibold.eot"); - src: url("./fonts/koruri-semibold.eot?#iefix") format("embedded-opentype"), - url("./fonts/koruri-semibold.woff") format("woff"), - url("./fonts/koruri-semibold.ttf") format("truetype"); + src: url("/fonts/koruri-semibold.eot"); + src: url("/fonts/koruri-semibold.eot?#iefix") format("embedded-opentype"), + url("/fonts/koruri-semibold.woff") format("woff"), + url("/fonts/koruri-semibold.ttf") format("truetype"); font-style: normal; font-weight: 500; font-display: swap; @@ -28,10 +28,10 @@ @font-face { font-family: "Koruri"; - src: url("./fonts/koruri-bold.eot"); - src: url("./fonts/koruri-bold.eot?#iefix") format("embedded-opentype"), - url("./fonts/koruri-bold.woff") format("woff"), - url("./fonts/koruri-bold.ttf") format("truetype"); + src: url("/fonts/koruri-bold.eot"); + src: url("/fonts/koruri-bold.eot?#iefix") format("embedded-opentype"), + url("/fonts/koruri-bold.woff") format("woff"), + url("/fonts/koruri-bold.ttf") format("truetype"); font-style: normal; font-weight: 700; font-display: swap; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e74ccd..affb5f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,8 +5,8 @@ importers: .: devDependencies: turbo: - specifier: ^1.9.3 - version: 1.9.3 + specifier: ^1.9.9 + version: 1.9.9 packages/backend: dependencies: @@ -152,6 +152,9 @@ importers: '@radix-ui/colors': specifier: ^0.1.8 version: 0.1.8 + '@radix-ui/react-alert-dialog': + specifier: ^1.0.3 + version: 1.0.3(@types/react@18.2.0)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-dropdown-menu': specifier: ^2.0.4 version: 2.0.4(@types/react@18.2.0)(react-dom@18.2.0)(react@18.2.0) @@ -266,13 +269,13 @@ importers: version: 7.0.7(react-dom@18.2.0)(react@18.2.0) '@storybook/builder-vite': specifier: ^7.0.7 - version: 7.0.7(typescript@5.0.4)(vite@4.3.3) + version: 7.0.7(typescript@5.0.4)(vite@4.3.8) '@storybook/react': specifier: ^7.0.7 version: 7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.4) '@storybook/react-vite': specifier: ^7.0.7 - version: 7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.4)(vite@4.3.3) + version: 7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.4)(vite@4.3.8) '@storybook/testing-library': specifier: ^0.1.0 version: 0.1.0 @@ -296,7 +299,7 @@ importers: version: 0.4.0 '@vitejs/plugin-react': specifier: ^4.0.0 - version: 4.0.0(vite@4.3.3) + version: 4.0.0(vite@4.3.8) eslint-config-tools: specifier: workspace:* version: link:../eslint-config @@ -322,11 +325,11 @@ importers: specifier: 5.0.4 version: 5.0.4 vite: - specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3)(sass@1.62.1) + specifier: ^4.3.8 + version: 4.3.8(@types/node@18.16.3)(sass@1.62.1) vite-tsconfig-paths: specifier: ^4.2.0 - version: 4.2.0(typescript@5.0.4)(vite@4.3.3) + version: 4.2.0(typescript@5.0.4)(vite@4.3.8) vitest: specifier: ^0.30.1 version: 0.30.1(sass@1.62.1) @@ -2224,7 +2227,7 @@ packages: '@types/yargs': 17.0.24 chalk: 4.1.2 - /@joshwooding/vite-plugin-react-docgen-typescript@0.2.1(typescript@5.0.4)(vite@4.3.3): + /@joshwooding/vite-plugin-react-docgen-typescript@0.2.1(typescript@5.0.4)(vite@4.3.8): resolution: {integrity: sha512-ou4ZJSXMMWHqGS4g8uNRbC5TiTWxAgQZiVucoUrOCWuPrTbkpJbmVyIi9jU72SBry7gQtuMEDp4YR8EEXAg7VQ==} peerDependencies: typescript: '>= 4.3.x' @@ -2238,7 +2241,7 @@ packages: magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.0.4) typescript: 5.0.4 - vite: 4.3.3(@types/node@18.16.3)(sass@1.62.1) + vite: 4.3.8(@types/node@18.16.3)(sass@1.62.1) dev: true /@jridgewell/gen-mapping@0.3.3: @@ -2405,6 +2408,25 @@ packages: '@babel/runtime': 7.21.5 dev: false + /@radix-ui/react-alert-dialog@1.0.3(@types/react@18.2.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-QXFy7+bhGi0u+paF2QbJeSCHZs4gLMJIPm6sajUamyW0fro6g1CaSGc5zmc4QmK2NlSGUrq8m+UsUqJYtzvXow==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/primitive': 1.0.0 + '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) + '@radix-ui/react-context': 1.0.0(react@18.2.0) + '@radix-ui/react-dialog': 1.0.3(@types/react@18.2.0)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.1(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + dev: false + /@radix-ui/react-arrow@1.0.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-fqYwhhI9IarZ0ll2cUSfKuXHlJK0qE4AfnRrPBbRwEH/4mGQn04/QFGomLi8TXWIdv9WJk//KgGm+aDxVIr1wA==} peerDependencies: @@ -2450,6 +2472,33 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-dialog@1.0.3(@types/react@18.2.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-owNhq36kNPqC2/a+zJRioPg6HHnTn5B/sh/NjTY8r4W9g1L5VJlrzZIVcBr7R9Mg8iLjVmh6MGgMlfoVf/WO/A==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/primitive': 1.0.0 + '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) + '@radix-ui/react-context': 1.0.0(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.3(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.0(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.2(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.0(react@18.2.0) + '@radix-ui/react-portal': 1.0.2(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.0(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.1(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0) + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.0)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + dev: false + /@radix-ui/react-direction@1.0.0(react@18.2.0): resolution: {integrity: sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==} peerDependencies: @@ -3158,7 +3207,7 @@ packages: - supports-color dev: true - /@storybook/builder-vite@7.0.7(typescript@5.0.4)(vite@4.3.3): + /@storybook/builder-vite@7.0.7(typescript@5.0.4)(vite@4.3.8): resolution: {integrity: sha512-2wL6fsFWzij+R155urOLc7EjZtlVWf4FLfaSlLGAuZwRQU40N04YdMaHMp9tjd9Vdr5fxEDwTB51PnVWJMlsEw==} peerDependencies: '@preact/preset-vite': '*' @@ -3194,7 +3243,7 @@ packages: remark-slug: 6.1.0 rollup: 3.21.2 typescript: 5.0.4 - vite: 4.3.3(@types/node@18.16.3)(sass@1.62.1) + vite: 4.3.8(@types/node@18.16.3)(sass@1.62.1) transitivePeerDependencies: - supports-color dev: true @@ -3536,7 +3585,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/react-vite@7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.4)(vite@4.3.3): + /@storybook/react-vite@7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.4)(vite@4.3.8): resolution: {integrity: sha512-RuWfP/kiLpuHdcF9dWUUp9SOGMmO0FJ0HGV5yAOhGmi8KmTzvc8zjC+hJjj+sSgn2n71BO8pG/zqGl16FwfwVQ==} engines: {node: '>=16'} peerDependencies: @@ -3544,17 +3593,17 @@ packages: react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 vite: ^3.0.0 || ^4.0.0 dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.2.1(typescript@5.0.4)(vite@4.3.3) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.2.1(typescript@5.0.4)(vite@4.3.8) '@rollup/pluginutils': 4.2.1 - '@storybook/builder-vite': 7.0.7(typescript@5.0.4)(vite@4.3.3) + '@storybook/builder-vite': 7.0.7(typescript@5.0.4)(vite@4.3.8) '@storybook/react': 7.0.7(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.4) - '@vitejs/plugin-react': 3.1.0(vite@4.3.3) + '@vitejs/plugin-react': 3.1.0(vite@4.3.8) ast-types: 0.14.2 magic-string: 0.27.0 react: 18.2.0 react-docgen: 6.0.0-alpha.3 react-dom: 18.2.0(react@18.2.0) - vite: 4.3.3(@types/node@18.16.3)(sass@1.62.1) + vite: 4.3.8(@types/node@18.16.3)(sass@1.62.1) transitivePeerDependencies: - '@preact/preset-vite' - supports-color @@ -4218,7 +4267,7 @@ packages: eslint-visitor-keys: 3.4.0 dev: true - /@vitejs/plugin-react@3.1.0(vite@4.3.3): + /@vitejs/plugin-react@3.1.0(vite@4.3.8): resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -4229,12 +4278,12 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.21.5) magic-string: 0.27.0 react-refresh: 0.14.0 - vite: 4.3.3(@types/node@18.16.3)(sass@1.62.1) + vite: 4.3.8(@types/node@18.16.3)(sass@1.62.1) transitivePeerDependencies: - supports-color dev: true - /@vitejs/plugin-react@4.0.0(vite@4.3.3): + /@vitejs/plugin-react@4.0.0(vite@4.3.8): resolution: {integrity: sha512-HX0XzMjL3hhOYm+0s95pb0Z7F8O81G7joUHgfDd/9J/ZZf5k4xX6QAMFkKsHFxaHlf6X7GD7+XuaZ66ULiJuhQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -4244,7 +4293,7 @@ packages: '@babel/plugin-transform-react-jsx-self': 7.21.0(@babel/core@7.21.5) '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.21.5) react-refresh: 0.14.0 - vite: 4.3.3(@types/node@18.16.3)(sass@1.62.1) + vite: 4.3.8(@types/node@18.16.3)(sass@1.62.1) transitivePeerDependencies: - supports-color dev: true @@ -11072,65 +11121,65 @@ packages: typescript: 5.0.4 dev: true - /turbo-darwin-64@1.9.3: - resolution: {integrity: sha512-0dFc2cWXl82kRE4Z+QqPHhbEFEpUZho1msHXHWbz5+PqLxn8FY0lEVOHkq5tgKNNEd5KnGyj33gC/bHhpZOk5g==} + /turbo-darwin-64@1.9.9: + resolution: {integrity: sha512-UDGM9E21eCDzF5t1F4rzrjwWutcup33e7ZjNJcW/mJDPorazZzqXGKEPIy9kXwKhamUUXfC7668r6ZuA1WXF2Q==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.9.3: - resolution: {integrity: sha512-1cYbjqLBA2zYE1nbf/qVnEkrHa4PkJJbLo7hnuMuGM0bPzh4+AnTNe98gELhqI1mkTWBu/XAEeF5u6dgz0jLNA==} + /turbo-darwin-arm64@1.9.9: + resolution: {integrity: sha512-VyfkXzTJpYLTAQ9krq2myyEq7RPObilpS04lgJ4OO1piq76RNmSpX9F/t9JCaY9Pj/4TL7i0d8PM7NGhwEA5Ag==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.9.3: - resolution: {integrity: sha512-UuBPFefawEwpuxh5pM9Jqq3q4C8M0vYxVYlB3qea/nHQ80pxYq7ZcaLGEpb10SGnr3oMUUs1zZvkXWDNKCJb8Q==} + /turbo-linux-64@1.9.9: + resolution: {integrity: sha512-Fu1MY29Odg8dHOqXcpIIGC3T63XLOGgnGfbobXMKdrC7JQDvtJv8TUCYciRsyknZYjyyKK1z6zKuYIiDjf3KeQ==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.9.3: - resolution: {integrity: sha512-vUrNGa3hyDtRh9W0MkO+l1dzP8Co2gKnOVmlJQW0hdpOlWlIh22nHNGGlICg+xFa2f9j4PbQlWTsc22c019s8Q==} + /turbo-linux-arm64@1.9.9: + resolution: {integrity: sha512-50LI8NafPuJxdnMCBeDdzgyt1cgjQG7FwkyY336v4e95WJPUVjrHdrKH6jYXhOUyrv9+jCJxwX1Yrg02t5yJ1g==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.9.3: - resolution: {integrity: sha512-0BZ7YaHs6r+K4ksqWus1GKK3W45DuDqlmfjm/yuUbTEVc8szmMCs12vugU2Zi5GdrdJSYfoKfEJ/PeegSLIQGQ==} + /turbo-windows-64@1.9.9: + resolution: {integrity: sha512-9IsTReoLmQl1IRsy3WExe2j2RKWXQyXujfJ4fXF+jp08KxjVF4/tYP2CIRJx/A7UP/7keBta27bZqzAjsmbSTA==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.9.3: - resolution: {integrity: sha512-QJUYLSsxdXOsR1TquiOmLdAgtYcQ/RuSRpScGvnZb1hY0oLc7JWU0llkYB81wVtWs469y8H9O0cxbKwCZGR4RQ==} + /turbo-windows-arm64@1.9.9: + resolution: {integrity: sha512-CUu4hpeQo68JjDr0V0ygTQRLbS+/sNfdqEVV+Xz9136vpKn2WMQLAuUBVZV0Sp0S/7i+zGnplskT0fED+W46wQ==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.9.3: - resolution: {integrity: sha512-ID7mxmaLUPKG/hVkp+h0VuucB1U99RPCJD9cEuSEOdIPoSIuomcIClEJtKamUsdPLhLCud+BvapBNnhgh58Nzw==} + /turbo@1.9.9: + resolution: {integrity: sha512-+ZS66LOT7ahKHxh6XrIdcmf2Yk9mNpAbPEj4iF2cs0cAeaDU3xLVPZFF0HbSho89Uxwhx7b5HBgPbdcjQTwQkg==} hasBin: true requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.9.3 - turbo-darwin-arm64: 1.9.3 - turbo-linux-64: 1.9.3 - turbo-linux-arm64: 1.9.3 - turbo-windows-64: 1.9.3 - turbo-windows-arm64: 1.9.3 + turbo-darwin-64: 1.9.9 + turbo-darwin-arm64: 1.9.9 + turbo-linux-64: 1.9.9 + turbo-linux-arm64: 1.9.9 + turbo-windows-64: 1.9.9 + turbo-windows-arm64: 1.9.9 dev: true /twemoji-parser@14.0.0: @@ -11537,7 +11586,7 @@ packages: mlly: 1.2.0 pathe: 1.1.0 picocolors: 1.0.0 - vite: 4.3.3(@types/node@18.16.3)(sass@1.62.1) + vite: 4.3.8(@types/node@18.16.3)(sass@1.62.1) transitivePeerDependencies: - '@types/node' - less @@ -11548,7 +11597,7 @@ packages: - terser dev: true - /vite-tsconfig-paths@4.2.0(typescript@5.0.4)(vite@4.3.3): + /vite-tsconfig-paths@4.2.0(typescript@5.0.4)(vite@4.3.8): resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==} peerDependencies: vite: '*' @@ -11559,14 +11608,14 @@ packages: debug: 4.3.4 globrex: 0.1.2 tsconfck: 2.1.1(typescript@5.0.4) - vite: 4.3.3(@types/node@18.16.3)(sass@1.62.1) + vite: 4.3.8(@types/node@18.16.3)(sass@1.62.1) transitivePeerDependencies: - supports-color - typescript dev: true - /vite@4.3.3(@types/node@18.16.3)(sass@1.62.1): - resolution: {integrity: sha512-MwFlLBO4udZXd+VBcezo3u8mC77YQk+ik+fbc0GZWGgzfbPP+8Kf0fldhARqvSYmtIWoAJ5BXPClUbMTlqFxrA==} + /vite@4.3.8(@types/node@18.16.3)(sass@1.62.1): + resolution: {integrity: sha512-uYB8PwN7hbMrf4j1xzGDk/lqjsZvCDbt/JC5dyfxc19Pg8kRm14LinK/uq+HSLNswZEoKmweGdtpbnxRtrAXiQ==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -11653,7 +11702,7 @@ packages: strip-literal: 1.0.1 tinybench: 2.5.0 tinypool: 0.4.0 - vite: 4.3.3(@types/node@18.16.3)(sass@1.62.1) + vite: 4.3.8(@types/node@18.16.3)(sass@1.62.1) vite-node: 0.30.1(@types/node@18.16.3)(sass@1.62.1) why-is-node-running: 2.2.2 transitivePeerDependencies: