Skip to content

Commit 623b972

Browse files
committed
refactor: nested ternary operators into independent statements
1 parent f0704ba commit 623b972

File tree

11 files changed

+164
-55
lines changed

11 files changed

+164
-55
lines changed

frontend/__tests__/unit/components/ModuleList.test.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@ import ModuleList from 'components/ModuleList'
55

66
// Mock FontAwesome icons
77
jest.mock('@fortawesome/react-fontawesome', () => ({
8-
FontAwesomeIcon: ({ icon, className }: { icon: unknown; className?: string }) => (
9-
<span
10-
data-testid={`icon-${icon === faChevronDown ? 'chevron-down' : icon === faChevronUp ? 'chevron-up' : 'unknown'}`}
11-
className={className}
12-
/>
13-
),
8+
FontAwesomeIcon: ({ icon, className }: { icon: unknown; className?: string }) => {
9+
let iconName = 'unknown'
10+
11+
if (icon === faChevronDown) {
12+
iconName = 'chevron-down'
13+
} else if (icon === faChevronUp) {
14+
iconName = 'chevron-up'
15+
}
16+
17+
return <span data-testid={`icon-${iconName}`} className={className} />
18+
},
1419
}))
1520

1621
// Mock HeroUI Button component

frontend/__tests__/unit/components/ProgramCard.test.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ import type { Program } from 'types/mentorship'
77
import ProgramCard from 'components/ProgramCard'
88

99
jest.mock('@fortawesome/react-fontawesome', () => ({
10-
FontAwesomeIcon: ({ icon, className }: { icon: unknown; className?: string }) => (
11-
<span
12-
data-testid={`icon-${icon === faEye ? 'eye' : icon === faEdit ? 'edit' : 'unknown'}`}
13-
className={className}
14-
/>
15-
),
10+
FontAwesomeIcon: ({ icon, className }: { icon: unknown; className?: string }) => {
11+
let iconName = 'unknown'
12+
13+
if (icon === faEye) {
14+
iconName = 'eye'
15+
} else if (icon === faEdit) {
16+
iconName = 'edit'
17+
}
18+
19+
return <span data-testid={`icon-${iconName}`} className={className} />
20+
},
1621
}))
1722

