Skip to content

Commit

Permalink
add tour (#930)
Browse files Browse the repository at this point in the history
  • Loading branch information
andxu282 committed May 2, 2024
1 parent 5e8d334 commit b929b5e
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 12 deletions.
6 changes: 6 additions & 0 deletions cypress/integration/accessibility-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ it('Check navbar accessibility', () => {
cy.checkA11y('[data-cyId=navbar]', null, null, true); // only check accessibility within the navbar
});

// Test to confirm that the new user walkthrough works as expected
// Click through the initial explanation, then the 4 following steps, and finally the finishing page
it('Click through schedule generator tour', () => {
cy.get('.introjs-nextbutton').click();
});

// Check the accessibility of the requirements sidebar with all toggles fully open
// Note that the selector in checkA11y ensures only the sidebar is inspected
it('Check accessibility of the requirements sidebar', () => {
Expand Down
18 changes: 13 additions & 5 deletions scripts/migration/new-feature-migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,32 @@
import { usernameCollection, onboardingDataCollection } from '../firebase-config';

/**
* Perform migration of semester to plans with a list of semesters
* Perform migration of user data to add sawNewFeature boolean
* TODO: update sawNewFeature to sawMultiplePlans
*/
async function runOnUser(userEmail: string) {
await onboardingDataCollection.doc(userEmail).update({ sawNewFeature: false });
// async function addSawMultiplePlans(userEmail: string) {
// await onboardingDataCollection.doc(userEmail).update({ sawNewFeature: false });
// }

/**
* Perform migration of user data to add sawScheduleGenerator boolean
*/
async function addSawScheduleGenerator(userEmail: string) {
await onboardingDataCollection.doc(userEmail).update({ sawScheduleGenerator: false });
}

async function main() {
const userEmail = process.argv[2];
if (userEmail != null) {
await runOnUser(userEmail);
await addSawScheduleGenerator(userEmail);
return;
}
const collection = await usernameCollection.get();
for (const { id } of collection.docs) {
console.group(`Running on ${id}...`);
// Intentionally await in a loop to have no interleaved console logs.
// eslint-disable-next-line no-await-in-loop
await runOnUser(id);
await addSawScheduleGenerator(id);
console.groupEnd();
}
}
Expand Down
27 changes: 25 additions & 2 deletions src/components/NavBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
</div>
<div class="navbar-buttonWrapper desktop">
<button
id="schedule-generator"
class="navbar-iconWrapper schedule-builder-icon full-opacity-on-hover"
@click="openScheduleGenerate"
/>
Expand Down Expand Up @@ -70,9 +71,9 @@
<div class="navbar-iconWrapper profile-mobile-icon" />
<span class="nav-mobile-button-text">Profile</span>
</button>
<button class="nav-mobile-button" @click="openProfile">
<button class="nav-mobile-button" @click="openScheduleGenerate">
<div class="navbar-iconWrapper schedule-builder-mobile-icon" />
<span class="nav-mobile-button-text">Builder</span>
<span class="nav-mobile-button-text">Build</span>
</button>
<button class="nav-mobile-button" @click="logout">
<div class="navbar-iconWrapper logout-mobile-icon" />
Expand All @@ -95,12 +96,15 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { getAuth, signOut } from 'firebase/auth';
import introJs from 'intro.js';
import { GTagEvent } from '@/gtag';
import { clickOutside } from '@/utilities';
import { updateSawScheduleGenerator } from '@/global-firestore-data/user-onboarding-data';
export default defineComponent({
props: {
isDisplayingRequirementsMobile: { type: Boolean, required: true },
startScheduleGeneratorTour: { type: Boolean, required: true },
},
emits: [
'openPlan',
Expand All @@ -114,6 +118,25 @@ export default defineComponent({
menuOpen: false,
};
},
watch: {
startScheduleGeneratorTour() {
const scheduleGeneratorTour = introJs();
scheduleGeneratorTour.setOptions({
steps: [
{
element: '#schedule-generator',
intro: `<div class="introjs-tooltipTop"><div class="introjs-customTitle">Introducing a New Page</div></div>
<div class = "introjs-bodytext">Use Build 💪 to automatically generate new schedules based on the courses you want to take! 📆</div>`,
position: 'right',
},
],
doneLabel: 'Got it',
});
// check firestore if the user has seen it already
scheduleGeneratorTour.start();
updateSawScheduleGenerator(true);
},
},
methods: {
logout() {
GTagEvent(this.$gtag, 'logout');
Expand Down
4 changes: 2 additions & 2 deletions src/components/Requirements/RequirementSideBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ export default defineComponent({
isDisplayingMobile: { type: Boolean, required: true },
isMobile: { type: Boolean, required: true },
isMinimized: { type: Boolean, required: true },
startNewFeatureTour: { type: Boolean, required: true },
startMultiplePlansTour: { type: Boolean, required: true },
},
emits: ['showTourEndWindow', 'toggleMinimized'],
data(): Data {
Expand Down Expand Up @@ -288,7 +288,7 @@ export default defineComponent({
this.tourStep = 0;
});
},
startNewFeatureTour() {
startMultiplePlansTour() {
const newFeatureTour = introJs();
newFeatureTour.setOptions({
steps: [
Expand Down
10 changes: 7 additions & 3 deletions src/containers/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
class="dashboard-nav"
data-cyId="navbar"
:isDisplayingRequirementsMobile="requirementsIsDisplayedMobile"
:startScheduleGeneratorTour="startScheduleGeneratorTour"
@openPlan="openPlan"
@openTools="openTools"
@openProfile="openProfile"
Expand All @@ -41,7 +42,7 @@
@toggleMinimized="toggleMinimizeRequirements"
:startTour="startTour"
@showTourEndWindow="showTourEnd"
:startNewFeatureTour="startNewFeatureTour"
:startMultiplePlansTour="startMultiplePlansTour"
/>
<schedule-generate-side-bar
v-if="loaded && !showToolsPage && !isProfileOpen && isScheduleGenerateOpen"
Expand Down Expand Up @@ -180,7 +181,8 @@ export default defineComponent({
maxBottomBarTabs: getMaxButtonBarTabs(),
welcomeHidden: false,
startTour: false,
startNewFeatureTour: false,
startMultiplePlansTour: false,
startScheduleGeneratorTour: false,
showTourEndWindow: false,
showToolsPage: false,
isProfileOpen: false,
Expand Down Expand Up @@ -224,7 +226,9 @@ export default defineComponent({
if (this.onboardingData.college !== '' || this.onboardingData.grad !== '') {
this.loaded = true;
if (!this.onboardingData.sawNewFeature) {
this.startNewFeatureTour = true;
this.startMultiplePlansTour = true;
} else if (!this.onboardingData.sawScheduleGenerator) {
this.startScheduleGeneratorTour = true;
}
} else {
this.startOnboarding();
Expand Down
8 changes: 8 additions & 0 deletions src/global-firestore-data/user-onboarding-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const setAppOnboardingData = (
})),
tookSwim: onboarding.tookSwim,
sawNewFeature: onboarding.sawNewFeature,
sawScheduleGenerator: onboarding.sawScheduleGenerator,
});
};

Expand Down Expand Up @@ -59,3 +60,10 @@ export const updateSawNewFeature = (sawNewFeature: boolean): void => {
sawNewFeature,
});
};

export const updateSawScheduleGenerator = (sawScheduleGenerator: boolean): void => {
store.commit('setSawScheduleGenerator', sawScheduleGenerator);
updateDoc(doc(onboardingDataCollection, store.state.currentFirebaseUser.email), {
sawScheduleGenerator,
});
};
1 change: 1 addition & 0 deletions src/requirements/__test__/exam-credit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ it('Exam is converted to correct course', () => {
minor: [],
tookSwim: 'no',
sawNewFeature: false,
sawScheduleGenerator: false,
};
const examCourses = userDataToExamCourses(userData);
const expected = {
Expand Down
4 changes: 4 additions & 0 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const store: TypedVuexStore = new TypedVuexStore({
exam: [],
tookSwim: 'no',
sawNewFeature: false,
sawScheduleGenerator: false,
},
orderByNewest: true,
derivedCoursesData: {
Expand Down Expand Up @@ -186,6 +187,9 @@ const store: TypedVuexStore = new TypedVuexStore({
setSawNewFeature(state: VuexStoreState, seen: boolean) {
state.onboardingData.sawNewFeature = seen;
},
setSawScheduleGenerator(state: VuexStoreState, seen: boolean) {
state.onboardingData.sawScheduleGenerator = seen;
},
},
});

Expand Down
1 change: 1 addition & 0 deletions src/user-data-converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,5 @@ export const createAppOnboardingData = (data: FirestoreOnboardingUserData): AppO
: [],
tookSwim: 'tookSwim' in data ? data.tookSwim : 'no',
sawNewFeature: data.sawNewFeature,
sawScheduleGenerator: data.sawScheduleGenerator,
});
2 changes: 2 additions & 0 deletions src/user-data.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type FirestoreOnboardingUserData = {
readonly exam: readonly FirestoreTransferExam[];
readonly tookSwim: 'yes' | 'no';
sawNewFeature: boolean;
sawScheduleGenerator: boolean;
};

type FirestoreCourseOptInOptOutChoices = {
Expand Down Expand Up @@ -191,6 +192,7 @@ type AppOnboardingData = {
readonly exam: readonly FirestoreTransferExam[];
readonly tookSwim: 'yes' | 'no';
sawNewFeature: boolean;
sawScheduleGenerator: boolean;
};

type AppBottomBarCourse = {
Expand Down

0 comments on commit b929b5e

Please sign in to comment.