Skip to content
This repository was archived by the owner on Jun 30, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a77318f
Beging work hacking patient registration.
schlagercollin Feb 19, 2021
cceb08d
Add user registration.
schlagercollin Feb 28, 2021
5ca4bf2
Add medication.
schlagercollin Feb 28, 2021
3dd0f80
Added iOS dynamic link.
schlagercollin Mar 2, 2021
a9b6470
Update user card style.
schlagercollin Mar 2, 2021
993563d
Add simple provider check to sign in.
schlagercollin Mar 2, 2021
7eccc22
Update README.md
cswingle98 Mar 3, 2021
a5c5366
updating firestore
cswingle98 Mar 4, 2021
c6bc7e5
asdferge branch 'master' of https://github.com/schlagercollin/Cardina…
cswingle98 Mar 4, 2021
f676b50
Reconfigure provider check based on new firebase forma.
schlagercollin Mar 4, 2021
51cd6a7
Update user detail card.
schlagercollin Mar 4, 2021
4575db5
Add surveys and last active.
schlagercollin Mar 4, 2021
d3985d3
Temporarily remove lastActive from summary card.
schlagercollin Mar 4, 2021
d8e34ed
Re-add lastActive in summary.
schlagercollin Mar 4, 2021
2535d36
Minor formatting.
schlagercollin Mar 4, 2021
50514e0
Add registration time and UI improvements.
schlagercollin Mar 4, 2021
0c54531
Add remove user base functionality.
schlagercollin Mar 4, 2021
b450b04
Change login button text
schlagercollin Mar 4, 2021
99c64e5
Add resend email link button.
schlagercollin Mar 14, 2021
58368f8
Clean formatting
schlagercollin Mar 14, 2021
f609761
Progress toward medication functionality for provider portal.
schlagercollin Mar 14, 2021
3fc1f36
Added medication view.
schlagercollin Mar 15, 2021
1f75886
Add styling
schlagercollin Mar 15, 2021
2856990
Styling
schlagercollin Mar 15, 2021
553fed5
Fix register patient bug
schlagercollin Mar 15, 2021
4e750ab
Fix bug when medications is represented by empty string
schlagercollin Mar 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ Run `npm install`

Run `npm start`

## Installation Debugging

If `npm install` fails with errors about pre-gyp, trying the following.

1. Remove partially installed node modeules `rm -rf node_modules`
2. Install pre-gyp first `npm install -g node-pre-gyp`
3. Install other modules `npm install --no-bin-links`

<img src="https://github.com/cs342/CardinalKit-CS342-Web/blob/master/Materials/footer.png?raw=true" alt="biodesign logo">
Finally, we should be able to use `npm start` to host locally.



<img src="https://github.com/cs342/CardinalKit-CS342-Web/blob/master/Materials/footer.png?raw=true" alt="biodesign logo">
10 changes: 10 additions & 0 deletions ReactJS-Project-CardinalKit/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions ReactJS-Project-CardinalKit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
"history": "^4.7.2",
"js-yaml": "^3.13.1",
"lodash": "^4.17.13",
"lodash.isequal": "^4.5.0",
"lodash.template": "^4.5.0",
"mixin-deep": "^1.3.2",
"prop-types": "^15.6.2",
"react": "^16.10.2",
"react-day-picker": "^7.2.4",
"react-dom": "^16.10.2",
"react-feather": "^1.1.4",
"react-icons": "^4.2.0",
"react-intl": "3.2.1",
"react-redux": "^7.1.1",
"react-router": "5.1.2",
Expand Down
16 changes: 14 additions & 2 deletions ReactJS-Project-CardinalKit/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { isAuthenticated } from './selectors/loginSelectors';
import Header from './components/Header';
import LoginPage from './components/LoginPage';
import NotFoundPage from './components/NotFoundPage';
import UsersPage from './components/UsersPage';
import RegisterPage from './components/RegisterPage';
import MedicationPage from './components/MedicationPage'
import UserPage from './components/UserPage';
import UsersPage from './components/UsersPage';

