@autobusal/common 1.33.12 → 1.33.14
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/CHANGELOG.md +10 -0
- package/RouteItem/RouteItem.tsx +6 -2
- package/Seats/ChooseSeat.tsx +42 -4
- package/Seats/styles.ts +23 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.33.14 (2026-08-26)
|
|
4
|
+
|
|
5
|
+
- ChooseSeat: seat-selection add-on mode - `optional` + `fee` props; unpicked state shows the free-auto note, a made choice gets a back-to-automatic control. Default behaviour (required free pick) unchanged.
|
|
6
|
+
|
|
7
|
+
## 1.33.13
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **`RouteItem` no longer advertises "From 0.00"**: zero-fare rows are unpriced legs search never sells, so they no longer count toward the cheapest-of figure. (Audit RT-11b.)
|
|
12
|
+
|
|
3
13
|
## 1.33.12
|
|
4
14
|
|
|
5
15
|
### Added
|
package/RouteItem/RouteItem.tsx
CHANGED
|
@@ -25,8 +25,12 @@ const RouteItem = ({ type, route, t }: Props): JSX.Element => {
|
|
|
25
25
|
// reformatting `adult` itself - the server already applied this label's
|
|
26
26
|
// currency symbol/decimal convention, and re-deriving that here would
|
|
27
27
|
// risk disagreeing with every other price on the site.
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
// Claude - 2026-08-22 (audit finding RT-11b): zero-fare rows are
|
|
29
|
+
// unpriced legs search never sells - see RouteView's matching note.
|
|
30
|
+
const priced = route.prices.filter(price => price.adult > 0);
|
|
31
|
+
|
|
32
|
+
const cheapest = priced.length > 0
|
|
33
|
+
? priced.reduce((min, price) => (price.adult < min.adult ? price : min))
|
|
30
34
|
: null;
|
|
31
35
|
|
|
32
36
|
return (
|
package/Seats/ChooseSeat.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { MdEventSeat } from 'react-icons/md';
|
|
|
6
6
|
import { Validate } from '@autobusal/utilities';
|
|
7
7
|
import Unavailable from './Unavailable';
|
|
8
8
|
import Preview from './Preview';
|
|
9
|
-
import { ButtonSeat } from './styles';
|
|
9
|
+
import { ButtonSeat, AutoNote, ClearChoice } from './styles';
|
|
10
10
|
import { OccupiedData } from '@autobusal/providers/types/buses';
|
|
11
11
|
import { PersonData } from '@autobusal/providers/types/persons';
|
|
12
12
|
|
|
@@ -17,12 +17,29 @@ interface Props {
|
|
|
17
17
|
bus: OccupiedData
|
|
18
18
|
picked: number[]
|
|
19
19
|
validation: string
|
|
20
|
+
/**
|
|
21
|
+
* Edited: Claude - Date: 2026-08-26
|
|
22
|
+
*
|
|
23
|
+
* The seat-selection ADD-ON mode. When the brand sells seat choice
|
|
24
|
+
* (settings addons.seats.available), picking becomes optional: the
|
|
25
|
+
* unpicked state is honest ("a seat is assigned automatically, free"),
|
|
26
|
+
* the call to action carries the fee, and a made choice can be taken
|
|
27
|
+
* back. When absent, this component behaves exactly as it always has -
|
|
28
|
+
* a required, free pick - which is what every brand still on the old
|
|
29
|
+
* model gets.
|
|
30
|
+
*
|
|
31
|
+
* `fee` is the DISPLAY string ("1.5 EUR"), already formatted by the
|
|
32
|
+
* caller; the figure actually charged is the server's own
|
|
33
|
+
* (obtapi Orders\Make\Addons), never this.
|
|
34
|
+
*/
|
|
35
|
+
optional?: boolean
|
|
36
|
+
fee?: string
|
|
20
37
|
t: TFunction<'common'>
|
|
21
38
|
refs: UseFormRegister<PersonData | any>
|
|
22
39
|
onUpdate: (name: string, type: ('from' | 'to'), value: number, previous: number) => void
|
|
23
40
|
}
|
|
24
41
|
|
|
25
|
-
const ChooseSeat = ({ name, type, defaultValue, bus, picked, validation, t, refs, onUpdate }: Props): JSX.Element => {
|
|
42
|
+
const ChooseSeat = ({ name, type, defaultValue, bus, picked, validation, optional, fee, t, refs, onUpdate }: Props): JSX.Element => {
|
|
26
43
|
const [ show, setShow ] = useState<boolean>(false);
|
|
27
44
|
const [ selected, setSelected ] = useState<number>(defaultValue ?? 0);
|
|
28
45
|
|
|
@@ -41,14 +58,35 @@ const ChooseSeat = ({ name, type, defaultValue, bus, picked, validation, t, refs
|
|
|
41
58
|
}
|
|
42
59
|
};
|
|
43
60
|
|
|
61
|
+
// back to the free automatic assignment - the parent drops the seat from
|
|
62
|
+
// its picked list and the form value goes to 0, which the order submission
|
|
63
|
+
// strips entirely (the API auto-assigns absent fields)
|
|
64
|
+
const onClear = (): void => {
|
|
65
|
+
onUpdate(name, type, 0, selected);
|
|
66
|
+
|
|
67
|
+
setSelected(0);
|
|
68
|
+
};
|
|
69
|
+
|
|
44
70
|
return (
|
|
45
71
|
<div>
|
|
46
72
|
<ButtonSeat type="button" $selected={ selected > 0 } onClick={ () => setShow(true) }>
|
|
47
73
|
{ selected > 0
|
|
48
74
|
? <><FaCheck /> { t('seats.chosen', { ns: 'common', number: selected }) }</>
|
|
49
|
-
: <><MdEventSeat /> {
|
|
75
|
+
: <><MdEventSeat /> { (optional && fee)
|
|
76
|
+
? t('seats.choose_fee', { ns: 'common', price: fee })
|
|
77
|
+
: t('seats.choose', { ns: 'common' }) }</> }
|
|
50
78
|
</ButtonSeat>
|
|
51
79
|
|
|
80
|
+
{ (optional && selected === 0) && (
|
|
81
|
+
<AutoNote>{ t('seats.auto', { ns: 'common' }) }</AutoNote>
|
|
82
|
+
) }
|
|
83
|
+
|
|
84
|
+
{ (optional && selected > 0) && (
|
|
85
|
+
<ClearChoice type="button" onClick={ onClear }>
|
|
86
|
+
{ t('seats.clear', { ns: 'common' }) }
|
|
87
|
+
</ClearChoice>
|
|
88
|
+
) }
|
|
89
|
+
|
|
52
90
|
{ (show && bus.bus !== undefined) && (
|
|
53
91
|
<Preview
|
|
54
92
|
bus={ bus.bus }
|
|
@@ -66,4 +104,4 @@ const ChooseSeat = ({ name, type, defaultValue, bus, picked, validation, t, refs
|
|
|
66
104
|
);
|
|
67
105
|
};
|
|
68
106
|
|
|
69
|
-
export default ChooseSeat;
|
|
107
|
+
export default ChooseSeat;
|
package/Seats/styles.ts
CHANGED
|
@@ -25,6 +25,29 @@ export const ButtonSeat = styled.button<{ $selected: boolean }>`
|
|
|
25
25
|
` }
|
|
26
26
|
`;
|
|
27
27
|
|
|
28
|
+
// Edited: Claude - Date: 2026-08-26 - the two states of the seat-selection
|
|
29
|
+
// ADD-ON mode (see ChooseSeat): the honest "you get a seat anyway, free"
|
|
30
|
+
// note under an unpicked button, and the way back out of a paid choice.
|
|
31
|
+
export const AutoNote = styled.div`
|
|
32
|
+
margin-top: 3px;
|
|
33
|
+
font-size: ${ props => props.theme.size.xs };
|
|
34
|
+
color: ${ props => props.theme.font.faded };
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
export const ClearChoice = styled.button`
|
|
38
|
+
margin-top: 3px;
|
|
39
|
+
padding: 0;
|
|
40
|
+
font-size: ${ props => props.theme.size.xs };
|
|
41
|
+
color: ${ props => props.theme.font.faded };
|
|
42
|
+
background: none;
|
|
43
|
+
text-decoration: underline;
|
|
44
|
+
transition: all 0.3s ease;
|
|
45
|
+
|
|
46
|
+
&:hover {
|
|
47
|
+
color: ${ props => props.theme.font.error };
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
|
|
28
51
|
export const Seats = styled.div`
|
|
29
52
|
overflow-x: auto;
|
|
30
53
|
`;
|