• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CBIIT / INS-WebPortal / 20350373879

18 Dec 2025 08:28PM UTC coverage: 2.453%. First build
20350373879

push

github

web-flow
Merge pull request #482 from CBIIT/3.2.0

3.2.0 Release

43 of 1822 branches covered (2.36%)

Branch coverage included in aggregate %.

7 of 490 new or added lines in 27 files covered. (1.43%)

83 of 3314 relevant lines covered (2.5%)

1.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/components/Header/components/NavbarDesktop.tsx
NEW
1
import React, { useEffect, useState, useRef } from 'react';
×
NEW
2
import { NavLink, Link } from 'react-router-dom';
×
NEW
3
import styled from 'styled-components';
×
4

NEW
5
import { navMobileList, navbarSublists } from '../../../config/globalHeaderData.tsx';
×
6

NEW
7
const Nav = styled.div`
×
8
    top: 0;
9
    left: 0;
10
    width: 100%;
11
    background: #ffffff;
12
    box-shadow: -0.1px 6px 9px -6px rgba(0, 0, 0, 0.5);
13
    z-index: 1100;
14
    position: relative;
15

16
    .dropdownContainer {
17
      // outline: none;
18
      // visibility: hidden;
19
      // opacity: 0;
20
      margin: 0 auto;
21
      position: relative;
22
      width: 1400px;
23
    }
24
    .invisible {
25
      visibility: hidden;
26
    }
27
 `;
28

NEW
29
const NavContainer = styled.div`
×
30
    margin: 0 auto;
31
    max-width: 1400px;
32
    text-align: left;
33
    position: relative;
34
    display: flex;
35
    justify-content: space-between;
36
    align-items: end;
37
`;
38

NEW
39
const UlContainer = styled.ul`
×
40
  list-style: none;
41
  margin: 0;
42
  padding-top: 17px;
43
  padding-left: 11px;
44
`;
45

NEW
46
const LiSection = styled.li`
×
47
  display: inline-block;
48
  position: relative;
49
  line-height: 50px;
50
  letter-spacing: 1px;
51
  text-align: center;
52
  transition:all 0.3s ease-in-out;
53

54
  a {
55
    color: #585C65;
56
    text-decoration: none;
57
  }
58

59
  .navTitle {
60
    display: block;
61
    color: #585C65;
62
    font-family: poppins;
63
    font-size: 17px;
64
    font-weight: 700;
65
    line-height: 40px;
66
    letter-spacing: normal;
67
    text-decoration: none;
68
    margin: 0 45px 0 5px;
69
    padding: 0 15px;
70
    user-select:none;
71
    border-top: 4px solid transparent;
72
    border-left: 4px solid transparent;
73
    border-right: 4px solid transparent;
74
  }
75

76
  .navTitle:hover {
77
    cursor: pointer;
78
  }
79

80
  .navText {
81
    border-bottom: 4px solid transparent;
82
  }
83

84
  .navText:hover {
85
    cursor: pointer;
86
    color: #3A75BD;
87
    border-bottom: 4px solid #3A75BD;
88

89
    ::after {
90
      content: "";
91
      display: inline-block;
92
      width: 6px;
93
      height: 6px;
94
      border-bottom: 1px solid #298085;
95
      border-left: 1px solid #298085;
96
      margin: 0 0 4px 8px;
97
      transform: rotate(-45deg);
98
      -webkit-transform: rotate(-45deg);
99
    }
100
  }
101

102
  .navText::after {
103
    content: "";
104
    display: inline-block;
105
    width: 6px;
106
    height: 6px;
107
    border-bottom: 1px solid #585C65;
108
    border-left: 1px solid #585C65;
109
    margin: 0 0 4px 8px;
110
    transform: rotate(-45deg);
111
    -webkit-transform: rotate(-45deg);
112
  }
113

114
  .clicked {
115
    color: #FFFFFF;
116
    background: #1F4671;
117
  }
118

119
  .clicked::after {
120
    border-top: 1px solid #FFFFFF;
121
    border-right: 1px solid #FFFFFF;
122
    border-bottom: 0;
123
    border-left: 0;
124
    margin: 0 0 0 8px
125
  }
126

127
  .clicked:hover {
128
    border-bottom: 4px solid #1F4671;
129
    color: #FFFFFF;
130

131
    ::after {
132
      content: "";
133
      display: inline-block;
134
      width: 6px;
135
      height: 6px;
136
      border-top: 1px solid #FFFFFF;
137
      border-right: 1px solid #FFFFFF;
138
      border-bottom: 0;
139
      border-left: 0;
140
      margin: 0 0 0 8px;
141
      transform: rotate(-45deg);
142
      -webkit-transform: rotate(-45deg);
143
    }
144
  }
145

146
  .directLink::after {
147
    display: none;
148
  }
149

150
  .directLink:hover {
151
    ::after {
152
      display: none;
153
    }
154
  }
155
  .shouldBeUnderlined {
156
    border-bottom: 4px solid #3A75BD;
157
  }
158
  .navTitleClicked {
159
    display: block;
160
    color: #FFFFFF;
161
    font-family: poppins;
162
    font-size: 17px;
163
    font-weight: 700;
164
    line-height: 40px;
165
    letter-spacing: normal;
166
    text-decoration: none;
167
    margin: 0 45px 0 5px;
168
    padding: 0 15px;
169
    user-select:none;
170
    background: #1F4671;
171
    border-top: 4px solid #5786FF;
172
    border-left: 4px solid #5786FF;
173
    border-right: 4px solid #5786FF;
174
  }
175
`;
176

