diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..c175e41 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": [ + "plugin:@typescript-eslint/recommended" + ], + "rules": {} +} diff --git a/.gitignore b/.gitignore index 4d29575..41eb6e1 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +components-lib diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..a97639f --- /dev/null +++ b/.prettierignore @@ -0,0 +1,14 @@ +.cache +.next +.db +.history +out +node_modules +package.json +package-lock.json +yarn.lock +public +*.md +*.mdx +.env* +!.env.validator.js diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..923983b --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,13 @@ +{ + "printWidth": 140, + "endOfLine": "lf", + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "arrowParens": "always", + "importOrder": ["^react$", "^(?!^react$|^@/|^[./]).*", "^@/(.*)$", "^[./]"], + "importOrderSeparation": true, + "importOrderSortSpecifiers": true, + "importOrderParserPlugins": ["jsx", "typescript"] +} diff --git a/MeetingsView.tsx b/MeetingsView.tsx new file mode 100644 index 0000000..67e8d20 --- /dev/null +++ b/MeetingsView.tsx @@ -0,0 +1,475 @@ +// how deploy +// how test +// server side pagination +// how to filer by date range +import { ActionsButton } from "@/components/ActionsButton"; +import { ConfirmMenuItem } from "@/components/ConfirmMenuItem"; +import { + DataList, + DataListCell, + DataListFooter, + DataListHeader, + DataListRow, +} from "@/components/DataList"; +import { DateAgo } from "@/components/DateAgo"; +import { Icon } from "@/components/Icons"; +import { + Pagination, + PaginationButtonFirstPage, + PaginationButtonLastPage, + PaginationButtonNextPage, + PaginationButtonPrevPage, + PaginationInfo, +} from "@/components/Pagination"; +import { useToastError, useToastSuccess } from "@/components/Toast"; +import { Page, PageContent } from "@/spa/layout"; +import { + useMeetingList, + useUserRemove, + useUserUpdate, +} from "@/spa/meetings.service"; +import { Meeting, User } from "@/spa/meetings.types"; +import { usePaginationFromUrl } from "@/spa/router"; +import { + Alert, + AlertDescription, + AlertIcon, + AlertTitle, + Avatar, + Box, + Button, + Center, + HStack, + Heading, + IconButton, + LinkBox, + LinkOverlay, + Menu, + MenuButton, + MenuDivider, + MenuGroup, + MenuItem, + MenuItemOption, + MenuList, + MenuOptionGroup, + MenuProps, + Portal, + Text, +} from "@chakra-ui/react"; +import React from "react"; +import { useTranslation } from "react-i18next"; +import { + FiCheckCircle, + FiChevronDown, + FiEdit, + FiPlus, + FiRefreshCw, + FiTrash2, + FiXCircle, +} from "react-icons/fi"; +import { Link } from "react-router-dom"; + +type UserActionProps = Omit & { user: User }; + +const UserActions = ({ user, ...rest }: UserActionProps) => { + const { t } = useTranslation(["common", "meetings"]); + const toastSuccess = useToastSuccess(); + const toastError = useToastError(); + const userUpdate = useUserUpdate({ + onSuccess: ({ activated, login }) => { + if (activated) { + toastSuccess({ + title: t("meetings:feedbacks.activateUserSuccess.title"), + description: t("meetings:feedbacks.activateUserSuccess.description", { + login, + }), + }); + } else { + toastSuccess({ + title: t("meetings:feedbacks.deactivateUserSuccess.title"), + description: t( + "meetings:feedbacks.deactivateUserSuccess.description", + { login } + ), + }); + } + }, + onError: (_, { activated, login }) => { + if (activated) { + toastError({ + title: t("meetings:feedbacks.activateUserError.title"), + description: t("meetings:feedbacks.activateUserError.description", { + login, + }), + }); + } else { + toastError({ + title: t("meetings:feedbacks.deactivateUserError.title"), + description: t("meetings:feedbacks.deactivateUserError.description", { + login, + }), + }); + } + }, + }); + + const activateUser = () => userUpdate.mutate({ ...user, activated: true }); + const deactivateUser = () => userUpdate.mutate({ ...user, activated: false }); + const isActionsLoading = userUpdate.isLoading; + + const userRemove = useUserRemove({ + onSuccess: (_, { login }) => { + toastSuccess({ + title: t("meetings:feedbacks.deleteUserSuccess.title"), + description: t("meetings:feedbacks.deleteUserSuccess.description", { + login, + }), + }); + }, + onError: (_, { login }) => { + toastError({ + title: t("meetings:feedbacks.deleteUserError.title"), + description: t("meetings:feedbacks.deleteUserError.description", { + login, + }), + }); + }, + }); + const removeUser = () => userRemove.mutate(user); + const isRemovalLoading = userRemove.isLoading; + + return ( + + + + + } + > + {t("common:actions.edit")} + + {user.activated ? ( + } + > + {t("common:actions.deactivate")} + + ) : ( + + } + > + {t("common:actions.activate")} + + )} + + } + onClick={removeUser} + > + {t("common:actions.delete")} + + + + + ); +}; + +const MeetingsView = () => { + const { t } = useTranslation(["meetings"]); + const { page, setPage } = usePaginationFromUrl(); + const pageSize = 20; + const meetings = useMeetingList({ page: page - 1, size: pageSize }); + const getContactName = (id: string) => { + const contact = meetings?.contacts?.find((contact) => contact.id === id); + return contact?.properties?.firstname + " " + contact?.properties?.lastname; + }; + const getContactEmail = (id: string) => { + const contact = meetings?.contacts?.find((contact) => contact.id === id); + return contact?.properties?.email; + }; + + return ( + + + + + {t("meetings:list.title")} + + + + + + } + display={{ base: "none", md: "flex" }} + > + Filter + + + Download + Create a Copy + Mark as Draft + Delete + Attend a Workshop + + + + } + variant="outline" + display={{ base: "flex", md: "none" }} + /> + + Download + Create a Copy + Mark as Draft + Delete + Attend a Workshop + + + + + + } + display={{ base: "none", md: "flex" }} + > + Actions + + + Download + Create a Copy + Mark as Draft + Delete + Attend a Workshop + + + + } + variant="outline" + display={{ base: "flex", md: "none" }} + /> + + Download + Create a Copy + Mark as Draft + Delete + Attend a Workshop + + + + + + } + display={{ base: "none", md: "flex" }} + > + Sort + + + Download + Create a Copy + Mark as Draft + Delete + Attend a Workshop + + + + } + variant="outline" + display={{ base: "flex", md: "none" }} + /> + + Download + Create a Copy + Mark as Draft + Delete + Attend a Workshop + + + + + + } + /> + + + + + + + {t("meetings:data.name.label")} + + + {t("meetings:data.time.label")} + + + {t("meetings:data.account.label")} + + + {t("meetings:data.nextSteps.label")} + + + + {meetings.isError && ( +
+ + + + {t("meetings:feedbacks.loadingUserError.title")} + + + {t("meetings:feedbacks.loadingUserError.description")} + + + +
+ )} + {meetings?.meetings + ?.slice(pageSize * (page - 1), pageSize * page) + .map((user) => ( + + + + + {user.properties.hs_meeting_title} + + + + + + {user.createdAt} + + {!!user.createdAt && ( + + + + )} + + + + + + + {getContactName( + user.associations?.contacts?.results[0]?.id || "" + )} + + + {getContactEmail( + user.associations?.contacts?.results[0]?.id || "" + )} + + + + + + + {user.properties.hs_internal_meeting_notes || + user.properties.hs_meeting_outcome} + + + + {/* */} + + + ))} + + + + + + + + + +
+
+
+ ); +}; + +export default MeetingsView; +// {!!user.createdAt && ( +// +// +// +// )} diff --git a/package-lock.json b/package-lock.json index 42d78c1..cb78a83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,10 @@ "@chakra-ui/react": "^2.6.1", "@emotion/react": "^11.11.0", "@emotion/styled": "^11.11.0", + "@fontsource/inter": "^4.5.15", + "@formkit/auto-animate": "^1.0.0-beta.6", + "@lukemorales/query-key-factory": "^1.2.0", + "@tanstack/react-query": "^4.29.5", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^14.4.3", @@ -18,13 +22,25 @@ "@types/node": "^12.20.55", "@types/react": "^18.2.6", "@types/react-dom": "^18.2.4", + "axios": "^1.4.0", + "date-fns": "^2.30.0", + "dayjs": "^1.11.7", "framer-motion": "^6.5.1", "react": "^18.2.0", + "react-day-picker": "^8.7.1", "react-dom": "^18.2.0", + "react-error-boundary": "^4.0.4", "react-icons": "^3.11.0", + "react-router-dom": "^6.11.1", "react-scripts": "5.0.1", + "react-use-measure": "^2.1.1", "typescript": "^4.9.5", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "@trivago/prettier-plugin-sort-imports": "^4.1.1", + "cypress": "^12.11.0", + "prettier": "^2.8.8" } }, "node_modules/@adobe/css-tools": { @@ -3026,6 +3042,16 @@ "react": ">=18" } }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@csstools/normalize.css": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", @@ -3296,6 +3322,96 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@cypress/request": { + "version": "2.88.11", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz", + "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "~6.10.3", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@cypress/request/node_modules/qs": { + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", + "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@cypress/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", @@ -3541,6 +3657,16 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fontsource/inter": { + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.5.15.tgz", + "integrity": "sha512-FzleM9AxZQK2nqsTDtBiY0PMEVWvnKnuu2i09+p6DHvrHsuucoV2j0tmw+kAT3L4hvsLdAIDv6MdGehsPIdT+Q==" + }, + "node_modules/@formkit/auto-animate": { + "version": "1.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-1.0.0-beta.6.tgz", + "integrity": "sha512-PVDhLAlr+B4Xb7e+1wozBUWmXa6BFU8xUPR/W/E+TsQhPS1qkAdAsJ25keEnFrcePSnXHrOsh3tiFbEToOzV9w==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -4315,6 +4441,17 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "node_modules/@lukemorales/query-key-factory": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@lukemorales/query-key-factory/-/query-key-factory-1.2.0.tgz", + "integrity": "sha512-ilUedLpJdpOCMKgxoncRkYEFF7C+K//IK/QWXHs0G6HjmZunT9XcrpWHNc5RjrBBqPhdxYNa7aUoEhjonwl4eQ==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@tanstack/query-core": "^4.0.0" + } + }, "node_modules/@motionone/animation": { "version": "10.15.1", "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.15.1.tgz", @@ -4491,6 +4628,14 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@remix-run/router": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.1.tgz", + "integrity": "sha512-YUkWj+xs0oOzBe74OgErsuR3wVn+efrFhXBWrit50kOiED+pvQe2r6MWY0iJMQU/mSVKxvNzL4ZaYvjdX+G7ZA==", + "engines": { + "node": ">=14" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -4809,6 +4954,41 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@tanstack/query-core": { + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.5.tgz", + "integrity": "sha512-xXIiyQ/4r9KfaJ3k6kejqcaqFXXBTzN2aOJ5H1J6aTJE9hl/nbgAdfF6oiIu0CD5xowejJEJ6bBg8TO7BN4NuQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.5.tgz", + "integrity": "sha512-F87cibC3s3eG0Q90g2O+hqntpCrudKFnR8P24qkH9uccEhXErnJxBC/AAI4cJRV2bfMO8IeGZQYf3WyYgmSg0w==", + "dependencies": { + "@tanstack/query-core": "4.29.5", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/@testing-library/dom": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.2.0.tgz", @@ -5099,6 +5279,86 @@ "node": ">= 6" } }, + "node_modules/@trivago/prettier-plugin-sort-imports": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.1.1.tgz", + "integrity": "sha512-dQ2r2uzNr1x6pJsuh/8x0IRA3CBUB+pWEW3J/7N98axqt7SQSm+2fy0FLNXvXGg77xEDC7KHxJlHfLYyi7PDcw==", + "dev": true, + "dependencies": { + "@babel/generator": "7.17.7", + "@babel/parser": "^7.20.5", + "@babel/traverse": "7.17.3", + "@babel/types": "7.17.0", + "javascript-natural-sort": "0.7.1", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "@vue/compiler-sfc": "3.x", + "prettier": "2.x" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + } + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/generator": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", + "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", @@ -5621,6 +5881,18 @@ "@types/node": "*" } }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, "node_modules/@types/sockjs": { "version": "0.3.33", "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", @@ -5668,6 +5940,16 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.59.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", @@ -6140,6 +6422,19 @@ "node": ">= 6.0.0" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -6199,6 +6494,15 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -6260,6 +6564,26 @@ "node": ">= 8" } }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -6404,11 +6728,38 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", @@ -6470,6 +6821,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, "node_modules/axe-core": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", @@ -6478,6 +6844,29 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", @@ -6771,11 +7160,40 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/bfj": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", @@ -6806,6 +7224,12 @@ "node": ">=8" } }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -6942,6 +7366,39 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -6966,6 +7423,15 @@ "node": ">= 0.8" } }, + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -7052,6 +7518,12 @@ "node": ">=4" } }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -7073,6 +7545,15 @@ "node": ">=10" } }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/check-types": { "version": "11.2.2", "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz", @@ -7161,17 +7642,69 @@ "node": ">=0.10.0" } }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/co": { + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", @@ -7847,11 +8380,248 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, + "node_modules/cypress": { + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.11.0.tgz", + "integrity": "sha512-TJE+CCWI26Hwr5Msb9GpQhFLubdYooW0fmlPwTsfiyxmngqc7+SZGLPeIkj2dTSSZSEtpQVzOzvcnzH0o8G7Vw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^2.88.10", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^14.14.31", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.6.0", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.3.2", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + } + }, + "node_modules/cypress/node_modules/@types/node": { + "version": "14.18.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.45.tgz", + "integrity": "sha512-Nd+FPp60jEaJpm4LAxuLT3wIhB4k0Jdj9DAP4ydqGyMg8DhE+7oM1we+QkwOkpMySTjcqcNfPOWY5kBuAOhkeg==", + "dev": true + }, + "node_modules/cypress/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cypress/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cypress/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cypress/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cypress/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cypress/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/cypress/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cypress/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/cypress/node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, + "node_modules/cypress/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -7865,6 +8635,31 @@ "node": ">=10" } }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -8204,6 +8999,16 @@ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -8260,6 +9065,15 @@ "node": ">= 0.8" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.13.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.13.0.tgz", @@ -8272,6 +9086,18 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -9181,6 +10007,12 @@ "node": ">= 0.6" } }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -9216,6 +10048,18 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -9297,6 +10141,56 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -9365,6 +10259,30 @@ "bser": "2.1.1" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -9562,6 +10480,15 @@ "is-callable": "^1.1.3" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", @@ -9957,6 +10884,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -9992,6 +10937,30 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -10419,6 +11388,20 @@ } } }, + "node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -10477,6 +11460,26 @@ "node": ">=4" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -10680,6 +11683,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, "node_modules/is-core-module": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", @@ -10754,6 +11769,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", @@ -10944,6 +11975,18 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakmap": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", @@ -10996,6 +12039,12 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -11173,6 +12222,12 @@ "node": ">=8" } }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "dev": true + }, "node_modules/jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -13084,6 +14139,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -13160,6 +14221,12 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -13190,6 +14257,21 @@ "node": ">=0.10.0" } }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", @@ -13248,6 +14330,15 @@ "shell-quote": "^1.7.3" } }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -13265,91 +14356,292 @@ "type-check": "~0.4.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/loader-runner": { + "node_modules/log-update/node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=6.11.5" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "node_modules/log-update/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "color-name": "~1.1.4" }, "engines": { - "node": ">=8.9.0" + "node": ">=7.0.0" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/log-update/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, "dependencies": { - "p-locate": "^5.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } }, "node_modules/loose-envify": { "version": "1.4.0", @@ -13999,6 +15291,12 @@ "node": ">= 0.8.0" } }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -14027,6 +15325,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-retry": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", @@ -14148,6 +15461,12 @@ "node": ">=8" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -15517,6 +16836,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -15621,11 +16955,26 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -15776,6 +17125,19 @@ "react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-day-picker": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.7.1.tgz", + "integrity": "sha512-Gv426AW8b151CZfh3aP5RUGztLwHB/EyJgWZ5iMgtzbFBkjHfG6Y66CIQFMWGLnYjsQ9DYSJRmJ5S0Pg5HWKjA==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/gpbl" + }, + "peerDependencies": { + "date-fns": "^2.28.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -15905,6 +17267,17 @@ "react": "^18.2.0" } }, + "node_modules/react-error-boundary": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.4.tgz", + "integrity": "sha512-AbqMFx8bCsob8rCHZvJYQ42MQijK0/034RUvan9qrqyJCpazr8d9vKHrysbxcr6odoHLZvQEcYomFPoIqH9fow==", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, "node_modules/react-error-overlay": { "version": "6.0.11", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", @@ -16014,6 +17387,36 @@ } } }, + "node_modules/react-router": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.11.1.tgz", + "integrity": "sha512-OZINSdjJ2WgvAi7hgNLazrEV8SGn6xrKA+MkJe9wVDMZ3zQ6fdJocUjpCUCI0cNrelWjcvon0S/QK/j0NzL3KA==", + "dependencies": { + "@remix-run/router": "1.6.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.11.1.tgz", + "integrity": "sha512-dPC2MhoPeTQ1YUOt5uIK376SMNWbwUxYRWk2ZmTT4fZfwlOvabF8uduRKKJIyfkCZvMgiF0GSCQckmkGGijIrg==", + "dependencies": { + "@remix-run/router": "1.6.1", + "react-router": "6.11.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -16108,6 +17511,18 @@ } } }, + "node_modules/react-use-measure": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz", + "integrity": "sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==", + "dependencies": { + "debounce": "^1.2.1" + }, + "peerDependencies": { + "react": ">=16.13", + "react-dom": ">=16.13" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -16268,6 +17683,15 @@ "strip-ansi": "^6.0.1" } }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -16388,6 +17812,19 @@ "node": ">=10" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -16405,6 +17842,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -16510,6 +17953,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-array-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", @@ -16889,6 +18341,53 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -16996,6 +18495,31 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -17646,6 +19170,18 @@ "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" }, + "node_modules/throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -17656,6 +19192,18 @@ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -17790,6 +19338,24 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -17947,6 +19513,15 @@ "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", @@ -18043,6 +19618,14 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -18104,6 +19687,26 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -19037,6 +20640,16 @@ "node": ">=10" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 38fb348..d79ddb9 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,10 @@ "@chakra-ui/react": "^2.6.1", "@emotion/react": "^11.11.0", "@emotion/styled": "^11.11.0", + "@fontsource/inter": "^4.5.15", + "@formkit/auto-animate": "^1.0.0-beta.6", + "@lukemorales/query-key-factory": "^1.2.0", + "@tanstack/react-query": "^4.29.5", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^14.4.3", @@ -13,11 +17,18 @@ "@types/node": "^12.20.55", "@types/react": "^18.2.6", "@types/react-dom": "^18.2.4", + "axios": "^1.4.0", + "date-fns": "^2.30.0", + "dayjs": "^1.11.7", "framer-motion": "^6.5.1", "react": "^18.2.0", + "react-day-picker": "^8.7.1", "react-dom": "^18.2.0", + "react-error-boundary": "^4.0.4", "react-icons": "^3.11.0", + "react-router-dom": "^6.11.1", "react-scripts": "5.0.1", + "react-use-measure": "^2.1.1", "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, @@ -41,5 +52,10 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "@trivago/prettier-plugin-sort-imports": "^4.1.1", + "cypress": "^12.11.0", + "prettier": "^2.8.8" } } diff --git a/public/index.html b/public/index.html index aa069f2..e46b73d 100644 --- a/public/index.html +++ b/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + Epicbrief Meetings diff --git a/src/App.test.tsx b/src/App.test.tsx deleted file mode 100644 index 44b1463..0000000 --- a/src/App.test.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from "react" -import { screen } from "@testing-library/react" -import { render } from "./test-utils" -import { App } from "./App" - -test("renders learn react link", () => { - render() - const linkElement = screen.getByText(/learn chakra/i) - expect(linkElement).toBeInTheDocument() -}) diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index 4d1d279..0000000 --- a/src/App.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as React from "react" -import { - ChakraProvider, - Box, - Text, - Link, - VStack, - Code, - Grid, - theme, -} from "@chakra-ui/react" -import { ColorModeSwitcher } from "./ColorModeSwitcher" -import { Logo } from "./Logo" - -export const App = () => ( - - - - - - - - Edit src/App.tsx and save to reload. - - - Learn Chakra - - - - - -) diff --git a/src/Logo.tsx b/src/Logo.tsx deleted file mode 100644 index ba97a8f..0000000 --- a/src/Logo.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import * as React from "react" -import { - chakra, - keyframes, - ImageProps, - forwardRef, - usePrefersReducedMotion, -} from "@chakra-ui/react" -import logo from "./logo.svg" - -const spin = keyframes` - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } -` - -export const Logo = forwardRef((props, ref) => { - const prefersReducedMotion = usePrefersReducedMotion() - - const animation = prefersReducedMotion - ? undefined - : `${spin} infinite 20s linear` - - return -}) diff --git a/src/components/DataList/index.tsx b/src/components/DataList/index.tsx new file mode 100644 index 0000000..f1aac6a --- /dev/null +++ b/src/components/DataList/index.tsx @@ -0,0 +1,276 @@ +import { + Accordion, + AccordionButton, + AccordionIcon, + AccordionItem, + AccordionPanel, + AccordionProps, + Box, + Flex, + FlexProps, + useBreakpointValue, +} from "@chakra-ui/react"; +import { useAutoAnimate } from "@formkit/auto-animate/react"; +import React, { FC, useContext, useEffect, useRef, useState } from "react"; + +type DataListColumns = Record; +type DataListContextValue = { + setColumns: React.Dispatch>; + columns: DataListColumns; + isHover: boolean; +}; +type DataListHeaderContextValue = boolean; + +export const DataListContext = React.createContext( + {} as any +); +export const DataListHeaderContext = + React.createContext(false); + +export type DataListCellProps = FlexProps & { + colName?: string; + colWidth?: string | number | Record; + isVisible?: boolean | boolean[] | Record; +}; + +export const DataListCell = ({ + children, + colName, + colWidth = 1, + isVisible = true, + ...rest +}: DataListCellProps) => { + const { columns, setColumns } = useContext(DataListContext); + const isInHeader = useContext(DataListHeaderContext); + const restRef = useRef(rest); + restRef.current = rest; + + useEffect(() => { + if (isInHeader && colName) { + setColumns((prevColumns) => ({ + ...prevColumns, + [colName]: { colWidth, isVisible, ...restRef.current }, + })); + } + }, [isInHeader, colName, colWidth, isVisible, setColumns]); + + const headerProps = !isInHeader ? columns?.[colName ?? ""] ?? {} : {}; + const { + isVisible: _isVisible = true, + colWidth: _colWidth = true, + ...cellProps + } = { + colWidth, + isVisible, + ...headerProps, + ...rest, + }; + + const showCell = useBreakpointValue( + typeof _isVisible === "object" ? _isVisible : { base: _isVisible } + ); + + const cellWidth = + useBreakpointValue( + typeof _colWidth === "object" ? _colWidth : { base: _colWidth } + ) ?? 0; + + if (!showCell) return null; + + const isWidthUnitless = /^[0-9.]+$/.test(String(cellWidth)); + + return ( + + {children} + + ); +}; + +export const DataListAccordion = ({ ...rest }) => { + return ; +}; + +export const DataListAccordionButton = ({ ...rest }) => { + return ( + + ); +}; + +export const DataListAccordionIcon = ({ ...rest }) => { + return ( + + ); +}; + +export const DataListAccordionPanel = ({ ...rest }) => { + return ( + + ); +}; + +export type DataListRowProps = FlexProps & { + isVisible?: boolean | boolean[] | Record; + isDisabled?: boolean; +}; + +export const DataListRow: FC> = ({ + isVisible = true, + isDisabled = false, + ...rest +}) => { + const { isHover } = useContext(DataListContext); + const showRow = useBreakpointValue( + typeof isVisible === "object" ? isVisible : { base: isVisible } + ); + const disabledProps = isDisabled + ? { + bg: "gray.50", + _dark: { borderBottomColor: "gray.900", bg: "whiteAlpha.50" }, + _hover: {}, + _focusVisible: {}, + "aria-disabled": true, + opacity: "1 !important", + css: { + "> *": { + opacity: 0.3, + }, + }, + } + : {}; + return ( + + ); +}; + +export type DataListHeaderProps = DataListRowProps; + +export const DataListHeader: FC< + React.PropsWithChildren +> = ({ ...rest }) => { + return ( + + + + ); +}; + +export type DataListFooterProps = DataListRowProps; + +export const DataListFooter: FC< + React.PropsWithChildren +> = ({ ...rest }) => { + return ( + + + + ); +}; + +export type DataListProps = AccordionProps & { + isHover?: boolean; +}; + +export const DataList: FC> = ({ + allowMultiple = true, + allowToggle = false, + isHover = true, + ...rest +}) => { + const [columns, setColumns] = useState({}); + const [listRef] = useAutoAnimate(); + + return ( + + + + ); +}; diff --git a/src/components/ErrorBoundary/index.tsx b/src/components/ErrorBoundary/index.tsx new file mode 100644 index 0000000..31fafee --- /dev/null +++ b/src/components/ErrorBoundary/index.tsx @@ -0,0 +1,60 @@ +import { + Alert, + AlertDescription, + AlertIcon, + AlertTitle, + Box, + Button, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalHeader, + ModalOverlay, + useDisclosure, +} from "@chakra-ui/react"; +import React, { FC } from "react"; +import { + FallbackProps, + ErrorBoundary as ReactErrorBoundary, +} from "react-error-boundary"; + +const ErrorFallback = ({ error }: FallbackProps) => { + const errorModal = useDisclosure(); + return ( + + + + + Error + + + + + + Error + + + {error.message} + + + + + + + + ); +}; + +export const ErrorBoundary: FC> = (props) => { + return ; +}; diff --git a/src/components/ErrorPage/Illustration403.tsx b/src/components/ErrorPage/Illustration403.tsx new file mode 100644 index 0000000..f156c71 --- /dev/null +++ b/src/components/ErrorPage/Illustration403.tsx @@ -0,0 +1,104 @@ +import { useId } from 'react'; + +import { + HTMLChakraProps, + ThemingProps, + chakra, + useTheme, +} from '@chakra-ui/react'; + +export const Illustration403 = ({ + colorScheme = 'gray', + ...rest +}: HTMLChakraProps<'svg'> & { colorScheme?: ThemingProps['colorScheme'] }) => { + const clipPathId01 = useId(); + const theme = useTheme(); + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/components/ErrorPage/Illustration404.tsx b/src/components/ErrorPage/Illustration404.tsx new file mode 100644 index 0000000..b36915f --- /dev/null +++ b/src/components/ErrorPage/Illustration404.tsx @@ -0,0 +1,412 @@ +import { useId } from 'react'; + +import { + HTMLChakraProps, + ThemingProps, + chakra, + useTheme, +} from '@chakra-ui/react'; + +export const Illustration404 = ({ + colorScheme = 'gray', + ...rest +}: HTMLChakraProps<'svg'> & { colorScheme?: ThemingProps['colorScheme'] }) => { + const clipPathId01 = useId(); + const clipPathId02 = useId(); + const theme = useTheme(); + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/components/ErrorPage/IllustrationDefault.tsx b/src/components/ErrorPage/IllustrationDefault.tsx new file mode 100644 index 0000000..f32fd13 --- /dev/null +++ b/src/components/ErrorPage/IllustrationDefault.tsx @@ -0,0 +1,147 @@ +import { useId } from 'react'; + +import { + HTMLChakraProps, + ThemingProps, + chakra, + useTheme, +} from '@chakra-ui/react'; + +export const IllustrationDefault = ({ + colorScheme = 'gray', + ...rest +}: HTMLChakraProps<'svg'> & { colorScheme?: ThemingProps['colorScheme'] }) => { + const clipPathId01 = useId(); + const theme = useTheme(); + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/src/components/ErrorPage/index.tsx b/src/components/ErrorPage/index.tsx new file mode 100644 index 0000000..8517d46 --- /dev/null +++ b/src/components/ErrorPage/index.tsx @@ -0,0 +1,58 @@ +import { Logo } from "../Logo"; +import { Illustration403 } from "./Illustration403"; +import { Illustration404 } from "./Illustration404"; +import { IllustrationDefault } from "./IllustrationDefault"; +import { Center, Heading, Stack, Text, Link } from "@chakra-ui/react"; +import React, { ReactElement } from "react"; + +const SupportedErrors: Record< + "default" | 403 | 404, + { illustration?: ReactElement } +> = { + default: { illustration: }, + 403: { illustration: }, + 404: { illustration: }, +}; + +export const ErrorPage = ({ errorCode }: { errorCode?: number }) => { + const errorType = + errorCode && errorCode in SupportedErrors + ? (errorCode as keyof typeof SupportedErrors) + : "default"; + const illustration = + SupportedErrors[errorType].illustration ?? + SupportedErrors.default.illustration ?? + null; + + return ( +
+ + {illustration} + + + + + Error Title + Error Description + {!!errorCode && ( + + `Error ${errorCode}` + + )} + + +
+ ); +}; diff --git a/src/components/Icons/Icon.tsx b/src/components/Icons/Icon.tsx new file mode 100644 index 0000000..907c2cd --- /dev/null +++ b/src/components/Icons/Icon.tsx @@ -0,0 +1,45 @@ +import React, { FC } from 'react'; + +import { + Box, + BoxProps, + Icon as ChakraIcon, + IconProps as ChakraIconProps, + forwardRef, +} from '@chakra-ui/react'; + +export type IconProps = BoxProps & { + icon: FC>; + iconProps?: ChakraIconProps; +}; + +export const Icon = forwardRef( + ({ icon: IconEl, iconProps, ...rest }, ref) => { + return ( + + + + ); + } +); diff --git a/src/components/Icons/index.ts b/src/components/Icons/index.ts new file mode 100644 index 0000000..76d7732 --- /dev/null +++ b/src/components/Icons/index.ts @@ -0,0 +1,2 @@ +export * from "./Icon"; +// export * from './icons-generated'; diff --git a/src/components/Logo/index.tsx b/src/components/Logo/index.tsx new file mode 100644 index 0000000..b0be92f --- /dev/null +++ b/src/components/Logo/index.tsx @@ -0,0 +1,69 @@ +import { chakra, useTheme } from "@chakra-ui/react"; +import React from "react"; + +// +export const Logo = ({ ...rest }) => { + // const theme = useTheme(); + // const gradientId = 'logo-brand-gradient'; + return ( + + Epicbrief + + + + + + + + + + + + + + ); +}; diff --git a/src/components/Pagination/index.tsx b/src/components/Pagination/index.tsx new file mode 100644 index 0000000..12ff423 --- /dev/null +++ b/src/components/Pagination/index.tsx @@ -0,0 +1,192 @@ +import { Icon } from "../Icons"; +import { + Box, + HStack, + IconButton, + IconButtonProps, + Spinner, + StackProps, +} from "@chakra-ui/react"; +import React, { FC, useContext } from "react"; +import { + FiChevronLeft, + FiChevronRight, + FiChevronsLeft, + FiChevronsRight, +} from "react-icons/fi"; + +export const getPaginationInfo = ({ + page = 1, + pageSize = 10, + totalItems = 0, +}) => { + const firstItemOnPage = (page - 1) * pageSize + 1; + const lastItemOnPage = Math.min( + (page - 1) * pageSize + pageSize, + totalItems ?? 0 + ); + const isFirstPage = firstItemOnPage <= 1; + const isLastPage = lastItemOnPage >= totalItems; + const firstPage = 1; + const lastPage = Math.ceil(totalItems / pageSize); + + return { + firstPage, + lastPage, + firstItemOnPage, + lastItemOnPage, + isFirstPage, + isLastPage, + }; +}; + +export type PaginationContextValue = { + page: PageType; + setPage: (page: PageType) => void; + firstPage: PageType; + isFirstPage: boolean; + lastPage: PageType; + isLastPage: boolean; + totalItems: number; + isLoadingPage: boolean; + pageSize: number; + firstItemOnPage: number; + lastItemOnPage: number; +}; + +export const PaginationContext = React.createContext({ + page: 0, + setPage: () => undefined, + firstPage: 0, + isFirstPage: false, + lastPage: 0, + isLastPage: false, + totalItems: 0, + isLoadingPage: false, + pageSize: 0, + firstItemOnPage: 0, + lastItemOnPage: 0, +}); + +export const PaginationButtonFirstPage: FC< + React.PropsWithChildren> +> = ({ ...rest }) => { + const { setPage, firstPage, isFirstPage } = useContext(PaginationContext); + return ( + setPage(firstPage)} + aria-label={"firstPage"} + icon={} + size="sm" + isDisabled={isFirstPage} + {...rest} + /> + ); +}; + +export const PaginationButtonPrevPage: FC< + React.PropsWithChildren> +> = ({ ...rest }) => { + const { setPage, page, isFirstPage } = useContext(PaginationContext); + return ( + setPage(page - 1)} + aria-label={"prevPage"} + icon={} + size="sm" + isDisabled={isFirstPage} + {...rest} + /> + ); +}; + +export const PaginationButtonLastPage: FC< + React.PropsWithChildren> +> = ({ ...rest }) => { + const { setPage, lastPage, isLastPage } = useContext(PaginationContext); + return ( + setPage(lastPage)} + aria-label={"lastPage"} + icon={} + size="sm" + isDisabled={isLastPage} + {...rest} + /> + ); +}; + +export const PaginationButtonNextPage: FC< + React.PropsWithChildren> +> = ({ ...rest }) => { + const { setPage, page, isLastPage } = useContext(PaginationContext); + return ( + setPage(page + 1)} + aria-label={"nextPage"} + icon={} + size="sm" + isDisabled={isLastPage} + {...rest} + /> + ); +}; + +export const PaginationInfo = ({ ...rest }) => { + const { firstItemOnPage, lastItemOnPage, totalItems, isLoadingPage } = + useContext(PaginationContext); + return ( + + {isLoadingPage ? ( + + + loading {firstItemOnPage} - {lastItemOnPage} of {totalItems} + + ) : ( + // showing firstItemOnPage to lastItemOnPage of totalItems + + showing {firstItemOnPage} - {lastItemOnPage} of {totalItems} + + )} + + ); +}; + +export type PaginationProps = StackProps & { + setPage: (page: number) => void; + page?: number; + pageSize?: number; + totalItems?: number; + isLoadingPage?: boolean; +}; + +export const Pagination = ({ + setPage, + page = 1, + pageSize = 10, + totalItems = 0, + isLoadingPage = false, + ...rest +}: PaginationProps) => { + const pagination = getPaginationInfo({ page, pageSize, totalItems }); + return ( + + + + ); +}; diff --git a/src/components/Viewport/index.tsx b/src/components/Viewport/index.tsx new file mode 100644 index 0000000..535bf8d --- /dev/null +++ b/src/components/Viewport/index.tsx @@ -0,0 +1,41 @@ +import { Flex, FlexProps, useMediaQuery } from "@chakra-ui/react"; +import React, { useEffect } from "react"; + +const useFixViewport = () => { + useEffect(() => { + const updateCssViewportHeight = () => { + const vh = window.innerHeight * 0.01; + document.documentElement.style.setProperty("--vh", `${vh}px`); + }; + + updateCssViewportHeight(); + window.addEventListener("resize", updateCssViewportHeight); + + return () => { + window.removeEventListener("resize", updateCssViewportHeight); + }; + }, []); +}; + +export const Viewport = (props: FlexProps) => { + const [isStandalone] = useMediaQuery("(display-mode: standalone)"); + useFixViewport(); + + return ( + + ); +}; diff --git a/src/config/axios.ts b/src/config/axios.ts new file mode 100644 index 0000000..3076704 --- /dev/null +++ b/src/config/axios.ts @@ -0,0 +1,29 @@ +import Axios, { AxiosResponse } from 'axios'; + +// import { isBrowser } from '@/utils/ssr'; + +Axios.interceptors.request.use( + (config) => { + // const isExternal = !!config?.url?.startsWith('http'); + // const token = isBrowser ? localStorage.getItem('jwt') : null; + + // if (token && !isExternal) { + // config.headers['Authorization'] = `Bearer ${token}`; + // } + + config.baseURL = process.env.NEXT_PUBLIC_API_BASE_URL || '/api'; + + return config; + }, + (error) => Promise.reject(error) +); + +Axios.interceptors.response.use((response: AxiosResponse) => { + // if (response.headers['x-total-count']) { + // return { + // content: response.data, + // totalItems: response?.headers['x-total-count'], + // }; + // } + return response.data; +}); diff --git a/src/config/dayjs.ts b/src/config/dayjs.ts new file mode 100644 index 0000000..91f3fe2 --- /dev/null +++ b/src/config/dayjs.ts @@ -0,0 +1,6 @@ +import dayjs from 'dayjs'; +import customParseFormat from 'dayjs/plugin/customParseFormat'; +import relativeTime from 'dayjs/plugin/relativeTime'; + +dayjs.extend(relativeTime); +dayjs.extend(customParseFormat); diff --git a/src/config/index.ts b/src/config/index.ts new file mode 100644 index 0000000..4c76df6 --- /dev/null +++ b/src/config/index.ts @@ -0,0 +1,2 @@ +import "./axios"; +import "./dayjs"; diff --git a/src/containers/App/App.test.tsx b/src/containers/App/App.test.tsx new file mode 100644 index 0000000..8dd3134 --- /dev/null +++ b/src/containers/App/App.test.tsx @@ -0,0 +1,10 @@ +import { render } from "../../test-utils"; +import { App } from "./App"; +import { screen } from "@testing-library/react"; +import React from "react"; + +test("renders learn react link", () => { + render(); + const linkElement = screen.getByText(/learn chakra/i); + expect(linkElement).toBeInTheDocument(); +}); diff --git a/src/containers/App/App.tsx b/src/containers/App/App.tsx new file mode 100644 index 0000000..42e47e0 --- /dev/null +++ b/src/containers/App/App.tsx @@ -0,0 +1,19 @@ +import React, { useEffect, useState } from 'react'; + +import { Flex, Progress } from '@chakra-ui/react'; + +import { Router } from '../Router/Router'; + +const Loading = () => ( + + + +); + +export const App = () => { + const [isLoading, setIsLoading] = useState(true); + useEffect(() => { + setIsLoading(false); + }, []); + return isLoading ? : ; +}; diff --git a/src/ColorModeSwitcher.tsx b/src/containers/ColorModeSwitcher.tsx similarity index 100% rename from src/ColorModeSwitcher.tsx rename to src/containers/ColorModeSwitcher.tsx diff --git a/src/containers/Layout/Layout.tsx b/src/containers/Layout/Layout.tsx new file mode 100644 index 0000000..68ecbf5 --- /dev/null +++ b/src/containers/Layout/Layout.tsx @@ -0,0 +1,107 @@ +import React, { FC, useContext, useEffect, useMemo, useState } from 'react'; + +import { Box, Flex, IconButton, IconButtonProps, SlideFade, useColorMode, useColorModeValue, useTheme } from '@chakra-ui/react'; +import { FaMoon, FaSun } from 'react-icons/fa'; +import { useLocation } from 'react-router-dom'; +import { Link as RouterLink } from 'react-router-dom'; + +import { Logo } from '../../components/Logo'; +import { Viewport } from '../../components/Viewport'; + +type LayoutContextValue = { + isFocusMode: boolean; + setIsFocusMode: React.Dispatch> | undefined; +}; + +export const LayoutContext = React.createContext({ + isFocusMode: false, + setIsFocusMode: undefined, +}); + +export const useLayoutContext = () => useContext(LayoutContext); + +type ColorModeSwitcherProps = Omit; + +export const ColorModeSwitcher: React.FC = (props) => { + const { toggleColorMode } = useColorMode(); + const text = useColorModeValue('dark', 'light'); + const SwitchIcon = useColorModeValue(FaMoon, FaSun); + + return ( + } + aria-label={`Switch to ${text} mode`} + {...props} + /> + ); +}; + +export const useFocusMode = (enabled = true) => { + const ctx = useLayoutContext(); + const { setIsFocusMode } = ctx || {}; + + useEffect(() => { + setIsFocusMode?.(enabled); + return () => setIsFocusMode?.(false); + }, [ctx, setIsFocusMode, enabled]); +}; + +export const TopBar = () => { + const theme = useTheme(); + + return ( + <> + + + + + + + + + + + + + ); +}; + +export const Layout: FC> = ({ children }) => { + const [isFocusMode, setIsFocusMode] = useState(false); + const { pathname } = useLocation(); + + useEffect(() => { + window.scrollTo(0, 0); + }, [pathname]); + + const providerValue = useMemo(() => ({ isFocusMode, setIsFocusMode }), [isFocusMode]); + + return ( + + + {!isFocusMode && } + + {children} + + + + ); +}; diff --git a/src/containers/MeetingsActions/MeetingsActions.tsx b/src/containers/MeetingsActions/MeetingsActions.tsx new file mode 100644 index 0000000..f1f9c9b --- /dev/null +++ b/src/containers/MeetingsActions/MeetingsActions.tsx @@ -0,0 +1,132 @@ +import React from 'react'; + +import { Box, Button, HStack, IconButton, Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react'; +import { format } from 'date-fns'; +import { DateRange, DayPicker } from 'react-day-picker'; +import { BiCalendar, BiFilter, BiSort } from 'react-icons/bi'; +import { FiChevronDown, FiEdit, FiPlus } from 'react-icons/fi'; +import { Link } from 'react-router-dom'; + +import { MeetingFilterType, MeetingSortType } from '../../types/meetings.types'; + +type MeetingsActionsProps = { + sort: string; + setSort: (sort: MeetingSortType) => void; + filter: string; + setFilter: (filter: MeetingFilterType) => void; + range: DateRange | undefined; + setRange: (range: DateRange | undefined) => void; +}; + +const FilterOptions = ({ filter, setFilter }: Pick) => ( + + setFilter('ALL')}>{filter == 'ALL' ? All : 'All'} + setFilter('SCHEDULED')}>{filter == 'SCHEDULED' ? Scheduled : 'Scheduled'} + setFilter('COMPLETED')}>{filter == 'COMPLETED' ? Completed : 'Completed'} + setFilter('CANCELLED')}>{filter == 'CANCELLED' ? Cancelled : 'Cancelled'} + +); + +const ActionsOptions = () => ( + + Download + Create a Copy + Mark as Draft + Delete + Attend a Workshop + +); + +const SortOptions = ({ sort, setSort }: Pick) => ( + + setSort('NEWEST')}>{sort == 'NEWEST' ? Newest : 'Newest'} + setSort('OLDEST')}>{sort == 'OLDEST' ? Oldest : 'Oldest'} + +); + +export const MeetingsActions = ({ sort, setSort, filter, setFilter, range, setRange }: MeetingsActionsProps) => { + let period = 'Period'; + if (range?.from) { + if (!range.to) { + period = `${format(range.from, 'dd, MMM yyyy')}`; + } else if (range.to) { + period = ` ${format(range.from, 'dd, MMM yyyy')}ā€“ ${format(range.to, 'dd, MMM yyyy')} `; + } + } + return ( + + + + } + rightIcon={} + display={{ base: 'none', md: 'flex' }} + > + Filter: {filter.charAt(0) + filter.slice(1).toLowerCase()} + + + + + } variant="outline" display={{ base: 'flex', md: 'none' }} /> + + + + + + } rightIcon={} display={{ base: 'none', md: 'flex' }}> + Actions + + + + + } variant="outline" display={{ base: 'flex', md: 'none' }} /> + + + + + + } rightIcon={} display={{ base: 'none', md: 'flex' }}> + `Sort: {sort.charAt(0) + sort.slice(1).toLowerCase()} + + + + + } variant="outline" display={{ base: 'flex', md: 'none' }} /> + + + + + + } rightIcon={} display={{ base: 'none', md: 'flex' }}> + {period} + + + + + + + } variant="outline" display={{ base: 'flex', md: 'none' }} /> + + + + + + + + } + /> + + + ); +}; diff --git a/src/containers/MeetingsFooter/MeetingsFooter.tsx b/src/containers/MeetingsFooter/MeetingsFooter.tsx new file mode 100644 index 0000000..91f0af1 --- /dev/null +++ b/src/containers/MeetingsFooter/MeetingsFooter.tsx @@ -0,0 +1,67 @@ +import { DataListFooter } from "../../components/DataList"; +import { + Pagination, + PaginationButtonFirstPage, + PaginationButtonLastPage, + PaginationButtonNextPage, + PaginationButtonPrevPage, + PaginationInfo, +} from "../../components/Pagination"; +import React from "react"; + +type MeetingsFooterProps = { + isLoadingPage: boolean; + setPage: (page: number) => void; + page: number; + pageSize: number; + totalItems: number; +}; + +export const MeetingsFooter = ({ + isLoadingPage, + setPage, + page, + pageSize, + totalItems, +}: MeetingsFooterProps) => { + return ( + + + + + + + + + + ); +}; +// {meetings.isError && ( +//
+// +// +// +// {t("meetings:feedbacks.loadingUserError.title")} +// +// +// {t("meetings:feedbacks.loadingUserError.description")} +// +// +// +//
+// )} diff --git a/src/containers/MeetingsHeader/MeetingsHeader.tsx b/src/containers/MeetingsHeader/MeetingsHeader.tsx new file mode 100644 index 0000000..92970aa --- /dev/null +++ b/src/containers/MeetingsHeader/MeetingsHeader.tsx @@ -0,0 +1,43 @@ +import { DataListHeader, DataListCell } from "../../components/DataList"; +import React from "react"; + +export const MeetingsHeader = () => { + return ( + + Name + + Time + + + Account + + + NextSteps + + + + ); +}; +// {meetings.isError && ( +//
+// +// +// +// {t("meetings:feedbacks.loadingUserError.title")} +// +// +// {t("meetings:feedbacks.loadingUserError.description")} +// +// +// +//
+// )} diff --git a/src/containers/MeetingsRow/MeetingsRow.tsx b/src/containers/MeetingsRow/MeetingsRow.tsx new file mode 100644 index 0000000..7f50b3b --- /dev/null +++ b/src/containers/MeetingsRow/MeetingsRow.tsx @@ -0,0 +1,97 @@ +import { DataListCell, DataListRow } from "../../components/DataList"; +import { Meeting, Contact } from "../../types/meetings.types"; +import { + Avatar, + Box, + HStack, + LinkOverlay, + Text, + LinkBox, +} from "@chakra-ui/react"; +import React from "react"; +import { Link } from "react-router-dom"; + +type MeetingsHeaderProps = { + meeting: Meeting; + contacts: Contact[] | undefined; +}; + +export const MeetingsRow = ({ meeting, contacts }: MeetingsHeaderProps) => { + const getContactName = (id: string) => { + const contact = contacts?.find((contact) => contact.id === id); + return contact?.properties?.firstname + " " + contact?.properties?.lastname; + }; + const getContactEmail = (id: string) => { + const contact = contacts?.find((contact) => contact.id === id); + return contact?.properties?.email; + }; + return ( + + + + + {meeting.properties.hs_meeting_title} + + + + + + {meeting.properties.hs_meeting_start_time} + + {!!meeting.createdAt && ( + + {meeting.createdAt} + + )} + + + + + + + {getContactName( + meeting.associations?.contacts?.results[0]?.id || "" + )} + + + {getContactEmail( + meeting.associations?.contacts?.results[0]?.id || "" + )} + + + + + + + {meeting.properties.hs_internal_meeting_notes || + meeting.properties.hs_meeting_outcome} + + + + {/* */} + + + ); +}; diff --git a/src/containers/MeetingsView/MeetingsView.tsx b/src/containers/MeetingsView/MeetingsView.tsx new file mode 100644 index 0000000..bd43f6a --- /dev/null +++ b/src/containers/MeetingsView/MeetingsView.tsx @@ -0,0 +1,68 @@ +import { DataList } from "../../components/DataList"; +import { + useMeetingList, + sortMeetingList, + filterMeetingList, + rangeMeetingList, +} from "../../services/meetings.service"; +import { MeetingSortType, MeetingFilterType } from "../../types/meetings.types"; +import { MeetingsActions } from "../MeetingsActions/MeetingsActions"; +import { MeetingsFooter } from "../MeetingsFooter/MeetingsFooter"; +import { MeetingsHeader } from "../MeetingsHeader/MeetingsHeader"; +import { MeetingsRow } from "../MeetingsRow/MeetingsRow"; +import { Page, PageContent } from "../Page/Page"; +import { usePaginationFromUrl } from "../Router/Router"; +import { Box, HStack, Heading } from "@chakra-ui/react"; +import React, { useContext, useMemo, useState } from "react"; +import { DateRange } from "react-day-picker"; + +const MeetingsView = () => { + const { page, setPage } = usePaginationFromUrl(); + const [sort, setSort] = useState("NEWEST"); + const [filter, setFilter] = useState("ALL"); + const [range, setRange] = useState(); + const pageSize = 20; + const data = useMeetingList({ page: page - 1, size: pageSize }); + const sortedMeetings = sortMeetingList(data?.meetings || [], sort); + const filteredMeetings = filterMeetingList(sortedMeetings, filter); + const rangedMeetings = rangeMeetingList(filteredMeetings, range); + const pagedMeetings = rangedMeetings.slice( + pageSize * (page - 1), + pageSize * page + ); + + return ( + + + + + Meetings + + + + + + {pagedMeetings.map((meeting) => ( + + ))} + + + + + ); +}; + +export default MeetingsView; diff --git a/src/containers/Page/Page.tsx b/src/containers/Page/Page.tsx new file mode 100644 index 0000000..0245676 --- /dev/null +++ b/src/containers/Page/Page.tsx @@ -0,0 +1,181 @@ +import { useFocusMode, useLayoutContext } from "../Layout/Layout"; +import { + Box, + Flex, + FlexProps, + HStack, + IconButton, + Stack, + useTheme, +} from "@chakra-ui/react"; +import React, { useContext } from "react"; +import { FiArrowLeft } from "react-icons/fi"; +import useMeasure from "react-use-measure"; + +type PageContextValue = { + hideContainer: boolean; + containerSize: keyof typeof containerSizes; +}; + +const PageContext = React.createContext(null as any); + +const containerSizes = { + sm: "60ch", + md: "80ch", + lg: "100ch", + xl: "140ch", + full: "100%", +} as const; + +const PageContainer = ({ children, ...rest }: FlexProps) => { + const { hideContainer, containerSize } = useContext(PageContext); + + if (hideContainer) return <>{children}; + + return ( + + {children} + + ); +}; + +type PageTopBarProps = FlexProps & { + onBack?(): void; + showBack?: boolean; + isFixed?: boolean; +}; + +export const PageTopBar = ({ + children, + onBack = () => undefined, + showBack = false, + isFixed = false, + ...rest +}: PageTopBarProps) => { + const { isFocusMode } = useLayoutContext(); + const theme = useTheme(); + const [ref, { height }] = useMeasure(); + + return ( + <> + {isFixed && } + + + + + {showBack && ( + + } + variant="ghost" + onClick={() => onBack()} + /> + + )} + {children} + + + + + ); +}; + +type PageContentProps = FlexProps & { + onBack?(): void; + showBack?: boolean; +}; + +export const PageContent = ({ children, ...rest }: PageContentProps) => { + return ( + + + + + {" "} + {children}{" "} + + + + + + ); +}; + +export const PageBottomBar = ({ children, ...rest }: FlexProps) => { + const [ref, { height }] = useMeasure(); + + return ( + <> + + + {children} + + + + ); +}; + +type PageProps = FlexProps & { + isFocusMode?: boolean; + containerSize?: "sm" | "md" | "lg" | "xl" | "full"; + hideContainer?: boolean; +}; + +export const Page = ({ + isFocusMode = false, + hideContainer = false, + containerSize = "md", + ...rest +}: PageProps) => { + useFocusMode(isFocusMode); + return ( + + + + ); +}; diff --git a/src/containers/Router/Router.tsx b/src/containers/Router/Router.tsx new file mode 100644 index 0000000..d458148 --- /dev/null +++ b/src/containers/Router/Router.tsx @@ -0,0 +1,75 @@ +import { ErrorBoundary } from "../../components/ErrorBoundary"; +import { ErrorPage } from "../../components/ErrorPage"; +import { Layout } from "../Layout/Layout"; +import { Center, Spinner } from "@chakra-ui/react"; +import React, { Suspense, useCallback } from "react"; +import { + BrowserRouter, + Route, + Routes, + useSearchParams, + useNavigate, +} from "react-router-dom"; + +export const Loader = () => ( +
+ +
+); + +export const usePaginationFromUrl = () => { + const [searchParams, setSearchParam] = useSearchParams(); + const page = +(searchParams.get("page") ?? 1); + const setPage = useCallback( + (p: number) => { + const newPage = Math.max(1, p); + setSearchParam({ page: newPage.toString() }); + }, + [setSearchParam] + ); + return { page, setPage }; +}; + +export const useRedirectFromUrl = (defaultTo = "/") => { + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + return useCallback( + () => + navigate( + searchParams.get("redirect") + ? decodeURIComponent(searchParams.get("redirect") ?? "") + : defaultTo, + { replace: true } + ), + [navigate, searchParams, defaultTo] + ); +}; + +const MeetingsView = React.lazy(() => import("../MeetingsView/MeetingsView")); +// const MeetingCreateView = React.lazy( +// () => import("@/spa/views/MeetingCreateView") +// ); +// const MeetingUpdateView = React.lazy( +// () => import("@/spa/views/MeetingUpdateView") +// ); +// const ApiView = React.lazy(() => import("@/spa/views/ApiView")); + +export const Router = () => { + return ( + + + + }> + + } /> + } /> + + + + + + ); +}; +// } /> +// } /> +// } /> diff --git a/src/index.tsx b/src/index.tsx index c28e918..d32cf67 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,29 +1,44 @@ -import { ColorModeScript } from "@chakra-ui/react" -import * as React from "react" -import * as ReactDOM from "react-dom/client" -import { App } from "./App" -import reportWebVitals from "./reportWebVitals" -import * as serviceWorker from "./serviceWorker" +import * as React from 'react'; +import { ColorModeScript } from '@chakra-ui/react'; +import { ChakraProvider } from '@chakra-ui/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import * as ReactDOM from 'react-dom/client'; -const container = document.getElementById("root") +import { ErrorBoundary } from './components/ErrorBoundary'; +import { Viewport } from './components/Viewport'; +import './config'; +import { App } from './containers/App/App'; +import reportWebVitals from './reportWebVitals'; +import * as serviceWorker from './serviceWorker'; +import theme from './theme'; + +const container = document.getElementById('root'); if (!container) throw new Error('Failed to find the root element'); -const root = ReactDOM.createRoot(container) +const root = ReactDOM.createRoot(container); +const queryClient = new QueryClient(); root.render( - - - , -) + + + + + + + + + + + +); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://cra.link/PWA -serviceWorker.unregister() +serviceWorker.unregister(); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals() - +reportWebVitals(); diff --git a/src/logo.svg b/src/logo.svg deleted file mode 100644 index 620fe26..0000000 --- a/src/logo.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/services/meetings.service.ts b/src/services/meetings.service.ts new file mode 100644 index 0000000..fcfb97f --- /dev/null +++ b/src/services/meetings.service.ts @@ -0,0 +1,208 @@ +import { Meeting, MeetingList } from "../types/meetings.types"; +import { + createQueryKeys, + inferQueryKeys, +} from "@lukemorales/query-key-factory"; +import { + // UseMutationOptions, + UseQueryOptions, // useMutation, + useQuery, // useQueryClient, +} from "@tanstack/react-query"; +import Axios, { AxiosError } from "axios"; +import { DateRange } from "react-day-picker"; + +// type UserMutateError = { +// title: string; +// errorKey: "userexists" | "emailexists"; +// }; + +export const sortMeetingList = (meetings: Meeting[], sort: string) => { + if (sort === "NEWEST") { + return meetings.sort((a, b) => { + return ( + new Date(b.properties.hs_meeting_start_time).getTime() - + new Date(a.properties.hs_meeting_start_time).getTime() + ); + }); + } else if (sort === "OLDEST") { + return meetings.sort((a, b) => { + return ( + new Date(a.properties.hs_meeting_start_time).getTime() - + new Date(b.properties.hs_meeting_start_time).getTime() + ); + }); + } else { + return meetings; + } +}; + +export const filterMeetingList = (meetings: Meeting[], filter: string) => { + if (filter === "ALL") { + return meetings; + } else { + return meetings.filter((meeting) => { + return meeting.properties.hs_meeting_outcome === filter; + }); + } +}; + +export const rangeMeetingList = ( + meetings: Meeting[], + range: DateRange | undefined +) => { + if (!range || !range.from || !range.to) { + return meetings; + } else { + return meetings.filter((meeting) => { + return ( + range.from && + new Date(meeting.properties.hs_meeting_start_time).getTime() >= + range.from.getTime() && + range.to && + new Date(meeting.properties.hs_meeting_start_time).getTime() <= + range.to.getTime() + ); + }); + } +}; + +const usersKeys = createQueryKeys("usersService", { + meetings: (params: { limit?: number; after?: number }) => [params], + users: (params: { page?: number; size?: number }) => [params], + user: (params: { login?: string }) => [params], +}); +type UsersKeys = inferQueryKeys; + +export const useMeetingList = ( + { page = 0, size = 10, limit = 20 } = {}, + config: UseQueryOptions< + MeetingList, + AxiosError, + MeetingList, + UsersKeys["meetings"]["queryKey"] + > = {} +) => { + const result = useQuery( + usersKeys.meetings({ limit: 20, after: 0 }).queryKey, + (): Promise => + Axios.get( + "https://us-central1-epicbrief-c47c8.cloudfunctions.net/meetings" + ), + { keepPreviousData: true, ...config } + ); + console.log("result", result.data); + + const { meetings, contacts } = result.data || {}; + const totalItems = meetings?.length; + const totalPages = Math.ceil((totalItems ?? 0) / size); + const hasMore = page + 1 < totalPages; + const isLoadingPage = result.isFetching; + + return { + meetings, + contacts, + totalItems, + hasMore, + totalPages, + isLoadingPage, + ...result, + }; +}; + +// export const useUser = ( +// userLogin?: string, +// config: UseQueryOptions< +// User, +// AxiosError, +// User, +// UsersKeys["user"]["queryKey"] +// > = {} +// ) => { +// const result = useQuery( +// usersKeys.user({ login: userLogin }).queryKey, +// (): Promise => Axios.get(`${USERS_BASE_URL}/${userLogin}`), +// { +// enabled: !!userLogin, +// ...config, +// } +// ); + +// return { user: result.data, ...result }; +// }; + +// export const useUserUpdate = ( +// config: UseMutationOptions, User> = {} +// ) => { +// const queryClient = useQueryClient(); +// return useMutation((payload) => Axios.put(USERS_BASE_URL, payload), { +// ...config, +// onSuccess: (data, payload, ...rest) => { +// queryClient.cancelQueries(usersKeys.users._def); +// queryClient +// .getQueryCache() +// .findAll(usersKeys.users._def) +// .forEach(({ queryKey }) => { +// queryClient.setQueryData( +// queryKey, +// (cachedData) => { +// if (!cachedData) return; +// return { +// ...cachedData, +// content: (cachedData.content || []).map((user) => +// user.id === data.id ? data : user +// ), +// }; +// } +// ); +// }); +// queryClient.invalidateQueries(usersKeys.users._def); +// queryClient.invalidateQueries(usersKeys.user({ login: payload.login })); +// if (config.onSuccess) { +// config.onSuccess(data, payload, ...rest); +// } +// }, +// }); +// }; + +// export const useUserCreate = ( +// config: UseMutationOptions< +// User, +// AxiosError, +// Pick< +// User, +// "login" | "email" | "firstName" | "lastName" | "langKey" | "authorities" +// > +// > = {} +// ) => { +// const queryClient = useQueryClient(); +// return useMutation( +// ({ langKey = DEFAULT_LANGUAGE_KEY, ...payload }) => +// Axios.post("/admin/users", { langKey, ...payload }), +// { +// ...config, +// onSuccess: (...args) => { +// queryClient.invalidateQueries(usersKeys.users._def); +// config?.onSuccess?.(...args); +// }, +// } +// ); +// }; + +// type UserWithLoginOnly = Pick; + +// export const useUserRemove = ( +// config: UseMutationOptions = {} +// ) => { +// const queryClient = useQueryClient(); +// return useMutation( +// (user: UserWithLoginOnly): Promise => +// Axios.delete(`/admin/users/${user.login}`), +// { +// ...config, +// onSuccess: (...args) => { +// queryClient.invalidateQueries(usersKeys.users._def); +// config?.onSuccess?.(...args); +// }, +// } +// ); +// }; diff --git a/src/theme/components/alert.ts b/src/theme/components/alert.ts new file mode 100644 index 0000000..1b2fb2f --- /dev/null +++ b/src/theme/components/alert.ts @@ -0,0 +1,123 @@ +import { alertAnatomy as parts } from '@chakra-ui/anatomy'; +import { getColor, mode, transparentize } from '@chakra-ui/theme-tools'; +import type { + PartsStyleFunction, + PartsStyleObject, + StyleFunctionProps, +} from '@chakra-ui/theme-tools'; + +const baseStyle: PartsStyleObject = { + container: { + px: 4, + py: 2, + borderRadius: 'md', + fontSize: 'sm', + flexWrap: 'wrap', + }, + title: { + fontWeight: 'bold', + lineHeight: 6, + marginEnd: 2, + }, + description: { + lineHeight: 5, + }, + icon: { + flexShrink: 0, + marginEnd: 2, + w: 4, + h: 4, + }, + spinner: { + flexShrink: 0, + marginEnd: 2, + w: 4, + h: 4, + }, +}; + +function getBg(props: StyleFunctionProps): string { + const { theme, colorScheme: c } = props; + const lightBg = getColor(theme, `${c}.100`, c); + const darkBg = transparentize(`${c}.200`, 0.16)(theme); + return mode(lightBg, darkBg)(props); +} + +const variantSubtle: PartsStyleFunction = (props) => { + const { colorScheme: c } = props; + return { + container: { + bg: getBg(props), + color: mode(`${c}.800`, `${c}.200`)(props), + }, + icon: { color: mode(`${c}.500`, `${c}.200`)(props) }, + spinner: { + color: mode(`${c}.500`, `${c}.200`)(props), + }, + }; +}; + +const variantLeftAccent: PartsStyleFunction = (props) => { + const { colorScheme: c } = props; + return { + container: { + paddingStart: 3, + borderStartWidth: '4px', + borderStartColor: mode(`${c}.500`, `${c}.200`)(props), + bg: getBg(props), + }, + icon: { + color: mode(`${c}.500`, `${c}.200`)(props), + }, + spinner: { + color: mode(`${c}.500`, `${c}.200`)(props), + }, + }; +}; + +const variantTopAccent: PartsStyleFunction = (props) => { + const { colorScheme: c } = props; + return { + container: { + pt: 2, + borderTopWidth: '4px', + borderTopColor: mode(`${c}.500`, `${c}.200`)(props), + bg: getBg(props), + }, + icon: { + color: mode(`${c}.500`, `${c}.200`)(props), + }, + spinner: { + color: mode(`${c}.500`, `${c}.200`)(props), + }, + }; +}; + +const variantSolid: PartsStyleFunction = (props) => { + const { colorScheme: c } = props; + return { + container: { + bg: mode(`${c}.500`, `${c}.200`)(props), + color: mode(`white`, `gray.900`)(props), + }, + }; +}; + +const variants = { + subtle: variantSubtle, + 'left-accent': variantLeftAccent, + 'top-accent': variantTopAccent, + solid: variantSolid, +}; + +const defaultProps = { + variant: 'subtle', + colorScheme: 'blue', +}; + +export default { + parts: parts.keys, + baseStyle, + variants, + defaultProps, +}; diff --git a/src/theme/components/badge.ts b/src/theme/components/badge.ts new file mode 100644 index 0000000..07a02e3 --- /dev/null +++ b/src/theme/components/badge.ts @@ -0,0 +1,19 @@ +export default { + sizes: { + xs: { + fontSize: '0.6em', + }, + sm: { + fontSize: '0.7em', + }, + md: { + fontSize: '0.8em', + }, + lg: { + fontSize: '0.9em', + }, + }, + defaultProps: { + size: 'md', + }, +}; diff --git a/src/theme/components/button.ts b/src/theme/components/button.ts new file mode 100644 index 0000000..67fffc8 --- /dev/null +++ b/src/theme/components/button.ts @@ -0,0 +1,104 @@ +import { + StyleFunctionProps, + SystemStyleInterpolation, + isAccessible, + mode, + transparentize, +} from '@chakra-ui/theme-tools'; + +type customVariantOptions = { + theme: StyleFunctionProps['theme']; + bg: string; + bgHover?: string; + bgActive?: string; + color: string; + colorHover?: string; + boxShadowFocus?: string; +}; +const customVariant = ({ + theme, + bg, + bgHover = bg, + bgActive = bgHover, + color, + colorHover = color, + boxShadowFocus = 'outline', +}: customVariantOptions) => { + const isColorAccessible = isAccessible(color, bg, { + size: 'large', + level: 'AA', + })(theme); + + return { + bg, + color: isColorAccessible ? color : 'black', + _focusVisible: { + boxShadow: boxShadowFocus, + }, + _hover: { + bg: bgHover, + color: isColorAccessible ? colorHover : 'black', + _disabled: { + bg, + }, + }, + _active: { bg: bgActive }, + }; +}; + +const variants: Record = { + // Custom variants + '@primary': (props) => + customVariant({ + theme: props.theme, + bg: mode('brand.600', 'brand.300')(props), + bgHover: mode('brand.700', 'brand.400')(props), + bgActive: mode('brand.800', 'brand.500')(props), + color: mode('white', 'brand.900')(props), + boxShadowFocus: 'outline-brand', + }), + '@secondary': (props) => + customVariant({ + theme: props.theme, + bg: mode('brand.100', 'brand.900')(props), + bgHover: mode('brand.200', 'brand.800')(props), + bgActive: mode('brand.300', 'brand.700')(props), + color: mode('brand.700', 'brand.50')(props), + colorHover: mode('brand.800', 'brand.100')(props), + boxShadowFocus: 'outline-brand', + }), + '@danger': (props) => + customVariant({ + theme: props.theme, + bg: mode('error.100', 'error.900')(props), + bgHover: mode('error.200', 'error.800')(props), + bgActive: mode('error.300', 'error.700')(props), + color: mode('error.700', 'error.50')(props), + colorHover: mode('error.800', 'error.100')(props), + boxShadowFocus: 'outline-error', + }), + + // Default variants + solid: (props) => ({ + bg: + props.colorScheme === 'gray' + ? mode('gray.100', 'whiteAlpha.100')(props) + : `${props.colorScheme}.600`, + _hover: { + bg: + props.colorScheme === 'gray' + ? mode('gray.200', 'whiteAlpha.200')(props) + : `${props.colorScheme}.700`, + }, + }), + ghost: (props) => ({ + bg: transparentize(`${props.colorScheme}.50`, 0.05)(props.theme), + _hover: { + bg: transparentize(`${props.colorScheme}.50`, 0.15)(props.theme), + }, + }), +}; + +export default { + variants, +}; diff --git a/src/theme/components/checkbox.ts b/src/theme/components/checkbox.ts new file mode 100644 index 0000000..5d26314 --- /dev/null +++ b/src/theme/components/checkbox.ts @@ -0,0 +1,5 @@ +export default { + defaultProps: { + colorScheme: 'brand', + }, +}; diff --git a/src/theme/components/index.ts b/src/theme/components/index.ts new file mode 100644 index 0000000..8eb3f76 --- /dev/null +++ b/src/theme/components/index.ts @@ -0,0 +1,10 @@ +export { default as Alert } from './alert'; +export { default as Badge } from './badge'; +export { default as Button } from './button'; +export { default as Checkbox } from './checkbox'; +export { default as Input } from './input'; +export { default as Modal } from './modal'; +export { default as Popover } from './popover'; +export { default as Radio } from './radio'; +export { default as Select } from './select'; +export { default as Textarea } from './textarea'; diff --git a/src/theme/components/input.ts b/src/theme/components/input.ts new file mode 100644 index 0000000..c356e72 --- /dev/null +++ b/src/theme/components/input.ts @@ -0,0 +1,30 @@ +import { + SystemStyleInterpolation, + getColor, + mode, +} from '@chakra-ui/theme-tools'; + +const variants: Record = { + outline: (props) => { + const focusBorderColor = getColor( + props.theme, + props.focusBorderColor + ? props.focusBorderColor + : mode('brand.500', 'brand.300')(props) + ); + return { + field: { + bg: mode('blackAlpha.50', 'whiteAlpha.50')(props), + borderColor: mode('blackAlpha.100', 'whiteAlpha.100')(props), + _focusVisible: { + borderColor: focusBorderColor, + boxShadow: `0 0 0 1px ${focusBorderColor}`, + }, + }, + }; + }, +}; + +export default { + variants, +}; diff --git a/src/theme/components/modal.ts b/src/theme/components/modal.ts new file mode 100644 index 0000000..5bffbe1 --- /dev/null +++ b/src/theme/components/modal.ts @@ -0,0 +1,104 @@ +import { modalAnatomy as parts } from '@chakra-ui/anatomy'; +import type { + PartsStyleFunction, + PartsStyleObject, + SystemStyleFunction, + SystemStyleObject, +} from '@chakra-ui/theme-tools'; +import { mode } from '@chakra-ui/theme-tools'; + +const baseStyleOverlay: SystemStyleObject = { + backdropFilter: 'blur(4px)', +}; + +const baseStyleDialog: SystemStyleFunction = (props) => { + return { + bg: mode('white', 'gray.800')(props), + mx: 4, + py: 0, + }; +}; + +const baseStyleHeader: SystemStyleObject = { + px: 4, + pt: 4, + pb: 0, +}; + +const baseStyleCloseButton: SystemStyleObject = { + top: 2, + insetEnd: 2, +}; + +const baseStyleBody: SystemStyleFunction = (_) => { + return { + px: 4, + py: 4, + }; +}; + +const baseStyleFooter: SystemStyleObject = { + px: 4, + pt: 0, + pb: 4, +}; + +const baseStyle: PartsStyleFunction = (props) => ({ + overlay: baseStyleOverlay, + dialog: baseStyleDialog(props), + header: baseStyleHeader, + closeButton: baseStyleCloseButton, + body: baseStyleBody(props), + footer: baseStyleFooter, +}); + +/** + * Since the `maxWidth` prop references theme.sizes internally, + * we can leverage that to size our modals. + */ +function getSize(value: string): PartsStyleObject { + if (value === 'full') { + return { + dialog: { + maxW: '100vw', + minH: '100vh', + '@supports(min-height: -webkit-fill-available)': { + minH: '-webkit-fill-available', + }, + '@supports(min-height: fill-available)': { + minH: 'fill-available', + }, + m: 0, + borderRadius: 0, + }, + }; + } + return { + dialog: { maxW: value }, + }; +} + +const sizes = { + xs: getSize('xs'), + sm: getSize('sm'), + md: getSize('md'), + lg: getSize('lg'), + xl: getSize('xl'), + '2xl': getSize('2xl'), + '3xl': getSize('3xl'), + '4xl': getSize('4xl'), + '5xl': getSize('5xl'), + '6xl': getSize('6xl'), + full: getSize('full'), +}; + +const defaultProps = { + size: 'md', +}; + +export default { + parts: parts.keys, + baseStyle, + sizes, + defaultProps, +}; diff --git a/src/theme/components/popover.ts b/src/theme/components/popover.ts new file mode 100644 index 0000000..875802f --- /dev/null +++ b/src/theme/components/popover.ts @@ -0,0 +1,132 @@ +import { popoverAnatomy as parts } from '@chakra-ui/anatomy'; +import type { + PartsStyleFunction, + SystemStyleFunction, + SystemStyleObject, +} from '@chakra-ui/theme-tools'; +import { cssVar, mode } from '@chakra-ui/theme-tools'; + +const $popperBg = cssVar('popper-bg'); + +const baseStyleContent: SystemStyleFunction = (props) => { + const bg = mode('white', 'gray.900')(props); + return { + [$popperBg.variable]: `colors.${bg}`, + py: 3, + maxW: '98vw', + }; +}; + +const baseStyleHeader: SystemStyleObject = { + px: 3, + pt: 0, + pb: 0, + borderBottomWidth: 0, + fontWeight: 'semibold', +}; + +const baseStyleBody: SystemStyleObject = { + px: 3, + py: 0, +}; + +const baseStyleFooter: SystemStyleObject = { + px: 3, + pb: 0, + pt: 3, + borderTopWidth: 0, +}; + +const baseStyleCloseButton: SystemStyleObject = { + top: 1, + insetEnd: 1, + padding: 2, +}; + +const baseStyle: PartsStyleFunction = (props) => ({ + content: baseStyleContent(props), + header: baseStyleHeader, + body: baseStyleBody, + footer: baseStyleFooter, + closeButton: baseStyleCloseButton, +}); + +export default { + parts: parts.keys, + baseStyle, + defaultProps: { + size: 'xs', + }, + sizes: { + '3xs': { + content: { + width: '3xs', + }, + }, + '2xs': { + content: { + width: '2xs', + }, + }, + xs: { + content: { + width: 'xs', + }, + }, + sm: { + content: { + width: 'sm', + }, + }, + md: { + content: { + width: 'md', + }, + }, + lg: { + content: { + width: 'lg', + }, + }, + xl: { + content: { + width: 'xl', + }, + }, + '2xl': { + content: { + width: '2xl', + }, + }, + '3xl': { + content: { + width: '3xl', + }, + }, + '4xl': { + content: { + width: '4xl', + }, + }, + '5xl': { + content: { + width: '5xl', + }, + }, + '6xl': { + content: { + width: '6xl', + }, + }, + '7xl': { + content: { + width: '7xl', + }, + }, + '8xl': { + content: { + width: '8xl', + }, + }, + }, +}; diff --git a/src/theme/components/radio.ts b/src/theme/components/radio.ts new file mode 100644 index 0000000..5d26314 --- /dev/null +++ b/src/theme/components/radio.ts @@ -0,0 +1,5 @@ +export default { + defaultProps: { + colorScheme: 'brand', + }, +}; diff --git a/src/theme/components/select.ts b/src/theme/components/select.ts new file mode 100644 index 0000000..c356e72 --- /dev/null +++ b/src/theme/components/select.ts @@ -0,0 +1,30 @@ +import { + SystemStyleInterpolation, + getColor, + mode, +} from '@chakra-ui/theme-tools'; + +const variants: Record = { + outline: (props) => { + const focusBorderColor = getColor( + props.theme, + props.focusBorderColor + ? props.focusBorderColor + : mode('brand.500', 'brand.300')(props) + ); + return { + field: { + bg: mode('blackAlpha.50', 'whiteAlpha.50')(props), + borderColor: mode('blackAlpha.100', 'whiteAlpha.100')(props), + _focusVisible: { + borderColor: focusBorderColor, + boxShadow: `0 0 0 1px ${focusBorderColor}`, + }, + }, + }; + }, +}; + +export default { + variants, +}; diff --git a/src/theme/components/textarea.ts b/src/theme/components/textarea.ts new file mode 100644 index 0000000..b6281cf --- /dev/null +++ b/src/theme/components/textarea.ts @@ -0,0 +1,28 @@ +import { + SystemStyleInterpolation, + getColor, + mode, +} from '@chakra-ui/theme-tools'; + +const variants: Record = { + outline: (props) => { + const focusBorderColor = getColor( + props.theme, + props.focusBorderColor + ? props.focusBorderColor + : mode('brand.500', 'brand.300')(props) + ); + return { + bg: mode('blackAlpha.50', 'whiteAlpha.50')(props), + borderColor: mode('blackAlpha.100', 'whiteAlpha.100')(props), + _focusVisible: { + borderColor: focusBorderColor, + boxShadow: `0 0 0 1px ${focusBorderColor}`, + }, + }; + }, +}; + +export default { + variants, +}; diff --git a/src/theme/config.ts b/src/theme/config.ts new file mode 100644 index 0000000..279f194 --- /dev/null +++ b/src/theme/config.ts @@ -0,0 +1,6 @@ +import { ThemeConfig } from "@chakra-ui/react"; + +export const config: ThemeConfig = { + initialColorMode: "light", + useSystemColorMode: false, +}; diff --git a/src/theme/externals-css.ts b/src/theme/externals-css.ts new file mode 100644 index 0000000..bce65a8 --- /dev/null +++ b/src/theme/externals-css.ts @@ -0,0 +1,2 @@ +import "@fontsource/inter/latin.css"; +import "react-day-picker/dist/style.css"; diff --git a/src/theme/externals/index.ts b/src/theme/externals/index.ts new file mode 100644 index 0000000..e57f797 --- /dev/null +++ b/src/theme/externals/index.ts @@ -0,0 +1 @@ +export { reactDayPicker } from './reactDayPicker'; diff --git a/src/theme/externals/reactDayPicker.ts b/src/theme/externals/reactDayPicker.ts new file mode 100644 index 0000000..6cfd733 --- /dev/null +++ b/src/theme/externals/reactDayPicker.ts @@ -0,0 +1,143 @@ +import { Styles, mode } from '@chakra-ui/theme-tools'; + +export const reactDayPicker: Styles['global'] = (props) => ({ + '.DayPicker *': { + outline: 'none', + }, + + '.DayPickerInput': { + display: 'inline-block', + fontSize: '0.1em', + width: '100%', + }, + + '.DayPickerInput-OverlayWrapper': { + position: { base: 'absolute', sm: 'relative' }, + left: { base: 0, sm: 'auto' }, + right: { base: 0, sm: 'auto' }, + marginLeft: 'auto', + marginRight: 'auto', + top: '3em', + width: '100%', + maxWidth: '90vw', + }, + + '.DayPickerInput-Overlay': { + position: 'absolute', + left: '0', + zIndex: 2, + borderRadius: 'md', + boxShadow: 'lg', + bg: mode('white', 'gray.700')(props), + }, + + '.DayPicker': { + display: 'inline-block', + fontSize: { base: '0.8rem', sm: '1rem' }, + borderRadius: 'md', + width: 'min-content', + }, + + '.DayPicker-Months': { + display: 'grid', + gridTemplateColumns: { + base: 'repeat(1, 1fr)', + md: 'repeat(2, 1fr)', + xl: 'repeat(4, 1fr)', + }, + }, + + '.DayPicker-Day--outside': { + backgroundColor: 'transparent!important', + }, + + '.DayPicker-Day--disabled, .DayPicker-Day--today.DayPicker-Day--disabled': { + pointerEvents: 'none', + }, + + '.DayPicker-Day--today.DayPicker-Day--disabled': { + color: 'gray.300', + }, + + '.DayPicker-Day--selected:not(.DayPicker-Day--disabled):not(.DayPicker-Day--outside)': + { + position: 'relative', + backgroundColor: mode('brand.500', 'brand.600')(props), + borderRadius: '100%', + }, + + '.DayPicker-Day--selected:not(.DayPicker-Day--disabled):not(.DayPicker-Day--outside):hover': + { + backgroundColor: mode('brand.400', 'brand.500')(props), + borderRadius: '100%', + color: 'white', + }, + + '.DayPicker:not(.DayPicker--interactionDisabled)': { + '.DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside):hover': + { + backgroundColor: mode('blackAlpha.200', 'whiteAlpha.200')(props), + borderRadius: '100%', + color: mode('black', 'white')(props), + }, + }, + + '.DayPicker-Day--weekend:.DayPicker-Day--selected': { + color: 'white', + }, + + '.DayPicker-Day--weekend': { + color: 'gray.400', + }, + + '.DayPicker-Day': { + display: 'block', + borderRadius: 'full', + cursor: 'pointer', + height: '2rem', + minWidth: '2rem', + transition: '0.2s', + padding: 0, + lineHeight: '2rem', + }, + + '.DayPicker-Day--today': { + color: mode('black', 'white')(props), + fontWeight: 'bold', + }, + + '.DayPicker-Caption': { + display: 'block', + }, + + '.DayPicker-Caption > div': { + fontWeight: '400', + fontSize: '1em', + }, + + '.DayPicker-Weekdays': { + display: 'block', + }, + + '.DayPicker-WeekdaysRow': { + display: 'grid', + gridTemplateColumns: 'repeat(7, 1fr)', + }, + + '.DayPicker-Weekday': { + display: 'block', + fontWeight: '350', + color: mode('black', 'white')(props), + fontSize: '0.875em', + }, + + '.DayPicker-Body': { + display: 'grid', + }, + + '.DayPicker-Week': { + display: 'grid', + gridTemplateColumns: 'repeat(7, 1fr)', + gridGap: '0.1rem', + }, +}); diff --git a/src/theme/foundations/colors.ts b/src/theme/foundations/colors.ts new file mode 100644 index 0000000..50420c4 --- /dev/null +++ b/src/theme/foundations/colors.ts @@ -0,0 +1,19 @@ +import tailwindColors from './tailwindColors'; + +export const colors = { + // Update me with other Tailwind colors or with https://smart-swatch.netlify.app/ + brand: tailwindColors.blue, + gray: tailwindColors.blueGray, + + success: tailwindColors.lime, + green: tailwindColors.lime, + + error: tailwindColors.rose, + red: tailwindColors.rose, + + warning: tailwindColors.amber, + orange: tailwindColors.amber, + + info: tailwindColors.sky, + blue: tailwindColors.sky, +}; diff --git a/src/theme/foundations/index.ts b/src/theme/foundations/index.ts new file mode 100644 index 0000000..cb2c830 --- /dev/null +++ b/src/theme/foundations/index.ts @@ -0,0 +1,17 @@ +import { colors } from './colors'; +import { layout } from './layout'; +import { shadows } from './shadows'; +import { spacing } from './spacing'; +import { typography } from './typography'; +import { zIndices } from './z-index'; + +const foundations = { + colors, + ...typography, + shadows, + space: spacing, + layout, + zIndices, +}; + +export default foundations; diff --git a/src/theme/foundations/layout.ts b/src/theme/foundations/layout.ts new file mode 100644 index 0000000..f15f9b5 --- /dev/null +++ b/src/theme/foundations/layout.ts @@ -0,0 +1,10 @@ +import { spacing } from './spacing'; + +export const layout = { + breakpoints: { + desktop: 'md', + }, + topBar: { + height: `calc(4rem + ${spacing['safe-top']})`, + }, +}; diff --git a/src/theme/foundations/shadows.ts b/src/theme/foundations/shadows.ts new file mode 100644 index 0000000..b1cae78 --- /dev/null +++ b/src/theme/foundations/shadows.ts @@ -0,0 +1,14 @@ +import { colors } from "./colors"; +import { transparentize } from "@chakra-ui/theme-tools"; + +const createOutline = (colorScheme = "gray") => + `0 0 0 3px ${transparentize(`${colorScheme}.500`, 0.3)({ colors })}`; + +export const shadows = { + outline: createOutline("brand"), + "outline-brand": createOutline("brand"), + "outline-gray": createOutline("gray"), + "outline-success": createOutline("success"), + "outline-warning": createOutline("warning"), + "outline-error": createOutline("error"), +}; diff --git a/src/theme/foundations/spacing.ts b/src/theme/foundations/spacing.ts new file mode 100644 index 0000000..d42e3a0 --- /dev/null +++ b/src/theme/foundations/spacing.ts @@ -0,0 +1,6 @@ +export const spacing = { + 'safe-top': 'env(safe-area-inset-top)', + 'safe-bottom': 'env(safe-area-inset-bottom)', + 'safe-left': 'env(safe-area-inset-left)', + 'safe-right': 'env(safe-area-inset-right)', +}; diff --git a/src/theme/foundations/tailwindColors.ts b/src/theme/foundations/tailwindColors.ts new file mode 100644 index 0000000..d223474 --- /dev/null +++ b/src/theme/foundations/tailwindColors.ts @@ -0,0 +1,268 @@ +const tailwindColors = { + rose: { + 50: '#fff1f2', + 100: '#ffe4e6', + 200: '#fecdd3', + 300: '#fda4af', + 400: '#fb7185', + 500: '#f43f5e', + 600: '#e11d48', + 700: '#be123c', + 800: '#9f1239', + 900: '#881337', + }, + pink: { + 50: '#fdf2f8', + 100: '#fce7f3', + 200: '#fbcfe8', + 300: '#f9a8d4', + 400: '#f472b6', + 500: '#ec4899', + 600: '#db2777', + 700: '#be185d', + 800: '#9d174d', + 900: '#831843', + }, + fuchsia: { + 50: '#fdf4ff', + 100: '#fae8ff', + 200: '#f5d0fe', + 300: '#f0abfc', + 400: '#e879f9', + 500: '#d946ef', + 600: '#c026d3', + 700: '#a21caf', + 800: '#86198f', + 900: '#701a75', + }, + purple: { + 50: '#faf5ff', + 100: '#f3e8ff', + 200: '#e9d5ff', + 300: '#d8b4fe', + 400: '#c084fc', + 500: '#a855f7', + 600: '#9333ea', + 700: '#7e22ce', + 800: '#6b21a8', + 900: '#581c87', + }, + violet: { + 50: '#f5f3ff', + 100: '#ede9fe', + 200: '#ddd6fe', + 300: '#c4b5fd', + 400: '#a78bfa', + 500: '#8b5cf6', + 600: '#7c3aed', + 700: '#6d28d9', + 800: '#5b21b6', + 900: '#4c1d95', + }, + indigo: { + 50: '#eef2ff', + 100: '#e0e7ff', + 200: '#c7d2fe', + 300: '#a5b4fc', + 400: '#818cf8', + 500: '#6366f1', + 600: '#4f46e5', + 700: '#4338ca', + 800: '#3730a3', + 900: '#312e81', + }, + blue: { + 50: '#eff6ff', + 100: '#dbeafe', + 200: '#bfdbfe', + 300: '#93c5fd', + 400: '#60a5fa', + 500: '#3b82f6', + 600: '#2563eb', + 700: '#1d4ed8', + 800: '#1e40af', + 900: '#1e3a8a', + }, + sky: { + 50: '#f0f9ff', + 100: '#e0f2fe', + 200: '#bae6fd', + 300: '#7dd3fc', + 400: '#38bdf8', + 500: '#0ea5e9', + 600: '#0284c7', + 700: '#0369a1', + 800: '#075985', + 900: '#0c4a6e', + }, + cyan: { + 50: '#ecfeff', + 100: '#cffafe', + 200: '#a5f3fc', + 300: '#67e8f9', + 400: '#22d3ee', + 500: '#06b6d4', + 600: '#0891b2', + 700: '#0e7490', + 800: '#155e75', + 900: '#164e63', + }, + teal: { + 50: '#f0fdfa', + 100: '#ccfbf1', + 200: '#99f6e4', + 300: '#5eead4', + 400: '#2dd4bf', + 500: '#14b8a6', + 600: '#0d9488', + 700: '#0f766e', + 800: '#115e59', + 900: '#134e4a', + }, + emerald: { + 50: '#ecfdf5', + 100: '#d1fae5', + 200: '#a7f3d0', + 300: '#6ee7b7', + 400: '#34d399', + 500: '#10b981', + 600: '#059669', + 700: '#047857', + 800: '#065f46', + 900: '#064e3b', + }, + green: { + 50: '#f0fdf4', + 100: '#dcfce7', + 200: '#bbf7d0', + 300: '#86efac', + 400: '#4ade80', + 500: '#22c55e', + 600: '#16a34a', + 700: '#15803d', + 800: '#166534', + 900: '#14532d', + }, + lime: { + 50: '#f7fee7', + 100: '#ecfccb', + 200: '#d9f99d', + 300: '#bef264', + 400: '#a3e635', + 500: '#84cc16', + 600: '#65a30d', + 700: '#4d7c0f', + 800: '#3f6212', + 900: '#365314', + }, + yellow: { + 50: '#fefce8', + 100: '#fef9c3', + 200: '#fef08a', + 300: '#fde047', + 400: '#facc15', + 500: '#eab308', + 600: '#ca8a04', + 700: '#a16207', + 800: '#854d0e', + 900: '#713f12', + }, + amber: { + 50: '#fffbeb', + 100: '#fef3c7', + 200: '#fde68a', + 300: '#fcd34d', + 400: '#fbbf24', + 500: '#f59e0b', + 600: '#d97706', + 700: '#b45309', + 800: '#92400e', + 900: '#78350f', + }, + orange: { + 50: '#fff7ed', + 100: '#ffedd5', + 200: '#fed7aa', + 300: '#fdba74', + 400: '#fb923c', + 500: '#f97316', + 600: '#ea580c', + 700: '#c2410c', + 800: '#9a3412', + 900: '#7c2d12', + }, + red: { + 50: '#fef2f2', + 100: '#fee2e2', + 200: '#fecaca', + 300: '#fca5a5', + 400: '#f87171', + 500: '#ef4444', + 600: '#dc2626', + 700: '#b91c1c', + 800: '#991b1b', + 900: '#7f1d1d', + }, + warmGray: { + 50: '#fafaf9', + 100: '#f5f5f4', + 200: '#e7e5e4', + 300: '#d6d3d1', + 400: '#a8a29e', + 500: '#78716c', + 600: '#57534e', + 700: '#44403c', + 800: '#292524', + 900: '#1c1917', + }, + trueGray: { + 50: '#fafafa', + 100: '#f5f5f5', + 200: '#e5e5e5', + 300: '#d4d4d4', + 400: '#a3a3a3', + 500: '#737373', + 600: '#525252', + 700: '#404040', + 800: '#262626', + 900: '#171717', + }, + gray: { + 50: '#fafafa', + 100: '#f4f4f5', + 200: '#e4e4e7', + 300: '#d4d4d8', + 400: '#a1a1aa', + 500: '#71717a', + 600: '#52525b', + 700: '#3f3f46', + 800: '#27272a', + 900: '#18181b', + }, + coolGray: { + 50: '#f9fafb', + 100: '#f3f4f6', + 200: '#e5e7eb', + 300: '#d1d5db', + 400: '#9ca3af', + 500: '#6b7280', + 600: '#4b5563', + 700: '#374151', + 800: '#1f2937', + 900: '#111827', + }, + blueGray: { + 50: '#f8fafc', + 100: '#f1f5f9', + 200: '#e2e8f0', + 300: '#cbd5e1', + 400: '#94a3b8', + 500: '#64748b', + 600: '#475569', + 700: '#334155', + 800: '#1e293b', + 900: '#0f172a', + }, +}; + +export default tailwindColors; diff --git a/src/theme/foundations/typography.ts b/src/theme/foundations/typography.ts new file mode 100644 index 0000000..ecd60cd --- /dev/null +++ b/src/theme/foundations/typography.ts @@ -0,0 +1,7 @@ +export const typography = { + fonts: { + heading: `Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`, + body: `Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`, + mono: `SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace`, + }, +}; diff --git a/src/theme/foundations/z-index.ts b/src/theme/foundations/z-index.ts new file mode 100644 index 0000000..d3fd34c --- /dev/null +++ b/src/theme/foundations/z-index.ts @@ -0,0 +1,6 @@ +// Documentation: https://chakra-ui.com/docs/theming/theme#z-index-values +// Default Theme zIndices: https://github.com/chakra-ui/chakra-ui/blob/main/packages/theme/src/foundations/z-index.ts +export const zIndices = { + select: 1650, + dayPicker: 1650, +}; diff --git a/src/theme/index.ts b/src/theme/index.ts new file mode 100644 index 0000000..f7fcd61 --- /dev/null +++ b/src/theme/index.ts @@ -0,0 +1,3 @@ +import './externals-css'; + +export { theme as default } from './theme'; diff --git a/src/theme/styleguide/alerts.stories.mdx b/src/theme/styleguide/alerts.stories.mdx new file mode 100644 index 0000000..9c4af6a --- /dev/null +++ b/src/theme/styleguide/alerts.stories.mdx @@ -0,0 +1,105 @@ +import { Alert, AlertTitle, AlertDescription, AlertIcon, Stack, Box} from '@chakra-ui/react' +import { Meta, Story, Canvas } from '@storybook/addon-docs'; + + + +# Alerts + +```jsx +import { Alert, AlertTitle, AlertDescription, AlertIcon } from '@chakra-ui/react' +``` + +## Default Alert + + + + + + Description + + + Title + + + Title + Description + + + Title + Lorem, ipsum dolor sit amet consectetur adipisicing elit. Beatae odio distinctio eos sequi, voluptates sit voluptas fuga perspiciatis nostrum excepturi cum expedita itaque in assumenda, sed voluptatum non accusantium enim. + + + + Title + Lorem, ipsum dolor sit amet consectetur adipisicing elit. Beatae odio distinctio eos sequi, voluptates sit voluptas fuga perspiciatis nostrum excepturi cum expedita itaque in assumenda, sed voluptatum non accusantium enim. + + + + Title + + + + + + +## Success Alert + + + + + + Success! + Data uploaded to the server. Fire on! + + + + +## Warning Alert + + + + + + Warning! + Seems your account is about expire, upgrade now. + + + + +## Error Alert + + + + + + Your browser is outdated! + Your Chakra experience may be degraded. + + + + + +## Info Alert + + + + + + Info + Chakra is going live on August 30th. Get ready! + + + + + +## Loading Alert + + + + + + Processing + We are validating your order... + + + diff --git a/src/theme/styleguide/buttons.stories.mdx b/src/theme/styleguide/buttons.stories.mdx new file mode 100644 index 0000000..50a0326 --- /dev/null +++ b/src/theme/styleguide/buttons.stories.mdx @@ -0,0 +1,59 @@ +import { Button, ButtonGroup, IconButton } from '@chakra-ui/react'; +import { Meta, Story, Canvas } from '@storybook/addon-docs'; +import { HiPlus, HiMinus } from 'react-icons/hi' + + + +# Buttons + +```jsx +import { Button, IconButtonĀ } from '@chakra-ui/react' +``` + +## Default Button + + + + + + + } aria-label="Add" /> + + + + +## Primary Button + + + + + + + } aria-label="Add" /> + + + + +## Secondary Button + + + + + + + } aria-label="Add" /> + + + + +## Danger Button + + + + + + + } aria-label="Remove" /> + + + diff --git a/src/theme/styleguide/colors.stories.mdx b/src/theme/styleguide/colors.stories.mdx new file mode 100644 index 0000000..4c0c7bd --- /dev/null +++ b/src/theme/styleguide/colors.stories.mdx @@ -0,0 +1,68 @@ +import { Meta, Story, Canvas } from '@storybook/addon-docs'; +import { Box, Flex, HStack } from '@chakra-ui/react'; + + + +export const Color = ({ children, ...rest }) => ( + + + {children} + + +); + +export const Colors = ({ colorScheme = 'gray', ...rest }) => ( + + 50 + 100 + 200 + 300 + 400 + 500 + 600 + 700 + 800 + 900 + +); + +# Colors + +## Brand Color + + + + + +## Gray Color + + + + + +## Error Color + + + + + +## Warning Color + + + + + +## Success Color + + + + diff --git a/src/theme/styleguide/modals.stories.mdx b/src/theme/styleguide/modals.stories.mdx new file mode 100644 index 0000000..369c721 --- /dev/null +++ b/src/theme/styleguide/modals.stories.mdx @@ -0,0 +1,208 @@ +import { + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalFooter, + ModalBody, + ModalCloseButton, + Button, + ButtonGroup, + useDisclosure, + } from '@chakra-ui/react' +import { Meta, Story, Canvas } from '@storybook/addon-docs'; + + + +# Modals + +```jsx +import { + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalFooter, + ModalBody, + ModalCloseButton, +} from '@chakra-ui/react' +``` + +## Default Modal + + + + {(() => { + const modal = useDisclosure() + return ( + <> + + + + + Modal Title + + + Lorem ipsum dolor, sit amet consectetur adipisicing elit. Corporis ullam esse aperiam, vitae aliquam ipsum sapiente possimus nostrum, temporibus facere consequuntur magnam error dicta consectetur asperiores tempore omnis quasi aliquid. + + + + + + + + + + + ) + })()} + + + +## Without Header + + + + {(() => { + const modal = useDisclosure() + return ( + <> + + + + + + Lorem ipsum dolor, sit amet consectetur adipisicing elit. Corporis ullam esse aperiam, vitae aliquam ipsum sapiente possimus nostrum, temporibus facere consequuntur magnam error dicta consectetur asperiores tempore omnis quasi aliquid. + + + + + + + + + + + ) + })()} + + + + +## Without Body + + + + {(() => { + const modal = useDisclosure() + return ( + <> + + + + + Modal Title + + + + + + + + + + + ) + })()} + + + +## Without Footer + + + + {(() => { + const modal = useDisclosure() + return ( + <> + + + + + Modal Title + + + Lorem ipsum dolor, sit amet consectetur adipisicing elit. Corporis ullam esse aperiam, vitae aliquam ipsum sapiente possimus nostrum, temporibus facere consequuntur magnam error dicta consectetur asperiores tempore omnis quasi aliquid. + + + + + ) + })()} + + + + +## Body Only + + + + {(() => { + const modal = useDisclosure() + return ( + <> + + + + + + + Lorem ipsum dolor, sit amet consectetur adipisicing elit. Corporis ullam esse aperiam, vitae aliquam ipsum sapiente possimus nostrum, temporibus facere consequuntur magnam error dicta consectetur asperiores tempore omnis quasi aliquid. + + + + + ) + })()} + + + + +## Modal Full + + + + {(() => { + const modal = useDisclosure() + return ( + <> + + + + + Modal Title + + + Lorem ipsum dolor, sit amet consectetur adipisicing elit. Corporis ullam esse aperiam, vitae aliquam ipsum sapiente possimus nostrum, temporibus facere consequuntur magnam error dicta consectetur asperiores tempore omnis quasi aliquid. + + + + + + + + + + + ) + })()} + + diff --git a/src/theme/styleguide/popovers.stories.mdx b/src/theme/styleguide/popovers.stories.mdx new file mode 100644 index 0000000..d0910af --- /dev/null +++ b/src/theme/styleguide/popovers.stories.mdx @@ -0,0 +1,152 @@ +import { + Popover, + PopoverTrigger, + PopoverContent, + PopoverHeader, + PopoverBody, + PopoverFooter, + PopoverArrow, + PopoverCloseButton, + PopoverAnchor, + Portal, + Button, + ButtonGroup, + } from '@chakra-ui/react' +import { Meta, Story, Canvas } from '@storybook/addon-docs'; + + + +# Popovers + +```jsx +import { + Popover, + PopoverTrigger, + PopoverContent, + PopoverHeader, + PopoverBody, + PopoverFooter, + PopoverArrow, + PopoverCloseButton, + PopoverAnchor, +} from '@chakra-ui/react' +``` + +## Default Popover + + + + + + + + + + + + Confirmation! + Are you sure you want to have that milkshake? + + + + + + + + + + + + + + +## Without header + + + + + + + + + + + Are you sure you want to have that milkshake? + + + + + + + + + + + + + +## Without Body + + + + + + + + + + + + Confirmation! + + + + + + + + + + + + + +## Without Footer + + + + + + + + + + + + Confirmation! + Are you sure you want to have that milkshake? + + + + + + + +## Body Only + + + + + + + + + + + + Are you sure you want to have that milkshake? + + + + + diff --git a/src/theme/styleguide/shadows.stories.mdx b/src/theme/styleguide/shadows.stories.mdx new file mode 100644 index 0000000..0f88a1b --- /dev/null +++ b/src/theme/styleguide/shadows.stories.mdx @@ -0,0 +1,48 @@ +import { Meta, Story, Canvas } from '@storybook/addon-docs'; +import { Box, HStack, useColorModeValue } from '@chakra-ui/react'; + + + +export const Shadow = ({ boxShadow, ...rest }) => ( + + {boxShadow} + +); + +# Shadows + +## Levels + + + + + + + + + + + + + + +## Inner + + + + + + + +## Outline + + + + + + + + + + + diff --git a/src/theme/styles.ts b/src/theme/styles.ts new file mode 100644 index 0000000..e77d4d6 --- /dev/null +++ b/src/theme/styles.ts @@ -0,0 +1,31 @@ +import { StyleFunctionProps, Styles, mode } from '@chakra-ui/theme-tools'; + +import * as externals from './externals'; + +const externalsStyles = (props: StyleFunctionProps) => + Object.values(externals).reduce( + (acc, cur) => ({ + ...acc, + ...(typeof cur === 'function' ? cur(props) : cur), + }), + {} + ); + +export const styles: Styles = { + global: (props) => ({ + html: { + bg: 'gray.800', + }, + body: { + bg: mode('gray.50', 'gray.800')(props), + WebkitTapHighlightColor: 'transparent', + }, + '#chakra-toast-portal > *': { + pt: 'safe-top', + pl: 'safe-left', + pr: 'safe-right', + pb: 'safe-bottom', + }, + ...externalsStyles(props), + }), +}; diff --git a/src/theme/theme.ts b/src/theme/theme.ts new file mode 100644 index 0000000..d99b390 --- /dev/null +++ b/src/theme/theme.ts @@ -0,0 +1,13 @@ +import { extendTheme } from '@chakra-ui/react'; + +import * as components from './components'; +import { config } from './config'; +import foundations from './foundations'; +import { styles } from './styles'; + +export const theme = extendTheme({ + config, + styles, + ...foundations, + components: { ...components }, +}); diff --git a/src/types/meetings.types.ts b/src/types/meetings.types.ts new file mode 100644 index 0000000..bda630a --- /dev/null +++ b/src/types/meetings.types.ts @@ -0,0 +1,47 @@ +export type MeetingSortType = 'OLDEST' | 'NEWEST'; +export type MeetingFilterType = 'ALL' | 'SCHEDULED' | 'COMPLETED' | 'CANCELLED'; + +export type Meeting = { + id: string; + properties: { + hs_createdate: string; + hs_internal_meeting_notes: string; + hs_lastmodifieddate: string; + hs_meeting_outcome: string; + hs_meeting_start_time: string; + hs_meeting_title: string; + hs_object_id: string; + }; + createdAt: string; + updatedAt: string; + archived: boolean; + associations: { + contacts: { + results: { + id: string; + type: string; + }[]; + }; + }; +}; + +export type Contact = { + id: string; + properties: { + createdate: string; + email: string; + firstname: string; + hs_object_id: string; + lastmodifieddate: string; + lastname: string; + }; + createdAt: string; + updatedAt: string; + archived: boolean; +}; + +export type MeetingList = { + meetings: Meeting[]; + contacts: Contact[]; + totalItems: number; +}; diff --git a/tsconfig-old.json b/tsconfig-old.json new file mode 100644 index 0000000..e81a2d2 --- /dev/null +++ b/tsconfig-old.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "paths": { "@/*": ["src/*"] } + }, + "include": [ + "src" + ] +} diff --git a/tsconfig.json b/tsconfig.json index a273b0c..c30534e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,26 +1,28 @@ { "compilerOptions": { - "target": "es5", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], + "target": "es2017", + "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, "strict": true, + "noImplicitAny": true, + "strictBindCallApply": true, "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, + "noEmit": true, + "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx" + "jsx": "preserve", + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + }, + "incremental": true, + "typeRoots": ["node_modules/@types", "src/types"], + "noUncheckedIndexedAccess": true }, - "include": [ - "src" - ] + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] }