Skip to content

Commit 378a5c9

Browse files
authored
Merge branch 'development' into fix/th-283-fix-env-for-s3
2 parents c480264 + 8412e44 commit 378a5c9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+929
-165
lines changed

backend/src/packages/map/libs/types/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ export {
22
type Client,
33
type Distance,
44
} from '@googlemaps/google-maps-services-js';
5+
export {
6+
type OrderCalculatePriceRequestDto,
7+
type OrderCalculatePriceResponseDto,
8+
} from 'shared/build/index.js';

backend/src/packages/map/map.service.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { TravelMode } from './libs/enums/enums.js';
22
import { convertMetersToKm } from './libs/helpers/helpers.js';
3-
import { type Client, type Distance } from './libs/types/types.js';
3+
import {
4+
type Client,
5+
type Distance,
6+
type OrderCalculatePriceRequestDto,
7+
type OrderCalculatePriceResponseDto,
8+
} from './libs/types/types.js';
49

510
class MapService {
611
private client: Client;
@@ -31,19 +36,15 @@ class MapService {
3136
}
3237

3338
public async getPriceByDistance({
34-
startPoint,
35-
endPoint,
39+
startAddress,
40+
endAddress,
3641
pricePerKm,
37-
}: {
38-
startPoint: string;
39-
endPoint: string;
40-
pricePerKm: number;
41-
}): Promise<number> {
42-
const distance = await this.getDistance(startPoint, endPoint);
42+
}: OrderCalculatePriceRequestDto): Promise<OrderCalculatePriceResponseDto> {
43+
const distance = await this.getDistance(startAddress, endAddress);
4344
const km = convertMetersToKm(distance.value);
4445
const orderPrice = (pricePerKm * km).toFixed(2);
4546

46-
return Number(orderPrice);
47+
return { price: Number(orderPrice) };
4748
}
4849
}
4950

