@autobusal/operator-routes 1.0.8 → 1.0.10

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.
@@ -4,7 +4,7 @@ import { BsPlusCircleFill } from 'react-icons/bs';
4
4
  import { Meta, BackWithTitle, Button, Table, Row } from '@autobusal/common';
5
5
  import { usePage } from '@autobusal/hooks';
6
6
  import { success } from '@autobusal/utilities';
7
- import { GetAlternates, PostAdd, DeleteAlternate } from './services';
7
+ import { useGetAlternates, usePostAdd, useDeleteAlternate } from './services';
8
8
 
9
9
  interface Props {
10
10
  url: string
@@ -24,11 +24,11 @@ const Browse = ({ url, backUrl, t }: Props): JSX.Element => {
24
24
 
25
25
  usePage('routes');
26
26
 
27
- const { data, isLoading, isFetching, refetch } = GetAlternates(id);
27
+ const { data, isLoading, isFetching, refetch } = useGetAlternates(id);
28
28
 
29
- const { mutate: Add, isPending } = PostAdd(id);
29
+ const { mutate: Add, isPending } = usePostAdd(id);
30
30
 
31
- const { mutate: Delete } = DeleteAlternate(id);
31
+ const { mutate: Delete } = useDeleteAlternate(id);
32
32
 
33
33
  if (id === 0) {
34
34
  return <Navigate to={ backUrl } />;
@@ -3,7 +3,7 @@ import { apiClient } from '@autobusal/providers';
3
3
  import { RouteData, AlternateData } from '@autobusal/providers/types/routes';
4
4
  import { ScheduleForm } from '../Prices/types';
5
5
 
6
- export const GetAlternates = (id: number): UseQueryResult<RouteData> => (
6
+ export const useGetAlternates = (id: number): UseQueryResult<RouteData> => (
7
7
  useQuery({
8
8
  queryKey: ['operator-alternates', { id }],
9
9
  queryFn: async () => (
@@ -18,7 +18,7 @@ export const GetAlternates = (id: number): UseQueryResult<RouteData> => (
18
18
  })
19
19
  );
20
20
 
21
- export const PostAdd = (id: number): UseMutationResult<AlternateData> => (
21
+ export const usePostAdd = (id: number): UseMutationResult<AlternateData> => (
22
22
  useMutation({
23
23
  mutationKey: ['operator-alternates-add', { id }],
24
24
  mutationFn: async () => (
@@ -31,7 +31,7 @@ export const PostAdd = (id: number): UseMutationResult<AlternateData> => (
31
31
  })
32
32
  );
33
33
 
34
- export const PostSchedule = (id: number, name: string): UseMutationResult<void, Error, ScheduleForm, unknown> => (
34
+ export const usePostSchedule = (id: number, name: string): UseMutationResult<void, Error, ScheduleForm, unknown> => (
35
35
  useMutation({
36
36
  mutationKey: ['operator-alternates-schedule', { id, name }],
37
37
  mutationFn: async (data: ScheduleForm) => (
@@ -48,7 +48,7 @@ export const PostSchedule = (id: number, name: string): UseMutationResult<void,
48
48
  })
49
49
  );
50
50
 
51
- export const DeleteAlternate = (id: number): UseMutationResult<void, Error, number, unknown> => (
51
+ export const useDeleteAlternate = (id: number): UseMutationResult<void, Error, number, unknown> => (
52
52
  useMutation({
53
53
  mutationKey: ['operator-alternates-delete'],
54
54
  mutationFn: async (name: number) => (
package/Browse.tsx CHANGED
@@ -4,7 +4,7 @@ import { Meta, Table, Row } from '@autobusal/common';
4
4
  import { usePage } from '@autobusal/hooks';
5
5
  import { getParams } from '@autobusal/utilities';
6
6
  import { Bags, Dates } from './Information';
7
- import { GetRoutes } from './services';
7
+ import { useGetRoutes } from './services';
8
8
 
9
9
  interface Props {
10
10
  url: string
@@ -16,7 +16,7 @@ const Browse = ({ url, t }: Props): JSX.Element => {
16
16
 
17
17
  usePage('routes');
18
18
 
19
- const { data, isLoading, isFetching } = GetRoutes(getParams(searchParams, ['page', 'sort', 'order', 'q']));
19
+ const { data, isLoading, isFetching } = useGetRoutes(getParams(searchParams, ['page', 'sort', 'order', 'q']));
20
20
 
21
21
  const rows = data?.data.map(item => (
22
22
  <Row
@@ -7,7 +7,7 @@ import Loading from './Loading';
7
7
  import { getStops } from '../utilities';
8
8
  import { Container, Title, ContainerAdd, Choose, Notice } from './styles';
9
9
  import { AddForm } from '../types';
10
- import { GetStops, AddLocation } from '../services';
10
+ import { useGetStops, useAddLocation } from '../services';
11
11
 
12
12
  interface Props {
13
13
  routeId: number
@@ -18,9 +18,9 @@ interface Props {
18
18
  const Add = ({ routeId, t, onReload }: Props): JSX.Element => {
19
19
  const { register, handleSubmit, formState: { errors } } = useForm<AddForm>();
20
20
 
21
- const { data, isLoading } = GetStops(routeId);
21
+ const { data, isLoading } = useGetStops(routeId);
22
22
 
23
- const { mutate: Save, isPending } = AddLocation(routeId);
23
+ const { mutate: Save, isPending } = useAddLocation(routeId);
24
24
 
25
25
  if (isLoading) {
26
26
  return <Loading t={ t } />;
@@ -6,7 +6,7 @@ import { getTomorrow } from '../utilities';
6
6
  import { Data } from './styles';
7
7
  import { LocationForm } from '../types';
8
8
  import { LocationData } from '@autobusal/providers/types/locations';
9
- import { PostMove, DeleteLocation, PostUpdate } from '../services';
9
+ import { usePostMove, useDeleteLocation, usePostUpdate } from '../services';
10
10
 
11
11
  interface Props {
12
12
  routeId: number
@@ -18,11 +18,11 @@ interface Props {
18
18
  const Item = ({ routeId, item, t, onReload }: Props): JSX.Element => {
19
19
  const { register, handleSubmit, formState: { errors } } = useForm<LocationForm>();
20
20
 
21
- const { mutate: Save, isPending: isPendingUpdate } = PostUpdate(routeId, item.id);
21
+ const { mutate: Save, isPending: isPendingUpdate } = usePostUpdate(routeId, item.id);
22
22
 
23
- const { mutate: Move, isPending: isPendingMove } = PostMove(routeId, item.id);
23
+ const { mutate: Move, isPending: isPendingMove } = usePostMove(routeId, item.id);
24
24
 
25
- const { mutate: Delete, isPending: isPendingDelete } = DeleteLocation(routeId, item.id);
25
+ const { mutate: Delete, isPending: isPendingDelete } = useDeleteLocation(routeId, item.id);
26
26
 
27
27
  const onSubmit = (data: LocationForm): void => {
28
28
  Save(data);
@@ -4,7 +4,7 @@ import { Meta, BackWithTitle, Report } from '@autobusal/common';
4
4
  import { usePage } from '@autobusal/hooks';
5
5
  import Add from './Add/Add';
6
6
  import Browse from './Browse/Browse';
7
- import { GetLocations } from './services';
7
+ import { useGetLocations } from './services';
8
8
 
9
9
  interface Props {
10
10
  url: string
@@ -20,7 +20,7 @@ const Manage = ({ url, t }: Props): JSX.Element => {
20
20
 
21
21
  usePage('routes');
22
22
 
23
- const { data, refetch } = GetLocations(id);
23
+ const { data, refetch } = useGetLocations(id);
24
24
 
25
25
  const onReload = (): void => {
26
26
  refetch();
@@ -4,7 +4,7 @@ import { RouteData } from '@autobusal/providers/types/routes';
4
4
  import { CountryData } from '@autobusal/providers/types/locations';
5
5
  import { AddForm, LocationForm } from './types';
6
6
 
7
- export const GetLocations = (id: number): UseSuspenseQueryResult<RouteData> => (
7
+ export const useGetLocations = (id: number): UseSuspenseQueryResult<RouteData> => (
8
8
  useSuspenseQuery({
9
9
  queryKey: ['operator-locations', { id }],
10
10
  queryFn: async () => (
@@ -19,7 +19,7 @@ export const GetLocations = (id: number): UseSuspenseQueryResult<RouteData> => (
19
19
  })
20
20
  );
21
21
 
22
- export const GetStops = (routeId: number): UseQueryResult<CountryData[]> => (
22
+ export const useGetStops = (routeId: number): UseQueryResult<CountryData[]> => (
23
23
  useQuery({
24
24
  queryKey: ['operator-stops', { routeId }],
25
25
  queryFn: async () => (
@@ -36,7 +36,7 @@ export const GetStops = (routeId: number): UseQueryResult<CountryData[]> => (
36
36
  })
37
37
  );
38
38
 
39
- export const AddLocation = (id: number): UseMutationResult<void, Error, AddForm, unknown> => (
39
+ export const useAddLocation = (id: number): UseMutationResult<void, Error, AddForm, unknown> => (
40
40
  useMutation({
41
41
  mutationKey: ['operator-locations-add', { id }],
42
42
  mutationFn: async (data: AddForm) => {
@@ -52,7 +52,7 @@ export const AddLocation = (id: number): UseMutationResult<void, Error, AddForm,
52
52
  })
53
53
  );
54
54
 
55
- export const PostMove = (id: number, location_id: number): UseMutationResult<void, Error, number, unknown> => (
55
+ export const usePostMove = (id: number, location_id: number): UseMutationResult<void, Error, number, unknown> => (
56
56
  useMutation({
57
57
  mutationKey: ['operator-locations-move', { id, location_id }],
58
58
  mutationFn: async (order: number) => (
@@ -69,7 +69,7 @@ export const PostMove = (id: number, location_id: number): UseMutationResult<voi
69
69
  })
70
70
  );
71
71
 
72
- export const DeleteLocation = (id: number, location_id: number): UseMutationResult<void> => (
72
+ export const useDeleteLocation = (id: number, location_id: number): UseMutationResult<void> => (
73
73
  useMutation({
74
74
  mutationKey: ['operator-locations-delete', { id, location_id }],
75
75
  mutationFn: async () => (
@@ -87,7 +87,7 @@ export const DeleteLocation = (id: number, location_id: number): UseMutationResu
87
87
  })
88
88
  );
89
89
 
90
- export const PostUpdate = (id: number, location_id: number): UseMutationResult<void, Error, LocationForm, unknown> => (
90
+ export const usePostUpdate = (id: number, location_id: number): UseMutationResult<void, Error, LocationForm, unknown> => (
91
91
  useMutation({
92
92
  mutationKey: ['operator-locations-update', { id, location_id }],
93
93
  mutationFn: async (data: LocationForm) => (
package/Manage.tsx CHANGED
@@ -5,14 +5,15 @@ import { RiMoneyEuroCircleLine } from 'react-icons/ri';
5
5
  import { FaMapMarkerAlt } from 'react-icons/fa';
6
6
  import { IoCalendarClearOutline } from 'react-icons/io5';
7
7
  import { Meta, BackWithTitle, Viewer } from '@autobusal/common';
8
- import { usePage, useBuses, useRouteFeatures, useOperatorDrivers } from '@autobusal/hooks';
8
+ import { usePage, useRouteFeatures, useOperatorDrivers } from '@autobusal/hooks';
9
9
  import { success } from '@autobusal/utilities';
10
10
  import Template from './Template';
11
11
  import Options from './Options';
12
12
  import Seating from './Seating';
13
- import { getType, getLanguagesExtended, getTemplates, getBusType, getSeatingType, getTransiting } from './utilities';
13
+ import { getType, getLanguagesExtended, getTemplates, getTransiting } from './utilities';
14
14
  import { RouteData } from '@autobusal/providers/types/routes';
15
- import { GetRoute, PostRoute, DeleteRoute } from './services';
15
+ import { SeatingOptionsData } from './types';
16
+ import { useGetRoute, usePostRoute, useDeleteRoute } from './services';
16
17
 
17
18
  interface Props {
18
19
  url: string
@@ -20,7 +21,7 @@ interface Props {
20
21
  }
21
22
 
22
23
  const Manage = ({ url, t }: Props): JSX.Element => {
23
- const [ seating, setSeating ] = useState<string>('');
24
+ const [ seating, setSeating ] = useState<SeatingOptionsData | undefined>(undefined);
24
25
 
25
26
  const params = useParams();
26
27
 
@@ -30,26 +31,16 @@ const Manage = ({ url, t }: Props): JSX.Element => {
30
31
 
31
32
  const navigate = useNavigate();
32
33
 
33
- const { data } = GetRoute(id);
34
+ const { data, isFetching } = useGetRoute(id);
34
35
 
35
- const { mutate: Update, isPending: isPendingSave } = PostRoute(id, seating);
36
+ const { mutate: Update, isPending: isPendingSave } = usePostRoute(id, seating);
36
37
 
37
- const { mutate: Delete, isPending: isPendingDelete } = DeleteRoute();
38
-
39
- const buses = useBuses();
38
+ const { mutate: Delete, isPending: isPendingDelete } = useDeleteRoute();
40
39
 
41
40
  const features = useRouteFeatures();
42
41
 
43
42
  const drivers = useOperatorDrivers('id');
44
43
 
45
- useEffect(() => {
46
- setSeating(data?.trip.seating ?? 'free');
47
- }, [data]);
48
-
49
- const onSeating = (id: string): void => {
50
- setSeating(id);
51
- };
52
-
53
44
  const onSave = (data: RouteData): void => {
54
45
  Update(data, {
55
46
  onSuccess: () => {
@@ -69,7 +60,11 @@ const Manage = ({ url, t }: Props): JSX.Element => {
69
60
  }
70
61
  });
71
62
  };
72
-
63
+
64
+ const onSeatingUpdated = (options: SeatingOptionsData): void => {
65
+ setSeating(options);
66
+ };
67
+
73
68
  const title = id > 0 ? t('operator_routes.manage.title.update', { name: data?.name, ns: 'common' }) : t('operator_routes.manage.title.new', { ns: 'common' });
74
69
 
75
70
  return (
@@ -95,12 +90,8 @@ const Manage = ({ url, t }: Props): JSX.Element => {
95
90
  label: t('operator_routes.manage.seat_reservation', { ns: 'common' }),
96
91
  type: 'component',
97
92
  name: 'seating',
98
- value: <Seating value={ seating } t={ t } onChange={ onSeating } />
99
- }, {}, (
100
- getBusType(buses, seating, t, data?.trip.bus?.id)
101
- ) , (
102
- getSeatingType(seating, t, data?.trip)
103
- ), {} , {
93
+ value: <Seating trip={ data?.trip } t={ t } onUpdated={ onSeatingUpdated } />
94
+ }, {} , {
104
95
  label: t('operator_routes.manage.schedule.title', { ns: 'common' }),
105
96
  name: 'schedule',
106
97
  type: 'link',
@@ -223,6 +214,7 @@ const Manage = ({ url, t }: Props): JSX.Element => {
223
214
  <Options id={ id } t={ t } />
224
215
  )
225
216
  }] }
217
+ fetching={ isFetching }
226
218
  pending={ isPendingSave || isPendingDelete }
227
219
  t={ t }
228
220
  actions={ [
package/Options.tsx CHANGED
@@ -4,7 +4,7 @@ import styled from 'styled-components';
4
4
  import { AiOutlineCopy, AiOutlineReload } from 'react-icons/ai';
5
5
  import { Button } from '@autobusal/common';
6
6
  import { success } from '@autobusal/utilities';
7
- import { PostCopy } from './services';
7
+ import { usePostCopy } from './services';
8
8
 
9
9
  interface Props {
10
10
  id: number
@@ -14,9 +14,9 @@ interface Props {
14
14
  const Options = ({ id, t }: Props): JSX.Element => {
15
15
  const navigate = useNavigate();
16
16
 
17
- const { mutate: Copy, isPending: isPendingCopy } = PostCopy(id);
17
+ const { mutate: Copy, isPending: isPendingCopy } = usePostCopy(id);
18
18
 
19
- const { mutate: Reverse, isPending: isPendingReverse } = PostCopy(id, true);
19
+ const { mutate: Reverse, isPending: isPendingReverse } = usePostCopy(id, true);
20
20
 
21
21
  const onCopy = (): void => {
22
22
  if (!window.confirm(t('operator_routes.manage.options.confirm', { ns: 'common' }))) {
@@ -6,7 +6,7 @@ import { Validate, Display, success } from '@autobusal/utilities';
6
6
  import { Prices, Actions } from './styles';
7
7
  import { PriceData } from '@autobusal/providers/types/routes';
8
8
  import { PriceForm } from '../types';
9
- import { PostPrice } from '../services';
9
+ import { usePostPrice } from '../services';
10
10
 
11
11
  interface Props {
12
12
  id: number
@@ -19,7 +19,7 @@ interface Props {
19
19
  const Item = ({ id, type, item, name, t }: Props): JSX.Element => {
20
20
  const { register, handleSubmit, formState: { errors } } = useForm<PriceForm>();
21
21
 
22
- const { mutate: Save, isPending } = PostPrice(id, item.id, type, name);
22
+ const { mutate: Save, isPending } = usePostPrice(id, item.id, type, name);
23
23
 
24
24
  const onSubmit = (data: PriceForm): void => {
25
25
  Save(data, {
package/Prices/Manage.tsx CHANGED
@@ -5,7 +5,7 @@ import { usePage } from '@autobusal/hooks';
5
5
  import Options from './Options/Options';
6
6
  import Schedule from './Schedule/Schedule';
7
7
  import Browse from './Browse/Browse';
8
- import { GetPrices } from './services';
8
+ import { useGetPrices } from './services';
9
9
 
10
10
  interface Props {
11
11
  type: 'normal' | 'alternate'
@@ -23,7 +23,7 @@ const Manage = ({ type, url, t }: Props): JSX.Element => {
23
23
 
24
24
  usePage('routes');
25
25
 
26
- const { data, refetch } = GetPrices(id, type, name);
26
+ const { data, refetch } = useGetPrices(id, type, name);
27
27
 
28
28
  const onReload = () => {
29
29
  refetch();
@@ -5,7 +5,7 @@ import { Inline } from '@autobusal/common';
5
5
  import { useOutside } from '@autobusal/hooks';
6
6
  import { success } from '@autobusal/utilities';
7
7
  import { Container, ButtonMore, Submenu, ButtonOption, Loading } from './styles';
8
- import { PostCopy } from '../services';
8
+ import { usePostCopy } from '../services';
9
9
 
10
10
  interface Props {
11
11
  id: number
@@ -20,7 +20,7 @@ const Options = ({ id, type, name, t, onReload }: Props): JSX.Element => {
20
20
 
21
21
  const ref = useRef(null);
22
22
 
23
- const { mutate: Copy, isPending } = PostCopy(id, type, name);
23
+ const { mutate: Copy, isPending } = usePostCopy(id, type, name);
24
24
 
25
25
  useOutside(ref, () => setShow(false));
26
26
 
@@ -5,7 +5,7 @@ import { Calendar, Button } from '@autobusal/common';
5
5
  import { Display, success } from '@autobusal/utilities';
6
6
  import { Container, Dates } from './styles';
7
7
  import { AlternateData } from '@autobusal/providers/types/routes';
8
- import { PostSchedule } from '../../Alternates/services';
8
+ import { usePostSchedule } from '../../Alternates/services';
9
9
  import { ScheduleForm } from '../types';
10
10
 
11
11
  interface Props {
@@ -21,7 +21,7 @@ const Schedule = ({ id, data, name, t }: Props): JSX.Element => {
21
21
  // we get the 1st value, as they're identical
22
22
  const details = data !== undefined ? data[0] : undefined;
23
23
 
24
- const { mutate: Save, isPending } = PostSchedule(id, name);
24
+ const { mutate: Save, isPending } = usePostSchedule(id, name);
25
25
 
26
26
  const onSubmit = (data: ScheduleForm): void => {
27
27
  Save(data, {
@@ -3,7 +3,7 @@ import { apiClient } from '@autobusal/providers';
3
3
  import { RouteData } from '@autobusal/providers/types/routes';
4
4
  import { PriceForm } from './types';
5
5
 
6
- export const GetPrices = (id: number, type: string, name: string): UseSuspenseQueryResult<RouteData> => (
6
+ export const useGetPrices = (id: number, type: string, name: string): UseSuspenseQueryResult<RouteData> => (
7
7
  useSuspenseQuery({
8
8
  queryKey: [`operator-prices-${ type }`, { id, type, name }],
9
9
  queryFn: async () => (
@@ -22,7 +22,7 @@ export const GetPrices = (id: number, type: string, name: string): UseSuspenseQu
22
22
  })
23
23
  );
24
24
 
25
- export const PostPrice = (id: number, price_id: number, type: ('normal' | 'alternate'), name: string): UseMutationResult<void, Error, PriceForm, unknown> => (
25
+ export const usePostPrice = (id: number, price_id: number, type: ('normal' | 'alternate'), name: string): UseMutationResult<void, Error, PriceForm, unknown> => (
26
26
  useMutation({
27
27
  mutationKey: ['operator-prices-save', { id, price_id, type, name }],
28
28
  mutationFn: async (data: PriceForm) => (
@@ -41,7 +41,7 @@ export const PostPrice = (id: number, price_id: number, type: ('normal' | 'alter
41
41
  })
42
42
  );
43
43
 
44
- export const PostCopy = (id: number, type: ('normal' | 'alternate'), name: string): UseMutationResult<void> => (
44
+ export const usePostCopy = (id: number, type: ('normal' | 'alternate'), name: string): UseMutationResult<void> => (
45
45
  useMutation({
46
46
  mutationKey: ['operator-prices-copy', { id, type, name }],
47
47
  mutationFn: async () => (
@@ -5,7 +5,7 @@ import { usePage } from '@autobusal/hooks';
5
5
  import { success } from '@autobusal/utilities';
6
6
  import { getSchedules } from './utilities';
7
7
  import { AvailableData } from '@autobusal/providers/types/routes';
8
- import { GetSchedule, PostSchedule } from './services';
8
+ import { useGetSchedule, usePostSchedule } from './services';
9
9
 
10
10
  interface Props {
11
11
  url: string
@@ -23,9 +23,9 @@ const Manage = ({ url, t }: Props): JSX.Element => {
23
23
 
24
24
  const navigate = useNavigate();
25
25
 
26
- const { data } = GetSchedule(id);
26
+ const { data, isFetching } = useGetSchedule(id);
27
27
 
28
- const { mutate: Update, isPending } = PostSchedule(id);
28
+ const { mutate: Update, isPending } = usePostSchedule(id);
29
29
 
30
30
  if (id === 0) {
31
31
  return <Navigate to={ url } />;
@@ -34,7 +34,7 @@ const Manage = ({ url, t }: Props): JSX.Element => {
34
34
  const onSave = (data: AvailableData): void => {
35
35
  Update(data, {
36
36
  onSuccess: () => {
37
- success(t('schedules_manage.message.saved', { ns: 'common' }));
37
+ success(t('schedules_manage.messages.saved', { ns: 'common' }));
38
38
 
39
39
  navigate(url);
40
40
  }
@@ -42,7 +42,7 @@ const Manage = ({ url, t }: Props): JSX.Element => {
42
42
  };
43
43
 
44
44
  const title = t('schedules_manage.title', { name: data?.name, ns: 'common' });
45
-
45
+
46
46
  return (
47
47
  <Meta title={ title }>
48
48
  <BackWithTitle title={ title } to={ url } t={ t } />
@@ -68,6 +68,7 @@ const Manage = ({ url, t }: Props): JSX.Element => {
68
68
  values: getSchedules(t),
69
69
  selected: data?.available.schedule ?? []
70
70
  }] }
71
+ fetching={ isFetching }
71
72
  pending={ isPending }
72
73
  t={ t }
73
74
  actions={ [
@@ -2,7 +2,7 @@ import { UseMutationResult, UseSuspenseQueryResult, useMutation, useSuspenseQuer
2
2
  import { apiClient } from '@autobusal/providers';
3
3
  import { RouteData, AvailableData } from '@autobusal/providers/types/routes';
4
4
 
5
- export const GetSchedule = (id: number): UseSuspenseQueryResult<RouteData> => (
5
+ export const useGetSchedule = (id: number): UseSuspenseQueryResult<RouteData> => (
6
6
  useSuspenseQuery({
7
7
  queryKey: ['operator-schedule-manage', { id }],
8
8
  queryFn: async () => {
@@ -21,7 +21,7 @@ export const GetSchedule = (id: number): UseSuspenseQueryResult<RouteData> => (
21
21
  })
22
22
  );
23
23
 
24
- export const PostSchedule = (id: number): UseMutationResult<void, Error, AvailableData, unknown> => (
24
+ export const usePostSchedule = (id: number): UseMutationResult<void, Error, AvailableData, unknown> => (
25
25
  useMutation({
26
26
  mutationKey: ['operator-schedule-save', { id }],
27
27
  mutationFn: async (data: AvailableData) => (
package/Seating.tsx CHANGED
@@ -1,29 +1,154 @@
1
+ import { useState, useEffect, ChangeEvent } from 'react';
1
2
  import { TFunction } from 'i18next';
3
+ import { useBuses } from '@autobusal/hooks';
4
+ import { Display } from '@autobusal/common/Viewer/styles';
2
5
  import styled from 'styled-components';
6
+ import { TripData } from '@autobusal/providers/types/routes';
7
+ import { SeatingOptionsData } from './types';
3
8
 
4
9
  interface Props {
5
- value?: string
10
+ trip?: TripData
6
11
  t: TFunction<'normal'>
7
- onChange: (id: string) => void
12
+ onUpdated: (options: SeatingOptionsData) => void
8
13
  }
9
14
 
10
- const Seating = ({ value, t, onChange }: Props): JSX.Element => (
11
- <Container>
12
- <label>
13
- <input checked={ value === 'free' } type="radio" name="seating" onChange={ () => onChange('free') } />
14
- { t('operator_routes.manage.seating.free', { ns: 'common' }) }
15
- </label>
15
+ const Seating = ({ trip, t, onUpdated }: Props): JSX.Element => {
16
+ const [ data, setData ] = useState<SeatingOptionsData>({
17
+ seating: trip?.seating ?? 'free',
18
+ bus_id: trip?.bus?.id,
19
+ blocked_seats: Number(trip?.blocked_seats),
20
+ available_seats: Number(trip?.available_seats)
21
+ });
22
+ const [ type, setType ] = useState<string>(data.seating);
16
23
 
17
- <label>
18
- <input checked={ value === 'reservation' } type="radio" name="seating" onChange={ () => onChange('reservation') } />
19
- { t('operator_routes.manage.seating.reservation', { ns: 'common' }) }
20
- </label>
21
- </Container>
22
- );
24
+ const buses = useBuses();
25
+
26
+ useEffect(() => {
27
+ onUpdated(data);
28
+ }, [data]);
29
+
30
+ const onSeatingChange = (type: string): void => {
31
+ const newData = { ...data };
32
+
33
+ newData.seating = type;
34
+
35
+ if (type === 'free') {
36
+ newData.bus_id = undefined;
37
+ newData.blocked_seats = 0;
38
+ } else {
39
+ newData.bus_id = Number(buses[0].id);
40
+ newData.available_seats = 0;
41
+ }
42
+
43
+ setType(type);
44
+ setData(newData);
45
+ };
46
+
47
+ const onBusChange = (event: ChangeEvent<HTMLSelectElement>): void => {
48
+ setData({
49
+ ...data,
50
+ bus_id: Number(event.target.value)
51
+ });
52
+ };
53
+
54
+ const onSeatsChange = (event: ChangeEvent<HTMLInputElement>, type: string): void => {
55
+ const seatsNo = Number(event.target.value);
56
+
57
+ if (type === 'blocked_seats') {
58
+ setData({
59
+ ...data,
60
+ blocked_seats: seatsNo
61
+ });
62
+ }
63
+
64
+ if (type === 'available_seats') {
65
+ setData({
66
+ ...data,
67
+ available_seats: seatsNo
68
+ });
69
+ }
70
+ };
71
+
72
+ const busOptions = buses.map(bus => (
73
+ <option key={ bus.id } value={ bus.id }>
74
+ { bus.name }
75
+ </option>
76
+ ));
77
+
78
+ return (
79
+ <>
80
+ <div className="row">
81
+ <Container>
82
+ <label>
83
+ <input checked={ type === 'free' } type="radio" name="seating" onChange={ () => onSeatingChange('free') } />
84
+ { t('operator_routes.manage.seating.free', { ns: 'common' }) }
85
+ </label>
86
+
87
+ <label>
88
+ <input checked={ type === 'reservation' } type="radio" name="seating" onChange={ () => onSeatingChange('reservation') } />
89
+ { t('operator_routes.manage.seating.reservation', { ns: 'common' }) }
90
+ </label>
91
+ </Container>
92
+ </div>
93
+
94
+ <Column className="column">
95
+ <div className="row">
96
+ { type === 'reservation' && (
97
+ <>
98
+ { t('operator_routes.manage.bus.reservation', { ns: 'common' }) }
99
+
100
+ <select defaultValue={ trip?.bus?.id } onChange={ onBusChange }>
101
+ { busOptions }
102
+ </select>
103
+ </>
104
+ ) }
105
+
106
+ { type === 'free' && (
107
+ <>
108
+ { t('operator_routes.manage.bus.title', { ns: 'common' }) }
109
+
110
+ <Display className="row-data">{ t('operator_routes.manage.bus.free', { ns: 'common' }) }</Display>
111
+ </>
112
+ ) }
113
+ </div>
114
+
115
+ <div className="row row-nomargin">
116
+ { type === 'reservation' && (
117
+ <>
118
+ { t('operator_routes.manage.seats.blocked', { ns: 'common' }) }
119
+
120
+ <input type="number" name="blocked_seats" defaultValue={ data.blocked_seats } onChange={ (event) => onSeatsChange(event, 'blocked_seats') } />
121
+ </>
122
+ ) }
123
+
124
+ { type === 'free' && (
125
+ <>
126
+ { t('operator_routes.manage.seats.available', { ns: 'common' }) }
127
+
128
+ <input type="number" name="available_seats" defaultValue={ data.available_seats } onChange={ (event) => onSeatsChange(event, 'available_seats') } />
129
+ </>
130
+ ) }
131
+ </div>
132
+ </Column>
133
+ </>
134
+ );
135
+ };
23
136
 
24
137
  const Container = styled.div`
25
138
  display: flex;
26
139
  gap: 15px;
27
140
  `;
28
141
 
142
+ const Column = styled.div`
143
+ & > div:first-of-type {
144
+ margin-bottom: 15px;
145
+ }
146
+
147
+ @media (min-width: 540px) {
148
+ & > div:first-of-type {
149
+ margin-bottom: 0;
150
+ }
151
+ }
152
+ `;
153
+
29
154
  export default Seating;
package/Template.tsx CHANGED
@@ -3,7 +3,7 @@ import { TFunction } from 'i18next';
3
3
  import styled from 'styled-components';
4
4
  import { RiEyeFill } from 'react-icons/ri';
5
5
  import { Button, Modal } from '@autobusal/common';
6
- import { GetSettings } from '@autobusal/providers/services';
6
+ import { useGetSettings } from '@autobusal/providers/services';
7
7
 
8
8
  interface Props {
9
9
  type?: string
@@ -13,7 +13,7 @@ interface Props {
13
13
  const Template = ({ type, t }: Props): JSX.Element => {
14
14
  const [ show, setShow ] = useState<boolean>(false);
15
15
 
16
- const { data } = GetSettings();
16
+ const { data } = useGetSettings();
17
17
 
18
18
  if (!type) {
19
19
  return (
@@ -6,7 +6,7 @@ import { success } from '@autobusal/utilities';
6
6
  import Countries from './Countries';
7
7
  import { filterCountries } from './utilities';
8
8
  import { TransitingData } from '@autobusal/providers/types/routes';
9
- import { GetTransiting, PostTransiting, DeleteTransiting } from './services';
9
+ import { useGetTransiting, usePostTransiting, useDeleteTransiting } from './services';
10
10
 
11
11
  interface Props {
12
12
  url: string
@@ -24,11 +24,11 @@ const Manage = ({ url, t }: Props): JSX.Element => {
24
24
 
25
25
  const { data: CountriesData, isLoading } = useCountries('available');
26
26
 
27
- const { data, refetch } = GetTransiting(id);
27
+ const { data, isFetching, refetch } = useGetTransiting(id);
28
28
 
29
- const { mutate: Update, isPending: isPendingSave } = PostTransiting(id);
29
+ const { mutate: Update, isPending: isPendingSave } = usePostTransiting(id);
30
30
 
31
- const { mutate: Delete, isPending: isPendingDelete } = DeleteTransiting(id);
31
+ const { mutate: Delete, isPending: isPendingDelete } = useDeleteTransiting(id);
32
32
 
33
33
  if (id === 0) {
34
34
  return <Navigate to={ url } />;
@@ -79,6 +79,7 @@ const Manage = ({ url, t }: Props): JSX.Element => {
79
79
  value: 0,
80
80
  rules: 'required|min:1'
81
81
  }] }
82
+ fetching={ isFetching }
82
83
  pending={ isPendingSave || isPendingDelete }
83
84
  t={ t }
84
85
  actions={ [
@@ -2,7 +2,7 @@ import { UseMutationResult, UseSuspenseQueryResult, useMutation, useSuspenseQuer
2
2
  import { apiClient } from '@autobusal/providers';
3
3
  import { RouteData, TransitingData } from '@autobusal/providers/types/routes';
4
4
 
5
- export const GetTransiting = (id: number): UseSuspenseQueryResult<RouteData> => (
5
+ export const useGetTransiting = (id: number): UseSuspenseQueryResult<RouteData> => (
6
6
  useSuspenseQuery({
7
7
  queryKey: ['operator-transiting', { id }],
8
8
  queryFn: async () => (
@@ -17,7 +17,7 @@ export const GetTransiting = (id: number): UseSuspenseQueryResult<RouteData> =>
17
17
  })
18
18
  );
19
19
 
20
- export const PostTransiting = (id: number): UseMutationResult<void, Error, TransitingData, unknown> => (
20
+ export const usePostTransiting = (id: number): UseMutationResult<void, Error, TransitingData, unknown> => (
21
21
  useMutation({
22
22
  mutationKey: ['operator-transiting-save', { id }],
23
23
  mutationFn: async (data: TransitingData) => (
@@ -33,7 +33,7 @@ export const PostTransiting = (id: number): UseMutationResult<void, Error, Trans
33
33
  })
34
34
  );
35
35
 
36
- export const DeleteTransiting = (id: number): UseMutationResult<void, Error, number, unknown> => (
36
+ export const useDeleteTransiting = (id: number): UseMutationResult<void, Error, number, unknown> => (
37
37
  useMutation({
38
38
  mutationKey: ['operator-transiting-delete'],
39
39
  mutationFn: async (countryId: number) => (
@@ -2,7 +2,7 @@ import { TFunction } from 'i18next';
2
2
  import { useParams, Navigate } from 'react-router-dom';
3
3
  import { Meta, BackWithTitle, Table, Row } from '@autobusal/common';
4
4
  import { usePage } from '@autobusal/hooks';
5
- import { GetUnavailableDates, DeleteUnavailable } from './services';
5
+ import { useGetUnavailableDates, useDeleteUnavailable } from './services';
6
6
 
7
7
  interface Props {
8
8
  url: string
@@ -18,9 +18,9 @@ const Browse = ({ url, t }: Props): JSX.Element => {
18
18
 
19
19
  usePage('routes');
20
20
 
21
- const { data, isLoading, isFetching, refetch } = GetUnavailableDates(id);
21
+ const { data, isLoading, isFetching, refetch } = useGetUnavailableDates(id);
22
22
 
23
- const { mutate: Delete } = DeleteUnavailable(id);
23
+ const { mutate: Delete } = useDeleteUnavailable(id);
24
24
 
25
25
  if (id === 0) {
26
26
  return <Navigate to={ url } />;
@@ -4,7 +4,7 @@ import { Meta, BackWithTitle, Viewer } from '@autobusal/common';
4
4
  import { usePage } from '@autobusal/hooks';
5
5
  import { success } from '@autobusal/utilities';
6
6
  import { UnavailableData } from '@autobusal/providers/types/routes';
7
- import { GetUnavailable, PostUnavailable, DeleteUnavailable } from './services';
7
+ import { useGetUnavailable, usePostUnavailable, useDeleteUnavailable } from './services';
8
8
 
9
9
  interface Props {
10
10
  url: string
@@ -23,11 +23,11 @@ const Manage = ({ url, t }: Props): JSX.Element => {
23
23
 
24
24
  const navigate = useNavigate();
25
25
 
26
- const { data } = GetUnavailable(routeId, id);
26
+ const { data, isFetching } = useGetUnavailable(routeId, id);
27
27
 
28
- const { mutate: Update, isPending: isPendingSave } = PostUnavailable(routeId, id);
28
+ const { mutate: Update, isPending: isPendingSave } = usePostUnavailable(routeId, id);
29
29
 
30
- const { mutate: Delete, isPending: isPendingDelete } = DeleteUnavailable(routeId);
30
+ const { mutate: Delete, isPending: isPendingDelete } = useDeleteUnavailable(routeId);
31
31
 
32
32
  if (routeId === 0) {
33
33
  return <Navigate to={ url } />;
@@ -76,6 +76,7 @@ const Manage = ({ url, t }: Props): JSX.Element => {
76
76
  value: unavailable?.end_inactive,
77
77
  rules: 'required'
78
78
  }] }
79
+ fetching={ isFetching }
79
80
  pending={ isPendingSave || isPendingDelete }
80
81
  t={ t }
81
82
  actions={ [
@@ -3,7 +3,7 @@ import { apiClient } from '@autobusal/providers';
3
3
  import { RouteData } from '@autobusal/providers/types/routes';
4
4
  import { UnavailableData } from '@autobusal/providers/types/routes';
5
5
 
6
- export const GetUnavailableDates = (id: number): UseQueryResult<RouteData> => (
6
+ export const useGetUnavailableDates = (id: number): UseQueryResult<RouteData> => (
7
7
  useQuery({
8
8
  queryKey: ['operators-unavailable', { id }],
9
9
  queryFn: async () => (
@@ -18,7 +18,7 @@ export const GetUnavailableDates = (id: number): UseQueryResult<RouteData> => (
18
18
  })
19
19
  );
20
20
 
21
- export const GetUnavailable = (routeId: number, id: number): UseSuspenseQueryResult<RouteData> => (
21
+ export const useGetUnavailable = (routeId: number, id: number): UseSuspenseQueryResult<RouteData> => (
22
22
  useSuspenseQuery({
23
23
  queryKey: ['operator-unavailable-manage', { routeId, id }],
24
24
  queryFn: async () => (
@@ -36,7 +36,7 @@ export const GetUnavailable = (routeId: number, id: number): UseSuspenseQueryRes
36
36
  })
37
37
  );
38
38
 
39
- export const PostUnavailable = (routeId: number, id: number): UseMutationResult<void, Error, UnavailableData, unknown> => (
39
+ export const usePostUnavailable = (routeId: number, id: number): UseMutationResult<void, Error, UnavailableData, unknown> => (
40
40
  useMutation({
41
41
  mutationKey: ['unavailable-operator-save', { routeId, id }],
42
42
  mutationFn: async (data: UnavailableData) => (
@@ -53,7 +53,7 @@ export const PostUnavailable = (routeId: number, id: number): UseMutationResult<
53
53
  })
54
54
  );
55
55
 
56
- export const DeleteUnavailable = (routeId: number): UseMutationResult<void, Error, number, unknown> => (
56
+ export const useDeleteUnavailable = (routeId: number): UseMutationResult<void, Error, number, unknown> => (
57
57
  useMutation({
58
58
  mutationKey: ['unavailable-operator-delete', { routeId }],
59
59
  mutationFn: async (id: number) => (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobusal/operator-routes",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "type": "module",
5
5
  "main": "index.ts"
6
6
  }
package/services.ts CHANGED
@@ -3,8 +3,9 @@ import { apiClient } from '@autobusal/providers';
3
3
  import { PaginationData } from '@autobusal/providers/types/pagination';
4
4
  import { RouteData } from '@autobusal/providers/types/routes';
5
5
  import { TableParamsData } from '@autobusal/providers/types/other';
6
+ import { SeatingOptionsData } from './types';
6
7
 
7
- export const GetRoutes = (params: TableParamsData): UseQueryResult<PaginationData<RouteData>> => (
8
+ export const useGetRoutes = (params: TableParamsData): UseQueryResult<PaginationData<RouteData>> => (
8
9
  useQuery({
9
10
  queryKey: ['operator-routes', params],
10
11
  queryFn: async () => (
@@ -17,7 +18,7 @@ export const GetRoutes = (params: TableParamsData): UseQueryResult<PaginationDat
17
18
  })
18
19
  );
19
20
 
20
- export const GetRoute = (id: number): UseSuspenseQueryResult<RouteData> => (
21
+ export const useGetRoute = (id: number): UseSuspenseQueryResult<RouteData> => (
21
22
  useSuspenseQuery({
22
23
  queryKey: ['operator-routes-manage', { id }],
23
24
  queryFn: async () => {
@@ -36,7 +37,7 @@ export const GetRoute = (id: number): UseSuspenseQueryResult<RouteData> => (
36
37
  })
37
38
  );
38
39
 
39
- export const PostRoute = (id: number, seating: string): UseMutationResult<void, Error, RouteData, unknown> => (
40
+ export const usePostRoute = (id: number, seating?: SeatingOptionsData): UseMutationResult<void, Error, RouteData, unknown> => (
40
41
  useMutation({
41
42
  mutationKey: ['operator-routes-save', { id, seating }],
42
43
  mutationFn: async (data: RouteData) => (
@@ -44,7 +45,7 @@ export const PostRoute = (id: number, seating: string): UseMutationResult<void,
44
45
  .post('/api/routes/operator/update', {
45
46
  ...data,
46
47
  id,
47
- seating,
48
+ ...seating,
48
49
  features: JSON.stringify(data.features),
49
50
  drivers: JSON.stringify(data.drivers)
50
51
  })
@@ -55,7 +56,7 @@ export const PostRoute = (id: number, seating: string): UseMutationResult<void,
55
56
  })
56
57
  );
57
58
 
58
- export const DeleteRoute = (): UseMutationResult<void, Error, number, unknown> => (
59
+ export const useDeleteRoute = (): UseMutationResult<void, Error, number, unknown> => (
59
60
  useMutation({
60
61
  mutationKey: ['operator-routes-delete'],
61
62
  mutationFn: async (id: number) => (
@@ -70,7 +71,7 @@ export const DeleteRoute = (): UseMutationResult<void, Error, number, unknown> =
70
71
  })
71
72
  );
72
73
 
73
- export const PostCopy = (id: number, reverse?: boolean): UseMutationResult<RouteData> => (
74
+ export const usePostCopy = (id: number, reverse?: boolean): UseMutationResult<RouteData> => (
74
75
  useMutation({
75
76
  mutationKey: [`operator-routes-copy${ reverse && '-reverse' }`, { id }],
76
77
  mutationFn: async () => (
package/types.ts ADDED
@@ -0,0 +1,6 @@
1
+ export interface SeatingOptionsData {
2
+ seating: string
3
+ bus_id?: number
4
+ blocked_seats?: number
5
+ available_seats?: number
6
+ }
package/utilities.tsx CHANGED
@@ -2,7 +2,6 @@ import { TFunction } from 'i18next';
2
2
  import { IoGlobeOutline } from 'react-icons/io5';
3
3
  import { getLanguages } from '@autobusal/utilities';
4
4
  import { DropdownData } from '@autobusal/providers/types/other';
5
- import { TripData } from '@autobusal/providers/types/routes';
6
5
  import { ViewData } from '@autobusal/common/Viewer/types';
7
6
 
8
7
  export const getType = (id: number, value: string, t: TFunction<'normal'>): ViewData => {
@@ -53,45 +52,6 @@ export const getTemplates = (t: TFunction<'normal'>): DropdownData[] => ([
53
52
  }
54
53
  ]);
55
54
 
56
- export const getBusType = (buses: DropdownData[], seating: string, t: TFunction<'normal'>, value?: number): ViewData => {
57
- if (seating === 'free') {
58
- return {
59
- label: t('operator_routes.manage.bus.reservation', { ns: 'common' }),
60
- name: 'bus_id',
61
- type: 'display',
62
- value: t('operator_routes.manage.bus.free', { ns: 'common' })
63
- };
64
- }
65
-
66
- return {
67
- label: t('operator_routes.manage.bus.title', { ns: 'common' }),
68
- name: 'bus_id',
69
- type: 'select',
70
- values: buses,
71
- value,
72
- rules: 'required|min:1'
73
- };
74
- };
75
-
76
- export const getSeatingType = (seating: string, t: TFunction<'normal'>, trip?: TripData): ViewData => {
77
- if (seating === 'free') {
78
- return {
79
- label: t('operator_routes.manage.seats.available', { ns: 'common' }),
80
- name: 'available_seats',
81
- type: 'number',
82
- value: trip?.available_seats,
83
- rules: 'required|min:1'
84
- };
85
- }
86
-
87
- return {
88
- label: t('operator_routes.manage.seats.blocked', { ns: 'common' }),
89
- name: 'blocked_seats',
90
- type: 'number',
91
- value: trip?.blocked_seats
92
- };
93
- };
94
-
95
55
  export const getTransiting = (id: number, t: TFunction<'normal'>, type?: string): ViewData => {
96
56
  if (type == 'national') {
97
57
  return {