From 6abbae79896768fdb4b2499309f34bd68ede81ac Mon Sep 17 00:00:00 2001 From: Keyur Doshi Date: Sat, 25 Oct 2025 18:19:03 +0530 Subject: [PATCH 1/4] New feature of adding multiple vehicles added --- docs/challengeSolutions.md | 2 +- openapi-spec/crapi-openapi-spec.json | 4 +- .../crAPI.postman_collection.json | 6 +- .../src/resources/crapi-openapi-spec.json | 4 +- .../java/com/crapi/constant/UserMessage.java | 6 +- .../crapi/controller/VehicleController.java | 23 +++- .../Impl/UserRegistrationServiceImpl.java | 4 +- .../service/Impl/VehicleServiceImpl.java | 33 ++++- .../com/crapi/service/VehicleService.java | 4 +- .../main/java/com/crapi/utils/MailBody.java | 4 +- .../service/Impl/VehicleServiceImplTest.java | 16 +-- services/web/src/actions/vehicleActions.ts | 10 ++ .../src/components/addVehicle/addVehicle.css | 56 ++++++++ .../src/components/addVehicle/addVehicle.tsx | 124 ++++++++++++++++++ .../src/components/dashboard/dashboard.tsx | 13 +- services/web/src/components/layout/layout.tsx | 6 +- .../verifyVehicle/verifyVehicle.tsx | 85 ------------ services/web/src/constants/APIConstant.ts | 3 +- services/web/src/constants/actionTypes.ts | 1 + services/web/src/constants/messages.ts | 1 + .../addVehicle.js} | 36 +++-- services/web/src/sagas/vehicleSaga.ts | 40 +++++- 22 files changed, 345 insertions(+), 136 deletions(-) create mode 100644 services/web/src/components/addVehicle/addVehicle.css create mode 100644 services/web/src/components/addVehicle/addVehicle.tsx delete mode 100644 services/web/src/components/verifyVehicle/verifyVehicle.tsx rename services/web/src/containers/{verifyVehicle/verifyVehicle.js => addVehicle/addVehicle.js} (65%) diff --git a/docs/challengeSolutions.md b/docs/challengeSolutions.md index 9c606fea..c512a623 100644 --- a/docs/challengeSolutions.md +++ b/docs/challengeSolutions.md @@ -14,7 +14,7 @@ Verify the ports of the container by running the following command : `docker ps` #### Detailed solution 1. Login to the application from http://localhost:8888/login -2. From the *Dashboard*, choose *Add a Vehicle* and add the vehicle by providing the VIN and pincode received in Mailhog mailbox after Signup or by reinitiating from *Dashboard* page. +2. From the *Dashboard*, choose *Add Vehicle* and add the vehicle by providing the VIN and pincode received in Mailhog mailbox after Signup or by reinitiating from *Dashboard* page. 3. After the vehicle details are verified successful, the vehicle will get added and then be populated in the *Dashboard* page. 4. Observe the request sent when we click *Refresh Location*. It can be seen that the endpoint is in the format `/identity/api/v2/vehicle//location`. 5. Sensitive information like latitude and longitude are provided back in the response for the endpoint. Send the request to *Repeater* for later purpose. diff --git a/openapi-spec/crapi-openapi-spec.json b/openapi-spec/crapi-openapi-spec.json index a33fef2f..87079b5b 100644 --- a/openapi-spec/crapi-openapi-spec.json +++ b/openapi-spec/crapi-openapi-spec.json @@ -1009,9 +1009,9 @@ }, "parameters" : [ ] }, - "/identity/api/v2/vehicle/add_vehicle" : { + "/identity/api/v2/vehicle/verify_vehicle" : { "post" : { - "operationId" : "add_vehicle", + "operationId" : "verify_vehicle", "summary" : "Add the user vehicle", "tags" : [ "Identity / Vehicle" ], "security" : [ { diff --git a/postman_collections/crAPI.postman_collection.json b/postman_collections/crAPI.postman_collection.json index 582fb11c..958017a9 100644 --- a/postman_collections/crAPI.postman_collection.json +++ b/postman_collections/crAPI.postman_collection.json @@ -775,7 +775,7 @@ "uid": "13872198-c0ef62ef-8ca0-4eaf-a3d8-44c1aa41a407" }, { - "name": "Add Vehicle from Mail", + "name": "Verify Vehicle from Mail", "event": [ { "listen": "test", @@ -850,7 +850,7 @@ "raw": "{\"vin\": \"{{VIN}}\", \"pincode\": \"{{PIN}}\"}" }, "url": { - "raw": "{{url}}/identity/api/v2/vehicle/add_vehicle", + "raw": "{{url}}/identity/api/v2/vehicle/verify_vehicle", "host": [ "{{url}}" ], @@ -859,7 +859,7 @@ "api", "v2", "vehicle", - "add_vehicle" + "verify_vehicle" ] } }, diff --git a/services/chatbot/src/resources/crapi-openapi-spec.json b/services/chatbot/src/resources/crapi-openapi-spec.json index a33fef2f..87079b5b 100644 --- a/services/chatbot/src/resources/crapi-openapi-spec.json +++ b/services/chatbot/src/resources/crapi-openapi-spec.json @@ -1009,9 +1009,9 @@ }, "parameters" : [ ] }, - "/identity/api/v2/vehicle/add_vehicle" : { + "/identity/api/v2/vehicle/verify_vehicle" : { "post" : { - "operationId" : "add_vehicle", + "operationId" : "verify_vehicle", "summary" : "Add the user vehicle", "tags" : [ "Identity / Vehicle" ], "security" : [ { diff --git a/services/identity/src/main/java/com/crapi/constant/UserMessage.java b/services/identity/src/main/java/com/crapi/constant/UserMessage.java index f1eead17..d8c78793 100644 --- a/services/identity/src/main/java/com/crapi/constant/UserMessage.java +++ b/services/identity/src/main/java/com/crapi/constant/UserMessage.java @@ -55,12 +55,12 @@ public class UserMessage { public static final String PASSWORD_GOT_RESET = "Password reset successful."; public static final String VEHICLE_MODEL_IS_NOT_AVAILABLE = "Sorry we don't have Vehicle model for this company. Please select other.."; - public static final String VEHICLE_SAVED_SUCCESSFULLY = "Vehicle save successfully.."; + public static final String VEHICLE_SAVED_SUCCESSFULLY = "Vehicle saved successfully!"; public static final String VEHICLE_NOT_FOUND = "Failed to get Vehicles"; public static final String VEHICLE_DETAILS_SENT_TO_EMAIL = - "Your newly purchased Vehicle Details have been sent to you email address. If you have used example.com email, check your email using the MailHog web portal. "; + "Your newly purchased vehicle details have been sent to you email address. Verify them to add your vehicle. [If you have used example.com email, check your email using the MailHog web portal]"; public static final String CHANGE_EMAIL_MESSAGE = - "The token has been sent to your email. If you have used example.com email, check your email using the MailHog web portal. "; + "The token has been sent to your email. If you have used example.com email, check your email using the MailHog web portal."; public static final String CHANGE_EMAIL_OLD_USEREMAIL_NOT_FOUND_MESSAGE = "Sorry, we didn't find any user for "; public static final String INVALID_EMAIL_TOKEN = "Sorry, Token did't match"; diff --git a/services/identity/src/main/java/com/crapi/controller/VehicleController.java b/services/identity/src/main/java/com/crapi/controller/VehicleController.java index 9d8ce88e..37be2b67 100644 --- a/services/identity/src/main/java/com/crapi/controller/VehicleController.java +++ b/services/identity/src/main/java/com/crapi/controller/VehicleController.java @@ -44,14 +44,27 @@ public class VehicleController { * @param vehicleDetails * @return response of success and failure message save vehicle Details for user in database */ - @PostMapping("/vehicle/add_vehicle") + @PostMapping("/vehicle/create_vehicle") + public ResponseEntity createVehicle(HttpServletRequest request) { + CRAPIResponse createVehicleResponse = vehicleService.createVehicle(request); + if (createVehicleResponse != null && createVehicleResponse.getStatus() == 200) { + return ResponseEntity.status(HttpStatus.OK).body(createVehicleResponse); + } + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(createVehicleResponse); + } + + /** + * @param vehicleDetails + * @return response of success and failure message save vehicle Details for user in database + */ + @PostMapping("/vehicle/verify_vehicle") public ResponseEntity addVehicle( @Valid @RequestBody VehicleForm vehicleDetails, HttpServletRequest request) { - CRAPIResponse checkVehicleResponse = vehicleService.checkVehicle(vehicleDetails, request); - if (checkVehicleResponse != null && checkVehicleResponse.getStatus() == 200) { - return ResponseEntity.status(HttpStatus.OK).body(checkVehicleResponse); + CRAPIResponse verifyVehicleResponse = vehicleService.verifyVehicle(vehicleDetails, request); + if (verifyVehicleResponse != null && verifyVehicleResponse.getStatus() == 200) { + return ResponseEntity.status(HttpStatus.OK).body(verifyVehicleResponse); } - return ResponseEntity.status(HttpStatus.FORBIDDEN).body(checkVehicleResponse); + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(verifyVehicleResponse); } /** diff --git a/services/identity/src/main/java/com/crapi/service/Impl/UserRegistrationServiceImpl.java b/services/identity/src/main/java/com/crapi/service/Impl/UserRegistrationServiceImpl.java index f0b19aee..5d73e62c 100644 --- a/services/identity/src/main/java/com/crapi/service/Impl/UserRegistrationServiceImpl.java +++ b/services/identity/src/main/java/com/crapi/service/Impl/UserRegistrationServiceImpl.java @@ -80,7 +80,7 @@ public CRAPIResponse registerUser(SignUpForm signUpRequest) { return new CRAPIResponse( UserMessage.NUMBER_ALREADY_REGISTERED + signUpRequest.getNumber(), 403); } - // check Number in database + // Check Email in database if (userRepository.existsByEmail(signUpRequest.getEmail())) { return new CRAPIResponse( UserMessage.EMAIL_ALREADY_REGISTERED + signUpRequest.getEmail(), 403); @@ -107,7 +107,7 @@ public CRAPIResponse registerUser(SignUpForm signUpRequest) { if (vehicleDetails != null) { smtpMailServer.sendMail( user.getEmail(), - MailBody.signupMailBody( + MailBody.newVehicleMailBody( vehicleDetails, (userDetails != null && userDetails.getName() != null ? userDetails.getName() diff --git a/services/identity/src/main/java/com/crapi/service/Impl/VehicleServiceImpl.java b/services/identity/src/main/java/com/crapi/service/Impl/VehicleServiceImpl.java index 9740d27b..0599a461 100644 --- a/services/identity/src/main/java/com/crapi/service/Impl/VehicleServiceImpl.java +++ b/services/identity/src/main/java/com/crapi/service/Impl/VehicleServiceImpl.java @@ -107,6 +107,35 @@ public VehicleDetails createVehicle() { 500); } + /** + * @param request + * @return CRAPIResponse after creating a new vehicle and assigning it to the current user + */ + @Transactional + @Override + public CRAPIResponse createVehicle(HttpServletRequest request) { + User user = null; + UserDetails userDetails = null; + VehicleDetails vehicleDetails = null; + + user = userService.getUserFromToken(request); + if (user == null) { + return new CRAPIResponse(UserMessage.TOKEN_VERIFICATION_MISSING, 401); + } + userDetails = userDetailsRepository.findByUser_id(user.getId()); + vehicleDetails = createVehicle(); + if (vehicleDetails != null) { + smtpMailServer.sendMail( + user.getEmail(), + MailBody.newVehicleMailBody( + vehicleDetails, + (userDetails != null && userDetails.getName() != null ? userDetails.getName() : "")), + "Your New Vehicle In crAPI"); + return new CRAPIResponse(UserMessage.VEHICLE_DETAILS_SENT_TO_EMAIL, 200); + } + return new CRAPIResponse(UserMessage.INTERNAL_SERVER_ERROR, 500); + } + /** * @param request * @return list of vehicle of user @@ -176,7 +205,7 @@ public VehicleLocationResponse getVehicleLocation(UUID carId) { */ @Transactional @Override - public CRAPIResponse checkVehicle(VehicleForm vehicleForm, HttpServletRequest request) { + public CRAPIResponse verifyVehicle(VehicleForm vehicleForm, HttpServletRequest request) { VehicleDetails checkVehicle = null; User user = null; checkVehicle = vehicleDetailsRepository.findByVin(vehicleForm.getVin()); @@ -219,7 +248,7 @@ public CRAPIResponse sendVehicleDetails(HttpServletRequest request) { } smtpMailServer.sendMail( user.getEmail(), - MailBody.signupMailBody( + MailBody.newVehicleMailBody( vehicleDetails, (userDetails != null && userDetails.getName() != null ? userDetails.getName() : "")), "Welcome to crAPI"); diff --git a/services/identity/src/main/java/com/crapi/service/VehicleService.java b/services/identity/src/main/java/com/crapi/service/VehicleService.java index 967247fc..23263f99 100644 --- a/services/identity/src/main/java/com/crapi/service/VehicleService.java +++ b/services/identity/src/main/java/com/crapi/service/VehicleService.java @@ -28,11 +28,13 @@ public interface VehicleService { VehicleDetails createVehicle(); + CRAPIResponse createVehicle(HttpServletRequest request); + List getVehicleDetails(HttpServletRequest request); VehicleLocationResponse getVehicleLocation(UUID carId); - CRAPIResponse checkVehicle(VehicleForm vehicleDetails, HttpServletRequest request); + CRAPIResponse verifyVehicle(VehicleForm vehicleDetails, HttpServletRequest request); CRAPIResponse sendVehicleDetails(HttpServletRequest request); } diff --git a/services/identity/src/main/java/com/crapi/utils/MailBody.java b/services/identity/src/main/java/com/crapi/utils/MailBody.java index 28090f5c..79267eb2 100644 --- a/services/identity/src/main/java/com/crapi/utils/MailBody.java +++ b/services/identity/src/main/java/com/crapi/utils/MailBody.java @@ -50,13 +50,13 @@ public static String otpMailBody(Otp otp) { * @param name * @return Mail body for user Signup */ - public static String signupMailBody(VehicleDetails vehicleDetails, String name) { + public static String newVehicleMailBody(VehicleDetails vehicleDetails, String name) { String msgBody = "" + "Hi " + name + "," - + "

