Skip to content

Commit da2fd8e

Browse files
authored
Merge branch 'seanprashad:main' into master
2 parents e6af625 + e7d5a58 commit da2fd8e

File tree

13 files changed

+4852
-4097
lines changed

13 files changed

+4852
-4097
lines changed

package-lock.json

Lines changed: 459 additions & 204 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"prop-types": "^15.8.1",
1616
"react": "^16.14.0",
1717
"react-dom": "^16.14.0",
18-
"react-ga": "^2.7.0",
18+
"react-ga4": "^2.1.0",
1919
"react-icons": "^3.11.0",
2020
"react-markdown": "^4.3.1",
2121
"react-minimal-pie-chart": "^8.4.0",

src/components/Acknowledgements/styles.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,13 @@
1313
padding: 0;
1414
}
1515
}
16+
17+
body.dark-mode .acknowledgements {
18+
background-color: #161a1d;
19+
color: #ffffff;
20+
21+
.card {
22+
background-color: #1d2125;
23+
color: #ffffff;
24+
}
25+
}

src/components/App.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@ import './styles.scss';
55
import Navigation from './Navigation';
66
import Tabs from './Tabs';
77

8-
import { initGA, PageView } from './Shared/Tracking';
8+
import { initGA } from './Shared/Tracking';
99

