From db0bc61b86704435ebbd4263264bb66b06464d69 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:01:05 +0530 Subject: [PATCH 1/7] refactor: optimize updatedOptions with useMemo for performance Signed-off-by: Amit Amrutiya --- src/custom/ResponsiveDataTable.tsx | 62 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/custom/ResponsiveDataTable.tsx b/src/custom/ResponsiveDataTable.tsx index 55098698..230822db 100644 --- a/src/custom/ResponsiveDataTable.tsx +++ b/src/custom/ResponsiveDataTable.tsx @@ -307,42 +307,45 @@ const ResponsiveDataTable = ({ year: 'numeric' }; - return new Intl.DateTimeFormat('un-US', dateOptions).format(date); + return new Intl.DateTimeFormat('en-US', dateOptions).format(date); }; - const updatedOptions = { - ...options, - print: false, - download: false, - search: false, - filter: false, - viewColumns: false, - rowsPerPageOptions: rowsPerPageOptions, - onViewColumnsChange: (column: string, action: string) => { - switch (action) { - case 'add': { - const colToAdd = columns.find((obj) => obj.name === column); - if (colToAdd) { - if (colToAdd.options) { - colToAdd.options.display = true; - updateCols && updateCols([...columns]); + const updatedOptions = React.useMemo( + () => ({ + ...options, + print: false, + download: false, + search: false, + filter: false, + viewColumns: false, + rowsPerPageOptions: rowsPerPageOptions, + onViewColumnsChange: (column: string, action: string) => { + switch (action) { + case 'add': { + const colToAdd = columns.find((obj) => obj.name === column); + if (colToAdd) { + if (colToAdd.options) { + colToAdd.options.display = true; + updateCols && updateCols([...columns]); + } } + break; } - break; - } - case 'remove': { - const colToRemove = columns.find((obj) => obj.name === column); - if (colToRemove) { - if (colToRemove.options) { - colToRemove.options.display = false; - updateCols && updateCols([...columns]); + case 'remove': { + const colToRemove = columns.find((obj) => obj.name === column); + if (colToRemove) { + if (colToRemove.options) { + colToRemove.options.display = false; + updateCols && updateCols([...columns]); + } } + break; } - break; } } - } - }; + }), + [options, rowsPerPageOptions, columns, updateCols] + ); const updateColumnsEffect = useCallback(() => { columns?.forEach((col) => { @@ -385,8 +388,7 @@ const ResponsiveDataTable = ({ } }); updateCols && updateCols([...columns]); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [columnVisibility, updateCols, data]); + }, [columnVisibility, updateCols, columns]); React.useEffect(() => { updateColumnsEffect(); From b5f0f955b85626a4c447f0fbb40d6efc37af45d2 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:01:42 +0530 Subject: [PATCH 2/7] refactor: rename getBackground to getCatalogCardBackground for clarity Signed-off-by: Amit Amrutiya --- src/custom/CustomCatalog/style.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/custom/CustomCatalog/style.tsx b/src/custom/CustomCatalog/style.tsx index 38fb8005..4fa95643 100644 --- a/src/custom/CustomCatalog/style.tsx +++ b/src/custom/CustomCatalog/style.tsx @@ -348,15 +348,16 @@ export const CardBack = styled('div')(({ isCatalog }) => ({ }) })); -const getBackground = (isLightMode: boolean) => { +export const getCatalogCardBackground = (isLightMode: boolean) => { const lightGradient = `linear-gradient(to left bottom, ${WHITESMOKE}, ${GRAY97},white, white, white, white, white, white, white, white, ${WHITESMOKE}, ${GRAY97})`; const darkGradient = `linear-gradient(to right top, ${DARK_PRIMARY_COLOR}, ${accentGrey[30]}, ${accentGrey[20]}, ${accentGrey[10]}, ${accentGrey[10]}, ${accentGrey[10]}, ${accentGrey[10]}, ${accentGrey[10]}, ${accentGrey[10]}, ${charcoal[20]}, ${charcoal[10]}, black)`; return isLightMode ? lightGradient : darkGradient; }; + export const CardFront = styled('div')(({ shouldFlip, isDetailed, theme }) => { const isLightMode = theme.palette.mode === 'light'; - const background = getBackground(isLightMode); + const background = getCatalogCardBackground(isLightMode); const boxShadow = `2px 2px 3px 0px ${theme.palette.background.brand?.default}`; return { @@ -414,7 +415,7 @@ export const DesignAuthorName = styled('div')(() => ({ export const CatalogEmptyStateDiv = styled('div')(({ theme }) => { const isLightMode = theme.palette.mode === 'light'; - const background = getBackground(isLightMode); + const background = getCatalogCardBackground(isLightMode); const boxShadow = `2px 2px 3px 0px ${theme.palette.background.brand?.default}`; return { From df1613339f293c2bfe5b8fe8136732e9cc3aeb48 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:02:16 +0530 Subject: [PATCH 3/7] feat: add TrophyIcon component and export from icons index Signed-off-by: Amit Amrutiya --- src/icons/Tropy/TropyIcon.tsx | 28 ++++++++++++++++++++++++++++ src/icons/Tropy/index.ts | 1 + src/icons/index.ts | 1 + 3 files changed, 30 insertions(+) create mode 100644 src/icons/Tropy/TropyIcon.tsx create mode 100644 src/icons/Tropy/index.ts diff --git a/src/icons/Tropy/TropyIcon.tsx b/src/icons/Tropy/TropyIcon.tsx new file mode 100644 index 00000000..61c27069 --- /dev/null +++ b/src/icons/Tropy/TropyIcon.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +interface TrophyIconProps { + width?: string; + height?: string; + fill?: string; + style?: React.CSSProperties; +} + +const TrophyIcon: React.FC = ({ + width = '24', + height = '24', + fill = 'currentColor', + style = {} +}) => ( + + + +); + +export default TrophyIcon; diff --git a/src/icons/Tropy/index.ts b/src/icons/Tropy/index.ts new file mode 100644 index 00000000..7f82f5cc --- /dev/null +++ b/src/icons/Tropy/index.ts @@ -0,0 +1 @@ +export { default as TropyIcon } from './TropyIcon'; diff --git a/src/icons/index.ts b/src/icons/index.ts index 22a3a721..1f0b66b8 100644 --- a/src/icons/index.ts +++ b/src/icons/index.ts @@ -94,6 +94,7 @@ export * from './TerminalIcon'; export * from './Toolkit'; export * from './Touch'; export * from './Triangle'; +export * from './Tropy'; export * from './Undeploy'; export * from './Undo'; export * from './Validate'; From 1acf7004cb09dd3ad01677ca2d0c6189673c590d Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:02:57 +0530 Subject: [PATCH 4/7] feat: add PerformersSectionButton component with tooltip and skeleton loading Signed-off-by: Amit Amrutiya --- .../PerformersToogleButton.tsx | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/custom/PerformersSection/PerformersToogleButton.tsx diff --git a/src/custom/PerformersSection/PerformersToogleButton.tsx b/src/custom/PerformersSection/PerformersToogleButton.tsx new file mode 100644 index 00000000..a0555408 --- /dev/null +++ b/src/custom/PerformersSection/PerformersToogleButton.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { Button, Skeleton } from '../../base'; +import { TropyIcon } from '../../icons'; +import { useTheme } from '../../theme'; +import { CustomTooltip } from '../CustomTooltip'; +import { CardSkeleton } from './styles'; + +interface PerformersSectionButtonProps { + open: boolean; + handleClick: () => void; +} + +const PerformersSectionButton: React.FC = ({ open, handleClick }) => { + const theme = useTheme(); + + return ( + + + + + + ); +}; + +export const StateCardSekeleton = () => { + return ( + + {[...Array(5)].map((_, index) => ( + + ))} + + ); +}; +export default PerformersSectionButton; From dd6623b00ee477c755c5509d4279a453aea1adf3 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:03:22 +0530 Subject: [PATCH 5/7] feat: add PerformersSection component with metrics display and export Signed-off-by: Amit Amrutiya --- .../PerformersSection/PerformersSection.tsx | 316 ++++++++++++++++++ src/custom/PerformersSection/index.ts | 3 + src/custom/index.tsx | 1 + 3 files changed, 320 insertions(+) create mode 100644 src/custom/PerformersSection/PerformersSection.tsx create mode 100644 src/custom/PerformersSection/index.ts diff --git a/src/custom/PerformersSection/PerformersSection.tsx b/src/custom/PerformersSection/PerformersSection.tsx new file mode 100644 index 00000000..2fdcc1d8 --- /dev/null +++ b/src/custom/PerformersSection/PerformersSection.tsx @@ -0,0 +1,316 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { memo, useMemo } from 'react'; +import { + CloneIcon, + DeploymentsIcon, + DownloadIcon, + OpenIcon, + ShareIcon, + TropyIcon +} from '../../icons'; +import { useTheme } from '../../theme'; +import { Pattern } from '../CustomCatalog/CustomCard'; +import { ErrorBoundary } from '../ErrorBoundary'; +import { StateCardSekeleton } from './PerformersToogleButton'; +import { + CardsContainer, + ContentWrapper, + ErrorContainer, + HeaderSection, + HeaderTitle, + IconContainer, + MainContainer, + RepoSection, + RepoTitle, + StatsValue, + StatusLabel, + StyledCard, + Title, + UserNameText +} from './styles'; + +interface MetricConfig { + label: string; + icon: React.ComponentType; + id: string; + countKey: keyof Pattern; +} + +interface BaseQueryParams { + pathType: string; + page: number; + pagesize: number; + metrics: boolean; + expandUser: boolean; + trim: boolean; + order?: string; +} + +interface StatCardProps { + label: string; + count: number; + patternName: string; + pattern: Pattern; + userName: string; + userid: string; + icon: React.ComponentType; + status: string; + id: string; + onCardClick: (pattern: Pattern) => void; + onIconClick: () => void; + onAuthorClick: (userId: string) => void; + onStatusClick: (status: string) => void; +} + +interface PerformersSectionProps { + useGetCatalogFilters: (params: any) => any; + onCardClick: (pattern: Pattern) => void; + onIconClick: () => void; + onAuthorClick: (userId: string) => void; + onStatusClick: (status: string) => void; +} + +type MetricType = 'view' | 'clone' | 'download' | 'deployment' | 'share'; + +const BASE_QUERY_PARAMS: BaseQueryParams = { + pathType: 'pattern', + page: 0, + pagesize: 1, + metrics: true, + expandUser: true, + trim: true +}; + +const METRICS: Record = { + view: { + label: 'Most Opens', + icon: OpenIcon, + id: 'open-icon', + countKey: 'view_count' + }, + clone: { + label: 'Most Clones', + icon: CloneIcon, + id: 'clone-icon', + countKey: 'clone_count' + }, + download: { + label: 'Most Downloads', + icon: DownloadIcon, + id: 'download-icon', + countKey: 'download_count' + }, + deployment: { + label: 'Most Deploys', + icon: DeploymentsIcon, + id: 'deployments-icon', + countKey: 'deployment_count' + }, + share: { + label: 'Most Shares', + icon: ShareIcon, + id: 'share-icon', + countKey: 'share_count' + } +}; + +const createQueryParams = (metric: MetricType): BaseQueryParams => ({ + ...BASE_QUERY_PARAMS, + order: `${METRICS[metric].countKey} desc` +}); + +const StatCardComponent: React.FC = ({ + label, + count, + patternName, + pattern, + userName, + userid, + icon: Icon, + status, + id, + onCardClick, + onIconClick, + onAuthorClick, + onStatusClick +}) => { + const handleCardClick = () => { + onCardClick(pattern); + }; + + const handleIconClick = (e: React.MouseEvent) => { + e.stopPropagation(); + onIconClick(); + }; + + const handleAuthorClick = (e: React.MouseEvent) => { + e.stopPropagation(); + onAuthorClick(userid); + }; + + const handleStatusClick = (e: React.MouseEvent) => { + e.stopPropagation(); + onStatusClick(status); + }; + + return ( + + + + {label} + + + + + + {count} + + + {patternName} + by {userName} + + + + {status} + + + ); +}; +interface PageArgs { + search?: string; + order?: string; + pagesize?: number; + page?: number; + [key: string]: any; +} + +const withDefaultPageArgs = (args: PageArgs = {}): PageArgs => ({ + search: args.search ?? '', + order: args.order ?? '', + pagesize: args.pagesize ?? 0, + page: args.page ?? 0, + ...args +}); + +const StatCard = memo(StatCardComponent); +StatCard.displayName = 'StatCard'; + +const useMetricQueries = (useGetCatalogFilters: PerformersSectionProps['useGetCatalogFilters']) => { + const viewQuery = useGetCatalogFilters(withDefaultPageArgs(createQueryParams('view'))); + + const cloneQuery = useGetCatalogFilters(withDefaultPageArgs(createQueryParams('clone'))); + + const downloadQuery = useGetCatalogFilters(withDefaultPageArgs(createQueryParams('download'))); + + const deploymentQuery = useGetCatalogFilters( + withDefaultPageArgs(createQueryParams('deployment')) + ); + + const shareQuery = useGetCatalogFilters(withDefaultPageArgs(createQueryParams('share'))); + + const metricQueries = { + view: viewQuery, + clone: cloneQuery, + download: downloadQuery, + deployment: deploymentQuery, + share: shareQuery + }; + + return { + queries: metricQueries, + isLoading: Object.values(metricQueries).some((query) => query.isLoading), + hasError: Object.values(metricQueries).some((query) => query.isError) + }; +}; + +const processQueryData = ( + queries: Record, + metric: MetricType +): Omit< + StatCardProps, + 'onCardClick' | 'onIconClick' | 'onAuthorClick' | 'onStatusClick' +> | null => { + const query = queries[metric]; + const config = METRICS[metric]; + const pattern = query?.isSuccess && query.data?.patterns?.[0]; + + if (!pattern) return null; + + return { + label: config.label, + count: pattern[config.countKey], + patternName: pattern.name || 'Unknown', + pattern: pattern, + userName: pattern.user?.first_name || 'Unknown', + userid: pattern.user?.id, + icon: config.icon, + id: config.id, + status: pattern?.catalog_data?.content_class + }; +}; + +const PerformersSection: React.FC = ({ + useGetCatalogFilters, + onCardClick, + onIconClick, + onAuthorClick, + onStatusClick +}) => { + const theme = useTheme(); + const { queries, isLoading, hasError } = useMetricQueries(useGetCatalogFilters); + + const stats = useMemo( + () => + (Object.keys(METRICS) as MetricType[]) + .map((metric) => processQueryData(queries, metric)) + .filter( + ( + stat + ): stat is Omit< + StatCardProps, + 'onCardClick' | 'onIconClick' | 'onAuthorClick' | 'onStatusClick' + > => Boolean(stat) + ), + [queries] + ); + + if (hasError) + return ( + + Error loading statistics. Please try again later. + + ); + + return ( + + + + Top Performers + <TropyIcon + style={{ + height: '2rem', + width: '2rem', + color: theme.palette.icon.secondary + }} + /> + + + {isLoading && } + {!isLoading && + stats.map((stat, index) => ( + + ))} + + + + ); +}; + +export default memo(PerformersSection); diff --git a/src/custom/PerformersSection/index.ts b/src/custom/PerformersSection/index.ts new file mode 100644 index 00000000..1e6aa1ea --- /dev/null +++ b/src/custom/PerformersSection/index.ts @@ -0,0 +1,3 @@ +import PerformersSection from './PerformersSection'; +import PerformersSectionButton from './PerformersToogleButton'; +export { PerformersSection, PerformersSectionButton }; diff --git a/src/custom/index.tsx b/src/custom/index.tsx index 1918d175..ded1e4f5 100644 --- a/src/custom/index.tsx +++ b/src/custom/index.tsx @@ -51,6 +51,7 @@ export { InputSearchField } from './InputSearchField'; export { LearningContent } from './LearningContent'; export { NavigationNavbar } from './NavigationNavbar'; export { Note } from './Note'; +export { PerformersSection, PerformersSectionButton } from './PerformersSection'; export { SetupPreReq } from './SetupPrerequisite'; export { StyledChapter } from './StyledChapter'; export { StyledSearchBar } from './StyledSearchBar'; From 4fef955fdfb8bef12976aa2fff339691ab183a81 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:03:36 +0530 Subject: [PATCH 6/7] feat: add styles for PerformersSection component Signed-off-by: Amit Amrutiya --- src/custom/PerformersSection/styles.tsx | 261 ++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 src/custom/PerformersSection/styles.tsx diff --git a/src/custom/PerformersSection/styles.tsx b/src/custom/PerformersSection/styles.tsx new file mode 100644 index 00000000..365b7886 --- /dev/null +++ b/src/custom/PerformersSection/styles.tsx @@ -0,0 +1,261 @@ +import { Box, Card, CardContent, Typography } from '../../base'; +import { DARK_TEAL, styled } from '../../theme'; +import { getCatalogCardBackground } from '../CustomCatalog/style'; + +interface StatusLabelProps { + labelType?: 'community' | 'official' | string; +} + +interface ContentWrapperProps { + cardId?: string; +} + +interface StyledCardProps { + status?: string; +} + +export const ChartDiv = styled(Box)(() => ({ + padding: '1rem', + borderRadius: '1rem', + backgroundColor: 'white', + width: '100%', + alignSelf: 'center', + height: '20rem', + marginBottom: '1rem', + boxShadow: '0px 2px 10px rgba(0, 0, 0, 0.2)', + display: 'block', + ['@media (max-width:900px)']: { + height: '18rem', + marginInline: '0', + padding: '0.5rem' + } +})); + +export const LoadButtonDiv = styled('div')(() => ({ + width: '100%', + justifyContent: 'center', + display: 'flex', + alignItems: 'center', + marginTop: '20px' +})); + +export const EmptyContainer = styled(Box)(() => ({ + display: 'flex', + justifyContent: 'space-evenly', + gap: '2.5rem', + width: '100%' +})); + +export const ContentContainer = styled(Box)(() => ({ + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-evenly', + gap: '2.5rem', + width: '100%' +})); + +export const EmptyStateDiv = styled('div')(({ theme }) => ({ + backgroundColor: theme.palette.common.white, + textAlign: 'center', + borderRadius: '1rem', + width: '100%', + padding: '1.5rem', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center' +})); + +export const MainContainer = styled(Box)(({ theme }) => ({ + background: + theme.palette.mode === 'light' + ? theme.palette.background.default + : theme.palette.background.secondary, + paddingTop: theme.spacing(2), + borderRadius: '1rem', + marginBottom: theme.spacing(4), + display: 'flex', + alignItems: 'center', + flexDirection: 'column' +})); + +export const Title = styled(Typography)(({ theme }) => ({ + fontSize: '1.5rem', + fontWeight: 600, + color: theme.palette.text.default, + paddingLeft: theme.spacing(2), + display: 'flex', + alignItems: 'center', + gap: '0.5rem', + placeSelf: 'flex-start' +})); + +export const StyledCard = styled(Card)(({ theme }) => ({ + width: 'inherit', + minWidth: '150px', + borderRadius: '16px', + position: 'relative', + overflow: 'hidden', + transition: 'all 0.3s ease-in-out', + background: getCatalogCardBackground(theme.palette.mode === 'light'), + border: '1px solid transparent', + boxShadow: '2px 2px 3px 2px rgb(0, 211, 169, 0.5)', + '&:hover': { + transform: 'translateY(-4px)', + boxShadow: `2px 2px 3px 2px ${theme.palette.text.brand}`, + cursor: 'pointer' + } +})); + +export const CardSkeleton = styled('div')(() => ({ + display: 'flex', + gap: '10px', + flexWrap: 'nowrap', + justifyContent: 'center', + width: '100%' +})); + +export const IconContainer = styled(Box)(() => ({ + width: '2rem', + height: '2rem', + padding: '0.25rem', + borderRadius: '8px', + backgroundColor: '#D6FFF7', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + transition: 'all 0.3s ease', + '& svg': { + transition: 'transform 0.3s ease' + }, + '&:hover svg': { + transform: 'scale(1.2)' + }, + '& .clone-icon': { + width: '20px', + height: '20px' + } +})); + +export const ContentWrapper = styled(CardContent)(({ cardId, theme }) => ({ + height: '100%', + display: 'flex', + flexDirection: 'column', + padding: theme.spacing(2), + paddingInline: cardId === 'download-icon' ? '12px' : theme.spacing(2), + '&:last-child': { + paddingBottom: theme.spacing(2) + } +})); + +export const HeaderSection = styled(Box)({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'flex-start', + marginBottom: '1rem', + gap: '0.6rem' +}); + +export const HeaderTitle = styled(Typography)(({ theme }) => ({ + fontSize: '0.85rem', + fontWeight: 'bold', + color: theme.palette.text.default, + lineHeight: 1.2, + marginTop: '4px', + textTransform: 'uppercase', + letterSpacing: '0.5px' +})); + +export const StatsValue = styled(Typography)(({ theme }) => ({ + fontSize: '24px', + fontWeight: 700, + color: theme.palette.icon.secondary, + marginBottom: '0.5rem', + lineHeight: 1.2 +})); + +export const RepoSection = styled(Box)(({ theme }) => ({ + marginBlock: '.35rem', + padding: '8px', + borderRadius: '8px', + background: theme.palette.mode === 'light' ? '#f8fafc' : DARK_TEAL, + color: theme.palette.mode === 'light' ? 'rgba(26, 26, 26, .8)' : theme.palette.text.default, + transition: 'background 0.3s ease, filter 0.3s ease', + '&:hover': { + filter: 'brightness(0.98)' + } +})); + +export const RepoTitle = styled(Typography)(({ theme }) => ({ + fontSize: '0.9rem', + fontWeight: 1000, + color: theme.palette.text.default, + lineHeight: 1.3, + marginBottom: '4px', + display: '-webkit-box', + WebkitLineClamp: 2, + WebkitBoxOrient: 'vertical', + overflow: 'hidden', + textOverflow: 'ellipsis', + height: '2.6em' +})); + +export const UserNameText = styled(Typography)(({ theme }) => ({ + fontSize: '0.75rem', + color: + theme.palette.mode === 'light' + ? theme.palette.text.constant?.disabled + : theme.palette.text.disabled, + marginBottom: '8px', + transition: 'color 0.3s ease', + + '&:hover': { + color: theme.palette.text.brand + } +})); + +export const CardsContainer = styled(Box)(({ theme }) => ({ + display: 'flex', + gap: '18px', + width: '100%', + overflowX: 'auto', + padding: '18px', + background: + theme.palette.mode === 'light' + ? theme.palette.background.default + : theme.palette.background.secondary, + borderRadius: '12px', + boxShadow: '0 1px 3px rgba(0, 0, 0, 0.05)', + paddingBottom: theme.spacing(3) +})); + +export const StatusLabel = styled(Box)(({ labelType, theme }) => ({ + position: 'absolute', + bottom: 0, + left: 0, + background: + labelType === 'community' + ? 'rgba(122,132,142,.8)' + : labelType === 'official' + ? theme.palette.background.cta?.default + : theme.palette.text.brand, + color: labelType === 'official' ? 'black' : 'white', + paddingInline: '1rem', + borderTopRightRadius: '1rem', + fontSize: '0.75rem', + fontWeight: 'bold', + letterSpacing: '0.5px', + textTransform: 'lowercase', + zIndex: 2, + transition: 'all 0.3s ease', + '&:hover': { + filter: 'brightness(1.2)' + } +})); + +export const ErrorContainer = styled(Box)(({ theme }) => ({ + padding: '1rem', + color: theme.palette.text.error, + fontSize: '1rem', + fontWeight: 500 +})); From 411a49f6ddf15a108fc90335fa5ec07a642b4477 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Mon, 18 Nov 2024 10:03:36 +0530 Subject: [PATCH 7/7] feat: add styles for PerformersSection component Signed-off-by: Amit Amrutiya --- src/custom/ResponsiveDataTable.tsx | 60 +++++++++++++++--------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/custom/ResponsiveDataTable.tsx b/src/custom/ResponsiveDataTable.tsx index 230822db..de09a30b 100644 --- a/src/custom/ResponsiveDataTable.tsx +++ b/src/custom/ResponsiveDataTable.tsx @@ -310,42 +310,39 @@ const ResponsiveDataTable = ({ return new Intl.DateTimeFormat('en-US', dateOptions).format(date); }; - const updatedOptions = React.useMemo( - () => ({ - ...options, - print: false, - download: false, - search: false, - filter: false, - viewColumns: false, - rowsPerPageOptions: rowsPerPageOptions, - onViewColumnsChange: (column: string, action: string) => { - switch (action) { - case 'add': { - const colToAdd = columns.find((obj) => obj.name === column); - if (colToAdd) { - if (colToAdd.options) { - colToAdd.options.display = true; - updateCols && updateCols([...columns]); - } + const updatedOptions = { + ...options, + print: false, + download: false, + search: false, + filter: false, + viewColumns: false, + rowsPerPageOptions: rowsPerPageOptions, + onViewColumnsChange: (column: string, action: string) => { + switch (action) { + case 'add': { + const colToAdd = columns.find((obj) => obj.name === column); + if (colToAdd) { + if (colToAdd.options) { + colToAdd.options.display = true; + updateCols && updateCols([...columns]); } - break; } - case 'remove': { - const colToRemove = columns.find((obj) => obj.name === column); - if (colToRemove) { - if (colToRemove.options) { - colToRemove.options.display = false; - updateCols && updateCols([...columns]); - } + break; + } + case 'remove': { + const colToRemove = columns.find((obj) => obj.name === column); + if (colToRemove) { + if (colToRemove.options) { + colToRemove.options.display = false; + updateCols && updateCols([...columns]); } - break; } + break; } } - }), - [options, rowsPerPageOptions, columns, updateCols] - ); + } + }; const updateColumnsEffect = useCallback(() => { columns?.forEach((col) => { @@ -388,7 +385,8 @@ const ResponsiveDataTable = ({ } }); updateCols && updateCols([...columns]); - }, [columnVisibility, updateCols, columns]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [columnVisibility, updateCols]); React.useEffect(() => { updateColumnsEffect();