diff --git a/src/assets/css/app.css b/src/assets/css/app.css index b3a8613975..bd34d56907 100644 --- a/src/assets/css/app.css +++ b/src/assets/css/app.css @@ -3442,6 +3442,7 @@ textarea.form-control.is-invalid { } } +/* To remove the green and replace by greyish hover , make changes here */ .btn:hover { color: var(--bs-btn-hover-color); background-color: var(--bs-btn-hover-bg); @@ -14066,6 +14067,7 @@ fieldset:disabled .btn { .btn-warning, .btn-info { color: #fff; + /* isolation: isolate; */ } .btn-primary:hover, @@ -14079,8 +14081,27 @@ fieldset:disabled .btn { .btn-info:hover, .btn-info:active { color: #fff !important; + box-shadow: inset 50px 50px 40px rgba(0, 0, 0, 0.5); + background-blend-mode: multiply; + /* background-color: #6c757d ; */ + /* filter: brightness(0.85); */ } +/* .btn-primary{ + --hover-bg: #6c757d !important; +} + + +.btn-primary:hover, +.btn-primary:active{ + --hover-bg: hsl(var(--button-hue, 0), 100%, 60%) !important; +} + +.btn-primary:hover, +.btn-primary:active{ + --hover-bg: hsl(var(--button-hue, 0), 100%, 0%) !important; +} */ + .btn-outline-primary:hover, .btn-outline-primary:active, .btn-outline-secondary:hover, diff --git a/src/components/EventCalendar/EventCalendar.module.css b/src/components/EventCalendar/EventCalendar.module.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/components/EventCalendar/EventHeader.tsx b/src/components/EventCalendar/EventHeader.tsx index d8f949ca97..d338de3b82 100644 --- a/src/components/EventCalendar/EventHeader.tsx +++ b/src/components/EventCalendar/EventHeader.tsx @@ -72,6 +72,7 @@ function eventHeader({ id="dropdown-basic" className={styles.dropdown} data-testid="selectViewType" + style={{ width: '100%' }} > {viewType} @@ -100,6 +101,7 @@ function eventHeader({ id="dropdown-basic" className={styles.dropdown} data-testid="eventType" + style={{ width: '100%' }} > {t('eventType')} diff --git a/src/components/OrgListCard/OrgListCard.tsx b/src/components/OrgListCard/OrgListCard.tsx index 10365d2364..cf651e9dfe 100644 --- a/src/components/OrgListCard/OrgListCard.tsx +++ b/src/components/OrgListCard/OrgListCard.tsx @@ -1,4 +1,6 @@ import React from 'react'; +import TruncatedText from './TruncatedText'; +// import {useState} from 'react'; import FlaskIcon from 'assets/svgs/flask.svg?react'; import Button from 'react-bootstrap/Button'; import { useTranslation } from 'react-i18next'; @@ -94,17 +96,18 @@ function orgListCard(props: InterfaceOrgListCardProps): JSX.Element {

{name}

{/* Description of the organization */} -
- {userData?.organizations[0].description} -
+
+ +
+ {/* Display the organization address if available */} - {address && address.city && ( + {address?.city && (
-
- {address.line1}, - {address.city}, - {address.countryCode} -
+
)} {/* Display the number of admins and members */} diff --git a/src/components/OrgListCard/TruncatedText.tsx b/src/components/OrgListCard/TruncatedText.tsx new file mode 100644 index 0000000000..94617178cb --- /dev/null +++ b/src/components/OrgListCard/TruncatedText.tsx @@ -0,0 +1,80 @@ +import React, { useState, useEffect, useRef } from 'react'; +import useDebounce from './useDebounce'; + +/** + * Props for the `TruncatedText` component. + * + * Includes the text to be displayed and an optional maximum width override. + */ +interface InterfaceTruncatedTextProps { + /** The full text to display. It may be truncated if it exceeds the maximum width. */ + text: string; + /** Optional: Override the maximum width for truncation. */ + maxWidthOverride?: number; +} + +/** + * A React functional component that displays text and truncates it with an ellipsis (`...`) + * if the text exceeds the available width or the `maxWidthOverride` value. + * + * The component adjusts the truncation dynamically based on the available space + * or the `maxWidthOverride` value. It also listens for window resize events to reapply truncation. + * + * @param props - The props for the component. + * @returns A heading element (`
`) containing the truncated or full text. + * + * @example + * ```tsx + * + * ``` + */ +const TruncatedText: React.FC = ({ + text, + maxWidthOverride, +}) => { + const [truncatedText, setTruncatedText] = useState(''); + const textRef = useRef(null); + + const { debouncedCallback, cancel } = useDebounce(() => { + truncateText(); + }, 100); + + /** + * Truncate the text based on the available width or the `maxWidthOverride` value. + */ + const truncateText = (): void => { + const element = textRef.current; + if (element) { + const maxWidth = maxWidthOverride || element.offsetWidth; + const fullText = text; + + const computedStyle = getComputedStyle(element); + const fontSize = parseFloat(computedStyle.fontSize); + const charPerPx = 0.065 + fontSize * 0.002; + const maxChars = Math.floor(maxWidth * charPerPx); + + setTruncatedText( + fullText.length > maxChars + ? `${fullText.slice(0, maxChars - 3)}...` + : fullText, + ); + } + }; + + useEffect(() => { + truncateText(); + window.addEventListener('resize', debouncedCallback); + return () => { + cancel(); + window.removeEventListener('resize', debouncedCallback); + }; + }, [text, maxWidthOverride, debouncedCallback, cancel]); + + return ( +
+ {truncatedText} +
+ ); +}; + +export default TruncatedText; diff --git a/src/components/OrgListCard/useDebounce.tsx b/src/components/OrgListCard/useDebounce.tsx new file mode 100644 index 0000000000..8ad30386e0 --- /dev/null +++ b/src/components/OrgListCard/useDebounce.tsx @@ -0,0 +1,42 @@ +import { useRef, useCallback } from 'react'; + +/** + * A custom React hook for debouncing a callback function. + * It delays the execution of the callback until after a specified delay has elapsed + * since the last time the debounced function was invoked. + * + * @param callback - The function to debounce. + * @param delay - The delay in milliseconds to wait before invoking the callback. + * @returns An object with the `debouncedCallback` function and a `cancel` method to clear the timeout. + */ +function useDebounce void>( + callback: T, + delay: number, +): { debouncedCallback: (...args: Parameters) => void; cancel: () => void } { + const timeoutRef = useRef(); + + /** + * The debounced version of the provided callback function. + * This function resets the debounce timer on each call, ensuring the callback + * is invoked only after the specified delay has elapsed without further calls. + * + * @param args - The arguments to pass to the callback when invoked. + */ + const debouncedCallback = useCallback( + (...args: Parameters) => { + if (timeoutRef.current) clearTimeout(timeoutRef.current); + timeoutRef.current = window.setTimeout(() => { + callback(...args); + }, delay); + }, + [callback, delay], + ); + + const cancel = useCallback(() => { + if (timeoutRef.current) clearTimeout(timeoutRef.current); + }, []); + + return { debouncedCallback, cancel }; +} + +export default useDebounce; diff --git a/src/components/UsersTableItem/UsersTableItem.tsx b/src/components/UsersTableItem/UsersTableItem.tsx index 9e94b8a9f5..6da3c1d6f4 100644 --- a/src/components/UsersTableItem/UsersTableItem.tsx +++ b/src/components/UsersTableItem/UsersTableItem.tsx @@ -161,6 +161,7 @@ const UsersTableItem = (props: Props): JSX.Element => { {user.user.email}