index.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import { dialogCloseHandler } from "@ente/shared/components/DialogBox/TitleWithCloseButton";
  2. import EnteButton from "@ente/shared/components/EnteButton";
  3. import {
  4. Box,
  5. Button,
  6. Dialog,
  7. Stack,
  8. Typography,
  9. type DialogProps,
  10. } from "@mui/material";
  11. import { t } from "i18next";
  12. import React, { useState } from "react";
  13. import type { DialogBoxAttributesV2 } from "./types";
  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. >
  51. <Stack spacing={"36px"} p={"16px"}>
  52. <Stack spacing={"19px"}>
  53. {attributes.icon && (
  54. <Box
  55. sx={{
  56. "& > svg": {
  57. fontSize: "32px",
  58. },
  59. }}
  60. >
  61. {attributes.icon}
  62. </Box>
  63. )}
  64. {attributes.title && (
  65. <Typography variant="large" fontWeight={"bold"}>
  66. {attributes.title}
  67. </Typography>
  68. )}
  69. {children ||
  70. (attributes?.content && (
  71. <Typography color="text.muted">
  72. {attributes.content}
  73. </Typography>
  74. ))}
  75. </Stack>
  76. {(attributes.proceed ||
  77. attributes.close ||
  78. attributes.buttons?.length) && (
  79. <Stack
  80. spacing={"8px"}
  81. direction={
  82. attributes.buttonDirection === "row"
  83. ? "row-reverse"
  84. : "column"
  85. }
  86. flex={1}
  87. >
  88. {attributes.proceed && (
  89. <EnteButton
  90. loading={loading}
  91. size="large"
  92. color={attributes.proceed?.variant}
  93. onClick={async () => {
  94. await attributes.proceed?.action(
  95. setLoading,
  96. );
  97. onClose();
  98. }}
  99. disabled={attributes.proceed.disabled}
  100. >
  101. {attributes.proceed.text}
  102. </EnteButton>
  103. )}
  104. {attributes.close && (
  105. <Button
  106. size="large"
  107. color={attributes.close?.variant ?? "secondary"}
  108. onClick={() => {
  109. attributes.close?.action &&
  110. attributes.close?.action();
  111. onClose();
  112. }}
  113. >
  114. {attributes.close?.text ?? t("OK")}
  115. </Button>
  116. )}
  117. {attributes.buttons &&
  118. attributes.buttons.map((b) => (
  119. <Button
  120. size="large"
  121. key={b.text}
  122. color={b.variant}
  123. onClick={() => {
  124. b.action();
  125. onClose();
  126. }}
  127. disabled={b.disabled}
  128. >
  129. {b.text}
  130. </Button>
  131. ))}
  132. </Stack>
  133. )}
  134. </Stack>
  135. </Dialog>
  136. );
  137. }