1010
class App extends React.Component {
1111
componentDidMount() {
12-
initGA('G-GKMJ4KP806', { debug: false });
13-
PageView();
12+
initGA('G-J7FBQPGZTW');
1413
}
1514

1615
render() {

src/components/Dark-Mode/index.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React, { useState, useEffect } from 'react';
2+
import Toggle from 'react-toggle';
3+
4+
const DarkMode = () => {
5+
const [darkMode, setDarkMode] = useState(() => {
6+
const savedMode = localStorage.getItem('darkMode');
7+
return savedMode ? JSON.parse(savedMode) : false;
8+
});
9+
10+
const toggleDarkMode = () => {
11+
setDarkMode(prevMode => {
12+
const newMode = !prevMode;
13+
localStorage.setItem('darkMode', newMode);
14+
return newMode;
15+
});
16+
};
17+
useEffect(() => {
18+
document.body.className = darkMode ? 'dark-mode' : 'light-mode';
19+
}, [darkMode]);
20+
21+
return (
22+
<Toggle
23+
id="darkMode-toggle"
24+
checked={darkMode}
25+
onChange={toggleDarkMode}
26+
icons={{ checked: '🌙', unchecked: '☀️' }}
27+
/>
28+
);
29+
};
30+
31+
export default DarkMode;

src/components/Navigation/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ import { FaGithub } from 'react-icons/fa';
1111
import { Event } from '../Shared/Tracking';
1212

1313
import './styles.scss';
14+
import DarkMode from '../Dark-Mode';
1415

1516
const Navigation = () => {
1617
return (
17-
<Navbar color="light" light>
18+
<Navbar className="navbar sticky">
1819
<Container>
1920
<NavbarBrand
2021
onClick={() =>
@@ -34,6 +35,7 @@ const Navigation = () => {
3435
</NavLink>
3536
</NavItem>
3637
</Nav>
38+
<DarkMode />
3739
</Container>
3840
</Navbar>
3941
);

src/components/Navigation/styles.scss

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
.navbar.sticky {
2+
position: sticky;
3+
top: 0;
4+
z-index: 1;
5+
}
6+
7+
body.light-mode .navbar {
8+
background-color: #f7f8f9;
9+
color: #000000;
10+
}
11+
body.light-mode .navbar a {
12+
color: #212529;
13+
}
14+
15+
body.dark-mode .navbar {
16+
background-color: #1d2125;
17+
color: #ffffff;
18+
}
19+
body.dark-mode .navbar a {
20+
color: #ffffff;
21+
}
22+
body.dark-mode .navbar-nav svg {
23+
color: #ffffff;
24+
}
25+
body.dark-mode .navbar-nav svg:hover {
26+
color: #ffc952;
27+
}
28+
129
.navbar-brand {
230
font-weight: 600;
331
letter-spacing: 1px;
@@ -29,5 +57,6 @@
2957

3058
svg {
3159
font-size: 2em;
60+
margin: 0px 10px;
3261
}
3362
}
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import ReactGA from 'react-ga';
1+
import ReactGA from 'react-ga4';
22

33
const initGA = (trackingID, options) => {
4-
ReactGA.initialize(trackingID, { ...options });
5-
};
6-
7-
const PageView = () => {
8-
ReactGA.pageview(window.___location.pathname + window.___location.search);
4+
ReactGA.initialize([
5+
{
6+
trackingId: trackingID,
7+
gaOptions: { ...options },
8+
},
9+
]);
910
};
1011

1112
const Event = (category, action, label) => {
@@ -16,4 +17,4 @@ const Event = (category, action, label) => {
1617
});
1718
};
1819

19-
export { initGA, PageView, Event };
20+
export { initGA, Event };

src/components/Table/index.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ const Table = () => {
4545
JSON.parse(localStorage.getItem('checked')) ||
4646
new Array(questions.length).fill(false);
4747

48+
let checkedAtList =
49+
JSON.parse(localStorage.getItem('checkedAt')) ||
50+
new Array(questions.length).fill('');
51+
4852
/* If the user has previously visited the website, then an array in
4953
LocalStorage would exist of a certain length which corresponds to which
5054
questions they have/have not completed. In the event that we add new questions
@@ -62,6 +66,17 @@ const Table = () => {
6266
window.localStorage.setItem('checked', JSON.stringify(checkedList));
6367
}
6468

69+
if (checkedAtList.length !== questions.length) {
70+
const resizedCheckedAtList = new Array(questions.length).fill('');
71+
72+
for (let i = 0; i < checkedAtList.length; i += 1) {
73+
resizedCheckedAtList[i] = checkedAtList[i];
74+
}
75+
76+
checkedAtList = resizedCheckedAtList;
77+
window.localStorage.setItem('checkedAt', JSON.stringify(checkedAtList));
78+
}
79+
6580
const filteredByCheckbox = () => {
6681
const checkbox = localStorage.getItem('checkbox') || '';
6782
return questions.filter(question => {
@@ -91,6 +106,7 @@ const Table = () => {
91106
totalDifficultyCount[questions[i].difficulty] += 1;
92107
}
93108

109+
const [checkedAt, setCheckedAt] = useState(checkedAtList);
94110
const [data, setData] = useState(filteredByCheckbox());
95111
const [difficultyCount, setDifficultyCount] = useState(difficultyMap);
96112
const [checked, setChecked] = useState(checkedList);
@@ -102,6 +118,10 @@ const Table = () => {
102118
window.localStorage.setItem('checked', JSON.stringify(checked));
103119
}, [checked]);
104120

121+
useEffect(() => {
122+
window.localStorage.setItem('checkedAt', JSON.stringify(checkedAt));
123+
}, [checkedAt]);
124+
105125
useEffect(() => {
106126
window.localStorage.setItem('showPatterns', JSON.stringify(showPatterns));
107127
}, [showPatterns]);
@@ -134,6 +154,8 @@ const Table = () => {
134154
const [resetModal, setResetModal] = React.useState(false);
135155
const toggleResetModal = () => {
136156
setResetModal(!resetModal);
157+
const clearedCheckedAt = checkedAt.map(() => null);
158+
setCheckedAt(clearedCheckedAt);
137159
};
138160

139161
return (
@@ -154,7 +176,7 @@ const Table = () => {
154176
labelPosition={0}
155177
labelStyle={{
156178
// Needed for Dark Reader to work
157-
fill: 'black',
179+
fill: '#A54800',
158180
}}
159181
startAngle={-90}
160182
lineWidth={12}
@@ -200,6 +222,13 @@ const Table = () => {
200222
checked[cellInfo.row.original.id] = !checked[
201223
cellInfo.row.original.id
202224
];
225+
const currentTime = new Date().toISOString().slice(0, 10);
226+
// const updatedCheckedAt = [...checkedAt];
227+
checkedAt[cellInfo.row.original.id] = checked[
228+
cellInfo.row.original.id
229+
]
230+
? currentTime
231+
: null;
203232
const question = questions.find(
204233
q => q.id === cellInfo.row.original.id,
205234
);
@@ -218,6 +247,7 @@ const Table = () => {
218247
setDifficultyCount(difficultyCount);
219248
setChecked([...checked]);
220249
setData(filteredByCheckbox());
250+
setCheckedAt([...checkedAt]);
221251
}}
222252
/>
223253
</span>
@@ -451,6 +481,19 @@ const Table = () => {
451481
},
452482
Filter: SelectColumnFilter,
453483
},
484+
{
485+
Header: 'Last Solved On',
486+
accessor: 'LastSolvedOn',
487+
disableSortBy: true,
488+
Cell: cellInfo => {
489+
return (
490+
<div className="lastSolvedOn">
491+
{checkedAt[cellInfo.row.original.id]}
492+
</div>
493+
);
494+
},
495+
disableFilters: true,
496+
},
454497
],
455498
},
456499
],

src/components/Table/styles.scss

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,54 @@
1+
body.light-mode .table {
2+
background-color: #ffffff;
3+
color: #000000;
4+
}
5+
body.light-mode .table thead > tr th {
6+
background-color: #ffffff;
7+
}
8+
body.light-mode .pattern-count {
9+
background-color: #ffffff;
10+
color: #000000;
11+
}
12+
body.light-mode .table tr:nth-child(odd) {
13+
background-color: #f1f2f4;
14+
}
15+
body.light-mode .table tr:nth-child(even) {
16+
background-color: #ffffff;
17+
}
18+
body.light-mode .table tbody tr:hover {
19+
background-color: #dcdfe4;
20+
color: #000000;
21+
}
22+
23+
body.dark-mode .table {
24+
background-color: #161a1d;
25+
color: #ffffff;
26+
}
27+
body.dark-mode .table thead > tr th {
28+
background-color: #161a1d;
29+
}
30+
body.dark-mode .pattern-count {
31+
background-color: #161a1d;
32+
color: #ffffff;
33+
}
34+
body.dark-mode .table tr:nth-child(odd) {
35+
background-color: #22272b;
36+
}
37+
body.dark-mode .table tr:nth-child(even) {
38+
background-color: #161a1d;
39+
}
40+
body.dark-mode .table tbody tr:hover {
41+
background-color: #101214;
42+
color: #ffffff;
43+
}
44+
body.dark-mode .modal-content {
45+
background-color: #1d2125;
46+
color: #ffffff;
47+
.close {
48+
color: #ffffff;
49+
}
50+
}
51+
152
.table {
253
.row {
354
justify-content: center;
@@ -11,7 +62,8 @@
1162
> tr th {
1263
background: white;
1364
position: sticky;
14-
top: 0;
65+
top: 50px;
66+
text-wrap: nowrap;
1567
}
1668
}
1769

@@ -67,4 +119,7 @@
67119
margin-bottom: 10px;
68120
font-size: 0.7rem;
69121
}
122+
.lastSolvedOn {
123+
text-wrap: nowrap;
124+
}
70125
}

0 commit comments

Comments
 (0)