NEW
177
const Dropdown = styled.div`
×
178
    top: 60.5px;
179
    left: 0;
180
    width: 100%;
181
    background: #1F4671;
182
    z-index: 1100;
183
    position: absolute;
184
    // visibility: hidden;
185
    // outline: none;
186
    // opacity: 0;
187
`;
188

NEW
189
const DropdownContainer = styled.div`
×
190
    margin: 0 auto;
191
    text-align: left;
192
    position: relative;
193
    max-width: 1400px;
194

195
    .dropdownList {
196
      background: #1F4671;
197
      display: grid;
198
      grid-template-columns: repeat( auto-fit, minmax(250px, 1fr) );
199
      padding: 32px 32px 0 32px;
200
    }
201

202
    .dropdownItem {
203
      padding: 0 10px 52px 10px;
204
      text-align: left;
205
      font-family: 'Poppins';
206
      font-weight: 600;
207
      font-style: normal;
208
      font-size: 20px;
209
      line-height: 110%;
210
      color: #FFFFFF;
211
      text-decoration: none;
212
  }
213

214
  .dropdownItem:hover {
215
    text-decoration: underline;
216
  }
217

218
  .dropdownItemText {
219
    margin-top: 5px;
220
    font-family: 'Open Sans';
221
    font-style: normal;
222
    font-weight: 400;
223
    font-size: 16.16px;
224
    line-height: 22px;
225
  }
226
`;
227

NEW
228
const StyledLoginLink = styled(Link)`
×
229
  color: #007BBD;
230
  text-align: right;
231
  font-size: 14px;
232
  font-family: Poppins;
233
  font-style: normal;
234
  font-weight: 600;
235
  line-height: normal;
236
  letter-spacing: 0.42px;
237
  text-decoration: none;
238
  text-transform: uppercase;
239
  padding: 10px 0 10px 0;
240
  margin-bottom: 4.5px;
241
  margin-right: 32px;
242
`;
243

NEW
244
const useOutsideAlerter = (ref) => {
×
NEW
245
  useEffect(() => {
×
246
    function handleClickOutside(event) {
NEW
247
      if (!event.target || (event.target.getAttribute("class") !== "dropdownList" && ref.current && !ref.current.contains(event.target))) {
×
NEW
248
        const toggle = document.getElementsByClassName("navText clicked");
×
NEW
249
        if (toggle[0] && event.target.getAttribute("class") !== "navText clicked" && event.target.getAttribute("class") !== "navText clicked") {
×
NEW
250
          const temp: HTMLElement = toggle[0] as HTMLElement;
×
NEW
251
          temp.click();
×
252
        }
253
      }
254
    }
255

NEW
256
    document.addEventListener("mousedown", handleClickOutside);
×
NEW
257
    return () => {
×
NEW
258
      document.removeEventListener("mousedown", handleClickOutside);
×
259
    };
260
  }, [ref]);
261
};
262

