├── src ├── pages │ ├── requests │ │ ├── requests.scss │ │ ├── requests.ts │ │ └── requests.html │ ├── tutorsubjects │ │ ├── tutorsubjects.scss │ │ ├── tutorsubjects.ts │ │ └── tutorsubjects.html │ ├── tutorclassmenu │ │ ├── tutorclassmenu.scss │ │ ├── tutorclassmenu.ts │ │ └── tutorclassmenu.html │ ├── classroom │ │ ├── classroom.scss │ │ ├── classroom.html │ │ └── classroom.ts │ ├── classmenu │ │ ├── classmenu.scss │ │ ├── classmenu.ts │ │ └── classmenu.html │ ├── createclass │ │ ├── createclass.scss │ │ ├── createclass.ts │ │ └── createclass.html │ ├── userselection │ │ ├── userselection.scss │ │ ├── userselection.html │ │ └── userselection.ts │ ├── videocall │ │ ├── videocall.scss │ │ └── videocall.html │ ├── myclasses │ │ ├── myclasses.scss │ │ ├── myclasses.ts │ │ └── myclasses.html │ ├── tutorsettings │ │ ├── tutorsettings.scss │ │ ├── tutorsettings.ts │ │ └── tutorsettings.html │ ├── tutorclasses │ │ ├── tutorclasses.scss │ │ └── tutorclasses.ts │ ├── settings │ │ ├── settings.scss │ │ ├── settings.ts │ │ └── settings.html │ ├── signup │ │ ├── signup.scss │ │ ├── signup.ts │ │ └── signup.html │ ├── wallet │ │ ├── wallet.scss │ │ ├── wallet.ts │ │ └── wallet.html │ ├── profile │ │ ├── profile.scss │ │ ├── profile.ts │ │ └── profile.html │ ├── tutorschedule │ │ ├── tutorschedule.scss │ │ ├── tutorschedule.html │ │ └── tutorschedule.ts │ ├── classbrowse │ │ ├── classbrowse.scss │ │ ├── classbrowse.ts │ │ └── classbrowse.html │ ├── parentregister │ │ ├── parentregister.scss │ │ ├── parentregister.ts │ │ └── parentregister.html │ ├── lesson │ │ ├── lesson.scss │ │ ├── lesson.html │ │ └── lesson.ts │ ├── logout │ │ ├── logout.html │ │ ├── logout.scss │ │ ├── logout.ts │ │ └── logout.spec.ts │ ├── appointments │ │ ├── appointments.scss │ │ ├── appointments.ts │ │ └── appointments.html │ ├── tutors │ │ ├── tutors.scss │ │ ├── tutors.ts │ │ └── tutors.html │ ├── tutorhome │ │ ├── tutorhome.scss │ │ ├── tutorhome.html │ │ └── tutorhome.ts │ ├── login │ │ ├── login.spec.ts │ │ ├── login.html │ │ ├── login.ts │ │ └── login.scss │ ├── tutorregister │ │ └── tutorregister.scss │ ├── draw │ │ ├── draw.scss │ │ └── draw.html │ ├── tutorprofile │ │ ├── tutorprofile.scss │ │ └── tutorprofile.html │ ├── home │ │ ├── home.scss │ │ ├── home.ts │ │ └── home.html │ ├── register │ │ └── register.scss │ └── messages │ │ ├── messages.html │ │ └── messages.scss ├── app │ ├── man.png │ ├── albert.jpg │ ├── typings.d.ts │ ├── main.ts │ ├── services │ │ ├── subjects │ │ │ └── subjects.ts │ │ ├── appointment-data │ │ │ └── appointment-data.ts │ │ ├── institutions │ │ │ └── institutions.ts │ │ ├── tutor-data │ │ │ └── tutor.data.ts │ │ └── users │ │ │ └── allusers.ts │ ├── common │ │ └── webrtc.config.ts │ └── app.scss ├── assets │ ├── tone.mp3 │ ├── img │ │ ├── man.png │ │ ├── flask.png │ │ ├── girl.png │ │ ├── gmail.png │ │ ├── gozer.png │ │ ├── isaac.jpg │ │ ├── tully.jpg │ │ ├── zuul.png │ │ ├── ghost-1.png │ │ ├── ghost-3.png │ │ ├── img-icon.png │ │ ├── nin-live.png │ │ ├── slide-01.png │ │ ├── slide-02.png │ │ ├── slide-03.png │ │ ├── slimer.jpg │ │ ├── spengler.jpg │ │ ├── stantz.jpg │ │ ├── venkman.jpg │ │ ├── winston.jpg │ │ ├── enlighten.png │ │ ├── ian-avatar.png │ │ ├── login-logo.png │ │ ├── queen-live.png │ │ ├── enlighten-red.png │ │ ├── google-full.png │ │ ├── ios-statusbar.png │ │ ├── marty-avatar.png │ │ ├── paypartners.png │ │ ├── rundmc-live.png │ │ ├── thumbnail-esb.png │ │ ├── wp-statusbar.png │ │ ├── card-wireframe.png │ │ ├── ghost-buster-1.png │ │ ├── ghost-buster-2.png │ │ ├── ghost-buster-3.png │ │ ├── ghost-buster-4.png │ │ ├── ghost-buster-5.png │ │ ├── marshmallow-man.png │ │ ├── thumbnail-bttf.png │ │ ├── thumbnail-rotla.png │ │ ├── footer-wireframe.png │ │ ├── ica-slidebox-img-1.png │ │ ├── ica-slidebox-img-2.png │ │ ├── ica-slidebox-img-3.png │ │ ├── ica-slidebox-img-4.png │ │ ├── sarah-avatar.png.jpeg │ │ ├── thumbnail-batman.png │ │ ├── thumbnail-kitten-1.jpg │ │ ├── thumbnail-kitten-2.jpg │ │ ├── thumbnail-kitten-3.jpg │ │ ├── thumbnail-kitten-4.jpg │ │ ├── thumbnail-puppy-1.jpg │ │ ├── thumbnail-puppy-2.jpg │ │ ├── thumbnail-puppy-3.jpg │ │ ├── thumbnail-puppy-4.jpg │ │ ├── thumbnail-totoro.png │ │ ├── thumbnail-duckling-1.jpg │ │ ├── thumbnail-duckling-2.jpg │ │ ├── thumbnail-duckling-3.jpg │ │ ├── thumbnail-duckling-4.jpg │ │ ├── thumbnail-terminator.png │ │ └── thumbnail-ghostbusters.png │ └── icon │ │ └── favicon.ico ├── data │ └── tutors.json ├── firebase-messaging-sw.js ├── manifest.json ├── pipes │ └── tolocal │ │ └── tolocal.ts ├── providers │ ├── scheduling │ │ └── scheduling.ts │ └── lessons │ │ └── lessons.ts ├── service-worker.js ├── components │ ├── canvas-draw │ │ ├── canvas-draw.scss │ │ └── canvas-draw.html │ └── calendar │ │ ├── calendar.html │ │ └── calendar.scss ├── index.html └── theme │ └── variables.scss ├── .DS_Store ├── testing ├── provider-mocks.js └── page-mocks.js ├── resources ├── icon.png ├── splash.png ├── ios │ ├── icon │ │ ├── icon.png │ │ ├── icon-40.png │ │ ├── icon-50.png │ │ ├── icon-60.png │ │ ├── icon-72.png │ │ ├── icon-76.png │ │ ├── icon@2x.png │ │ ├── icon-40@2x.png │ │ ├── icon-40@3x.png │ │ ├── icon-50@2x.png │ │ ├── icon-60@2x.png │ │ ├── icon-60@3x.png │ │ ├── icon-72@2x.png │ │ ├── icon-76@2x.png │ │ ├── icon-small.png │ │ ├── icon-83.5@2x.png │ │ ├── icon-small@2x.png │ │ └── icon-small@3x.png │ └── splash │ │ ├── Default-667h.png │ │ ├── Default-736h.png │ │ ├── Default~iphone.png │ │ ├── Default@2x~iphone.png │ │ ├── Default-568h@2x~iphone.png │ │ ├── Default-Landscape-736h.png │ │ ├── Default-Landscape~ipad.png │ │ ├── Default-Portrait~ipad.png │ │ ├── Default-Portrait@2x~ipad.png │ │ ├── Default-Landscape@2x~ipad.png │ │ ├── Default-Landscape@~ipadpro.png │ │ └── Default-Portrait@~ipadpro.png └── android │ ├── icon │ ├── drawable-hdpi-icon.png │ ├── drawable-ldpi-icon.png │ ├── drawable-mdpi-icon.png │ ├── drawable-xhdpi-icon.png │ ├── drawable-xxhdpi-icon.png │ └── drawable-xxxhdpi-icon.png │ └── splash │ ├── drawable-land-hdpi-screen.png │ ├── drawable-land-ldpi-screen.png │ ├── drawable-land-mdpi-screen.png │ ├── drawable-port-hdpi-screen.png │ ├── drawable-port-ldpi-screen.png │ ├── drawable-port-mdpi-screen.png │ ├── drawable-land-xhdpi-screen.png │ ├── drawable-land-xxhdpi-screen.png │ ├── drawable-land-xxxhdpi-screen.png │ ├── drawable-port-xhdpi-screen.png │ ├── drawable-port-xxhdpi-screen.png │ └── drawable-port-xxxhdpi-screen.png ├── ionic.config.json ├── tslint.json ├── e2e ├── tsconfig.e2e.json ├── app.po.ts └── app.e2e-spec.ts ├── README.md ├── docker-compose.yml ├── .editorconfig ├── server ├── package.json └── index.js ├── .gitignore ├── tsconfig.json ├── test-config ├── karma-test-shim.js ├── protractor.conf.js ├── webpack.test.js ├── karma.conf.js └── mocks-ionic.ts ├── reqs.txt └── google-services.json /src/pages/requests/requests.scss: -------------------------------------------------------------------------------- 1 | page-requests { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/.DS_Store -------------------------------------------------------------------------------- /src/pages/tutorsubjects/tutorsubjects.scss: -------------------------------------------------------------------------------- 1 | page-tutor { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /testing/provider-mocks.js: -------------------------------------------------------------------------------- 1 | 2 | export class AuthProviderMock { 3 | 4 | } 5 | -------------------------------------------------------------------------------- /src/pages/tutorclassmenu/tutorclassmenu.scss: -------------------------------------------------------------------------------- 1 | page-tutorclassmenu { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/app/man.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/app/man.png -------------------------------------------------------------------------------- /resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/icon.png -------------------------------------------------------------------------------- /src/app/albert.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/app/albert.jpg -------------------------------------------------------------------------------- /src/assets/tone.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/tone.mp3 -------------------------------------------------------------------------------- /resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/splash.png -------------------------------------------------------------------------------- /src/assets/img/man.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/man.png -------------------------------------------------------------------------------- /src/assets/img/flask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/flask.png -------------------------------------------------------------------------------- /src/assets/img/girl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/girl.png -------------------------------------------------------------------------------- /src/assets/img/gmail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/gmail.png -------------------------------------------------------------------------------- /src/assets/img/gozer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/gozer.png -------------------------------------------------------------------------------- /src/assets/img/isaac.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/isaac.jpg -------------------------------------------------------------------------------- /src/assets/img/tully.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/tully.jpg -------------------------------------------------------------------------------- /src/assets/img/zuul.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/zuul.png -------------------------------------------------------------------------------- /src/pages/classroom/classroom.scss: -------------------------------------------------------------------------------- 1 | page-classroom { 2 | a { 3 | color: white; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /resources/ios/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon.png -------------------------------------------------------------------------------- /src/assets/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/icon/favicon.ico -------------------------------------------------------------------------------- /src/assets/img/ghost-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ghost-1.png -------------------------------------------------------------------------------- /src/assets/img/ghost-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ghost-3.png -------------------------------------------------------------------------------- /src/assets/img/img-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/img-icon.png -------------------------------------------------------------------------------- /src/assets/img/nin-live.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/nin-live.png -------------------------------------------------------------------------------- /src/assets/img/slide-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/slide-01.png -------------------------------------------------------------------------------- /src/assets/img/slide-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/slide-02.png -------------------------------------------------------------------------------- /src/assets/img/slide-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/slide-03.png -------------------------------------------------------------------------------- /src/assets/img/slimer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/slimer.jpg -------------------------------------------------------------------------------- /src/assets/img/spengler.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/spengler.jpg -------------------------------------------------------------------------------- /src/assets/img/stantz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/stantz.jpg -------------------------------------------------------------------------------- /src/assets/img/venkman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/venkman.jpg -------------------------------------------------------------------------------- /src/assets/img/winston.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/winston.jpg -------------------------------------------------------------------------------- /src/assets/img/enlighten.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/enlighten.png -------------------------------------------------------------------------------- /src/assets/img/ian-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ian-avatar.png -------------------------------------------------------------------------------- /src/assets/img/login-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/login-logo.png -------------------------------------------------------------------------------- /src/assets/img/queen-live.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/queen-live.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-40.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-50.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-60.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-72.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-76.png -------------------------------------------------------------------------------- /resources/ios/icon/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon@2x.png -------------------------------------------------------------------------------- /src/assets/img/enlighten-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/enlighten-red.png -------------------------------------------------------------------------------- /src/assets/img/google-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/google-full.png -------------------------------------------------------------------------------- /src/assets/img/ios-statusbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ios-statusbar.png -------------------------------------------------------------------------------- /src/assets/img/marty-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/marty-avatar.png -------------------------------------------------------------------------------- /src/assets/img/paypartners.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/paypartners.png -------------------------------------------------------------------------------- /src/assets/img/rundmc-live.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/rundmc-live.png -------------------------------------------------------------------------------- /src/assets/img/thumbnail-esb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-esb.png -------------------------------------------------------------------------------- /src/assets/img/wp-statusbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/wp-statusbar.png -------------------------------------------------------------------------------- /testing/page-mocks.js: -------------------------------------------------------------------------------- 1 | export class UserselectionPageMock { 2 | 3 | } 4 | export class LoginPageMock { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /resources/ios/icon/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-40@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-40@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-50@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-60@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-60@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-72@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-76@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-small.png -------------------------------------------------------------------------------- /src/assets/img/card-wireframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/card-wireframe.png -------------------------------------------------------------------------------- /src/assets/img/ghost-buster-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ghost-buster-1.png -------------------------------------------------------------------------------- /src/assets/img/ghost-buster-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ghost-buster-2.png -------------------------------------------------------------------------------- /src/assets/img/ghost-buster-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ghost-buster-3.png -------------------------------------------------------------------------------- /src/assets/img/ghost-buster-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ghost-buster-4.png -------------------------------------------------------------------------------- /src/assets/img/ghost-buster-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ghost-buster-5.png -------------------------------------------------------------------------------- /src/assets/img/marshmallow-man.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/marshmallow-man.png -------------------------------------------------------------------------------- /src/assets/img/thumbnail-bttf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-bttf.png -------------------------------------------------------------------------------- /src/assets/img/thumbnail-rotla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-rotla.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-83.5@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-small@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/icon/icon-small@3x.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-667h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-667h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-736h.png -------------------------------------------------------------------------------- /src/assets/img/footer-wireframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/footer-wireframe.png -------------------------------------------------------------------------------- /src/assets/img/ica-slidebox-img-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ica-slidebox-img-1.png -------------------------------------------------------------------------------- /src/assets/img/ica-slidebox-img-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ica-slidebox-img-2.png -------------------------------------------------------------------------------- /src/assets/img/ica-slidebox-img-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ica-slidebox-img-3.png -------------------------------------------------------------------------------- /src/assets/img/ica-slidebox-img-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/ica-slidebox-img-4.png -------------------------------------------------------------------------------- /src/assets/img/sarah-avatar.png.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/sarah-avatar.png.jpeg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-batman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-batman.png -------------------------------------------------------------------------------- /src/assets/img/thumbnail-kitten-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-kitten-1.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-kitten-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-kitten-2.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-kitten-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-kitten-3.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-kitten-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-kitten-4.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-puppy-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-puppy-1.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-puppy-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-puppy-2.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-puppy-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-puppy-3.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-puppy-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-puppy-4.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-totoro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-totoro.png -------------------------------------------------------------------------------- /src/pages/classmenu/classmenu.scss: -------------------------------------------------------------------------------- 1 | page-classmenu { 2 | h3 { 3 | margin-top: 0 !important; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/pages/createclass/createclass.scss: -------------------------------------------------------------------------------- 1 | page-createclass { 2 | .reduce { 3 | margin-top: 15%; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /resources/ios/splash/Default~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default~iphone.png -------------------------------------------------------------------------------- /src/assets/img/thumbnail-duckling-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-duckling-1.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-duckling-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-duckling-2.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-duckling-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-duckling-3.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-duckling-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-duckling-4.jpg -------------------------------------------------------------------------------- /src/assets/img/thumbnail-terminator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-terminator.png -------------------------------------------------------------------------------- /src/data/tutors.json: -------------------------------------------------------------------------------- 1 | {"tutors": { 2 | "0": { 3 | "name": "Albert Einstein", 4 | "likes": "100" 5 | } 6 | }} -------------------------------------------------------------------------------- /resources/ios/splash/Default@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default@2x~iphone.png -------------------------------------------------------------------------------- /src/app/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*'; 2 | 3 | declare var cordova: any; 4 | declare const Twilio: any; 5 | // declare var Peer: any; -------------------------------------------------------------------------------- /src/assets/img/thumbnail-ghostbusters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/src/assets/img/thumbnail-ghostbusters.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-hdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/icon/drawable-hdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-ldpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/icon/drawable-ldpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-mdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/icon/drawable-mdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-xhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/icon/drawable-xhdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-xxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/icon/drawable-xxhdpi-icon.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-568h@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-568h@2x~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-Landscape-736h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-Landscape~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-Portrait~ipad.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-xxxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/icon/drawable-xxxhdpi-icon.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-Portrait@2x~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-Landscape@2x~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape@~ipadpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-Landscape@~ipadpro.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait@~ipadpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/ios/splash/Default-Portrait@~ipadpro.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-land-hdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-land-ldpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-land-mdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-port-hdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-port-ldpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-port-mdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-land-xhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-land-xxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-land-xxxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-port-xhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-port-xxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/enlighten/master/resources/android/splash/drawable-port-xxxhdpi-screen.png -------------------------------------------------------------------------------- /ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "enlighten-app-za", 3 | "integrations": { 4 | "cordova": {} 5 | }, 6 | "type": "ionic-angular", 7 | "pro_id": "24006e0d" 8 | } -------------------------------------------------------------------------------- /src/pages/userselection/userselection.scss: -------------------------------------------------------------------------------- 1 | page-userselection { 2 | h2 { 3 | margin-bottom: 5% 0; 4 | } 5 | .reduce { 6 | width: 70%; 7 | margin-bottom: 7.5%; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-duplicate-variable": true, 4 | "no-unused-variable": [ 5 | true 6 | ] 7 | }, 8 | "rulesDirectory": [ 9 | "node_modules/tslint-eslint-rules/dist/rules" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/videocall/videocall.scss: -------------------------------------------------------------------------------- 1 | page-videocall { 2 | #credentials, #dialler, #messages { 3 | clear: both; 4 | } 5 | #remote { 6 | max-width: 300px; 7 | } 8 | #mini { 9 | max-width: 150px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/myclasses/myclasses.scss: -------------------------------------------------------------------------------- 1 | page-myclasses { 2 | 3 | 4 | .il { 5 | display: inline-block; 6 | vertical-align: middle; 7 | } 8 | .il.left { 9 | width: 80%; 10 | } 11 | 12 | .il p { 13 | font-size: 0.8em; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/pages/tutorsettings/tutorsettings.scss: -------------------------------------------------------------------------------- 1 | page-tutorsettings { 2 | .reduce { 3 | margin-top: 15%; 4 | width: 50%; 5 | } 6 | 7 | .toggle-form ion-label { 8 | font-size: 0.85em; 9 | display: inline 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/pages/tutorclasses/tutorclasses.scss: -------------------------------------------------------------------------------- 1 | page-tutorclasses { 2 | .il { 3 | display: inline-block; 4 | vertical-align: middle; 5 | } 6 | .il.left { 7 | width: 80%; 8 | } 9 | 10 | .il p { 11 | font-size: 0.8em; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "typeRoots": [ 9 | "../node_modules/@types" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/app/main.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 5 | 6 | import { AppModule } from './app.module'; 7 | 8 | platformBrowserDynamic().bootstrapModule(AppModule); 9 | -------------------------------------------------------------------------------- /src/firebase-messaging-sw.js: -------------------------------------------------------------------------------- 1 | importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js'); 2 | importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js'); 3 | firebase.initializeApp({ 4 | 'messagingSenderId': '745996686081' 5 | }); 6 | const messaging = firebase.messaging(); -------------------------------------------------------------------------------- /src/pages/settings/settings.scss: -------------------------------------------------------------------------------- 1 | page-settings { 2 | button.reduce { 3 | display: inline-block; 4 | text-align: center; 5 | margin-top: 15%; 6 | width: 50%; 7 | } 8 | 9 | .toggle-form ion-label { 10 | font-size: 0.85em; 11 | display: inline 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

This is the development code for enlighten

2 |

To setup on local environment

3 |

git clone 4 |

cd enlighten

5 |

npm install

6 |

type docker-compose up -d

7 |

(for development) type docker exec -it enlighten_dev bash

8 |

to access machine GUI: http://localhost:6901/?password=vncpassword

9 | 10 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | 2 | 3 | version: '2' 4 | services: 5 | enlighten_dev: 6 | image: gerhardlr/ionic_dev:1.2 7 | container_name: enlighten_dev 8 | volumes: 9 | - .:/project/ 10 | ports: 11 | - 8100:8100 12 | - 6901:6901 13 | - 5901:5901 14 | - 9876:9876 15 | entrypoint: 16 | - /dockerstartup/vnc_startup.sh 17 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Enlighten", 3 | "short_name": "Enlighten", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "gcm_sender_id": "103953800507", 7 | "icons": [{ 8 | "src": "assets/imgs/logo.png", 9 | "sizes": "512x512", 10 | "type": "image/png" 11 | }], 12 | "background_color": "#993333", 13 | "theme_color": "#993333" 14 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | 10 | # We recommend you to keep these unchanged 11 | end_of_line = lf 12 | charset = utf-8 13 | trim_trailing_whitespace = true 14 | insert_final_newline = true 15 | 16 | [*.md] 17 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class Page { 4 | 5 | navigateTo(destination) { 6 | return browser.get(destination); 7 | } 8 | 9 | getTitle() { 10 | return browser.getTitle(); 11 | } 12 | 13 | getPageOneTitleText() { 14 | 15 | let el = 16 | element(by.tagName('ion-navbar')) 17 | .element(by.tagName('ion-title')) 18 | ; 19 | 20 | return (el.getText()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phonertcdemo-server", 3 | "version": "0.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "engines": { 7 | "node": "6.11.1" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "author": "Alon Gubkin", 13 | "license": "Apache", 14 | "dependencies": { 15 | "express": "^4.9.0", 16 | "lodash-node": "^2.4.1", 17 | "socket.io": "^1.1.0" 18 | } 19 | } -------------------------------------------------------------------------------- /e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Page } from './app.po'; 2 | 3 | describe('App', () => { 4 | let page: Page; 5 | 6 | beforeEach(() => { 7 | page = new Page(); 8 | }); 9 | 10 | describe('default screen', () => { 11 | beforeEach(() => { 12 | page.navigateTo('/'); 13 | }); 14 | 15 | it('should have a title saying Home', () => { 16 | page.getPageOneTitleText().then(title => { 17 | expect(title).toEqual('Home'); 18 | }); 19 | }); 20 | }) 21 | }); 22 | -------------------------------------------------------------------------------- /src/pages/signup/signup.scss: -------------------------------------------------------------------------------- 1 | page-signup { 2 | .center{ 3 | height: 100px; 4 | width: auto; 5 | margin: auto; 6 | display: block; 7 | } 8 | .girl{ 9 | position: absolute; 10 | left: 0; 11 | bottom:0; 12 | height: 38%; 13 | width: 50%; 14 | } 15 | .google{ 16 | position: absolute; 17 | width: 55%; 18 | height: 16%; 19 | bottom: 0; 20 | right:0; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/pipes/tolocal/tolocal.ts: -------------------------------------------------------------------------------- 1 | import { Pipe } from '@angular/core' 2 | import * as moment from 'moment' 3 | 4 | /** 5 | * Generated class for the TolocalPipe pipe. 6 | * 7 | * See https://angular.io/docs/ts/latest/guide/pipes.html for more info on 8 | * Angular Pipes. 9 | */ 10 | @Pipe({ 11 | name: 'tolocal', 12 | }) 13 | export class TolocalPipe { 14 | /** 15 | * Takes a value and makes it lowercase. 16 | */ 17 | transform(value: string, ...args) { 18 | return moment(value).format('MMM Do hh:mm') 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/pages/wallet/wallet.scss: -------------------------------------------------------------------------------- 1 | page-wallet { 2 | h3 { 3 | font-size: 1.2em; 4 | text-transform: uppercase; 5 | font-weight: lighter; 6 | } 7 | h2 { 8 | font-size: 3em; 9 | text-transform: uppercase; 10 | } 11 | .mid-text { 12 | margin-top: 20%; 13 | } 14 | button.reduce { 15 | display: inline-block; 16 | margin-top: 15%; 17 | width: 50%; 18 | } 19 | 20 | img { 21 | width: 90%; 22 | margin: 5%; 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/providers/scheduling/scheduling.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http } from '@angular/http'; 3 | import 'rxjs/add/operator/map'; 4 | 5 | /* 6 | Generated class for the SchedulingProvider provider. 7 | 8 | See https://angular.io/docs/ts/latest/guide/dependency-injection.html 9 | for more info on providers and Angular DI. 10 | */ 11 | @Injectable() 12 | export class SchedulingProvider { 13 | 14 | constructor(public http: Http) { 15 | console.log('Hello SchedulingProvider Provider'); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | 4 | *~ 5 | *.sw[mnpcod] 6 | *.log 7 | *.tmp 8 | *.tmp.* 9 | log.txt 10 | *.sublime-project 11 | *.sublime-workspace 12 | .vscode/ 13 | npm-debug.log* 14 | 15 | .idea/ 16 | .sass-cache/ 17 | .tmp/ 18 | .versions/ 19 | coverage/ 20 | dist/ 21 | node_modules/ 22 | tmp/ 23 | temp/ 24 | hooks/ 25 | platforms/ 26 | plugins/ 27 | plugins/android.json 28 | plugins/ios.json 29 | www/ 30 | $RECYCLE.BIN/ 31 | 32 | .DS_Store 33 | Thumbs.db 34 | UserInterfaceState.xcuserstate 35 | -------------------------------------------------------------------------------- /src/pages/profile/profile.scss: -------------------------------------------------------------------------------- 1 | page-profile { 2 | ion-content{ 3 | img{ 4 | height: 80px; 5 | width: auto; 6 | margin: auto; 7 | display: block; 8 | border-radius: 50%; 9 | } 10 | ion-input{ 11 | font-size: 14px; 12 | color: grey; 13 | } 14 | ion-select{ 15 | font-size: 14px; 16 | color: grey; 17 | } 18 | .up-btn{ 19 | position: absolute; 20 | left: calc(35%); 21 | } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/pages/tutorschedule/tutorschedule.scss: -------------------------------------------------------------------------------- 1 | page-tutorschedule { 2 | .schedule-item { 3 | margin: 1rem; 4 | box-shadow: 2px 3px 3px rgba(0, 0, 0, 0.1); 5 | position: relative; 6 | 7 | .delete { 8 | position: absolute; 9 | left: auto !important; 10 | right: 1rem !important; 11 | top: 1rem !important; 12 | height: 20px; 13 | width: 20px; 14 | font-size: 16px; 15 | z-index: 10; 16 | } 17 | 18 | ion-col { 19 | text-align: left !important; 20 | display: flex; 21 | align-items: center; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": false, 5 | "emitDecoratorMetadata": true, 6 | "experimentalDecorators": true, 7 | "lib": [ 8 | "dom", 9 | "es2015" 10 | ], 11 | "module": "es2015", 12 | "moduleResolution": "node", 13 | "sourceMap": true, 14 | "target": "es5", 15 | "skipLibCheck": true 16 | }, 17 | "include": [ 18 | "src/**/*.ts" 19 | ], 20 | "exclude": [ 21 | "node_modules" 22 | ], 23 | "compileOnSave": false, 24 | "atom": { 25 | "rewriteTsconfig": false 26 | } 27 | } -------------------------------------------------------------------------------- /src/pages/wallet/wallet.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | 4 | /** 5 | * Generated class for the WalletPage page. 6 | * 7 | * See http://ionicframework.com/docs/components/#navigation for more info 8 | * on Ionic pages and navigation. 9 | */ 10 | 11 | @Component({ 12 | selector: 'page-wallet', 13 | templateUrl: 'wallet.html', 14 | }) 15 | export class WalletPage { 16 | 17 | constructor(public navCtrl: NavController, public navParams: NavParams) { 18 | } 19 | 20 | ionViewDidLoad() { 21 | console.log('ionViewDidLoad WalletPage'); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/pages/requests/requests.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | 4 | /** 5 | * Generated class for the RequestsPage page. 6 | * 7 | * See http://ionicframework.com/docs/components/#navigation for more info 8 | * on Ionic pages and navigation. 9 | */ 10 | 11 | @Component({ 12 | selector: 'page-requests', 13 | templateUrl: 'requests.html', 14 | }) 15 | export class RequestsPage { 16 | 17 | constructor(public navCtrl: NavController, public navParams: NavParams) { 18 | } 19 | 20 | ionViewDidLoad() { 21 | console.log('ionViewDidLoad RequestsPage'); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/pages/settings/settings.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | 4 | /** 5 | * Generated class for the SettingsPage page. 6 | * 7 | * See http://ionicframework.com/docs/components/#navigation for more info 8 | * on Ionic pages and navigation. 9 | */ 10 | 11 | @Component({ 12 | selector: 'page-settings', 13 | templateUrl: 'settings.html', 14 | }) 15 | export class SettingsPage { 16 | 17 | constructor(public navCtrl: NavController, public navParams: NavParams) { 18 | } 19 | 20 | ionViewDidLoad() { 21 | console.log('ionViewDidLoad SettingsPage'); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/pages/tutorsubjects/tutorsubjects.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | 4 | /** 5 | * Generated class for the TutorPage page. 6 | * 7 | * See http://ionicframework.com/docs/components/#navigation for more info 8 | * on Ionic pages and navigation. 9 | */ 10 | 11 | @Component({ 12 | selector: 'page-tutorsubjects', 13 | templateUrl: 'tutorsubjects.html', 14 | }) 15 | export class TutorsubjectsPage { 16 | 17 | constructor(public navCtrl: NavController, public navParams: NavParams) { 18 | } 19 | 20 | ionViewDidLoad() { 21 | console.log('ionViewDidLoad TutorsubjectsPage'); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/pages/tutorsettings/tutorsettings.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | 4 | /** 5 | * Generated class for the TutorsettingsPage page. 6 | * 7 | * See http://ionicframework.com/docs/components/#navigation for more info 8 | * on Ionic pages and navigation. 9 | */ 10 | 11 | @Component({ 12 | selector: 'page-tutorsettings', 13 | templateUrl: 'tutorsettings.html', 14 | }) 15 | export class TutorsettingsPage { 16 | 17 | constructor(public navCtrl: NavController, public navParams: NavParams) { 18 | } 19 | 20 | ionViewDidLoad() { 21 | console.log('ionViewDidLoad TutorsettingsPage'); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/pages/classbrowse/classbrowse.scss: -------------------------------------------------------------------------------- 1 | page-classbrowse { 2 | .item-md p { 3 | font-size: 0.75em; 4 | } 5 | 6 | .item-block.il { 7 | max-width: 35%; 8 | display: inline-block; 9 | vertical-align: middle; 10 | } 11 | 12 | .item-block.il.left { 13 | max-width: 65%; 14 | } 15 | 16 | em { 17 | color: #f8d650; 18 | font-style: none; 19 | } 20 | 21 | .toolbar-md { 22 | padding: 0; 23 | } 24 | 25 | .toolbar-content-md, .toolbar-md { 26 | background: #993333; 27 | 28 | } 29 | 30 | .respect { 31 | min-height: auto; 32 | } 33 | 34 | .toolbar-background-md { 35 | display: none; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/pages/parentregister/parentregister.scss: -------------------------------------------------------------------------------- 1 | page-parentregister { 2 | ion-content{ 3 | img{ 4 | height: 80px; 5 | width: auto; 6 | margin: auto; 7 | display: block; 8 | border-radius: 50%; 9 | } 10 | ion-input{ 11 | font-size: 14px; 12 | color: grey; 13 | } 14 | ion-select{ 15 | font-size: 14px; 16 | color: grey; 17 | } 18 | .reduce{ 19 | width: 60%; 20 | left: calc(20%); 21 | } 22 | .text { 23 | text-align: center; 24 | width: 95%; 25 | font-size: 14px; 26 | } 27 | 28 | .col { 29 | padding: 0; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test-config/karma-test-shim.js: -------------------------------------------------------------------------------- 1 | Error.stackTraceLimit = Infinity; 2 | 3 | require('core-js/es6'); 4 | require('core-js/es7/reflect'); 5 | 6 | require('zone.js/dist/zone'); 7 | require('zone.js/dist/long-stack-trace-zone'); 8 | require('zone.js/dist/proxy'); 9 | require('zone.js/dist/sync-test'); 10 | require('zone.js/dist/jasmine-patch'); 11 | require('zone.js/dist/async-test'); 12 | require('zone.js/dist/fake-async-test'); 13 | 14 | var appContext = require.context('../src', true, /\.spec\.ts/); 15 | 16 | appContext.keys().forEach(appContext); 17 | 18 | var testing = require('@angular/core/testing'); 19 | var browser = require('@angular/platform-browser-dynamic/testing'); 20 | 21 | testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting()); 22 | -------------------------------------------------------------------------------- /src/pages/lesson/lesson.scss: -------------------------------------------------------------------------------- 1 | page-lesson { 2 | p{ 3 | color: white; 4 | } 5 | ion-item{ 6 | strong{ 7 | color: white; 8 | } 9 | .desc{ 10 | color: white; 11 | font-size: 10px; 12 | font-weight: lighter; 13 | } 14 | } 15 | .pad{ 16 | padding: 0 25%; 17 | } 18 | img{ 19 | height: 80px; 20 | width: auto; 21 | margin: auto; 22 | display: block; 23 | } 24 | .sec{ 25 | color: #f8d64e 26 | } 27 | .btn{ 28 | position:relative; 29 | width: 60%; 30 | left: calc(18%); 31 | } 32 | .center-align{ 33 | position: relative; 34 | left: calc(15%); 35 | background-color: #333 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/pages/logout/logout.html: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | 12 | 13 | 14 | 17 | 20 | 21 | 22 |
23 |

South Africa's 1st Live Online Tutoring App

24 |
25 | -------------------------------------------------------------------------------- /src/pages/appointments/appointments.scss: -------------------------------------------------------------------------------- 1 | page-appointments { 2 | ion-content p.small { 3 | font-size: 0.75em; 4 | } 5 | 6 | .item-block.il { 7 | max-width: 35%; 8 | display: inline-block; 9 | vertical-align: middle; 10 | } 11 | 12 | .item-block.il.left { 13 | max-width: 60%; 14 | } 15 | 16 | .card-md { 17 | border-radius: 7.5px; 18 | border:1px solid #ccc; 19 | } 20 | 21 | b { 22 | font-weight: bold; 23 | } 24 | 25 | .il { 26 | display: inline-block; 27 | vertical-align: middle; 28 | } 29 | 30 | .il.left.title { 31 | max-width: none; 32 | width: 80%; 33 | } 34 | .item-block.il.icon { 35 | max-width: none; 36 | width: 18%; 37 | padding-left: 2%; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /test-config/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | '../e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome', 13 | 14 | }, 15 | directConnect: true, 16 | baseUrl: 'http://localhost:8100/', 17 | framework: 'jasmine', 18 | jasmineNodeOpts: { 19 | showColors: true, 20 | defaultTimeoutInterval: 30000, 21 | print: function() {} 22 | }, 23 | onPrepare() { 24 | require('ts-node').register({ 25 | project: 'e2e/tsconfig.e2e.json' 26 | }); 27 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /src/pages/logout/logout.scss: -------------------------------------------------------------------------------- 1 | page-logout { 2 | .display{ 3 | width: 100%; 4 | padding-top: 20%; 5 | height: auto; 6 | background-color: #993333; 7 | } 8 | .bg { 9 | background-color: #993333; 10 | position: relative; 11 | } 12 | img{ 13 | margin-top: 10%; 14 | position: relative; 15 | width: auto; 16 | margin: auto; 17 | display: block; 18 | margin-bottom: 10vh; 19 | } 20 | .btn{ 21 | position:relative; 22 | width: 60%; 23 | } 24 | .text { 25 | color: white; 26 | text-align: center; 27 | margin-top: 25%; 28 | text-align:center; 29 | width: 100%; 30 | font-size: 14px; 31 | 32 | } 33 | 34 | .img-logout { 35 | width: 60%; 36 | max-width: 175px; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check out https://googlechrome.github.io/sw-toolbox/ for 3 | * more info on how to use sw-toolbox to custom configure your service worker. 4 | */ 5 | 6 | 7 | 'use strict'; 8 | importScripts('./build/sw-toolbox.js'); 9 | 10 | self.toolbox.options.cache = { 11 | name: 'ionic-cache' 12 | }; 13 | 14 | // pre-cache our key assets 15 | self.toolbox.precache( 16 | [ 17 | './build/main.js', 18 | './build/vendor.js', 19 | './build/main.css', 20 | './build/polyfills.js', 21 | 'index.html', 22 | 'manifest.json' 23 | ] 24 | ); 25 | 26 | // dynamically cache any other local assets 27 | self.toolbox.router.any('/*', self.toolbox.cacheFirst); 28 | 29 | // for any other requests go to the network, cache, 30 | // and then only use that cached resource if your user goes offline 31 | self.toolbox.router.default = self.toolbox.networkFirst; 32 | -------------------------------------------------------------------------------- /src/pages/tutors/tutors.scss: -------------------------------------------------------------------------------- 1 | page-tutors { 2 | transition: all 1s; 3 | /*ion-card{ 4 | position: absolute; 5 | padding: 0px 5%; 6 | top: 50px; 7 | }*/ 8 | img{ 9 | 10 | background-size: contain; 11 | } 12 | .info{ 13 | font-size: 12px; 14 | } 15 | .description{ 16 | font-size: 10px; 17 | } 18 | .info-sec{ 19 | width: 90%; 20 | height: 20%; 21 | margin: 0px 5%; 22 | } 23 | .no{ 24 | padding: 5px; 25 | } 26 | .request-btn{ 27 | width: 50%; 28 | left: calc(25%); 29 | margin-top: 5%; 30 | margin-bottom: 7.5%; 31 | } 32 | h3{ 33 | text-align:center; 34 | width: 100%; 35 | padding: 0px 15%; 36 | font-size: 14px; 37 | } 38 | 39 | .fab-md { 40 | height: 45px; 41 | width: 45px; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/components/canvas-draw/canvas-draw.scss: -------------------------------------------------------------------------------- 1 | canvas-draw { 2 | height: 100%; 3 | width: 100%; 4 | display: block; 5 | 6 | .selected { 7 | color: #fff; 8 | border: 1px solid white; 9 | border-radius: 2px; 10 | } 11 | 12 | .unsel { 13 | color: #ccc; 14 | } 15 | 16 | #top-toolbar{ 17 | position: absolute; 18 | top: 0; 19 | left: 0; 20 | width: 100%; 21 | border: 0px solid white; 22 | border-radius: 0px; 23 | } 24 | 25 | #bottom-toolbar { 26 | position: absolute; 27 | bottom: 0; 28 | } 29 | 30 | .back { 31 | font-size: 28px; 32 | margin-left: 2%; 33 | } 34 | 35 | .content { 36 | margin-top: 56px; 37 | height: calc(100vh - 112px); 38 | } 39 | 40 | ion-fab button { 41 | height: 36px !important; 42 | width: 36px !important; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/pages/tutorsubjects/tutorsubjects.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | My Subjects 11 | 12 | 13 | 14 | 15 | 16 | 17 |

My Subjects

18 | 19 | 20 | 21 | 22 | Mathematics 23 | 24 | 25 | 26 | Physics 27 | 28 | 29 | 30 | 31 |
32 | -------------------------------------------------------------------------------- /src/pages/wallet/wallet.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Wallet 13 | 14 | 15 | 16 | 17 | 18 |

Your current balance is

19 |

R420.00

20 | 21 |

Add credits

22 | 23 | 24 | Card Number 25 | 26 | 27 | 28 | 31 |
32 | -------------------------------------------------------------------------------- /src/pages/classroom/classroom.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Classroom 13 | 14 | 15 | 16 | 17 | 18 | 23 | 24 | Open WhatsApp chat window 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/pages/tutorhome/tutorhome.scss: -------------------------------------------------------------------------------- 1 | page-tutorhome { 2 | .item-md p { 3 | font-size: 0.75em; 4 | } 5 | 6 | .item-block.il { 7 | max-width: 35%; 8 | display: inline-block; 9 | vertical-align: middle; 10 | } 11 | 12 | .item-block.il.left { 13 | max-width: 65%; 14 | } 15 | 16 | .item-md h2 { 17 | font-weight: bold; 18 | } 19 | 20 | em { 21 | color: #f8d650; 22 | font-style: none; 23 | } 24 | .item-md.item-block div.item-inner { 25 | border-bottom: none; 26 | } 27 | 28 | .label-md, .card-md { 29 | margin-top: 1px; 30 | } 31 | 32 | .pending { 33 | position: fixed; 34 | width: 80%; 35 | bottom: 0%; 36 | left: 10%; 37 | padding: 2%; 38 | border-radius: 7.5px; 39 | border-bottom-left-radius: 0; 40 | border-bottom-right-radius: 0; 41 | color: #eee; 42 | background: #333; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/pages/classbrowse/classbrowse.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams, AlertController } from 'ionic-angular'; 3 | 4 | /** 5 | * Generated class for the ClassbrowsePage page. 6 | * 7 | * See http://ionicframework.com/docs/components/#navigation for more info 8 | * on Ionic pages and navigation. 9 | */ 10 | 11 | @Component({ 12 | selector: 'page-classbrowse', 13 | templateUrl: 'classbrowse.html', 14 | }) 15 | export class ClassbrowsePage { 16 | browse: string = "offers"; 17 | 18 | constructor(public navCtrl: NavController, public navParams: NavParams, public alertCtrl: AlertController) { 19 | } 20 | 21 | ionViewDidLoad() { 22 | console.log('ionViewDidLoad ClassbrowsePage'); 23 | } 24 | 25 | showAlert() { 26 | let alert = this.alertCtrl.create({ 27 | title: 'Request Sent!', 28 | buttons: ['OK'] 29 | }); 30 | alert.present(); 31 | } 32 | 33 | request(){ 34 | //Send Request 35 | this.showAlert(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/pages/signup/signup.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | import { RegisterPage } from '../register/register'; 4 | import { UserselectionPage } from '../userselection/userselection'; 5 | 6 | /** 7 | * Generated class for the SignupPage page. 8 | * 9 | * See http://ionicframework.com/docs/components/#navigation for more info 10 | * on Ionic pages and navigation. 11 | */ 12 | 13 | @Component({ 14 | selector: 'page-signup', 15 | templateUrl: 'signup.html', 16 | }) 17 | export class SignupPage { 18 | browse: string = "first"; 19 | constructor(public navCtrl: NavController, public navParams: NavParams) { 20 | } 21 | 22 | ionViewDidLoad() { 23 | console.log('ionViewDidLoad SignupPage'); 24 | } 25 | regPg(){ 26 | this.navCtrl.push(RegisterPage); 27 | //setTimeout(this.back(), 4000); 28 | } 29 | next(){ 30 | this.browse = "second"; 31 | } 32 | back(){ 33 | this.browse = "first"; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/pages/classroom/classroom.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { SocialSharing } from '@ionic-native/social-sharing'; 3 | import { NavController, NavParams } from 'ionic-angular'; 4 | 5 | 6 | /** 7 | * Generated class for the ClassroomPage page. 8 | * 9 | * See http://ionicframework.com/docs/components/#navigation for more info 10 | * on Ionic pages and navigation. 11 | */ 12 | 13 | @Component({ 14 | selector: 'page-classroom', 15 | templateUrl: 'classroom.html', 16 | }) 17 | export class ClassroomPage { 18 | 19 | constructor(public navCtrl: NavController, 20 | public navParams: NavParams, private socialSharing: SocialSharing) { 21 | } 22 | 23 | ionViewDidLoad() { 24 | console.log('ionViewDidLoad ClassroomPage'); 25 | } 26 | 27 | whatsappShare() { 28 | this.socialSharing.shareViaWhatsApp("shareViaWhatsApp", null, null).then(() => { 29 | console.log("shareViaWhatsApp: Success"); 30 | }).catch(() => { 31 | console.error("shareViaWhatsApp: failed"); 32 | }); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/app/services/subjects/subjects.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | 4 | @Injectable() 5 | export class SubjectsAccess { 6 | subjects = [{ 7 | "name": "Mathematics", 8 | "founded": "1829", 9 | "info": "assets/img/avatar-albert.jpg" 10 | }, 11 | { 12 | "name": "Physical Sciences", 13 | "founded": "1829", 14 | "info": "assets/img/avatar-albert.jpg" 15 | }] 16 | constructor () {} 17 | 18 | getSubjects() { 19 | 20 | var data = JSON.parse(`{"tutors": ${JSON.stringify(this.subjects)} 21 | }`) 22 | return data.tutors; 23 | 24 | } 25 | 26 | getSubject(id) { 27 | var result = this.subjects.filter(function( obj ) { 28 | return obj.name == id; 29 | }); 30 | return result; 31 | } 32 | } -------------------------------------------------------------------------------- /src/pages/classmenu/classmenu.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | 4 | /** 5 | * Generated class for the ClassmenuPage page. 6 | * 7 | * See http://ionicframework.com/docs/components/#navigation for more info 8 | * on Ionic pages and navigation. 9 | */ 10 | import {MyclassesPage} from '../myclasses/myclasses'; 11 | import {ClassbrowsePage} from '../classbrowse/classbrowse'; 12 | 13 | 14 | @Component({ 15 | selector: 'page-classmenu', 16 | templateUrl: 'classmenu.html', 17 | }) 18 | export class ClassmenuPage { 19 | private myclassesPage; 20 | private classbrowsePage; 21 | private user; 22 | constructor(public navCtrl: NavController, public navParams: NavParams) { 23 | this.myclassesPage = MyclassesPage; 24 | this.classbrowsePage = ClassbrowsePage; 25 | this.user = navParams.get('user'); 26 | } 27 | 28 | ionViewDidLoad() { 29 | console.log('ionViewDidLoad ClassmenuPage'); 30 | } 31 | 32 | toPage(page) { 33 | this.navCtrl.push(page, {user: this.user}); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/pages/tutorclassmenu/tutorclassmenu.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | 4 | 5 | /** 6 | * Generated class for the TutorclassmenuPage page. 7 | * 8 | * See http://ionicframework.com/docs/components/#navigation for more info 9 | * on Ionic pages and navigation. 10 | */ 11 | import {TutorclassesPage} from '../tutorclasses/tutorclasses'; 12 | import {CreateclassPage} from '../createclass/createclass'; 13 | 14 | @Component({ 15 | selector: 'page-tutorclassmenu', 16 | templateUrl: 'tutorclassmenu.html', 17 | }) 18 | export class TutorclassmenuPage { 19 | private tutorclassesPage; 20 | private createclassPage; 21 | private user; 22 | constructor(public navCtrl: NavController, public navParams: NavParams) { 23 | this.tutorclassesPage = TutorclassesPage; 24 | this.createclassPage = CreateclassPage; 25 | this.user = navParams.get('user'); 26 | } 27 | 28 | ionViewDidLoad() { 29 | console.log('ionViewDidLoad TutorclassmenuPage'); 30 | } 31 | toPage(page) { 32 | this.navCtrl.push(page, {user: this.user}); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/pages/appointments/appointments.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | 4 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'; 5 | import { AngularFireAuth } from 'angularfire2/auth'; 6 | import { Observable } from 'rxjs/Observable'; 7 | /** 8 | * Generated class for the AppointmentsPage page. 9 | * 10 | * See http://ionicframework.com/docs/components/#navigation for more info 11 | * on Ionic pages and navigation. 12 | */ 13 | 14 | @Component({ 15 | selector: 'page-appointments', 16 | templateUrl: 'appointments.html', 17 | }) 18 | export class AppointmentsPage { 19 | private user; 20 | private lessons_upcoming: FirebaseListObservable 21 | constructor(public navCtrl: NavController, 22 | public navParams: NavParams, 23 | private af: AngularFireDatabase) { 24 | this.user = navParams.get('user'); 25 | this.lessons_upcoming = af.list(`/lessons_upcoming_tutors/${this.user.uid}`); 26 | } 27 | 28 | ionViewDidLoad() { 29 | console.log('ionViewDidLoad AppointmentsPage'); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/pages/logout/logout.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { MenuController,NavController, NavParams } from 'ionic-angular'; 3 | import { LoginPage } from '../login/login'; 4 | import { Events } from 'ionic-angular'; 5 | import { UserselectionPage } from '../userselection/userselection'; 6 | 7 | /** 8 | * Generated class for the LogoutPage page. 9 | * 10 | * See http://ionicframework.com/docs/components/#navigation for more info 11 | * on Ionic pages and navigation. 12 | */ 13 | 14 | @Component({ 15 | selector: 'page-logout', 16 | templateUrl: 'logout.html', 17 | }) 18 | export class LogoutPage { 19 | private menuCtrl; 20 | constructor(public navCtrl: NavController, public navParams: NavParams, 21 | public events: Events,public menu: MenuController) { 22 | //this.menuCtrl = menu; 23 | this.menu.enable(false, 'myMenu') 24 | } 25 | 26 | ionViewDidLoad() { 27 | console.log('ionViewDidLoad LogoutPage'); 28 | } 29 | loginPg() { 30 | this.navCtrl.push(LoginPage); 31 | } 32 | regPg() { 33 | this.navCtrl.push(UserselectionPage); 34 | } 35 | 36 | onPageWillLeave() { 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/pages/settings/settings.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Settings 13 | 14 | 15 | 16 | 17 | 18 |

Change your preferences below

19 | 20 | 21 | Show my profile info to
tutors
22 | 23 |
24 | 25 | 26 | Show profile when offline 27 | 28 | 29 | 30 | 31 | Limit tutors to
my location
32 | 33 |
34 | 35 | 38 | 39 |
40 | 41 | -------------------------------------------------------------------------------- /src/pages/tutorsettings/tutorsettings.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Settings 13 | 14 | 15 | 16 | 17 | 18 |

Change your preferences below

19 | 20 | 21 | Show my profile info to
students
22 | 23 |
24 | 25 | 26 | Show profile when offline 27 | 28 | 29 | 30 | 31 | Limit student requests to
location
32 | 33 |
34 | 35 | 38 | 39 |
40 | -------------------------------------------------------------------------------- /src/pages/login/login.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, TestBed } from '@angular/core/testing'; 2 | import { NavController, IonicModule, Platform, Events } from 'ionic-angular'; 3 | //unit under test 4 | import {LoginPage} from './login.ts' 5 | //dependencies also being developed and requiring mocking 6 | import { AuthProvider } from '../../providers/auth/auth'//to be mocked by: 7 | import {AuthProviderMock} from '../../../testing/provider-mocks.js' 8 | 9 | describe('The login page shall', () => { 10 | let fixture; 11 | let component; 12 | 13 | beforeEach(async(() => { 14 | TestBed.configureTestingModule({ 15 | declarations: [LoginPage], 16 | imports: [ 17 | IonicModule.forRoot(LoginPage) 18 | ], 19 | providers:[ 20 | NavController, Events,//stable dependencies 21 | //non stable dependencies 22 | {provide: AuthProvider, useClass: AuthProviderMock} 23 | ] 24 | 25 | }); 26 | })); 27 | 28 | beforeEach(() => { 29 | fixture = TestBed.createComponent(LoginPage); 30 | component = fixture.componentInstance; 31 | }); 32 | 33 | it('be created successfully', () => { 34 | expect(component instanceof LoginPage).toBe(true); 35 | }); 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /src/pages/tutorclassmenu/tutorclassmenu.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | CLASSES 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |

MY CLASSES

24 |

Create and view details
about your classes

25 |
26 | 27 | 28 | 29 | 30 | 31 |

CREATE LESSON

32 |

Create a lesson to match
your own schedule

33 |
34 |
35 |
36 | -------------------------------------------------------------------------------- /src/app/common/webrtc.config.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable() 4 | export class WebRTCConfig { 5 | 6 | peerServerPort: number = 9000; 7 | 8 | key: string = 'iu6qotrrnfm9529'; 9 | 10 | stun: string = 'stun.l.google.com:19302'; 11 | turn: string = 'numb.viagenie.ca'; 12 | turnCredentials: string = 'homeo'; 13 | user = 'wshilumani@gmail.com'; 14 | c = 'Bluevenom1' 15 | 16 | turnServer = { 17 | url: 'turn:' + this.turn, 18 | username: this.user, 19 | credential: this.c 20 | }; 21 | stunServer = { 22 | url: 'stun:' + this.stun 23 | }; 24 | 25 | getPeerJSOption()/*: PeerJS.PeerJSOption*/ { 26 | return { 27 | host: 'enlighten-video.herokuapp.com', 28 | debug: 3, 29 | port:443, 30 | key: 'peerjs', 31 | secure: true, 32 | }; 33 | } 34 | 35 | /**********************/ 36 | 37 | audio: boolean = true; 38 | video: boolean = true; 39 | 40 | getMediaStreamConstraints(): MediaStreamConstraints { 41 | return { 42 | audio: this.audio, 43 | video: this.video 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/pages/classmenu/classmenu.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | CLASSES 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |

MY CLASSES

24 |

Create and view details
about your classes

25 |
26 | 27 | 28 | 29 | 30 | 31 |

BROWSE CLASSES

32 |

Find and view class offers
that match your profile

33 |
34 |
35 |
36 | -------------------------------------------------------------------------------- /src/pages/tutorregister/tutorregister.scss: -------------------------------------------------------------------------------- 1 | page-tutorregister { 2 | ion-content { 3 | text-align: center; 4 | 5 | h2 { 6 | font-family: 'Roboto', sans-serif; 7 | font-weight: lighter; 8 | } 9 | 10 | img { 11 | height: 80px; 12 | width: auto; 13 | margin: auto; 14 | display: block; 15 | border-radius: 50%; 16 | } 17 | 18 | ion-input { 19 | font-size: 14px; 20 | color: grey; 21 | } 22 | 23 | ion-select { 24 | font-size: 14px; 25 | color: grey; 26 | } 27 | 28 | .reduce { 29 | width: 60%; 30 | } 31 | 32 | .sign { 33 | margin-top: 5%; 34 | width: 100%; 35 | } 36 | 37 | .text { 38 | text-align: center; 39 | width: 95%; 40 | font-size: 14px; 41 | } 42 | 43 | .col { 44 | padding: 0; 45 | } 46 | 47 | span.hint { 48 | padding: 4px 16px; 49 | color: color($colors, danger); 50 | font-size: 1rem; 51 | width: 100%; 52 | text-align: left; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /test-config/webpack.test.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var path = require('path'); 3 | 4 | module.exports = { 5 | devtool: 'inline-source-map', 6 | 7 | resolve: { 8 | extensions: ['.ts', '.js'] 9 | }, 10 | 11 | module: { 12 | rules: [{ 13 | test: /\.ts$/, 14 | loaders: [{ 15 | loader: 'ts-loader' 16 | }, 'angular2-template-loader'] 17 | }, 18 | { 19 | test: /.+\.ts$/, 20 | exclude: /(index.ts|mocks.ts|\.spec\.ts$)/, 21 | loader: 'istanbul-instrumenter-loader', 22 | enforce: 'post', 23 | query: { 24 | esModules: true 25 | } 26 | }, 27 | { 28 | test: /\.html$/, 29 | loader: 'html-loader?attrs=false' 30 | }, 31 | { 32 | test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, 33 | loader: 'null-loader' 34 | } 35 | ] 36 | }, 37 | 38 | plugins: [ 39 | new webpack.ContextReplacementPlugin( 40 | // The (\\|\/) piece accounts for path separators in *nix and Windows 41 | /(ionic-angular)|(angular(\\|\/)core(\\|\/)@angular)/, 42 | root('./src'), // location of your src 43 | {} // a map of your routes 44 | ) 45 | ] 46 | }; 47 | 48 | function root(localPath) { 49 | return path.resolve(__dirname, localPath); 50 | } 51 | -------------------------------------------------------------------------------- /reqs.txt: -------------------------------------------------------------------------------- 1 | Enlighten 2017/08/13 2 | 3 | APK 4 | [Google takes her back to login page] 5 | 6 | Students can request tutors - calendar; 7 | 8 | LASTLY: 9 | Website info; 10 | 11 | PNG of logo; 12 | 13 | Use school pass rates 14 | 15 | for every 3 disadvantaged learners, they get 2 paying learners; 16 | 17 | Chat system 18 | 19 | Send skype link to computer | 20 | 21 | So, 22 | 23 | Move from inactive to credits loaded 24 | 25 | grade changes affects credits_inactive and loaded; move ll PIDs to used; but concantenate all the PIDs 26 | 27 | accounts_credits_converted 28 | 29 | Feedback, length of session; credits_loaded - check for difference in figures, and compare with feedback length 30 | account_history_learner - latest node must match difference in credits_loaded 31 | 32 | accounts_history, last_transaction 33 | 34 | Write all the history 35 | 36 | Portal - verify 37 | 38 | Learner starts account: learner_profiles onCreate; create accounts_credits_loaded with 1 credit; do that for history_learner too; check onCreate for tutor 39 | 40 | check onCreate inactive, check credits_loaded is less than 0.75 41 | ROUNDING: thats for baseRateChange 42 | 43 | account_history_tutor with -1 credits 44 | 45 | if feedback not submitted (Adrian is doing this), deduct a credit - 46 | 47 | type: payment from lesson or withdrawal 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/pages/userselection/userselection.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | Role selection 10 | 11 | 12 | 13 | 14 | 15 |

Please select your role:

16 | 19 | 20 | 23 | 24 | 27 | 28 | 36 | 37 |
38 | -------------------------------------------------------------------------------- /src/pages/draw/draw.scss: -------------------------------------------------------------------------------- 1 | page-draw { 2 | .no-scroll, ion-content, .scroll-content { 3 | overflow: hidden !important; 4 | } 5 | 6 | button.disabled { 7 | background: #777 !important; 8 | } 9 | 10 | .videos { 11 | height: calc(100vh - 56px); 12 | position: fixed; 13 | z-index: 100; 14 | top: 56px; 15 | left: 0; 16 | font-size: 0; 17 | width: 100%; 18 | text-align: center; 19 | } 20 | 21 | .vid.ilb { 22 | font-size: 16px; 23 | display: inline-block; 24 | width: 100%; 25 | height: calc(100vh - 56px); 26 | margin: 0% !important; 27 | vertical-align: top; 28 | background: #222; 29 | text-align: center; 30 | } 31 | 32 | video { 33 | width: 100%; 34 | height: calc(100vh - 56px); 35 | } 36 | 37 | .vid.ilb.mine { 38 | width: 128px; 39 | height: 128px; 40 | margin-left: 24.5% !important; 41 | position: absolute; 42 | bottom: 0; 43 | right: 0; 44 | } 45 | 46 | .waiting { 47 | color: white; 48 | } 49 | 50 | .vid.ilb.mine video { 51 | width: 128px; 52 | height: 128px; 53 | } 54 | #credentials, #dialler, #messages { 55 | clear: both; 56 | } 57 | #remote { 58 | max-width: 300px; 59 | } 60 | #mini { 61 | max-width: 150px; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /test-config/karma.conf.js: -------------------------------------------------------------------------------- 1 | var webpackConfig = require('./webpack.test.js'); 2 | 3 | module.exports = function(config) { 4 | var _config = { 5 | basePath: '../', 6 | 7 | frameworks: ['jasmine'], 8 | 9 | files: [ 10 | { 11 | pattern: './test-config/karma-test-shim.js', 12 | watched: true 13 | }, 14 | { 15 | pattern: './src/assets/**/*', 16 | watched: false, 17 | included: false, 18 | served: true, 19 | nocache: false 20 | } 21 | ], 22 | 23 | proxies: { 24 | '/assets/': '/base/src/assets/' 25 | }, 26 | 27 | preprocessors: { 28 | './test-config/karma-test-shim.js': ['webpack', 'sourcemap'] 29 | }, 30 | 31 | webpack: webpackConfig, 32 | 33 | webpackMiddleware: { 34 | stats: 'errors-only' 35 | }, 36 | 37 | webpackServer: { 38 | noInfo: true 39 | }, 40 | 41 | browserConsoleLogOptions: { 42 | level: 'log', 43 | format: '%b %T: %m', 44 | terminal: true 45 | }, 46 | 47 | coverageIstanbulReporter: { 48 | reports: [ 'html', 'lcovonly' ], 49 | fixWebpackSourcePaths: true 50 | }, 51 | 52 | reporters: config.coverage ? ['kjhtml', 'dots', 'coverage-istanbul'] : ['kjhtml', 'dots'], 53 | port: 9876, 54 | colors: true, 55 | logLevel: config.LOG_INFO, 56 | autoWatch: true, 57 | browsers: ['Chrome'], 58 | singleRun: false 59 | }; 60 | 61 | config.set(_config); 62 | }; 63 | -------------------------------------------------------------------------------- /src/pages/tutorprofile/tutorprofile.scss: -------------------------------------------------------------------------------- 1 | page-tutorprofile { 2 | ion-content{ 3 | 4 | .select-md { 5 | padding: 13px 8px 13px 16px !important; 6 | } 7 | 8 | ion-col { 9 | text-align: left !important; 10 | display: flex; 11 | align-items: center; 12 | } 13 | img{ 14 | height: 80px; 15 | width: auto; 16 | margin: auto; 17 | display: block; 18 | border-radius: 50%; 19 | } 20 | 21 | .header { 22 | min-width: 35%; 23 | text-align: left; 24 | } 25 | 26 | .select-text, .datetime-text { 27 | line-height: 1.2!important; 28 | min-height: 1.2em!important; 29 | height: 20px !important; 30 | } 31 | ion-input, ion-datetime{ 32 | font-size: 14px; 33 | color: grey; 34 | } 35 | ion-select{ 36 | font-size: 14px; 37 | color: grey; 38 | } 39 | .up-btn{ 40 | position: absolute; 41 | left: calc(35%); 42 | } 43 | 44 | .col { 45 | padding: 0; 46 | } 47 | 48 | .column { 49 | max-width: 10% !important; 50 | } 51 | 52 | ion-icon { 53 | align-self: center !important; 54 | margin-left: 10%; 55 | line-height: 100%; 56 | vertical-align: middle; 57 | display: flex !important; 58 | } 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/components/canvas-draw/canvas-draw.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/pages/requests/requests.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Recommended Tutors 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | No recommended tutors around you at the moment 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Recommended for you 30 | 31 | 32 | 33 | 34 |
35 |
36 | {{tutor.name}} 37 |

{{tutor.institution}}

38 |

{{tutor.subjects.join(', ')}}

39 | 40 | {{tutor.likes}} 41 |
42 |
43 |
44 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'), 2 | http = require('http'); 3 | var app = express(); 4 | var server = http.createServer(app); 5 | var io = require('socket.io').listen(server); 6 | var _ = require('lodash'); 7 | var ExpressPeerServer = require('peer').ExpressPeerServer; 8 | 9 | var options = { 10 | debug: true 11 | } 12 | 13 | var peerServer = require('http').createServer(app); 14 | app.use('/peerjs', ExpressPeerServer(server, options)); 15 | peerServer.listen(9000); 16 | 17 | server.listen(3000); 18 | app.use(express.static(__dirname + '/public')) 19 | console.log("Server running on 127.0.0.1:3000"); 20 | var boards = ['same_board'] 21 | var line_history = []; 22 | var userids = []; 23 | 24 | io.on('connection', socket => { 25 | socket.on('adduser', user => { 26 | if(boards.indexOf(user.boardid) == -1) { 27 | boards.push(user.boardid); 28 | } 29 | socket.username = user.username; 30 | console.log(`${user.username} has connected to this room`) 31 | socket.room = user.boardid; 32 | socket.join(user.boardid); 33 | socket.emit('updateboard','SERVER', `you have connected to ${user.boardid}`); 34 | socket.broadcast.to(user.boardid).emit('updateboard','SERVER', `${user.username} has connected to this room`); 35 | socket.emit('updateboards', boards, user.boardid) 36 | }) 37 | 38 | socket.on('disconnect', ()=> { 39 | socket.leave(socket.room); 40 | }) 41 | for(var i in line_history) { 42 | socket.emit('draw_line', {line: line_history[i]}); 43 | } 44 | 45 | socket.on('draw_line', data => { 46 | line_history.push(data.line); 47 | io.sockets.in(socket.room).emit('draw_line', {line: data.line}) 48 | }) 49 | }) -------------------------------------------------------------------------------- /src/app/services/appointment-data/appointment-data.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | 4 | @Injectable() 5 | export class AppointmentAccess { 6 | constructor () {} 7 | 8 | getAppointments() { 9 | var appointments = `{ 10 | "subject": "Physics", 11 | "type": "contact", 12 | "duration": "25 minutes", 13 | "module": "Electromagnetism", 14 | "date": "Tuesday, Jun 20", 15 | "price": "R100", 16 | "tutorid": "123albert" 17 | }, 18 | { 19 | "subject": "Mathematics", 20 | "type": "contacts", 21 | "duration": "1 hour", 22 | "module": "Double Integration", 23 | "date": "Saturday, Jul 29", 24 | "price": "R250", 25 | "tutorid": "123isaac" 26 | }, 27 | { 28 | "subject": "Geology", 29 | "type": "contact", 30 | "duration": "1 hour", 31 | "module": "The Rock Cycle", 32 | "date": "Thursday, Jun 29", 33 | "price": "R250", 34 | "tutorid": "123ricardo" 35 | }` 36 | var data = JSON.parse(`{"appointments": [${appointments}] 37 | }`) 38 | return data.appointments; 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /src/pages/myclasses/myclasses.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | import { DrawPage } from '../draw/draw' 4 | 5 | import * as firebase from 'firebase/app'; 6 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'; 7 | import { Observable } from 'rxjs/Observable'; 8 | import { LessonsProvider } from '../../providers/lessons/lessons' 9 | 10 | /** 11 | * Generated class for the MyclassesPage page. 12 | * 13 | * See http://ionicframework.com/docs/components/#navigation for more info 14 | * on Ionic pages and navigation. 15 | */ 16 | 17 | @Component({ 18 | selector: 'page-myclasses', 19 | templateUrl: 'myclasses.html', 20 | }) 21 | export class MyclassesPage { 22 | my: string = "scheduled"; 23 | private user; 24 | private lessons_pending: FirebaseListObservable; 25 | private lessons_upcoming: FirebaseListObservable; 26 | private lessons_history: FirebaseListObservable; 27 | private drawPage; 28 | 29 | constructor(public navCtrl: NavController, public navParams: NavParams, 30 | private af: AngularFireDatabase, private lessonsProvider: LessonsProvider) { 31 | this.user = navParams.get('user'); 32 | this.drawPage = DrawPage; 33 | const type = 'learner' 34 | this.lessons_upcoming = lessonsProvider.getUpcomingLessons(this.user, type) 35 | this.lessons_history = lessonsProvider.getLessonHistory(this.user, type) 36 | this.lessons_pending = lessonsProvider.getPendingLessons(this.user, type) 37 | } 38 | 39 | ionViewDidLoad() { 40 | console.log('ionViewDidLoad MyclassesPage'); 41 | } 42 | 43 | openPage(p, lesson, start) { 44 | this.navCtrl.push(p, {user: this.user, target: lesson.tutorid, start: start, type:'learner', object: lesson}); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Enlighten 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/app/app.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/theming/ 2 | 3 | 4 | // App Global Sass 5 | // -------------------------------------------------- 6 | // Put style rules here that you want to apply globally. These 7 | // styles are for the entire app and not just one component. 8 | // Additionally, this file can be also used as an entry point 9 | // to import other Sass files to be included in the output CSS. 10 | // 11 | // Shared Sass variables, which can be used to adjust Ionic's 12 | // default Sass variables, belong in "theme/variables.scss". 13 | // 14 | // To declare rules for a specific mode, create a child rule 15 | // for the .md, .ios, or .wp mode classes. The mode class is 16 | // automatically applied to the element in the app. 17 | 18 | //material design 19 | .toolbar-content-md, .toolbar-md { 20 | background: #993333; 21 | 22 | } 23 | 24 | .respect { 25 | min-height: auto; 26 | } 27 | 28 | .toolbar-background-md { 29 | display: none; 30 | } 31 | 32 | .toolbar-md { 33 | padding: 0; 34 | } 35 | 36 | .dark, .dark button { 37 | background-color: #333; 38 | color: #ddd 39 | } 40 | 41 | .dark button:hover { 42 | background-color: #444; 43 | } 44 | .dark button:active { 45 | background-color: #474747; 46 | } 47 | 48 | .list-md .item-block .item-inner { 49 | border-color: #444; 50 | } 51 | 52 | .list-md .item-block.classes .item-inner { 53 | border-color: #ddd; 54 | } 55 | 56 | .grey { 57 | background-color: #ddd; 58 | } 59 | 60 | .no-scroll { 61 | scroll-content { 62 | overflow: hidden; 63 | } 64 | } 65 | 66 | .scroll { 67 | scroll-content { 68 | overflow-y: scroll; 69 | } 70 | } -------------------------------------------------------------------------------- /src/pages/userselection/userselection.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | import { RegisterPage } from '../register/register'; 4 | import { TutorregisterPage } from '../tutorregister/tutorregister'; 5 | import { ParentregisterPage } from '../parentregister/parentregister'; 6 | import { MyApp } from '../../app/app.component'; 7 | import { Events } from 'ionic-angular'; 8 | import { SignupPage } from '../signup/signup'; 9 | import { NativeStorage } from '@ionic-native/native-storage'; 10 | /** 11 | * Generated class for the UserselectionPage page. 12 | * 13 | * See http://ionicframework.com/docs/components/#navigation for more info 14 | * on Ionic pages and navigation. 15 | */ 16 | 17 | @Component({ 18 | selector: 'page-userselection', 19 | templateUrl: 'userselection.html', 20 | }) 21 | export class UserselectionPage { 22 | public type: string = "typing"; 23 | private displayName: string; 24 | private myApp; 25 | constructor(public navCtrl: NavController, public navParams: NavParams,public events: Events,private nativeStorage: NativeStorage) { 26 | this.type = ''; 27 | this.displayName = "N Nkuna" 28 | } 29 | 30 | ionViewDidLoad() { 31 | console.log('ionViewDidLoad UserselectionPage'); 32 | } 33 | 34 | registerPage(type) { 35 | this.type = type; 36 | this.nativeStorage.setItem('usertype', {type: type}) 37 | this.events.publish('globals:update', type, this.displayName); 38 | switch (type) { 39 | case "student": 40 | this.navCtrl.push(SignupPage, {type: type}); 41 | break; 42 | case "tutor": 43 | this.navCtrl.push(TutorregisterPage, {type: type}); 44 | break; 45 | case "parent": 46 | this.navCtrl.push(ParentregisterPage, {type: type}); 47 | break; 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/pages/tutors/tutors.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams, AlertController } from 'ionic-angular'; 3 | import { TutorAccess } from '../../app/services/tutor-data/tutor.data'; 4 | 5 | import * as firebase from 'firebase/app'; 6 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'; 7 | import { AngularFireAuth } from 'angularfire2/auth'; 8 | import { Observable } from 'rxjs/Observable'; 9 | /** 10 | * Generated class for the TutorsPage page. 11 | * 12 | * See http://ionicframework.com/docs/components/#navigation for more info 13 | * on Ionic pages and navigation. 14 | */ 15 | 16 | @Component({ 17 | selector: 'page-tutors', 18 | templateUrl: 'tutors.html', 19 | }) 20 | export class TutorsPage { 21 | tutors: TutorAccess[]; 22 | private ftutors: FirebaseListObservable; 23 | len: number = 0; 24 | name:string = ""; 25 | constructor(public navCtrl: NavController, public navParams: NavParams, private tutorAccess: TutorAccess, 26 | private af: AngularFireDatabase, public alertCtrl: AlertController) { 27 | this.tutors = this.tutorAccess.getTutors(); 28 | this.ftutors = af.list(`/users_tutors`); 29 | } 30 | 31 | ionViewDidLoad() { 32 | console.log('ionViewDidLoad TutorsPage'); 33 | } 34 | 35 | request(){ 36 | //Send Request 37 | this.showAlert(); 38 | } 39 | 40 | next(){ 41 | if(this.len < this.tutors.length - 1){ 42 | this.len++; 43 | } 44 | else{ 45 | this.len = 0; 46 | } 47 | } 48 | 49 | prev(){ 50 | if(this.len > 0){ 51 | this.len--; 52 | } 53 | else{ 54 | this.len = this.tutors.length - 1; 55 | } 56 | } 57 | showAlert() { 58 | let alert = this.alertCtrl.create({ 59 | title: 'Request Sent!', 60 | buttons: ['OK'] 61 | }); 62 | alert.present(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/pages/appointments/appointments.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Appointments 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | {{appointment.title}} 22 | 23 | 24 | 25 | 26 | 27 |

{{appointment.duration}}

28 |

{{appointment.subtitle}}

29 |
30 | 31 |

{{appointment.price}}

32 |
33 | 34 | 35 |

{{appointment.start | date:'MMM dd, yyyy HH:mm'}}

36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | {{appointment.learnername}} 44 |

{{appointment.institution}}

45 |

{{appointment.type}}

46 | 47 |
48 | 49 |
50 |
51 | -------------------------------------------------------------------------------- /google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "745996686081", 4 | "firebase_url": "https://enlighten-175514.firebaseio.com", 5 | "project_id": "enlighten-175514", 6 | "storage_bucket": "enlighten-175514.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:745996686081:android:b88c7b80fc5c3028", 12 | "android_client_info": { 13 | "package_name": "com.enlighten.app" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "745996686081-m7ennpb44vmeu5dpt6c4ha85j9dvbh9a.apps.googleusercontent.com", 19 | "client_type": 3 20 | }, 21 | { 22 | "client_id": "745996686081-40ar6il00j6dv417gjguco5d8p9t6bjg.apps.googleusercontent.com", 23 | "client_type": 1, 24 | "android_info": { 25 | "package_name": "com.enlighten.app", 26 | "certificate_hash": "4be537828228b45a76323ac0b78413a75188c94e" 27 | } 28 | }, 29 | { 30 | "client_id": "745996686081-ta15tog2jhd7v3832l95874i2ng8c3m6.apps.googleusercontent.com", 31 | "client_type": 3 32 | } 33 | ], 34 | "api_key": [ 35 | { 36 | "current_key": "AIzaSyCovxe0MuxtqQnGcaZ-bCmXOMH7haPM0ZA" 37 | } 38 | ], 39 | "services": { 40 | "analytics_service": { 41 | "status": 1 42 | }, 43 | "appinvite_service": { 44 | "status": 2, 45 | "other_platform_oauth_client": [ 46 | { 47 | "client_id": "745996686081-m7ennpb44vmeu5dpt6c4ha85j9dvbh9a.apps.googleusercontent.com", 48 | "client_type": 3 49 | } 50 | ] 51 | }, 52 | "ads_service": { 53 | "status": 2 54 | } 55 | } 56 | } 57 | ], 58 | "configuration_version": "1" 59 | } -------------------------------------------------------------------------------- /src/app/services/institutions/institutions.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | 4 | @Injectable() 5 | export class InstitutionsAccess { 6 | institutions = [ 7 | { 8 | name: 'SARAO', 9 | founded: 'unknown', 10 | info: '' 11 | }, 12 | { 13 | name: 'Just Grace', 14 | founded: 'unknown', 15 | info: '' 16 | }, 17 | { 18 | name: 'Emagqabini Education Academy', 19 | founded: 'unknown', 20 | info: '' 21 | }, 22 | { 23 | "name": "University of Cape Town", 24 | "founded": "1829", 25 | "info": "assets/img/avatar-albert.jpg" 26 | }, 27 | { 28 | "name": "University of Pretoria", 29 | "founded": "1829", 30 | "info": "assets/img/avatar-albert.jpg" 31 | }, 32 | { 33 | "name": "Stellenbosch University", 34 | "founded": "1829", 35 | "info": "assets/img/avatar-albert.jpg" 36 | },{ 37 | "name": "University of Witwatersrand", 38 | "founded": "1829", 39 | "info": "assets/img/avatar-albert.jpg" 40 | },{ 41 | "name": "University of Johannesburg", 42 | "founded": "1829", 43 | "info": "assets/img/avatar-albert.jpg" 44 | },{ 45 | "name": "Cape Peninsula University of Technology", 46 | "founded": "1829", 47 | "info": "assets/img/avatar-albert.jpg" 48 | } 49 | ] 50 | constructor () {} 51 | 52 | getUniversities() { 53 | var data = JSON.parse(`{"tutors": ${JSON.stringify(this.institutions)}}`) 54 | return data.tutors; 55 | } 56 | 57 | getUniversity(id) { 58 | var result = this.institutions.filter(function( obj ) { 59 | return obj.name == id; 60 | }); 61 | return result; 62 | } 63 | } -------------------------------------------------------------------------------- /src/app/services/tutor-data/tutor.data.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | 4 | @Injectable() 5 | export class TutorAccess { 6 | tutors = [{ 7 | "name": "Albert Einstein", 8 | "likes": "100", 9 | "image": "assets/img/avatar-albert.jpg", 10 | "institution": "University of Zürich", 11 | "subjects": ["Mathematics","Physics"], 12 | "status": "online", 13 | "tutorid": "123albert" 14 | }, 15 | { 16 | "name": "Isaac Newton", 17 | "likes": "981", 18 | "image": "assets/img/isaac.jpg", 19 | "institution": "Trinity College, Cambridge", 20 | "subjects": ["Mathematics","Physics"], 21 | "status": "offline", 22 | "tutorid": "123isaac" 23 | }, 24 | { 25 | "name": "Pierre-Simon Laplace", 26 | "likes": "11", 27 | "image": "assets/img/man.png", 28 | "institution": "University of Caen Normandy", 29 | "subjects": ["Mathematics","Geology"], 30 | "status": "away", 31 | "tutorid": "123ricardo" 32 | }] 33 | constructor () {} 34 | 35 | getTutors() { 36 | 37 | var data = JSON.parse(`{"tutors": ${JSON.stringify(this.tutors)} 38 | }`) 39 | return data.tutors; 40 | 41 | } 42 | 43 | getTutor(id) { 44 | var result = this.tutors.filter(function( obj ) { 45 | return obj.tutorid == id; 46 | }); 47 | return result; 48 | } 49 | } -------------------------------------------------------------------------------- /src/pages/draw/draw.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | Draw 10 | 11 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 |

Waiting for user to enter session

39 |
40 | 41 |
42 |
43 | 44 |
45 |
46 |
-------------------------------------------------------------------------------- /src/components/calendar/calendar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
{{monthHead[displayMonth]}} {{displayYear}}
9 |
10 | 11 | 12 | 13 |
14 | 15 | 16 | {{head}} 17 | 18 | 19 | 20 | 21 | {{day.date}} 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | {{event.val.start | date:'HH:mm'}}
{{event.val.end | date:'HH:mm'}} 31 |
32 | 33 |
34 | {{event.val.title}} 35 |
36 | 37 | 38 | 39 | 40 | 43 |
44 |
45 | 46 |
-------------------------------------------------------------------------------- /src/pages/createclass/createclass.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | import { SubjectsAccess } from '../../app/services/subjects/subjects'; 4 | import { Calendar } from '@ionic-native/calendar'; 5 | 6 | /** 7 | * Generated class for the CreateclassPage page. 8 | * 9 | * See http://ionicframework.com/docs/components/#navigation for more info 10 | * on Ionic pages and navigation. 11 | */ 12 | 13 | @Component({ 14 | selector: 'page-createclass', 15 | templateUrl: 'createclass.html', 16 | }) 17 | export class CreateclassPage { 18 | private subjects; 19 | private tzoffset; //offset in milliseconds 20 | myDate: String = new Date().toISOString() 21 | constructor(public navCtrl: NavController, public navParams: NavParams, 22 | private subjectsAccess: SubjectsAccess, 23 | private calendar: Calendar) { 24 | this.subjects = this.subjectsAccess.getSubjects(); 25 | var date = new Date(); 26 | this.tzoffset = date.getTimezoneOffset() * 60000; 27 | this.myDate = (new Date(Date.now() - this.tzoffset)).toISOString().slice(0,-1); 28 | } 29 | 30 | ionViewDidLoad() { 31 | console.log('ionViewDidLoad CreateclassPage'); 32 | } 33 | 34 | yyyymmdd(date) { 35 | var mm = date.getMonth() + 1; // getMonth() is zero-based 36 | var dd = date.getDate(); 37 | 38 | return [date.getFullYear(), 39 | (mm>9 ? '' : '0') + mm, 40 | (dd>9 ? '' : '0') + dd 41 | ].join(''); 42 | }; 43 | 44 | createClass(date,duration,grd,sbj) { 45 | var startDate = new Date(Date.parse(date)); 46 | var endNum = parseInt(Date.parse(date).toString()) + parseInt(duration)*60000; 47 | var endDate = new Date(endNum); 48 | var title = `Grade ${grd} ${sbj}`; 49 | var eventLocation = "Enlighten App: Class"; 50 | var notes = `class`; 51 | 52 | this.calendar.createEvent(title,eventLocation,notes,startDate,endDate).then(result => { 53 | //alert(result) 54 | }).catch(err => { 55 | alert(err) 56 | }); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/pages/tutorschedule/tutorschedule.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | My Schedule 10 | 11 | 12 | 13 | 14 | 15 |

My weekly schedule

16 | 17 | 18 | 19 | 20 | Time 21 | 22 | 23 | 24 | Duration 25 | 26 | 15 minutes 27 | 30 minutes 28 | 45 minutes 29 | 60 minutes 30 | 90 minutes 31 | 120 minutes 32 | 33 | 34 | 35 | Repeat weekly 36 | 37 | 38 | 39 | 40 |
41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/app/services/users/allusers.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { userAccess } from "./users" 3 | 4 | 5 | @Injectable() 6 | export class allUsers { 7 | private allusers: string[] =[]; 8 | private alluserInfo: any[]; 9 | public loggedIn: string[] = ["0","1","2","3","4","5","6","7"]; 10 | private reg: boolean = false; 11 | private log: boolean = false; 12 | 13 | add(accNo: string, info: string[]){ 14 | this.alreadyReg(accNo); 15 | if (!this.reg){ 16 | localStorage.setItem(accNo, JSON.stringify(info)); 17 | this.allusers.push(accNo); 18 | this.loggedIn = info; 19 | return true; 20 | } 21 | else{ 22 | this.reg = false; 23 | return false; 24 | } 25 | 26 | } 27 | update(accNo: string, info: string[]){ 28 | for (let a in allUsers){ 29 | if(a == accNo){ 30 | localStorage.setItem(accNo, JSON.stringify(info)); 31 | this.loggedIn = info; 32 | } 33 | } 34 | } 35 | loginCheck(accNo: string, pw: string){ 36 | for (let a in allUsers){ 37 | if(a == accNo){ 38 | let check: any = localStorage.getItem(accNo); 39 | let i: string[] = check ? JSON.parse(check): []; 40 | if(i[1] == pw){ 41 | this.log = true; 42 | this.loggedIn = i; 43 | } 44 | else{ 45 | this.log = false; 46 | } 47 | } 48 | } 49 | if(this.log){ 50 | this.log = false; 51 | return true; 52 | } 53 | else{ 54 | return false; 55 | } 56 | } 57 | private alreadyReg(num:string){ 58 | for (let a in allUsers){ 59 | if(a == num){ 60 | this.reg = true; 61 | } 62 | } 63 | 64 | } 65 | logout(){ 66 | this.reg = false; 67 | this.log = false; 68 | this.loggedIn = []; 69 | } 70 | } -------------------------------------------------------------------------------- /src/pages/tutorclasses/tutorclasses.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core' 2 | import { NavController, NavParams } from 'ionic-angular' 3 | import { DrawPage } from '../draw/draw' 4 | 5 | import * as firebase from 'firebase/app' 6 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database' 7 | import { Observable } from 'rxjs/Observable' 8 | import { LessonsProvider } from '../../providers/lessons/lessons' 9 | 10 | /** 11 | * Generated class for the TutorclassesPage page. 12 | * 13 | * See http://ionicframework.com/docs/components/#navigation for more info 14 | * on Ionic pages and navigation. 15 | */ 16 | 17 | @Component({ 18 | selector: 'page-tutorclasses', 19 | templateUrl: 'tutorclasses.html', 20 | }) 21 | export class TutorclassesPage { 22 | my: string = "pending" 23 | private user 24 | private lessons_pending: FirebaseListObservable 25 | private lessons_upcoming: FirebaseListObservable 26 | private lessons_history: FirebaseListObservable 27 | private drawPage 28 | constructor(public navCtrl: NavController, public navParams: NavParams, 29 | private af: AngularFireDatabase, private lessonsProvider: LessonsProvider) { 30 | this.drawPage = DrawPage 31 | this.user = navParams.get('user') 32 | const type = 'tutor' 33 | this.lessons_pending = lessonsProvider.getPendingLessons(this.user, type) 34 | this.lessons_upcoming = lessonsProvider.getUpcomingLessons(this.user, type) 35 | this.lessons_history = lessonsProvider.getLessonHistory(this.user, type) 36 | } 37 | 38 | ionViewDidLoad () { 39 | console.log('ionViewDidLoad TutorclassesPage') 40 | } 41 | 42 | openPage (p, lesson, start) { 43 | this.navCtrl.push(p, {user: this.user, target: lesson.learnerid, start: start, type:'tutor', object: lesson}); 44 | } 45 | 46 | name (type) { 47 | if (type == 'group') { 48 | return 'contacts' 49 | } else { 50 | return 'person' 51 | } 52 | } 53 | 54 | acceptLesson (lessonid, learnerid) { 55 | this.lessonsProvider.acceptLesson(lessonid, learnerid, this.user) 56 | this.my = 'upcoming' 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/pages/videocall/videocall.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | Call Demo - {{myId}} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Call ID: 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |

Remote Stream

48 | 49 |
50 |
51 |
52 | 53 | 54 | 55 |

My Stream

56 | 57 |
58 |
59 |
60 |
61 |
62 | -------------------------------------------------------------------------------- /src/pages/signup/signup.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | Register 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |

Enlighten requires the use of a Google Account

18 | 19 | 20 | 21 |

Creating a google account is easy!

22 |

Step 1: Visit https://gmail.com

23 |

Step 2: Click "More Options" and select create account

24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 |
37 |

Google Account cont.

38 | 39 | 40 | 41 |

Step 3: Fill in all your details and click continue. Keep your username and password saved somewhere.

42 |

Step 4: Follow the rest of the steps and you're all set! You can now create an Enlighten account with your Google Account!

43 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
53 |
54 | -------------------------------------------------------------------------------- /src/pages/home/home.scss: -------------------------------------------------------------------------------- 1 | page-home { 2 | .vertical-align-content > * { 3 | display: flex!important; 4 | align-content: center!important; 5 | align-items: center!important; 6 | .readjust { 7 | margin-top: -60px; 8 | font-size: 20px; 9 | font-weight: 400; 10 | line-height: 1.5em; 11 | color: #676767; 12 | } 13 | } 14 | .stricken { 15 | text-decoration: line-through; 16 | } 17 | .scroll-bar-indicator 18 | { 19 | display: none; 20 | } 21 | 22 | .avatar { 23 | position: relative; 24 | } 25 | 26 | .has-header { 27 | padding-bottom: 200px !important; 28 | } 29 | 30 | .status { 31 | position: absolute; 32 | right: 0; 33 | bottom: -7.5%; 34 | border: 2px solid white; 35 | height: 15px; 36 | width: 15px; 37 | border-radius: 50%; 38 | } 39 | .status.online { 40 | background-color: green; 41 | } 42 | .status.away { 43 | background-color: orange; 44 | } 45 | .status.offline { 46 | background-color: red; 47 | } 48 | 49 | em{ 50 | color: #f8d64e; 51 | } 52 | 53 | ion-slide h2 { 54 | font-size: 1.8em; 55 | font-weight: normal; 56 | 57 | em{ 58 | font-weight: bold; 59 | color: black; 60 | } 61 | } 62 | 63 | ion-slide img { 64 | width: 100% !important; 65 | display: block; 66 | 67 | object-fit: contain; 68 | } 69 | 70 | ion-slide img.girl { 71 | position: absolute; 72 | bottom: -10%; 73 | left: -7.5%; 74 | width: 40% !important; 75 | z-index: -1; 76 | } 77 | 78 | .pending { 79 | position: fixed; 80 | width: 80%; 81 | bottom: 0%; 82 | left: 10%; 83 | padding: 2%; 84 | border-radius: 7.5px; 85 | border-bottom-left-radius: 0; 86 | border-bottom-right-radius: 0; 87 | color: #eee; 88 | background: #333; 89 | } 90 | .item-md.item-block .item-inner { 91 | border-bottom: none; 92 | } 93 | } -------------------------------------------------------------------------------- /src/pages/login/login.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 41 | 42 |

Forgot your password? Reset password

43 | 44 | 45 |

or sign in with

46 | 47 | 48 | 52 | 53 | 54 | 55 | 59 | 60 | 61 |
62 |
63 |
64 | -------------------------------------------------------------------------------- /src/pages/lesson/lesson.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | Lesson 10 | 11 | 12 | 13 | 14 |

YOUR LESSON IS ABOUT TO BEGIN

15 | 16 | 17 | 18 | 19 |

{{start | date:'HH:mm'}}

20 | 21 |

MATHEMATICS

22 |

with

23 | 24 | 25 | 26 | 27 | 28 | {{lesson.learnername}} 29 |

{{lesson.school}}

30 |

{{lesson.subjects.join(', ')}}

31 |
32 |
33 | 34 | 35 | 36 | 37 | 38 | {{lesson.tutorname}} 39 |

{{lesson.institution}}

40 |

{{lesson.subjects.join(', ')}}

41 |
42 |
43 | 44 | 47 |

Please wait for your tutor to create a board...

48 |
49 | 52 | 53 |
54 | 55 |
56 | -------------------------------------------------------------------------------- /src/pages/register/register.scss: -------------------------------------------------------------------------------- 1 | page-register { 2 | ion-content { 3 | text-align: center; 4 | 5 | h2 { 6 | font-family: 'Roboto', sans-serif; 7 | font-weight: lighter; 8 | } 9 | 10 | img { 11 | height: 80px; 12 | width: auto; 13 | margin: auto; 14 | display: block; 15 | border-radius: 50%; 16 | } 17 | 18 | ion-input { 19 | font-size: 14px; 20 | color: grey; 21 | } 22 | 23 | ion-select { 24 | font-size: 14px; 25 | color: grey; 26 | } 27 | 28 | .reduce { 29 | width: 60%; 30 | } 31 | 32 | .text { 33 | text-align: center; 34 | width: 95%; 35 | font-size: 14px; 36 | } 37 | 38 | .col { 39 | padding: 0; 40 | } 41 | 42 | .sign { 43 | margin-top: 5%; 44 | width: 100%; 45 | } 46 | 47 | .searchbar-input { 48 | font-size: 1.375rem !important; 49 | } 50 | 51 | ion-col { 52 | 53 | &:nth-of-type(1) { 54 | .btn { 55 | margin-right: 5%; 56 | } 57 | } 58 | 59 | &:nth-of-type(2) { 60 | .btn { 61 | margin-left: 5%; 62 | } 63 | } 64 | } 65 | 66 | .btn { 67 | position:relative; 68 | width: 95%; 69 | font-weight: normal; 70 | margin: 0; 71 | box-shadow: none; 72 | text-transform: capitalize !important; 73 | } 74 | 75 | .school { 76 | 77 | .label-md { 78 | margin-top: 0; 79 | margin-bottom: 0; 80 | } 81 | 82 | .list { 83 | color: #999; 84 | font-size: 1.25rem; 85 | } 86 | } 87 | 88 | .searchbar-input { 89 | padding-left: 0!important; 90 | } 91 | 92 | .searchbar-search-icon { 93 | display: none !important; 94 | } 95 | 96 | span.hint { 97 | padding: 4px 16px; 98 | color: color($colors, danger); 99 | font-size: 1rem; 100 | width: 100%; 101 | text-align: left; 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /test-config/mocks-ionic.ts: -------------------------------------------------------------------------------- 1 | import { StatusBar } from '@ionic-native/status-bar'; 2 | import { SplashScreen } from '@ionic-native/splash-screen'; 3 | 4 | export class PlatformMock { 5 | public ready(): Promise { 6 | return new Promise((resolve) => { 7 | resolve('READY'); 8 | }); 9 | } 10 | 11 | public getQueryParam() { 12 | return true; 13 | } 14 | 15 | public registerBackButtonAction(fn: Function, priority?: number): Function { 16 | return (() => true); 17 | } 18 | 19 | public hasFocus(ele: HTMLElement): boolean { 20 | return true; 21 | } 22 | 23 | public doc(): HTMLDocument { 24 | return document; 25 | } 26 | 27 | public is(): boolean { 28 | return true; 29 | } 30 | 31 | public getElementComputedStyle(container: any): any { 32 | return { 33 | paddingLeft: '10', 34 | paddingTop: '10', 35 | paddingRight: '10', 36 | paddingBottom: '10', 37 | }; 38 | } 39 | 40 | public onResize(callback: any) { 41 | return callback; 42 | } 43 | 44 | public registerListener(ele: any, eventName: string, callback: any): Function { 45 | return (() => true); 46 | } 47 | 48 | public win(): Window { 49 | return window; 50 | } 51 | 52 | public raf(callback: any): number { 53 | return 1; 54 | } 55 | 56 | public timeout(callback: any, timer: number): any { 57 | return setTimeout(callback, timer); 58 | } 59 | 60 | public cancelTimeout(id: any) { 61 | // do nothing 62 | } 63 | 64 | public getActiveElement(): any { 65 | return document['activeElement']; 66 | } 67 | } 68 | 69 | export class StatusBarMock extends StatusBar { 70 | styleDefault() { 71 | return; 72 | } 73 | } 74 | 75 | export class SplashScreenMock extends SplashScreen { 76 | hide() { 77 | return; 78 | } 79 | } 80 | 81 | export class NavMock { 82 | 83 | public pop(): any { 84 | return new Promise(function(resolve: Function): void { 85 | resolve(); 86 | }); 87 | } 88 | 89 | public push(): any { 90 | return new Promise(function(resolve: Function): void { 91 | resolve(); 92 | }); 93 | } 94 | 95 | public getActive(): any { 96 | return { 97 | 'instance': { 98 | 'model': 'something', 99 | }, 100 | }; 101 | } 102 | 103 | public setRoot(): any { 104 | return true; 105 | } 106 | 107 | public registerChildNav(nav: any): void { 108 | return ; 109 | } 110 | 111 | } 112 | 113 | export class DeepLinkerMock { 114 | 115 | } -------------------------------------------------------------------------------- /src/pages/logout/logout.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, TestBed} from '@angular/core/testing'; 2 | import {DebugElement} from '@angular/core'; 3 | import { By } from '@angular/platform-browser'; 4 | //depencies part of framework 5 | import { MenuController,NavController, NavParams , Events, IonicModule} from 'ionic-angular'; 6 | //unit under test 7 | import {LogoutPage} from './logout.ts' 8 | //dependencies also being developed and requiring mocking 9 | import { UserselectionPage } from '../userselection/userselection';//to be mocked by 10 | import { UserselectionPageMock } from '../../../testing/page-mocks.js'; 11 | import { LoginPage } from '../login/login';//to be mocked by 12 | import { LoginPageMock } from '../../../testing/page-mocks.js'; 13 | 14 | describe('The logout page (home page) shall', () => { 15 | let fixture; 16 | let component; 17 | let loginButton: DebugElement; 18 | let registerButton: DebugElement; 19 | let NavControllerSpy; 20 | // setup 21 | beforeEach(async(() => { 22 | NavControllerSpy = jasmine.createSpyObj("NavController",["push"]); 23 | TestBed.configureTestingModule({ 24 | declarations: [LogoutPage], 25 | imports: [ 26 | IonicModule.forRoot(LogoutPage) 27 | ], 28 | providers:[ 29 | Events,//stable dependencies 30 | //dependecies requiring mocking/spying 31 | {provide: NavController, useValue: NavControllerSpy }, 32 | {provide: NavParams, useClass: class { NavParamsSpy = jasmine.createSpy("NavParams"); } }, 33 | //non stable dependencies 34 | {provide: UserselectionPage, useClass: UserselectionPageMock}, 35 | {provide: LoginPage, useClass: LoginPageMock} 36 | ] 37 | }); 38 | })); 39 | 40 | beforeEach(() => { 41 | fixture = TestBed.createComponent(LogoutPage); 42 | component = fixture.componentInstance; 43 | loginButton = fixture.debugElement.queryAll(By.css('button'))[0]; 44 | registerButton =fixture.debugElement.queryAll(By.css('button'))[1]; 45 | }); 46 | 47 | //specs 48 | 49 | it('be created successfully', () => { 50 | expect(component instanceof LogoutPage).toBe(true); 51 | }); 52 | 53 | it('navigate to login page when user click login',() => { 54 | loginButton.triggerEventHandler('click', null); 55 | expect(NavControllerSpy.push.calls.first().args[0]).toBe(LoginPage); 56 | }); 57 | 58 | it('navigate to UserselectionPage when user click register',() => { 59 | registerButton.triggerEventHandler('click', null); 60 | expect(NavControllerSpy.push.calls.first().args[0]).toBe(UserselectionPage); 61 | }); 62 | 63 | }); 64 | -------------------------------------------------------------------------------- /src/pages/lesson/lesson.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewChild } from '@angular/core' 2 | import { NavController, NavParams, Navbar } from 'ionic-angular' 3 | import { TutorAccess } from '../../app/services/tutor-data/tutor.data' 4 | import { DrawPage } from '../draw/draw' 5 | import * as firebase from 'firebase/app' 6 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database' 7 | 8 | /** 9 | * Generated class for the LessonPage page. 10 | * 11 | * See http://ionicframework.com/docs/components/#navigation for more info 12 | * on Ionic pages and navigation. 13 | */ 14 | 15 | @Component({ 16 | selector: 'page-lesson', 17 | templateUrl: 'lesson.html', 18 | }) 19 | export class LessonPage { 20 | @ViewChild (Navbar) navBar : Navbar 21 | 22 | lessons: FirebaseListObservable 23 | len: number = 0 24 | private currentBoard: FirebaseListObservable 25 | private user 26 | private target 27 | private start 28 | private drawPage 29 | private object 30 | private type:string 31 | private boardid: string ='' 32 | 33 | constructor (public navCtrl: NavController, public navParams: NavParams, 34 | private af: AngularFireDatabase, private tutorAccess: TutorAccess) { 35 | if (navParams.get('user') != null && navParams.get('user') != undefined) { 36 | this.user = navParams.get('user') 37 | this.target = navParams.get('target') 38 | this.start = navParams.get('start') 39 | this.type = navParams.get('type') 40 | this.object = navParams.get('object') 41 | let env = this 42 | this.currentBoard = af.list(`users_boards_using/${this.user.uid}/`, {query: {limitToFirst: 1}}) 43 | 44 | firebase.database().ref(`users_boards_using/${this.user.uid}/`).on('value', snapshot => { 45 | if (snapshot.val()) { 46 | env.boardid = snapshot.val().boardid 47 | } 48 | }) 49 | 50 | if (this.type === 'learner') { 51 | this.lessons = af.list(`/lessons_upcoming_now_learners/${this.user.uid}`, {query: {limitToFirst: 1}}) 52 | } else { 53 | this.lessons = af.list(`/lessons_upcoming_now_tutors/${this.user.uid}`, {query: {limitToFirst: 1}}) 54 | } 55 | } 56 | 57 | this.drawPage = DrawPage 58 | } 59 | 60 | ionViewDidLoad() { 61 | console.log('ionViewDidLoad LessonPage') 62 | 63 | this.navBar.backButtonClick = (e:UIEvent) => { 64 | e.preventDefault() 65 | this.navCtrl.pop() 66 | } 67 | } 68 | 69 | openPage(p) { 70 | this.navCtrl.push(p, {user: this.user, target: this.target, object: this.object, type: this.type, boardid: this.boardid}) 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/pages/login/login.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core' 2 | 3 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database' 4 | import { AngularFireAuth } from 'angularfire2/auth' 5 | import { Observable } from 'rxjs/Observable' 6 | import * as firebase from 'firebase/app' 7 | 8 | import { NavController, NavParams, AlertController, MenuController, LoadingController, Platform, ToastController } from 'ionic-angular' 9 | import { HomePage } from '../home/home' 10 | import { TutorhomePage } from '../tutorhome/tutorhome' 11 | import { userAccess } from '../../app/services/users/users' 12 | import { Events } from 'ionic-angular' 13 | 14 | import { AuthProvider } from '../../providers/auth/auth' 15 | 16 | import 'rxjs/Rx' 17 | 18 | /** 19 | * Generated class for the LoginPage page. 20 | * 21 | * See http://ionicframework.com/docs/components/#navigation for more info 22 | * on Ionic pages and navigation. 23 | */ 24 | 25 | @Component({ 26 | selector: 'page-login', 27 | templateUrl: 'login.html', 28 | }) 29 | export class LoginPage { 30 | private currentUser 31 | private gUser 32 | private authState 33 | private user 34 | private email: string = '' 35 | private password: string = '' 36 | private password2: string = '' 37 | 38 | public cellNo: string 39 | public userData 40 | private pass: string 41 | private users 42 | private authSub: any; 43 | 44 | constructor(public navCtrl: NavController, private events: Events, private authProvider: AuthProvider) { // 45 | 46 | } 47 | 48 | ionViewDidLoad() { 49 | console.log('ionViewDidLoad LoginPage') 50 | } 51 | 52 | gg () { 53 | this.authProvider.googleLogin() 54 | } 55 | 56 | fb () { 57 | this.authProvider.facebookLogin() 58 | } 59 | 60 | signin () { 61 | this.authProvider.emailLogin(this.email, this.password) 62 | } 63 | 64 | subscribeToAuthState () { 65 | this.events.subscribe('globals:update', (user, type) => { 66 | this.user = user 67 | this.gUser = user 68 | this.proceedToRoot({}, type) 69 | }) 70 | } 71 | 72 | proceedToRoot(data, type) { 73 | if (type === 'tutor') { 74 | this.navCtrl.setRoot(TutorhomePage, { 75 | user: this.user, 76 | guser: this.gUser 77 | }) 78 | } else if (type === 'learner') { 79 | this.navCtrl.setRoot(HomePage, { 80 | user: this.user, 81 | guser: this.gUser, 82 | data: data 83 | }) 84 | } else if(type === 'parent') { 85 | this.navCtrl.setRoot(HomePage,{ 86 | user: this.user, 87 | guser: this.gUser, 88 | data: data 89 | }) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/pages/createclass/createclass.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | Create Lesson 10 | 11 | 12 | 13 | 14 | 15 |

Enter lesson details

16 | 17 | 18 | 19 | 20 | Subject 21 | 22 | {{subject.name}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | Grade 30 | 31 | Any 32 | 7 33 | 8 34 | 9 35 | 10 36 | 11 37 | 12 38 | 39 | 40 | 41 | 42 | 43 | 44 | Duration 45 | 46 | 15 minutes 47 | 30 minutes 48 | 45 minutes 49 | 60 minutes 50 | 90 minutes 51 | 120 minutes 52 | 53 | 54 | 55 | 56 | 57 | 58 | Date 59 | 60 | 61 | 62 | 63 | 64 | 67 |
68 | -------------------------------------------------------------------------------- /src/pages/messages/messages.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Book Tutor 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 |

Book a session

24 |
25 | 26 | {{session.start | tolocal}} 27 | Single lesson 28 | 29 | 32 | 33 | 34 |
35 |
36 |

No available sessions

37 |
38 | 58 | 59 | 60 |
61 | 62 | 70 | -------------------------------------------------------------------------------- /src/components/calendar/calendar.scss: -------------------------------------------------------------------------------- 1 | calendar { 2 | font-family: "Microsoft YaHei"; 3 | .center { 4 | text-align: center; 5 | } 6 | .text { 7 | font-size: 16px; 8 | display: inline-block; 9 | vertical-align: middle; 10 | } 11 | .blok { 12 | border-radius: 3px; 13 | /*background-color: color($colors, tint);*/ 14 | border: 2px solid color($colors,primary); 15 | width: 100%; 16 | margin-top: 4%; 17 | position: relative; 18 | } 19 | .class { 20 | height: 12px; 21 | width: 12px; 22 | background-color: color($colors, secondary); 23 | display: inline-block; 24 | vertical-align: middle; 25 | } 26 | 27 | .ilb { 28 | display: inline-block; 29 | vertical-align: top; 30 | line-height: 18px; 31 | font-size: 16px; 32 | } 33 | 34 | .ilb.prim { 35 | border-radius: 5px; 36 | background-color: color($colors, primary); 37 | height: 40px; 38 | width: 40px; 39 | color: white; 40 | line-height: 40px; 41 | position: absolute; 42 | right: 4%; 43 | } 44 | 45 | .ilb.g { 46 | color: #555; 47 | padding-left: 4%; 48 | } 49 | 50 | .c-class { 51 | color: black;/*color($colors, secondary);*/ 52 | display: inline-block; 53 | } 54 | 55 | .session { 56 | color: black; /*color($colors, openg);*/ 57 | display: inline-block; 58 | } 59 | 60 | .one { 61 | height: 12px; 62 | width: 12px; 63 | background-color: color($colors, openg); 64 | display: inline-block; 65 | vertical-align: middle; 66 | } 67 | 68 | .calendar-header-col { 69 | font-size: 1rem; 70 | color: #777; 71 | } 72 | .calendar-row { 73 | &:last-child { 74 | border-bottom: 1px solid #eee; 75 | } 76 | .calendar-col { 77 | display: flex; 78 | justify-content: center; 79 | padding: 0.8rem; 80 | font-size: 1.2rem; 81 | border-left: 1px solid #eee; 82 | border-top: 1px solid #eee; 83 | &:last-child { 84 | border-right: 1px solid #eee; 85 | } 86 | } 87 | .not-this-month { 88 | color: #fff; 89 | background: linear-gradient(#e5e5e5, #dfdfdf); 90 | } 91 | .today { 92 | color: #fff; 93 | box-shadow: inset 0 0 10px #aaa; 94 | background: radial-gradient(#c5c5c5, #c8c8c8, #ccc); 95 | } 96 | .select, .select.event { 97 | box-shadow: none; 98 | color: #fff; 99 | background: radial-gradient(#da5c5c, #df5f5f, #df5f5f)!important; 100 | } 101 | .event, .event.today { 102 | background: color($colors,primary); 103 | color: white; 104 | box-shadow: none !important; 105 | } 106 | 107 | 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/pages/profile/profile.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core' 2 | import { NavController, NavParams, AlertController } from 'ionic-angular' 3 | import { userAccess } from '../../app/services/users/users' 4 | import { LoginPage } from '../login/login' 5 | import { SubjectsAccess } from '../../app/services/subjects/subjects' 6 | 7 | import * as firebase from 'firebase/app' 8 | /** 9 | * Generated class for the ProfilePage page. 10 | * 11 | * See http://ionicframework.com/docs/components/#navigation for more info 12 | * on Ionic pages and navigation. 13 | */ 14 | @Component({ 15 | selector: 'page-profile', 16 | templateUrl: 'profile.html', 17 | }) 18 | export class ProfilePage { 19 | user 20 | login: LoginPage 21 | private fname: string 22 | private sname: string 23 | private grd: string 24 | private sch: string 25 | private cell: string 26 | private sub: string 27 | private picture: string 28 | private email: string 29 | private userInfo 30 | private type: string = 'learner' 31 | 32 | //INFO FOR SUBJECT CHOICES 33 | subinterests: Array = [] 34 | private subjects 35 | 36 | constructor(public navCtrl: NavController, public navParams: NavParams, public alertCtrl: AlertController, 37 | private subjectsAccess: SubjectsAccess) { 38 | this.user = navParams.get('user') 39 | let env = this 40 | 41 | firebase.database().ref(`/users_${this.type}s/${this.user.uid}`).once('value').then(res => { 42 | var data = res.val() 43 | env.cell = data.cellphone 44 | env.fname = data.name 45 | env.sname = data.lastname 46 | env.grd = data.grade 47 | env.sch = data.school 48 | env.sub = data.subjects 49 | env.picture = data.imageurl 50 | env.email = data.email 51 | }) 52 | 53 | this.addsubinterest() 54 | } 55 | 56 | ionViewDidLoad () { 57 | console.log('ionViewDidLoad ProfilePage') 58 | } 59 | 60 | addsubinterest () { 61 | this.subinterests.push('') 62 | } 63 | 64 | sendUserData () { 65 | let env = this 66 | 67 | firebase.database().ref(`/users_${this.type}s/${this.user.uid}`).update({ 68 | cellphone: env.cell, 69 | name: env.fname, 70 | lastname:env.sname, 71 | grade: env.grd, 72 | school: env.sch, 73 | subjects: env.sub, 74 | imageurl: env.picture, 75 | email: env.email 76 | }).then(() => { 77 | this.showAlert('Profile updated!', 'Your profile has susccessfully been updated') 78 | }).catch(err => { 79 | this.showAlert('Sorry', `Could not update your profile at this time: ${err}`) 80 | }) 81 | } 82 | 83 | showAlert (title, subTitle) { 84 | let alert = this.alertCtrl.create({ 85 | title, 86 | subTitle, 87 | buttons: ['OK'] 88 | }) 89 | 90 | alert.present() 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/theme/variables.scss: -------------------------------------------------------------------------------- 1 | // Ionic Variables and Theming. For more info, please see: 2 | // http://ionicframework.com/docs/theming/ 3 | 4 | // Font path is used to include ionicons, 5 | // roboto, and noto sans fonts 6 | $font-path: "../assets/fonts"; 7 | 8 | 9 | // The app direction is used to include 10 | // rtl styles in your app. For more info, please see: 11 | // http://ionicframework.com/docs/theming/rtl-support/ 12 | $app-direction: ltr; 13 | 14 | 15 | @import "ionic.globals"; 16 | 17 | 18 | // Shared Variables 19 | // -------------------------------------------------- 20 | // To customize the look and feel of this app, you can override 21 | // the Sass variables found in Ionic's source scss files. 22 | // To view all the possible Ionic variables, see: 23 | // http://ionicframework.com/docs/theming/overriding-ionic-variables/ 24 | 25 | 26 | 27 | 28 | // Named Color Variables 29 | // -------------------------------------------------- 30 | // Named colors makes it easy to reuse colors on various components. 31 | // It's highly recommended to change the default colors 32 | // to match your app's branding. Ionic uses a Sass map of 33 | // colors so you can add, rename and remove colors as needed. 34 | // The "primary" color is the only required color in the map. 35 | 36 | $colors: ( 37 | primary: #993333, 38 | secondary: #f8d64e, 39 | danger: #f53d3d, 40 | light: #f4f4f4, 41 | dark: #222, 42 | notsodark: #333, 43 | like: #488aff, 44 | fb: #0084ff, 45 | gg: #db3236, 46 | openg: #4Ba454, 47 | tint: #f9baba, 48 | cWhite: #ffffff 49 | ); 50 | 51 | 52 | // App iOS Variables 53 | // -------------------------------------------------- 54 | // iOS only Sass variables can go here 55 | 56 | 57 | 58 | 59 | // App Material Design Variables 60 | // -------------------------------------------------- 61 | // Material Design only Sass variables can go here 62 | $toolbar-md-active-color: white; 63 | 64 | 65 | 66 | // App Windows Variables 67 | // -------------------------------------------------- 68 | // Windows only Sass variables can go here 69 | 70 | 71 | 72 | 73 | // App Theme 74 | // -------------------------------------------------- 75 | // Ionic apps can have different themes applied, which can 76 | // then be future customized. This import comes last 77 | // so that the above variables are used and Ionic's 78 | // default are overridden. 79 | 80 | @import "ionic.theme.default"; 81 | 82 | 83 | // Ionicons 84 | // -------------------------------------------------- 85 | // The premium icon font for Ionic. For more info, please see: 86 | // http://ionicframework.com/docs/ionicons/ 87 | 88 | @import "ionic.ionicons"; 89 | 90 | 91 | // Fonts 92 | // -------------------------------------------------- 93 | 94 | @import "roboto"; 95 | @import "noto-sans"; 96 | -------------------------------------------------------------------------------- /src/pages/home/home.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams } from 'ionic-angular'; 3 | import { ToastController, AlertController, Loading, LoadingController, MenuController } from 'ionic-angular'; 4 | import { TutorAccess } from '../../app/services/tutor-data/tutor.data'; 5 | import { Events } from 'ionic-angular'; 6 | import { LessonPage } from '../lesson/lesson'; 7 | import { MessagesPage } from '../messages/messages'; 8 | import { NativeStorage } from '@ionic-native/native-storage'; 9 | import * as firebase from 'firebase/app'; 10 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'; 11 | import { AngularFireAuth } from 'angularfire2/auth'; 12 | import { Observable } from 'rxjs/Observable'; 13 | 14 | //Importing pages 15 | 16 | @Component({ 17 | selector: 'page-home', 18 | templateUrl: 'home.html' 19 | }) 20 | export class HomePage { 21 | loader: Loading; 22 | private ftutors: FirebaseListObservable; 23 | private lessons_upcoming_now: FirebaseListObservable; 24 | private lessonPage; 25 | private messagesPage; 26 | private user: any = {uid:'', displayName: '', photoURL: ''}; 27 | private first: boolean = false; 28 | 29 | constructor( 30 | public navCtrl: NavController, 31 | private alertCtrl: AlertController, 32 | private toastCtrl: ToastController, 33 | private tutorAccess: TutorAccess, 34 | private menuController: MenuController, 35 | public loadingCtrl: LoadingController, 36 | public events: Events, private navParams: NavParams, 37 | private af: AngularFireDatabase, private nativeStorage: NativeStorage) { 38 | this.user = navParams.get('user'); 39 | this.nativeStorage.setItem('user-info', {user: this.user, type: 'learner'}); 40 | this.lessons_upcoming_now = af.list(`/lessons_upcoming_now_learners/${this.user.uid}`, {query: {limitToFirst: 1}}); 41 | this.ftutors = af.list(`/users_tutors`); 42 | this.lessonPage = LessonPage; 43 | this.messagesPage = MessagesPage; 44 | } 45 | 46 | ngOnInit() { 47 | 48 | } 49 | 50 | changePage(page, object, start) { 51 | this.navCtrl.push(page, {user: this.user, target: object.tutorid, start: start, type:'learner', object: object}); 52 | } 53 | 54 | ionViewDidLoad() { 55 | this.menuController.enable(true, 'myMenu'); 56 | console.log('ionViewDidLoad ProfilePage'); 57 | } 58 | 59 | endGuide() { 60 | this.first = false; 61 | firebase.database().ref(`users_global/${this.user.uid}`).update({ 62 | first: false 63 | }) 64 | } 65 | 66 | viewTutor(id) { 67 | this.navCtrl.push(this.messagesPage, {user: this.user,id: id}); 68 | } 69 | 70 | private presentToast(message: string) { 71 | this.toastCtrl.create({message: message, duration: 2000}).present(); 72 | } 73 | 74 | private initLoader() { 75 | this.loader = this.loadingCtrl.create({ 76 | content: "Loading items..." 77 | }); 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/pages/parentregister/parentregister.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController, NavParams, AlertController } from 'ionic-angular'; 3 | import { userAccess } from '../../app/services/users/users'; 4 | import { HomePage } from '../home/home'; 5 | 6 | import { Events } from 'ionic-angular'; 7 | 8 | import { NativeStorage } from '@ionic-native/native-storage'; 9 | 10 | import { GooglePlus } from '@ionic-native/google-plus'; 11 | 12 | import * as firebase from 'firebase/app'; 13 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database'; 14 | import { AngularFireAuth } from 'angularfire2/auth'; 15 | import { Observable } from 'rxjs/Observable'; 16 | /** 17 | * Generated class for the ParentregisterPage page. 18 | * 19 | * See http://ionicframework.com/docs/components/#navigation for more info 20 | * on Ionic pages and navigation. 21 | */ 22 | 23 | @Component({ 24 | selector: 'page-parentregister', 25 | templateUrl: 'parentregister.html', 26 | }) 27 | export class ParentregisterPage { 28 | browse: string = "info"; 29 | users: userAccess; 30 | private fname: string; 31 | private sname: string; 32 | private grd: string; 33 | private sch: string; 34 | private cell: string; 35 | private sub: string; 36 | private email: string; 37 | private pass: string; 38 | 39 | constructor(public navCtrl: NavController, public navParams: NavParams, public alertCtrl: AlertController, 40 | private user: userAccess,public events: Events) { 41 | this.users = user; 42 | } 43 | 44 | ionViewDidLoad() { 45 | console.log('ionViewDidLoad ParentregisterPage'); 46 | } 47 | 48 | next(){ 49 | this.browse = "details"; 50 | } 51 | 52 | reg(){ 53 | if (this.users.alreadyReg(this.cell)){ 54 | this.showDeny(); 55 | } 56 | else{ 57 | this.users.registerUser(this.fname, this.sname, this.grd, this.sch, this.cell, this.sub, this.email, this.pass); 58 | this.users.currentUserMobile = this.cell; //UPDATE USERS GLOBAL VARIABLE 59 | this.events.publish('globals:update', "student" , this.users.getName(this.cell),'menu'); 60 | this.showAlert(); 61 | } 62 | } 63 | 64 | showAlert() { 65 | let alert = this.alertCtrl.create({ 66 | title: 'Registered!', 67 | subTitle: 'Welcome to Enlighten!', 68 | buttons: [ 69 | { 70 | text: 'OK', 71 | handler: () => { 72 | this.navCtrl.setRoot(HomePage); 73 | } 74 | }] 75 | }); 76 | alert.present(); 77 | } 78 | showDeny() { 79 | let alert = this.alertCtrl.create({ 80 | title: 'Already Registered!', 81 | subTitle: 'This account is already used, please go to the Login Page!', 82 | buttons: [ 83 | { 84 | text: 'OK', 85 | handler: () => { 86 | this.navCtrl.remove(2,1); // This will remove the 'ResultPage' from stack. 87 | this.navCtrl.pop(); 88 | } 89 | }] 90 | }); 91 | alert.present(); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/pages/home/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | Recommended Tutors 7 | 8 | 9 | 10 | 39 | 40 | 41 | 42 | 43 | 44 | No recommended tutors around you at the moment 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Recommended for you 54 | 55 | 56 | 57 | 58 |
59 |
60 | {{tutor.name}} {{tutor.lastname}} 61 |

{{tutor.institution}}

62 |

Subjects

63 |
64 |
65 | 66 |
67 | 68 | 69 | 70 | 71 | LESSON COMING UP 72 |

{{lesson.start | date:'HH:mm'}} Today

73 |

with {{lesson.tutorname}}

74 |
75 |
76 |
77 | 78 | 79 | -------------------------------------------------------------------------------- /src/pages/parentregister/parentregister.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | Register 10 | 11 | 12 | 13 | 14 | Parent/Guardian Info 15 | 16 | 17 | Child Details 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 |

Please fill in your details

28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | First Name 38 | 39 | 40 | 41 | 42 | 43 | Last Name 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Cellphone Number 53 | 54 | 55 | 56 | 57 | 58 | 59 | Password 60 | 61 | 62 | 63 | 64 | 65 | 68 | 69 |
70 | 71 |
72 |

Enter the number of the student you wish to monitor

73 | 74 | 75 | 76 | 77 | Cellphone Number 78 | 79 | 80 | 81 | 82 | 83 | 84 |

Complete Signup Using

85 | 86 | 90 | 91 |
92 | 93 |
94 | -------------------------------------------------------------------------------- /src/pages/tutorhome/tutorhome.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Home 13 | 14 | 15 | 16 | 17 |

UPCOMING LESSONS

18 | 19 | 20 | 21 | 22 | {{lesson.title}} 23 | 24 |

{{lesson.type}}

25 | 26 |

Grade {{lesson.grade}}

27 |

{{lesson.duration}} minutes

28 |

{{lesson.subtitle}}

29 |
30 | 31 | 32 |

{{lesson.start | date:'MMM dd, yyyy HH:mm'}}

33 |
34 | 35 | 36 | 37 | 38 | 39 | {{lesson.learnername}} 40 |

{{lesson.school}}

41 |

{{lesson.subtitle}}

42 | 43 |
44 |
45 |
46 |
47 | 48 |
49 | 50 | 51 | 52 | 53 | LESSON COMING UP 54 |

{{lesson.start | date:'HH:mm'}} Today

55 |

with {{lesson.learnername}}

56 | 57 |
58 |
59 | 60 |
61 | 62 | 63 | 64 |

New lesson request

65 |

{{ lesson.learnername }}

66 |

{{lesson.start | date:'Do dd/MM HH:mm'}}

67 |
68 |
69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/providers/lessons/lessons.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { AuthProvider } from '../auth/auth' 3 | import 'rxjs/add/operator/map'; 4 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database' 5 | import { AngularFireAuth } from 'angularfire2/auth' 6 | import { Events } from 'ionic-angular' 7 | 8 | /* 9 | Generated class for the LessonsProvider provider. 10 | 11 | See https://angular.io/docs/ts/latest/guide/dependency-injection.html 12 | for more info on providers and Angular DI. 13 | */ 14 | @Injectable() 15 | export class LessonsProvider { 16 | 17 | constructor(public auth: AuthProvider, private af: AngularFireDatabase, events: Events) { 18 | 19 | } 20 | 21 | getUpcomingLessons (user, type): FirebaseListObservable { 22 | return this.af.list(`/lessons_upcoming_${type}s/${user.uid}`) 23 | } 24 | 25 | getUpcomingNowLessons (uid, type, query = {}): FirebaseListObservable { 26 | return this.af.list(`/lessons_upcoming_now_${type}s/${uid}/`, query) 27 | } 28 | 29 | getPendingLessons (user, type): FirebaseListObservable { 30 | let query = type === 'tutor' ? { 31 | query: { 32 | orderByChild: 'rate' 33 | } 34 | } : {} 35 | 36 | return this.af.list(`/lessons_pending_${type}s/${user.uid}`, query) 37 | } 38 | 39 | getLessonHistory (user, type): FirebaseListObservable { 40 | return this.af.list(`/lessons_history_${type}s/${user.uid}`) 41 | } 42 | 43 | acceptLesson (lessonid, learnerid, user) { 44 | firebase.database().ref(`/lessons_pending_learners/${learnerid}/${lessonid}`).once('value').then(res => { 45 | firebase.database().ref(`/lessons_upcoming_learners/${learnerid}/${lessonid}`).update(res.val()) 46 | firebase.database().ref(`/lessons_pending_learners/${learnerid}/${lessonid}`).remove() 47 | 48 | firebase.database().ref(`/lessons_pending_tutors/${user.uid}/${lessonid}`).once('value').then(res2 => { 49 | var data = res2.val() 50 | data.tutorname = res.val().tutorname 51 | firebase.database().ref(`/lessons_upcoming_tutors/${user.uid}/${lessonid}`).update(data) 52 | firebase.database().ref(`/lessons_pending_tutors/${user.uid}/${lessonid}`).remove() 53 | }) 54 | }) 55 | 56 | firebase.database().ref(`/lessons_pending_tutors_learners/${user.uid}/${learnerid}/${lessonid}`).remove() 57 | } 58 | 59 | autoAcceptLesson (lessonid, learnerid, tutorid) { 60 | firebase.database().ref(`/lessons_pending_learners/${learnerid}/${lessonid}`).once('value').then(res => { 61 | firebase.database().ref(`/lessons_upcoming_learners/${learnerid}/${lessonid}`).update(res.val()) 62 | firebase.database().ref(`/lessons_pending_learners/${learnerid}/${lessonid}`).remove() 63 | 64 | firebase.database().ref(`/lessons_pending_tutors/${tutorid}/${lessonid}`).once('value').then(res2 => { 65 | var data = res2.val() 66 | data.tutorname = res.val().tutorname 67 | firebase.database().ref(`/lessons_upcoming_tutors/${tutorid}/${lessonid}`).update(data) 68 | firebase.database().ref(`/lessons_pending_tutors/${tutorid}/${lessonid}`).remove() 69 | }) 70 | }) 71 | 72 | firebase.database().ref(`/lessons_pending_tutors_learners/${tutorid.uid}/${learnerid}/${lessonid}`).remove() 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/pages/classbrowse/classbrowse.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Browse Classes 13 | 14 | 15 | 16 | 17 | Class Offers 18 | 19 | 20 | Tutors 21 | 22 | 23 | --> 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | Physics 34 | 35 |

2 accepts

36 | 37 |

Grade 12

38 |

Created 19 Jun 2017

39 |

25 minutes

40 |
41 | 42 |

R200

43 |
44 | 45 | 46 |

Available:

47 |

Tues, Jun 20, 2017 13:00 (recurring)

48 |

Sun, July 2, 2017 16:00

49 |
50 |
51 | 52 | 53 | 54 | 55 | 56 | Albert Einstein 57 |

University of Cape Town

58 |

Maths, Physics

59 | 60 | 14 61 |
62 |
63 | 66 |
67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 |
81 |
82 | 83 | 92 |
93 |
94 | -------------------------------------------------------------------------------- /src/pages/tutorschedule/tutorschedule.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core' 2 | import { NavController, NavParams } from 'ionic-angular' 3 | import { Calendar } from '@ionic-native/calendar' 4 | import * as moment from 'moment' 5 | import * as firebase from 'firebase/app' 6 | 7 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database' 8 | import { AngularFireAuth } from 'angularfire2/auth' 9 | import { Observable } from 'rxjs/Observable' 10 | /** 11 | * Generated class for the TutorschedulePage page. 12 | * 13 | * See http://ionicframework.com/docs/components/#navigation for more info 14 | * on Ionic pages and navigation. 15 | */ 16 | 17 | @Component({ 18 | selector: 'page-tutorschedule', 19 | templateUrl: 'tutorschedule.html', 20 | }) 21 | export class TutorschedulePage { 22 | private fcalendar: FirebaseListObservable 23 | private user 24 | private type: string = 'tutor' 25 | private lastDay 26 | constructor(public navCtrl: NavController, public navParams: NavParams, 27 | private calendar: Calendar, 28 | private af: AngularFireDatabase) { 29 | this.user = navParams.get('user') 30 | this.fcalendar = af.list(`/calendar_tutors/${this.user.uid}`) 31 | } 32 | 33 | ionViewDidLoad() { 34 | console.log('ionViewDidLoad TutorschedulePage') 35 | } 36 | 37 | updateDtStart(k, val, key, slot) { 38 | let date = val 39 | date.month = date.month - 1 40 | this.lastDay = moment(date) 41 | 42 | firebase.database().ref(`/calendar_tutors/${this.user.uid}/${key}`).once('value').then(res => { 43 | const obj = res.val() 44 | let duration 45 | 46 | if (obj.duration !== null && obj.duration !== undefined) { 47 | duration = 60 48 | slot.duration = duration 49 | } 50 | 51 | const start = moment(slot.start).format() 52 | 53 | firebase.database().ref(`/calendar_tutors/${this.user.uid}/${key}`).update({ 54 | start, 55 | booked: false, 56 | duration, 57 | end: moment(start).add('minutes', duration).format() 58 | }) 59 | 60 | firebase.database().ref(`/calendar_tutors_unbooked/${this.user.uid}/${key}`).update({ 61 | start, 62 | booked: false, 63 | duration, 64 | end: moment(start).add('minutes', duration).format() 65 | }) 66 | }) 67 | } 68 | 69 | updateDur(k, val, key, val2) { 70 | let end = moment(this.lastDay).add('minutes', val) //FIRST CHECK IF IT CLASHES WITH OTHER DATES 71 | 72 | firebase.database().ref(`/calendar_tutors/${this.user.uid}/${key}`).update({ 73 | duration: val, //miliseconds 74 | end: moment(end).format(), 75 | booked: false, //how to do this better 76 | static: true 77 | }) 78 | 79 | firebase.database().ref(`/calendar_tutors_unbooked/${this.user.uid}/${key}`).update({ 80 | duration: val, //miliseconds 81 | end: moment(end).format(), 82 | booked: false, //how to do this better 83 | static: true 84 | }) 85 | } 86 | 87 | addToCalendar() { 88 | this.fcalendar.push({ 89 | start: moment().format(), 90 | duration:'', 91 | recurring: false, 92 | static: false, 93 | location: 'Enlighten App', 94 | notes: 'Calendar slot', 95 | title: 'Enlighten Tutoring Session' 96 | }) 97 | } 98 | 99 | delete (key) { 100 | firebase.database().ref(`/calendar_tutors/${this.user.uid}/${key}`).remove() 101 | firebase.database().ref(`/calendar_tutors_unbooked/${this.user.uid}/${key}`).remove() 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/pages/profile/profile.html: -------------------------------------------------------------------------------- 1 | 7 | 13 | 14 | 15 | 18 | My Profile 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | First Name 34 | 35 | 36 | 37 | 38 | 39 | Last Name 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Grade 48 | 49 | 8 50 | 9 51 | 10 52 | 11 53 | 12 54 | 55 | 56 | 57 | 58 | 59 | 60 | School 61 | 62 | MERENSKY HIGH SCHOOL 63 | SAX HIGH SCHOOL 64 | BISHOPS HIGH SCHOOL 65 | DANKLY HIGH SCHOOL 66 | 67 | 68 | 69 | 70 | 71 | 72 | Email Address 73 | 74 | 75 | 76 | 77 | 78 | 79 | Cellphone Number 80 | 81 | 82 | 83 |

My Subjects

84 | 85 | 86 | 87 | Subject Requiring Tutoring 88 | 89 | {{subject.name}} 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 |
99 | 100 | 101 | 102 | 103 | 104 |
105 | -------------------------------------------------------------------------------- /src/pages/tutorprofile/tutorprofile.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | My Profile 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | First Name 28 | 29 | 30 | 31 | 32 | 33 | Last Name 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Highest Qualification 42 | 43 | DOCTOR'S DEGREE 44 | MASTER'S DEGREE 45 | HONOURS DEGREE 46 | BACHELORS DEGREE 47 | NATIONAL DIPLOMA 48 | HIGHER CERTIFICATE 49 | MATRIC 50 | 51 | 52 | 53 | 54 | 55 | 56 | Year of Study 57 | 58 | 1 59 | 2 60 | 3 61 | 4 62 | 5 63 | 6 64 | 65 | 66 | 67 | 68 | 69 | 70 | Institute 71 | 72 | {{institution.name}} 73 | 74 | 75 | 76 | 77 | 78 | 79 | Degree of Study 80 | 81 | 82 | 83 | 84 | 85 | 86 | Email Address 87 | 88 | 89 | 90 | 91 | 92 | 93 | Cellphone Number 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /src/pages/login/login.scss: -------------------------------------------------------------------------------- 1 | page-login { 2 | .thumbn { 3 | width: 60%; 4 | margin-left: 20%; 5 | } 6 | 7 | .reduce { 8 | width: 100%; 9 | margin: 0% 0; 10 | min-height: 55px; 11 | line-height: 55px; 12 | } 13 | 14 | .display { 15 | width: 100%; 16 | height: 100vh; 17 | background: white; /* For browsers that do not support gradients 18 | background: -webkit-linear-gradient(top left, #FFB74D, #FF7043); /* For Safari 5.1 to 6.0 19 | background: -o-linear-gradient(top left, #FFB74D, #FF7043); /* For Opera 11.1 to 12.0 20 | background: -moz-linear-gradient(top left, #FFB74D, #FF7043); 21 | background: linear-gradient(top left, #FFB74D, #FF7043); */ 22 | position: relative; 23 | text-align: center; 24 | } 25 | 26 | img { 27 | width: auto; 28 | display: inline-block; 29 | text-align: center; 30 | height: 22.5%; 31 | margin-bottom: 5%; 32 | } 33 | 34 | ion-icon { 35 | line-height: 32px!important; 36 | } 37 | 38 | ion-col { 39 | &:nth-of-type(1) { 40 | .btn { 41 | margin-right: 5%; 42 | } 43 | } 44 | 45 | &:nth-of-type(2) { 46 | .btn { 47 | margin-left: 5%; 48 | } 49 | } 50 | } 51 | 52 | .btn { 53 | position:relative; 54 | width: 95%; 55 | font-weight: normal; 56 | margin: 0; 57 | box-shadow: none; 58 | text-transform: capitalize !important; 59 | } 60 | 61 | .text { 62 | color: grey; 63 | position: relative; 64 | top: 35%; 65 | text-align:center; 66 | width: 100%; 67 | padding: 0px 15%; 68 | font-size: 14px; 69 | } 70 | 71 | ion-item { 72 | background-color: transparent !important; 73 | color: grey; 74 | } 75 | 76 | ion-input { 77 | color: grey; 78 | } 79 | 80 | p { 81 | padding: 0; 82 | margin: 0; 83 | margin-bottom: 3.5%; 84 | } 85 | 86 | ion-grid { 87 | margin-top: 3rem; 88 | background-color: white; 89 | } 90 | 91 | .text-input { 92 | color: grey !important; 93 | } 94 | 95 | .sign { 96 | box-shadow: 0px 0px 0px transparent; 97 | margin: 4% 0%; 98 | margin-top: 0%; 99 | width: 100%; 100 | font-weight: normal; 101 | min-height: 47px; 102 | } 103 | 104 | p.terms { 105 | color: grey; 106 | font-size: 0.82em; 107 | 108 | a { 109 | color:color($colors, primary); 110 | font-weight: bold; 111 | } 112 | } 113 | 114 | // Input items 115 | ion-select{ 116 | max-width: 95% !important; 117 | min-width: 95% !important; 118 | padding-left: 8px !important; 119 | } 120 | 121 | .text-input-ios { 122 | margin-left: 8px !important; 123 | } 124 | 125 | .select-placeholder { 126 | color: #999 !important; 127 | } 128 | 129 | .select-icon .select-icon-inner { 130 | color: #999 !important; 131 | } 132 | 133 | 134 | ion-item { 135 | border-radius: 2px !important; 136 | padding-left: 10px !important; 137 | margin-bottom: 15px !important; 138 | margin-bottom: 10px; 139 | color: color($colors, primary) !important; 140 | background-color: #fefefe !important; 141 | border: 1px solid #aaa !important; 142 | font-size: 0.9em; 143 | } 144 | ::-webkit-input-placeholder { 145 | color: #999 !important; 146 | } 147 | .item-inner { 148 | border-bottom: 0 !important; 149 | box-shadow: none !important; 150 | } 151 | 152 | .create { 153 | width: 100%; 154 | display: inline-block; 155 | vertical-align: bottom; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/pages/tutors/tutors.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | Browse Tutors 13 | 14 | 15 | 16 | 17 | 58 | 59 | 60 |

Find Tutors that match your profile

61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | {{tutor.likes}} 70 | 71 |

{{tutor.name}} {{tutor.lastname}}

72 |

{{tutor.institution}}

73 |

{{subjects}}

74 |
75 | 76 |
77 |

Rosebank, Cape Town

78 |

{{tutor.bio}}

79 |
80 | 83 |
84 | 85 | 86 | 87 | 88 | 91 | 92 | 93 | 96 | 97 |
98 | -------------------------------------------------------------------------------- /src/pages/myclasses/myclasses.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 12 | My Classes 13 | 14 | 15 | 16 | 17 | Booked 18 | 19 | 20 | Pending 21 | 22 | 23 | History 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | {{lesson.title}} 38 | 39 |

{{lesson.start | date:'MMM dd, yyyy HH:mm'}}

40 | 41 |

{{lesson.subtitle}}

42 |

{{lesson.duration}} minutes

43 |
44 | 45 | 46 | 47 | 48 | 49 | {{lesson.tutorname}} 50 |

{{lesson.institution}}

51 | 52 |
53 |
54 | 57 |
58 |
59 |
60 |
61 |
62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | {{lesson.title}} 70 | 71 |

{{lesson.start | date:'MMM dd, yyyy HH:mm'}}

72 | 73 |

{{lesson.subtitle}}

74 |

{{lesson.duration}} minutes

75 |
76 | 77 | 78 | 79 | 80 | 81 | {{lesson.tutorname}} 82 |

{{lesson.institution}}

83 | 84 |
85 |
86 |
87 |
88 |
89 | 90 | 91 | 92 | 93 | 94 | 95 |

{{lesson.title}}

96 |
97 |
98 |
99 |
100 | -------------------------------------------------------------------------------- /src/pages/messages/messages.scss: -------------------------------------------------------------------------------- 1 | page-messages { 2 | 3 | .scroll { 4 | padding: 10px 0 50px !important; 5 | } 6 | 7 | button.book { 8 | width: 100% !important; 9 | box-shadow: none !important; 10 | } 11 | 12 | ion-col { 13 | display: flex; 14 | align-items: center; 15 | justify-content: center; 16 | } 17 | 18 | .messages { 19 | display: -webkit-box !important; 20 | display: -moz-box !important; 21 | display: -ms-flexbox !important; 22 | display: -webkit-flex !important; 23 | display: flex !important; 24 | -webkit-align-content: center !important; 25 | -ms-flex-line-pack: center !important; 26 | align-content: center !important; 27 | -webkit-box-align: center !important; 28 | -moz-box-align: center !important; 29 | -webkit-align-items: center!important; 30 | -ms-flex-align: center !important; 31 | align-items: center !important; 32 | margin-bottom: 2px !important; 33 | .message { 34 | -webkit-box-flex: 1 !important; 35 | -moz-box-flex: 1 !important; 36 | -webkit-flex: 1 1 auto !important; 37 | -ms-flex: 1 1 auto !important; 38 | flex: 1 1 auto !important; 39 | padding: 10px !important; 40 | -webkit-transition: all 250ms ease-in-out !important; 41 | transition: all 250ms ease-in-out !important; 42 | overflow: hidden !important; 43 | text-align: left !important; 44 | -webkit-transform: translate3d(0, 0, 0) !important; 45 | -moz-transform: translate3d(0, 0, 0) !important; 46 | transform: translate3d(0, 0, 0) !important; 47 | } 48 | } 49 | 50 | ion-footer { 51 | height: 50px; 52 | } 53 | 54 | input { 55 | height: calc(40px - 4%); 56 | width: 70%; 57 | margin: 2%; 58 | vertical-align: top; 59 | text-indent: 5px; 60 | } 61 | 62 | .button-clear { 63 | height: calc(40px - 4%); 64 | margin: 2%; 65 | vertical-align: top; 66 | width: 18%; 67 | background: #993333; 68 | color: white; 69 | } 70 | 71 | .time { 72 | -webkit-box-flex: 0 !important; 73 | -moz-box-flex: 0 !important; 74 | -webkit-flex: 0 1 auto !important; 75 | -ms-flex: 0 1 auto !important; 76 | flex: 0 1 auto !important; 77 | -webkit-align-self: auto !important; 78 | -ms-flex-item-align: auto !important; 79 | align-self: auto !important; 80 | width: 120px !important; 81 | text-align: center !important; 82 | padding: 0 0 0 0 !important; 83 | -webkit-transition: all 250ms ease-in-out !important; 84 | transition: all 250ms ease-in-out !important; 85 | -webkit-transform: translate3d(10px, 0, 0) !important; 86 | -moz-transform: translate3d(10px, 0, 0) !important; 87 | transform: translate3d(10px, 0, 0) !important; 88 | 89 | &.slide-right { 90 | -webkit-transform: translate3d(130px, 0, 0) !important; 91 | -moz-transform: translate3d(130px, 0, 0) !important; 92 | transform: translate3d(130px, 0, 0) !important; 93 | } 94 | } 95 | 96 | .messages.other { 97 | .message { 98 | -webkit-transform: translate3d(0, 0, 0) !important; 99 | -moz-transform: translate3d(0, 0, 0) !important; 100 | transform: translate3d(0, 0, 0) !important; 101 | text-align: right !important; 102 | } 103 | .message.slide-right { 104 | -webkit-transform: translate3d(120px, 0, 0) !important; 105 | -moz-transform: translate3d(120px, 0, 0) !important; 106 | transform: translate3d(120px, 0, 0) !important; 107 | } 108 | span { 109 | color: black !important; 110 | background-color: #C7C7CC !important; 111 | position: relative; 112 | padding-bottom: 27.5px; 113 | } 114 | } 115 | 116 | .message span { 117 | background: #da5c5c !important; 118 | display: inline-block !important; 119 | color: white !important; 120 | padding: 10px; 121 | border-radius: 10px !important; 122 | text-align: left !important; 123 | max-width: 240px !important; 124 | position: relative; 125 | padding-bottom: 27.5px; 126 | } 127 | 128 | span p { 129 | position: absolute; 130 | right: 10px; 131 | bottom: 2%; 132 | font-size: 0.6em; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/pages/tutorhome/tutorhome.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core' 2 | import { NavController, NavParams, MenuController, Events, AlertController } from 'ionic-angular' 3 | import { TutorschedulePage } from '../tutorschedule/tutorschedule' 4 | import { TutorclassesPage } from '../tutorclasses/tutorclasses' 5 | import { LessonPage } from '../lesson/lesson' 6 | 7 | import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database' 8 | import { AngularFireAuth } from 'angularfire2/auth' 9 | import { Observable } from 'rxjs/Observable' 10 | import * as firebase from 'firebase' 11 | import { LessonsProvider } from '../../providers/lessons/lessons' 12 | 13 | /** 14 | * Generated class for the TutorhomePage page. 15 | * 16 | * See http://ionicframework.com/docs/components/#navigation for more info 17 | * on Ionic pages and navigation. 18 | */ 19 | 20 | @Component({ 21 | selector: 'page-tutorhome', 22 | templateUrl: 'tutorhome.html', 23 | }) 24 | export class TutorhomePage { 25 | tutorschedulePage 26 | tutorclassesPage 27 | private lessons_upcoming: FirebaseListObservable 28 | private lessons_upcoming_now: FirebaseListObservable 29 | private lessons_pending 30 | private lessonPage 31 | private user 32 | constructor(public navCtrl: NavController, 33 | private af: AngularFireDatabase, public navParams: NavParams, public menuController: MenuController, 34 | public events: Events, public alertCtrl: AlertController, private lessonsProvider: LessonsProvider) { 35 | this.tutorschedulePage = TutorschedulePage 36 | this.menuController.enable(true, 'myMenu') 37 | this.lessonPage = LessonPage 38 | this.tutorclassesPage = TutorclassesPage 39 | this.user = navParams.get('user') 40 | const type = 'tutor' 41 | this.lessons_pending = lessonsProvider.getPendingLessons(this.user, type) 42 | this.lessons_upcoming = lessonsProvider.getUpcomingLessons(this.user, type) 43 | this.lessons_upcoming_now = lessonsProvider.getUpcomingNowLessons(this.user.uid, type, {query: {limitToFirst: 1}}) 44 | //keep in mind, through node - we can make the calendar rewrite itself or delete itself weekly 45 | //UPDATE CALENDAR TO FIT THIS WEEK! 46 | } 47 | 48 | ionViewDidLoad() { 49 | this.menuController.enable(true, 'myMenu') 50 | this.events.publish('globals:update', this.user, 'tutor') 51 | console.log('ionViewDidLoad TutorhomePage') 52 | } 53 | 54 | changePage(page, object = { learnerid: null }, start = '') { 55 | this.navCtrl.push(page, { user: this.user, target: object.learnerid, start: start, type:'tutor', object: object }) 56 | } 57 | 58 | viewLesson (lesson, key) { 59 | let confirm = this.alertCtrl.create({ 60 | title: `Accept lesson with ${lesson.learnername}?`, 61 | message: `Do you agree to tutor ${lesson.learnername} at ${lesson.date}?`, 62 | buttons: [ 63 | { 64 | text: 'No', 65 | handler: () => { 66 | this.rejectLesson(lesson, key) 67 | } 68 | }, 69 | { 70 | text: 'Yes', 71 | handler: () => { 72 | this.acceptLesson(lesson, key) 73 | } 74 | } 75 | ] 76 | }) 77 | 78 | confirm.present() 79 | } 80 | 81 | acceptLesson (lesson, lessonid) { 82 | let env = this 83 | let learnerid = lesson.learnerid 84 | 85 | firebase.database().ref(`/lessons_pending_learners/${learnerid}/${lessonid}`).once('value').then(res => { 86 | firebase.database().ref(`/lessons_upcoming_learners/${learnerid}/${lessonid}`).update(res.val()) 87 | firebase.database().ref(`/lessons_pending_learners/${learnerid}/${lessonid}`).remove() 88 | 89 | firebase.database().ref(`/lessons_pending_tutors/${env.user.uid}/${lessonid}`).once('value').then(res2 => { 90 | var data = res2.val() 91 | data.tutorname = res.val().tutorname 92 | firebase.database().ref(`/lessons_upcoming_tutors/${env.user.uid}/${lessonid}`).update(data) 93 | firebase.database().ref(`/lessons_pending_tutors/${env.user.uid}/${lessonid}`).remove() 94 | }) 95 | }) 96 | 97 | firebase.database().ref(`/lessons_pending_tutors_learners/${this.user.uid}/${learnerid}/${lessonid}`).remove() 98 | } 99 | 100 | rejectLesson (lesson, lessonid) { 101 | let learnerid = lesson.learnerid 102 | firebase.database().ref(`/lessons_pending_tutors_learners/${this.user.uid}/${learnerid}/${lessonid}`).remove() 103 | } 104 | 105 | } 106 | --------------------------------------------------------------------------------