We are glad to have you on-board. Your newly purchased vehiche details are provided below. Please add it on your crAPI dashboard.

" + + "

We are glad to have you on-board with a new vehicle. Your newly purchased vehicle details are provided below. Please add it on your crAPI dashboard.

" + "

Your vehicle information is VIN: " + vehicleDetails.getVin() + " and Pincode: " diff --git a/services/identity/src/test/java/com/crapi/service/Impl/VehicleServiceImplTest.java b/services/identity/src/test/java/com/crapi/service/Impl/VehicleServiceImplTest.java index f4e62f17..1c7e298a 100644 --- a/services/identity/src/test/java/com/crapi/service/Impl/VehicleServiceImplTest.java +++ b/services/identity/src/test/java/com/crapi/service/Impl/VehicleServiceImplTest.java @@ -181,7 +181,7 @@ public void getVehicleLocationNotFoundWhenVehicleDetailsOwnerIsNull() { } @Test - public void checkVehicleSuccessFull() { + public void verifyVehicleSuccessFull() { VehicleForm vehicleForm = getDummyVehicleForm(); VehicleDetails vehicleDetails = getDummyVehicleDetails(); User user = getDummyUser(); @@ -191,14 +191,14 @@ public void checkVehicleSuccessFull() { .thenReturn(vehicleDetails); Mockito.when(userService.getUserFromToken(Mockito.any())).thenReturn(user); CRAPIResponse crapiAPIResponse = - vehicleService.checkVehicle(vehicleForm, getDummyHttpRequest()); + vehicleService.verifyVehicle(vehicleForm, getDummyHttpRequest()); Mockito.verify(vehicleDetailsRepository, Mockito.times(1)).save(Mockito.any()); Assertions.assertEquals(UserMessage.VEHICLE_SAVED_SUCCESSFULLY, crapiAPIResponse.getMessage()); Assertions.assertEquals(HttpStatus.OK.value(), crapiAPIResponse.getStatus()); } @Test - public void checkVehicleFailWhenPinCodeNotEqual() { + public void verifyVehicleFailWhenPinCodeNotEqual() { VehicleForm vehicleForm = getDummyVehicleForm(); VehicleDetails vehicleDetails = getDummyVehicleDetails(); User user = getDummyUser(); @@ -206,27 +206,27 @@ public void checkVehicleFailWhenPinCodeNotEqual() { .thenReturn(vehicleDetails); Mockito.when(userService.getUserFromToken(Mockito.any())).thenReturn(user); CRAPIResponse crapiAPIResponse = - vehicleService.checkVehicle(vehicleForm, getDummyHttpRequest()); + vehicleService.verifyVehicle(vehicleForm, getDummyHttpRequest()); Mockito.verify(vehicleDetailsRepository, Mockito.times(0)).save(Mockito.any()); Assertions.assertEquals(UserMessage.VEHICLE_ALREADY_CREATED, crapiAPIResponse.getMessage()); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), crapiAPIResponse.getStatus()); } @Test - public void checkVehicleFailWhenVehicleDetailsNotFound() { + public void verifyVehicleFailWhenVehicleDetailsNotFound() { VehicleForm vehicleForm = getDummyVehicleForm(); User user = getDummyUser(); Mockito.when(vehicleDetailsRepository.findByVin(Mockito.anyString())).thenReturn(null); Mockito.when(userService.getUserFromToken(Mockito.any())).thenReturn(user); CRAPIResponse crapiAPIResponse = - vehicleService.checkVehicle(vehicleForm, getDummyHttpRequest()); + vehicleService.verifyVehicle(vehicleForm, getDummyHttpRequest()); Mockito.verify(vehicleDetailsRepository, Mockito.times(0)).save(Mockito.any()); Assertions.assertEquals(UserMessage.VEHICLE_ALREADY_CREATED, crapiAPIResponse.getMessage()); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), crapiAPIResponse.getStatus()); } @Test - public void checkVehicleFailWhenUserNotFound() { + public void verifyVehicleFailWhenUserNotFound() { VehicleForm vehicleForm = getDummyVehicleForm(); VehicleDetails vehicleDetails = getDummyVehicleDetails(); vehicleDetails.setPincode(vehicleForm.getPincode()); @@ -234,7 +234,7 @@ public void checkVehicleFailWhenUserNotFound() { .thenReturn(vehicleDetails); Mockito.when(userService.getUserFromToken(Mockito.any())).thenReturn(null); CRAPIResponse crapiAPIResponse = - vehicleService.checkVehicle(vehicleForm, getDummyHttpRequest()); + vehicleService.verifyVehicle(vehicleForm, getDummyHttpRequest()); Mockito.verify(vehicleDetailsRepository, Mockito.times(0)).save(Mockito.any()); Assertions.assertEquals(UserMessage.VEHICLE_ALREADY_CREATED, crapiAPIResponse.getMessage()); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), crapiAPIResponse.getStatus()); diff --git a/services/web/src/actions/vehicleActions.ts b/services/web/src/actions/vehicleActions.ts index 6392eef4..9d645266 100644 --- a/services/web/src/actions/vehicleActions.ts +++ b/services/web/src/actions/vehicleActions.ts @@ -25,6 +25,16 @@ interface GetVehiclesPayload extends ActionPayload { email?: string; } +export const createVehicleAction = ({ callback, accessToken }: ActionPayload) => { + return { + type: actionTypes.CREATE_VEHICLE, + payload: { + accessToken, + callback, + }, + }; +}; + export const verifyVehicleAction = ({ callback, accessToken, diff --git a/services/web/src/components/addVehicle/addVehicle.css b/services/web/src/components/addVehicle/addVehicle.css new file mode 100644 index 00000000..d40ddf0e --- /dev/null +++ b/services/web/src/components/addVehicle/addVehicle.css @@ -0,0 +1,56 @@ + .add-vehicle-container .ant-row { + align-items: stretch; + gap: calc(var(--spacing-md) * 2) !important; + } + + .add-vehicle-card { + height: 100%; + width: 100%; + min-height: 320px; + display: flex; + flex-direction: column; + } + + .add-vehicle-card .ant-card-body { + flex: 1; + display: flex; + flex-direction: column; + padding: 16px; + } + + .vehicle-alert { + margin-top: 8px; + font-size: 12px; + } + + .vehicle-alert .ant-alert-message { + font-weight: 600; + margin-bottom: 4px; + } + + .vehicle-alert .ant-alert-description { + font-size: 12px; + line-height: 1.3; + } + + .verify-vehicle-form .ant-form-item { + margin-bottom: 12px; + } + + .verify-vehicle-form .ant-form-item:last-child { + margin-bottom: 0; + } + + @media (max-width: 768px) { + .add-vehicle-card { + min-height: auto; + } + + .add-vehicle-container .ant-col { + margin-bottom: 20px; + } + + .add-vehicle-container .ant-row { + gap: var(--spacing-md); + } + } \ No newline at end of file diff --git a/services/web/src/components/addVehicle/addVehicle.tsx b/services/web/src/components/addVehicle/addVehicle.tsx new file mode 100644 index 00000000..d00a3c8d --- /dev/null +++ b/services/web/src/components/addVehicle/addVehicle.tsx @@ -0,0 +1,124 @@ +/* + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from "react"; +import { Button, Form, Card, Input, Row, Col, Alert } from "antd"; +import { + PIN_CODE_REQUIRED, + INVALID_PIN_CODE, + VEHICLE_NO_REQUIRED, + INVALID_VIN, +} from "../../constants/messages"; +import { PIN_CODE_VALIDATION, VIN_VALIDATION } from "../../constants/constants"; +import "./addVehicle.css"; + +interface AddVehicleProps { + hasErrored: boolean; + errorMessage: string; + onFinish: (values: any) => void; + onCreateVehicle: () => void; + vehicleCreated: number; + creationMessage: string; +} + +const AddVehicle: React.FC = ({ + hasErrored, + errorMessage, + onFinish, + onCreateVehicle, + vehicleCreated, + creationMessage, +}) => { + return ( +