NEW
263
const NavBar = () => {
×
NEW
264
  const [clickedTitle, setClickedTitle] = useState("");
×
NEW
265
  const dropdownSelection = useRef(null);
×
NEW
266
  const clickableObject = navMobileList.filter((item) => item.className === 'navMobileItem clickable');
×
NEW
267
  const clickableTitle = clickableObject.map((item) => item.name);
×
NEW
268
  useOutsideAlerter(dropdownSelection);
×
269

NEW
270
  const handleMenuClick = (e) => {
×
NEW
271
    if (e.target.innerText === clickedTitle || !clickableTitle.includes(e.target.innerText)) {
×
NEW
272
      setClickedTitle("");
×
273
    } else {
NEW
274
      setClickedTitle(e.target.innerText);
×
275
    }
276
  };
277

NEW
278
  const onKeyPressHandler = (e) => {
×
NEW
279
    if (e.key === "Enter") {
×
NEW
280
      handleMenuClick(e);
×
281
    }
282
  };
283
  type NavSubLinkData = {
284
    name: string;
285
    link: string;
286
    className: string;
287
  };
288

289
  function shouldBeUnderlined(item) {
NEW
290
    const linkName = item.name;
×
NEW
291
    const correctPath = window.location.href.slice(window.location.href.lastIndexOf(window.location.host) + window.location.host.length);
×
292
    // Take out the prefix of the hash routing ie '/#/programs' -> '/programs'
NEW
293
    const hashIndex = correctPath.indexOf('#');
×
NEW
294
    const trimmedPath = hashIndex !== -1 ? correctPath.substring(hashIndex + 1) : correctPath;
×
295

296
    // Check if current path matches any sublist paths for this item
NEW
297
    if (navbarSublists[linkName] !== undefined) {
×
NEW
298
      const linkNames = Object.values(navbarSublists[linkName]).map((e: NavSubLinkData) => e.link);
×
299
      // Check for both exact match and prefix match (for detail pages like /program/xyz)
NEW
300
      const hasMatch = linkNames.some(link =>
×
NEW
301
        trimmedPath === link || trimmedPath.startsWith(link + '/')
×
302
      );
NEW
303
      if (hasMatch) {
×
NEW
304
        return true;
×
305
      }
306
    }
307

308
    // For direct links without sublists, check exact match
NEW
309
    if (item.className === "navMobileItem") {
×
NEW
310
      return trimmedPath === item.link;
×
311
    }
NEW
312
    return false;
×
313
  }
314

NEW
315
  useEffect(() => {
×
NEW
316
    setClickedTitle("");
×
317
  }, []);
318

NEW
319
  return (
×
320
    <Nav>
321
      <NavContainer>
322
        <UlContainer>
323
          {
324
            navMobileList.map((navMobileItem, idx) => {
NEW
325
              const navkey = `nav_${idx}`;
×
NEW
326
              return (
×
327
                navMobileItem.className === 'navMobileItem'
328
                  ? (
329
                    <LiSection key={navkey}>
×
330
                      <div className="navTitle directLink">
331
                        <NavLink to={navMobileItem.link}>
332
                          <div
333
                            id={navMobileItem.id}
334
                            onKeyDown={onKeyPressHandler}
335
                            role="button"
336
                            tabIndex={0}
337
                            className={`navText directLink ${shouldBeUnderlined(navMobileItem) ? "shouldBeUnderlined" : ""}`}
×
338
                            onClick={handleMenuClick}
339
                          >
340
                            {navMobileItem.name}
341
                          </div>
342
                        </NavLink>
343
                      </div>
344
                    </LiSection>
345
                  )
346
                  : (
347
                    <LiSection key={navkey}>
348
                      <div className={clickedTitle === navMobileItem.name ? 'navTitleClicked' : 'navTitle'}>
×
349
                        <div
350
                          id={navMobileItem.id}
351
                          onKeyDown={onKeyPressHandler}
352
                          role="button"
353
                          tabIndex={0}
354
                          className={`${clickedTitle === navMobileItem.name ? 'navText clicked' : 'navText'} ${shouldBeUnderlined(navMobileItem) ? "shouldBeUnderlined" : ""}`}
×
355
                          onClick={handleMenuClick}
356
                        >
357
                          {navMobileItem.name}
358
                        </div>
359
                      </div>
360
                    </LiSection>
361
                  )
362
              );
363
            })
364
          }
365
        </UlContainer>
366
      </NavContainer>
367
      <Dropdown ref={dropdownSelection} className={clickedTitle === ''  ? "invisible" : ""}>
×
368
        <DropdownContainer>
369
          <div className="dropdownList">
370
            {
371
              clickedTitle !== "" ? navbarSublists[clickedTitle].map((dropItem, idx) => {
×
NEW
372
                const dropkey = `drop_${idx}`;
×
NEW
373
                const isPdf = dropItem.link && dropItem.link.endsWith('.pdf');
×
NEW
374
                const isExternal = dropItem.link && (dropItem.link.startsWith('http') || isPdf);
×
375

NEW
376
                return (
×
377
                  dropItem.link && (
×
378
                    isExternal ? (
379
                      <a
×
380
                        id={dropItem.id}
381
                        href={dropItem.link}
382
                        className="dropdownItem"
383
                        key={dropkey}
384
                        target="_blank"
385
                        rel="noopener noreferrer"
NEW
386
                        onClick={() => setClickedTitle("")}
×
387
                      >
388
                        {dropItem.name}
389
                        <div className="dropdownItemText">{dropItem.text}</div>
390
                      </a>
391
                    ) : (
392
                      <Link
393
                        id={dropItem.id}
394
                        to={dropItem.link}
395
                        className="dropdownItem"
396
                        key={dropkey}
NEW
397
                        onClick={() => setClickedTitle("")}
×
398
                      >
399
                        {dropItem.name}
400
                        <div className="dropdownItemText">{dropItem.text}</div>
401
                      </Link>
402
                    )
403
                  )
404
                );
405
              })
406
                : null
407
            }
408
          </div>
409
        </DropdownContainer>
410
      </Dropdown>
411
    </Nav>
412
  );
NEW
413
};
×
414

415
export default NavBar;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc