From 2067c021ed8bd1817c4688869e60e8f64994b271 Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Mon, 7 Aug 2023 16:21:51 +0530 Subject: [PATCH 1/2] feat(ui): added pagination component --- frontend/.storybook/preview.js | 22 ++++- .../v2/Pagination/Pagination.stories.tsx | 29 ++++++ .../components/v2/Pagination/Pagination.tsx | 95 +++++++++++++++++++ .../src/components/v2/Pagination/index.tsx | 2 + 4 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 frontend/src/components/v2/Pagination/Pagination.stories.tsx create mode 100644 frontend/src/components/v2/Pagination/Pagination.tsx create mode 100644 frontend/src/components/v2/Pagination/index.tsx diff --git a/frontend/.storybook/preview.js b/frontend/.storybook/preview.js index 1fef7cf80..2a3a61d5a 100644 --- a/frontend/.storybook/preview.js +++ b/frontend/.storybook/preview.js @@ -1,8 +1,22 @@ -import { themes } from '@storybook/theming'; -import '../src/styles/globals.css'; +import { themes } from "@storybook/theming"; +import "react-day-picker/dist/style.css"; +import "../src/styles/globals.css"; export const parameters = { - actions: { argTypesRegex: '^on[A-Z].*' }, + actions: { argTypesRegex: "^on[A-Z].*" }, + backgrounds: { + default: "dark", + values: [ + { + name: "dark", + value: "rgb(14, 16, 20)" + }, + { + name: "paper", + value: "rgb(30, 31, 34)" + } + ] + }, controls: { matchers: { color: /(background|color)$/i, @@ -10,6 +24,6 @@ export const parameters = { } }, darkMode: { - dark: { ...themes.dark, appContentBg: 'rgb(14,16,20)', appBg: 'rgb(14,16,20)' } + dark: { ...themes.dark, appContentBg: "rgb(14,16,20)", appBg: "rgb(14,16,20)" } } }; diff --git a/frontend/src/components/v2/Pagination/Pagination.stories.tsx b/frontend/src/components/v2/Pagination/Pagination.stories.tsx new file mode 100644 index 000000000..fd10ef8c6 --- /dev/null +++ b/frontend/src/components/v2/Pagination/Pagination.stories.tsx @@ -0,0 +1,29 @@ +// eslint-disable-next-line +import { useArgs } from "@storybook/client-api"; +import type { Meta } from "@storybook/react"; + +import { Pagination, PaginationProps } from "./Pagination"; + +const meta: Meta = { + title: "Components/Pagination", + component: Pagination, + tags: ["v2"], + args: { + count: 50 + } +}; + +export default meta; +// type Story = StoryObj; + +export const Primary = (args: PaginationProps) => { + const [, updateArgs] = useArgs(); + + return ( + updateArgs({ page })} + onChangePerPage={(perPage) => updateArgs({ perPage, page: 1 })} + /> + ); +}; diff --git a/frontend/src/components/v2/Pagination/Pagination.tsx b/frontend/src/components/v2/Pagination/Pagination.tsx new file mode 100644 index 000000000..99d50a07f --- /dev/null +++ b/frontend/src/components/v2/Pagination/Pagination.tsx @@ -0,0 +1,95 @@ +import { + faCaretDown, + faCheck, + faChevronLeft, + faChevronRight +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { twMerge } from "tailwind-merge"; + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from "../Dropdown"; +import { IconButton } from "../IconButton"; + +export type PaginationProps = { + count: number; + page: number; + perPage?: number; + onChangePage: (pageNumber: number) => void; + onChangePerPage: (newRows: number) => void; + className: string; + perPageList?: number[]; +}; + +export const Pagination = ({ + count, + page = 1, + perPage = 20, + onChangePage, + onChangePerPage, + perPageList = [10, 20, 50, 100], + className +}: PaginationProps) => { + const prevPageNumber = Math.max(1, page - 1); + const canGoPrev = page > 1; + + const upperLimit = Math.ceil(count / perPage); + const nextPageNumber = Math.min(upperLimit, page + 1); + const canGoNext = page + 1 <= upperLimit; + + return ( +
+
+
+ {(page - 1) * perPage} - {(page - 1) * perPage + perPage} of {count} +
+ + + + + + + + {perPageList.map((perPageOption) => ( + } + iconPos="right" + onClick={() => onChangePerPage(perPageOption)} + > + {perPageOption} rows per page + + ))} + + +
+
+ onChangePage(prevPageNumber)} + isDisabled={!canGoPrev} + > + + + onChangePage(nextPageNumber)} + isDisabled={!canGoNext} + > + + +
+
+ ); +}; diff --git a/frontend/src/components/v2/Pagination/index.tsx b/frontend/src/components/v2/Pagination/index.tsx new file mode 100644 index 000000000..583a0b550 --- /dev/null +++ b/frontend/src/components/v2/Pagination/index.tsx @@ -0,0 +1,2 @@ +export type { PaginationProps } from "./Pagination"; +export { Pagination } from "./Pagination"; From be86e4176cdf7914edc48767fe9dab3fe71057ce Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Mon, 7 Aug 2023 16:22:15 +0530 Subject: [PATCH 2/2] feat(ui): added datepicker component --- frontend/package-lock.json | 244 ++++++++++++++++-- frontend/package.json | 4 +- .../v2/DatePicker/DatePicker.stories.tsx | 18 ++ .../components/v2/DatePicker/DatePicker.tsx | 37 +++ .../src/components/v2/DatePicker/index.tsx | 2 + .../src/components/v2/Dropdown/Dropdown.tsx | 5 +- frontend/src/components/v2/index.tsx | 2 + frontend/src/pages/_app.tsx | 1 + frontend/src/styles/globals.css | 15 ++ .../components/WebhooksTab/WebhooksTab.tsx | 5 +- 10 files changed, 310 insertions(+), 23 deletions(-) create mode 100644 frontend/src/components/v2/DatePicker/DatePicker.stories.tsx create mode 100644 frontend/src/components/v2/DatePicker/DatePicker.tsx create mode 100644 frontend/src/components/v2/DatePicker/index.tsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 987ebd5c8..568410bb2 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -47,7 +47,7 @@ "classnames": "^2.3.1", "cookies": "^0.8.0", "cva": "npm:class-variance-authority@^0.4.0", - "dayjs": "^1.11.9", + "date-fns": "^2.30.0", "framer-motion": "^6.2.3", "fs": "^0.0.2", "gray-matter": "^4.0.3", @@ -69,6 +69,7 @@ "react-beautiful-dnd": "^13.1.1", "react-code-input": "^3.10.1", "react-contenteditable": "^3.3.7", + "react-day-picker": "^8.8.0", "react-dom": "^17.0.2", "react-grid-layout": "^1.3.4", "react-hook-form": "^7.43.0", @@ -95,6 +96,7 @@ "@storybook/addon-links": "^7.0.23", "@storybook/addon-styling": "^1.3.0", "@storybook/blocks": "^7.0.23", + "@storybook/client-api": "^7.2.1", "@storybook/nextjs": "^7.0.23", "@storybook/react": "^7.0.23", "@storybook/testing-library": "^0.2.0", @@ -5781,6 +5783,20 @@ } } }, + "node_modules/@storybook/builder-webpack5/node_modules/@storybook/client-api": { + "version": "7.0.23", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.0.23.tgz", + "integrity": "sha512-Z2ubbWJXORuhb1Faur3DL5zV8OObanQY7ow506CmEwNKRgy2LVzkBwpm4woEJHgw95sOyGuz3f3xfDP2DC6M7A==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "7.0.23", + "@storybook/preview-api": "7.0.23" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { "version": "16.18.36", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.36.tgz", @@ -6126,13 +6142,96 @@ "dev": true }, "node_modules/@storybook/client-api": { - "version": "7.0.23", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.0.23.tgz", - "integrity": "sha512-Z2ubbWJXORuhb1Faur3DL5zV8OObanQY7ow506CmEwNKRgy2LVzkBwpm4woEJHgw95sOyGuz3f3xfDP2DC6M7A==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.2.1.tgz", + "integrity": "sha512-VeRUxc4ufSaGAQPe/LM4aucpEx2UHHw9c+tzolV3hzGIp6pmIAS8XI6thL2IccYmsNMS2zz9oDESYP9cNlTsyA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.23", - "@storybook/preview-api": "7.0.23" + "@storybook/client-logger": "7.2.1", + "@storybook/preview-api": "7.2.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/client-api/node_modules/@storybook/channels": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.2.1.tgz", + "integrity": "sha512-3ZogzjwlFG+oarwnI7TTvWvHVOUtJbjrgZkM5QuLMlxNzIR1XuBY8f01yf4K8+VpdNy9DY+7Q/j6tBThfwYvpA==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "7.2.1", + "@storybook/core-events": "7.2.1", + "@storybook/global": "^5.0.0", + "qs": "^6.10.0", + "telejson": "^7.0.3", + "tiny-invariant": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/client-api/node_modules/@storybook/client-logger": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.2.1.tgz", + "integrity": "sha512-Lyht/lJg2S65CXRy9rXAZXP/Mgye7jbi/aqQL8z9VRMGChbL+k/3pSZnXTTrD1OVSpCEr4UWA+9bStzT4VjtYA==", + "dev": true, + "dependencies": { + "@storybook/global": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/client-api/node_modules/@storybook/core-events": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.2.1.tgz", + "integrity": "sha512-EUXYb3gyQ2EzpDAWkgfoDl1EPabj3OE6+zntsD/gwvzQU85BTocs10ksnRyS55bfrQpYbf+Z+gw2CZboyagLgg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/client-api/node_modules/@storybook/preview-api": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.2.1.tgz", + "integrity": "sha512-WKecuOdeh9+og6bPR9KoQf/JCeSRPCcfZv9uNfJzAp3IiTnS3UpfCz+HBZzZJQrisgbd7OulNY400HQUmxY2Ag==", + "dev": true, + "dependencies": { + "@storybook/channels": "7.2.1", + "@storybook/client-logger": "7.2.1", + "@storybook/core-events": "7.2.1", + "@storybook/csf": "^0.1.0", + "@storybook/global": "^5.0.0", + "@storybook/types": "7.2.1", + "@types/qs": "^6.9.5", + "dequal": "^2.0.2", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "synchronous-promise": "^2.0.15", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/client-api/node_modules/@storybook/types": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.2.1.tgz", + "integrity": "sha512-YwlIY1uyxfJjijbB5x1d1QOKaUUDJnMX8BSb8oGqU4cyT76X/Is4CbGs+vccFsJo0tZu1GfuahYXl0EDT0nnSQ==", + "dev": true, + "dependencies": { + "@storybook/channels": "7.2.1", + "@types/babel__core": "^7.0.0", + "@types/express": "^4.7.0", + "file-system-cache": "2.3.0" }, "funding": { "type": "opencollective", @@ -10724,10 +10823,20 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, - "node_modules/dayjs": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", - "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" + "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/debug": { "version": "4.3.4", @@ -19041,6 +19150,19 @@ "react": ">=16.3" } }, + "node_modules/react-day-picker": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.8.0.tgz", + "integrity": "sha512-QIC3uOuyGGbtypbd5QEggsCSqVaPNu8kzUWquZ7JjW9fuWB9yv7WyixKmnaFelTLXFdq7h7zU6n/aBleBqe/dA==", + "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-docgen": { "version": "5.4.3", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-5.4.3.tgz", @@ -26972,6 +27094,16 @@ "webpack-virtual-modules": "^0.4.3" }, "dependencies": { + "@storybook/client-api": { + "version": "7.0.23", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.0.23.tgz", + "integrity": "sha512-Z2ubbWJXORuhb1Faur3DL5zV8OObanQY7ow506CmEwNKRgy2LVzkBwpm4woEJHgw95sOyGuz3f3xfDP2DC6M7A==", + "dev": true, + "requires": { + "@storybook/client-logger": "7.0.23", + "@storybook/preview-api": "7.0.23" + } + }, "@types/node": { "version": "16.18.36", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.36.tgz", @@ -27215,13 +27347,78 @@ } }, "@storybook/client-api": { - "version": "7.0.23", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.0.23.tgz", - "integrity": "sha512-Z2ubbWJXORuhb1Faur3DL5zV8OObanQY7ow506CmEwNKRgy2LVzkBwpm4woEJHgw95sOyGuz3f3xfDP2DC6M7A==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-7.2.1.tgz", + "integrity": "sha512-VeRUxc4ufSaGAQPe/LM4aucpEx2UHHw9c+tzolV3hzGIp6pmIAS8XI6thL2IccYmsNMS2zz9oDESYP9cNlTsyA==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.23", - "@storybook/preview-api": "7.0.23" + "@storybook/client-logger": "7.2.1", + "@storybook/preview-api": "7.2.1" + }, + "dependencies": { + "@storybook/channels": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.2.1.tgz", + "integrity": "sha512-3ZogzjwlFG+oarwnI7TTvWvHVOUtJbjrgZkM5QuLMlxNzIR1XuBY8f01yf4K8+VpdNy9DY+7Q/j6tBThfwYvpA==", + "dev": true, + "requires": { + "@storybook/client-logger": "7.2.1", + "@storybook/core-events": "7.2.1", + "@storybook/global": "^5.0.0", + "qs": "^6.10.0", + "telejson": "^7.0.3", + "tiny-invariant": "^1.3.1" + } + }, + "@storybook/client-logger": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.2.1.tgz", + "integrity": "sha512-Lyht/lJg2S65CXRy9rXAZXP/Mgye7jbi/aqQL8z9VRMGChbL+k/3pSZnXTTrD1OVSpCEr4UWA+9bStzT4VjtYA==", + "dev": true, + "requires": { + "@storybook/global": "^5.0.0" + } + }, + "@storybook/core-events": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.2.1.tgz", + "integrity": "sha512-EUXYb3gyQ2EzpDAWkgfoDl1EPabj3OE6+zntsD/gwvzQU85BTocs10ksnRyS55bfrQpYbf+Z+gw2CZboyagLgg==", + "dev": true + }, + "@storybook/preview-api": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.2.1.tgz", + "integrity": "sha512-WKecuOdeh9+og6bPR9KoQf/JCeSRPCcfZv9uNfJzAp3IiTnS3UpfCz+HBZzZJQrisgbd7OulNY400HQUmxY2Ag==", + "dev": true, + "requires": { + "@storybook/channels": "7.2.1", + "@storybook/client-logger": "7.2.1", + "@storybook/core-events": "7.2.1", + "@storybook/csf": "^0.1.0", + "@storybook/global": "^5.0.0", + "@storybook/types": "7.2.1", + "@types/qs": "^6.9.5", + "dequal": "^2.0.2", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "synchronous-promise": "^2.0.15", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/types": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.2.1.tgz", + "integrity": "sha512-YwlIY1uyxfJjijbB5x1d1QOKaUUDJnMX8BSb8oGqU4cyT76X/Is4CbGs+vccFsJo0tZu1GfuahYXl0EDT0nnSQ==", + "dev": true, + "requires": { + "@storybook/channels": "7.2.1", + "@types/babel__core": "^7.0.0", + "@types/express": "^4.7.0", + "file-system-cache": "2.3.0" + } + } } }, "@storybook/client-logger": { @@ -30800,10 +30997,13 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, - "dayjs": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", - "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" + "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==", + "requires": { + "@babel/runtime": "^7.21.0" + } }, "debug": { "version": "4.3.4", @@ -36915,6 +37115,12 @@ "prop-types": "^15.7.1" } }, + "react-day-picker": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.8.0.tgz", + "integrity": "sha512-QIC3uOuyGGbtypbd5QEggsCSqVaPNu8kzUWquZ7JjW9fuWB9yv7WyixKmnaFelTLXFdq7h7zU6n/aBleBqe/dA==", + "requires": {} + }, "react-docgen": { "version": "5.4.3", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-5.4.3.tgz", diff --git a/frontend/package.json b/frontend/package.json index e779e95b1..9aa355d4b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -55,7 +55,7 @@ "classnames": "^2.3.1", "cookies": "^0.8.0", "cva": "npm:class-variance-authority@^0.4.0", - "dayjs": "^1.11.9", + "date-fns": "^2.30.0", "framer-motion": "^6.2.3", "fs": "^0.0.2", "gray-matter": "^4.0.3", @@ -77,6 +77,7 @@ "react-beautiful-dnd": "^13.1.1", "react-code-input": "^3.10.1", "react-contenteditable": "^3.3.7", + "react-day-picker": "^8.8.0", "react-dom": "^17.0.2", "react-grid-layout": "^1.3.4", "react-hook-form": "^7.43.0", @@ -103,6 +104,7 @@ "@storybook/addon-links": "^7.0.23", "@storybook/addon-styling": "^1.3.0", "@storybook/blocks": "^7.0.23", + "@storybook/client-api": "^7.2.1", "@storybook/nextjs": "^7.0.23", "@storybook/react": "^7.0.23", "@storybook/testing-library": "^0.2.0", diff --git a/frontend/src/components/v2/DatePicker/DatePicker.stories.tsx b/frontend/src/components/v2/DatePicker/DatePicker.stories.tsx new file mode 100644 index 000000000..4c6e95b5e --- /dev/null +++ b/frontend/src/components/v2/DatePicker/DatePicker.stories.tsx @@ -0,0 +1,18 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import { DatePicker } from "./DatePicker"; + +const meta: Meta = { + title: "Components/DatePicker", + component: DatePicker, + tags: ["v2"], + argTypes: {} +}; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/7.0/react/writing-stories/args +export const Primary: Story = { + args: {} +}; diff --git a/frontend/src/components/v2/DatePicker/DatePicker.tsx b/frontend/src/components/v2/DatePicker/DatePicker.tsx new file mode 100644 index 000000000..4c59c00b1 --- /dev/null +++ b/frontend/src/components/v2/DatePicker/DatePicker.tsx @@ -0,0 +1,37 @@ +import { DayPicker, DayPickerProps } from "react-day-picker"; +import { faCalendar } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { PopoverContentProps, PopoverProps } from "@radix-ui/react-popover"; +import { format } from "date-fns"; + +import { Button } from "../Button"; +import { Popover, PopoverContent, PopoverTrigger } from "../Popoverv2"; + +export type DatePickerProps = Omit & { + value?: Date; + onChange: (date?: Date) => void; + popUpProps: PopoverProps; + popUpContentProps: PopoverContentProps; +}; + +// Doc: https://react-day-picker.js.org/ +export const DatePicker = ({ + value, + onChange, + popUpProps, + popUpContentProps, + ...props +}: DatePickerProps) => { + return ( + + + + + + + + + ); +}; diff --git a/frontend/src/components/v2/DatePicker/index.tsx b/frontend/src/components/v2/DatePicker/index.tsx new file mode 100644 index 000000000..86fa9e298 --- /dev/null +++ b/frontend/src/components/v2/DatePicker/index.tsx @@ -0,0 +1,2 @@ +export type { DatePickerProps } from "./DatePicker"; +export { DatePicker } from "./DatePicker"; diff --git a/frontend/src/components/v2/Dropdown/Dropdown.tsx b/frontend/src/components/v2/Dropdown/Dropdown.tsx index def928c74..8d2427c1c 100644 --- a/frontend/src/components/v2/Dropdown/Dropdown.tsx +++ b/frontend/src/components/v2/Dropdown/Dropdown.tsx @@ -49,6 +49,7 @@ export type DropdownMenuItemProps = icon?: ReactNode; as?: T; inputRef?: Ref; + iconPos?: "left" | "right"; }; export const DropdownMenuItem = ({ @@ -57,6 +58,7 @@ export const DropdownMenuItem = ({ className, icon, as: Item = "button", + iconPos = "left", ...props }: DropdownMenuItemProps & ComponentPropsWithRef) => ( ({ )} > - {icon && {icon}} + {icon && iconPos === "left" && {icon}} {children} + {icon && iconPos === "right" && {icon}} ); diff --git a/frontend/src/components/v2/index.tsx b/frontend/src/components/v2/index.tsx index b4412b47b..8d23594dc 100644 --- a/frontend/src/components/v2/index.tsx +++ b/frontend/src/components/v2/index.tsx @@ -1,6 +1,7 @@ export * from "./Button"; export * from "./Card"; export * from "./Checkbox"; +export * from "./DatePicker"; export * from "./DeleteActionModal"; export * from "./Drawer"; export * from "./Dropdown"; @@ -12,6 +13,7 @@ export * from "./IconButton"; export * from "./Input"; export * from "./Menu"; export * from "./Modal"; +export * from "./Pagination"; export * from "./Popoverv2"; export * from "./SecretInput"; export * from "./Select"; diff --git a/frontend/src/pages/_app.tsx b/frontend/src/pages/_app.tsx index 82e642245..332557732 100644 --- a/frontend/src/pages/_app.tsx +++ b/frontend/src/pages/_app.tsx @@ -28,6 +28,7 @@ import { queryClient } from "@app/reactQuery"; import "nprogress/nprogress.css"; import "@fortawesome/fontawesome-svg-core/styles.css"; +import "react-day-picker/dist/style.css"; import "../styles/globals.css"; import "@app/i18n"; diff --git a/frontend/src/styles/globals.css b/frontend/src/styles/globals.css index ed191a319..ae8d17427 100644 --- a/frontend/src/styles/globals.css +++ b/frontend/src/styles/globals.css @@ -1,5 +1,20 @@ @tailwind base; @tailwind components; + +.rdp-day, +.rdp-nav_button { + @apply rounded-md hover:text-mineshaft-500; +} + +.rdp-button:hover:not([disabled]):not(.rdp-day_selected), +.rdp-nav_button:hover { + @apply bg-primary; +} + +.rdp-day_today { + @apply bg-primary/50 hover:bg-primary-600 text-mineshaft-500; +} + @tailwind utilities; @layer utilities { diff --git a/frontend/src/views/Settings/ProjectSettingsPage/components/WebhooksTab/WebhooksTab.tsx b/frontend/src/views/Settings/ProjectSettingsPage/components/WebhooksTab/WebhooksTab.tsx index 598af0360..d5cb16b7b 100644 --- a/frontend/src/views/Settings/ProjectSettingsPage/components/WebhooksTab/WebhooksTab.tsx +++ b/frontend/src/views/Settings/ProjectSettingsPage/components/WebhooksTab/WebhooksTab.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { faInfoCircle, faPlug, faPlus } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import dayjs from "dayjs"; +import { format } from "date-fns"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { @@ -196,7 +196,8 @@ export const WebhooksTab = () => { content={
- Updated At: {dayjs(updatedAt).format("YYYY-MM-DD, hh:mm A")} + Updated At:{" "} + {format(new Date(updatedAt), "YYYY-MM-DD, hh:mm aaa")}
{lastRunErrorMessage && (