diff --git a/functions/split-user-data.js b/functions/split-user-data.js deleted file mode 100644 index bab05988b..000000000 --- a/functions/split-user-data.js +++ /dev/null @@ -1,86 +0,0 @@ -const admin = require('firebase-admin'); -const fs = require('fs'); -const serviceAccount = require('./service-account.json'); - -admin.initializeApp({ - credential: admin.credential.cert(serviceAccount), - databaseURL: 'https://cornelldti-courseplan-dev.firebaseio.com', -}); - -const db = admin.firestore(); -const userDataCollection = db.collection('userData'); - -const usernameCollection = db.collection('user-name'); -const semestersCollection = db.collection('user-semesters'); -const toggleableRequirementChoicesCollection = db.collection('user-toggleable-requirement-choices'); -const subjectColorsCollection = db.collection('user-subject-colors'); -const uniqueIncrementerCollection = db.collection('user-unique-incrementer'); -const onboardingDataCollection = db.collection('user-onboarding-data'); - -if (process.argv[2] === '--dry-run') { - userDataCollection.get().then(userData => { - const oldData = []; - const newUsernameCollection = {}; - const newSemestersCollection = {}; - const newToggleableRequirementChoicesCollection = {}; - const newSubjectColorsCollection = {}; - const newUniqueIncrementerCollection = {}; - const newOnboardingDataCollection = {}; - userData.docs.forEach(userDataDocument => { - const data = userDataDocument.data(); - oldData.push(data); - - newUsernameCollection[userDataDocument.id] = data.name; - newSemestersCollection[userDataDocument.id] = { semesters: data.semesters }; - newToggleableRequirementChoicesCollection[userDataDocument.id] = - data.toggleableRequirementChoices || {}; - newSubjectColorsCollection[userDataDocument.id] = data.subjectColors || {}; - newUniqueIncrementerCollection[userDataDocument.id] = { - uniqueIncrementer: data.uniqueIncrementer || 0, - }; - newOnboardingDataCollection[userDataDocument.id] = data.userData; - }); - - fs.writeFileSync('old.json', JSON.stringify(oldData, undefined, 2)); - fs.writeFileSync('new-usernames.json', JSON.stringify(newUsernameCollection, undefined, 2)); - fs.writeFileSync('new-semesters.json', JSON.stringify(newSemestersCollection, undefined, 2)); - fs.writeFileSync( - 'new-toggleable.json', - JSON.stringify(newToggleableRequirementChoicesCollection, undefined, 2) - ); - fs.writeFileSync( - 'new-subject-color.json', - JSON.stringify(newSubjectColorsCollection, undefined, 2) - ); - fs.writeFileSync( - 'new-unique-incrementer.json', - JSON.stringify(newUniqueIncrementerCollection, undefined, 2) - ); - fs.writeFileSync( - 'new-onboarding.json', - JSON.stringify(newOnboardingDataCollection, undefined, 2) - ); - }); -} else { - userDataCollection.get().then(userData => { - Promise.all( - userData.docs.map(userDataDocument => { - const batch = db.batch(); - const data = userDataDocument.data(); - batch.set(usernameCollection.doc(userDataDocument.id), data.name); - batch.set(semestersCollection.doc(userDataDocument.id), { semesters: data.semesters }); - batch.set( - toggleableRequirementChoicesCollection.doc(userDataDocument.id), - data.toggleableRequirementChoices || {} - ); - batch.set(subjectColorsCollection.doc(userDataDocument.id), data.subjectColors || {}); - batch.set(uniqueIncrementerCollection.doc(userDataDocument.id), { - uniqueIncrementer: data.uniqueIncrementer || 0, - }); - batch.set(onboardingDataCollection.doc(userDataDocument.id), data.userData); - batch.delete(userDataDocument.ref); - return batch.commit(); - }) - ); - }); -} diff --git a/functions/update-user-data-courses.js b/functions/update-user-data-courses.js deleted file mode 100644 index b665da7a7..000000000 --- a/functions/update-user-data-courses.js +++ /dev/null @@ -1,50 +0,0 @@ -const admin = require('firebase-admin'); -const fs = require('fs'); -const serviceAccount = require('./service-account.json'); - -admin.initializeApp({ - credential: admin.credential.cert(serviceAccount), - databaseURL: 'https://cornelldti-courseplan-dev.firebaseio.com', -}); - -const filteredAllCourses = Object.values( - JSON.parse(fs.readFileSync('../src/assets/courses/full-courses.json').toString()) -).flat(); - -const db = admin.firestore(); -const userDataCollection = db.collection('userData'); - -const transformData = data => ({ - ...data, - semesters: data.semesters.map(semester => ({ - ...semester, - courses: semester.courses.map(course => { - const { code } = course; - const [subject, number] = code.split(' '); - const fullCourse = filteredAllCourses.find( - it => it.subject === subject && it.catalogNbr === number - ); - const crseId = fullCourse && fullCourse.crseId; - if (crseId == null) throw new Error(`user=${data.id}, subject=${subject}, number=${number}`); - return { ...course, crseId }; - }), - })), -}); - -if (process.argv[2] === '--dry-run') { - userDataCollection.get().then(userData => { - const oldUserData = userData.docs.map(doc => ({ id: doc.id, ...doc.data() })); - const newUserData = oldUserData.map(transformData); - fs.writeFileSync('old.json', JSON.stringify(oldUserData, undefined, 2)); - fs.writeFileSync('new.json', JSON.stringify(newUserData, undefined, 2)); - }); - return; -} else { - userDataCollection.get().then(userData => { - Promise.all( - userData.docs.map(userDataDocument => - userDataDocument.ref.set(transformData(userDataDocument.data())) - ) - ); - }); -} diff --git a/functions/update-user-data-semesters.js b/functions/update-user-data-semesters.js deleted file mode 100644 index 61773b886..000000000 --- a/functions/update-user-data-semesters.js +++ /dev/null @@ -1,98 +0,0 @@ -// Updates the order of the semesters in the userData collection to be in order -// from most recent to least recent - -const admin = require('firebase-admin'); -const fs = require('fs'); -const serviceAccount = require('./service-account.json'); - -admin.initializeApp({ - credential: admin.credential.cert(serviceAccount), - databaseURL: 'https://cornelldti-courseplan-dev.firebaseio.com', -}); - -const db = admin.firestore(); -const userDataCollection = db.collection('userData'); - -/** - * @param {*} type of the season. 'Spring' | 'Summer' | 'Fall' | 'Winter' - * @returns the ordered number that represents the type of season. 1 is returned - * for 'Spring', 6 is returned for 'Summer', 8 is returned for 'Fall', and 12 is - * returned for 'Winter' - */ -function typeToOrderedNumber(type) { - switch (type) { - case 'Spring': - return 1; - case 'Summer': - return 6; - case 'Fall': - return 8; - case 'Winter': - return 12; - default: - } -} - -/** - * Compares semesterObject1 and semesterObject2 based on type and year properties - * @param {*} semesterObject1 is an object that is in the userData.semesters array - * @param {*} semesterObject2 is an object that is in the userData.semesters array - * @returns 1 if semesterObject2 occurs more recently than semesterObject1, - * -1 if semesterObject1 occurs more recently than semesterObject2, 0 otherwise. - */ -function compareSemesterObjectsByTypeAndYear(semesterObject1, semesterObject2) { - const type1 = semesterObject1.type; - const type2 = semesterObject2.type; - const year1 = semesterObject1.year; - const year2 = semesterObject2.year; - - if (year2 > year1) { - // semesterObject2 has more recent year than semesterObject1 - return 1; - } else if (year1 > year2) { - // semesterObject1 has more recent year than semesterObject2 - return -1; - } else if (typeToOrderedNumber(type2) > typeToOrderedNumber(type1)) { - // semesterObject2 has more recent semester type than semesterObject1 - return 1; - } else if (typeToOrderedNumber(type1) > typeToOrderedNumber(type2)) { - // semesterObject1 has more recent semester type than semesterObject2 - return -1; - } else { - return 0; - } -} - -/** - * - * @param {*} semesters is the userData.semesters array on Firestore - * @returns semesters sorted from most recent to least recent type and year - */ -function semesterObjectsByMostRecentTypeAndYear(semesters) { - // Sorts from most recent type and year - return semesters.sort(compareSemesterObjectsByTypeAndYear); -} - -const transformData = data => ({ - ...data, - semesters: semesterObjectsByMostRecentTypeAndYear(data.semesters), -}); - -if (process.argv[2] === '--dry-run') { - userDataCollection.get().then(userData => { - const oldUserData = userData.docs.map(doc => ({ id: doc.id, ...doc.data() })); - // Using JSON parse and stringify trick so we get a deep copy of the nested oldUserData - const newUserData = JSON.parse(JSON.stringify(oldUserData)).map(transformData); - fs.writeFileSync('old-userData-semesters.json', JSON.stringify(oldUserData, undefined, 2)); - fs.writeFileSync('new-userData-semesters.json', JSON.stringify(newUserData, undefined, 2)); - }); - return; -} else { - userDataCollection.get().then(userData => { - Promise.all( - userData.docs.map(userDataDocument => - userDataDocument.ref.set(transformData(userDataDocument.data())) - ) - ); - }); -} diff --git a/src/components/Course/Course.vue b/src/components/Course/Course.vue index c34213f67..e9ee07bd1 100644 --- a/src/components/Course/Course.vue +++ b/src/components/Course/Course.vue @@ -26,7 +26,7 @@ @delete-course="deleteCourse" @color-course="colorCourse" @edit-course-credit="editCourseCredit" - :getCreditRange="getCreditRange" + :getCreditRange="getCreditRange || []" v-click-outside="closeMenuIfOpen" /> diff --git a/src/components/Modals/CourseMenu.vue b/src/components/Modals/CourseMenu.vue index f77c878cc..aaf7df22a 100644 --- a/src/components/Modals/CourseMenu.vue +++ b/src/components/Modals/CourseMenu.vue @@ -52,7 +52,7 @@ class="courseMenu-section" @mouseover="setDisplayEditCourseCredits(true)" @mouseleave="setDisplayEditCourseCredits(false)" - v-if="getCreditRange[0] != getCreditRange[1]" + v-if="getCreditRange && getCreditRange[0] != getCreditRange[1]" > , default: '' }, isCourseModelSelectingSemester: { type: Boolean, default: false }, @@ -287,6 +288,10 @@ export default Vue.extend({ } else { this.yearText = 0; } + + if (this.isSemesterAdd) { + this.$emit('updateSemProps', this.seasonPlaceholder, Number(this.yearPlaceholder)); + } }, resetDropdowns() { // reset season dropdown diff --git a/src/components/Modals/NewSemesterModal.vue b/src/components/Modals/NewSemesterModal.vue index 26a895e5b..4a3d172bf 100644 --- a/src/components/Modals/NewSemesterModal.vue +++ b/src/components/Modals/NewSemesterModal.vue @@ -12,6 +12,7 @@ { - // Check whitelist emails to ensure user can log in - if (user == null) { + if (user == null || user.user == null) { return; } - this.checkEmailAccess(user); + const simplifiedUser = { + displayName: checkNotNull(user.user.displayName), + email: checkNotNull(user.user.email), + }; + store.commit('setCurrentFirebaseUser', simplifiedUser); + this.performingRequest = false; + this.$router.push('/'); + GTagLoginEvent(this.$gtag, 'Google'); }) .catch(err => { this.performingRequest = false; this.errorMsg = err.message; }); }, - checkEmailAccess({ user }: { user: firebase.User | null }) { - if (user == null) { - return; - } - const docRef = whitelistCollection.doc(user.email || ''); - docRef - .get() - .then(doc => { - if (doc.exists) { - this.performingRequest = false; - this.$router.push('/'); - GTagLoginEvent(this.$gtag, 'Google'); - } else { - this.handleUserWithoutAccess(); - } - }) - .catch(() => this.handleUserWithoutAccess()); - }, - - handleUserWithoutAccess() { - this.performingRequest = false; - fb.auth.signOut(); - // eslint-disable-next-line no-alert - alert( - "Sorry, but you do not have access currently.\nPlease check back April 5 for CoursePlan's public release." - ); - }, - - validateEmail(email: string): boolean { - return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); - }, - validateMajor(major: string): boolean { - return major.trim().length > 0; - }, - addUser() { - if (this.validateEmail(this.waitlist.email) && this.validateMajor(this.waitlist.major)) { - // eslint-disable-next-line no-alert - alert("You have been added to the waitlist. We'll be in touch shortly!"); - - // Add timestamp to data in YYYY-MM-DD hh:mm:ss - const dt = new Date(); - this.waitlist.time = `${(dt.getMonth() + 1) - .toString() - .padStart(2, '0')}/${dt - .getDate() - .toString() - .padStart(2, '0')}/${dt - .getFullYear() - .toString() - .padStart(4, '0')} ${dt - .getHours() - .toString() - .padStart(2, '0')}:${dt - .getMinutes() - .toString() - .padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}`; - - // Add landing page data to Firebase - landingEmailsCollection.add(this.waitlist); - - // Clear fields - this.waitlist.email = ''; - this.waitlist.major = ''; - } else if (!this.validateEmail(this.waitlist.email)) { - // eslint-disable-next-line no-alert - alert('You have entered an invalid email address!'); - } else { - // eslint-disable-next-line no-alert - alert('You have not entered a major!'); - } - }, getYear(): number { const today = new Date(); return today.getFullYear(); diff --git a/src/firebaseConfig.ts b/src/firebaseConfig.ts index fea03d587..760b34eaf 100644 --- a/src/firebaseConfig.ts +++ b/src/firebaseConfig.ts @@ -111,6 +111,3 @@ export const onboardingDataCollection = db return userData; }, }); - -export const whitelistCollection = db.collection('cpWhitelist'); -export const landingEmailsCollection = db.collection('landingEmails');