1823
jest.mock('components/ActionButton', () => ({

frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,18 @@ describe('MetricsPage', () => {
148148
})
149149
})
150150

151+
test('SortableColumnHeader applies correct alignment classes', async () => {
152+
render(<MetricsPage />)
153+
154+
// Find the "Stars" sort button
155+
const sortButton = await screen.findByTitle('Sort by Stars')
156+
const wrapperDiv = sortButton.closest('div')
157+
158+
// "Stars" uses align="center" in the MetricsPage
159+
expect(wrapperDiv).toHaveClass('justify-center')
160+
expect(sortButton).toHaveClass('text-center')
161+
})
162+
151163
test('handles sorting state and URL updates', async () => {
152164
const mockReplace = jest.fn()
153165
const { useRouter, useSearchParams } = jest.requireMock('next/navigation')
@@ -236,4 +248,6 @@ describe('MetricsPage', () => {
236248
expect(nextPageButton).toBeInTheDocument()
237249
fireEvent.click(nextPageButton)
238250
})
251+
252+
//test for helper functions
239253
})
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { faCircleCheck, faClock, faUserGear } from '@fortawesome/free-solid-svg-icons'
2+
3+
import { getMilestoneProgressIcon, getMilestoneProgressText } from 'utils/milestoneProgress'
4+
5+
describe('milestone progress helpers', () => {
6+
describe('getMilestoneProgressText', () => {
7+
test('returns "Completed" when progress is 100', () => {
8+
expect(getMilestoneProgressText(100)).toBe('Completed')
9+
})
10+
11+
test('returns "In Progress" when progress is between 1 and 99', () => {
12+
expect(getMilestoneProgressText(50)).toBe('In Progress')
13+
})
14+
15+
test('returns "Not Started" when progress is 0', () => {
16+
expect(getMilestoneProgressText(0)).toBe('Not Started')
17+
})
18+
})
19+
20+
describe('getMilestoneProgressIcon', () => {
21+
test('returns faCircleCheck when progress is 100', () => {
22+
expect(getMilestoneProgressIcon(100)).toBe(faCircleCheck)
23+
})
24+
25+
test('returns faUserGear when progress is between 1 and 99', () => {
26+
expect(getMilestoneProgressIcon(50)).toBe(faUserGear)
27+
})
28+
29+
test('returns faClock when progress is 0', () => {
30+
expect(getMilestoneProgressIcon(0)).toBe(faClock)
31+
})
32+
})
33+
})

frontend/src/app/about/page.tsx

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { useQuery } from '@apollo/client/react'
33
import {
44
faCircleCheck,
55
faClock,
6-
faUserGear,
76
faMapSigns,
87
faScroll,
98
faUsers,
@@ -34,6 +33,7 @@ import {
3433
projectTimeline,
3534
projectStory,
3635
} from 'utils/aboutData'
36+
import { getMilestoneProgressIcon, getMilestoneProgressText } from 'utils/milestoneProgress'
3737
import AnchorTitle from 'components/AnchorTitle'
3838
import AnimatedCounter from 'components/AnimatedCounter'
3939
import Leaders from 'components/Leaders'
@@ -218,28 +218,14 @@ const About = () => {
218218
</Link>
219219
<Tooltip
220220
closeDelay={100}
221-
content={
222-
milestone.progress === 100
223-
? 'Completed'
224-
: milestone.progress > 0
225-
? 'In Progress'
226-
: 'Not Started'
227-
}
221+
content={getMilestoneProgressText(milestone.progress)}
228222
id={`tooltip-state-${index}`}
229223
delay={100}
230224
placement="top"
231225
showArrow
232226
>
233227
<span className="absolute top-0 right-0 text-xl text-gray-400">
234-
<FontAwesomeIcon
235-
icon={
236-
milestone.progress === 100
237-
? faCircleCheck
238-
: milestone.progress > 0
239-
? faUserGear
240-
: faClock
241-
}
242-
/>
228+
<FontAwesomeIcon icon={getMilestoneProgressIcon(milestone.progress)} />
243229
</span>
244230
</Tooltip>
245231
</div>

frontend/src/app/global-error.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,14 @@ export class AppError extends Error {
6464
}
6565

6666
export const handleAppError = (error: unknown) => {
67-
const appError =
68-
error instanceof AppError
69-
? error
70-
: new AppError(500, error instanceof Error ? error.message : ERROR_CONFIGS['500'].message)
67+
let appError: AppError
68+
69+
if (error instanceof AppError) {
70+
appError = error
71+
} else {
72+
const message = error instanceof Error ? error.message : ERROR_CONFIGS['500'].message
73+
appError = new AppError(500, message)
74+
}
7175

7276
if (appError.statusCode >= 500) {
7377
Sentry.captureException(error instanceof Error ? error : appError)

frontend/src/app/projects/dashboard/metrics/page.tsx

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,35 @@ const SortableColumnHeader: FC<{
7777
}
7878
}
7979

80-
const alignmentClass =
81-
align === 'center' ? 'justify-center' : align === 'right' ? 'justify-end' : 'justify-start'
82-
const textAlignClass =
83-
align === 'center' ? 'text-center' : align === 'right' ? 'text-right' : 'text-left'
80+
const alignmentClass = (() => {
81+
if (align === 'center') {
82+
return 'justify-center'
83+
} else if (align === 'right') {
84+
return 'justify-end'
85+
} else {
86+
return 'justify-start'
87+
}
88+
})()
89+
90+
const textAlignClass = (() => {
91+
if (align === 'center') {
92+
return 'text-center'
93+
} else if (align === 'right') {
94+
return 'text-right'
95+
} else {
96+
return 'text-left'
97+
}
98+
})()
99+
100+
const fontAwesomeIconType = (() => {
101+
if (isActiveSortDesc) {
102+
return faSortDown
103+
} else if (isActiveSortAsc) {
104+
return faSortUp
105+
} else {
106+
return faSort
107+
}
108+
})()
84109

85110
return (
86111
<div className={`flex items-center gap-1 ${alignmentClass}`}>
@@ -93,7 +118,7 @@ const SortableColumnHeader: FC<{
93118
>
94119
<span className="truncate">{label}</span>
95120
<FontAwesomeIcon
96-
icon={isActiveSortDesc ? faSortDown : isActiveSortAsc ? faSortUp : faSort}
121+
icon={fontAwesomeIconType}
97122
className={`h-3 w-3 ${isActive ? 'text-blue-600' : 'text-gray-400'}`}
98123
/>
99124
</button>

frontend/src/components/CardDetailsPage.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@ const DetailsCard = ({
7373
}: DetailsCardProps) => {
7474
const { data } = useSession()
7575
const router = useRouter()
76+
77+
const secondaryCardStyles = (() => {
78+
if (type === 'program' || type == 'module') {
79+
return 'gap-2 md:col-span-7'
80+
} else if (type !== 'chapter') {
81+
return 'gap-2 md:col-span-5'
82+
} else {
83+
return 'gap-2 md:col-span-3'
84+
}
85+
})()
86+
7687
return (
7788
<div className="min-h-screen bg-white p-8 text-gray-600 dark:bg-[#212529] dark:text-gray-300">
7889
<div className="mx-auto max-w-6xl">
@@ -122,13 +133,7 @@ const DetailsCard = ({
122133
<SecondaryCard
123134
icon={faRectangleList}
124135
title={<AnchorTitle title={`${upperFirst(type)} Details`} />}
125-
className={
126-
type === 'program' || type === 'module'
127-
? 'gap-2 md:col-span-7'
128-
: type !== 'chapter'
129-
? 'gap-2 md:col-span-5'
130-
: 'gap-2 md:col-span-3'
131-
}
136+
className={secondaryCardStyles}
132137
>
133138
{details?.map((detail) =>
134139
detail?.label === 'Leaders' ? (

frontend/src/components/ProgramCard.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ const ProgramCard: React.FC<ProgramCardProps> = ({ program, onEdit, onView, acce
3131
? `${program.description.slice(0, 100)}...`
3232
: program.description || 'No description available.'
3333

34+
const dateInfo = (() => {
35+
if (program.startedAt && program.endedAt) {
36+
return `${formatDate(program.startedAt)}${formatDate(program.endedAt)}`
37+
} else if (program.startedAt) {
38+
return `Started: ${formatDate(program.startedAt)}`
39+
} else {
40+
return 'No dates set'
41+
}
42+
})()
43+
3444
return (
3545
<div className="h-64 w-80 rounded-[5px] border border-gray-400 bg-white p-6 text-left transition-transform duration-300 hover:scale-[1.02] hover:brightness-105 dark:border-gray-600 dark:bg-gray-800">
3646
<div className="flex h-full flex-col justify-between">
@@ -47,13 +57,7 @@ const ProgramCard: React.FC<ProgramCardProps> = ({ program, onEdit, onView, acce
4757
</span>
4858
)}
4959
</div>
50-
<div className="mb-2 text-xs text-gray-600 dark:text-gray-400">
51-
{program.startedAt && program.endedAt
52-
? `${formatDate(program.startedAt)}${formatDate(program.endedAt)}`
53-
: program.startedAt
54-
? `Started: ${formatDate(program.startedAt)}`
55-
: 'No dates set'}
56-
</div>
60+
<div className="mb-2 text-xs text-gray-600 dark:text-gray-400">{dateInfo}</div>
5761
<p className="mb-4 text-sm text-gray-700 dark:text-gray-300">{description}</p>
5862
</div>
5963

frontend/src/hooks/useSearchPage.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,17 @@ export function useSearchPage<T>({
8282

8383
const fetchData = async () => {
8484
try {
85+
let computedIndexName = indexName
86+
87+
const hasValidSort = sortBy && sortBy !== 'default' && sortBy[0] !== 'default'
88+
89+
if (hasValidSort) {
90+
const orderSuffix = order && order !== '' ? `_${order}` : ''
91+
computedIndexName = `${indexName}_${sortBy}${orderSuffix}`
92+
}
93+
8594
const response = await fetchAlgoliaData<T>(
86-
sortBy && sortBy !== 'default' && sortBy[0] !== 'default'
87-
? `${indexName}_${sortBy}${order && order !== '' ? `_${order}` : ''}`
88-
: indexName,
95+
computedIndexName,
8996
searchQuery,
9097
currentPage,
9198
hitsPerPage

0 commit comments

Comments
 (0)