Skip to content
This repository has been archived by the owner on May 20, 2020. It is now read-only.

Commit

Permalink
wip(app): use proper URL queries and polish setup
Browse files Browse the repository at this point in the history
Closes #263 and helps out with the setup flow for #259.
  • Loading branch information
nicholaschiang committed Mar 30, 2020
1 parent c2bba6d commit ce9d684
Show file tree
Hide file tree
Showing 13 changed files with 369 additions and 162 deletions.
18 changes: 9 additions & 9 deletions build/app/index.js

Large diffs are not rendered by default.

14 changes: 6 additions & 8 deletions build/redirect.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
const subdomain = window.location.hostname.split('.').length > 2;
const splitLocation = window.location.toString().split('/');
if (splitLocation.indexOf('app') >= 0 || subdomain) {
var locationParameter = "/app/?redirect=";
splitLocation.forEach((str) => {
if (splitLocation.indexOf(str) > splitLocation.indexOf('app'))
locationParameter += str + '/';
});
window.location.replace(locationParameter);
const pathnameParts = window.location.pathname.split('/').filter(part => part);
if (pathnameParts.shift() === 'app' || subdomain) {
var newLocation = '/app/?redirect=' + pathnameParts.join('/');
for (const [key, value] of new URLSearchParams(window.location.search))
newLocation += '&' + key + '=' + window.encodeURIComponent(value);
window.location.replace(newLocation);
}
56 changes: 24 additions & 32 deletions src/app/packages/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,42 +326,34 @@ export default class Tutorbook {
/**
* Initializes app variables based on URL parameters.
* @todo Debug security issues b/c anyone can fake any URL parameters.
* @todo Actually use standard URL parameter syntax here (i.e. instead of
* separating pairs with a `?` use an `&`).
* @return {Promise} Promise that resolves once the data has been synced
* with the app and the current user's Firestore profile document.
*/
initURLParams() {
const pairs = window.location.toString().split('?');
return Promise.all(pairs.map(p => p.split('=')).map(([key, val]) => {
switch (key) {
case 'code':
this.user.cards.setupStripe = false;
this.redirectedFromStripe = true; // For payments
this.snackbar.view('Connecting payments account...');
return axios({
method: 'GET',
url: this.functionsURL + 'initStripeAccount',
params: {
code: val.replace('/', ''),
id: firebase.auth().currentUser.uid,
test: this.test,
},
}).then((res) => {
this.snackbar.view(
'Connected payments account.', 'View', () => {
window.open(res.data.url); // Opens dashboard
});
}).catch((err) => {
console.error('[ERROR] While initializing Stripe ' +
'account:', err);
this.snackbar.view('Could not connect payments ' +
'account.', 'Retry', () => {
window.location = this.payments.setupURL;
});
});
async initURLParams() {
for (const [key, val] of new URLSearchParams(window.location.search)) {
if (key !== 'code') continue;
this.user.cards.setupStripe = false;
this.redirectedFromStripe = true; // For payments
this.snackbar.view('Connecting payments account...');
const [err, res] = await to(axios({
method: 'GET',
url: this.functionsURL + 'initStripeAccount',
params: {
code: val.replace('/', ''),
id: firebase.auth().currentUser.uid,
test: this.test,
},
}));
if (err) {
console.error('[ERROR] While init-ing Stripe:', err);
this.snackbar.view('Could not connect payments ' +
'account.', 'Retry',
() => window.location = this.payments.setupURL);
} else {
this.snackbar.view('Connected payments account.',
'View', () => window.open(res.data.url));
}
}));
}
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/app/packages/app/styles/welcome.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
font-family: 'Poppins', sans-serif;
font-weight: 600;
font-size: 4.5rem;
margin-bottom: 0;
margin-top: 24px;
color: #181818;
span {
color: #6200EE;
Expand All @@ -22,7 +22,7 @@
font-size: 0.85rem;
letter-spacing: 0;
color: #181818;
margin-bottom: 10px;
margin-bottom: 0;
}

.mdc-fab {
Expand Down
51 changes: 49 additions & 2 deletions src/app/packages/data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,19 @@ export default class Data {
}
}

/**
* Returns the Firestore document or collection reference given a reference
* path in the form of an array.
* @param {string[]} path - The path through the Firestore database to the
* desired resource.
* @param {external:CollectionReference} [ref=window.app.db] - The origin of
* the path.
* @return {(external:CollectionReference|external:DocumentReference)} The
* Firestore resource that the `path` leads us to from the origin (`ref`).
*/
static ref(path, ref = window.app.db) {
for (var i = 0; i < path.length; i++) {
for (var i = 0; i < path.length; i++)
ref = i % 2 === 0 ? ref.collection(path[i]) : ref.doc(path[i]);
}
return ref;
}

Expand Down Expand Up @@ -476,6 +485,44 @@ export default class Data {
throw new Error('User (' + id + ') did not exist.');
}

/**
* Creates a new website configuration using our data REST API.
* @param {Website} website - The website to create.
* @return {Promise} Promise that resolves with the `res.data` once the
* website has been created.
*/
static createWebsite(website) {
return Data.post('createWebsite', {
website: website,
});
}

/**
* Updates a new website configuration using our data REST API.
* @param {Website} website - The website to update.
* @param {string} id - The ID of the website's Firestore document.
* @return {Promise} Promise that resolves with the `res.data` once the
* website has been updated.
*/
static updateWebsite(website, id) {
return Data.post('updateWebsite', {
website: website,
id: id,
});
}

/**
* Deletes a new website configuration using our data REST API.
* @param {string} id - The ID of the website's Firestore document.
* @return {Promise} Promise that resolves with the `res.data` once the
* website has been deleted.
*/
static deleteWebsite(id) {
return Data.post('deleteWebsite', {
id: id,
});
}

static deleteLocation(id) {
return Data.post('deleteLocation', {
id: id,
Expand Down
73 changes: 37 additions & 36 deletions src/app/packages/login/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,51 +99,52 @@ export class Login {
$(this.main).find('#first-login-prompt').show();
},
pupil: () => {
// Show setup cards in the dashboard for:
// 1) Their profile (i.e. subjects, availability, locations)
// 2) Linking Google Calendar or iCal to their account
// 3) Setting up their first payment method
// We want them to set availability so that tutors can edit
// their requests as needed.
Utils.url('/app/home?cards=searchTutors+setupNotifications+' +
'setupAvailability?auth=true?type=Pupil');
/**
* Show setup cards in the dashboard for:
* 1) Their profile (i.e. subjects, availability, locations)
* 2) Linking Google Calendar or iCal to their account
* 3) Setting up their first payment method
* We want them to set availability so that tutors can edit
* their requests as needed.
*/
Utils.url('/app/home?cards=' + window.encodeURIComponent([
'searchTutors',
'setupNotifications',
'setupAvailability',
]) + '&auth=true&type=Pupil');
Login.viewGoogleSignIn();
},
paidTutor: () => {
Utils.url('/app/home?cards=setupProfile+setupNotifications?' +
'payments=true?auth=true?type=Tutor');
Utils.url('/app/home?cards=' + window.encodeURIComponent([
'setupProfile',
'setupNotifications',
]) + '&payments=true&auth=true&type=Tutor');
Login.viewGoogleSignIn();
},
tutor: () => {
// Show setup cards in the dashboard for:
// 1) Their profile (i.e. subjects, availability, locations)
// 2) Linking Google Calendar or iCal to their account
// 3) Setting up their first deposit/payment method
Utils.url('/app/home?cards=setupProfile+setupNotifications?' +
'auth=true?type=Tutor');
Login.viewGoogleSignIn();
},
parent: () => {
// Show setup cards in the dashboard for:
// 1) Creating children accounts
// 2) Searching for a tutor
// 3) Enabling notifications (i.e. adding phone #, etc.)
Utils.url('/app/home?cards=searchTutors+setupNotifications+' +
'setupAvailability?auth=true?type=Parent');
Login.viewGoogleSignIn();
/* TODO: Right now, we just show the pupil cards.
*Utils.url('/app/home?cards=searchTutors+addChildren+setupNotifications?auth=true?type=Parent');
*Login.viewGoogleSignIn();
/**
* Show setup cards in the dashboard for:
* 1) Their profile (i.e. subjects, availability, locations)
* 2) Linking Google Calendar or iCal to their account
* 3) Setting up their first deposit/payment method
*/
Utils.url('/app/home?cards=' + window.encodeURIComponent([
'setupProfile',
'setupNotifications',
]) + '&auth=true&type=Tutor');
Login.viewGoogleSignIn();
},
supervisor: () => {
// Show setup cards in the dashboard for:
// 1) Their profile (i.e. subjects, availability, locations)
// 2) Linking Google Calendar or iCal to their account
// 3) Setting up their first location or applying to be a supervisor
// for an existing location
Utils.url('/app/home?cards=setupNotifications?auth=false?' +
'type=Supervisor');
/**
* Show setup cards in the dashboard for:
* 1) Their profile (i.e. subjects, availability, locations)
* 2) Linking Google Calendar or iCal to their account
* 3) Setting up their first location or applying to be a
* supervisor for an existing location
*/
Utils.url('/app/home?cards=' + window.encodeURIComponent([
'setupNotifications',
]) + '&auth=false&type=Supervisor');
Login.viewGoogleSignIn();
},
});
Expand Down
5 changes: 2 additions & 3 deletions src/app/packages/navigation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,9 @@ export default class Navigation {
if (window.location.toString().indexOf('redirect') < 0)
return this.router.navigate('/app/home');
// b) Redirect user to desired destination
const pairs = window.location.toString().split('?');
pairs.map(p => p.split('=')).map(([key, val]) => {
for (const [key, val] of new URLSearchParams(window.location.search)) {
if (key === 'redirect') this.router.navigate('/app/' + val);
});
}
}

initDrawer() {
Expand Down
Loading

0 comments on commit ce9d684

Please sign in to comment.