From 32305cedbc8f94c369af5ca5e79494daad590b25 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Fri, 8 Mar 2024 12:44:48 +0700 Subject: [PATCH 01/22] =?UTF-8?q?=F0=9F=8E=A8=20style:=20add=20overflow=20?= =?UTF-8?q?for=20the=20content?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/layouts/ProjectSearch.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/layouts/ProjectSearch.tsx b/packages/frontend/src/layouts/ProjectSearch.tsx index 5a71356d..1343a5b0 100644 --- a/packages/frontend/src/layouts/ProjectSearch.tsx +++ b/packages/frontend/src/layouts/ProjectSearch.tsx @@ -72,7 +72,7 @@ const ProjectSearch = () => { {/* Content */} -
+
From 16e7b225071e3b5919aea5498254eddf2f967f73 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Fri, 8 Mar 2024 15:27:53 +0700 Subject: [PATCH 02/22] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20create=20mod?= =?UTF-8?q?al=20comopnent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/shared/Modal/Modal.theme.ts | 67 +++++++++++++++++++ .../src/components/shared/Modal/Modal.tsx | 46 +++++++++++++ .../shared/Modal/ModalBody/ModalBody.tsx | 26 +++++++ .../shared/Modal/ModalBody/index.ts | 1 + .../Modal/ModalContent/ModalContent.tsx | 64 ++++++++++++++++++ .../shared/Modal/ModalContent/index.ts | 1 + .../shared/Modal/ModalFooter/ModalFooter.tsx | 23 +++++++ .../shared/Modal/ModalFooter/index.ts | 1 + .../shared/Modal/ModalHeader/ModalHeader.tsx | 52 ++++++++++++++ .../shared/Modal/ModalHeader/index.ts | 1 + .../components/shared/Modal/ModalProvider.tsx | 42 ++++++++++++ .../src/components/shared/Modal/index.ts | 1 + 12 files changed, 325 insertions(+) create mode 100644 packages/frontend/src/components/shared/Modal/Modal.theme.ts create mode 100644 packages/frontend/src/components/shared/Modal/Modal.tsx create mode 100644 packages/frontend/src/components/shared/Modal/ModalBody/ModalBody.tsx create mode 100644 packages/frontend/src/components/shared/Modal/ModalBody/index.ts create mode 100644 packages/frontend/src/components/shared/Modal/ModalContent/ModalContent.tsx create mode 100644 packages/frontend/src/components/shared/Modal/ModalContent/index.ts create mode 100644 packages/frontend/src/components/shared/Modal/ModalFooter/ModalFooter.tsx create mode 100644 packages/frontend/src/components/shared/Modal/ModalFooter/index.ts create mode 100644 packages/frontend/src/components/shared/Modal/ModalHeader/ModalHeader.tsx create mode 100644 packages/frontend/src/components/shared/Modal/ModalHeader/index.ts create mode 100644 packages/frontend/src/components/shared/Modal/ModalProvider.tsx create mode 100644 packages/frontend/src/components/shared/Modal/index.ts diff --git a/packages/frontend/src/components/shared/Modal/Modal.theme.ts b/packages/frontend/src/components/shared/Modal/Modal.theme.ts new file mode 100644 index 00000000..81dec838 --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/Modal.theme.ts @@ -0,0 +1,67 @@ +import type { VariantProps } from 'tailwind-variants'; +import { tv } from 'tailwind-variants'; + +export const modalTheme = tv({ + slots: { + overlay: [ + 'z-modal', + 'fixed', + 'inset-0', + 'bg-bg-base/90', + 'backdrop-blur-sm', + 'overflow-y-auto', + 'flex', + 'justify-center', + 'items-center', + 'p-6', + 'sm:p-10', + 'data-[state=closed]:animate-[dialog-overlay-hide_200ms]', + 'data-[state=open]:animate-[dialog-overlay-show_200ms]', + 'data-[state=closed]:hidden', // Fix overlay not close when modal is closed + ], + close: [ + 'absolute', + 'right-6', + 'top-5', + 'sm:right-10', + 'sm:top-[38px]', + 'z-[1]', + ], + header: ['flex', 'flex-col', 'gap-2', 'items-start', 'px-6', 'sm:px-10'], + headerTitle: ['text-lg', 'sm:text-xl', 'text-text-em-high'], + headerDescription: ['text-sm', 'text-text-em-low'], + footer: ['flex', 'justify-end', 'gap-3', 'sm:gap-4', 'px-6', 'sm:px-10'], + content: [ + 'h-fit', + 'sm:min-h-0', + 'sm:m-auto', + 'relative', + 'flex', + 'flex-col', + 'gap-y-8', + 'py-6', + 'sm:py-10', + 'overflow-hidden', + 'w-full', + 'max-w-[560px]', + 'rounded-xl', + 'bg-surface-base', + 'border', + 'border-border-base', + 'text-text-em-high', + ], + body: ['flex-1', 'px-6', 'sm:px-10'], + }, + variants: { + fullPage: { + true: { + content: ['h-full'], + overlay: ['!p-0'], + }, + }, + }, + defaultVariants: { + fullPage: false, + }, +}); +export type ModalVariants = VariantProps; diff --git a/packages/frontend/src/components/shared/Modal/Modal.tsx b/packages/frontend/src/components/shared/Modal/Modal.tsx new file mode 100644 index 00000000..ef9069f4 --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/Modal.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import type { DialogProps } from '@radix-ui/react-dialog'; +import { Root, Trigger } from '@radix-ui/react-dialog'; +import type { ComponentPropsWithoutRef, PropsWithChildren } from 'react'; + +import type { ModalVariants } from './Modal.theme'; +import { ModalBody } from './ModalBody'; +import { ModalContent } from './ModalContent'; +import { ModalFooter } from './ModalFooter'; +import { ModalHeader } from './ModalHeader'; +import ModalProvider from './ModalProvider'; + +export interface ModalProps + extends ComponentPropsWithoutRef<'div'>, + ModalVariants, + DialogProps { + hasCloseButton?: boolean; + hasOverlay?: boolean; + preventClickOutsideToClose?: boolean; +} +export const Modal = ({ + children, + hasCloseButton = true, + hasOverlay = true, + preventClickOutsideToClose = false, + fullPage = false, + ...props +}: PropsWithChildren) => { + return ( + + {children} + + ); +}; + +Modal.Trigger = Trigger; +Modal.Content = ModalContent; +Modal.Header = ModalHeader; +Modal.Footer = ModalFooter; +Modal.Body = ModalBody; diff --git a/packages/frontend/src/components/shared/Modal/ModalBody/ModalBody.tsx b/packages/frontend/src/components/shared/Modal/ModalBody/ModalBody.tsx new file mode 100644 index 00000000..3079b267 --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/ModalBody/ModalBody.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import type { ComponentPropsWithoutRef, PropsWithChildren } from 'react'; +import { modalTheme } from 'components/shared/Modal/Modal.theme'; + +export interface ModalBodyProps extends ComponentPropsWithoutRef<'div'> { + className?: string; +} + +export const ModalBody = ({ + children, + className, + ...props +}: PropsWithChildren) => { + const { body } = modalTheme(); + + return ( +
+ {children} +
+ ); +}; diff --git a/packages/frontend/src/components/shared/Modal/ModalBody/index.ts b/packages/frontend/src/components/shared/Modal/ModalBody/index.ts new file mode 100644 index 00000000..ad32ff0c --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/ModalBody/index.ts @@ -0,0 +1 @@ +export * from './ModalBody'; diff --git a/packages/frontend/src/components/shared/Modal/ModalContent/ModalContent.tsx b/packages/frontend/src/components/shared/Modal/ModalContent/ModalContent.tsx new file mode 100644 index 00000000..166256a8 --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/ModalContent/ModalContent.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import type { DialogContentProps } from '@radix-ui/react-dialog'; +import { Close, Content, Overlay, Portal } from '@radix-ui/react-dialog'; +import { Ref, forwardRef, type PropsWithChildren } from 'react'; +import { useModal } from 'components/shared/Modal/ModalProvider'; +import { modalTheme } from 'components/shared/Modal/Modal.theme'; +import { Button } from 'components/shared/Button'; +import { CrossIcon } from 'components/shared/CustomIcon'; + +type PointerDownOutsideEvent = CustomEvent<{ + originalEvent: PointerEvent; +}>; + +export interface ModalContentProps extends DialogContentProps { + className?: string; +} + +const ModalContent = forwardRef( + ( + { children, className, ...props }: PropsWithChildren, + forwardedRef, + ) => { + const { hasCloseButton, preventClickOutsideToClose, fullPage } = useModal(); + + const { content, close, overlay } = modalTheme({ fullPage }); + + const preventClickOutsideToCloseProps = preventClickOutsideToClose && { + onPointerDownOutside: (e: PointerDownOutsideEvent) => e.preventDefault(), + onEscapeKeyDown: (e: KeyboardEvent) => e.preventDefault(), + }; + + return ( + + + } + > + {hasCloseButton && ( + + + + )} + {children} + + + + ); + }, +); + +ModalContent.displayName = 'ModalContent'; + +export { ModalContent }; diff --git a/packages/frontend/src/components/shared/Modal/ModalContent/index.ts b/packages/frontend/src/components/shared/Modal/ModalContent/index.ts new file mode 100644 index 00000000..79dee456 --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/ModalContent/index.ts @@ -0,0 +1 @@ +export * from './ModalContent'; diff --git a/packages/frontend/src/components/shared/Modal/ModalFooter/ModalFooter.tsx b/packages/frontend/src/components/shared/Modal/ModalFooter/ModalFooter.tsx new file mode 100644 index 00000000..5152e884 --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/ModalFooter/ModalFooter.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import type { ComponentPropsWithoutRef, PropsWithChildren } from 'react'; +import { modalTheme } from 'components/shared/Modal/Modal.theme'; + +type ModalFooterProps = ComponentPropsWithoutRef<'div'> & { + className?: string; +}; + +export const ModalFooter = ({ + children, + className, + ...props +}: PropsWithChildren) => { + const { footer } = modalTheme({ + className, + }); + + return ( +
+ {children} +
+ ); +}; diff --git a/packages/frontend/src/components/shared/Modal/ModalFooter/index.ts b/packages/frontend/src/components/shared/Modal/ModalFooter/index.ts new file mode 100644 index 00000000..2da6856b --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/ModalFooter/index.ts @@ -0,0 +1 @@ +export * from './ModalFooter'; diff --git a/packages/frontend/src/components/shared/Modal/ModalHeader/ModalHeader.tsx b/packages/frontend/src/components/shared/Modal/ModalHeader/ModalHeader.tsx new file mode 100644 index 00000000..ca588db9 --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/ModalHeader/ModalHeader.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import type { DialogDescriptionProps } from '@radix-ui/react-dialog'; +import { Description, Title } from '@radix-ui/react-dialog'; +import type { ComponentPropsWithoutRef, PropsWithChildren } from 'react'; +import { Heading } from 'components/shared/Heading'; +import { modalTheme } from 'components/shared/Modal/Modal.theme'; + +type ModalHeaderProps = ComponentPropsWithoutRef<'div'> & { + className?: string; + description?: string | React.ReactNode; + descriptionProps?: DialogDescriptionProps; + headingProps?: ComponentPropsWithoutRef<'h2'>; +}; + +export const ModalHeader = ({ + children, + description, + className, + descriptionProps, + headingProps, + ...props +}: PropsWithChildren) => { + const { header, headerDescription, headerTitle } = modalTheme(); + + return ( +
+ + <Heading + {...headingProps} + className={headerTitle({ className: headingProps?.className })} + > + {children} + </Heading> + + {description && ( + + {description} + + )} +
+ ); +}; diff --git a/packages/frontend/src/components/shared/Modal/ModalHeader/index.ts b/packages/frontend/src/components/shared/Modal/ModalHeader/index.ts new file mode 100644 index 00000000..4424e620 --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/ModalHeader/index.ts @@ -0,0 +1 @@ +export * from './ModalHeader'; diff --git a/packages/frontend/src/components/shared/Modal/ModalProvider.tsx b/packages/frontend/src/components/shared/Modal/ModalProvider.tsx new file mode 100644 index 00000000..2be6bebd --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/ModalProvider.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import type { PropsWithChildren } from 'react'; +import { createContext, useContext } from 'react'; + +import type { ModalProps } from './Modal'; +import type { ModalVariants } from './Modal.theme'; + +export interface ModalProviderProps + extends Partial, + ModalProps {} + +type ModalProviderContext = ReturnType; + +const ModalContext = createContext | undefined>( + undefined, +); + +// For inferring return type +const useModalValues = (props: ModalProviderProps) => { + return props; +}; + +export const ModalProvider = ({ + children, + ...props +}: PropsWithChildren): JSX.Element => { + const values = useModalValues(props); + + return ( + {children} + ); +}; + +export const useModal = () => { + const context = useContext(ModalContext); + if (context === undefined) { + throw new Error('useModal was used outside of its Provider'); + } + return context; +}; + +export default ModalProvider; diff --git a/packages/frontend/src/components/shared/Modal/index.ts b/packages/frontend/src/components/shared/Modal/index.ts new file mode 100644 index 00000000..cb89ee17 --- /dev/null +++ b/packages/frontend/src/components/shared/Modal/index.ts @@ -0,0 +1 @@ +export * from './Modal'; From cbda1cc6523412fda6c7e862daf25cd7b9b70054 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Fri, 8 Mar 2024 15:28:23 +0700 Subject: [PATCH 03/22] =?UTF-8?q?=F0=9F=8E=A8=20style:=20add=20new=20keyfr?= =?UTF-8?q?ame=20animation=20for=20modal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/index.css | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/packages/frontend/src/index.css b/packages/frontend/src/index.css index 502904a5..541fb61e 100644 --- a/packages/frontend/src/index.css +++ b/packages/frontend/src/index.css @@ -153,4 +153,44 @@ .focus-ring { @apply focus-visible:ring-[3px] focus-visible:ring-snowball-200 focus-visible:ring-offset-1 focus-visible:ring-offset-snowball-500 focus-visible:outline-none; } + + @keyframes dialog-overlay-show { + from { + opacity: 0; + } + to { + opacity: 1; + } + } + + @keyframes dialog-overlay-hide { + from { + opacity: 1; + } + to { + opacity: 0; + } + } + + @keyframes dialog-content-show { + from { + opacity: 0; + transform: translate(-50%, -50%) scale(0.95); + } + to { + opacity: 1; + transform: translate(-50%, -50%) scale(1); + } + } + + @keyframes dialog-content-hide { + from { + opacity: 1; + transform: translate(-50%, -50%) scale(1); + } + to { + opacity: 0; + transform: translate(-50%, -50%) scale(0.95); + } + } } From 296e149391875426a444fccc18a7facc6a81fa73 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Fri, 8 Mar 2024 15:29:06 +0700 Subject: [PATCH 04/22] =?UTF-8?q?=F0=9F=8E=A8=20style:=20update=20confirm?= =?UTF-8?q?=20dialog=20to=20use=20custom=20modal=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/shared/ConfirmDialog.tsx | 56 ++++++------------- 1 file changed, 16 insertions(+), 40 deletions(-) diff --git a/packages/frontend/src/components/shared/ConfirmDialog.tsx b/packages/frontend/src/components/shared/ConfirmDialog.tsx index 1de20e98..9a943d54 100644 --- a/packages/frontend/src/components/shared/ConfirmDialog.tsx +++ b/packages/frontend/src/components/shared/ConfirmDialog.tsx @@ -1,16 +1,10 @@ import React from 'react'; import { color } from '@material-tailwind/react/types/components/button'; -import { - Typography, - Button, - Dialog, - DialogHeader, - DialogBody, - DialogFooter, -} from '@material-tailwind/react'; +import { Modal, ModalProps } from './Modal'; +import { Button } from './Button'; -type ConfirmDialogProp = { +type ConfirmDialogProp = ModalProps & { children: React.ReactNode; dialogTitle: string; open: boolean; @@ -23,42 +17,24 @@ type ConfirmDialogProp = { const ConfirmDialog = ({ children, dialogTitle, - open, handleOpen, confirmButtonTitle, handleConfirm, - color, + ...props }: ConfirmDialogProp) => { return ( - - - - {dialogTitle}{' '} - - - - {children} - - - - - + + + {dialogTitle} + {children} + + + + + + ); }; From 300b8e4b5e2e132013d1fd54fa2028c622f97577 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Fri, 8 Mar 2024 15:30:53 +0700 Subject: [PATCH 05/22] =?UTF-8?q?=F0=9F=93=9D=20docs:=20add=20modal=20to?= =?UTF-8?q?=20the=20example=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/pages/components/index.tsx | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/frontend/src/pages/components/index.tsx b/packages/frontend/src/pages/components/index.tsx index feee4595..85e5631e 100644 --- a/packages/frontend/src/pages/components/index.tsx +++ b/packages/frontend/src/pages/components/index.tsx @@ -35,6 +35,8 @@ import { import { renderDefaultTag, renderMinimalTag } from './renders/tag'; import { renderToast, renderToastsWithCta } from './renders/toast'; import { renderTooltips } from './renders/tooltip'; +import { Button } from 'components/shared/Button'; +import { Modal } from 'components/shared/Modal'; const Page: React.FC = () => { const [singleDate, setSingleDate] = useState(); @@ -43,6 +45,7 @@ const Page: React.FC = () => { useState('Test 1'); const [switchValue, setSwitchValue] = useState(false); const [selectedRadio, setSelectedRadio] = useState(''); + const [openModal, setOpenModal] = useState(false); return (
@@ -57,6 +60,31 @@ const Page: React.FC = () => {
+ {/* Modal */} +
+
+

Modal

+
+ + + + + + Modal title + +

Modal content

+
+ + + +
+
+
+
+
+ +
+ {/* Steps */}
From 56e9be59ad976ffee955f69c00c84e9048cf20e3 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Fri, 8 Mar 2024 15:32:11 +0700 Subject: [PATCH 06/22] =?UTF-8?q?=F0=9F=90=9B=20fix:=20missing=20props?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projects/ProjectSearchBar/ProjectSearchBarDialog.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/frontend/src/components/projects/ProjectSearchBar/ProjectSearchBarDialog.tsx b/packages/frontend/src/components/projects/ProjectSearchBar/ProjectSearchBarDialog.tsx index e49b44d0..0f5e1172 100644 --- a/packages/frontend/src/components/projects/ProjectSearchBar/ProjectSearchBarDialog.tsx +++ b/packages/frontend/src/components/projects/ProjectSearchBar/ProjectSearchBarDialog.tsx @@ -12,6 +12,7 @@ import { useNavigate } from 'react-router-dom'; import { useCombobox } from 'downshift'; interface ProjectSearchBarDialogProps extends Dialog.DialogProps { + open?: boolean; onClose?: () => void; onClickItem?: (data: Project) => void; } From 102c86161729557f59b0c35d91f6a6ac703e7168 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:49:13 +0700 Subject: [PATCH 07/22] =?UTF-8?q?=F0=9F=8E=A8=20style:=20adjust=20modal=20?= =?UTF-8?q?theme=20and=20add=20wavy=20border=20on=20the=20header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/shared/Modal/Modal.theme.ts | 54 ++++++++++--------- .../shared/Modal/ModalHeader/ModalHeader.tsx | 54 ++++++++++--------- 2 files changed, 59 insertions(+), 49 deletions(-) diff --git a/packages/frontend/src/components/shared/Modal/Modal.theme.ts b/packages/frontend/src/components/shared/Modal/Modal.theme.ts index 81dec838..4552ff70 100644 --- a/packages/frontend/src/components/shared/Modal/Modal.theme.ts +++ b/packages/frontend/src/components/shared/Modal/Modal.theme.ts @@ -7,30 +7,40 @@ export const modalTheme = tv({ 'z-modal', 'fixed', 'inset-0', - 'bg-bg-base/90', + 'bg-black/80', 'backdrop-blur-sm', 'overflow-y-auto', 'flex', 'justify-center', - 'items-center', - 'p-6', + 'items-end', + 'sm:items-center', + 'p-0', 'sm:p-10', 'data-[state=closed]:animate-[dialog-overlay-hide_200ms]', 'data-[state=open]:animate-[dialog-overlay-show_200ms]', 'data-[state=closed]:hidden', // Fix overlay not close when modal is closed ], - close: [ - 'absolute', - 'right-6', - 'top-5', - 'sm:right-10', - 'sm:top-[38px]', - 'z-[1]', + close: ['absolute', 'right-4', 'top-2', 'sm:right-6', 'sm:top-3', 'z-[1]'], + header: [ + 'flex', + 'flex-col', + 'gap-4', + 'items-start', + 'px-4', + 'py-4', + 'sm:px-6', + 'sm:py-5', + 'bg-base-bg-alternate', ], - header: ['flex', 'flex-col', 'gap-2', 'items-start', 'px-6', 'sm:px-10'], - headerTitle: ['text-lg', 'sm:text-xl', 'text-text-em-high'], - headerDescription: ['text-sm', 'text-text-em-low'], - footer: ['flex', 'justify-end', 'gap-3', 'sm:gap-4', 'px-6', 'sm:px-10'], + headerTitle: [ + 'text-base', + 'sm:text-lg', + 'tracking-[0.011em]', + 'sm:tracking-normal', + 'text-elements-high-em', + ], + headerDescription: ['text-sm', 'text-elements-low-em'], + footer: ['flex', 'gap-3', 'px-4', 'pb-4', 'pt-7', 'sm:pb-6', 'sm:px-6'], content: [ 'h-fit', 'sm:min-h-0', @@ -38,19 +48,15 @@ export const modalTheme = tv({ 'relative', 'flex', 'flex-col', - 'gap-y-8', - 'py-6', - 'sm:py-10', 'overflow-hidden', 'w-full', - 'max-w-[560px]', - 'rounded-xl', - 'bg-surface-base', - 'border', - 'border-border-base', - 'text-text-em-high', + 'sm:max-w-[562px]', + 'rounded-2xl', + 'bg-base-bg', + 'shadow-card', + 'text-elements-high-em', ], - body: ['flex-1', 'px-6', 'sm:px-10'], + body: ['flex-1', 'px-4', 'pt-4', 'sm:pt-6', 'sm:px-6'], }, variants: { fullPage: { diff --git a/packages/frontend/src/components/shared/Modal/ModalHeader/ModalHeader.tsx b/packages/frontend/src/components/shared/Modal/ModalHeader/ModalHeader.tsx index ca588db9..c0783847 100644 --- a/packages/frontend/src/components/shared/Modal/ModalHeader/ModalHeader.tsx +++ b/packages/frontend/src/components/shared/Modal/ModalHeader/ModalHeader.tsx @@ -4,6 +4,7 @@ import { Description, Title } from '@radix-ui/react-dialog'; import type { ComponentPropsWithoutRef, PropsWithChildren } from 'react'; import { Heading } from 'components/shared/Heading'; import { modalTheme } from 'components/shared/Modal/Modal.theme'; +import { WavyBorder } from 'components/shared/WavyBorder'; type ModalHeaderProps = ComponentPropsWithoutRef<'div'> & { className?: string; @@ -23,30 +24,33 @@ export const ModalHeader = ({ const { header, headerDescription, headerTitle } = modalTheme(); return ( -
- - <Heading - {...headingProps} - className={headerTitle({ className: headingProps?.className })} - > - {children} - </Heading> - - {description && ( - - {description} - - )} -
+ <> +
+ + <Heading + {...headingProps} + className={headerTitle({ className: headingProps?.className })} + > + {children} + </Heading> + + {description && ( + + {description} + + )} +
+ + ); }; From 3674750011bbc3927fb6d0dcd631189b047613c8 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:49:45 +0700 Subject: [PATCH 08/22] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20update=20con?= =?UTF-8?q?firm=20dialog=20to=20use=20new=20modal=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/shared/ConfirmDialog.tsx | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/packages/frontend/src/components/shared/ConfirmDialog.tsx b/packages/frontend/src/components/shared/ConfirmDialog.tsx index 9a943d54..e7374ad5 100644 --- a/packages/frontend/src/components/shared/ConfirmDialog.tsx +++ b/packages/frontend/src/components/shared/ConfirmDialog.tsx @@ -1,37 +1,49 @@ -import React from 'react'; - -import { color } from '@material-tailwind/react/types/components/button'; +import React, { ReactNode } from 'react'; import { Modal, ModalProps } from './Modal'; -import { Button } from './Button'; +import { Button, ButtonOrLinkProps } from './Button'; -type ConfirmDialogProp = ModalProps & { - children: React.ReactNode; - dialogTitle: string; +export type ConfirmDialogProps = ModalProps & { + children?: ReactNode; + dialogTitle?: string; open: boolean; - handleOpen: () => void; - confirmButtonTitle: string; + handleCancel: () => void; + confirmButtonTitle?: string; handleConfirm?: () => void; - color: color; + cancelButtonProps?: ButtonOrLinkProps; + confirmButtonProps?: ButtonOrLinkProps; }; const ConfirmDialog = ({ children, dialogTitle, - handleOpen, + handleCancel, confirmButtonTitle, handleConfirm, + cancelButtonProps, + confirmButtonProps, ...props -}: ConfirmDialogProp) => { +}: ConfirmDialogProps) => { + // Close the dialog when the user clicks outside of it + const handleOpenChange = (open: boolean) => { + if (!open) return handleCancel?.(); + }; + return ( - + {dialogTitle} {children} - - - + From d50a318e16db40bcb6bd785947dd02127cc88689 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:50:11 +0700 Subject: [PATCH 09/22] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20create=20che?= =?UTF-8?q?vron=20doublw=20down=20icon=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomIcon/ChevronDoubleDownIcon.tsx | 20 +++++++++++++++++++ .../src/components/shared/CustomIcon/index.ts | 1 + 2 files changed, 21 insertions(+) create mode 100644 packages/frontend/src/components/shared/CustomIcon/ChevronDoubleDownIcon.tsx diff --git a/packages/frontend/src/components/shared/CustomIcon/ChevronDoubleDownIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/ChevronDoubleDownIcon.tsx new file mode 100644 index 00000000..64993ac6 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/ChevronDoubleDownIcon.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const ChevronDoubleDownIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/index.ts b/packages/frontend/src/components/shared/CustomIcon/index.ts index 29e38448..4d77a8b9 100644 --- a/packages/frontend/src/components/shared/CustomIcon/index.ts +++ b/packages/frontend/src/components/shared/CustomIcon/index.ts @@ -61,6 +61,7 @@ export * from './CirclePlaceholderOnIcon'; export * from './WarningTriangleIcon'; export * from './CheckRadioOutlineIcon'; export * from './TrendingIcon'; +export * from './ChevronDoubleDownIcon'; // Templates export * from './templates'; From c2417a9daa84473ead1bf372a45854fd73c7df27 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:52:07 +0700 Subject: [PATCH 10/22] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20export=20the?= =?UTF-8?q?=20tag=20props?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/shared/Tag/Tag.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/shared/Tag/Tag.tsx b/packages/frontend/src/components/shared/Tag/Tag.tsx index 8be34c85..08fb665e 100644 --- a/packages/frontend/src/components/shared/Tag/Tag.tsx +++ b/packages/frontend/src/components/shared/Tag/Tag.tsx @@ -6,7 +6,7 @@ import React, { import { tagTheme, type TagTheme } from './Tag.theme'; import { cloneIcon } from 'utils/cloneIcon'; -type TagProps = ComponentPropsWithoutRef<'div'> & +export type TagProps = ComponentPropsWithoutRef<'div'> & TagTheme & { /** * The optional left icon element for a component. From f3ce0d062111cf5f2daaeac32f61a0013acf349c Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:52:55 +0700 Subject: [PATCH 11/22] =?UTF-8?q?=F0=9F=8E=A8=20style:=20adjust=20deployme?= =?UTF-8?q?nt=20body=20card=20design=20to=20match=20with=20the=20figma?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deployments/DeploymentDialogBodyCard.tsx | 81 +++++++++++++------ 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/packages/frontend/src/components/projects/project/deployments/DeploymentDialogBodyCard.tsx b/packages/frontend/src/components/projects/project/deployments/DeploymentDialogBodyCard.tsx index a8b40b8b..64b6956d 100644 --- a/packages/frontend/src/components/projects/project/deployments/DeploymentDialogBodyCard.tsx +++ b/packages/frontend/src/components/projects/project/deployments/DeploymentDialogBodyCard.tsx @@ -1,17 +1,23 @@ import React from 'react'; import { Deployment } from 'gql-client'; -import { Typography, Chip, Card } from '@material-tailwind/react'; -import { color } from '@material-tailwind/react/types/components/chip'; -import { relativeTimeMs } from '../../../../utils/time'; +import { relativeTimeMs } from 'utils/time'; import { SHORT_COMMIT_HASH_LENGTH } from '../../../../constants'; -import { formatAddress } from '../../../../utils/format'; +import { + BranchStrokeIcon, + ClockOutlineIcon, + CommitIcon, +} from 'components/shared/CustomIcon'; +import { Avatar } from 'components/shared/Avatar'; +import { getInitials } from 'utils/geInitials'; +import { OverflownText } from 'components/shared/OverflownText'; +import { Tag, TagProps } from 'components/shared/Tag'; interface DeploymentDialogBodyCardProps { deployment: Deployment; chip?: { value: string; - color?: color; + type?: TagProps['type']; }; } @@ -19,31 +25,54 @@ const DeploymentDialogBodyCard = ({ chip, deployment, }: DeploymentDialogBodyCardProps) => { + const commit = + deployment.commitHash.substring(0, SHORT_COMMIT_HASH_LENGTH) + + ' ' + + deployment.commitMessage; + return ( - +
{chip && ( - + + {chip.value} + )} - {deployment.url && ( - +
+ {/* Title */} +

{deployment.url} - - )} - - ^ {deployment.branch} ^{' '} - {deployment.commitHash.substring(0, SHORT_COMMIT_HASH_LENGTH)}{' '} - {deployment.commitMessage} - - - ^ {relativeTimeMs(deployment.createdAt)} ^{' '} - {formatAddress(deployment.createdBy.name ?? '')} - - +

+ {/* Branch & commit */} +
+
+ +

{deployment.branch}

+
+
+ +

+ {commit} +

+
+
+
+
+ +

+ {relativeTimeMs(deployment.createdAt)} +

+ +

+ {deployment.createdBy.name ?? 'Unknown'} +

+
+
); }; From 97289d85a3da163a62144a07062c0a06ab10d081 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:53:48 +0700 Subject: [PATCH 12/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20create?= =?UTF-8?q?=20cancel=20deployment=20dialog=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dialog/CancelDeploymentDialog.tsx | 30 +++++++++++++++++++ .../src/components/projects/create/Deploy.tsx | 20 ++++--------- 2 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 packages/frontend/src/components/projects/Dialog/CancelDeploymentDialog.tsx diff --git a/packages/frontend/src/components/projects/Dialog/CancelDeploymentDialog.tsx b/packages/frontend/src/components/projects/Dialog/CancelDeploymentDialog.tsx new file mode 100644 index 00000000..f238788d --- /dev/null +++ b/packages/frontend/src/components/projects/Dialog/CancelDeploymentDialog.tsx @@ -0,0 +1,30 @@ +import ConfirmDialog, { + ConfirmDialogProps, +} from 'components/shared/ConfirmDialog'; +import React from 'react'; + +interface CancelDeploymentDialogProps extends ConfirmDialogProps {} + +export const CancelDeploymentDialog = ({ + open, + handleCancel, + handleConfirm, + ...props +}: CancelDeploymentDialogProps) => { + return ( + +

+ This will halt the deployment and you'll have to start the process + from scratch. +

+
+ ); +}; diff --git a/packages/frontend/src/components/projects/create/Deploy.tsx b/packages/frontend/src/components/projects/create/Deploy.tsx index a251773d..f443d5ed 100644 --- a/packages/frontend/src/components/projects/create/Deploy.tsx +++ b/packages/frontend/src/components/projects/create/Deploy.tsx @@ -1,14 +1,12 @@ import React, { useCallback, useEffect } from 'react'; import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; -import { Typography } from '@material-tailwind/react'; - import { DeployStep, DeployStatus } from './DeployStep'; -import { Stopwatch, setStopWatchOffset } from '../../StopWatch'; -import ConfirmDialog from 'components/shared/ConfirmDialog'; +import { Stopwatch, setStopWatchOffset } from 'components/StopWatch'; import { Heading } from 'components/shared/Heading'; import { Button } from 'components/shared/Button'; import { ClockOutlineIcon, WarningIcon } from 'components/shared/CustomIcon'; +import { CancelDeploymentDialog } from 'components/projects/Dialog/CancelDeploymentDialog'; const TIMEOUT_DURATION = 5000; const Deploy = () => { @@ -55,19 +53,11 @@ const Deploy = () => { > Cancel - - - This will halt the deployment and you will have to start the process - from scratch. - - + />
From 28740ffbee5d520ea3da4a3e512778ca808fa684 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:54:30 +0700 Subject: [PATCH 13/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20create?= =?UTF-8?q?=20change=20state=20to=20production=20dialog=20reusable=20compo?= =?UTF-8?q?nent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dialog/ChangeStateToProductionDialog.tsx | 90 ++++++++++++++++ .../project/deployments/DeploymentMenu.tsx | 102 ++++-------------- 2 files changed, 109 insertions(+), 83 deletions(-) create mode 100644 packages/frontend/src/components/projects/Dialog/ChangeStateToProductionDialog.tsx diff --git a/packages/frontend/src/components/projects/Dialog/ChangeStateToProductionDialog.tsx b/packages/frontend/src/components/projects/Dialog/ChangeStateToProductionDialog.tsx new file mode 100644 index 00000000..cf7f1ef1 --- /dev/null +++ b/packages/frontend/src/components/projects/Dialog/ChangeStateToProductionDialog.tsx @@ -0,0 +1,90 @@ +import ConfirmDialog, { + ConfirmDialogProps, +} from 'components/shared/ConfirmDialog'; +import { Deployment, Domain } from 'gql-client'; +import React from 'react'; +import DeploymentDialogBodyCard from 'components/projects/project/deployments/DeploymentDialogBodyCard'; +import { Button } from 'components/shared/Button'; +import { + ChevronDoubleDownIcon, + LinkChainIcon, +} from 'components/shared/CustomIcon'; +import { TagProps } from 'components/shared/Tag'; + +interface ChangeStateToProductionDialogProps extends ConfirmDialogProps { + deployment: Deployment; + newDeployment?: Deployment; + domains: Domain[]; +} + +export const ChangeStateToProductionDialog = ({ + deployment, + newDeployment, + domains, + open, + handleCancel, + handleConfirm, + ...props +}: ChangeStateToProductionDialogProps) => { + const currentChip = { + value: 'Live Deployment', + type: 'positive' as TagProps['type'], + }; + const newChip = { + value: 'New Deployment', + type: 'attention' as TagProps['type'], + }; + + return ( + +
+
+

+ Upon confirmation, this deployment will be changed to production. +

+ + {newDeployment && ( + <> +
+ {Array.from({ length: 7 }).map((_, index) => ( + + ))} +
+ + + )} +
+
+

+ The new deployment will be associated with these domains: +

+ {domains.length > 0 && + domains.map((value) => { + return ( + + ); + })} +
+
+
+ ); +}; diff --git a/packages/frontend/src/components/projects/project/deployments/DeploymentMenu.tsx b/packages/frontend/src/components/projects/project/deployments/DeploymentMenu.tsx index f4eb9808..516b468a 100644 --- a/packages/frontend/src/components/projects/project/deployments/DeploymentMenu.tsx +++ b/packages/frontend/src/components/projects/project/deployments/DeploymentMenu.tsx @@ -17,12 +17,10 @@ import { MenuList, } from '@material-tailwind/react'; import { ComponentPropsWithRef } from 'react'; -import ConfirmDialog from '../../../shared/ConfirmDialog'; import AssignDomainDialog from './AssignDomainDialog'; -import DeploymentDialogBodyCard from './DeploymentDialogBodyCard'; -import { Typography } from '@material-tailwind/react'; -import { useGQLClient } from '../../../../context/GQLClientContext'; +import { useGQLClient } from 'context/GQLClientContext'; import { cn } from 'utils/classnames'; +import { ChangeStateToProductionDialog } from 'components/projects/Dialog/ChangeStateToProductionDialog'; interface DeploymentMenuProps extends ComponentPropsWithRef<'div'> { deployment: Deployment; @@ -158,106 +156,44 @@ export const DeploymentMenu = ({
{/* Dialogs */} - setChangeToProduction((preVal) => !preVal)} - open={changeToProduction} confirmButtonTitle="Change" - color="blue" + handleCancel={() => setChangeToProduction((preVal) => !preVal)} + open={changeToProduction} handleConfirm={async () => { await updateDeployment(); setChangeToProduction((preVal) => !preVal); }} - > -
- - Upon confirmation, this deployment will be changed to production. - - - - The new deployment will be associated with these domains: - - {prodBranchDomains.length > 0 && - prodBranchDomains.map((value) => { - return ( - - ^ {value.name} - - ); - })} -
-
- + setRedeployToProduction((preVal) => !preVal)} + handleCancel={() => setRedeployToProduction((preVal) => !preVal)} open={redeployToProduction} confirmButtonTitle="Redeploy" - color="blue" handleConfirm={async () => { await redeployToProd(); setRedeployToProduction((preVal) => !preVal); }} - > -
- - Upon confirmation, new deployment will be created with the same - source code as current deployment. - - - - These domains will point to your new deployment: - - {deployment.domain?.name && ( - - {deployment.domain?.name} - - )} -
-
+ deployment={deployment} + domains={deployment.domain ? [deployment.domain] : []} + /> {Boolean(currentDeployment) && ( - setRollbackDeployment((preVal) => !preVal)} + handleCancel={() => setRollbackDeployment((preVal) => !preVal)} open={rollbackDeployment} confirmButtonTitle="Rollback" - color="blue" handleConfirm={async () => { await rollbackDeploymentHandler(); setRollbackDeployment((preVal) => !preVal); }} - > -
- - Upon confirmation, this deployment will replace your current - deployment - - - - - These domains will point to your new deployment: - - - ^ {currentDeployment.domain?.name} - -
-
+ deployment={currentDeployment} + newDeployment={deployment} + domains={currentDeployment.domain ? [currentDeployment.domain] : []} + /> )} Date: Thu, 14 Mar 2024 21:55:02 +0700 Subject: [PATCH 14/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20create?= =?UTF-8?q?=20delete=20domain=20dialog=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projects/Dialog/DeleteDomainDialog.tsx | 42 +++++++++++++++++++ .../projects/project/settings/DomainCard.tsx | 26 ++++-------- 2 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 packages/frontend/src/components/projects/Dialog/DeleteDomainDialog.tsx diff --git a/packages/frontend/src/components/projects/Dialog/DeleteDomainDialog.tsx b/packages/frontend/src/components/projects/Dialog/DeleteDomainDialog.tsx new file mode 100644 index 00000000..5d6d3e07 --- /dev/null +++ b/packages/frontend/src/components/projects/Dialog/DeleteDomainDialog.tsx @@ -0,0 +1,42 @@ +import ConfirmDialog, { + ConfirmDialogProps, +} from 'components/shared/ConfirmDialog'; +import React from 'react'; + +interface DeleteDomainDialogProps extends ConfirmDialogProps { + projectName: string; + domainName: string; +} + +export const DeleteDomainDialog = ({ + projectName, + domainName, + open, + handleCancel, + handleConfirm, + ...props +}: DeleteDomainDialogProps) => { + return ( + +

+ Once deleted, the project{' '} + + {projectName} + {' '} + will not be accessible from the domain{' '} + + {domainName} + + . +

+
+ ); +}; diff --git a/packages/frontend/src/components/projects/project/settings/DomainCard.tsx b/packages/frontend/src/components/projects/project/settings/DomainCard.tsx index c5f657eb..e8a7c81c 100644 --- a/packages/frontend/src/components/projects/project/settings/DomainCard.tsx +++ b/packages/frontend/src/components/projects/project/settings/DomainCard.tsx @@ -12,9 +12,9 @@ import { Card, } from '@material-tailwind/react'; -import ConfirmDialog from '../../../shared/ConfirmDialog'; import EditDomainDialog from './EditDomainDialog'; -import { useGQLClient } from '../../../../context/GQLClientContext'; +import { useGQLClient } from 'context/GQLClientContext'; +import { DeleteDomainDialog } from 'components/projects/Dialog/DeleteDomainDialog'; enum RefreshStatus { IDLE, @@ -118,28 +118,16 @@ const DomainCard = ({
- setDeleteDialogOpen((preVal) => !preVal)} + setDeleteDialogOpen((preVal) => !preVal)} open={deleteDialogOpen} - confirmButtonTitle="Yes, Delete domain" handleConfirm={() => { deleteDomain(); setDeleteDialogOpen((preVal) => !preVal); }} - color="red" - > - - Once deleted, the project{' '} - - {project.name} - {' '} - will not be accessible from the domain{' '} - - {domain.name}. - - - + projectName={project.name} + domainName={domain.name} + />
From c1696fbf480a1e5bf10b067f8bf36ef38485abba Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:55:30 +0700 Subject: [PATCH 15/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20create?= =?UTF-8?q?=20delete=20variable=20dialog=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projects/Dialog/DeleteVariableDialog.tsx | 36 +++++++++++++++++++ .../settings/EditEnvironmentVariableRow.tsx | 20 ++++------- 2 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 packages/frontend/src/components/projects/Dialog/DeleteVariableDialog.tsx diff --git a/packages/frontend/src/components/projects/Dialog/DeleteVariableDialog.tsx b/packages/frontend/src/components/projects/Dialog/DeleteVariableDialog.tsx new file mode 100644 index 00000000..227fa34a --- /dev/null +++ b/packages/frontend/src/components/projects/Dialog/DeleteVariableDialog.tsx @@ -0,0 +1,36 @@ +import ConfirmDialog, { + ConfirmDialogProps, +} from 'components/shared/ConfirmDialog'; +import React from 'react'; + +interface DeleteVariableDialogProps extends ConfirmDialogProps { + variableKey: string; +} + +export const DeleteVariableDialog = ({ + variableKey, + open, + handleCancel, + handleConfirm, + ...props +}: DeleteVariableDialogProps) => { + return ( + +

+ Are you sure you want to delete the variable{' '} + + {variableKey} + + ? +

+
+ ); +}; diff --git a/packages/frontend/src/components/projects/project/settings/EditEnvironmentVariableRow.tsx b/packages/frontend/src/components/projects/project/settings/EditEnvironmentVariableRow.tsx index c15c142e..0e382986 100644 --- a/packages/frontend/src/components/projects/project/settings/EditEnvironmentVariableRow.tsx +++ b/packages/frontend/src/components/projects/project/settings/EditEnvironmentVariableRow.tsx @@ -5,8 +5,8 @@ import { EnvironmentVariable } from 'gql-client'; import { IconButton, Input, Typography } from '@material-tailwind/react'; -import ConfirmDialog from '../../../shared/ConfirmDialog'; -import { useGQLClient } from '../../../../context/GQLClientContext'; +import { useGQLClient } from 'context/GQLClientContext'; +import { DeleteVariableDialog } from 'components/projects/Dialog/DeleteVariableDialog'; const ShowPasswordIcon = ({ handler, @@ -161,20 +161,12 @@ const EditEnvironmentVariableRow = ({ )}
- - setDeleteDialogOpen((preVal) => !preVal)} + setDeleteDialogOpen((preVal) => !preVal)} open={deleteDialogOpen} - confirmButtonTitle="Yes, Confirm delete" handleConfirm={removeEnvironmentVariableHandler} - color="red" - > - - Are you sure you want to delete the variable  - {variable.key}? - - + variableKey={variable.key} + /> ); }; From f5807c1126271fc5f84819384fb549b6b91e446e Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:56:00 +0700 Subject: [PATCH 16/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20create?= =?UTF-8?q?=20delete=20webhook=20dialog=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projects/Dialog/DeleteWebhookDialog.tsx | 36 +++++++++++++++++++ .../projects/project/settings/WebhookCard.tsx | 21 ++++------- 2 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 packages/frontend/src/components/projects/Dialog/DeleteWebhookDialog.tsx diff --git a/packages/frontend/src/components/projects/Dialog/DeleteWebhookDialog.tsx b/packages/frontend/src/components/projects/Dialog/DeleteWebhookDialog.tsx new file mode 100644 index 00000000..c2c82c16 --- /dev/null +++ b/packages/frontend/src/components/projects/Dialog/DeleteWebhookDialog.tsx @@ -0,0 +1,36 @@ +import ConfirmDialog, { + ConfirmDialogProps, +} from 'components/shared/ConfirmDialog'; +import React from 'react'; + +interface DeleteWebhookDialogProps extends ConfirmDialogProps { + webhookUrl: string; +} + +export const DeleteWebhookDialog = ({ + webhookUrl, + open, + handleCancel, + handleConfirm, + ...props +}: DeleteWebhookDialogProps) => { + return ( + +

+ Are you sure you want to delete{' '} + + {webhookUrl} + + ? +

+
+ ); +}; diff --git a/packages/frontend/src/components/projects/project/settings/WebhookCard.tsx b/packages/frontend/src/components/projects/project/settings/WebhookCard.tsx index 0d03e46e..80aaf4f1 100644 --- a/packages/frontend/src/components/projects/project/settings/WebhookCard.tsx +++ b/packages/frontend/src/components/projects/project/settings/WebhookCard.tsx @@ -1,9 +1,9 @@ import React, { useState } from 'react'; import toast from 'react-hot-toast'; -import { Button, Typography } from '@material-tailwind/react'; +import { Button } from '@material-tailwind/react'; -import ConfirmDialog from '../../../shared/ConfirmDialog'; +import { DeleteWebhookDialog } from 'components/projects/Dialog/DeleteWebhookDialog'; interface WebhookCardProps { webhookUrl: string; @@ -15,7 +15,6 @@ const WebhookCard = ({ webhookUrl, onDelete }: WebhookCardProps) => { return (
{webhookUrl} -
- - setDeleteDialogOpen((preVal) => !preVal)} + setDeleteDialogOpen((preVal) => !preVal)} open={deleteDialogOpen} - confirmButtonTitle="Yes, Confirm delete" handleConfirm={() => { setDeleteDialogOpen((preVal) => !preVal); onDelete(); }} - color="red" - > - - Are you sure you want to delete the variable{' '} - {webhookUrl}? - - + webhookUrl={webhookUrl} + />
); }; From 4c936b1eb7c377c2dfc69c6fe1cbe196c47bd5b2 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:56:29 +0700 Subject: [PATCH 17/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20create?= =?UTF-8?q?=20remove=20member=20dialog=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projects/Dialog/RemoveMemberDialog.tsx | 38 +++++++++++++++++++ .../projects/project/settings/MemberCard.tsx | 23 ++++------- 2 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 packages/frontend/src/components/projects/Dialog/RemoveMemberDialog.tsx diff --git a/packages/frontend/src/components/projects/Dialog/RemoveMemberDialog.tsx b/packages/frontend/src/components/projects/Dialog/RemoveMemberDialog.tsx new file mode 100644 index 00000000..6695ff8b --- /dev/null +++ b/packages/frontend/src/components/projects/Dialog/RemoveMemberDialog.tsx @@ -0,0 +1,38 @@ +import ConfirmDialog, { + ConfirmDialogProps, +} from 'components/shared/ConfirmDialog'; +import React from 'react'; +import { formatAddress } from 'utils/format'; + +interface RemoveMemberDialogProps extends ConfirmDialogProps { + memberName: string; + ethAddress: string; + emailDomain: string; +} + +export const RemoveMemberDialog = ({ + memberName, + ethAddress, + emailDomain, + open, + handleCancel, + handleConfirm, + ...props +}: RemoveMemberDialogProps) => { + return ( + +

+ Once removed, {formatAddress(memberName)} ({formatAddress(ethAddress)}@ + {emailDomain}) will not be able to access this project. +

+
+ ); +}; diff --git a/packages/frontend/src/components/projects/project/settings/MemberCard.tsx b/packages/frontend/src/components/projects/project/settings/MemberCard.tsx index 715d8bf4..8dd8fd16 100644 --- a/packages/frontend/src/components/projects/project/settings/MemberCard.tsx +++ b/packages/frontend/src/components/projects/project/settings/MemberCard.tsx @@ -3,15 +3,14 @@ import { Permission, User } from 'gql-client'; import { Select, - Typography, Option, Chip, IconButton, Tooltip, } from '@material-tailwind/react'; -import ConfirmDialog from '../../../shared/ConfirmDialog'; -import { formatAddress } from '../../../../utils/format'; +import { formatAddress } from 'utils/format'; +import { RemoveMemberDialog } from 'components/projects/Dialog/RemoveMemberDialog'; const PERMISSION_OPTIONS = [ { @@ -141,25 +140,19 @@ const MemberCard = ({
)} - setRemoveMemberDialogOpen((preVal) => !preVal)} + setRemoveMemberDialogOpen((preVal) => !preVal)} open={removeMemberDialogOpen} - confirmButtonTitle="Yes, Remove member" handleConfirm={() => { setRemoveMemberDialogOpen((preVal) => !preVal); if (onRemoveProjectMember) { onRemoveProjectMember(); } }} - color="red" - > - - Once removed, {formatAddress(member.name ?? '')} ( - {formatAddress(ethAddress)}@{emailDomain}) will not be able to access - this project. - - + memberName={member.name ?? ''} + ethAddress={ethAddress} + emailDomain={emailDomain} + /> ); }; From e4fdae332956104190c52989d014fce09b6d9d4e Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:57:00 +0700 Subject: [PATCH 18/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20create?= =?UTF-8?q?=20disconnect=20repository=20dialog=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dialog/DisconnectRepositoryDialog.tsx | 30 +++++++++++++++++++ .../project/settings/RepoConnectedSection.tsx | 18 ++++------- 2 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 packages/frontend/src/components/projects/Dialog/DisconnectRepositoryDialog.tsx diff --git a/packages/frontend/src/components/projects/Dialog/DisconnectRepositoryDialog.tsx b/packages/frontend/src/components/projects/Dialog/DisconnectRepositoryDialog.tsx new file mode 100644 index 00000000..52ac52f8 --- /dev/null +++ b/packages/frontend/src/components/projects/Dialog/DisconnectRepositoryDialog.tsx @@ -0,0 +1,30 @@ +import ConfirmDialog, { + ConfirmDialogProps, +} from 'components/shared/ConfirmDialog'; +import React from 'react'; + +interface DisconnectRepositoryDialogProps extends ConfirmDialogProps {} + +export const DisconnectRepositoryDialog = ({ + open, + handleCancel, + handleConfirm, + ...props +}: DisconnectRepositoryDialogProps) => { + return ( + +

+ Any data tied to your Git project may become misconfigured. Are you sure + you want to continue? +

+
+ ); +}; diff --git a/packages/frontend/src/components/projects/project/settings/RepoConnectedSection.tsx b/packages/frontend/src/components/projects/project/settings/RepoConnectedSection.tsx index 594062fe..f0a35e97 100644 --- a/packages/frontend/src/components/projects/project/settings/RepoConnectedSection.tsx +++ b/packages/frontend/src/components/projects/project/settings/RepoConnectedSection.tsx @@ -2,8 +2,8 @@ import React, { useState } from 'react'; import { Button, Typography } from '@material-tailwind/react'; -import { GitRepositoryDetails } from '../../../../types'; -import ConfirmDialog from '../../../shared/ConfirmDialog'; +import { GitRepositoryDetails } from 'types'; +import { DisconnectRepositoryDialog } from 'components/projects/Dialog/DisconnectRepositoryDialog'; const RepoConnectedSection = ({ linkedRepo, @@ -34,21 +34,13 @@ const RepoConnectedSection = ({ ^ Disconnect - setDisconnectRepoDialogOpen((preVal) => !preVal)} + setDisconnectRepoDialogOpen((preVal) => !preVal)} open={disconnectRepoDialogOpen} - confirmButtonTitle="Yes, confirm disconnect" handleConfirm={() => { setDisconnectRepoDialogOpen((preVal) => !preVal); }} - color="red" - > - - Any data tied to your Git project may become misconfigured. Are you - sure you want to continue? - - + /> ); }; From 9b3ac4654fa560adbf71d572389e3545a39bc38e Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:57:26 +0700 Subject: [PATCH 19/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20create?= =?UTF-8?q?=20transfer=20project=20dialog=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projects/Dialog/TransferProjectDialog.tsx | 47 +++++++++++++++++++ .../org-slug/projects/id/settings/General.tsx | 27 +++++------ 2 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 packages/frontend/src/components/projects/Dialog/TransferProjectDialog.tsx diff --git a/packages/frontend/src/components/projects/Dialog/TransferProjectDialog.tsx b/packages/frontend/src/components/projects/Dialog/TransferProjectDialog.tsx new file mode 100644 index 00000000..7d26ab93 --- /dev/null +++ b/packages/frontend/src/components/projects/Dialog/TransferProjectDialog.tsx @@ -0,0 +1,47 @@ +import ConfirmDialog, { + ConfirmDialogProps, +} from 'components/shared/ConfirmDialog'; +import React from 'react'; + +interface TransferProjectDialogProps extends ConfirmDialogProps { + projectName: string; + from: string; + to: string; +} + +export const TransferProjectDialog = ({ + projectName, + from, + to, + open, + handleCancel, + handleConfirm, + ...props +}: TransferProjectDialogProps) => { + return ( + +

+ Upon confirmation, your project{' '} + + {projectName} + {' '} + will be transferred from{' '} + + {from} + {' '} + to{' '} + + {to} + + . +

+
+ ); +}; diff --git a/packages/frontend/src/pages/org-slug/projects/id/settings/General.tsx b/packages/frontend/src/pages/org-slug/projects/id/settings/General.tsx index 22d42089..8c1d0bd7 100644 --- a/packages/frontend/src/pages/org-slug/projects/id/settings/General.tsx +++ b/packages/frontend/src/pages/org-slug/projects/id/settings/General.tsx @@ -6,11 +6,11 @@ import { Organization } from 'gql-client'; import { Button, Typography, Input, Option } from '@material-tailwind/react'; -import DeleteProjectDialog from '../../../../../components/projects/project/settings/DeleteProjectDialog'; -import ConfirmDialog from '../../../../../components/shared/ConfirmDialog'; -import { useGQLClient } from '../../../../../context/GQLClientContext'; -import AsyncSelect from '../../../../../components/shared/AsyncSelect'; -import { OutletContextType } from '../../../../../types'; +import DeleteProjectDialog from 'components/projects/project/settings/DeleteProjectDialog'; +import { useGQLClient } from 'context/GQLClientContext'; +import AsyncSelect from 'components/shared/AsyncSelect'; +import { OutletContextType } from 'types'; +import { TransferProjectDialog } from 'components/projects/Dialog/TransferProjectDialog'; const CopyIcon = ({ value }: { value: string }) => { return ( @@ -230,19 +230,14 @@ const GeneralTabPanel = () => { Transfer - setOpenTransferDialog(!openTransferDialog)} + setOpenTransferDialog(!openTransferDialog)} open={openTransferDialog} - confirmButtonTitle="Yes, Confirm transfer" handleConfirm={handleTransferProject} - color="blue" - > - - Upon confirmation, your project {project.name} will be transferred - from {project.organization.name} to {selectedUserOrgName}. - - + projectName={project.name} + from={project.organization.name} + to={selectedUserOrgName} + />
From 8834de893ecdb7ad745a3fa87c6768424f3b78e3 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 21:58:04 +0700 Subject: [PATCH 20/22] =?UTF-8?q?=F0=9F=93=9D=20docs:=20put=20all=20the=20?= =?UTF-8?q?new=20dialog=20into=20component=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/pages/components/index.tsx | 233 +++++++++++++++++- 1 file changed, 228 insertions(+), 5 deletions(-) diff --git a/packages/frontend/src/pages/components/index.tsx b/packages/frontend/src/pages/components/index.tsx index 85e5631e..2d4fe399 100644 --- a/packages/frontend/src/pages/components/index.tsx +++ b/packages/frontend/src/pages/components/index.tsx @@ -37,6 +37,74 @@ import { renderToast, renderToastsWithCta } from './renders/toast'; import { renderTooltips } from './renders/tooltip'; import { Button } from 'components/shared/Button'; import { Modal } from 'components/shared/Modal'; +import { TransferProjectDialog } from 'components/projects/Dialog/TransferProjectDialog'; +import { DeleteWebhookDialog } from 'components/projects/Dialog/DeleteWebhookDialog'; +import { DisconnectRepositoryDialog } from 'components/projects/Dialog/DisconnectRepositoryDialog'; +import { RemoveMemberDialog } from 'components/projects/Dialog/RemoveMemberDialog'; +import { DeleteVariableDialog } from 'components/projects/Dialog/DeleteVariableDialog'; +import { DeleteDomainDialog } from 'components/projects/Dialog/DeleteDomainDialog'; +import { CancelDeploymentDialog } from 'components/projects/Dialog/CancelDeploymentDialog'; +import { + Deployment, + DeploymentStatus, + Domain, + DomainStatus, + Environment, +} from 'gql-client'; +import { ChangeStateToProductionDialog } from 'components/projects/Dialog/ChangeStateToProductionDialog'; + +const deployment: Deployment = { + id: '1', + domain: { + id: 'domain1', + branch: 'main', + name: 'example.com', + status: DomainStatus.Live, + redirectTo: null, + createdAt: '1677609600', // 2023-02-25T12:00:00Z + updatedAt: '1677613200', // 2023-02-25T13:00:00Z + }, + branch: 'main', + commitHash: 'a1b2c3d', + commitMessage: + 'lkajsdlakjsdlaijwlkjadlksjdlaisjdlakjswdalijsdlaksdj lakjsdlasjdlaijwdel akjsdlaj sldkjaliwjdeal ksjdla ijsdlaksjd', + url: 'https://deploy1.example.com', + environment: Environment.Production, + isCurrent: true, + status: DeploymentStatus.Ready, + createdBy: { + id: 'user1', + name: 'Alice', + email: 'alice@example.com', + isVerified: true, + createdAt: '1672656000', // 2023-01-01T10:00:00Z + updatedAt: '1672659600', // 2023-01-01T11:00:00Z + gitHubToken: null, + }, + createdAt: '1677676800', // 2023-03-01T12:00:00Z + updatedAt: '1677680400', // 2023-03-01T13:00:00Z +}; + +const domains: Domain[] = [ + { + id: '1', + branch: 'main', + name: 'saugat.com', + status: DomainStatus.Live, + redirectTo: null, + createdAt: '1677676800', // 2023-03-01T12:00:00Z + updatedAt: '1677680400', // 2023-03-01T13:00:00Z + }, + { + id: '2', + branch: 'main', + name: 'www.saugat.com', + status: DomainStatus.Live, + redirectTo: null, + createdAt: '1677676800', // 2023-03-01T12:00:00Z + updatedAt: '1677680400', // 2023-03-01T13:00:00Z + }, +]; const Page: React.FC = () => { const [singleDate, setSingleDate] = useState(); @@ -45,7 +113,20 @@ const Page: React.FC = () => { useState('Test 1'); const [switchValue, setSwitchValue] = useState(false); const [selectedRadio, setSelectedRadio] = useState(''); - const [openModal, setOpenModal] = useState(false); + const [openTransferDialog, setOpenTransferDialog] = useState(false); + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); + const [disconnectRepoDialogOpen, setDisconnectRepoDialogOpen] = + useState(false); + const [removeMemberDialogOpen, setRemoveMemberDialogOpen] = useState(false); + const [deleteVariableDialogOpen, setDeleteVariableDialogOpen] = + useState(false); + const [deleteDomainDialogOpen, setDeleteDomainDialogOpen] = useState(false); + const [cancelDeploymentDialogOpen, setCancelDeploymentDialogOpen] = + useState(false); + const [changeProductionDialogOpen, setChangeProductionDialogOpen] = + useState(false); + const [redeployToProduction, setRedeployToProduction] = useState(false); + const [rollbackDeployment, setRollbackDeployment] = useState(false); return (
@@ -64,10 +145,11 @@ const Page: React.FC = () => {

Modal

-
- +
+ {/* Modal example */} + - + Modal title @@ -75,10 +157,151 @@ const Page: React.FC = () => {

Modal content

- +
+ {/* Transfer project */} + + setOpenTransferDialog(!openTransferDialog)} + open={openTransferDialog} + handleConfirm={() => setOpenTransferDialog(!openTransferDialog)} + projectName="nextjs-boilerplate" + from="ayungavis" + to="Airfoil" + /> + {/* Delete webhook */} + + setDeleteDialogOpen((preVal) => !preVal)} + open={deleteDialogOpen} + handleConfirm={() => setDeleteDialogOpen((preVal) => !preVal)} + webhookUrl="examplehook.com" + /> + {/* Disconnect repository */} + + + setDisconnectRepoDialogOpen((preVal) => !preVal) + } + open={disconnectRepoDialogOpen} + handleConfirm={() => { + setDisconnectRepoDialogOpen((preVal) => !preVal); + }} + /> + {/* Remove member */} + + + setRemoveMemberDialogOpen((preVal) => !preVal) + } + open={removeMemberDialogOpen} + confirmButtonTitle="Yes, Remove member" + handleConfirm={() => + setRemoveMemberDialogOpen((preVal) => !preVal) + } + memberName="John Doe" + ethAddress="0x1234567890" + emailDomain="example.com" + /> + {/* Delete variable */} + + + setDeleteVariableDialogOpen((preVal) => !preVal) + } + open={deleteVariableDialogOpen} + handleConfirm={() => + setDeleteVariableDialogOpen((preVal) => !preVal) + } + variableKey="AIUTH_TOKEN" + /> + {/* Delete domain */} + + + setDeleteDomainDialogOpen((preVal) => !preVal) + } + open={deleteDomainDialogOpen} + handleConfirm={() => + setDeleteDomainDialogOpen((preVal) => !preVal) + } + projectName="Airfoil" + domainName="airfoil.com" + /> + {/* Cancel deployment */} + + + setCancelDeploymentDialogOpen(!cancelDeploymentDialogOpen) + } + open={cancelDeploymentDialogOpen} + handleConfirm={() => + setCancelDeploymentDialogOpen(!cancelDeploymentDialogOpen) + } + /> + {/* Change to production */} + + setChangeProductionDialogOpen(false)} + open={changeProductionDialogOpen} + handleConfirm={() => setChangeProductionDialogOpen(false)} + deployment={deployment} + domains={domains} + /> + {/* Redeploy to production */} + + + setRedeployToProduction((preVal) => !preVal) + } + open={redeployToProduction} + confirmButtonTitle="Redeploy" + handleConfirm={async () => + setRedeployToProduction((preVal) => !preVal) + } + deployment={deployment} + domains={deployment.domain ? [deployment.domain] : []} + /> + {/* Rollback to this deployment */} + + setRollbackDeployment((preVal) => !preVal)} + open={rollbackDeployment} + confirmButtonTitle="Rollback" + handleConfirm={async () => + setRollbackDeployment((preVal) => !preVal) + } + deployment={deployment} + newDeployment={deployment} + domains={deployment.domain ? [deployment.domain] : []} + />
From 193dbb058aa6faddb01893fa3778ed19d1084ca5 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 22:07:05 +0700 Subject: [PATCH 21/22] =?UTF-8?q?=F0=9F=8E=A8=20style:=20adjust=20overflow?= =?UTF-8?q?=20text=20width=20on=20mobile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projects/project/deployments/DeploymentDialogBodyCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/projects/project/deployments/DeploymentDialogBodyCard.tsx b/packages/frontend/src/components/projects/project/deployments/DeploymentDialogBodyCard.tsx index 64b6956d..fd008de6 100644 --- a/packages/frontend/src/components/projects/project/deployments/DeploymentDialogBodyCard.tsx +++ b/packages/frontend/src/components/projects/project/deployments/DeploymentDialogBodyCard.tsx @@ -50,7 +50,7 @@ const DeploymentDialogBodyCard = ({
-

+

{commit}

From 4fcf8e92b7c9b42cb63e73b669b038052139f4b7 Mon Sep 17 00:00:00 2001 From: Wahyu Kurniawan Date: Thu, 14 Mar 2024 22:07:36 +0700 Subject: [PATCH 22/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20create?= =?UTF-8?q?=20another=20example=20page=20for=20modal=20only?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/pages/components/index.tsx | 223 -------------- .../frontend/src/pages/components/modals.tsx | 274 ++++++++++++++++++ 2 files changed, 274 insertions(+), 223 deletions(-) create mode 100644 packages/frontend/src/pages/components/modals.tsx diff --git a/packages/frontend/src/pages/components/index.tsx b/packages/frontend/src/pages/components/index.tsx index 2d4fe399..84e3e188 100644 --- a/packages/frontend/src/pages/components/index.tsx +++ b/packages/frontend/src/pages/components/index.tsx @@ -37,74 +37,6 @@ import { renderToast, renderToastsWithCta } from './renders/toast'; import { renderTooltips } from './renders/tooltip'; import { Button } from 'components/shared/Button'; import { Modal } from 'components/shared/Modal'; -import { TransferProjectDialog } from 'components/projects/Dialog/TransferProjectDialog'; -import { DeleteWebhookDialog } from 'components/projects/Dialog/DeleteWebhookDialog'; -import { DisconnectRepositoryDialog } from 'components/projects/Dialog/DisconnectRepositoryDialog'; -import { RemoveMemberDialog } from 'components/projects/Dialog/RemoveMemberDialog'; -import { DeleteVariableDialog } from 'components/projects/Dialog/DeleteVariableDialog'; -import { DeleteDomainDialog } from 'components/projects/Dialog/DeleteDomainDialog'; -import { CancelDeploymentDialog } from 'components/projects/Dialog/CancelDeploymentDialog'; -import { - Deployment, - DeploymentStatus, - Domain, - DomainStatus, - Environment, -} from 'gql-client'; -import { ChangeStateToProductionDialog } from 'components/projects/Dialog/ChangeStateToProductionDialog'; - -const deployment: Deployment = { - id: '1', - domain: { - id: 'domain1', - branch: 'main', - name: 'example.com', - status: DomainStatus.Live, - redirectTo: null, - createdAt: '1677609600', // 2023-02-25T12:00:00Z - updatedAt: '1677613200', // 2023-02-25T13:00:00Z - }, - branch: 'main', - commitHash: 'a1b2c3d', - commitMessage: - 'lkajsdlakjsdlaijwlkjadlksjdlaisjdlakjswdalijsdlaksdj lakjsdlasjdlaijwdel akjsdlaj sldkjaliwjdeal ksjdla ijsdlaksjd', - url: 'https://deploy1.example.com', - environment: Environment.Production, - isCurrent: true, - status: DeploymentStatus.Ready, - createdBy: { - id: 'user1', - name: 'Alice', - email: 'alice@example.com', - isVerified: true, - createdAt: '1672656000', // 2023-01-01T10:00:00Z - updatedAt: '1672659600', // 2023-01-01T11:00:00Z - gitHubToken: null, - }, - createdAt: '1677676800', // 2023-03-01T12:00:00Z - updatedAt: '1677680400', // 2023-03-01T13:00:00Z -}; - -const domains: Domain[] = [ - { - id: '1', - branch: 'main', - name: 'saugat.com', - status: DomainStatus.Live, - redirectTo: null, - createdAt: '1677676800', // 2023-03-01T12:00:00Z - updatedAt: '1677680400', // 2023-03-01T13:00:00Z - }, - { - id: '2', - branch: 'main', - name: 'www.saugat.com', - status: DomainStatus.Live, - redirectTo: null, - createdAt: '1677676800', // 2023-03-01T12:00:00Z - updatedAt: '1677680400', // 2023-03-01T13:00:00Z - }, -]; const Page: React.FC = () => { const [singleDate, setSingleDate] = useState(); @@ -113,20 +45,6 @@ const Page: React.FC = () => { useState('Test 1'); const [switchValue, setSwitchValue] = useState(false); const [selectedRadio, setSelectedRadio] = useState(''); - const [openTransferDialog, setOpenTransferDialog] = useState(false); - const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); - const [disconnectRepoDialogOpen, setDisconnectRepoDialogOpen] = - useState(false); - const [removeMemberDialogOpen, setRemoveMemberDialogOpen] = useState(false); - const [deleteVariableDialogOpen, setDeleteVariableDialogOpen] = - useState(false); - const [deleteDomainDialogOpen, setDeleteDomainDialogOpen] = useState(false); - const [cancelDeploymentDialogOpen, setCancelDeploymentDialogOpen] = - useState(false); - const [changeProductionDialogOpen, setChangeProductionDialogOpen] = - useState(false); - const [redeployToProduction, setRedeployToProduction] = useState(false); - const [rollbackDeployment, setRollbackDeployment] = useState(false); return (
@@ -161,147 +79,6 @@ const Page: React.FC = () => { - {/* Transfer project */} - - setOpenTransferDialog(!openTransferDialog)} - open={openTransferDialog} - handleConfirm={() => setOpenTransferDialog(!openTransferDialog)} - projectName="nextjs-boilerplate" - from="ayungavis" - to="Airfoil" - /> - {/* Delete webhook */} - - setDeleteDialogOpen((preVal) => !preVal)} - open={deleteDialogOpen} - handleConfirm={() => setDeleteDialogOpen((preVal) => !preVal)} - webhookUrl="examplehook.com" - /> - {/* Disconnect repository */} - - - setDisconnectRepoDialogOpen((preVal) => !preVal) - } - open={disconnectRepoDialogOpen} - handleConfirm={() => { - setDisconnectRepoDialogOpen((preVal) => !preVal); - }} - /> - {/* Remove member */} - - - setRemoveMemberDialogOpen((preVal) => !preVal) - } - open={removeMemberDialogOpen} - confirmButtonTitle="Yes, Remove member" - handleConfirm={() => - setRemoveMemberDialogOpen((preVal) => !preVal) - } - memberName="John Doe" - ethAddress="0x1234567890" - emailDomain="example.com" - /> - {/* Delete variable */} - - - setDeleteVariableDialogOpen((preVal) => !preVal) - } - open={deleteVariableDialogOpen} - handleConfirm={() => - setDeleteVariableDialogOpen((preVal) => !preVal) - } - variableKey="AIUTH_TOKEN" - /> - {/* Delete domain */} - - - setDeleteDomainDialogOpen((preVal) => !preVal) - } - open={deleteDomainDialogOpen} - handleConfirm={() => - setDeleteDomainDialogOpen((preVal) => !preVal) - } - projectName="Airfoil" - domainName="airfoil.com" - /> - {/* Cancel deployment */} - - - setCancelDeploymentDialogOpen(!cancelDeploymentDialogOpen) - } - open={cancelDeploymentDialogOpen} - handleConfirm={() => - setCancelDeploymentDialogOpen(!cancelDeploymentDialogOpen) - } - /> - {/* Change to production */} - - setChangeProductionDialogOpen(false)} - open={changeProductionDialogOpen} - handleConfirm={() => setChangeProductionDialogOpen(false)} - deployment={deployment} - domains={domains} - /> - {/* Redeploy to production */} - - - setRedeployToProduction((preVal) => !preVal) - } - open={redeployToProduction} - confirmButtonTitle="Redeploy" - handleConfirm={async () => - setRedeployToProduction((preVal) => !preVal) - } - deployment={deployment} - domains={deployment.domain ? [deployment.domain] : []} - /> - {/* Rollback to this deployment */} - - setRollbackDeployment((preVal) => !preVal)} - open={rollbackDeployment} - confirmButtonTitle="Rollback" - handleConfirm={async () => - setRollbackDeployment((preVal) => !preVal) - } - deployment={deployment} - newDeployment={deployment} - domains={deployment.domain ? [deployment.domain] : []} - />
diff --git a/packages/frontend/src/pages/components/modals.tsx b/packages/frontend/src/pages/components/modals.tsx new file mode 100644 index 00000000..63d34e2a --- /dev/null +++ b/packages/frontend/src/pages/components/modals.tsx @@ -0,0 +1,274 @@ +import React from 'react'; + +import { useState } from 'react'; + +import { Button } from 'components/shared/Button'; +import { Modal } from 'components/shared/Modal'; +import { TransferProjectDialog } from 'components/projects/Dialog/TransferProjectDialog'; +import { DeleteWebhookDialog } from 'components/projects/Dialog/DeleteWebhookDialog'; +import { DisconnectRepositoryDialog } from 'components/projects/Dialog/DisconnectRepositoryDialog'; +import { RemoveMemberDialog } from 'components/projects/Dialog/RemoveMemberDialog'; +import { DeleteVariableDialog } from 'components/projects/Dialog/DeleteVariableDialog'; +import { DeleteDomainDialog } from 'components/projects/Dialog/DeleteDomainDialog'; +import { CancelDeploymentDialog } from 'components/projects/Dialog/CancelDeploymentDialog'; +import { + Deployment, + DeploymentStatus, + Domain, + DomainStatus, + Environment, +} from 'gql-client'; +import { ChangeStateToProductionDialog } from 'components/projects/Dialog/ChangeStateToProductionDialog'; + +const deployment: Deployment = { + id: '1', + domain: { + id: 'domain1', + branch: 'main', + name: 'example.com', + status: DomainStatus.Live, + redirectTo: null, + createdAt: '1677609600', // 2023-02-25T12:00:00Z + updatedAt: '1677613200', // 2023-02-25T13:00:00Z + }, + branch: 'main', + commitHash: 'a1b2c3d', + commitMessage: + 'lkajsdlakjsdlaijwlkjadlksjdlaisjdlakjswdalijsdlaksdj lakjsdlasjdlaijwdel akjsdlaj sldkjaliwjdeal ksjdla ijsdlaksjd', + url: 'https://deploy1.example.com', + environment: Environment.Production, + isCurrent: true, + status: DeploymentStatus.Ready, + createdBy: { + id: 'user1', + name: 'Alice', + email: 'alice@example.com', + isVerified: true, + createdAt: '1672656000', // 2023-01-01T10:00:00Z + updatedAt: '1672659600', // 2023-01-01T11:00:00Z + gitHubToken: null, + }, + createdAt: '1677676800', // 2023-03-01T12:00:00Z + updatedAt: '1677680400', // 2023-03-01T13:00:00Z +}; + +const domains: Domain[] = [ + { + id: '1', + branch: 'main', + name: 'saugat.com', + status: DomainStatus.Live, + redirectTo: null, + createdAt: '1677676800', // 2023-03-01T12:00:00Z + updatedAt: '1677680400', // 2023-03-01T13:00:00Z + }, + { + id: '2', + branch: 'main', + name: 'www.saugat.com', + status: DomainStatus.Live, + redirectTo: null, + createdAt: '1677676800', // 2023-03-01T12:00:00Z + updatedAt: '1677680400', // 2023-03-01T13:00:00Z + }, +]; + +const ModalsPage: React.FC = () => { + const [openTransferDialog, setOpenTransferDialog] = useState(false); + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); + const [disconnectRepoDialogOpen, setDisconnectRepoDialogOpen] = + useState(false); + const [removeMemberDialogOpen, setRemoveMemberDialogOpen] = useState(false); + const [deleteVariableDialogOpen, setDeleteVariableDialogOpen] = + useState(false); + const [deleteDomainDialogOpen, setDeleteDomainDialogOpen] = useState(false); + const [cancelDeploymentDialogOpen, setCancelDeploymentDialogOpen] = + useState(false); + const [changeProductionDialogOpen, setChangeProductionDialogOpen] = + useState(false); + const [redeployToProduction, setRedeployToProduction] = useState(false); + const [rollbackDeployment, setRollbackDeployment] = useState(false); + + return ( +
+
+

Manual Storybook

+

+ Get started by editing{' '} + + packages/frontend/src/pages/components/index.tsx + +

+ +
+ + {/* Modal */} +
+
+

Modal

+
+ {/* Modal example */} + + + + + + Modal title + +

Modal content

+
+ + + +
+
+ {/* Transfer project */} + + setOpenTransferDialog(!openTransferDialog)} + open={openTransferDialog} + handleConfirm={() => setOpenTransferDialog(!openTransferDialog)} + projectName="nextjs-boilerplate" + from="ayungavis" + to="Airfoil" + /> + {/* Delete webhook */} + + setDeleteDialogOpen((preVal) => !preVal)} + open={deleteDialogOpen} + handleConfirm={() => setDeleteDialogOpen((preVal) => !preVal)} + webhookUrl="examplehook.com" + /> + {/* Disconnect repository */} + + + setDisconnectRepoDialogOpen((preVal) => !preVal) + } + open={disconnectRepoDialogOpen} + handleConfirm={() => { + setDisconnectRepoDialogOpen((preVal) => !preVal); + }} + /> + {/* Remove member */} + + + setRemoveMemberDialogOpen((preVal) => !preVal) + } + open={removeMemberDialogOpen} + confirmButtonTitle="Yes, Remove member" + handleConfirm={() => + setRemoveMemberDialogOpen((preVal) => !preVal) + } + memberName="John Doe" + ethAddress="0x1234567890" + emailDomain="example.com" + /> + {/* Delete variable */} + + + setDeleteVariableDialogOpen((preVal) => !preVal) + } + open={deleteVariableDialogOpen} + handleConfirm={() => + setDeleteVariableDialogOpen((preVal) => !preVal) + } + variableKey="AIUTH_TOKEN" + /> + {/* Delete domain */} + + + setDeleteDomainDialogOpen((preVal) => !preVal) + } + open={deleteDomainDialogOpen} + handleConfirm={() => + setDeleteDomainDialogOpen((preVal) => !preVal) + } + projectName="Airfoil" + domainName="airfoil.com" + /> + {/* Cancel deployment */} + + + setCancelDeploymentDialogOpen(!cancelDeploymentDialogOpen) + } + open={cancelDeploymentDialogOpen} + handleConfirm={() => + setCancelDeploymentDialogOpen(!cancelDeploymentDialogOpen) + } + /> + {/* Change to production */} + + setChangeProductionDialogOpen(false)} + open={changeProductionDialogOpen} + handleConfirm={() => setChangeProductionDialogOpen(false)} + deployment={deployment} + domains={domains} + /> + {/* Redeploy to production */} + + + setRedeployToProduction((preVal) => !preVal) + } + open={redeployToProduction} + confirmButtonTitle="Redeploy" + handleConfirm={async () => + setRedeployToProduction((preVal) => !preVal) + } + deployment={deployment} + domains={deployment.domain ? [deployment.domain] : []} + /> + {/* Rollback to this deployment */} + + setRollbackDeployment((preVal) => !preVal)} + open={rollbackDeployment} + confirmButtonTitle="Rollback" + handleConfirm={async () => + setRollbackDeployment((preVal) => !preVal) + } + deployment={deployment} + newDeployment={deployment} + domains={deployment.domain ? [deployment.domain] : []} + /> +
+
+
+
+
+ ); +}; + +export default ModalsPage;