dhre-component-lib 0.1.7 → 0.1.8

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.
Files changed (158) hide show
  1. package/{src/components/Badge → dist}/Badge.module.scss +0 -1
  2. package/{src/components/BreadCrumb → dist}/Breadcrumb.module.scss +0 -3
  3. package/{src/components/Button → dist}/Button.module.scss +3 -16
  4. package/{src/components/CircularProgress → dist}/CircularProgress.module.scss +0 -1
  5. package/dist/assets/output-4Fi7j5sB.css +247 -0
  6. package/dist/components/Badge/index.d.ts +0 -1
  7. package/dist/components/BreadCrumb/index.d.ts +0 -1
  8. package/dist/components/Button/index.d.ts +0 -1
  9. package/dist/components/CircularProgress/index.d.ts +0 -1
  10. package/dist/components/Map/index.d.ts +0 -1
  11. package/dist/components/Modal/index.d.ts +0 -1
  12. package/dist/components/Notification/index.d.ts +0 -1
  13. package/dist/components/OtpInput/index.d.ts +0 -1
  14. package/dist/components/PdfView/index.d.ts +0 -1
  15. package/dist/components/Tooltip/index.d.ts +0 -1
  16. package/dist/dist/styles.css +2 -0
  17. package/dist/dist/styles.css.map +1 -0
  18. package/dist/index.d.ts +15 -1
  19. package/dist/index.esm.js +9323 -0
  20. package/dist/index.esm.js.map +1 -0
  21. package/dist/index.js +9359 -1
  22. package/dist/index.js.map +1 -0
  23. package/package.json +8 -7
  24. package/dist/components/Avatar/Avatar.js +0 -6
  25. package/dist/components/Avatar/Avatar.test.js +0 -39
  26. package/dist/components/Avatar/index.js +0 -1
  27. package/dist/components/Badge/Badge.js +0 -6
  28. package/dist/components/Badge/Badge.test.js +0 -44
  29. package/dist/components/Badge/index.js +0 -2
  30. package/dist/components/BreadCrumb/BreadCrumb.js +0 -8
  31. package/dist/components/BreadCrumb/BreadCrumb.test.js +0 -55
  32. package/dist/components/BreadCrumb/index.js +0 -2
  33. package/dist/components/Button/Button.js +0 -6
  34. package/dist/components/Button/Button.test.js +0 -36
  35. package/dist/components/Button/index.js +0 -2
  36. package/dist/components/Checkbox/Checkbox.js +0 -7
  37. package/dist/components/Checkbox/Checkbox.test.js +0 -59
  38. package/dist/components/Checkbox/index.js +0 -1
  39. package/dist/components/CircularProgress/CircularProgress.js +0 -15
  40. package/dist/components/CircularProgress/CircularProgress.test.js +0 -31
  41. package/dist/components/CircularProgress/index.js +0 -2
  42. package/dist/components/Divider/Divider.js +0 -7
  43. package/dist/components/Divider/Divider.test.js +0 -30
  44. package/dist/components/Divider/index.js +0 -1
  45. package/dist/components/Enum.js +0 -17
  46. package/dist/components/InputTextField/InputTextField.js +0 -9
  47. package/dist/components/InputTextField/InputTextField.test.js +0 -98
  48. package/dist/components/InputTextField/index.js +0 -1
  49. package/dist/components/Link/Link.js +0 -6
  50. package/dist/components/Link/Link.test.js +0 -47
  51. package/dist/components/Link/index.js +0 -1
  52. package/dist/components/Map/Directions.js +0 -9
  53. package/dist/components/Map/GoogleMap.js +0 -104
  54. package/dist/components/Map/GoogleMapsLoader.js +0 -10
  55. package/dist/components/Map/index.js +0 -3
  56. package/dist/components/Modal/Modal.js +0 -14
  57. package/dist/components/Modal/Modal.test.js +0 -52
  58. package/dist/components/Modal/index.js +0 -2
  59. package/dist/components/Notification/Notification.js +0 -21
  60. package/dist/components/Notification/Notification.test.js +0 -40
  61. package/dist/components/Notification/index.js +0 -2
  62. package/dist/components/OtpInput/OtpInput.js +0 -68
  63. package/dist/components/OtpInput/OtpInput.test.js +0 -36
  64. package/dist/components/OtpInput/index.js +0 -2
  65. package/dist/components/PdfView/PdfView.js +0 -59
  66. package/dist/components/PdfView/PdfView.test.js +0 -41
  67. package/dist/components/PdfView/index.js +0 -2
  68. package/dist/components/Progress/Progress.js +0 -9
  69. package/dist/components/Progress/Progress.test.js +0 -34
  70. package/dist/components/Progress/index.js +0 -1
  71. package/dist/components/RadioButton/RadioButton.js +0 -7
  72. package/dist/components/RadioButton/RadioButton.test.js +0 -29
  73. package/dist/components/RadioButton/index.js +0 -1
  74. package/dist/components/Switch/Switch.js +0 -10
  75. package/dist/components/Switch/Switch.test.js +0 -45
  76. package/dist/components/Switch/index.js +0 -1
  77. package/dist/components/Tag/Tag.js +0 -6
  78. package/dist/components/Tag/Tag.test.js +0 -43
  79. package/dist/components/Tag/index.js +0 -1
  80. package/dist/components/Tooltip/Tooltip.js +0 -11
  81. package/dist/components/Tooltip/Tooltip.test.js +0 -48
  82. package/dist/components/Tooltip/index.js +0 -2
  83. package/dist/components/index.d.ts +0 -15
  84. package/dist/components/index.js +0 -15
  85. package/dist/theme/colors.js +0 -2
  86. package/src/__mocks__/styleMock.js +0 -1
  87. package/src/components/Avatar/Avatar.test.tsx +0 -53
  88. package/src/components/Avatar/Avatar.tsx +0 -28
  89. package/src/components/Avatar/index.ts +0 -1
  90. package/src/components/Badge/Badge.test.tsx +0 -59
  91. package/src/components/Badge/Badge.tsx +0 -25
  92. package/src/components/Badge/index.ts +0 -2
  93. package/src/components/BreadCrumb/BreadCrumb.test.tsx +0 -90
  94. package/src/components/BreadCrumb/BreadCrumb.tsx +0 -45
  95. package/src/components/BreadCrumb/index.ts +0 -2
  96. package/src/components/Button/Button.test.tsx +0 -49
  97. package/src/components/Button/Button.tsx +0 -29
  98. package/src/components/Button/index.ts +0 -2
  99. package/src/components/Checkbox/Checkbox.test.tsx +0 -93
  100. package/src/components/Checkbox/Checkbox.tsx +0 -35
  101. package/src/components/Checkbox/index.ts +0 -1
  102. package/src/components/CircularProgress/CircularProgress.test.tsx +0 -39
  103. package/src/components/CircularProgress/CircularProgress.tsx +0 -37
  104. package/src/components/CircularProgress/index.ts +0 -2
  105. package/src/components/Divider/Divider.test.tsx +0 -44
  106. package/src/components/Divider/Divider.tsx +0 -24
  107. package/src/components/Divider/index.ts +0 -1
  108. package/src/components/Enum.ts +0 -19
  109. package/src/components/InputTextField/InputTextField.test.tsx +0 -118
  110. package/src/components/InputTextField/InputTextField.tsx +0 -48
  111. package/src/components/InputTextField/index.ts +0 -1
  112. package/src/components/Link/Link.test.tsx +0 -55
  113. package/src/components/Link/Link.tsx +0 -33
  114. package/src/components/Link/index.ts +0 -1
  115. package/src/components/Map/Directions.tsx +0 -36
  116. package/src/components/Map/GoogleMap.tsx +0 -186
  117. package/src/components/Map/GoogleMapsLoader.tsx +0 -12
  118. package/src/components/Map/index.ts +0 -3
  119. package/src/components/Modal/Modal.test.tsx +0 -74
  120. package/src/components/Modal/Modal.tsx +0 -39
  121. package/src/components/Modal/index.ts +0 -2
  122. package/src/components/Notification/Notification.test.tsx +0 -53
  123. package/src/components/Notification/Notification.tsx +0 -42
  124. package/src/components/Notification/index.ts +0 -2
  125. package/src/components/OtpInput/OtpInput.test.tsx +0 -53
  126. package/src/components/OtpInput/OtpInput.tsx +0 -137
  127. package/src/components/OtpInput/index.ts +0 -2
  128. package/src/components/PdfView/PdfView.test.tsx +0 -52
  129. package/src/components/PdfView/PdfView.tsx +0 -116
  130. package/src/components/PdfView/index.ts +0 -2
  131. package/src/components/Progress/Progress.test.tsx +0 -43
  132. package/src/components/Progress/Progress.tsx +0 -35
  133. package/src/components/Progress/index.ts +0 -1
  134. package/src/components/RadioButton/RadioButton.test.tsx +0 -56
  135. package/src/components/RadioButton/RadioButton.tsx +0 -43
  136. package/src/components/RadioButton/index.ts +0 -1
  137. package/src/components/Switch/Switch.test.tsx +0 -83
  138. package/src/components/Switch/Switch.tsx +0 -38
  139. package/src/components/Switch/index.ts +0 -1
  140. package/src/components/Tag/Tag.css +0 -14
  141. package/src/components/Tag/Tag.test.tsx +0 -61
  142. package/src/components/Tag/Tag.tsx +0 -19
  143. package/src/components/Tag/index.ts +0 -1
  144. package/src/components/Tooltip/Tooltip.test.tsx +0 -68
  145. package/src/components/Tooltip/Tooltip.tsx +0 -38
  146. package/src/components/Tooltip/index.ts +0 -2
  147. package/src/components/index.ts +0 -15
  148. package/src/index.ts +0 -1
  149. package/src/theme/colors.ts +0 -3
  150. package/src/typings.d.ts +0 -1
  151. /package/{src/components/Map → dist}/GoogleMap.module.scss +0 -0
  152. /package/{src/components/Modal → dist}/Modal.module.scss +0 -0
  153. /package/{src/components/Notification → dist}/Notification.module.scss +0 -0
  154. /package/{src/components/OtpInput → dist}/OtpInput.module.scss +0 -0
  155. /package/{src/components/PdfView → dist}/PdfView.module.scss +0 -0
  156. /package/{src/components/Tooltip → dist}/Tooltip.module.scss +0 -0
  157. /package/{src/theme/colors → dist}/colors.scss +0 -0
  158. /package/{src/theme/Typography → dist}/typography.scss +0 -0
