mautourco-components 0.2.46 → 0.2.48
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.
- package/dist/components/molecules/AgeSelector/AgeSelector.d.ts +20 -0
- package/dist/components/molecules/AgeSelector/AgeSelector.js +84 -0
- package/dist/components/molecules/LocationDropdown/LocationDropdown.js +1 -1
- package/dist/components/molecules/Pagination/Pagination.css +27 -17
- package/dist/components/molecules/Pagination/Pagination.js +4 -4
- package/dist/components/organisms/PaxSelector/PaxSelector.d.ts +5 -0
- package/dist/components/organisms/PaxSelector/PaxSelector.js +100 -114
- package/dist/components/organisms/RoundTrip/RoundTrip.d.ts +2 -0
- package/dist/components/organisms/RoundTrip/RoundTrip.js +7 -7
- package/dist/components/organisms/SearchBarTransfer/SearchBarTransfer.d.ts +4 -0
- package/dist/components/organisms/SearchBarTransfer/SearchBarTransfer.js +19 -57
- package/dist/components/organisms/Table/Table.css +64 -53
- package/dist/components/organisms/Table/Table.d.ts +1 -0
- package/dist/components/organisms/Table/Table.js +2 -1
- package/dist/components/organisms/Table/columns/booking-columns.d.ts +1 -1
- package/dist/components/organisms/Table/columns/booking-columns.js +17 -2
- package/dist/components/organisms/Table/columns/index.d.ts +1 -1
- package/dist/components/organisms/TransferLine/TransferLine.d.ts +9 -5
- package/dist/components/organisms/TransferLine/TransferLine.js +52 -35
- package/dist/index.d.ts +19 -16
- package/dist/index.js +3 -1
- package/dist/styles/components/molecule/age-selector.css +216 -0
- package/dist/styles/components/molecule/calendarInput.css +25 -6
- package/dist/styles/components/molecule/location-dropdown.css +16 -4
- package/dist/styles/components/organism/pax-selector.css +27 -189
- package/dist/styles/components/organism/transfer-line.css +40 -0
- package/dist/styles/mautourco.css +1 -0
- package/package.json +1 -1
- package/src/components/molecules/AgeSelector/AgeSelector.tsx +172 -0
- package/src/components/molecules/LocationDropdown/LocationDropdown.tsx +1 -1
- package/src/components/molecules/Pagination/Pagination.css +27 -18
- package/src/components/molecules/Pagination/Pagination.tsx +9 -13
- package/src/components/organisms/PaxSelector/PaxSelector.tsx +132 -208
- package/src/components/organisms/RoundTrip/RoundTrip.tsx +7 -0
- package/src/components/organisms/SearchBarTransfer/SearchBarTransfer.tsx +34 -54
- package/src/components/organisms/Table/Table.css +64 -53
- package/src/components/organisms/Table/Table.tsx +22 -1
- package/src/components/organisms/Table/columns/booking-columns.tsx +40 -13
- package/src/components/organisms/TransferLine/TransferLine.tsx +107 -85
- package/src/styles/components/molecule/age-selector.css +136 -0
- package/src/styles/components/molecule/calendarInput.css +12 -4
- package/src/styles/components/molecule/location-dropdown.css +9 -2
- package/src/styles/components/organism/pax-selector.css +25 -186
- package/src/styles/components/organism/transfer-line.css +31 -0
|
@@ -40,8 +40,12 @@ export interface SearchBarTransferProps {
|
|
|
40
40
|
onSearch?: (data: SearchBarTransferData) => void;
|
|
41
41
|
/** Callback when data changes */
|
|
42
42
|
onChange?: (data: SearchBarTransferData) => void;
|
|
43
|
+
/** Callback when a transfer line is removed */
|
|
44
|
+
onRemove?: (index: number, transferLine: TransferLineData) => void;
|
|
43
45
|
/** Additional CSS classes */
|
|
44
46
|
className?: string;
|
|
47
|
+
/** Whether to scroll to the input when the calendar opens */
|
|
48
|
+
scrollOnOpen?: boolean;
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
let transferIdCounter = 0;
|
|
@@ -54,7 +58,9 @@ const SearchBarTransfer: React.FC<SearchBarTransferProps> = ({
|
|
|
54
58
|
defaultSameVehicle = false,
|
|
55
59
|
onSearch,
|
|
56
60
|
onChange,
|
|
61
|
+
onRemove,
|
|
57
62
|
className = "",
|
|
63
|
+
scrollOnOpen = false,
|
|
58
64
|
}) => {
|
|
59
65
|
// Generate unique ID for transfer lines
|
|
60
66
|
const generateTransferId = () => {
|
|
@@ -101,27 +107,9 @@ const SearchBarTransfer: React.FC<SearchBarTransferProps> = ({
|
|
|
101
107
|
const transferMode = newMode as TransferMode;
|
|
102
108
|
if (transferMode === mode) return;
|
|
103
109
|
|
|
104
|
-
if (transferMode === "custom" && mode === "roundtrip"
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
id: generateTransferId(),
|
|
108
|
-
type: "arrival",
|
|
109
|
-
paxData: roundTripData.paxData,
|
|
110
|
-
transferDate: roundTripData.arrivalDate,
|
|
111
|
-
pickupPoint: roundTripData.pickupDropoffPoint,
|
|
112
|
-
dropoffPoint: roundTripData.accommodation,
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const departureTransfer: TransferLineData = {
|
|
116
|
-
id: generateTransferId(),
|
|
117
|
-
type: "departure",
|
|
118
|
-
paxData: roundTripData.paxData,
|
|
119
|
-
transferDate: roundTripData.departureDate,
|
|
120
|
-
pickupPoint: roundTripData.accommodation,
|
|
121
|
-
dropoffPoint: roundTripData.pickupDropoffPoint,
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
setTransferLines([arrivalTransfer, departureTransfer]);
|
|
110
|
+
if (transferMode === "custom" && mode === "roundtrip") {
|
|
111
|
+
// When switching to custom mode, reset transfer lines (will show placeholder)
|
|
112
|
+
setTransferLines([]);
|
|
125
113
|
setRoundTripData(undefined);
|
|
126
114
|
} else if (transferMode === "roundtrip" && mode === "custom") {
|
|
127
115
|
// Reset everything when switching to roundtrip
|
|
@@ -172,46 +160,16 @@ const SearchBarTransfer: React.FC<SearchBarTransferProps> = ({
|
|
|
172
160
|
</div>
|
|
173
161
|
);
|
|
174
162
|
|
|
175
|
-
// Handle adding transfer from round-trip mode (
|
|
163
|
+
// Handle adding transfer from round-trip mode (switches to custom and adds new transfer)
|
|
176
164
|
const handleAddTransferFromRoundTrip = (type: TransferType) => {
|
|
177
|
-
if (!roundTripData) {
|
|
178
|
-
// If no round trip data, just add a new transfer and switch to custom
|
|
179
|
-
const newTransfer: TransferLineData = {
|
|
180
|
-
id: generateTransferId(),
|
|
181
|
-
type,
|
|
182
|
-
};
|
|
183
|
-
setTransferLines([newTransfer]);
|
|
184
|
-
setMode("custom");
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Convert roundtrip to two transfer lines
|
|
189
|
-
const arrivalTransfer: TransferLineData = {
|
|
190
|
-
id: generateTransferId(),
|
|
191
|
-
type: "arrival",
|
|
192
|
-
paxData: roundTripData.paxData,
|
|
193
|
-
transferDate: roundTripData.arrivalDate,
|
|
194
|
-
pickupPoint: roundTripData.pickupDropoffPoint,
|
|
195
|
-
dropoffPoint: roundTripData.accommodation,
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
const departureTransfer: TransferLineData = {
|
|
199
|
-
id: generateTransferId(),
|
|
200
|
-
type: "departure",
|
|
201
|
-
paxData: roundTripData.paxData,
|
|
202
|
-
transferDate: roundTripData.departureDate,
|
|
203
|
-
pickupPoint: roundTripData.accommodation,
|
|
204
|
-
dropoffPoint: roundTripData.pickupDropoffPoint,
|
|
205
|
-
};
|
|
206
|
-
|
|
207
165
|
// Add the new transfer of the clicked type
|
|
208
166
|
const newTransfer: TransferLineData = {
|
|
209
167
|
id: generateTransferId(),
|
|
210
168
|
type,
|
|
211
169
|
};
|
|
212
170
|
|
|
213
|
-
// Set
|
|
214
|
-
setTransferLines([
|
|
171
|
+
// Set the transfer and switch to custom mode
|
|
172
|
+
setTransferLines([newTransfer]);
|
|
215
173
|
setRoundTripData(undefined);
|
|
216
174
|
setMode("custom");
|
|
217
175
|
setError(null);
|
|
@@ -226,6 +184,13 @@ const SearchBarTransfer: React.FC<SearchBarTransferProps> = ({
|
|
|
226
184
|
|
|
227
185
|
// Handle transfer line deletion
|
|
228
186
|
const handleDeleteTransferLine = (id: string) => {
|
|
187
|
+
const index = transferLines.findIndex((line) => line.id === id);
|
|
188
|
+
const transferLine = transferLines.find((line) => line.id === id);
|
|
189
|
+
|
|
190
|
+
if (index !== -1 && transferLine) {
|
|
191
|
+
onRemove?.(index, transferLine);
|
|
192
|
+
}
|
|
193
|
+
|
|
229
194
|
setTransferLines((prevLines) => prevLines.filter((line) => line.id !== id));
|
|
230
195
|
};
|
|
231
196
|
|
|
@@ -314,6 +279,7 @@ const SearchBarTransfer: React.FC<SearchBarTransferProps> = ({
|
|
|
314
279
|
accommodation={roundTripData?.accommodation?.id as string}
|
|
315
280
|
onChange={setRoundTripData}
|
|
316
281
|
checkEmpty={error !== null}
|
|
282
|
+
scrollOnOpen={scrollOnOpen}
|
|
317
283
|
/>
|
|
318
284
|
{/* Transfer type buttons for round-trip mode */}
|
|
319
285
|
<div className="search-bar-transfer__transfer-type">
|
|
@@ -330,6 +296,19 @@ const SearchBarTransfer: React.FC<SearchBarTransferProps> = ({
|
|
|
330
296
|
{renderTransferTypeButtons(handleAddTransfer)}
|
|
331
297
|
</div>
|
|
332
298
|
|
|
299
|
+
{/* Show placeholder disabled transfer line when there are no transfers */}
|
|
300
|
+
{transferLines.length === 0 && (
|
|
301
|
+
<TransferLine
|
|
302
|
+
id="placeholder-transfer"
|
|
303
|
+
type="inter-hotel"
|
|
304
|
+
locations={locations}
|
|
305
|
+
onDataChange={() => {}}
|
|
306
|
+
showDelete={false}
|
|
307
|
+
disabled={true}
|
|
308
|
+
scrollOnOpen={scrollOnOpen}
|
|
309
|
+
/>
|
|
310
|
+
)}
|
|
311
|
+
|
|
333
312
|
{/* Transfer lines list */}
|
|
334
313
|
{transferLines.length > 0 && (
|
|
335
314
|
<div className="search-bar-transfer__transfer-lines">
|
|
@@ -381,6 +360,7 @@ const SearchBarTransfer: React.FC<SearchBarTransferProps> = ({
|
|
|
381
360
|
onDelete={() => handleDeleteTransferLine(line.id)}
|
|
382
361
|
showDelete={transferLines.length > 1}
|
|
383
362
|
checkEmpty={error !== null}
|
|
363
|
+
scrollOnOpen={scrollOnOpen}
|
|
384
364
|
/>
|
|
385
365
|
))}
|
|
386
366
|
|
|
@@ -16,10 +16,14 @@
|
|
|
16
16
|
width: 100%;
|
|
17
17
|
border-collapse: collapse;
|
|
18
18
|
border-spacing: 0;
|
|
19
|
+
table-layout: fixed;
|
|
19
20
|
th,
|
|
20
21
|
td {
|
|
21
22
|
padding-inline: var(--spacing-padding-px-4);
|
|
22
23
|
}
|
|
24
|
+
.table__cell-highlighted {
|
|
25
|
+
padding: 0;
|
|
26
|
+
}
|
|
23
27
|
}
|
|
24
28
|
.table__header {
|
|
25
29
|
th {
|
|
@@ -34,61 +38,13 @@
|
|
|
34
38
|
&:hover:not(.table__no-hover) {
|
|
35
39
|
background-color: var(--color-elevation-state-hover-subtle);
|
|
36
40
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
&.table__row-yellow {
|
|
41
|
-
background-color: var(--color-yellow-50);
|
|
42
|
-
border: 1px solid transparent;
|
|
43
|
-
position: relative;
|
|
44
|
-
&::after {
|
|
45
|
-
content: '';
|
|
46
|
-
position: absolute;
|
|
47
|
-
inset: -1px;
|
|
48
|
-
pointer-events: none;
|
|
49
|
-
background-image:
|
|
50
|
-
repeating-linear-gradient(
|
|
51
|
-
to right,
|
|
52
|
-
var(--color-yellow-600) 0,
|
|
53
|
-
var(--color-yellow-600) 8px,
|
|
54
|
-
transparent 8px,
|
|
55
|
-
transparent 16px
|
|
56
|
-
),
|
|
57
|
-
repeating-linear-gradient(
|
|
58
|
-
to right,
|
|
59
|
-
var(--color-yellow-600) 0,
|
|
60
|
-
var(--color-yellow-600) 8px,
|
|
61
|
-
transparent 8px,
|
|
62
|
-
transparent 16px
|
|
63
|
-
),
|
|
64
|
-
repeating-linear-gradient(
|
|
65
|
-
to bottom,
|
|
66
|
-
var(--color-yellow-600) 0,
|
|
67
|
-
var(--color-yellow-600) 8px,
|
|
68
|
-
transparent 8px,
|
|
69
|
-
transparent 16px
|
|
70
|
-
),
|
|
71
|
-
repeating-linear-gradient(
|
|
72
|
-
to bottom,
|
|
73
|
-
var(--color-yellow-600) 0,
|
|
74
|
-
var(--color-yellow-600) 8px,
|
|
75
|
-
transparent 8px,
|
|
76
|
-
transparent 16px
|
|
77
|
-
);
|
|
78
|
-
background-size:
|
|
79
|
-
100% 1px,
|
|
80
|
-
100% 1px,
|
|
81
|
-
1px 100%,
|
|
82
|
-
1px 100%;
|
|
83
|
-
background-position: top, bottom, left, right;
|
|
84
|
-
background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
|
|
85
|
-
}
|
|
86
|
-
&:hover {
|
|
41
|
+
&.table__row-highlighted:hover {
|
|
42
|
+
tr {
|
|
87
43
|
background-color: var(--color-yellow-100);
|
|
88
44
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
45
|
+
}
|
|
46
|
+
&:first-child {
|
|
47
|
+
border-top: none;
|
|
92
48
|
}
|
|
93
49
|
&.table__row-border-0 {
|
|
94
50
|
border-top: none;
|
|
@@ -258,3 +214,58 @@
|
|
|
258
214
|
}
|
|
259
215
|
}
|
|
260
216
|
}
|
|
217
|
+
|
|
218
|
+
.table__row-div-highlighted {
|
|
219
|
+
background-color: var(--color-yellow-50);
|
|
220
|
+
border: 1px solid transparent;
|
|
221
|
+
position: relative;
|
|
222
|
+
|
|
223
|
+
&::after {
|
|
224
|
+
content: '';
|
|
225
|
+
position: absolute;
|
|
226
|
+
inset: -1px;
|
|
227
|
+
pointer-events: none;
|
|
228
|
+
background-image:
|
|
229
|
+
repeating-linear-gradient(
|
|
230
|
+
to right,
|
|
231
|
+
var(--color-yellow-600) 0,
|
|
232
|
+
var(--color-yellow-600) 8px,
|
|
233
|
+
transparent 8px,
|
|
234
|
+
transparent 16px
|
|
235
|
+
),
|
|
236
|
+
repeating-linear-gradient(
|
|
237
|
+
to right,
|
|
238
|
+
var(--color-yellow-600) 0,
|
|
239
|
+
var(--color-yellow-600) 8px,
|
|
240
|
+
transparent 8px,
|
|
241
|
+
transparent 16px
|
|
242
|
+
),
|
|
243
|
+
repeating-linear-gradient(
|
|
244
|
+
to bottom,
|
|
245
|
+
var(--color-yellow-600) 0,
|
|
246
|
+
var(--color-yellow-600) 8px,
|
|
247
|
+
transparent 8px,
|
|
248
|
+
transparent 16px
|
|
249
|
+
),
|
|
250
|
+
repeating-linear-gradient(
|
|
251
|
+
to bottom,
|
|
252
|
+
var(--color-yellow-600) 0,
|
|
253
|
+
var(--color-yellow-600) 8px,
|
|
254
|
+
transparent 8px,
|
|
255
|
+
transparent 16px
|
|
256
|
+
);
|
|
257
|
+
background-size:
|
|
258
|
+
100% 1px,
|
|
259
|
+
100% 1px,
|
|
260
|
+
1px 100%,
|
|
261
|
+
1px 100%;
|
|
262
|
+
background-position: top, bottom, left, right;
|
|
263
|
+
background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
|
|
264
|
+
}
|
|
265
|
+
&:hover {
|
|
266
|
+
background-color: var(--color-yellow-100);
|
|
267
|
+
}
|
|
268
|
+
& + tr {
|
|
269
|
+
border-top: none;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -22,6 +22,8 @@ export type TableRowData<T = any> = {
|
|
|
22
22
|
*/
|
|
23
23
|
className?: string;
|
|
24
24
|
|
|
25
|
+
isHighlighted?: boolean;
|
|
26
|
+
|
|
25
27
|
/** Children rows for the row */
|
|
26
28
|
children?: T[];
|
|
27
29
|
};
|
|
@@ -194,9 +196,28 @@ export function Table<T extends TableRowData<T>>(props: TableProps<T>) {
|
|
|
194
196
|
className={cn(row.className, {
|
|
195
197
|
'table__row-nested': row.children?.length,
|
|
196
198
|
'table__row-clickable': onClickRow,
|
|
199
|
+
'table__row-highlighted': row.isHighlighted,
|
|
197
200
|
})}
|
|
198
201
|
onClick={(e) => onClickRow?.(e, row)}>
|
|
199
|
-
|
|
202
|
+
{row.isHighlighted ? (
|
|
203
|
+
<td colSpan={columns.length} className="table__cell-highlighted">
|
|
204
|
+
<div className="table__row-div-highlighted">
|
|
205
|
+
<table className="table">
|
|
206
|
+
<tbody>
|
|
207
|
+
<tr>
|
|
208
|
+
<TableCell<T>
|
|
209
|
+
columns={columns}
|
|
210
|
+
row={row}
|
|
211
|
+
rowIndex={rowIndex}
|
|
212
|
+
/>
|
|
213
|
+
</tr>
|
|
214
|
+
</tbody>
|
|
215
|
+
</table>
|
|
216
|
+
</div>
|
|
217
|
+
</td>
|
|
218
|
+
) : (
|
|
219
|
+
<TableCell<T> columns={columns} row={row} rowIndex={rowIndex} />
|
|
220
|
+
)}
|
|
200
221
|
</tr>
|
|
201
222
|
);
|
|
202
223
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Button from '@/src/components/atoms/Button/Button';
|
|
2
|
+
import Chip from '@/src/components/atoms/Chip/Chip';
|
|
2
3
|
import { Text } from '@/src/components/atoms/Typography/Typography';
|
|
3
4
|
import { ActionDropdown } from '@/src/components/molecules/ActionDropdown/ActionDropdown';
|
|
4
5
|
import { DateDisplay } from '@/src/components/molecules/DateDisplay/DateDisplay';
|
|
@@ -8,8 +9,40 @@ import { BookingListItem } from '@/src/types/table/booking.types';
|
|
|
8
9
|
import { ColumnType } from '../TableCell';
|
|
9
10
|
import { actionDropdownData } from '../constant';
|
|
10
11
|
|
|
12
|
+
const CHIP_WIDTH = 'w-[184px]';
|
|
13
|
+
const BUTTON_WIDTH = 'w-[89px]';
|
|
14
|
+
|
|
15
|
+
const renderStatusContent = (status: BookingListItem['status']) => {
|
|
16
|
+
if (status === 'PENDING') {
|
|
17
|
+
return (
|
|
18
|
+
<Chip size="sm" color="yellow" className={CHIP_WIDTH}>
|
|
19
|
+
On Request
|
|
20
|
+
</Chip>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (status === 'Cancelled') {
|
|
25
|
+
return (
|
|
26
|
+
<Chip size="sm" color="red" className={CHIP_WIDTH}>
|
|
27
|
+
Cancelled
|
|
28
|
+
</Chip>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div className="flex items-center gap-x-3">
|
|
34
|
+
<Button variant="secondary" size="sm" className={BUTTON_WIDTH}>
|
|
35
|
+
Proforma
|
|
36
|
+
</Button>
|
|
37
|
+
<Button variant="outline-secondary" size="sm" className={BUTTON_WIDTH}>
|
|
38
|
+
Voucher
|
|
39
|
+
</Button>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
11
44
|
export const bookingColumns: (params: {
|
|
12
|
-
onAction?: (action: ActionDropdownType) => void;
|
|
45
|
+
onAction?: (data: BookingListItem) => (action: ActionDropdownType) => void;
|
|
13
46
|
keywords?: string;
|
|
14
47
|
}) => ColumnType<BookingListItem>[] = ({ onAction, keywords = '' }) => [
|
|
15
48
|
{
|
|
@@ -101,19 +134,13 @@ export const bookingColumns: (params: {
|
|
|
101
134
|
key: 'actions',
|
|
102
135
|
width: 232,
|
|
103
136
|
cell: (_value, raw) => {
|
|
137
|
+
const handleAction = onAction?.(raw) ?? (() => {});
|
|
138
|
+
const actionData = actionDropdownData(handleAction);
|
|
139
|
+
|
|
104
140
|
return (
|
|
105
|
-
<div>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<Button variant="secondary" size="sm" className="w-[89px]">
|
|
109
|
-
Proforma
|
|
110
|
-
</Button>
|
|
111
|
-
<Button variant="outline-secondary" size="sm" className="w-[89px]">
|
|
112
|
-
Voucher
|
|
113
|
-
</Button>
|
|
114
|
-
</div>
|
|
115
|
-
<ActionDropdown data={actionDropdownData(onAction ?? (() => {}))} />
|
|
116
|
-
</div>
|
|
141
|
+
<div className="flex items-center justify-between">
|
|
142
|
+
{renderStatusContent(raw.status)}
|
|
143
|
+
<ActionDropdown data={actionData} />
|
|
117
144
|
</div>
|
|
118
145
|
);
|
|
119
146
|
},
|