Skip to content

Commit 225a4e9

Browse files
committed
Merge branch 'refactor/add-optimiser-unit-tests' of https://github.com/leslieyip02/nusmods into refactor/add-optimiser-unit-tests
2 parents 60f4963 + a35e7d8 commit 225a4e9

File tree

6 files changed

+177
-3
lines changed

6 files changed

+177
-3
lines changed

website/src/storage/keys.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ export const CONTACT_INFO = 'contact-info';
2626

2727
// Used by MPE
2828
export const NUS_AUTH_TOKEN = 'nus-auth-token';
29+
30+
// Used by Beta Banner
31+
export const BETA_BANNER = 'beta-banner';
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
@import '~styles/utils/modules-entry';
2+
3+
// Make the buttons move below the body on small screens and in vertical mode
4+
@mixin wrap-buttons {
5+
flex-wrap: wrap;
6+
7+
.buttons {
8+
flex: 1 0 auto;
9+
justify-content: space-between;
10+
width: 100%;
11+
margin-top: 1rem;
12+
13+
:global(.btn) {
14+
display: block;
15+
width: 100%;
16+
text-align: center;
17+
}
18+
}
19+
}
20+
21+
.announcement {
22+
z-index: 1;
23+
display: flex;
24+
overflow: hidden;
25+
justify-content: space-between;
26+
padding: 1.2rem 1rem 1.1rem 1.4rem;
27+
line-height: 1.3;
28+
29+
h3 {
30+
margin-bottom: 0.5rem;
31+
font-weight: $font-weight-bold;
32+
font-size: 1.2rem;
33+
}
34+
35+
.body {
36+
margin-right: 0.5rem;
37+
38+
a:hover {
39+
text-decoration: underline;
40+
}
41+
42+
.bodyElement {
43+
margin-bottom: 0.4rem;
44+
45+
ul {
46+
padding-top: 0.5rem;
47+
margin-bottom: 0.5rem;
48+
}
49+
}
50+
51+
.bodyElement:last-child {
52+
margin-bottom: 0;
53+
}
54+
}
55+
56+
.actions {
57+
margin-top: 0.5rem;
58+
}
59+
60+
@include media-breakpoint-down(xs) {
61+
padding: 1rem 0.75rem 0.75rem 1rem;
62+
}
63+
}
64+
65+
.buttons {
66+
display: flex;
67+
flex: 0 0 auto;
68+
align-items: center;
69+
70+
@include media-breakpoint-down(xs) {
71+
flex: 0 0;
72+
}
73+
}
74+
75+
.Betabutton {
76+
margin-top: 15px;
77+
@extend .buttons;
78+
}
79+
80+
.backgroundIcon {
81+
position: absolute;
82+
top: -1rem;
83+
left: -1rem;
84+
opacity: 0.1;
85+
width: 8rem;
86+
height: 8rem;
87+
pointer-events: none;
88+
}
89+
90+
.wrapButtons {
91+
@include media-breakpoint-down(xs) {
92+
@include wrap-buttons;
93+
}
94+
}
95+
96+
.hacktoberfest {
97+
:global(.verticalMode) & {
98+
@include wrap-buttons;
99+
}
100+
}
101+
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { memo, useCallback, useState } from 'react';
2+
import classnames from 'classnames';
3+
import { Info } from 'react-feather';
4+
import { useHistory } from 'react-router-dom';
5+
6+
import CloseButton from 'views/components/CloseButton';
7+
import { useSelector } from 'react-redux';
8+
import { State } from 'types/state';
9+
import { BETA_BANNER } from 'storage/keys';
10+
import storage from 'storage';
11+
import styles from './BetaBanner.scss';
12+
13+
const key = BETA_BANNER;
14+
15+
const BetaBanner = memo(() => {
16+
const history = useHistory();
17+
const beta = useSelector(({ settings }: State) => settings.beta);
18+
const [isOpen, setIsOpen] = useState(() => {
19+
if (beta) return false;
20+
if (key) return !storage.getItem(key);
21+
return true;
22+
});
23+
24+
const dismiss = useCallback(() => {
25+
if (key) storage.setItem(key, true);
26+
setIsOpen(false);
27+
}, []);
28+
29+
if (!isOpen) {
30+
return null;
31+
}
32+
33+
return (
34+
<div className={classnames('alert alert-info no-export', styles.announcement)}>
35+
<Info className={styles.backgroundIcon} />
36+
37+
<div className={classnames(styles.body, styles.wrapButtons)}>
38+
<h3>Timetable Optimiser is now in BETA!</h3>
39+
<p className={styles.bodyElement}>
40+
Turn on NUSMods BETA to try out the new timetable optimiser to help you find your optimal
41+
timetable based on your preferences.
42+
</p>
43+
<p className={styles.bodyElement}>Share your feedback to help us make it even better!</p>
44+
<div className={styles.Betabutton}>
45+
<button
46+
className="btn btn-info"
47+
type="button"
48+
onClick={() => history.push('/settings#beta')}
49+
>
50+
Turn on BETA
51+
</button>
52+
</div>
53+
</div>
54+
55+
<div className={styles.buttons}>
56+
<CloseButton onClick={dismiss} />
57+
</div>
58+
</div>
59+
);
60+
});
61+
62+
export default BetaBanner;

website/src/views/settings/BetaToggle.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import ExternalLink from 'views/components/ExternalLink';
44
import config from 'config';
55
import styles from './SettingsContainer.scss';
66

7-
export const currentTests = ['Timetable Optimiser: find the perfect timetable for you'];
7+
export const currentTests = ['Timetable Optimiser: build a timetable that suits your needs'];
88

99
type Props = {
1010
betaTester: boolean;
@@ -23,7 +23,7 @@ const BetaToggle = memo<Props>((props) => {
2323

2424
const testDescriptions = hasTests ? (
2525
<>
26-
<h5>Current tests</h5>
26+
<h5>Current Tests</h5>
2727
<ul>
2828
{currentTests.map((test) => (
2929
<li key={test}>{test}</li>
@@ -36,7 +36,9 @@ const BetaToggle = memo<Props>((props) => {
3636

3737
return (
3838
<div>
39-
<h4 id="beta">NUSMods Beta</h4>
39+
<h4 id="beta" className={styles.targetable}>
40+
NUSMods Beta
41+
</h4>
4042

4143
<div className={styles.toggleRow}>
4244
<div className={styles.toggleDescription}>

website/src/views/settings/SettingsContainer.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@
6666
}
6767
}
6868

69+
.targetable {
70+
scroll-margin-top: $navbar-height + 2rem;
71+
}
72+
6973
.betaToggle {
7074
margin-bottom: 1rem;
7175
}

website/src/views/timetable/TimetableContent.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import ErrorBoundary from 'views/errors/ErrorBoundary';
5252
import ModRegNotification from 'views/components/notfications/ModRegNotification';
5353
import { State as StoreState } from 'types/state';
5454
import { ModuleWithColor, TombstoneModule } from 'types/views';
55+
import BetaBanner from 'views/components/notfications/BetaBanner';
5556
import Timetable from './Timetable';
5657
import TimetableActions from './TimetableActions';
5758
import TimetableModulesTable from './TimetableModulesTable';
@@ -442,6 +443,7 @@ class TimetableContent extends React.Component<Props, State> {
442443
<Title>Timetable</Title>
443444

444445
<Announcements />
446+
<BetaBanner />
445447

446448
<ErrorBoundary>
447449
<ModRegNotification />

0 commit comments

Comments
 (0)