index.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import React, { useState } from 'react';
  2. import {
  3. Box,
  4. Button,
  5. Dialog,
  6. DialogProps,
  7. Stack,
  8. Typography,
  9. } from '@mui/material';
  10. import { t } from 'i18next';
  11. import { dialogCloseHandler } from '@ente/shared/components/DialogBox/TitleWithCloseButton';
  12. import { DialogBoxAttributesV2 } from './types';
  13. import EnteButton from '@ente/shared/components/EnteButton';
  14. type IProps = React.PropsWithChildren<
  15. Omit<DialogProps, 'onClose'> & {
  16. onClose: () => void;
  17. attributes: DialogBoxAttributesV2;
  18. }
  19. >;
  20. export default function DialogBoxV2({
  21. attributes,
  22. children,
  23. open,
  24. onClose,
  25. ...props
  26. }: IProps) {
  27. const [loading, setLoading] = useState(false);
  28. if (!attributes) {
  29. return <></>;
  30. }
  31. const handleClose = dialogCloseHandler({
  32. staticBackdrop: attributes.staticBackdrop,
  33. nonClosable: attributes.nonClosable,
  34. onClose: onClose,
  35. });
  36. const { PaperProps, ...rest } = props;
  37. return (
  38. <Dialog
  39. open={open}
  40. onClose={handleClose}
  41. PaperProps={{
  42. ...PaperProps,
  43. sx: {
  44. padding: '8px 12px',
  45. maxWidth: '360px',
  46. ...PaperProps?.sx,
  47. },
  48. }}
  49. {...rest}>
  50. <Stack spacing={'36px'} p={'16px'}>
  51. <Stack spacing={'19px'}>
  52. {attributes.icon && (
  53. <Box
  54. sx={{
  55. '& > svg': {
  56. fontSize: '32px',
  57. },
  58. }}>
  59. {attributes.icon}
  60. </Box>
  61. )}
  62. {attributes.title && (
  63. <Typography variant="large" fontWeight={'bold'}>
  64. {attributes.title}
  65. </Typography>
  66. )}
  67. {children ||
  68. (attributes?.content && (
  69. <Typography color="text.muted">
  70. {attributes.content}
  71. </Typography>
  72. ))}
  73. </Stack>
  74. {(attributes.proceed ||
  75. attributes.close ||
  76. attributes.buttons?.length) && (
  77. <Stack
  78. spacing={'8px'}
  79. direction={
  80. attributes.buttonDirection === 'row'
  81. ? 'row-reverse'
  82. : 'column'
  83. }
  84. flex={1}>
  85. {attributes.proceed && (
  86. <EnteButton
  87. loading={loading}
  88. size="large"
  89. color={attributes.proceed?.variant}
  90. onClick={async () => {
  91. await attributes.proceed.action(setLoading);
  92. onClose();
  93. }}
  94. disabled={attributes.proceed.disabled}>
  95. {attributes.proceed.text}
  96. </EnteButton>
  97. )}
  98. {attributes.close && (
  99. <Button
  100. size="large"
  101. color={attributes.close?.variant ?? 'secondary'}
  102. onClick={() => {
  103. attributes.close.action &&
  104. attributes.close?.action();
  105. onClose();
  106. }}>
  107. {attributes.close?.text ?? t('OK')}
  108. </Button>
  109. )}
  110. {attributes.buttons &&
  111. attributes.buttons.map((b) => (
  112. <Button
  113. size="large"
  114. key={b.text}
  115. color={b.variant}
  116. onClick={() => {
  117. b.action();
  118. onClose();
  119. }}
  120. disabled={b.disabled}>
  121. {b.text}
  122. </Button>
  123. ))}
  124. </Stack>
  125. )}
  126. </Stack>
  127. </Dialog>
  128. );
  129. }