backend/src/packages/orders/libs/types/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ type OrderDatabaseModel = InferModel<DatabaseSchema['orders']>;
77
export {
88
type DriverInfo,
99
type Id,
10+
type OrderCalculatePriceRequestDto,
11+
type OrderCalculatePriceResponseDto,
1012
type OrderCreateRequestDto,
1113
type OrderEntity,
1214
type OrderFindByIdResponseDto,

backend/src/packages/orders/order.controller.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import {
66
} from '~/libs/packages/controller/controller.js';
77
import { HttpCode } from '~/libs/packages/http/http.js';
88
import { type ILogger } from '~/libs/packages/logger/logger.js';
9+
import { type MapService } from '~/packages/map/map.service.js';
910
import { type OrderService } from '~/packages/orders/order.service.js';
1011

1112
import { AuthStrategy } from '../auth/auth.js';
1213
import { type UserEntityObjectWithGroupT } from '../users/users.js';
1314
import { OrdersApiPath } from './libs/enums/enums.js';
1415
import {
1516
type Id,
17+
type OrderCalculatePriceRequestDto,
1618
type OrderCreateRequestDto,
1719
type OrderResponseDto,
1820
type OrderUpdateRequestDto,
@@ -200,16 +202,21 @@ import {
200202
class OrderController extends Controller {
201203
private orderService: OrderService;
202204

205+
private mapService: MapService;
206+
203207
public constructor({
204208
logger,
205209
orderService,
210+
mapService,
206211
}: {
207212
logger: ILogger;
208213
orderService: OrderService;
214+
mapService: MapService;
209215
}) {
210216
super(logger, ApiPath.ORDERS);
211217

212218
this.orderService = orderService;
219+
this.mapService = mapService;
213220

214221
this.addRoute({
215222
path: OrdersApiPath.ROOT,
@@ -291,6 +298,19 @@ class OrderController extends Controller {
291298
}>,
292299
),
293300
});
301+
302+
this.addRoute({
303+
path: OrdersApiPath.CALCULATE_PRICE,
304+
method: 'POST',
305+
authStrategy: AuthStrategy.INJECT_USER,
306+
handler: (options) =>
307+
this.calculatePrice(
308+
options as ApiHandlerOptions<{
309+
body: OrderCalculatePriceRequestDto;
310+
user: UserEntityObjectWithGroupT | null;
311+
}>,
312+
),
313+
});
294314
}
295315

296316
/**
@@ -574,6 +594,20 @@ class OrderController extends Controller {
574594
}),
575595
};
576596
}
597+
598+
private async calculatePrice(
599+
options: ApiHandlerOptions<{
600+
body: OrderCalculatePriceRequestDto;
601+
user: UserEntityObjectWithGroupT | null;
602+
}>,
603+
): Promise<ApiHandlerResponse> {
604+
return {
605+
status: HttpCode.OK,
606+
payload: await this.mapService.getPriceByDistance({
607+
...options.body,
608+
}),
609+
};
610+
}
577611
}
578612

579613
export { OrderController };

backend/src/packages/orders/orders.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { logger } from '~/libs/packages/logger/logger.js';
33

44
import { businessService } from '../business/business.js';
55
import { driverService } from '../drivers/drivers.js';
6+
import { mapService } from '../map/map.js';
67
import { shiftService } from '../shifts/shift.js';
78
import { truckService } from '../trucks/trucks.js';
89
import { userService } from '../users/users.js';
@@ -22,6 +23,7 @@ const orderService = new OrderService({
2223
const orderController = new OrderController({
2324
logger,
2425
orderService,
26+
mapService,
2527
});
2628

2729
export { orderController, orderService };

frontend/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
"@fortawesome/fontawesome-svg-core": "6.4.2",
2121
"@fortawesome/free-solid-svg-icons": "6.4.2",
2222
"@fortawesome/react-fontawesome": "0.2.0",
23-
"@googlemaps/react-wrapper": "1.1.35",
2423
"@hookform/resolvers": "2.9.11",
24+
"@react-google-maps/api": "2.19.2",
2525
"@reduxjs/toolkit": "1.9.3",
2626
"@vitejs/plugin-react": "4.0.4",
2727
"@rollup/pluginutils": "5.0.4",
@@ -32,7 +32,6 @@
3232
"react": "18.2.0",
3333
"react-dom": "18.2.0",
3434
"react-dropzone": "14.2.3",
35-
"react-google-autocomplete": "2.7.3",
3635
"react-hook-form": "7.43.5",
3736
"react-redux": "8.1.2",
3837
"react-router-dom": "6.8.2",

frontend/src/libs/components/components.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export { Spinner } from './spinner/spinner.js';
2929
export { StarRating } from './star-rating/star-rating.jsx';
3030
export { Table } from './table/table.js';
3131
export { Toggle } from './toggle/toggle.js';
32+
export { TowTruckCard } from './tow-truck-card/tow-truck-card.js';
3233
export { TruckFilter } from './truck-filter/truck-filter.js';
3334
export { Provider as StoreProvider } from 'react-redux';
3435
export { Outlet as RouterOutlet } from 'react-router-dom';

frontend/src/libs/components/form/form.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@ import { FileInput } from '../file-input/file-input.js';
2020
import { fileInputDefaultsConfig } from '../file-input/libs/config/config.js';
2121
import { type FileFormType } from '../file-input/libs/types/types.js';
2222
import { Input } from '../input/input.jsx';
23+
import { LocationInput } from '../location-input/location-input.js';
2324
import styles from './styles.module.scss';
2425

2526
type Properties<T extends FieldValues> = {
2627
fields: FormField<T>[];
2728
defaultValues: DeepPartial<T>;
2829
validationSchema: ValidationSchema;
2930
btnLabel?: string;
31+
isDisabled?: boolean;
3032
onSubmit: (payload: T) => void;
33+
additionalFields?: JSX.Element;
3134
};
3235

3336
type Parameters<T extends FieldValues = FieldValues> = {
@@ -45,10 +48,10 @@ const renderField = <T extends FieldValues = FieldValues>({
4548
setError,
4649
clearErrors,
4750
}: Parameters<T>): JSX.Element => {
48-
const { options, name, label } = field;
49-
5051
switch (field.type) {
5152
case 'dropdown': {
53+
const { options, name, label } = field;
54+
5255
return (
5356
<DropdownInput
5457
options={options ?? []}
@@ -65,7 +68,10 @@ const renderField = <T extends FieldValues = FieldValues>({
6568
case 'password': {
6669
return <Input {...field} control={control} errors={errors} />;
6770
}
71+
6872
case 'file': {
73+
const { label } = field;
74+
6975
return (
7076
<FileInput
7177
setError={setError as unknown as UseFormSetError<FileFormType>}
@@ -80,6 +86,10 @@ const renderField = <T extends FieldValues = FieldValues>({
8086
/>
8187
);
8288
}
89+
case 'location': {
90+
return <LocationInput {...field} control={control} errors={errors} />;
91+
}
92+
8393
default: {
8494
return <Input {...field} control={control} errors={errors} />;
8595
}
@@ -91,6 +101,8 @@ const Form = <T extends FieldValues = FieldValues>({
91101
defaultValues,
92102
validationSchema,
93103
btnLabel,
104+
additionalFields,
105+
isDisabled,
94106
onSubmit,
95107
}: Properties<T>): JSX.Element => {
96108
const { control, errors, handleSubmit, setError, clearErrors } =
@@ -117,7 +129,13 @@ const Form = <T extends FieldValues = FieldValues>({
117129
return (
118130
<form onSubmit={handleFormSubmit} className={styles.form} noValidate>
119131
{createInputs()}
120-
<Button type="submit" label={btnLabel ?? 'Submit'} isFullWidth />
132+
{additionalFields}
133+
<Button
134+
type="submit"
135+
label={btnLabel ?? 'Submit'}
136+
isDisabled={isDisabled}
137+
isFullWidth
138+
/>
121139
</form>
122140
);
123141
};

frontend/src/libs/components/input/input.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import {
55
type FieldValues,
66
} from 'react-hook-form';
77

8+
import { type InputType } from '~/libs/enums/enums.js';
89
import { IconName } from '~/libs/enums/icon-name.enum.js';
910
import { getValidClassNames } from '~/libs/helpers/helpers.js';
1011
import {
1112
useCallback,
1213
useFormController,
1314
useState,
1415
} from '~/libs/hooks/hooks.js';
16+
import { type ValueOf } from '~/libs/types/types.js';
1517

1618
import { Icon } from '../components.js';
1719
import styles from './styles.module.scss';
@@ -22,7 +24,7 @@ type Properties<T extends FieldValues> = {
2224
label?: string;
2325
name: FieldPath<T>;
2426
placeholder?: string;
25-
type?: 'text' | 'email' | 'password' | 'number' | 'dropdown' | 'file';
27+
type?: ValueOf<typeof InputType>;
2628
isDisabled?: boolean;
2729
min?: number;
2830
max?: number;

frontend/src/libs/components/input/styles.module.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ $error-message-height: calc($error-font-size * $line-height-coefficient);
77
.inputComponentWrapper {
88
display: flex;
99
flex-direction: column;
10-
max-width: 327px;
1110
color: $grey-dark;
1211
font-weight: $font-weight-semibold;
1312
font-size: 16px;

0 commit comments

Comments
 (0)