@@ -1,186 +0,0 @@
1
- import React, { useState, useRef, useEffect } from "react";
2
- import {
3
- GoogleMap,
4
- Marker,
5
- Circle,
6
- DirectionsRenderer,
7
- } from "@react-google-maps/api";
8
- import { useGoogleMapsLoader } from "./GoogleMapsLoader";
9
- import styles from './GoogleMap.module.scss'
10
- export interface MapComponentProps {
11
- containerClassName?: string;
12
- zoom?: number;
13
- mapOptions?: google.maps.MapOptions;
14
- radius?: number;
15
- googleMapsUrls: string[];
16
- buttonText: string;
17
- buttonClassName: string;
18
- }
19
-
20
- const MapComponent: React.FC<MapComponentProps> = ({
21
- containerClassName = "map-container",
22
- zoom = 18,
23
- mapOptions = {
24
- zoomControl: true,
25
- tilt: 0,
26
- gestureHandling: "auto",
27
- mapTypeId: "roadmap",
28
- },
29
- radius = 5000,
30
- googleMapsUrls,
31
- buttonText,
32
- buttonClassName,
33
- }) => {
34
- const [location, setLocation] = useState<{
35
- latitude: number;
36
- longitude: number;
37
- } | null>(null);
38
- const [mapVisible, setMapVisible] = useState(false);
39
- const [directionsResponse, setDirectionsResponse] =
40
- useState<google.maps.DirectionsResult | null>(null);
41
- const mapRef = useRef<google.maps.Map | null>(null);
42
- const directionsService = useRef<google.maps.DirectionsService | null>(null);
43
- const directionsRenderer = useRef<google.maps.DirectionsRenderer | null>(
44
- null
45
- );
46
-
47
- const handleLocationRequest = () => {
48
- if ("geolocation" in navigator) {
49
- navigator.geolocation.getCurrentPosition(
50
- ({ coords }) => {
51
- const { latitude, longitude } = coords;
52
- setLocation({ latitude, longitude });
53
- setMapVisible(true);
54
- },
55
- () => {
56
- alert("Failed to get location. Please try again.");
57
- }
58
- );
59
- } else {
60
- alert("Geolocation is not supported by this browser.");
61
- }
62
- };
63
-
64
- const handleMarkerClick = (lat: number, lng: number) => {
65
- if (location) {
66
- const directionsServiceInstance =
67
- directionsService.current || new google.maps.DirectionsService();
68
- const directionsRendererInstance =
69
- directionsRenderer.current || new google.maps.DirectionsRenderer();
70
-
71
- if (!directionsService.current)
72
- directionsService.current = directionsServiceInstance;
73
- if (!directionsRenderer.current)
74
- directionsRenderer.current = directionsRendererInstance;
75
-
76
- const directionsRequest: google.maps.DirectionsRequest = {
77
- origin: { lat: location.latitude, lng: location.longitude },
78
- destination: { lat, lng },
79
- travelMode: google.maps.TravelMode.DRIVING,
80
- };
81
-
82
- directionsService.current.route(directionsRequest, (result, status) => {
83
- if (status === google.maps.DirectionsStatus.OK) {
84
- setDirectionsResponse(result);
85
- if (mapRef.current && directionsRenderer.current) {
86
- directionsRenderer.current.setMap(mapRef.current);
87
- directionsRenderer.current.setDirections(result);
88
- }
89
- } else {
90
- alert("Failed to get directions. Please try again.");
91
- }
92
- });
93
- }
94
- };
95
-
96
- const extractCoordinatesFromUrl = (url: string) => {
97
- const regex = /@(-?\d+\.\d+),(-?\d+\.\d+)/;
98
- const match = url.match(regex);
99
- if (match) {
100
- return {
101
- lat: parseFloat(match[1]),
102
- lng: parseFloat(match[2]),
103
- };
104
- }
105
-
106
- return null;
107
- };
108
-
109
- const { isLoaded } = useGoogleMapsLoader();
110
-
111
- useEffect(() => {}, [isLoaded]);
112
-
113
- useEffect(() => {}, [mapVisible]);
114
-
115
- if (!isLoaded) {
116
- return <div>Loading map...</div>;
117
- }
118
-
119
- if (mapVisible && location) {
120
- return (
121
- <div className={containerClassName}>
122
- <button onClick={handleLocationRequest} className={buttonClassName}>
123
- {buttonText}
124
- </button>
125
-
126
- <GoogleMap
127
- mapContainerStyle={styles.mapContainerStyle}
128
- center={{ lat: location.latitude, lng: location.longitude }}
129
- zoom={zoom}
130
- options={mapOptions}
131
- onLoad={(map) => {
132
- mapRef.current = map;
133
- directionsRenderer.current = new google.maps.DirectionsRenderer();
134
- directionsRenderer.current.setMap(map);
135
- }}
136
- >
137
- <Marker
138
- position={{ lat: location.latitude, lng: location.longitude }}
139
- icon="http://maps.google.com/mapfiles/ms/icons/red-dot.png"
140
- />
141
- <Circle
142
- center={{ lat: location.latitude, lng: location.longitude }}
143
- radius={radius}
144
- options={{
145
- strokeColor: "#FF0000",
146
- strokeOpacity: 0.8,
147
- strokeWeight: 2,
148
- fillColor: "#FF0000",
149
- fillOpacity: 0,
150
- }}
151
- />
152
- {googleMapsUrls.map((url, index) => {
153
- const coord = extractCoordinatesFromUrl(url);
154
- if (!coord) return null;
155
-
156
- return (
157
- <Marker
158
- key={index}
159
- position={{ lat: coord.lat, lng: coord.lng }}
160
- title={`Sample Location ${index + 1}`}
161
- icon="http://maps.google.com/mapfiles/ms/icons/blue-dot.png"
162
- onClick={() => handleMarkerClick(coord.lat, coord.lng)}
163
- />
164
- );
165
- })}
166
- {directionsResponse && (
167
- <DirectionsRenderer
168
- directions={directionsResponse}
169
- options={{ suppressMarkers: true }}
170
- />
171
- )}
172
- </GoogleMap>
173
- </div>
174
- );
175
- } else {
176
- return (
177
- <div className={containerClassName}>
178
- <button onClick={handleLocationRequest} className={buttonClassName}>
179
- {buttonText}
180
- </button>
181
- </div>
182
- );
183
- }
184
- };
185
-
186
- export default MapComponent;
@@ -1,12 +0,0 @@
1
- import { useJsApiLoader } from '@react-google-maps/api';
2
-
3
- const GOOGLE_MAPS_API_KEY = process.env.NEXT_PUBLIC_GOOGLE_MAP_API as string; // Ensure you are using environment variable
4
-
5
- export const useGoogleMapsLoader = () => {
6
- return useJsApiLoader({
7
- googleMapsApiKey: GOOGLE_MAPS_API_KEY, // Replace with your API key
8
- libraries: ['places', 'drawing', 'geometry'], // Include all libraries you need
9
- language: 'en',
10
- region: 'US',
11
- });
12
- };
@@ -1,3 +0,0 @@
1
- export { default as Directions } from "./Directions";
2
- export { default as GoogleMap } from "./GoogleMap";
3
- import "./GoogleMap.module.scss"
@@ -1,74 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, fireEvent } from '@testing-library/react';
3
- import Modal from './Modal';
4
-
5
- describe('Modal Component', () => {
6
- const onCloseMock = jest.fn();
7
- const modalContentText = 'This is the modal content';
8
-
9
- const renderModal = (
10
- isOpen: boolean,
11
- modalOverlayClassname?: string,
12
- modalContentClassname?: string
13
- ) => {
14
- render(
15
- <Modal
16
- isOpen={isOpen}
17
- onClose={onCloseMock}
18
- modalOverlayClassname={modalOverlayClassname}
19
- modalContentClassname={modalContentClassname}
20
- >
21
- <div>{modalContentText}</div>
22
- </Modal>
23
- );
24
- };
25
-
26
- afterEach(() => {
27
- jest.clearAllMocks();
28
- });
29
-
30
- it('renders the modal when isOpen is true', () => {
31
- renderModal(true);
32
- expect(screen.getByText(modalContentText)).toBeInTheDocument();
33
- });
34
-
35
- it('does not render the modal when isOpen is false', () => {
36
- renderModal(false);
37
- expect(screen.queryByText(modalContentText)).not.toBeInTheDocument();
38
- });
39
-
40
- it('calls onClose when clicking on the overlay', () => {
41
- renderModal(true);
42
- const overlay = screen.getByText(modalContentText).closest('button');
43
- fireEvent.click(overlay!);
44
- expect(onCloseMock).toHaveBeenCalled();
45
- });
46
-
47
- it('does not call onClose when clicking inside the modal content', () => {
48
- renderModal(true);
49
- const modalContent = screen.getByText(modalContentText);
50
- fireEvent.click(modalContent);
51
- expect(onCloseMock).not.toHaveBeenCalled();
52
- });
53
-
54
- it('applies the provided modalOverlayClassname', () => {
55
- const overlayClass = 'customOverlayClass';
56
- renderModal(true, overlayClass);
57
- const overlay = screen.getByText(modalContentText).closest('button');
58
- expect(overlay).toHaveClass(overlayClass);
59
- });
60
-
61
- it('applies the provided modalContentClassname', () => {
62
- const contentClass = 'customContentClass';
63
- renderModal(true, undefined, contentClass);
64
- const modalContent = screen.getByText(modalContentText);
65
- expect(modalContent.parentElement).toHaveClass(contentClass);
66
- });
67
-
68
- it('does not render modal when isOpen is false, even if modalOverlayClassname and modalContentClassname are provided', () => {
69
- const overlayClass = 'customOverlayClass';
70
- const contentClass = 'customContentClass';
71
- renderModal(false, overlayClass, contentClass);
72
- expect(screen.queryByText(modalContentText)).not.toBeInTheDocument();
73
- });
74
- });
@@ -1,39 +0,0 @@
1
- import React from "react";
2
- import styles from './Modal.module.scss';
3
-
4
- interface ModalProps {
5
- isOpen: boolean;
6
- onClose: () => void;
7
- children: React.ReactNode;
8
- modalOverlayClassname?: string;
9
- modalContentClassname?: string;
10
- }
11
-
12
- const Modal: React.FC<ModalProps> = ({
13
- isOpen,
14
- onClose,
15
- children,
16
- modalOverlayClassname = '',
17
- modalContentClassname = ''
18
- }) => {
19
- if (!isOpen) return null;
20
-
21
- const handleOverlayClick = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
22
- if (event.target === event.currentTarget) {
23
- onClose();
24
- }
25
- };
26
-
27
- return (
28
- <button
29
- className={`${styles.modalOverlay} ${modalOverlayClassname}`}
30
- onClick={handleOverlayClick}
31
- >
32
- <div className={`${styles.modalContent} ${modalContentClassname}`}>
33
- {children}
34
- </div>
35
- </button>
36
- );
37
- };
38
-
39
- export default Modal;
@@ -1,2 +0,0 @@
1
- export { default } from "./Modal";
2
- import "./Modal.module.scss"
@@ -1,53 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3
- import Notification, { NotificationProps } from './Notification';
4
-
5
- describe('Notification Component', () => {
6
- const defaultProps: NotificationProps = {
7
- message: 'Test Message',
8
- severity: 'info',
9
- autoHideDuration: 6000,
10
- onClose: jest.fn(),
11
- };
12
-
13
- const renderNotification = (props: Partial<NotificationProps> = {}) => {
14
- return render(<Notification {...defaultProps} {...props} />);
15
- };
16
-
17
- test('renders notification with the correct message', () => {
18
- render(<Notification message="Test Message" severity="info" />);
19
-
20
- // Check if the element exists by querying it
21
- const notificationElement = screen.getByText('Test Message');
22
- expect(notificationElement).not.toBeNull(); // Equivalent to `toBeInTheDocument`
23
-
24
- // Alternatively, check for the presence of the role or className
25
- const alertElement = screen.getByRole('alert');
26
- expect(alertElement.className).toContain('info'); // Check if className includes "info"
27
- });
28
-
29
- test('calls onClose when the notification is clicked', () => {
30
- const onClose = jest.fn();
31
- renderNotification({ onClose });
32
-
33
- fireEvent.click(screen.getByRole('alert'));
34
-
35
- expect(onClose).toHaveBeenCalled();
36
- });
37
-
38
- test('calls onClose when the close button is clicked', () => {
39
- const onClose = jest.fn();
40
- renderNotification({ onClose });
41
-
42
- fireEvent.click(screen.getByLabelText('Close notification'));
43
-
44
- expect(onClose).toHaveBeenCalledWith(expect.anything(), 'close');
45
- });
46
-
47
- test('calls onClose after autoHideDuration expires', async () => {
48
- const onClose = jest.fn();
49
- renderNotification({ onClose, autoHideDuration: 1000 });
50
-
51
- await waitFor(() => expect(onClose).toHaveBeenCalledWith(expect.anything(), 'timeout'), { timeout: 1500 });
52
- });
53
- });
@@ -1,42 +0,0 @@
1
- import React, { useEffect } from "react";
2
- import './Notification.module.scss';
3
- export interface NotificationProps {
4
- message: string;
5
- severity?: 'error' | 'warning' | 'info' | 'success';
6
- autoHideDuration?: number;
7
- onClose?: (event: React.SyntheticEvent<any> | Event, reason?: string) => void;
8
- }
9
-
10
- const Notification: React.FC<NotificationProps> = ({
11
- message,
12
- severity = 'info',
13
- autoHideDuration = 6000,
14
- onClose,
15
- }) => {
16
- useEffect(() => {
17
- if (autoHideDuration && onClose) {
18
- const timer = setTimeout(() => {
19
- onClose(new Event('timeout'), 'timeout');
20
- }, autoHideDuration);
21
-
22
- return () => clearTimeout(timer);
23
- }
24
- }, [autoHideDuration, onClose]);
25
-
26
- const handleClose = (event: React.SyntheticEvent<any> | Event, reason?: string) => {
27
- if (onClose) {
28
- onClose(event, reason);
29
- }
30
- };
31
-
32
- return (
33
- <div className={`notification ${severity}`} onClick={(e) => handleClose(e)} role="alert">
34
- <div className="notification-message">{message}</div>
35
- <button className="close-button" onClick={(e) => handleClose(e, 'close')} aria-label="Close notification">
36
- &times;
37
- </button>
38
- </div>
39
- );
40
- };
41
-
42
- export default Notification;
@@ -1,2 +0,0 @@
1
- export { default } from "./Notification";
2
- import "./Notification.module.scss"
@@ -1,53 +0,0 @@
1
- import React from 'react';
2
- import { render, fireEvent, screen } from '@testing-library/react';
3
- import OTPInput from './OtpInput';
4
- import '@testing-library/jest-dom';
5
-
6
- describe('OTPInput Component', () => {
7
- it('renders the correct number of input fields based on the length prop', () => {
8
- render(
9
- <OTPInput
10
- length={4}
11
- onChange={() => {}}
12
- onResend={() => {}}
13
- resendText="Resend OTP"
14
- />
15
- );
16
- const inputs = screen.getAllByRole('textbox');
17
- expect(inputs).toHaveLength(4);
18
- });
19
- it('calls onChange prop when input changes', () => {
20
- const handleChange = jest.fn();
21
- render(<OTPInput length={4} onChange={handleChange} onResend={() => {}} resendText="Resend OTP" />);
22
- const inputs = screen.getAllByRole('textbox');
23
- fireEvent.change(inputs[0], { target: { value: '1' } });
24
- expect(handleChange).toHaveBeenCalledWith('1');
25
- });
26
-
27
- it('calls onResend prop when the resend button is clicked', async () => {
28
- const handleResend = jest.fn();
29
- render(<OTPInput length={4} onChange={() => {}} onResend={handleResend} resendText="Resend OTP" resendDelay={0} />);
30
- const resendButton = screen.getByRole('button', { name: /resend otp/i });
31
- fireEvent.click(resendButton);
32
- expect(handleResend).toHaveBeenCalled();
33
- });
34
- it('displays error text when the error prop is true', () => {
35
- const errorMessage = 'Invalid OTP';
36
- render(<OTPInput length={4} onChange={() => {}} onResend={() => {}} resendText="Resend OTP" error={true} errorText={errorMessage} />);
37
- const errorElement = screen.getByText(errorMessage);
38
- expect(errorElement).toBeInTheDocument();
39
- });
40
- it('changes border color to red when the error prop is true', () => {
41
- render(
42
- <OTPInput
43
- length={4}
44
- onChange={() => {}}
45
- onResend={() => {}}
46
- resendText="Resend OTP"
47
- error={true}
48
- />
49
- );
50
- const firstInput = screen.getByTestId('otp-input-0');
51
- expect(firstInput).toHaveStyle('border: 1px solid #EB0542');
52
- });
53
- });
@@ -1,137 +0,0 @@
1
- import React, { useEffect, useState } from "react";
2
- import "./OtpInput.module.scss";
3
- interface OTPInputProps {
4
- length?: number;
5
- // eslint-disable-next-line no-unused-vars
6
- onChange: (otp: string) => void;
7
- autoFocus?: boolean;
8
- onResend: () => void;
9
- resendDelay?: number;
10
- error?: boolean;
11
- errorText?: string;
12
- resendText: string;
13
- }
14
-
15
- const OTPInput: React.FC<OTPInputProps> = ({
16
- length = 4,
17
- onChange,
18
- autoFocus = false,
19
- onResend,
20
- resendDelay = 60,
21
- error = false,
22
- errorText,
23
- resendText,
24
- }) => {
25
- const [otp, setOtp] = useState<string[]>(Array(length).fill(""));
26
- const [timer, setTimer] = useState<number>(resendDelay);
27
- const [isComplete, setIsComplete] = useState<boolean>(false);
28
-
29
- useEffect(() => {
30
- const countdown = setInterval(() => {
31
- setTimer((prevTimer) => (prevTimer > 0 ? prevTimer - 1 : 0));
32
- }, 1000);
33
-
34
- return () => clearInterval(countdown);
35
- }, []);
36
- const handleChange = (value: string, index: number) => {
37
- if (isNaN(Number(value))) return;
38
-
39
- const newOtp = [...otp];
40
- newOtp[index] = value;
41
- setOtp(newOtp);
42
- onChange(newOtp.join(""));
43
-
44
- if (value && index < length - 1) {
45
- const nextInput = document.getElementById(
46
- `otp-input-${index + 1}`
47
- ) as HTMLInputElement;
48
- if (nextInput) {
49
- nextInput.focus();
50
- }
51
- }
52
- };
53
-
54
- const handleKeyDown = (
55
- e: React.KeyboardEvent<HTMLInputElement>,
56
- index: number
57
- ) => {
58
- if (e.key === "Backspace" && !otp[index] && index > 0) {
59
- const prevInput = document.getElementById(
60
- `otp-input-${index - 1}`
61
- ) as HTMLInputElement;
62
- if (prevInput) {
63
- prevInput.focus();
64
- }
65
- }
66
- };
67
-
68
- const handleResendClick = () => {
69
- onResend();
70
- setOtp(Array(length).fill(""));
71
- setTimer(resendDelay);
72
- setIsComplete(false);
73
- };
74
-
75
- useEffect(() => {
76
- setIsComplete(otp.every((digit) => digit !== ""));
77
- }, [otp]);
78
-
79
- useEffect(() => {
80
- if (error) {
81
- setTimer(0);
82
- }
83
- }, [error]);
84
-
85
- function getReadableStatus() {
86
- if (error) {
87
- return "#EB0542";
88
- }
89
- return isComplete ? "#00B578" : "#A7A7A7";
90
- }
91
- return (
92
- <div className="otpMainContainer">
93
- <div className="otpInputDiv">
94
- {Array(length)
95
- .fill("")
96
- .map((_, index) => (
97
- <input
98
- key={index}
99
- type="text"
100
- id={`otp-input-${index}`}
101
- value={otp[index]}
102
- data-testid={`otp-input-${index}`}
103
- role="textbox"
104
- onChange={(e) => handleChange(e.target.value, index)}
105
- onKeyDown={(e) => handleKeyDown(e, index)}
106
- maxLength={1}
107
- style={{ border: `1px solid ${getReadableStatus()}` }}
108
- className="otpInput"
109
- autoFocus={autoFocus && index === 0}
110
- />
111
- ))}
112
- </div>
113
- <div className="resendContainer">
114
- {error ? (
115
- <div className="errorText">{errorText}</div>
116
- ) : (
117
- <div className="timerText">
118
- {timer > 0 ? `00:${timer} secs` : ""}
119
- </div>
120
- )}
121
- <button
122
- onClick={handleResendClick}
123
- disabled={timer > 0}
124
- style={{
125
- border: "none",
126
- background: "none",
127
- cursor: timer > 0 ? "not-allowed" : "pointer",
128
- }}
129
- >
130
- <div className="resendText">{resendText}</div>
131
- </button>
132
- </div>
133
- </div>
134
- );
135
- };
136
-
137
- export default OTPInput;
@@ -1,2 +0,0 @@
1
- export { default } from "./OtpInput";
2
- import "./OtpInput.module.scss"
@@ -1,52 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
- import PdfView from './PdfView';
5
-
6
- // Dummy base64 content for testing
7
- const validBase64Content = 'JVBERi0xLjQKJeLjz9MNCjEgMCBvYmoKPDwvTGluay9QYWdlcyAyIDAgUj4+CnN0YXJ0eHJlZgoyNCAwIFIKZW5kb2JqCjEgMCBvYmoKPDwvTGluay9QYWdlcyAyIDAgUj4+CnN0YXJ0eHJlZgo2IDAgUgo+';
8
- const invalidBase64Content = 'invalid base64 content';
9
- const errorText = 'Failed to load PDF';
10
- const buttonText = 'View PDF';
11
- const loadingText = 'Loading...';
12
-
13
- // Save the original implementation of createObjectURL
14
- const originalCreateObjectURL = global.URL.createObjectURL;
15
-
16
- describe('PdfView Component', () => {
17
- beforeAll(() => {
18
- // Mock URL.createObjectURL directly
19
- global.URL.createObjectURL = jest.fn(() => 'mock-url');
20
- });
21
-
22
- afterAll(() => {
23
- // Restore the original implementation
24
- global.URL.createObjectURL = originalCreateObjectURL;
25
- });
26
-
27
- it('renders correctly with default props', () => {
28
- render(<PdfView content={validBase64Content} />);
29
- expect(screen.getByText(buttonText)).toBeInTheDocument();
30
- });
31
-
32
- it('shows error message if content is invalid', () => {
33
- render(<PdfView content={invalidBase64Content} />);
34
- expect(screen.getByText(errorText)).toBeInTheDocument();
35
- });
36
-
37
- it('applies the provided class names', () => {
38
- const className = 'custom-class';
39
- render(<PdfView content={validBase64Content} className={className} />);
40
- expect(screen.getByText(buttonText).parentElement).toHaveClass(className);
41
- });
42
-
43
-
44
-
45
- it('does not show spinner or loading text if isLoading is false', () => {
46
- render(<PdfView content={validBase64Content} />);
47
-
48
- // The component should not be in a loading state initially
49
- expect(screen.queryByTestId('spinnertest')).not.toBeInTheDocument();
50
- expect(screen.queryByText(loadingText)).not.toBeInTheDocument();
51
- });
52
- });