@autobusal/routes-order 1.0.0
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/Found/Booking/Booking.tsx +61 -0
- package/Found/Booking/styles.ts +50 -0
- package/Found/Dates/Dates.tsx +82 -0
- package/Found/Dates/Loading.tsx +14 -0
- package/Found/Dates/styles.ts +50 -0
- package/Found/Found.tsx +31 -0
- package/Found/Header/Header.tsx +21 -0
- package/Found/Header/styles.ts +40 -0
- package/Found/Orders/Orders.tsx +40 -0
- package/Found/Orders/styles.ts +12 -0
- package/Found/Route/Route.tsx +112 -0
- package/Found/Route/styles.ts +187 -0
- package/RoutesOrder.tsx +130 -0
- package/Step1/Step1.tsx +63 -0
- package/Step1/prepare.ts +38 -0
- package/Step2.tsx +55 -0
- package/Step3.tsx +56 -0
- package/Step4/Loading.tsx +26 -0
- package/Step4/Passenger/Passenger.tsx +173 -0
- package/Step4/Passenger/styles.ts +10 -0
- package/Step4/Passengers/Display.tsx +50 -0
- package/Step4/Passengers/Passengers.tsx +96 -0
- package/Step4/Passengers/styles.ts +7 -0
- package/Step4/Step4.tsx +96 -0
- package/Step4/checkAge.ts +48 -0
- package/Step5/Billing/Billing.tsx +161 -0
- package/Step5/Billing/Loading.tsx +22 -0
- package/Step5/Billing/styles.ts +13 -0
- package/Step5/Coupons/Coupons.tsx +71 -0
- package/Step5/Coupons/styles.ts +20 -0
- package/Step5/Payments/Payments.tsx +82 -0
- package/Step5/Payments/styles.ts +42 -0
- package/Step5/Step5.tsx +131 -0
- package/Step5/Summary/About/About.tsx +48 -0
- package/Step5/Summary/About/styles.ts +49 -0
- package/Step5/Summary/Amount/Amount.tsx +24 -0
- package/Step5/Summary/Amount/styles.ts +29 -0
- package/Step5/Summary/Summary.tsx +44 -0
- package/Step5/Summary/Tickets/Preview.tsx +41 -0
- package/Step5/Summary/Tickets/Tickets.tsx +34 -0
- package/Step5/Summary/Tickets/styles.ts +36 -0
- package/Step5/Summary/styles.ts +11 -0
- package/Step5/utilities.ts +24 -0
- package/Steps/Steps.tsx +28 -0
- package/Steps/styles.ts +47 -0
- package/index.ts +3 -0
- package/package.json +6 -0
- package/services.ts +149 -0
- package/styles.ts +24 -0
- package/types.ts +32 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { FoundData } from '@autobusal/providers/types/routes';
|
|
2
|
+
import { CouponData } from '@autobusal/providers/types/orders';
|
|
3
|
+
import { TotalData } from '../types';
|
|
4
|
+
|
|
5
|
+
export const getTotal = (step2: FoundData, step3?: FoundData): TotalData => {
|
|
6
|
+
// we get the currency
|
|
7
|
+
const currency = step2.price.display.split(' ');
|
|
8
|
+
|
|
9
|
+
const total = step2.price.value + (step3?.price.value ?? 0);
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
display: `${ total } ${ currency[1] }`,
|
|
13
|
+
value: total
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const convertCoupon = (data: CouponData): TotalData => {
|
|
18
|
+
const currency = data.total.split(' ');
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
display: data.total,
|
|
22
|
+
value: Number(currency[0])
|
|
23
|
+
};
|
|
24
|
+
};
|
package/Steps/Steps.tsx
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { AiOutlineCheck } from 'react-icons/ai';
|
|
2
|
+
import { Container, Item, Content } from './styles';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
value: number
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const Steps = ({ value }: Props): JSX.Element => {
|
|
9
|
+
const items: JSX.Element[] = [];
|
|
10
|
+
|
|
11
|
+
for (let i = 1; i <= 5; i++) {
|
|
12
|
+
items.push(
|
|
13
|
+
<Item key={ i }>
|
|
14
|
+
<Content $selected={ value > i }>
|
|
15
|
+
{ value > i ? <AiOutlineCheck /> : i }
|
|
16
|
+
</Content>
|
|
17
|
+
</Item>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Container>
|
|
23
|
+
{ items }
|
|
24
|
+
</Container>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default Steps;
|
package/Steps/styles.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
|
|
3
|
+
export const Container = styled.div`
|
|
4
|
+
position: relative;
|
|
5
|
+
display: flex;
|
|
6
|
+
max-width: 600px;
|
|
7
|
+
margin: 0 auto 30px;
|
|
8
|
+
padding: 0 25px;
|
|
9
|
+
justify-content: space-between;
|
|
10
|
+
|
|
11
|
+
&:before {
|
|
12
|
+
position: absolute;
|
|
13
|
+
left: 0;
|
|
14
|
+
bottom: 50%;
|
|
15
|
+
z-index: 0;
|
|
16
|
+
width: 100%;
|
|
17
|
+
content: '';
|
|
18
|
+
border-bottom: 3px solid ${ props => props.theme.background.neutral };
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
export const Item = styled.div`
|
|
23
|
+
position: relative;
|
|
24
|
+
z-index: 1;
|
|
25
|
+
width: 48px;
|
|
26
|
+
background-color: ${ props => props.theme.background.normal };
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
export const Content = styled.div<{ $selected: boolean }>`
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
width: 28px;
|
|
34
|
+
height: 28px;
|
|
35
|
+
margin: 0 auto;
|
|
36
|
+
font-weight: 700;
|
|
37
|
+
font-size: ${ props => props.theme.size.xs };
|
|
38
|
+
background-color: ${ props => props.theme.background.normal };
|
|
39
|
+
border: 1px solid ${ props => props.theme.primary.normal };
|
|
40
|
+
border-radius: 100px;
|
|
41
|
+
|
|
42
|
+
${ props => props.$selected && css`
|
|
43
|
+
color: #FFFFFF;
|
|
44
|
+
background-color: ${ props => props.theme.font.success };
|
|
45
|
+
border-color: ${ props => props.theme.font.success };
|
|
46
|
+
` }
|
|
47
|
+
`;
|
package/index.ts
ADDED
package/package.json
ADDED
package/services.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { useMutation, UseMutationResult, useQuery, UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import { apiClient } from '@autobusal/providers';
|
|
3
|
+
import { RoutesSearchForm } from '@autobusal/routes-search/types';
|
|
4
|
+
import { FoundData } from '@autobusal/providers/types/routes';
|
|
5
|
+
import { CouponData } from '@autobusal/providers/types/orders';
|
|
6
|
+
import { BillingData, PersonData } from '@autobusal/providers/types/persons';
|
|
7
|
+
import { FoundDay, ActionData, SaveData, OrderedData, CouponForm } from './types';
|
|
8
|
+
|
|
9
|
+
export const GetDepartures = (data: RoutesSearchForm): UseQueryResult<FoundData[]> => (
|
|
10
|
+
useQuery({
|
|
11
|
+
queryKey: ['search-routes-step2', { data }],
|
|
12
|
+
queryFn: async () => (
|
|
13
|
+
await apiClient
|
|
14
|
+
.get('/api/routes/search/departure', {
|
|
15
|
+
params: data
|
|
16
|
+
})
|
|
17
|
+
.then(response => (
|
|
18
|
+
response?.data ?? []
|
|
19
|
+
))
|
|
20
|
+
)
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export const GetReturns = (data: RoutesSearchForm, departure: FoundData): UseQueryResult<FoundData[]> => (
|
|
25
|
+
useQuery({
|
|
26
|
+
queryKey: ['search-routes-step3', { data }],
|
|
27
|
+
queryFn: async () => (
|
|
28
|
+
await apiClient
|
|
29
|
+
.get('/api/routes/search/return', {
|
|
30
|
+
params: {
|
|
31
|
+
...data,
|
|
32
|
+
operator_id: departure.operator.id
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
.then(response => (
|
|
36
|
+
response?.data ?? []
|
|
37
|
+
))
|
|
38
|
+
)
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export const GetDates = (step1: RoutesSearchForm, type: ('departure' | '_return'), number: number): UseQueryResult<FoundDay[]> => {
|
|
43
|
+
const step = { ...step1 };
|
|
44
|
+
|
|
45
|
+
// we switch the locations and dates if a return trip
|
|
46
|
+
if (type === '_return' && step._return !== undefined) {
|
|
47
|
+
step.departure = step1._return ?? '';
|
|
48
|
+
step._return = step1.departure;
|
|
49
|
+
|
|
50
|
+
step.from = step1.to;
|
|
51
|
+
step.to = step1.from;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return useQuery({
|
|
55
|
+
queryKey: ['step2-dates', { number }],
|
|
56
|
+
queryFn: async () => (
|
|
57
|
+
await apiClient
|
|
58
|
+
.get('/api/routes/search/dates', {
|
|
59
|
+
params: {
|
|
60
|
+
...step,
|
|
61
|
+
number
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
.then(response => (
|
|
65
|
+
response?.data ?? []
|
|
66
|
+
))
|
|
67
|
+
)
|
|
68
|
+
})
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const PostOrder = (
|
|
72
|
+
step1: RoutesSearchForm,
|
|
73
|
+
step2: FoundData,
|
|
74
|
+
step3: (FoundData | undefined),
|
|
75
|
+
step4: PersonData,
|
|
76
|
+
coupon: (CouponData | undefined),
|
|
77
|
+
action: (string | undefined)
|
|
78
|
+
): UseMutationResult<OrderedData, Error, BillingData, unknown> => (
|
|
79
|
+
useMutation({
|
|
80
|
+
mutationKey: ['save-order'],
|
|
81
|
+
mutationFn: async (data: BillingData) => {
|
|
82
|
+
const type = step1.type ?? 'departure';
|
|
83
|
+
|
|
84
|
+
const order: SaveData = {};
|
|
85
|
+
|
|
86
|
+
order.departure = step1.departure;
|
|
87
|
+
order.departure_price_id = step2.price.id;
|
|
88
|
+
|
|
89
|
+
if (type === 'return' && step1._return !== undefined && step3 !== undefined) {
|
|
90
|
+
order.return = step1._return;
|
|
91
|
+
order.return_price_id = step3?.price.id;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (coupon !== undefined) {
|
|
95
|
+
order.coupon = coupon.code;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
Object.keys(step4).forEach(index => {
|
|
99
|
+
order[index] = step4[index];
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (action !== undefined) {
|
|
103
|
+
order.action = action;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (data !== undefined) {
|
|
107
|
+
Object.keys(data).forEach(index => {
|
|
108
|
+
order[index] = data[index as keyof typeof data];
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return await apiClient
|
|
113
|
+
.post(`/api/orders/create/${ type }`, order)
|
|
114
|
+
.then(response => (
|
|
115
|
+
response.data
|
|
116
|
+
))
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
export const GetCoupon = (routeId: number, total: number): UseMutationResult<CouponData, Error, CouponForm, unknown> => (
|
|
122
|
+
useMutation({
|
|
123
|
+
mutationKey: ['search-coupon'],
|
|
124
|
+
mutationFn: async (data: CouponForm) => (
|
|
125
|
+
await apiClient
|
|
126
|
+
.post('/api/coupons/search', {
|
|
127
|
+
code: data.code,
|
|
128
|
+
route_id: routeId,
|
|
129
|
+
total
|
|
130
|
+
})
|
|
131
|
+
.then(response => (
|
|
132
|
+
response.data
|
|
133
|
+
))
|
|
134
|
+
)
|
|
135
|
+
})
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
export const GetPayments = (): UseQueryResult<ActionData> => (
|
|
139
|
+
useQuery({
|
|
140
|
+
queryKey: ['allowed-funds'],
|
|
141
|
+
queryFn: async () => (
|
|
142
|
+
await apiClient
|
|
143
|
+
.get('/api/funds/allowed')
|
|
144
|
+
.then(response => (
|
|
145
|
+
response.data
|
|
146
|
+
))
|
|
147
|
+
)
|
|
148
|
+
})
|
|
149
|
+
);
|
package/styles.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
|
|
3
|
+
export const Title = styled.h1`
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
gap: 10px;
|
|
7
|
+
`;
|
|
8
|
+
|
|
9
|
+
export const SubTitle = styled.h3`
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 10px;
|
|
13
|
+
padding-bottom: 18px;
|
|
14
|
+
margin-bottom: 18px;
|
|
15
|
+
border-bottom: 1px solid ${ props => props.theme.background.neutral };
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export const Actions = styled.div`
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-wrap: wrap;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
gap: 20px;
|
|
23
|
+
margin-top: 25px;
|
|
24
|
+
`;
|
package/types.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface FoundDay {
|
|
2
|
+
day: string
|
|
3
|
+
id: string
|
|
4
|
+
routes: boolean
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface CouponForm {
|
|
8
|
+
code: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ActionData {
|
|
12
|
+
fake: boolean
|
|
13
|
+
reserve: boolean
|
|
14
|
+
funds: boolean
|
|
15
|
+
bkt: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface SaveData {
|
|
19
|
+
[key: string]: string | number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface OrderedData {
|
|
23
|
+
departure: string
|
|
24
|
+
departure_download: string
|
|
25
|
+
return?: string
|
|
26
|
+
return_download?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface TotalData {
|
|
30
|
+
display: string
|
|
31
|
+
value: number
|
|
32
|
+
}
|