@autobusal/operator-routes 1.0.2 → 1.0.3
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/Transiting/Countries.tsx +42 -0
- package/Transiting/Manage.tsx +93 -0
- package/Transiting/services.ts +52 -0
- package/Transiting/styles.ts +28 -0
- package/Transiting/utilities.ts +11 -0
- package/index.ts +3 -1
- package/package.json +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { TFunction } from 'i18next';
|
|
2
|
+
import { BiTrash } from 'react-icons/bi';
|
|
3
|
+
import { Container, Item, ButtonDelete } from './styles';
|
|
4
|
+
import { TransitingData } from '@autobusal/providers/types/routes';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
transiting: TransitingData[]
|
|
8
|
+
t: TFunction<'normal'>
|
|
9
|
+
onDelete: (id: number) => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const Countries = ({ transiting, t, onDelete }: Props): JSX.Element => {
|
|
13
|
+
if (transiting.length == 0) {
|
|
14
|
+
return (
|
|
15
|
+
<>-</>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const onDeleteConfirm = (id: number): void => {
|
|
20
|
+
if (window.confirm(t('private.transiting_manage.confirm'))) {
|
|
21
|
+
onDelete(id);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const items = transiting.map(item => (
|
|
26
|
+
<Item key={ item.id }>
|
|
27
|
+
{ item.country.name }
|
|
28
|
+
|
|
29
|
+
<ButtonDelete type="button" onClick={ () => onDeleteConfirm(item.country.id) }>
|
|
30
|
+
<BiTrash />
|
|
31
|
+
</ButtonDelete>
|
|
32
|
+
</Item>
|
|
33
|
+
));
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Container>
|
|
37
|
+
{ items }
|
|
38
|
+
</Container>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default Countries;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { TFunction } from 'i18next';
|
|
2
|
+
import { useParams, Navigate } from 'react-router-dom';
|
|
3
|
+
import { Meta, BackWithTitle, Viewer, Box } from '@autobusal/common';
|
|
4
|
+
import { usePage, useCountries } from '@autobusal/hooks';
|
|
5
|
+
import { success } from '@autobusal/utilities';
|
|
6
|
+
import Countries from './Countries';
|
|
7
|
+
import { filterCountries } from './utilities';
|
|
8
|
+
import { TransitingData } from '@autobusal/providers/types/routes';
|
|
9
|
+
import { GetTransiting, PostTransiting, DeleteTransiting } from './services';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
url: string
|
|
13
|
+
t: TFunction<'common'>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const Manage = ({ url, t }: Props): JSX.Element => {
|
|
17
|
+
const params = useParams();
|
|
18
|
+
|
|
19
|
+
const id = Number(params.id);
|
|
20
|
+
|
|
21
|
+
url = url.replace('[id]', String(id));
|
|
22
|
+
|
|
23
|
+
usePage('routes');
|
|
24
|
+
|
|
25
|
+
const { data: CountriesData, isLoading } = useCountries('available');
|
|
26
|
+
|
|
27
|
+
const { data, refetch } = GetTransiting(id);
|
|
28
|
+
|
|
29
|
+
const { mutate: Update, isPending: isPendingSave } = PostTransiting(id);
|
|
30
|
+
|
|
31
|
+
const { mutate: Delete, isPending: isPendingDelete } = DeleteTransiting(id);
|
|
32
|
+
|
|
33
|
+
if (id === 0) {
|
|
34
|
+
return <Navigate to={ url } />;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (isLoading) {
|
|
38
|
+
return <Box />;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const onSave = (data: TransitingData): void => {
|
|
42
|
+
Update(data, {
|
|
43
|
+
onSuccess: () => {
|
|
44
|
+
success(t('transiting_manage.messages.saved', { ns: 'common' }));
|
|
45
|
+
|
|
46
|
+
refetch();
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const onDelete = (id: number): void => {
|
|
52
|
+
Delete(id, {
|
|
53
|
+
onSuccess: () => {
|
|
54
|
+
success(t('transiting_manage.messages.deleted', { ns: 'common' }));
|
|
55
|
+
|
|
56
|
+
refetch();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const title = t('transiting_manage.title', { name: data?.name, ns: 'common' });
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Meta title={ title }>
|
|
65
|
+
<BackWithTitle title={ title } to={ url } t={ t } />
|
|
66
|
+
|
|
67
|
+
<Viewer
|
|
68
|
+
id={ id }
|
|
69
|
+
data={ [{
|
|
70
|
+
label: t('transiting_manage.transiting', { ns: 'common' }),
|
|
71
|
+
type: 'component',
|
|
72
|
+
name: 'transiting',
|
|
73
|
+
value: <Countries transiting={ data?.transiting ?? [] } t={ t } onDelete={ onDelete } />
|
|
74
|
+
}, {}, {
|
|
75
|
+
label: t('transiting_manage.countries', { ns: 'common' }),
|
|
76
|
+
name: 'country_id',
|
|
77
|
+
type: 'select',
|
|
78
|
+
values: filterCountries(data?.transiting ?? [], CountriesData),
|
|
79
|
+
value: 0,
|
|
80
|
+
rules: 'required|min:1'
|
|
81
|
+
}] }
|
|
82
|
+
pending={ isPendingSave || isPendingDelete }
|
|
83
|
+
t={ t }
|
|
84
|
+
actions={ [
|
|
85
|
+
'add'
|
|
86
|
+
]}
|
|
87
|
+
onSave={ onSave }
|
|
88
|
+
/>
|
|
89
|
+
</Meta>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export default Manage;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { UseMutationResult, UseSuspenseQueryResult, useMutation, useSuspenseQuery } from '@tanstack/react-query';
|
|
2
|
+
import { apiClient } from '@autobusal/providers';
|
|
3
|
+
import { RouteData, TransitingData } from '@autobusal/providers/types/routes';
|
|
4
|
+
|
|
5
|
+
export const GetTransiting = (id: number): UseSuspenseQueryResult<RouteData> => (
|
|
6
|
+
useSuspenseQuery({
|
|
7
|
+
queryKey: ['operator-transiting', { id }],
|
|
8
|
+
queryFn: async () => (
|
|
9
|
+
await apiClient
|
|
10
|
+
.get('/api/transiting/operator/browse', {
|
|
11
|
+
params: { id }
|
|
12
|
+
})
|
|
13
|
+
.then(response => (
|
|
14
|
+
response.data
|
|
15
|
+
))
|
|
16
|
+
)
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const PostTransiting = (id: number): UseMutationResult<void, Error, TransitingData, unknown> => (
|
|
21
|
+
useMutation({
|
|
22
|
+
mutationKey: ['operator-transiting-save', { id }],
|
|
23
|
+
mutationFn: async (data: TransitingData) => (
|
|
24
|
+
await apiClient
|
|
25
|
+
.post('/api/transiting/operator/update', {
|
|
26
|
+
...data,
|
|
27
|
+
id
|
|
28
|
+
})
|
|
29
|
+
.then(response => (
|
|
30
|
+
response.data
|
|
31
|
+
))
|
|
32
|
+
)
|
|
33
|
+
})
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export const DeleteTransiting = (id: number): UseMutationResult<void, Error, number, unknown> => (
|
|
37
|
+
useMutation({
|
|
38
|
+
mutationKey: ['operator-transiting-delete'],
|
|
39
|
+
mutationFn: async (countryId: number) => (
|
|
40
|
+
await apiClient
|
|
41
|
+
.delete('/api/transiting/operator/delete', {
|
|
42
|
+
params: {
|
|
43
|
+
id,
|
|
44
|
+
country_id: countryId
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
.then(response => (
|
|
48
|
+
response.data
|
|
49
|
+
))
|
|
50
|
+
)
|
|
51
|
+
})
|
|
52
|
+
);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
|
|
3
|
+
export const Container = styled.div`
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
gap: 5px;
|
|
7
|
+
`;
|
|
8
|
+
|
|
9
|
+
export const Item = styled.div`
|
|
10
|
+
display: flex;
|
|
11
|
+
justify-content: space-between;
|
|
12
|
+
align-items: center;
|
|
13
|
+
gap: 10px;
|
|
14
|
+
padding: 7px 10px;
|
|
15
|
+
font-weight: 700;
|
|
16
|
+
border: 1px solid ${ props => props.theme.background.neutral };
|
|
17
|
+
border-radius: ${ props => props.theme.borderRadius };
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
export const ButtonDelete = styled.button`
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
width: 24px;
|
|
25
|
+
height: 24px;
|
|
26
|
+
color: ${ props => props.theme.font.error };
|
|
27
|
+
font-size: ${ props => props.theme.size.l };
|
|
28
|
+
`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CountryData } from '@autobusal/providers/types/locations';
|
|
2
|
+
import { DropdownData } from '@autobusal/providers/types/other';
|
|
3
|
+
import { TransitingData } from '@autobusal/providers/types/routes';
|
|
4
|
+
|
|
5
|
+
export const filterCountries = (transiting: TransitingData[], countries?: CountryData[]): DropdownData[] => {
|
|
6
|
+
const ids = transiting.map(item => item.country.id);
|
|
7
|
+
|
|
8
|
+
const available = countries?.filter(item => !ids.includes(item.id));
|
|
9
|
+
|
|
10
|
+
return available ?? [];
|
|
11
|
+
};
|
package/index.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import Browse from './Browse';
|
|
2
2
|
import Manage from './Manage';
|
|
3
3
|
import SchedulesManage from './Schedule/Manage';
|
|
4
|
+
import TransitingManage from './Transiting/Manage';
|
|
4
5
|
|
|
5
6
|
export {
|
|
6
7
|
Browse,
|
|
7
8
|
Manage,
|
|
8
|
-
SchedulesManage
|
|
9
|
+
SchedulesManage,
|
|
10
|
+
TransitingManage
|
|
9
11
|
};
|