mautourco-components 0.2.34 → 0.2.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/components/molecules/DialogContentPolicy/DialogCancellationAccom.js +1 -1
  2. package/dist/components/organisms/DialogBookingAddItem/AddItemNewService.js +6 -1
  3. package/dist/components/organisms/DialogDeleteConfirm/DialogDeleteConfirm.d.ts +9 -8
  4. package/dist/components/organisms/DialogDeleteConfirm/DialogDeleteConfirm.js +12 -7
  5. package/dist/components/organisms/DialogDeleteConfirm/DialogDeleteConfirmMultiple/DialogDeleteConfirmMultiple.css +2103 -0
  6. package/dist/components/organisms/DialogDeleteConfirm/DialogDeleteConfirmMultiple/DialogDeleteConfirmMultiple.d.ts +12 -0
  7. package/dist/components/organisms/DialogDeleteConfirm/DialogDeleteConfirmMultiple/DialogDeleteConfirmMultiple.js +44 -0
  8. package/dist/components/organisms/DialogDeleteConfirm/DialogDeleteConfirmWrapper.d.ts +10 -0
  9. package/dist/components/organisms/DialogDeleteConfirm/DialogDeleteConfirmWrapper.js +6 -0
  10. package/dist/components/organisms/DialogDeleteConfirm/index.d.ts +3 -0
  11. package/dist/components/organisms/DialogDeleteConfirm/index.js +1 -0
  12. package/dist/components/organisms/DialogSendingMail/DialogSendingMailMultiple/DialogSendingMailMultiple.d.ts +30 -1
  13. package/dist/components/organisms/DialogSendingMail/DialogSendingMailMultiple/DialogSendingMailMultiple.js +32 -6
  14. package/dist/components/organisms/DialogSendingMail/index.d.ts +1 -0
  15. package/dist/components/organisms/QuoteHeader/QuoteHeader.d.ts +1 -2
  16. package/dist/components/organisms/QuoteHeader/QuoteHeader.js +2 -2
  17. package/dist/index.d.ts +3 -0
  18. package/dist/index.js +2 -0
  19. package/package.json +1 -1
  20. package/src/components/molecules/DialogContentPolicy/DialogCancellationAccom.tsx +2 -2
  21. package/src/components/organisms/DialogBookingAddItem/AddItemNewService.tsx +7 -1
  22. package/src/components/organisms/DialogDeleteConfirm/DialogDeleteConfirm.tsx +19 -37
  23. package/src/components/organisms/DialogDeleteConfirm/DialogDeleteConfirmMultiple/DialogDeleteConfirmMultiple.css +20 -0
  24. package/src/components/organisms/DialogDeleteConfirm/DialogDeleteConfirmMultiple/DialogDeleteConfirmMultiple.tsx +84 -0
  25. package/src/components/organisms/DialogDeleteConfirm/DialogDeleteConfirmWrapper.tsx +34 -0
  26. package/src/components/organisms/DialogDeleteConfirm/index.ts +4 -0
  27. package/src/components/organisms/DialogSendingMail/DialogSendingMailMultiple/DialogSendingMailMultiple.tsx +45 -6
  28. package/src/components/organisms/DialogSendingMail/index.ts +1 -0
  29. package/src/components/organisms/QuoteHeader/QuoteHeader.tsx +2 -3
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import './DialogDeleteConfirmMultiple.css';
3
+ export interface AvailableQuote {
4
+ id: string;
5
+ name: string;
6
+ }
7
+ export interface DialogDeleteConfirmMultipleProps {
8
+ onCancel?: () => void;
9
+ onDelete?: (selectedQuotes: string[]) => void;
10
+ quotes: AvailableQuote[];
11
+ }
12
+ export declare const DialogDeleteConfirmMultiple: React.FC<DialogDeleteConfirmMultipleProps>;
@@ -0,0 +1,44 @@
1
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
2
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
3
+ if (ar || !(i in from)) {
4
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5
+ ar[i] = from[i];
6
+ }
7
+ }
8
+ return to.concat(ar || Array.prototype.slice.call(from));
9
+ };
10
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
+ import Toast from '../../../molecules/Toast/index';
12
+ import { useEffect, useState } from 'react';
13
+ import Checkbox from '../../../atoms/Checkbox/Checkbox';
14
+ import { DialogDeleteConfirm } from '../DialogDeleteConfirm';
15
+ import './DialogDeleteConfirmMultiple.css';
16
+ export var DialogDeleteConfirmMultiple = function (props) {
17
+ var quotes = props.quotes, onCancel = props.onCancel, onDelete = props.onDelete;
18
+ var _a = useState([]), selectedQuotes = _a[0], setSelectedQuotes = _a[1];
19
+ var _b = useState(false), isSelectAll = _b[0], setIsSelectAll = _b[1];
20
+ var handleSelectQuote = function (quote) {
21
+ setSelectedQuotes(function (prev) {
22
+ if (prev.includes(quote.id)) {
23
+ return prev.filter(function (id) { return id !== quote.id; });
24
+ }
25
+ return __spreadArray(__spreadArray([], prev, true), [quote.id], false);
26
+ });
27
+ };
28
+ var handleSelectAllQuotes = function () {
29
+ setIsSelectAll(!isSelectAll);
30
+ if (isSelectAll) {
31
+ setSelectedQuotes([]);
32
+ }
33
+ else {
34
+ setSelectedQuotes(quotes.map(function (quote) { return quote.id; }));
35
+ }
36
+ };
37
+ var handleDeleteQuotes = function () {
38
+ onDelete === null || onDelete === void 0 ? void 0 : onDelete(selectedQuotes);
39
+ };
40
+ useEffect(function () {
41
+ setIsSelectAll(selectedQuotes.length === quotes.length);
42
+ }, [selectedQuotes, quotes]);
43
+ return (_jsx(DialogDeleteConfirm.Wrapper, { onCancel: onCancel, onOk: handleDeleteQuotes, children: _jsxs("div", { className: "confirm-multiple", children: [_jsx(Checkbox, { label: "Select all quotations", checked: isSelectAll, onChange: handleSelectAllQuotes, labelPosition: "leading", className: "confirm-multiple__all" }), _jsx("ul", { className: "mb-1", children: quotes.map(function (quote) { return (_jsx("li", { children: _jsx(Checkbox, { label: quote.name, checked: selectedQuotes.includes(quote.id), onChange: function () { return handleSelectQuote(quote); }, labelPosition: "leading" }) }, quote.id)); }) }), isSelectAll && (_jsx(Toast, { text: "Caution: This would delete all quotations created.", type: "warning", showIcon: false }))] }) }));
44
+ };
@@ -0,0 +1,10 @@
1
+ import { ButtonProps } from '../../atoms/Button/Button';
2
+ export interface DialogDeleteConfirmWrapperProps {
3
+ onCancel?: () => void;
4
+ cancelText?: string;
5
+ okVariant?: ButtonProps['variant'];
6
+ onOk?: () => void;
7
+ okText?: string;
8
+ children: React.ReactNode;
9
+ }
10
+ export declare const DialogDeleteConfirmWrapper: (props: DialogDeleteConfirmWrapperProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Button from '../../atoms/Button/Button';
3
+ export var DialogDeleteConfirmWrapper = function (props) {
4
+ var onCancel = props.onCancel, _a = props.cancelText, cancelText = _a === void 0 ? 'Cancel' : _a, _b = props.okVariant, okVariant = _b === void 0 ? 'destructive' : _b, onOk = props.onOk, _c = props.okText, okText = _c === void 0 ? 'Delete' : _c, children = props.children;
5
+ return (_jsxs("div", { className: "space-y-9", children: [children, _jsxs("div", { className: "grid grid-cols-2 gap-x-4", children: [_jsx(Button, { variant: "outline-secondary", onClick: onCancel, size: "sm", children: cancelText }), _jsx(Button, { variant: okVariant, onClick: onOk, size: "sm", children: okText })] })] }));
6
+ };
@@ -0,0 +1,3 @@
1
+ export * from './DialogDeleteConfirm';
2
+ export type { DialogDeleteConfirmMultipleProps } from './DialogDeleteConfirmMultiple/DialogDeleteConfirmMultiple';
3
+ export type { DialogDeleteConfirmWrapperProps } from './DialogDeleteConfirmWrapper';
@@ -0,0 +1 @@
1
+ export * from './DialogDeleteConfirm';
@@ -6,12 +6,41 @@ export interface SelectedQuote {
6
6
  id: string;
7
7
  name: string;
8
8
  }
9
- export interface DialogSendingMailMultipleProps extends Omit<DialogSendingMailContentProps, 'onSubmit'> {
9
+ export interface DialogSendingMailMultipleProps extends Omit<DialogSendingMailContentProps, 'onSubmit' | 'onPreviewAttachment'> {
10
+ /** Default data of the quotes */
10
11
  data: SelectedQuote[];
12
+ /** Function to call when a quote is selected */
11
13
  onSelected?: (selectedQuotes: SelectedQuote[]) => void;
14
+ /** Function to call when the form is submitted */
12
15
  onSubmit: (payload: {
13
16
  selectedQuotes: SelectedQuote[];
14
17
  formData: SendingMailSchema;
15
18
  }) => void;
19
+ /** Function to call when the preview attachment is clicked */
20
+ onPreviewAttachment?: (selectedQuotes: SelectedQuote[]) => void;
16
21
  }
22
+ /**
23
+ * Props for the DialogSendingMailMultiple component
24
+ *
25
+ * @example
26
+ * <DialogSendingMail>
27
+ * <DialogSendingMail.MultipleQuotes
28
+ * data={[
29
+ * { id: '1', name: 'Quote 1' },
30
+ * { id: '2', name: 'Quote 2' },
31
+ * { id: '3', name: 'Quote 3' },
32
+ * ]}
33
+ * onPreviewAttachment={() => {
34
+ * console.log('Preview attachment');
35
+ * }}
36
+ * onSubmit={(data) => {
37
+ * console.log(data);
38
+ * }}
39
+ * onSelected={(selectedQuotes) => {
40
+ * console.log(selectedQuotes);
41
+ * }} />
42
+ * </DialogSendingMail>
43
+ *
44
+ * @param props - The props of the component
45
+ */
17
46
  export declare const DialogSendingMailMultiple: React.FC<DialogSendingMailMultipleProps>;
@@ -32,11 +32,35 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
32
32
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
33
33
  import Checkbox from '../../../atoms/Checkbox/Checkbox';
34
34
  import SelectedValue from '../../../atoms/SelectedValue/SelectedValue';
35
- import { useEffect, useState } from 'react';
35
+ import { useEffect, useMemo, useState } from 'react';
36
36
  import { DialogSendingMailContent, } from '../DialogSendingMailContent';
37
37
  import './DialogSendingMailMultiple.css';
38
+ /**
39
+ * Props for the DialogSendingMailMultiple component
40
+ *
41
+ * @example
42
+ * <DialogSendingMail>
43
+ * <DialogSendingMail.MultipleQuotes
44
+ * data={[
45
+ * { id: '1', name: 'Quote 1' },
46
+ * { id: '2', name: 'Quote 2' },
47
+ * { id: '3', name: 'Quote 3' },
48
+ * ]}
49
+ * onPreviewAttachment={() => {
50
+ * console.log('Preview attachment');
51
+ * }}
52
+ * onSubmit={(data) => {
53
+ * console.log(data);
54
+ * }}
55
+ * onSelected={(selectedQuotes) => {
56
+ * console.log(selectedQuotes);
57
+ * }} />
58
+ * </DialogSendingMail>
59
+ *
60
+ * @param props - The props of the component
61
+ */
38
62
  export var DialogSendingMailMultiple = function (props) {
39
- var data = props.data, onSelected = props.onSelected, onSubmit = props.onSubmit, rest = __rest(props, ["data", "onSelected", "onSubmit"]);
63
+ var data = props.data, onSelected = props.onSelected, onSubmit = props.onSubmit, onPreviewAttachment = props.onPreviewAttachment, rest = __rest(props, ["data", "onSelected", "onSubmit", "onPreviewAttachment"]);
40
64
  var _a = useState(false), isSelectAll = _a[0], setIsSelectAll = _a[1];
41
65
  var _b = useState(data), remainingQuotes = _b[0], setRemainingQuotes = _b[1];
42
66
  var _c = useState([]), selectedQuotes = _c[0], setSelectedQuotes = _c[1];
@@ -92,6 +116,10 @@ export var DialogSendingMailMultiple = function (props) {
92
116
  setSelectedQuotes(remainingQuotes.map(function (quote) { return quote.id; }));
93
117
  }
94
118
  };
119
+ /**
120
+ * Get the remaining quotes filtered by the selected quotes
121
+ */
122
+ var remainingQuotesFiltered = useMemo(function () { return remainingQuotes.filter(function (quote) { return selectedQuotes.includes(quote.id); }); }, [remainingQuotes, selectedQuotes]);
95
123
  useEffect(function () {
96
124
  // Select all quotes by default
97
125
  setSelectedQuotes(data.map(function (quote) { return quote.id; }));
@@ -104,11 +132,9 @@ export var DialogSendingMailMultiple = function (props) {
104
132
  setSelectedQuotes([remainingQuotes[0].id]);
105
133
  }
106
134
  }, [selectedQuotes, remainingQuotes]);
107
- return (_jsxs("div", { children: [_jsxs("div", { className: "selected-quotes", children: [_jsx("div", { className: "selected-quotes__list", children: remainingQuotes.map(function (item) { return (_jsx(SelectedValue, { value: item.name, color: selectedQuotes.includes(item.id) ? 'accent' : 'neutral', onSelect: function () { return handleSelect(item.id); }, onRemove: function () { return handleRemove(item.id); } }, item.id)); }) }), _jsx("div", { children: _jsx(Checkbox, { label: "Select all quotations", checked: isSelectAll || remainingQuotes.length === 1, disabled: remainingQuotes.length === 1, onChange: function () { return handleSelectAll(); }, labelPosition: "leading" }) })] }), _jsx(DialogSendingMailContent, __assign({}, rest, { onSubmit: function (data) {
135
+ return (_jsxs("div", { children: [_jsxs("div", { className: "selected-quotes", children: [_jsx("div", { className: "selected-quotes__list", children: remainingQuotes.map(function (item) { return (_jsx(SelectedValue, { value: item.name, color: selectedQuotes.includes(item.id) ? 'accent' : 'neutral', onSelect: function () { return handleSelect(item.id); }, onRemove: function () { return handleRemove(item.id); } }, item.id)); }) }), _jsx("div", { children: _jsx(Checkbox, { label: "Select all quotations", checked: isSelectAll || remainingQuotes.length === 1, disabled: remainingQuotes.length === 1, onChange: function () { return handleSelectAll(); }, labelPosition: "leading" }) })] }), _jsx(DialogSendingMailContent, __assign({}, rest, { onPreviewAttachment: function () { return onPreviewAttachment === null || onPreviewAttachment === void 0 ? void 0 : onPreviewAttachment(remainingQuotesFiltered); }, onSubmit: function (data) {
108
136
  return onSubmit({
109
- selectedQuotes: remainingQuotes.filter(function (quote) {
110
- return selectedQuotes.includes(quote.id);
111
- }),
137
+ selectedQuotes: remainingQuotesFiltered,
112
138
  formData: data,
113
139
  });
114
140
  } }))] }));
@@ -2,3 +2,4 @@ export * from './DialogSendingMail';
2
2
  export * from './sending-mail-schema';
3
3
  export type { DialogSendingMailProps } from './DialogSendingMail';
4
4
  export type { DialogSendingMailContentProps } from './DialogSendingMailContent';
5
+ export type { DialogSendingMailMultipleProps } from './DialogSendingMailMultiple/DialogSendingMailMultiple';
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import './QuoteHeader.css';
3
2
  export interface QuoteHeaderProps {
4
3
  /** Current tab */
@@ -9,4 +8,4 @@ export interface QuoteHeaderProps {
9
8
  onNewQuote: () => void;
10
9
  onFilterChange: (filter: 'date' | 'clientType' | 'fileStatus', value: string) => void;
11
10
  }
12
- export declare const QuoteHeader: React.FC<QuoteHeaderProps>;
11
+ export declare function QuoteHeader(props: QuoteHeaderProps): import("react/jsx-runtime").JSX.Element;
@@ -19,7 +19,7 @@ var filterConfig = {
19
19
  placeholder: 'File status',
20
20
  },
21
21
  };
22
- export var QuoteHeader = function (props) {
22
+ export function QuoteHeader(props) {
23
23
  var _a = props.current, current = _a === void 0 ? 'quotation' : _a, onNavigate = props.onNavigate, onNewQuote = props.onNewQuote, onFilterChange = props.onFilterChange;
24
24
  return (_jsxs("div", { className: "quote-header", children: [_jsx(Heading, { level: 4, as: "h1", className: "quote-header__title", color: "accent", children: "Quotation & Booking" }), _jsxs("div", { className: "flex gap-4", children: [_jsx(Button, { variant: current === 'quotation' ? 'primary' : 'outline-primary', className: "quote-header__button", onClick: function () { return onNavigate('quotation'); }, children: "Quotation" }), _jsx(Button, { variant: current === 'booking' ? 'primary' : 'outline-primary', className: "quote-header__button", onClick: function () { return onNavigate('booking'); }, children: "Booking" })] }), _jsxs("div", { className: "quote-header__search-container", children: [_jsx(Input, { placeholder: "Search", icon: "search", iconPosition: "leading", className: "quote-header__search" }), _jsx(Button, { variant: "primary", leadingIcon: "plus-circle", iconSize: "md", size: "sm", onClick: onNewQuote, children: "New quote" })] }), _jsx("div", { className: "quote-header__filters", children: Object.entries(filterConfig).map(function (_a) {
25
25
  var key = _a[0], value = _a[1];
@@ -27,4 +27,4 @@ export var QuoteHeader = function (props) {
27
27
  return onFilterChange(key, value);
28
28
  } }, key));
29
29
  }) })] }));
30
- };
30
+ }
package/dist/index.d.ts CHANGED
@@ -54,7 +54,9 @@ export * from './components/organisms/DialogBookingAddItem';
54
54
  export * from './components/organisms/DialogBookingConfirm';
55
55
  export * from './components/organisms/DialogCancelService';
56
56
  export { DialogComparison } from './components/organisms/DialogComparison/DialogComparison';
57
+ export * from './components/organisms/DialogDeleteConfirm';
57
58
  export { DialogDeleteConfirm } from './components/organisms/DialogDeleteConfirm/DialogDeleteConfirm';
59
+ export { DialogQuoteRename } from './components/organisms/DialogQuoteRename/DialogQuoteRename';
58
60
  export * from './components/organisms/DialogSendingMail';
59
61
  export { default as Docket } from './components/organisms/Docket/Docket';
60
62
  export { Footer } from './components/organisms/Footer/Footer';
@@ -115,6 +117,7 @@ export type { ToastProps } from './components/molecules/Toast/Toast';
115
117
  export type { TransferDocketProps } from './components/molecules/TransferDocket/TransferDocket';
116
118
  export type { ComparisonData, DialogComparisonProps, MultiComparisonData, } from './components/organisms/DialogComparison/DialogComparison';
117
119
  export type { DialogDeleteConfirmProps } from './components/organisms/DialogDeleteConfirm/DialogDeleteConfirm';
120
+ export type { DialogQuoteRenameProps } from './components/organisms/DialogQuoteRename/DialogQuoteRename';
118
121
  export type { SelectedQuote } from './components/organisms/DialogSendingMail/DialogSendingMailMultiple/DialogSendingMailMultiple';
119
122
  export type { QuoteHeaderProps } from './components/organisms/QuoteHeader/QuoteHeader';
120
123
  export type { TimelineProps, TimelineServices, } from './components/organisms/Timeline/Timeline';
package/dist/index.js CHANGED
@@ -57,7 +57,9 @@ export * from './components/organisms/DialogBookingAddItem';
57
57
  export * from './components/organisms/DialogBookingConfirm';
58
58
  export * from './components/organisms/DialogCancelService';
59
59
  export { DialogComparison } from './components/organisms/DialogComparison/DialogComparison';
60
+ export * from './components/organisms/DialogDeleteConfirm';
60
61
  export { DialogDeleteConfirm } from './components/organisms/DialogDeleteConfirm/DialogDeleteConfirm';
62
+ export { DialogQuoteRename } from './components/organisms/DialogQuoteRename/DialogQuoteRename';
61
63
  export * from './components/organisms/DialogSendingMail';
62
64
  export { default as Docket } from './components/organisms/Docket/Docket';
63
65
  export { Footer } from './components/organisms/Footer/Footer';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mautourco-components",
3
- "version": "0.2.34",
3
+ "version": "0.2.36",
4
4
  "private": false,
5
5
  "description": "Bibliothèque de composants Motorco pour le redesign",
6
6
  "main": "dist/index.js",
@@ -46,8 +46,8 @@ export const DialogCancellationAccom: React.FC<DialogCancellationAccomProps> = (
46
46
  </TextWithIcon>
47
47
  <Text size="sm">{room.RoomName}</Text>
48
48
  </div>
49
- {room.cancellation_policy.map((policy) => (
50
- <Fragment key={`policy-${index}`}>
49
+ {room.cancellation_policy.map((policy, pIndex) => (
50
+ <Fragment key={`policy-${pIndex}`}>
51
51
  <Chip type="outline" color="brand" isBlackText>
52
52
  Policy period applies{' '}
53
53
  <DateDisplay
@@ -1,4 +1,4 @@
1
- import { useCallback, useState } from 'react';
1
+ import { useCallback, useEffect, useState } from 'react';
2
2
  import Button from '../../atoms/Button/Button';
3
3
  import Checkbox from '../../atoms/Checkbox/Checkbox';
4
4
  import { Text } from '../../atoms/Typography/Typography';
@@ -50,6 +50,12 @@ export const AddItemNewService: React.FC<AddItemNewServiceProps> = (props) => {
50
50
  [selectedClients]
51
51
  );
52
52
 
53
+ useEffect(() => {
54
+ if (!!date) {
55
+ setDates(date);
56
+ }
57
+ }, [date]);
58
+
53
59
  return (
54
60
  <div className="space-y-9">
55
61
  <div className="flex sm:items-center gap-4 flex-col sm:flex-row">
@@ -1,32 +1,27 @@
1
1
  import React from 'react';
2
- import Button, { ButtonProps } from '../../atoms/Button/Button';
3
2
  import { Text } from '../../atoms/Typography/Typography';
4
3
  import { DialogBookingConfirm } from '../DialogBookingConfirm';
4
+ import { DialogDeleteConfirmMultiple } from './DialogDeleteConfirmMultiple/DialogDeleteConfirmMultiple';
5
+ import { DialogDeleteConfirmWrapper } from './DialogDeleteConfirmWrapper';
5
6
 
6
7
  export interface DialogDeleteConfirmProps {
7
8
  open: boolean;
8
9
  setOpen: (open: boolean) => void;
9
- message: string;
10
10
  title: string;
11
- cancelText?: string;
12
- okText?: string;
13
- okVariant?: ButtonProps['variant'];
14
- onOk?: () => void;
15
- onCancel?: () => void;
11
+ children?: React.ReactNode;
16
12
  }
17
13
 
18
- export const DialogDeleteConfirm: React.FC<DialogDeleteConfirmProps> = (props) => {
19
- const {
20
- open,
21
- setOpen,
22
- message,
23
- title,
24
- cancelText = 'Cancel',
25
- okText = 'Delete',
26
- okVariant = 'destructive',
27
- onOk,
28
- onCancel,
29
- } = props;
14
+ const DialogDeleteConfirmText = (props: { children: React.ReactNode }) => {
15
+ const { children } = props;
16
+ return (
17
+ <Text variant="medium" size="sm" leading="4">
18
+ {children}
19
+ </Text>
20
+ );
21
+ };
22
+
23
+ export const DialogDeleteConfirm = (props: DialogDeleteConfirmProps) => {
24
+ const { open, title, children, setOpen } = props;
30
25
  return (
31
26
  <DialogBookingConfirm
32
27
  open={open}
@@ -34,24 +29,11 @@ export const DialogDeleteConfirm: React.FC<DialogDeleteConfirmProps> = (props) =
34
29
  title={title}
35
30
  className="!max-w-[500px]"
36
31
  closeOnOverlayClick>
37
- <div className="space-y-9">
38
- <Text variant="medium" size="sm" leading="4">
39
- <span dangerouslySetInnerHTML={{ __html: message }} />
40
- </Text>
41
- <div className="grid grid-cols-2 gap-x-4">
42
- <Button
43
- variant="outline-secondary"
44
- onClick={() => {
45
- setOpen(false);
46
- onCancel?.();
47
- }}>
48
- {cancelText}
49
- </Button>
50
- <Button variant={okVariant} onClick={onOk}>
51
- {okText}
52
- </Button>
53
- </div>
54
- </div>
32
+ {children}
55
33
  </DialogBookingConfirm>
56
34
  );
57
35
  };
36
+
37
+ DialogDeleteConfirm.Text = DialogDeleteConfirmText;
38
+ DialogDeleteConfirm.Wrapper = DialogDeleteConfirmWrapper;
39
+ DialogDeleteConfirm.Multiple = DialogDeleteConfirmMultiple;
@@ -0,0 +1,20 @@
1
+ .confirm-multiple {
2
+ @apply space-y-5;
3
+ .checkbox-container {
4
+ @apply flex;
5
+ }
6
+ .checkbox-label {
7
+ @apply justify-between;
8
+ }
9
+
10
+ ul label > span {
11
+ font-weight: var(--font-weight-font-medium);
12
+ }
13
+ }
14
+
15
+ .confirm-multiple__all {
16
+ label > span {
17
+ font-size: var(--font-size-text-base);
18
+ font-weight: var(--font-weight-font-bold);
19
+ }
20
+ }
@@ -0,0 +1,84 @@
1
+ import Toast from '@/src/components/molecules/Toast';
2
+ import React, { useEffect, useState } from 'react';
3
+ import Checkbox from '../../../atoms/Checkbox/Checkbox';
4
+ import { DialogDeleteConfirm } from '../DialogDeleteConfirm';
5
+ import './DialogDeleteConfirmMultiple.css';
6
+
7
+ export interface AvailableQuote {
8
+ id: string;
9
+ name: string;
10
+ }
11
+
12
+ export interface DialogDeleteConfirmMultipleProps {
13
+ onCancel?: () => void;
14
+ onDelete?: (selectedQuotes: string[]) => void;
15
+ quotes: AvailableQuote[];
16
+ }
17
+
18
+ export const DialogDeleteConfirmMultiple: React.FC<DialogDeleteConfirmMultipleProps> = (
19
+ props
20
+ ) => {
21
+ const { quotes, onCancel, onDelete } = props;
22
+
23
+ const [selectedQuotes, setSelectedQuotes] = useState<string[]>([]);
24
+ const [isSelectAll, setIsSelectAll] = useState(false);
25
+
26
+ const handleSelectQuote = (quote: AvailableQuote) => {
27
+ setSelectedQuotes((prev) => {
28
+ if (prev.includes(quote.id)) {
29
+ return prev.filter((id) => id !== quote.id);
30
+ }
31
+ return [...prev, quote.id];
32
+ });
33
+ };
34
+
35
+ const handleSelectAllQuotes = () => {
36
+ setIsSelectAll(!isSelectAll);
37
+ if (isSelectAll) {
38
+ setSelectedQuotes([]);
39
+ } else {
40
+ setSelectedQuotes(quotes.map((quote) => quote.id));
41
+ }
42
+ };
43
+
44
+ const handleDeleteQuotes = () => {
45
+ onDelete?.(selectedQuotes);
46
+ };
47
+
48
+ useEffect(() => {
49
+ setIsSelectAll(selectedQuotes.length === quotes.length);
50
+ }, [selectedQuotes, quotes]);
51
+
52
+ return (
53
+ <DialogDeleteConfirm.Wrapper onCancel={onCancel} onOk={handleDeleteQuotes}>
54
+ <div className="confirm-multiple">
55
+ <Checkbox
56
+ label="Select all quotations"
57
+ checked={isSelectAll}
58
+ onChange={handleSelectAllQuotes}
59
+ labelPosition="leading"
60
+ className="confirm-multiple__all"
61
+ />
62
+ <ul className="mb-1">
63
+ {quotes.map((quote) => (
64
+ <li key={quote.id}>
65
+ <Checkbox
66
+ label={quote.name}
67
+ checked={selectedQuotes.includes(quote.id)}
68
+ onChange={() => handleSelectQuote(quote)}
69
+ labelPosition="leading"
70
+ />
71
+ </li>
72
+ ))}
73
+ </ul>
74
+ {isSelectAll && (
75
+ <Toast
76
+ text="Caution: This would delete all quotations created."
77
+ type="warning"
78
+ showIcon={false}
79
+ />
80
+ )}
81
+ </div>
82
+ </DialogDeleteConfirm.Wrapper>
83
+ );
84
+ };
@@ -0,0 +1,34 @@
1
+ import Button, { ButtonProps } from '../../atoms/Button/Button';
2
+
3
+ export interface DialogDeleteConfirmWrapperProps {
4
+ onCancel?: () => void;
5
+ cancelText?: string;
6
+ okVariant?: ButtonProps['variant'];
7
+ onOk?: () => void;
8
+ okText?: string;
9
+ children: React.ReactNode;
10
+ }
11
+
12
+ export const DialogDeleteConfirmWrapper = (props: DialogDeleteConfirmWrapperProps) => {
13
+ const {
14
+ onCancel,
15
+ cancelText = 'Cancel',
16
+ okVariant = 'destructive',
17
+ onOk,
18
+ okText = 'Delete',
19
+ children,
20
+ } = props;
21
+ return (
22
+ <div className="space-y-9">
23
+ {children}
24
+ <div className="grid grid-cols-2 gap-x-4">
25
+ <Button variant="outline-secondary" onClick={onCancel} size="sm">
26
+ {cancelText}
27
+ </Button>
28
+ <Button variant={okVariant} onClick={onOk} size="sm">
29
+ {okText}
30
+ </Button>
31
+ </div>
32
+ </div>
33
+ );
34
+ };
@@ -0,0 +1,4 @@
1
+ export * from './DialogDeleteConfirm';
2
+
3
+ export type { DialogDeleteConfirmMultipleProps } from './DialogDeleteConfirmMultiple/DialogDeleteConfirmMultiple';
4
+ export type { DialogDeleteConfirmWrapperProps } from './DialogDeleteConfirmWrapper';
@@ -1,6 +1,6 @@
1
1
  import Checkbox from '@/src/components/atoms/Checkbox/Checkbox';
2
2
  import SelectedValue from '@/src/components/atoms/SelectedValue/SelectedValue';
3
- import React, { useEffect, useState } from 'react';
3
+ import React, { useEffect, useMemo, useState } from 'react';
4
4
  import {
5
5
  DialogSendingMailContent,
6
6
  DialogSendingMailContentProps,
@@ -15,20 +15,52 @@ export interface SelectedQuote {
15
15
 
16
16
  export interface DialogSendingMailMultipleProps extends Omit<
17
17
  DialogSendingMailContentProps,
18
- 'onSubmit'
18
+ 'onSubmit' | 'onPreviewAttachment'
19
19
  > {
20
+ /** Default data of the quotes */
20
21
  data: SelectedQuote[];
22
+
23
+ /** Function to call when a quote is selected */
21
24
  onSelected?: (selectedQuotes: SelectedQuote[]) => void;
25
+
26
+ /** Function to call when the form is submitted */
22
27
  onSubmit: (payload: {
23
28
  selectedQuotes: SelectedQuote[];
24
29
  formData: SendingMailSchema;
25
30
  }) => void;
31
+
32
+ /** Function to call when the preview attachment is clicked */
33
+ onPreviewAttachment?: (selectedQuotes: SelectedQuote[]) => void;
26
34
  }
27
35
 
36
+ /**
37
+ * Props for the DialogSendingMailMultiple component
38
+ *
39
+ * @example
40
+ * <DialogSendingMail>
41
+ * <DialogSendingMail.MultipleQuotes
42
+ * data={[
43
+ * { id: '1', name: 'Quote 1' },
44
+ * { id: '2', name: 'Quote 2' },
45
+ * { id: '3', name: 'Quote 3' },
46
+ * ]}
47
+ * onPreviewAttachment={() => {
48
+ * console.log('Preview attachment');
49
+ * }}
50
+ * onSubmit={(data) => {
51
+ * console.log(data);
52
+ * }}
53
+ * onSelected={(selectedQuotes) => {
54
+ * console.log(selectedQuotes);
55
+ * }} />
56
+ * </DialogSendingMail>
57
+ *
58
+ * @param props - The props of the component
59
+ */
28
60
  export const DialogSendingMailMultiple: React.FC<DialogSendingMailMultipleProps> = (
29
61
  props
30
62
  ) => {
31
- const { data, onSelected, onSubmit, ...rest } = props;
63
+ const { data, onSelected, onSubmit, onPreviewAttachment, ...rest } = props;
32
64
 
33
65
  const [isSelectAll, setIsSelectAll] = useState(false);
34
66
  const [remainingQuotes, setRemainingQuotes] = useState<SelectedQuote[]>(data);
@@ -88,6 +120,14 @@ export const DialogSendingMailMultiple: React.FC<DialogSendingMailMultipleProps>
88
120
  }
89
121
  };
90
122
 
123
+ /**
124
+ * Get the remaining quotes filtered by the selected quotes
125
+ */
126
+ const remainingQuotesFiltered = useMemo(
127
+ () => remainingQuotes.filter((quote) => selectedQuotes.includes(quote.id)),
128
+ [remainingQuotes, selectedQuotes]
129
+ );
130
+
91
131
  useEffect(() => {
92
132
  // Select all quotes by default
93
133
  setSelectedQuotes(data.map((quote) => quote.id));
@@ -129,11 +169,10 @@ export const DialogSendingMailMultiple: React.FC<DialogSendingMailMultipleProps>
129
169
  </div>
130
170
  <DialogSendingMailContent
131
171
  {...rest}
172
+ onPreviewAttachment={() => onPreviewAttachment?.(remainingQuotesFiltered)}
132
173
  onSubmit={(data) =>
133
174
  onSubmit({
134
- selectedQuotes: remainingQuotes.filter((quote) =>
135
- selectedQuotes.includes(quote.id)
136
- ),
175
+ selectedQuotes: remainingQuotesFiltered,
137
176
  formData: data,
138
177
  })
139
178
  }
@@ -3,3 +3,4 @@ export * from './sending-mail-schema';
3
3
 
4
4
  export type { DialogSendingMailProps } from './DialogSendingMail';
5
5
  export type { DialogSendingMailContentProps } from './DialogSendingMailContent';
6
+ export type { DialogSendingMailMultipleProps } from './DialogSendingMailMultiple/DialogSendingMailMultiple';
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import Button from '../../atoms/Button/Button';
3
2
  import DropdownInput from '../../atoms/Inputs/DropdownInput/DropdownInput';
4
3
  import Input from '../../atoms/Inputs/Input/Input';
@@ -38,7 +37,7 @@ const filterConfig = {
38
37
  },
39
38
  };
40
39
 
41
- export const QuoteHeader: React.FC<QuoteHeaderProps> = (props) => {
40
+ export function QuoteHeader(props: QuoteHeaderProps) {
42
41
  const { current = 'quotation', onNavigate, onNewQuote, onFilterChange } = props;
43
42
 
44
43
  return (
@@ -90,4 +89,4 @@ export const QuoteHeader: React.FC<QuoteHeaderProps> = (props) => {
90
89
  </div>
91
90
  </div>
92
91
  );
93
- };
92
+ }