diff --git a/manifests/prod/cronjob.yml b/manifests/prod/cronjob.yml index e65523c0f2..64182c0ea1 100644 --- a/manifests/prod/cronjob.yml +++ b/manifests/prod/cronjob.yml @@ -14,7 +14,7 @@ spec: containers: - image: semesterly.azurecr.io/semesterly:Version name: gunicorn-cron - command: ["/bin/bash","/code/run_parser.sh"] + command: ["/bin/bash", "/code/run_parser.sh"] workingDir: /code envFrom: - secretRef: diff --git a/package-lock.json b/package-lock.json index fffa5f1efa..323b983d93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7205,6 +7205,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, "requires": { "file-uri-to-path": "1.0.0" } @@ -8122,6 +8123,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, "requires": { "bindings": "^1.5.0", "nan": "^2.12.1" @@ -8130,7 +8132,8 @@ "nan": { "version": "2.18.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "optional": true } } }, @@ -12986,7 +12989,8 @@ "fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==" + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "optional": true }, "function-bind": { "version": "1.1.0", @@ -18639,6 +18643,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, "requires": { "bindings": "^1.5.0", "nan": "^2.12.1" @@ -18647,7 +18652,8 @@ "nan": { "version": "2.18.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "optional": true } } }, @@ -28414,6 +28420,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, "requires": { "bindings": "^1.5.0", "nan": "^2.12.1" @@ -28422,7 +28429,8 @@ "nan": { "version": "2.18.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "optional": true } } }, @@ -32625,6 +32633,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, "requires": { "bindings": "^1.5.0", "nan": "^2.12.1" @@ -32777,7 +32786,8 @@ "nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "optional": true }, "pako": { "version": "1.0.11", @@ -33967,6 +33977,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, "requires": { "bindings": "^1.5.0", "nan": "^2.12.1" @@ -34147,7 +34158,8 @@ "nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "optional": true }, "negotiator": { "version": "0.6.2", diff --git a/static/js/redux/state/slices/newsModalSlice.ts b/static/js/redux/state/slices/newsModalSlice.ts index 029997d31b..82bdda7f9d 100644 --- a/static/js/redux/state/slices/newsModalSlice.ts +++ b/static/js/redux/state/slices/newsModalSlice.ts @@ -16,6 +16,7 @@ const newsModalSlice = createSlice({ state.isVisible = false; }, showNewsModal: (state) => { + localStorage.setItem("lastViewedNewsDate", new Date(Date.now()).toISOString()); // ! state.isVisible = true; }, }, diff --git a/static/js/redux/ui/Semesterly.tsx b/static/js/redux/ui/Semesterly.tsx index 592f413d7e..89dfed5b55 100644 --- a/static/js/redux/ui/Semesterly.tsx +++ b/static/js/redux/ui/Semesterly.tsx @@ -128,13 +128,55 @@ const Semesterly = () => { // DataLastUpdated Input example- 2021-05-02 14:42 UTC // Params: How the backend sends a timestamp // dateString: of the form yyyy-mm-dd hh:mm - const dateString = dataLastUpdated.toString().slice(0, -4); // exclude UTC + const dateString = dataLastUpdated.toString(); if (!dateString || dateString.length === 0) return ""; // Convert given datetime to local datetime of user - // in form yyyy-mm-dd hh:mm TZ (Timezone full name) - return new Date(dateString).toString(); + // in form (month) dd, yyyy + + const curDate: Date = new Date(dateString); + + const months = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", + ]; + + let dayEnding: String; + const curDay = curDate.getDay(); + if (curDay >= 11 && curDay <= 13) { + dayEnding = "th"; + } + + switch (curDay % 10) { + case 1: + dayEnding = "st"; + break; + case 2: + dayEnding = "nd"; + break; + case 3: + dayEnding = "rd"; + break; + default: + dayEnding = "th"; + } + + const monthIndex: number = curDate.getMonth(); + + return `${ + months[monthIndex] + } ${curDate.getUTCDate()}${dayEnding}, ${curDate.getFullYear()}`; }; const mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( diff --git a/static/js/redux/ui/SideBar.tsx b/static/js/redux/ui/SideBar.tsx index 643702c3dc..ae479ddada 100644 --- a/static/js/redux/ui/SideBar.tsx +++ b/static/js/redux/ui/SideBar.tsx @@ -79,6 +79,9 @@ const SideBar = () => { const hideDropdown = () => { setShowDropdown(false); + + // * Set hoveredCourse to -1 if user clicks out + setHoveredCourse(-1); }; const toggleDropdown = () => { diff --git a/static/js/redux/ui/modals/NewsModal.tsx b/static/js/redux/ui/modals/NewsModal.tsx index d3cc098762..39d758d687 100644 --- a/static/js/redux/ui/modals/NewsModal.tsx +++ b/static/js/redux/ui/modals/NewsModal.tsx @@ -26,23 +26,21 @@ const NewsModal = () => { useEffect(() => { const tutorialData = JSON.parse(localStorage.getItem("tutorial")); - if (!tutorialData || !tutorialData.modalTutShown || isSigningUp) { - return; - } + const displayCriteria = tutorialData && tutorialData.modalTutShown && !isSigningUp; const fetchData = async () => { const response = await fetch(getNewsEndpoint()); const data = await response.json(); // Only display modal if the news was posted after the last viewed time - if (data.date && new Date(data.date) > lastViewedTime) { + if (data.date && new Date(data.date) > lastViewedTime && displayCriteria) { dispatch(newsModalActions.showNewsModal()); // Set to current date and time localStorage.setItem("lastViewedNewsDate", new Date(Date.now()).toISOString()); } - setNewsTitle(data.title); - setNewsBody(data.body); + setNewsTitle(data.title === "" ? "No news at the moment!" : data.title); + setNewsBody(data.body === "" ? "Please check back again later." : data.body); }; fetchData();