interface AppProps {
isAuth: boolean;
Expand All @@ -27,7 +29,17 @@ class App extends React.Component<AppProps> {
<Switch>
<Route exact={true} path="/login" component={LoginPage} />
<PrivateRoute exact={true} path="/users" component={UsersPage} />
<PrivateRoute exact={true} path="/user/:userID" component={(props:any) => <UserPage {...props} />} />
<PrivateRoute
exact={true}
path="/user/:userID"
component={(props: any) => <UserPage {...props} />}
/>
<PrivateRoute exact={true} path="/register" component={RegisterPage} />
<PrivateRoute
exact={true}
path="/user/:userID/medication"
component={(props: any) => <MedicationPage {...props} />}
/>
<Redirect exact={true} from="/" to="/users" />
<Route component={NotFoundPage} />
</Switch>
Expand Down
24 changes: 24 additions & 0 deletions ReactJS-Project-CardinalKit/src/api/admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import app from 'firebase/app';
import Firebase from '../components/Firebase';

// checks
export function isAdmin(userEmail: string): Promise<boolean> {
const firebase = new Firebase();
const adminBool = firebase.db
.collection('providers')
.get()
.then(function(querySnapshot) {
let result = false;
querySnapshot.forEach(function(doc) {
if (doc.id == userEmail && doc.data().admin) {
result = true;
}
});
return result;
})
.catch(function(error) {
console.log('Error getting document:', error);
return false;
});
return adminBool;
}
127 changes: 114 additions & 13 deletions ReactJS-Project-CardinalKit/src/api/getAllUsers.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,137 @@
import Firebase from '../components/Firebase';
import app from 'firebase/app';
import Firebase from '../components/Firebase';

export function getAllFirebaseUsers(): Promise<app.firestore.QuerySnapshot> {
const firebase = new Firebase();
return firebase.users().get().then(function(doc) {
return firebase
.users()
.get()
.then(function(doc) {
return doc;
}).catch(function(error) {
console.log("Error getting document:", error);
})
.catch(function(error) {
console.log('Error getting document:', error);
return error;
});
}

export function updateUserList(userList: any): Promise<any[]> {
const out = userList.map((user: any) => {
return getHeartbeatInfo(user.email).then(heartbeatInfo => {
const heartbeatInfoData = heartbeatInfo.data();
if (heartbeatInfoData) {
const lastActive = heartbeatInfoData.lastActive;
user.lastActive = lastActive;
return user;
}
return user;
});
});

// we need to make this function return a promise (not an array of promises)
// so, we construct a Promise.all around it
return Promise.all(out);
}

export function getFirebaseUser(uid: String): Promise<app.firestore.QuerySnapshot> {
export function getFirebaseUser(email: String): Promise<app.firestore.QuerySnapshot> {
const firebase = new Firebase();
return firebase.user(uid).get().then(function(doc) {
return firebase
.user(email)
.get()
.then(function(doc) {
return doc;
}).catch(function(error) {
console.log("Error getting document:", error);
})
.catch(function(error) {
console.log('Error getting document:', error);
return error;
});
});
}

export function getSurveys(uid: String): Promise<app.firestore.QuerySnapshot> {
export function getHeartbeatInfo(uid: String): Promise<app.firestore.DocumentSnapshot> {
const firebase = new Firebase();
return firebase.surveys(uid).get().then(function(doc) {
return firebase
.user(uid)
.collection('studies')
.doc('heartbeat')
.get()
.then(function(doc) {
return doc;
}).catch(function(error) {
console.log("Error getting document:", error);
})
.catch(function(error) {
console.log('Error getting document:', error);
return error;
});
}

export function getUserFromUID(uid: string): Promise<app.firestore.QueryDocumentSnapshot> {
const firebase = new Firebase();
return firebase.db
.collection('registered-patients')
.where('userID', '==', uid)
.get()
.then(querySnapshot => {
// return the first since it should be unique
return querySnapshot.docs[0];
})
.catch(function(error) {
console.log('Error getting document:', error);
return error;
});
}

// export function getMedicationsFromUID(uid: String): Promise<app.firestore.QuerySnapshot>{
// const firebase = new Firebase();
// return getUserFromUID(uid).then((userDoc) => {
// return userDoc.ref.collection('medications').get().then((querySnapshot) => {
// console.log(querySnapshot);
// return querySnapshot;
// })
// });
// }

export function saveNewMedications(userEmail: string, newMedications: any) {
const firebase = new Firebase();
firebase.db
.collection('registered-patients')
.doc(userEmail)
.update({
medications: newMedications,
})
.then(() => {
alert('Medications saved.');
})
.catch(error => {
// The document probably doesn't exist.
alert('ERROR: Medications were not saved. ' + error);
});
}

export function deleteFirebaseUser(userID: string) {
getUserFromUID(userID).then(docSnapshot => {
docSnapshot.ref
.delete()
.then(() => {
console.log('Document successfully deleted!');
})
.catch((error: any) => {
console.error('Error removing document: ', error);
});
});
}

export function getSurveys(email: String, uid: String): Promise<app.firestore.QuerySnapshot> {
const firebase = new Firebase();
return firebase
.surveys(email, uid)
.get()
.then(function(doc) {
return doc;
})
.catch(function(error) {
console.log('Error getting document:', error);
return error;
});
}

/*
import { UserDetails } from './user';
Expand Down
53 changes: 53 additions & 0 deletions ReactJS-Project-CardinalKit/src/api/registerUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import app from 'firebase/app';
import Firebase from '../components/Firebase';

export function sendSignInEmail(email: string) {
const firebase = new Firebase();

const actionCodeSettings = {
// include email in link so it can be passed to iOS
url: 'https://cs342-alpha-9bb64.web.app/?email=' + email,
handleCodeInApp: true,
iOS: {
bundleId: 'https://cs342-alpha-9bb64.web.app',
},
dynamicLinkDomain: 'cs342alpha.page.link',
};

firebase.auth
.sendSignInLinkToEmail(email, actionCodeSettings)
.then(() => {
// The link was successfully sent. Inform the user.
// Save the email locally so you don't need to ask the user for it again
// if they open the link on the same device.
console.log('email sent!');
window.localStorage.setItem('emailForSignIn', email);
})
.catch(error => {
const errorCode = error.code;
const errorMessage = error.message;
console.log('email failed!', errorCode, errorMessage);
});
}

export function registerNewUser(user: any): Promise<app.firestore.QuerySnapshot> {
const firebase = new Firebase();
console.log('Registering a new user!');
const userRef = firebase.db
.collection(`registered-patients`)
.doc(user.email)
.set(user)
.then((docRef: any) => {
console.log('Document written to: ', user.email);
return docRef;
})
.catch((error: any) => {
console.error('Error adding document: ', error);
return error;
});

// send an email to the patient with the sign-in link
sendSignInEmail(user.email);

return userRef;
}
6 changes: 5 additions & 1 deletion ReactJS-Project-CardinalKit/src/api/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ export interface UserDetails {
eID: string;
userID: string;
email: string;
firstName: string;
lastName: string;
createdAt?: Date;
surveyList?: Survey[];
lastActive: Date;
lastActive: number;
registrationDate: number;
medications: string;
}
36 changes: 25 additions & 11 deletions ReactJS-Project-CardinalKit/src/components/Firebase/firebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,26 @@ import 'firebase/auth';
import 'firebase/firestore';

const config = {
apiKey: process.env.REACT_APP_API_KEY || 'AIzaSyCVzML6v4C16HNjUZN_xnEX5RWJmDq3YUU',
authDomain: process.env.REACT_APP_AUTH_DOMAIN || 'cs342-master-sample.firebaseapp.com',
databaseURL: process.env.REACT_APP_DATABASE_URL || 'https://cs342-master-sample.firebaseio.com',
projectId: process.env.REACT_APP_PROJECT_ID || 'cs342-master-sample',
storageBucket: process.env.REACT_APP_STORAGE_BUCKET || 'cs342-master-sample.appspot.com',
messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID || '267563013930',
appId: process.env.REACT_APP_ID || '1:267563013930:web:99eeeff653b0f07accb053',
iOSAppBundleId: process.env.IOS_APP_ID || 'edu.stanford.cardinalkit', // as setup on your iOS project
apiKey: 'AIzaSyBYlt95-E4qI7yOdkChGIdq1tkjVC6I68U',
authDomain: 'cs342-alpha-9bb64.firebaseapp.com',
projectId: 'cs342-alpha-9bb64',
storageBucket: 'cs342-alpha-9bb64.appspot.com',
messagingSenderId: '47235957743',
appId: '1:47235957743:web:30ad97b3d66cfb239f2c1a',
iOSAppBundleId: 'edu.stanford.cs342-alpha-cardiology',
};

// const config = {
// apiKey: process.env.REACT_APP_API_KEY || 'AIzaSyCVzML6v4C16HNjUZN_xnEX5RWJmDq3YUU',
// authDomain: process.env.REACT_APP_AUTH_DOMAIN || 'cs342-master-sample.firebaseapp.com',
// databaseURL: process.env.REACT_APP_DATABASE_URL || 'https://cs342-master-sample.firebaseio.com',
// projectId: process.env.REACT_APP_PROJECT_ID || 'cs342-master-sample',
// storageBucket: process.env.REACT_APP_STORAGE_BUCKET || 'cs342-master-sample.appspot.com',
// messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID || '267563013930',
// appId: process.env.REACT_APP_ID || '1:267563013930:web:99eeeff653b0f07accb053',
// iOSAppBundleId: process.env.IOS_APP_ID || 'edu.stanford.cardinalkit', // as setup on your iOS project
// };

class Firebase {
constructor() {
if (!app.apps.length) {
Expand Down Expand Up @@ -94,13 +104,17 @@ class Firebase {

// *** User API ***

user = uid => this.db.collection(`studies/${config.iOSAppBundleId}/users`).doc(`${uid}`);
// user = uid => this.db.collection(`studies/${config.iOSAppBundleId}/users`).doc(`${uid}`);

// users = () => this.db.collection(`studies/${config.iOSAppBundleId}/users/`);

user = uid => this.db.collection(`registered-patients`).doc(`${uid}`);

users = () => this.db.collection(`studies/${config.iOSAppBundleId}/users/`);
users = () => this.db.collection(`registered-patients`);

// *** Surveys API ***

surveys = uid => this.db.collection(`studies/${config.iOSAppBundleId}/users/${uid}/surveys/`);
surveys = (email, uid) => this.db.collection(`registered-patients/${email}/studies/${uid}/surveys`);
}

export default Firebase;
Loading