+ + + + + {creationMessage && ( + + )} + + + + + +
+ + + + + + + + {hasErrored &&
{errorMessage}
} + +
+
+
+ +
+
+ ); +}; + +export default AddVehicle; diff --git a/services/web/src/components/dashboard/dashboard.tsx b/services/web/src/components/dashboard/dashboard.tsx index 4aff0641..a4ea21f0 100644 --- a/services/web/src/components/dashboard/dashboard.tsx +++ b/services/web/src/components/dashboard/dashboard.tsx @@ -186,8 +186,8 @@ const Dashboard: React.FC = ({ {NO_VEHICLE_DESC_3} ); - const handleVerifyVehicleClick = () => { - navigate("/verify-vehicle"); + const handleAddVehicleClick = () => { + navigate("/add-vehicle"); }; const handleVehicleServiceClick = (vin: string) => { @@ -202,17 +202,16 @@ const Dashboard: React.FC = ({ } size="large" - onClick={handleVerifyVehicleClick} - key="verify-vehicle" + onClick={handleAddVehicleClick} + key="add-vehicle" > - Add a Vehicle + Add Vehicle , ] } diff --git a/services/web/src/components/layout/layout.tsx b/services/web/src/components/layout/layout.tsx index 3285c58c..dd2fba63 100644 --- a/services/web/src/components/layout/layout.tsx +++ b/services/web/src/components/layout/layout.tsx @@ -27,7 +27,7 @@ import ForgotPassword from "../forgotPassword/forgotPassword"; import ResetPasswordContainer from "../../containers/resetPassword/resetPassword"; import DashboardContainer from "../../containers/dashboard/dashboard"; import MechanicDashboardContainer from "../../containers/mechanicDashboard/mechanicDashboard"; -import VerifyVehicleContainer from "../../containers/verifyVehicle/verifyVehicle"; +import AddVehicleContainer from "../../containers/addVehicle/addVehicle"; import ContactMechanicContainer from "../../containers/contactMechanic/contactMechanic"; import ChangeEmail from "../changeEmail/changeEmail"; import roleTypes from "../../constants/roleTypes"; @@ -305,10 +305,10 @@ const StyledComp: React.FC = (props) => { } /> void; -} - -const VerifyVehicle: React.FC = ({ - hasErrored, - errorMessage, - onFinish, -}) => { - return ( -
- -
- - - - - - - - {hasErrored &&
{errorMessage}
} - -
-
-
-
- ); -}; - -export default VerifyVehicle; diff --git a/services/web/src/constants/APIConstant.ts b/services/web/src/constants/APIConstant.ts index 63d3fc2b..10c9aa26 100644 --- a/services/web/src/constants/APIConstant.ts +++ b/services/web/src/constants/APIConstant.ts @@ -42,7 +42,8 @@ export const requestURLS: RequestURLSType = { FORGOT_PASSWORD: "api/auth/forget-password", VERIFY_OTP: "api/auth/v3/check-otp", LOGIN_TOKEN: "api/auth/v4.0/user/login-with-token", - ADD_VEHICLE: "api/v2/vehicle/add_vehicle", + CREATE_VEHICLE: "api/v2/vehicle/create_vehicle", + VERIFY_VEHICLE: "api/v2/vehicle/verify_vehicle", GET_VEHICLES: "api/v2/vehicle/vehicles", RESEND_MAIL: "api/v2/vehicle/resend_email", CHANGE_EMAIL: "api/v2/user/change-email", diff --git a/services/web/src/constants/actionTypes.ts b/services/web/src/constants/actionTypes.ts index 861a3b60..246bc7ab 100644 --- a/services/web/src/constants/actionTypes.ts +++ b/services/web/src/constants/actionTypes.ts @@ -42,6 +42,7 @@ const actionTypes = { GET_VEHICLE_SERVICES: "GET_VEHICLE_SERVICES", GET_SERVICE_REPORT: "GET_SERVICE_REPORT", RESEND_MAIL: "RESEND_MAIL", + CREATE_VEHICLE: "CREATE_VEHICLE", VERIFY_VEHICLE: "VERIFY_VEHICLE", GET_VEHICLES: "GET_VEHICLES", FETCHED_VEHICLES: "FETCHED_VEHICLES", diff --git a/services/web/src/constants/messages.ts b/services/web/src/constants/messages.ts index 4a03de0e..6c378b83 100644 --- a/services/web/src/constants/messages.ts +++ b/services/web/src/constants/messages.ts @@ -100,6 +100,7 @@ export const EMAIL_NOT_CHANGED: string = "Could not change email id"; export const NO_SERVICES: string = "Could not get mechanic details"; export const EMAIL_NOT_SENT: string = "Could not resend mail"; export const VEHICLE_NOT_ADDED: string = "Internal Server error! Wrong VIN!"; +export const VEHICLE_NOT_CREATED: string = "Could not create vehicle. Try again!"; export const NO_VEHICLES: string = "Could not get vehicles"; export const NO_MECHANICS: string = "Could not get mechanic details"; export const SERVICE_REQUEST_SENT: string = diff --git a/services/web/src/containers/verifyVehicle/verifyVehicle.js b/services/web/src/containers/addVehicle/addVehicle.js similarity index 65% rename from services/web/src/containers/verifyVehicle/verifyVehicle.js rename to services/web/src/containers/addVehicle/addVehicle.js index bab604c9..f86e4e4a 100644 --- a/services/web/src/containers/verifyVehicle/verifyVehicle.js +++ b/services/web/src/containers/addVehicle/addVehicle.js @@ -18,20 +18,35 @@ import React from "react"; import PropTypes from "prop-types"; import { connect } from "react-redux"; import { Modal } from "antd"; -import { verifyVehicleAction } from "../../actions/vehicleActions"; -import VerifyVehicle from "../../components/verifyVehicle/verifyVehicle"; +import { createVehicleAction, verifyVehicleAction } from "../../actions/vehicleActions"; +import AddVehicle from "../../components/addVehicle/addVehicle"; import responseTypes from "../../constants/responseTypes"; import { SUCCESS_MESSAGE } from "../../constants/messages"; import { useNavigate } from "react-router-dom"; -const VerifyVehicleContainer = (props) => { +const AddVehicleContainer = (props) => { const navigate = useNavigate(); - const { verifyVehicle } = props; + const { createVehicle, verifyVehicle } = props; + const { accessToken } = props; const [hasErrored, setHasErrored] = React.useState(false); const [errorMessage, setErrorMessage] = React.useState(""); + const [vehicleCreated, setVehicleCreated] = React.useState(0); + const [creationMessage, setCreationMessage] = React.useState(""); - const { accessToken } = props; + const onCreateVehicle = () => { + setVehicleCreated(1); + const callback = (res, data) => { + if (res === responseTypes.SUCCESS) { + setVehicleCreated(2); + setCreationMessage(data); + } else { + setVehicleCreated(0); + setCreationMessage(data); + } + }; + createVehicle({ callback, accessToken }); + }; const onFinish = (values) => { const callback = (res, data) => { @@ -54,10 +69,13 @@ const VerifyVehicleContainer = (props) => { }; return ( - ); }; @@ -67,15 +85,17 @@ const mapStateToProps = ({ userReducer: { accessToken } }) => { }; const mapDispatchToProps = { + createVehicle: createVehicleAction, verifyVehicle: verifyVehicleAction, }; -VerifyVehicleContainer.propTypes = { +AddVehicleContainer.propTypes = { accessToken: PropTypes.string, + createVehicle: PropTypes.func, verifyVehicle: PropTypes.func, }; export default connect( mapStateToProps, mapDispatchToProps, -)(VerifyVehicleContainer); +)(AddVehicleContainer); diff --git a/services/web/src/sagas/vehicleSaga.ts b/services/web/src/sagas/vehicleSaga.ts index c423d571..268d0e63 100644 --- a/services/web/src/sagas/vehicleSaga.ts +++ b/services/web/src/sagas/vehicleSaga.ts @@ -27,6 +27,7 @@ import { SERVICE_REQUEST_NOT_SENT, LOC_NOT_REFRESHED, NO_SERVICES, + VEHICLE_NOT_CREATED, } from "../constants/messages"; interface ReceivedResponse extends Response { @@ -70,6 +71,42 @@ export function* resendMail(action: MyAction): Generator { } } +/** + * create a new vehicle with dummy data + * @payload { accessToken, callback } payload + * accessToken: access token of the user + * callback : callback method + */ +export function* createVehicle(action: MyAction): Generator { + const { accessToken, callback } = action.payload; + let recievedResponse: ReceivedResponse = {} as ReceivedResponse; + try { + yield put({ type: actionTypes.FETCHING_DATA }); + const postUrl = APIService.IDENTITY_SERVICE + requestURLS.CREATE_VEHICLE; + const headers = { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }; + const responseJson = yield fetch(postUrl, { + headers, + method: "POST", + }).then((response: Response) => { + recievedResponse = response as ReceivedResponse; + return response.json(); + }); + + yield put({ type: actionTypes.FETCHED_DATA, payload: recievedResponse }); + if (recievedResponse.ok) { + callback(responseTypes.SUCCESS, responseJson.message); + } else { + callback(responseTypes.FAILURE, VEHICLE_NOT_CREATED); + } + } catch (e) { + yield put({ type: actionTypes.FETCHED_DATA, payload: recievedResponse }); + callback(responseTypes.FAILURE, VEHICLE_NOT_CREATED); + } +} + /** * verify vehicle details entered by user and add this vehicle to this uder * @payload { pincode, vehicleNumber, accessToken, callback} payload @@ -83,7 +120,7 @@ export function* verifyVehicle(action: MyAction): Generator { let recievedResponse: ReceivedResponse = {} as ReceivedResponse; try { yield put({ type: actionTypes.FETCHING_DATA }); - const postUrl = APIService.IDENTITY_SERVICE + requestURLS.ADD_VEHICLE; + const postUrl = APIService.IDENTITY_SERVICE + requestURLS.VERIFY_VEHICLE; const headers = { "Content-Type": "application/json", Authorization: `Bearer ${accessToken}`, @@ -393,6 +430,7 @@ export function* getServiceReport(action: MyAction): Generator { export function* vehicleActionWatcher(): Generator { yield takeLatest(actionTypes.RESEND_MAIL, resendMail); + yield takeLatest(actionTypes.CREATE_VEHICLE, createVehicle); yield takeLatest(actionTypes.VERIFY_VEHICLE, verifyVehicle); yield takeLatest(actionTypes.GET_VEHICLES, getVehicles); yield takeLatest(actionTypes.GET_MECHANICS, getMechanics); From 445727363bfa70360f2ccfe649394f61ecb9fe6d Mon Sep 17 00:00:00 2001 From: Keyur Doshi Date: Mon, 27 Oct 2025 11:58:23 +0530 Subject: [PATCH 2/4] reverted to old apis and added register func --- openapi-spec/crapi-openapi-spec.json | 4 +- .../crAPI.postman_collection.json | 6 +- .../src/resources/crapi-openapi-spec.json | 4 +- .../java/com/crapi/constant/UserMessage.java | 2 +- .../crapi/controller/VehicleController.java | 26 +++---- .../service/Impl/VehicleServiceImpl.java | 6 +- .../com/crapi/service/VehicleService.java | 4 +- .../service/Impl/VehicleServiceImplTest.java | 16 ++-- services/web/src/actions/vehicleActions.ts | 4 +- .../src/components/dashboard/dashboard.tsx | 8 +- services/web/src/components/layout/layout.tsx | 6 +- .../verifyVehicle.css} | 0 .../verifyVehicle.tsx} | 76 ++++++++++--------- services/web/src/constants/APIConstant.ts | 4 +- services/web/src/constants/actionTypes.ts | 2 +- services/web/src/constants/messages.ts | 2 +- .../verifyVehicle.js} | 50 ++++++------ services/web/src/sagas/vehicleSaga.ts | 16 ++-- 18 files changed, 121 insertions(+), 115 deletions(-) rename services/web/src/components/{addVehicle/addVehicle.css => verifyVehicle/verifyVehicle.css} (100%) rename services/web/src/components/{addVehicle/addVehicle.tsx => verifyVehicle/verifyVehicle.tsx} (66%) rename services/web/src/containers/{addVehicle/addVehicle.js => verifyVehicle/verifyVehicle.js} (61%) diff --git a/openapi-spec/crapi-openapi-spec.json b/openapi-spec/crapi-openapi-spec.json index 87079b5b..a33fef2f 100644 --- a/openapi-spec/crapi-openapi-spec.json +++ b/openapi-spec/crapi-openapi-spec.json @@ -1009,9 +1009,9 @@ }, "parameters" : [ ] }, - "/identity/api/v2/vehicle/verify_vehicle" : { + "/identity/api/v2/vehicle/add_vehicle" : { "post" : { - "operationId" : "verify_vehicle", + "operationId" : "add_vehicle", "summary" : "Add the user vehicle", "tags" : [ "Identity / Vehicle" ], "security" : [ { diff --git a/postman_collections/crAPI.postman_collection.json b/postman_collections/crAPI.postman_collection.json index 958017a9..582fb11c 100644 --- a/postman_collections/crAPI.postman_collection.json +++ b/postman_collections/crAPI.postman_collection.json @@ -775,7 +775,7 @@ "uid": "13872198-c0ef62ef-8ca0-4eaf-a3d8-44c1aa41a407" }, { - "name": "Verify Vehicle from Mail", + "name": "Add Vehicle from Mail", "event": [ { "listen": "test", @@ -850,7 +850,7 @@ "raw": "{\"vin\": \"{{VIN}}\", \"pincode\": \"{{PIN}}\"}" }, "url": { - "raw": "{{url}}/identity/api/v2/vehicle/verify_vehicle", + "raw": "{{url}}/identity/api/v2/vehicle/add_vehicle", "host": [ "{{url}}" ], @@ -859,7 +859,7 @@ "api", "v2", "vehicle", - "verify_vehicle" + "add_vehicle" ] } }, diff --git a/services/chatbot/src/resources/crapi-openapi-spec.json b/services/chatbot/src/resources/crapi-openapi-spec.json index 87079b5b..a33fef2f 100644 --- a/services/chatbot/src/resources/crapi-openapi-spec.json +++ b/services/chatbot/src/resources/crapi-openapi-spec.json @@ -1009,9 +1009,9 @@ }, "parameters" : [ ] }, - "/identity/api/v2/vehicle/verify_vehicle" : { + "/identity/api/v2/vehicle/add_vehicle" : { "post" : { - "operationId" : "verify_vehicle", + "operationId" : "add_vehicle", "summary" : "Add the user vehicle", "tags" : [ "Identity / Vehicle" ], "security" : [ { diff --git a/services/identity/src/main/java/com/crapi/constant/UserMessage.java b/services/identity/src/main/java/com/crapi/constant/UserMessage.java index d8c78793..fa1c5c83 100644 --- a/services/identity/src/main/java/com/crapi/constant/UserMessage.java +++ b/services/identity/src/main/java/com/crapi/constant/UserMessage.java @@ -60,7 +60,7 @@ public class UserMessage { public static final String VEHICLE_DETAILS_SENT_TO_EMAIL = "Your newly purchased vehicle details have been sent to you email address. Verify them to add your vehicle. [If you have used example.com email, check your email using the MailHog web portal]"; public static final String CHANGE_EMAIL_MESSAGE = - "The token has been sent to your email. If you have used example.com email, check your email using the MailHog web portal."; + "The token has been sent to your email. If you have used example.com email, check your email using the MailHog web portal. "; public static final String CHANGE_EMAIL_OLD_USEREMAIL_NOT_FOUND_MESSAGE = "Sorry, we didn't find any user for "; public static final String INVALID_EMAIL_TOKEN = "Sorry, Token did't match"; diff --git a/services/identity/src/main/java/com/crapi/controller/VehicleController.java b/services/identity/src/main/java/com/crapi/controller/VehicleController.java index 37be2b67..faae362b 100644 --- a/services/identity/src/main/java/com/crapi/controller/VehicleController.java +++ b/services/identity/src/main/java/com/crapi/controller/VehicleController.java @@ -41,30 +41,30 @@ public class VehicleController { @Autowired VehicleOwnershipService vehicleOwnershipService; /** - * @param vehicleDetails - * @return response of success and failure message save vehicle Details for user in database + * @param request + * @return response of success and failure message creates vehicle and sends details to user */ - @PostMapping("/vehicle/create_vehicle") - public ResponseEntity createVehicle(HttpServletRequest request) { - CRAPIResponse createVehicleResponse = vehicleService.createVehicle(request); - if (createVehicleResponse != null && createVehicleResponse.getStatus() == 200) { - return ResponseEntity.status(HttpStatus.OK).body(createVehicleResponse); + @PostMapping("/vehicle/register_vehicle") + public ResponseEntity registerVehicle(HttpServletRequest request) { + CRAPIResponse registerVehicleResponse = vehicleService.registerVehicle(request); + if (registerVehicleResponse != null && registerVehicleResponse.getStatus() == 200) { + return ResponseEntity.status(HttpStatus.OK).body(registerVehicleResponse); } - return ResponseEntity.status(HttpStatus.FORBIDDEN).body(createVehicleResponse); + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(registerVehicleResponse); } /** * @param vehicleDetails * @return response of success and failure message save vehicle Details for user in database */ - @PostMapping("/vehicle/verify_vehicle") + @PostMapping("/vehicle/add_vehicle") public ResponseEntity addVehicle( @Valid @RequestBody VehicleForm vehicleDetails, HttpServletRequest request) { - CRAPIResponse verifyVehicleResponse = vehicleService.verifyVehicle(vehicleDetails, request); - if (verifyVehicleResponse != null && verifyVehicleResponse.getStatus() == 200) { - return ResponseEntity.status(HttpStatus.OK).body(verifyVehicleResponse); + CRAPIResponse checkVehicleResponse = vehicleService.checkVehicle(vehicleDetails, request); + if (checkVehicleResponse != null && checkVehicleResponse.getStatus() == 200) { + return ResponseEntity.status(HttpStatus.OK).body(checkVehicleResponse); } - return ResponseEntity.status(HttpStatus.FORBIDDEN).body(verifyVehicleResponse); + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(checkVehicleResponse); } /** diff --git a/services/identity/src/main/java/com/crapi/service/Impl/VehicleServiceImpl.java b/services/identity/src/main/java/com/crapi/service/Impl/VehicleServiceImpl.java index 0599a461..a6a6d1fb 100644 --- a/services/identity/src/main/java/com/crapi/service/Impl/VehicleServiceImpl.java +++ b/services/identity/src/main/java/com/crapi/service/Impl/VehicleServiceImpl.java @@ -109,11 +109,11 @@ public VehicleDetails createVehicle() { /** * @param request - * @return CRAPIResponse after creating a new vehicle and assigning it to the current user + * @return CRAPIResponse after creating a new vehicle and sending details to current user */ @Transactional @Override - public CRAPIResponse createVehicle(HttpServletRequest request) { + public CRAPIResponse registerVehicle(HttpServletRequest request) { User user = null; UserDetails userDetails = null; VehicleDetails vehicleDetails = null; @@ -205,7 +205,7 @@ public VehicleLocationResponse getVehicleLocation(UUID carId) { */ @Transactional @Override - public CRAPIResponse verifyVehicle(VehicleForm vehicleForm, HttpServletRequest request) { + public CRAPIResponse checkVehicle(VehicleForm vehicleForm, HttpServletRequest request) { VehicleDetails checkVehicle = null; User user = null; checkVehicle = vehicleDetailsRepository.findByVin(vehicleForm.getVin()); diff --git a/services/identity/src/main/java/com/crapi/service/VehicleService.java b/services/identity/src/main/java/com/crapi/service/VehicleService.java index 23263f99..c72f0ffb 100644 --- a/services/identity/src/main/java/com/crapi/service/VehicleService.java +++ b/services/identity/src/main/java/com/crapi/service/VehicleService.java @@ -28,13 +28,13 @@ public interface VehicleService { VehicleDetails createVehicle(); - CRAPIResponse createVehicle(HttpServletRequest request); + CRAPIResponse registerVehicle(HttpServletRequest request); List getVehicleDetails(HttpServletRequest request); VehicleLocationResponse getVehicleLocation(UUID carId); - CRAPIResponse verifyVehicle(VehicleForm vehicleDetails, HttpServletRequest request); + CRAPIResponse checkVehicle(VehicleForm vehicleDetails, HttpServletRequest request); CRAPIResponse sendVehicleDetails(HttpServletRequest request); } diff --git a/services/identity/src/test/java/com/crapi/service/Impl/VehicleServiceImplTest.java b/services/identity/src/test/java/com/crapi/service/Impl/VehicleServiceImplTest.java index 1c7e298a..f4e62f17 100644 --- a/services/identity/src/test/java/com/crapi/service/Impl/VehicleServiceImplTest.java +++ b/services/identity/src/test/java/com/crapi/service/Impl/VehicleServiceImplTest.java @@ -181,7 +181,7 @@ public void getVehicleLocationNotFoundWhenVehicleDetailsOwnerIsNull() { } @Test - public void verifyVehicleSuccessFull() { + public void checkVehicleSuccessFull() { VehicleForm vehicleForm = getDummyVehicleForm(); VehicleDetails vehicleDetails = getDummyVehicleDetails(); User user = getDummyUser(); @@ -191,14 +191,14 @@ public void verifyVehicleSuccessFull() { .thenReturn(vehicleDetails); Mockito.when(userService.getUserFromToken(Mockito.any())).thenReturn(user); CRAPIResponse crapiAPIResponse = - vehicleService.verifyVehicle(vehicleForm, getDummyHttpRequest()); + vehicleService.checkVehicle(vehicleForm, getDummyHttpRequest()); Mockito.verify(vehicleDetailsRepository, Mockito.times(1)).save(Mockito.any()); Assertions.assertEquals(UserMessage.VEHICLE_SAVED_SUCCESSFULLY, crapiAPIResponse.getMessage()); Assertions.assertEquals(HttpStatus.OK.value(), crapiAPIResponse.getStatus()); } @Test - public void verifyVehicleFailWhenPinCodeNotEqual() { + public void checkVehicleFailWhenPinCodeNotEqual() { VehicleForm vehicleForm = getDummyVehicleForm(); VehicleDetails vehicleDetails = getDummyVehicleDetails(); User user = getDummyUser(); @@ -206,27 +206,27 @@ public void verifyVehicleFailWhenPinCodeNotEqual() { .thenReturn(vehicleDetails); Mockito.when(userService.getUserFromToken(Mockito.any())).thenReturn(user); CRAPIResponse crapiAPIResponse = - vehicleService.verifyVehicle(vehicleForm, getDummyHttpRequest()); + vehicleService.checkVehicle(vehicleForm, getDummyHttpRequest()); Mockito.verify(vehicleDetailsRepository, Mockito.times(0)).save(Mockito.any()); Assertions.assertEquals(UserMessage.VEHICLE_ALREADY_CREATED, crapiAPIResponse.getMessage()); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), crapiAPIResponse.getStatus()); } @Test - public void verifyVehicleFailWhenVehicleDetailsNotFound() { + public void checkVehicleFailWhenVehicleDetailsNotFound() { VehicleForm vehicleForm = getDummyVehicleForm(); User user = getDummyUser(); Mockito.when(vehicleDetailsRepository.findByVin(Mockito.anyString())).thenReturn(null); Mockito.when(userService.getUserFromToken(Mockito.any())).thenReturn(user); CRAPIResponse crapiAPIResponse = - vehicleService.verifyVehicle(vehicleForm, getDummyHttpRequest()); + vehicleService.checkVehicle(vehicleForm, getDummyHttpRequest()); Mockito.verify(vehicleDetailsRepository, Mockito.times(0)).save(Mockito.any()); Assertions.assertEquals(UserMessage.VEHICLE_ALREADY_CREATED, crapiAPIResponse.getMessage()); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), crapiAPIResponse.getStatus()); } @Test - public void verifyVehicleFailWhenUserNotFound() { + public void checkVehicleFailWhenUserNotFound() { VehicleForm vehicleForm = getDummyVehicleForm(); VehicleDetails vehicleDetails = getDummyVehicleDetails(); vehicleDetails.setPincode(vehicleForm.getPincode()); @@ -234,7 +234,7 @@ public void verifyVehicleFailWhenUserNotFound() { .thenReturn(vehicleDetails); Mockito.when(userService.getUserFromToken(Mockito.any())).thenReturn(null); CRAPIResponse crapiAPIResponse = - vehicleService.verifyVehicle(vehicleForm, getDummyHttpRequest()); + vehicleService.checkVehicle(vehicleForm, getDummyHttpRequest()); Mockito.verify(vehicleDetailsRepository, Mockito.times(0)).save(Mockito.any()); Assertions.assertEquals(UserMessage.VEHICLE_ALREADY_CREATED, crapiAPIResponse.getMessage()); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), crapiAPIResponse.getStatus()); diff --git a/services/web/src/actions/vehicleActions.ts b/services/web/src/actions/vehicleActions.ts index 9d645266..baf99767 100644 --- a/services/web/src/actions/vehicleActions.ts +++ b/services/web/src/actions/vehicleActions.ts @@ -25,9 +25,9 @@ interface GetVehiclesPayload extends ActionPayload { email?: string; } -export const createVehicleAction = ({ callback, accessToken }: ActionPayload) => { +export const registerVehicleAction = ({ callback, accessToken }: ActionPayload) => { return { - type: actionTypes.CREATE_VEHICLE, + type: actionTypes.REGISTER_VEHICLE, payload: { accessToken, callback, diff --git a/services/web/src/components/dashboard/dashboard.tsx b/services/web/src/components/dashboard/dashboard.tsx index a4ea21f0..80fb03fa 100644 --- a/services/web/src/components/dashboard/dashboard.tsx +++ b/services/web/src/components/dashboard/dashboard.tsx @@ -186,8 +186,8 @@ const Dashboard: React.FC = ({ {NO_VEHICLE_DESC_3} ); - const handleAddVehicleClick = () => { - navigate("/add-vehicle"); + const handleVerifyVehicleClick = () => { + navigate("/verify-vehicle"); }; const handleVehicleServiceClick = (vin: string) => { @@ -208,8 +208,8 @@ const Dashboard: React.FC = ({ shape="round" icon={} size="large" - onClick={handleAddVehicleClick} - key="add-vehicle" + onClick={handleVerifyVehicleClick} + key="verify-vehicle" > Add Vehicle , diff --git a/services/web/src/components/layout/layout.tsx b/services/web/src/components/layout/layout.tsx index dd2fba63..3285c58c 100644 --- a/services/web/src/components/layout/layout.tsx +++ b/services/web/src/components/layout/layout.tsx @@ -27,7 +27,7 @@ import ForgotPassword from "../forgotPassword/forgotPassword"; import ResetPasswordContainer from "../../containers/resetPassword/resetPassword"; import DashboardContainer from "../../containers/dashboard/dashboard"; import MechanicDashboardContainer from "../../containers/mechanicDashboard/mechanicDashboard"; -import AddVehicleContainer from "../../containers/addVehicle/addVehicle"; +import VerifyVehicleContainer from "../../containers/verifyVehicle/verifyVehicle"; import ContactMechanicContainer from "../../containers/contactMechanic/contactMechanic"; import ChangeEmail from "../changeEmail/changeEmail"; import roleTypes from "../../constants/roleTypes"; @@ -305,10 +305,10 @@ const StyledComp: React.FC = (props) => { } /> void; - onCreateVehicle: () => void; - vehicleCreated: number; - creationMessage: string; + onRegisterVehicle: () => void; + vehicleRegistered: number; + registrationMessage: string; + vehicles: any[]; } -const AddVehicle: React.FC = ({ +const VerifyVehicle: React.FC = ({ hasErrored, errorMessage, onFinish, - onCreateVehicle, - vehicleCreated, - creationMessage, + onRegisterVehicle, + vehicleRegistered, + registrationMessage, + vehicles, }) => { return (
- - - - {creationMessage && ( - - )} - - + + {registrationMessage && ( + + )} + + + )} - + = ({ ); }; -export default AddVehicle; +export default VerifyVehicle; diff --git a/services/web/src/constants/APIConstant.ts b/services/web/src/constants/APIConstant.ts index 10c9aa26..bc2f2c66 100644 --- a/services/web/src/constants/APIConstant.ts +++ b/services/web/src/constants/APIConstant.ts @@ -42,8 +42,8 @@ export const requestURLS: RequestURLSType = { FORGOT_PASSWORD: "api/auth/forget-password", VERIFY_OTP: "api/auth/v3/check-otp", LOGIN_TOKEN: "api/auth/v4.0/user/login-with-token", - CREATE_VEHICLE: "api/v2/vehicle/create_vehicle", - VERIFY_VEHICLE: "api/v2/vehicle/verify_vehicle", + REGISTER_VEHICLE: "api/v2/vehicle/register_vehicle", + ADD_VEHICLE: "api/v2/vehicle/add_vehicle", GET_VEHICLES: "api/v2/vehicle/vehicles", RESEND_MAIL: "api/v2/vehicle/resend_email", CHANGE_EMAIL: "api/v2/user/change-email", diff --git a/services/web/src/constants/actionTypes.ts b/services/web/src/constants/actionTypes.ts index 246bc7ab..f6bf733f 100644 --- a/services/web/src/constants/actionTypes.ts +++ b/services/web/src/constants/actionTypes.ts @@ -42,7 +42,7 @@ const actionTypes = { GET_VEHICLE_SERVICES: "GET_VEHICLE_SERVICES", GET_SERVICE_REPORT: "GET_SERVICE_REPORT", RESEND_MAIL: "RESEND_MAIL", - CREATE_VEHICLE: "CREATE_VEHICLE", + REGISTER_VEHICLE: "REGISTER_VEHICLE", VERIFY_VEHICLE: "VERIFY_VEHICLE", GET_VEHICLES: "GET_VEHICLES", FETCHED_VEHICLES: "FETCHED_VEHICLES", diff --git a/services/web/src/constants/messages.ts b/services/web/src/constants/messages.ts index 6c378b83..3275b9e5 100644 --- a/services/web/src/constants/messages.ts +++ b/services/web/src/constants/messages.ts @@ -100,7 +100,7 @@ export const EMAIL_NOT_CHANGED: string = "Could not change email id"; export const NO_SERVICES: string = "Could not get mechanic details"; export const EMAIL_NOT_SENT: string = "Could not resend mail"; export const VEHICLE_NOT_ADDED: string = "Internal Server error! Wrong VIN!"; -export const VEHICLE_NOT_CREATED: string = "Could not create vehicle. Try again!"; +export const VEHICLE_NOT_REGISTERED: string = "Could not register vehicle. Try again!"; export const NO_VEHICLES: string = "Could not get vehicles"; export const NO_MECHANICS: string = "Could not get mechanic details"; export const SERVICE_REQUEST_SENT: string = diff --git a/services/web/src/containers/addVehicle/addVehicle.js b/services/web/src/containers/verifyVehicle/verifyVehicle.js similarity index 61% rename from services/web/src/containers/addVehicle/addVehicle.js rename to services/web/src/containers/verifyVehicle/verifyVehicle.js index f86e4e4a..1b161757 100644 --- a/services/web/src/containers/addVehicle/addVehicle.js +++ b/services/web/src/containers/verifyVehicle/verifyVehicle.js @@ -18,34 +18,34 @@ import React from "react"; import PropTypes from "prop-types"; import { connect } from "react-redux"; import { Modal } from "antd"; -import { createVehicleAction, verifyVehicleAction } from "../../actions/vehicleActions"; -import AddVehicle from "../../components/addVehicle/addVehicle"; +import { registerVehicleAction, verifyVehicleAction } from "../../actions/vehicleActions"; +import VerifyVehicle from "../../components/verifyVehicle/verifyVehicle"; import responseTypes from "../../constants/responseTypes"; import { SUCCESS_MESSAGE } from "../../constants/messages"; import { useNavigate } from "react-router-dom"; -const AddVehicleContainer = (props) => { +const VerifyVehicleContainer = (props) => { const navigate = useNavigate(); - const { createVehicle, verifyVehicle } = props; - const { accessToken } = props; + const { registerVehicle, verifyVehicle } = props; + const { accessToken, vehicles } = props; const [hasErrored, setHasErrored] = React.useState(false); const [errorMessage, setErrorMessage] = React.useState(""); - const [vehicleCreated, setVehicleCreated] = React.useState(0); - const [creationMessage, setCreationMessage] = React.useState(""); + const [vehicleRegistered, setVehicleRegistered] = React.useState(0); + const [registrationMessage, setRegistrationMessage] = React.useState(""); - const onCreateVehicle = () => { - setVehicleCreated(1); + const onRegisterVehicle = () => { + setVehicleRegistered(1); const callback = (res, data) => { if (res === responseTypes.SUCCESS) { - setVehicleCreated(2); - setCreationMessage(data); + setVehicleRegistered(2); + setRegistrationMessage(data); } else { - setVehicleCreated(0); - setCreationMessage(data); + setVehicleRegistered(0); + setRegistrationMessage(data); } }; - createVehicle({ callback, accessToken }); + registerVehicle({ callback, accessToken }); }; const onFinish = (values) => { @@ -69,33 +69,35 @@ const AddVehicleContainer = (props) => { }; return ( - ); }; -const mapStateToProps = ({ userReducer: { accessToken } }) => { - return { accessToken }; +const mapStateToProps = ({ userReducer: { accessToken }, vehicleReducer: { vehicles } }) => { + return { accessToken, vehicles }; }; const mapDispatchToProps = { - createVehicle: createVehicleAction, + registerVehicle: registerVehicleAction, verifyVehicle: verifyVehicleAction, }; -AddVehicleContainer.propTypes = { +VerifyVehicleContainer.propTypes = { accessToken: PropTypes.string, - createVehicle: PropTypes.func, + registerVehicle: PropTypes.func, verifyVehicle: PropTypes.func, + vehicles: PropTypes.array, }; export default connect( mapStateToProps, mapDispatchToProps, -)(AddVehicleContainer); +)(VerifyVehicleContainer); diff --git a/services/web/src/sagas/vehicleSaga.ts b/services/web/src/sagas/vehicleSaga.ts index 268d0e63..22680645 100644 --- a/services/web/src/sagas/vehicleSaga.ts +++ b/services/web/src/sagas/vehicleSaga.ts @@ -27,7 +27,7 @@ import { SERVICE_REQUEST_NOT_SENT, LOC_NOT_REFRESHED, NO_SERVICES, - VEHICLE_NOT_CREATED, + VEHICLE_NOT_REGISTERED, } from "../constants/messages"; interface ReceivedResponse extends Response { @@ -72,17 +72,17 @@ export function* resendMail(action: MyAction): Generator { } /** - * create a new vehicle with dummy data + * register a new vehicle * @payload { accessToken, callback } payload * accessToken: access token of the user * callback : callback method */ -export function* createVehicle(action: MyAction): Generator { +export function* registerVehicle(action: MyAction): Generator { const { accessToken, callback } = action.payload; let recievedResponse: ReceivedResponse = {} as ReceivedResponse; try { yield put({ type: actionTypes.FETCHING_DATA }); - const postUrl = APIService.IDENTITY_SERVICE + requestURLS.CREATE_VEHICLE; + const postUrl = APIService.IDENTITY_SERVICE + requestURLS.REGISTER_VEHICLE; const headers = { "Content-Type": "application/json", Authorization: `Bearer ${accessToken}`, @@ -99,11 +99,11 @@ export function* createVehicle(action: MyAction): Generator { if (recievedResponse.ok) { callback(responseTypes.SUCCESS, responseJson.message); } else { - callback(responseTypes.FAILURE, VEHICLE_NOT_CREATED); + callback(responseTypes.FAILURE, VEHICLE_NOT_REGISTERED); } } catch (e) { yield put({ type: actionTypes.FETCHED_DATA, payload: recievedResponse }); - callback(responseTypes.FAILURE, VEHICLE_NOT_CREATED); + callback(responseTypes.FAILURE, VEHICLE_NOT_REGISTERED); } } @@ -120,7 +120,7 @@ export function* verifyVehicle(action: MyAction): Generator { let recievedResponse: ReceivedResponse = {} as ReceivedResponse; try { yield put({ type: actionTypes.FETCHING_DATA }); - const postUrl = APIService.IDENTITY_SERVICE + requestURLS.VERIFY_VEHICLE; + const postUrl = APIService.IDENTITY_SERVICE + requestURLS.ADD_VEHICLE; const headers = { "Content-Type": "application/json", Authorization: `Bearer ${accessToken}`, @@ -430,7 +430,7 @@ export function* getServiceReport(action: MyAction): Generator { export function* vehicleActionWatcher(): Generator { yield takeLatest(actionTypes.RESEND_MAIL, resendMail); - yield takeLatest(actionTypes.CREATE_VEHICLE, createVehicle); + yield takeLatest(actionTypes.REGISTER_VEHICLE, registerVehicle); yield takeLatest(actionTypes.VERIFY_VEHICLE, verifyVehicle); yield takeLatest(actionTypes.GET_VEHICLES, getVehicles); yield takeLatest(actionTypes.GET_MECHANICS, getMechanics); From 3db86675c837b764f0c6f9191ce7d0f4e2103838 Mon Sep 17 00:00:00 2001 From: Keyur Doshi Date: Mon, 27 Oct 2025 12:05:13 +0530 Subject: [PATCH 3/4] fix dom rendering --- services/web/src/components/verifyVehicle/verifyVehicle.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/src/components/verifyVehicle/verifyVehicle.tsx b/services/web/src/components/verifyVehicle/verifyVehicle.tsx index 17883083..6979d8ca 100644 --- a/services/web/src/components/verifyVehicle/verifyVehicle.tsx +++ b/services/web/src/components/verifyVehicle/verifyVehicle.tsx @@ -46,7 +46,7 @@ const VerifyVehicle: React.FC = ({ return (
- {vehicles.length && ( + {vehicles.length > 0 && ( Date: Tue, 28 Oct 2025 00:01:49 +0530 Subject: [PATCH 4/4] lint fix --- services/web/src/actions/vehicleActions.ts | 5 +++- .../src/components/dashboard/dashboard.tsx | 23 +++++++++---------- .../verifyVehicle/verifyVehicle.tsx | 16 +++++++++---- services/web/src/constants/messages.ts | 3 ++- .../containers/verifyVehicle/verifyVehicle.js | 10 ++++++-- 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/services/web/src/actions/vehicleActions.ts b/services/web/src/actions/vehicleActions.ts index baf99767..02af86f3 100644 --- a/services/web/src/actions/vehicleActions.ts +++ b/services/web/src/actions/vehicleActions.ts @@ -25,7 +25,10 @@ interface GetVehiclesPayload extends ActionPayload { email?: string; } -export const registerVehicleAction = ({ callback, accessToken }: ActionPayload) => { +export const registerVehicleAction = ({ + callback, + accessToken, +}: ActionPayload) => { return { type: actionTypes.REGISTER_VEHICLE, payload: { diff --git a/services/web/src/components/dashboard/dashboard.tsx b/services/web/src/components/dashboard/dashboard.tsx index 80fb03fa..5bc56dd1 100644 --- a/services/web/src/components/dashboard/dashboard.tsx +++ b/services/web/src/components/dashboard/dashboard.tsx @@ -203,18 +203,17 @@ const Dashboard: React.FC = ({ className="dashboard-header" title="Vehicles Details" extra={[ - , - ] - } + , + ]} /> diff --git a/services/web/src/components/verifyVehicle/verifyVehicle.tsx b/services/web/src/components/verifyVehicle/verifyVehicle.tsx index 6979d8ca..a650d7dc 100644 --- a/services/web/src/components/verifyVehicle/verifyVehicle.tsx +++ b/services/web/src/components/verifyVehicle/verifyVehicle.tsx @@ -60,7 +60,9 @@ const VerifyVehicle: React.FC = ({ loading={vehicleRegistered === 1} className="form-button" > - {vehicleRegistered === 2 ? "Vehicle Registered" : "Register Your New Vehicle"} + {vehicleRegistered === 2 + ? "Vehicle Registered" + : "Register Your New Vehicle"} {registrationMessage && ( = ({ )} - + = ({ - {hasErrored &&
{errorMessage}
} -
diff --git a/services/web/src/constants/messages.ts b/services/web/src/constants/messages.ts index 3275b9e5..18dcc4dc 100644 --- a/services/web/src/constants/messages.ts +++ b/services/web/src/constants/messages.ts @@ -100,7 +100,8 @@ export const EMAIL_NOT_CHANGED: string = "Could not change email id"; export const NO_SERVICES: string = "Could not get mechanic details"; export const EMAIL_NOT_SENT: string = "Could not resend mail"; export const VEHICLE_NOT_ADDED: string = "Internal Server error! Wrong VIN!"; -export const VEHICLE_NOT_REGISTERED: string = "Could not register vehicle. Try again!"; +export const VEHICLE_NOT_REGISTERED: string = + "Could not register vehicle. Try again!"; export const NO_VEHICLES: string = "Could not get vehicles"; export const NO_MECHANICS: string = "Could not get mechanic details"; export const SERVICE_REQUEST_SENT: string = diff --git a/services/web/src/containers/verifyVehicle/verifyVehicle.js b/services/web/src/containers/verifyVehicle/verifyVehicle.js index 1b161757..39ad5d84 100644 --- a/services/web/src/containers/verifyVehicle/verifyVehicle.js +++ b/services/web/src/containers/verifyVehicle/verifyVehicle.js @@ -18,7 +18,10 @@ import React from "react"; import PropTypes from "prop-types"; import { connect } from "react-redux"; import { Modal } from "antd"; -import { registerVehicleAction, verifyVehicleAction } from "../../actions/vehicleActions"; +import { + registerVehicleAction, + verifyVehicleAction, +} from "../../actions/vehicleActions"; import VerifyVehicle from "../../components/verifyVehicle/verifyVehicle"; import responseTypes from "../../constants/responseTypes"; import { SUCCESS_MESSAGE } from "../../constants/messages"; @@ -81,7 +84,10 @@ const VerifyVehicleContainer = (props) => { ); }; -const mapStateToProps = ({ userReducer: { accessToken }, vehicleReducer: { vehicles } }) => { +const mapStateToProps = ({ + userReducer: { accessToken }, + vehicleReducer: { vehicles }, +}) => { return { accessToken, vehicles }; };