Skip to content

Commit

Permalink
Refactor firestore modifiers and gtag events (#342)
Browse files Browse the repository at this point in the history
* Refactor semester firestore modifier functions

* Refactor gtag

* Format

* Fix typo
  • Loading branch information
benjamin-shen authored Mar 4, 2021
1 parent 007e3de commit 0429190
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 115 deletions.
63 changes: 19 additions & 44 deletions src/components/Semester/Semester.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,12 @@ import fall from '@/assets/images/fallEmoji.svg';
import spring from '@/assets/images/springEmoji.svg';
import winter from '@/assets/images/winterEmoji.svg';
import summer from '@/assets/images/summerEmoji.svg';
import { chooseSelectableRequirementOption } from '@/global-firestore-data';
import {
editSemester,
addCourseToSemester,
deleteCourseFromSemester,
chooseSelectableRequirementOption,
} from '@/global-firestore-data';
import { cornellCourseRosterCourseToFirebaseSemesterCourse } from '@/user-data-converter';
import store from '@/store';
Expand Down Expand Up @@ -185,7 +190,10 @@ export default Vue.extend({
required: true,
},
compact: { type: Boolean, required: true },
activatedCourse: { type: Object as PropType<FirestoreSemesterCourse>, required: true },
activatedCourse: {
type: Object as PropType<FirestoreSemesterCourse>,
required: true,
},
isFirstSem: { type: Boolean, required: true },
},
mounted() {
Expand All @@ -209,8 +217,7 @@ export default Vue.extend({
return this.courses;
},
set(newCourses: readonly FirestoreSemesterCourse[]) {
this.$emit(
'edit-semester',
editSemester(
this.year,
this.type,
(semester: FirestoreSemester): FirestoreSemester => ({
Expand Down Expand Up @@ -312,52 +319,22 @@ export default Vue.extend({
},
addCourse(data: CornellCourseRosterCourse, requirementID: string) {
const newCourse = cornellCourseRosterCourseToFirebaseSemesterCourse(data);
addCourseToSemester(this.type, this.year, newCourse);
chooseSelectableRequirementOption({
...store.state.selectableRequirementChoices,
[newCourse.uniqueID]: requirementID,
});
const courseCode = `${data.subject} ${data.catalogNbr}`;
this.$emit(
'edit-semester',
this.year,
this.type,
(semester: FirestoreSemester): FirestoreSemester => ({
...semester,
courses: [...this.courses, newCourse],
})
);
const confirmationMsg = `Added ${courseCode} to ${this.type} ${this.year}`;
this.openConfirmationModal(confirmationMsg);
this.$gtag.event('add-course', {
event_category: 'course',
event_label: 'add',
value: 1,
});
const courseCode = `${data.subject} ${data.catalogNbr}`;
this.openConfirmationModal(`Added ${courseCode} to ${this.type} ${this.year}`);
},
deleteCourse(courseCode: string, uniqueID: number) {
this.openConfirmationModal(`Removed ${courseCode} from ${this.type} ${this.year}`);
this.$gtag.event('delete-course', {
event_category: 'course',
event_label: 'delete',
value: 1,
});
deleteCourseFromSemester(this.type, this.year, uniqueID);
// Update requirements menu
this.$emit(
'edit-semester',
this.year,
this.type,
(semester: FirestoreSemester): FirestoreSemester => ({
...semester,
courses: this.courses.filter(course => course.uniqueID !== uniqueID),
})
);
this.openConfirmationModal(`Removed ${courseCode} from ${this.type} ${this.year}`);
},
colorCourse(color: string, uniqueID: number) {
this.$emit(
'edit-semester',
editSemester(
this.year,
this.type,
(semester: FirestoreSemester): FirestoreSemester => ({
Expand All @@ -372,8 +349,7 @@ export default Vue.extend({
this.$emit('course-onclick', course);
},
editCourseCredit(credit: number, uniqueID: number) {
this.$emit(
'edit-semester',
editSemester(
this.year,
this.type,
(semester: FirestoreSemester): FirestoreSemester => ({
Expand Down Expand Up @@ -418,8 +394,7 @@ export default Vue.extend({
this.isEditSemesterOpen = true;
},
editSemester(seasonInput: 'Fall' | 'Spring' | 'Winter' | 'Summer', yearInput: number) {
this.$emit(
'edit-semester',
editSemester(
this.year,
this.type,
(oldSemester: FirestoreSemester): FirestoreSemester => ({
Expand Down
59 changes: 6 additions & 53 deletions src/components/Semester/SemesterView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
@course-onclick="courseOnClick"
@new-semester="openSemesterModal"
@delete-semester="deleteSemester"
@edit-semester="editSemester"
@open-caution-modal="openCautionModal"
@add-course-to-semester="addNewCourse"
/>
Expand Down Expand Up @@ -98,12 +97,8 @@ import SemesterCaution from '@/components/Semester/SemesterCaution.vue';
import NewSemesterModal from '@/components/Modals/NewSemesterModal.vue';
import store from '@/store';
import {
addCourseToSemester,
compareFirestoreSemesters,
createSemester,
editSemesters,
} from '@/global-firestore-data';
import { GTagEvent } from '@/gtag';
import { addSemester, deleteSemester, addCourseToSemester } from '@/global-firestore-data';
import { closeBottomBar } from '@/components/BottomBar/BottomBarState';
export default Vue.extend({
Expand Down Expand Up @@ -142,21 +137,13 @@ export default Vue.extend({
setCompact() {
if (!this.compact) {
this.$emit('compact-updated', !this.compact);
this.$gtag.event('to-compact', {
event_category: 'views',
event_label: 'compact',
value: 1,
});
GTagEvent(this.$gtag, 'to-compact');
}
},
setNotCompact() {
if (this.compact) {
this.$emit('compact-updated', !this.compact);
this.$gtag.event('to-not-compact', {
event_category: 'views',
event_label: 'not-compact',
value: 1,
});
GTagEvent(this.$gtag, 'to-not-compact');
}
},
openSemesterConfirmationModal(type: FirestoreSemesterType, year: number, isAdd: boolean) {
Expand Down Expand Up @@ -190,46 +177,12 @@ export default Vue.extend({
addCourseToSemester(season, year, course);
},
addSemester(type: FirestoreSemesterType, year: number) {
this.$gtag.event('add-semester', {
event_category: 'semester',
event_label: 'add',
value: 1,
});
editSemesters(oldSemesters =>
[...oldSemesters, createSemester([], type, year)].sort(compareFirestoreSemesters)
);
addSemester(type, year);
this.openSemesterConfirmationModal(type, year, true);
},
deleteSemester(type: FirestoreSemesterType, year: number) {
this.$gtag.event('delete-semester', {
event_category: 'semester',
event_label: 'delete',
value: 1,
});
// Confirm success with alert
deleteSemester(type, year);
this.openSemesterConfirmationModal(type, year, false);
// Update requirements menu from dashboard
editSemesters(oldSemesters =>
oldSemesters.filter(semester => semester.type !== type || semester.year !== year)
);
},
editSemester(
year: number,
type: FirestoreSemesterType,
updater: (oldSemester: FirestoreSemester) => FirestoreSemester
) {
editSemesters(oldSemesters =>
oldSemesters
.map(currentSemester =>
currentSemester.year === year && currentSemester.type === type
? updater(currentSemester)
: currentSemester
)
.sort(compareFirestoreSemesters)
);
},
courseOnClick(course: FirestoreSemesterCourse) {
this.activatedCourse = course;
Expand Down
15 changes: 11 additions & 4 deletions src/containers/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,25 @@
<div class="row new no-gutters">
<div class="col-12 col-md-6 tasks-wrapper">
<div class="row tasks">
<div class="col-1 tasks"><img src="@/assets/images/Task1.svg" alt="checklist" /></div>
<div class="col-1 tasks">
<img src="@/assets/images/Task1.svg" alt="checklist" />
</div>
<div class="col-11">
<p class="sub sub--task">Fully personalized to track your requirements</p>
</div>
</div>
<div class="row tasks">
<div class="col-1 tasks"><img src="@/assets/images/Task2.svg" alt="browser" /></div>
<div class="col-1 tasks">
<img src="@/assets/images/Task2.svg" alt="browser" />
</div>
<div class="col-11">
<p class="sub sub--task">Customizable interface to view your courses</p>
</div>
</div>
<div class="row tasks">
<div class="col-1 tasks"><img src="@/assets/images/Task3.svg" alt="Network" /></div>
<div class="col-1 tasks">
<img src="@/assets/images/Task3.svg" alt="Network" />
</div>
<div class="col-11">
<p class="sub sub--task">Built-in system to check your progress</p>
</div>
Expand Down Expand Up @@ -175,6 +181,7 @@ import firebase from 'firebase/app';
import CustomFooter from '@/components/Footer.vue';
import TopBar from '@/components/TopBar.vue';
import { GTagLoginEvent } from '@/gtag';
import * as fb from '@/firebaseConfig';
const { whitelistCollection, landingEmailsCollection } = fb;
Expand Down Expand Up @@ -232,7 +239,7 @@ export default Vue.extend({
if (doc.exists) {
this.performingRequest = false;
this.$router.push('/');
this.$gtag.event('login', { method: 'Google' });
GTagLoginEvent(this.$gtag, 'Google');
} else {
this.handleUserWithoutAccess();
}
Expand Down
86 changes: 72 additions & 14 deletions src/global-firestore-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
uniqueIncrementerCollection,
} from './firebaseConfig';
import store from './store';
import { GTag, GTagEvent } from './gtag';

// enum to define seasons as integers in season order
export const SeasonsEnum = Object.freeze({
Expand All @@ -19,14 +20,6 @@ export const SeasonsEnum = Object.freeze({
Fall: 3,
});

export const editSemesters = (
updater: (oldSemesters: readonly FirestoreSemester[]) => readonly FirestoreSemester[]
): void => {
const newSemesters = updater(store.state.semesters);
store.commit('setSemesters', newSemesters);
semestersCollection.doc(store.state.currentFirebaseUser.email).set({ semesters: newSemesters });
};

// compare function for FirestoreSemester to determine which comes first by year and type/season
export const compareFirestoreSemesters = (a: FirestoreSemester, b: FirestoreSemester): number => {
if (a.type === b.type && a.year === b.year) {
Expand All @@ -44,21 +37,62 @@ export const compareFirestoreSemesters = (a: FirestoreSemester, b: FirestoreSeme
return -1;
};

export const createSemester = (
courses: readonly FirestoreSemesterCourse[],
export const editSemesters = (
updater: (oldSemesters: readonly FirestoreSemester[]) => readonly FirestoreSemester[]
): void => {
const newSemesters = updater(store.state.semesters);
store.commit('setSemesters', newSemesters);
semestersCollection.doc(store.state.currentFirebaseUser.email).set({ semesters: newSemesters });
};

export const editSemester = (
year: number,
type: FirestoreSemesterType,
updater: (oldSemester: FirestoreSemester) => FirestoreSemester
): void => {
editSemesters(oldSemesters =>
oldSemesters
.map(sem => (sem.year === year && sem.type === type ? updater(sem) : sem))
.sort(compareFirestoreSemesters)
);
};

const createSemester = (
type: FirestoreSemesterType,
year: number
): { courses: readonly FirestoreSemesterCourse[]; type: FirestoreSemesterType; year: number } => ({
year: number,
courses: readonly FirestoreSemesterCourse[]
): { type: FirestoreSemesterType; year: number; courses: readonly FirestoreSemesterCourse[] } => ({
courses,
type,
year,
});

export const addSemester = (
type: FirestoreSemesterType,
year: number,
gtag?: GTag,
courses: readonly FirestoreSemesterCourse[] = []
): void => {
GTagEvent(gtag, 'add-semester');
editSemesters(oldSemesters =>
[...oldSemesters, createSemester(type, year, courses)].sort(compareFirestoreSemesters)
);
};

export const deleteSemester = (type: FirestoreSemesterType, year: number, gtag?: GTag): void => {
GTagEvent(gtag, 'delete-semester');
editSemesters(oldSemesters =>
oldSemesters.filter(semester => semester.type !== type || semester.year !== year)
);
};

export const addCourseToSemester = (
season: FirestoreSemesterType,
year: number,
newCourse: FirestoreSemesterCourse
newCourse: FirestoreSemesterCourse,
gtag?: GTag
): void => {
GTagEvent(gtag, 'add-course');
editSemesters(oldSemesters => {
let semesterFound = false;
const newSemestersWithCourse = oldSemesters.map(sem => {
Expand All @@ -69,12 +103,36 @@ export const addCourseToSemester = (
return sem;
});
if (semesterFound) return newSemestersWithCourse;
return [...oldSemesters, createSemester([newCourse], season, year)].sort(
return [...oldSemesters, createSemester(season, year, [newCourse])].sort(
compareFirestoreSemesters
);
});
};

export const deleteCourseFromSemester = (
season: FirestoreSemesterType,
year: number,
courseUniqueID: number,
gtag?: GTag
): void => {
GTagEvent(gtag, 'delete-course');
editSemesters(oldSemesters => {
let semesterFound = false;
const newSemestersWithoutCourse = oldSemesters.map(sem => {
if (sem.type === season && sem.year === year) {
semesterFound = true;
return {
...sem,
courses: sem.courses.filter(course => course.uniqueID !== courseUniqueID),
};
}
return sem;
});
if (semesterFound) return newSemestersWithoutCourse;
return oldSemesters;
});
};

export const chooseToggleableRequirementOption = (
toggleableRequirementChoices: AppToggleableRequirementChoices
): void => {
Expand Down
Loading

0 comments on commit 0429190

Please sign in to comment.