diff --git a/README.md b/README.md index e7d0f5a..97a570a 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,22 @@ -# hatch-template-project - replace with your project name - -This template project should be forked by hatch teams. - -This project was developed during [hatchlondon 2017](http://hatchlondon.io). - -## Todo - -Tick items off as you go along. - -- [ ] 1. [Sign up](https://help.github.com/articles/signing-up-for-a-new-github-account/) for a free GitHub account -- [ ] 2. [Fork](https://help.github.com/articles/fork-a-repo/) this project -- [ ] 3. Add your forked repo from `step 2` to this [project](https://github.com/SheCanCodeHQ/hatchlondon-2017-projects) as a [Pull Request](https://help.github.com/articles/about-pull-requests/) - -### Project setup - -From now on it is in your **Forked** repo - -- [ ] 4. At the top of your **repo** add a brief project description & link to where it is hosted. - -![Repo description and link](https://user-images.githubusercontent.com/624760/33160443-57e86a96-d014-11e7-8488-52592fc69a81.png) - -*TIP: [GitHub Pages](https://pages.github.com) gives free static website hosting* - -### README changes (this file) - -- [ ] 5. Change the name at the top of this file on `line 1` -- [ ] 6. Under the name of this project put a brief description of the project `line 3` (this can be more detailed than `step 4`) -- [ ] 7. Fill in your team members in the **TEAM** section below -- [ ] 8. Fill in the **PROBLEM AND SOLUTION** section below -- [ ] 9. Fill in the **INSTALL AND RUN THIS PROJECT** section below -- [ ] 10. Any *digital / paper* notes you make during the hackathon you MUST add to the **Issue** section in your repo - -*TIP: drag and drop [images / photos](https://help.github.com/articles/file-attachments-on-issues-and-pull-requests/)* +![logo](https://raw.githubusercontent.com/MedicusHatch/medicus/master/kdfjghfdkghds.png) ## Team -Include all members of your team for the hack here: +* [Huey Lee](https://github.com/hueyy/) +* [Kristina Kordova](https://github.com/KrisstinaKordova) +* [Darren Ko](https://github.com/darrenslko) +* [Patrick Pflughaupt](https://github.com/patrickpflughaupt) -* Full Name [github](link to github profile) -* Full Name [github](link to github profile) -* Full Name [github](link to github profile) -* Full Name [github](link to github profile) +## Problem & Solution -## Problem and Solution +**Problem**: Missed GP appointments - a £1 billion problem -Describe here which problem you are working on during the event, and what your solution is, succinctly. +**Solution**: A smart booking system that knows when you’re running late (or too far away) and reallocates the appointment to save doctors’ time ## Install and run this project -Paste here a link to the project if it is a running website, or some indications on how to use your code for other GitHub users who might be interested. The jury will take a look at what is in this repository during deliberations. +The app can be found here: [https://pr.to/AIFC4T/](https://pr.to/AIFC4T/). You may need to download the [proto.io app](https://play.google.com/store/apps/details?id=io.proto.player) to view it. + +The partially functional app which includes a booking screen & push notifications can be run using the [Expo](https://play.google.com/store/apps/details?id=host.exp.exponent) app. Scan the QR code below to open the app. + +![QR](https://raw.githubusercontent.com/MedicusHatch/medicus/master/qr.png) diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..839bfe4 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1,3 @@ +node_modules +.expo +*.log \ No newline at end of file diff --git a/app/App.js b/app/App.js new file mode 100644 index 0000000..edca562 --- /dev/null +++ b/app/App.js @@ -0,0 +1,4 @@ +import { createAppContainer } from 'react-navigation' +import RootNavigator from './RootNavigator' + +export default createAppContainer(RootNavigator) diff --git a/app/RootNavigator.js b/app/RootNavigator.js new file mode 100644 index 0000000..5e1e533 --- /dev/null +++ b/app/RootNavigator.js @@ -0,0 +1,21 @@ +import { createStackNavigator } from 'react-navigation' + +import RootView from 'app/views/RootView' +import BookAppointmentView from 'app/views/BookAppointmentView' +import AppointmentBookedView from 'app/views/AppointmentBookedView' + +const RootNavigator = createStackNavigator({ + RootView: { + screen: RootView, + }, + BookAppointmentView: { + screen: BookAppointmentView, + }, + AppointmentBookedView: { + screen: AppointmentBookedView + } +}, { + intialRouteName: 'RootView' +}) + +export default RootNavigator diff --git a/app/app.json b/app/app.json new file mode 100644 index 0000000..4b8022b --- /dev/null +++ b/app/app.json @@ -0,0 +1,27 @@ +{ + "expo": { + "name": "medicus", + "description": "This project is really great.", + "slug": "medicus", + "privacy": "public", + "sdkVersion": "31.0.0", + "platforms": ["ios", "android"], + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "splash": { + "image": "./assets/splash.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + }, + "updates": { + "fallbackToCacheTimeout": 0 + }, + "assetBundlePatterns": [ + "**/*" + ], + "ios": { + "supportsTablet": true + } + } +} diff --git a/app/assets/icon.png b/app/assets/icon.png new file mode 100644 index 0000000..3f5bbc0 Binary files /dev/null and b/app/assets/icon.png differ diff --git a/app/assets/splash.png b/app/assets/splash.png new file mode 100644 index 0000000..4f9ade6 Binary files /dev/null and b/app/assets/splash.png differ diff --git a/app/babel.config.js b/app/babel.config.js new file mode 100644 index 0000000..935fa33 --- /dev/null +++ b/app/babel.config.js @@ -0,0 +1,7 @@ +module.exports = function(api) { + api.cache(true) + return { + "presets": ["babel-preset-expo"] + } +} + diff --git a/app/components/HeaderText.js b/app/components/HeaderText.js new file mode 100644 index 0000000..f9e8311 --- /dev/null +++ b/app/components/HeaderText.js @@ -0,0 +1,18 @@ +import React from 'react' +import { StyleSheet, Text } from 'react-native' + +class HeaderText extends React.Component { + render(){ + return ( + + ) + } +} + +const styles = StyleSheet.create({ + headerText: { + fontSize: 16 + } +}) + +export default HeaderText diff --git a/app/components/NormalText.js b/app/components/NormalText.js new file mode 100644 index 0000000..542ba5f --- /dev/null +++ b/app/components/NormalText.js @@ -0,0 +1,18 @@ +import React from 'react' +import { StyleSheet, Text } from 'react-native' + +class NormalText extends React.Component { + render(){ + return ( + + ) + } +} + +const styles = StyleSheet.create({ + normalText: { + fontSize: 14 + } +}) + +export default NormalText diff --git a/app/components/TimePicker.js b/app/components/TimePicker.js new file mode 100644 index 0000000..958b0a7 --- /dev/null +++ b/app/components/TimePicker.js @@ -0,0 +1,38 @@ +import React from 'react' +import { Picker, StyleSheet } from 'react-native' + +import _ from 'lodash' + +class TimePicker extends React.Component { + render(){ + const { selectedValue, style, onValueChange } = this.props + + const pickerItems = _.fill(Array(18), 0).map((v,i) => { + const hour = Math.floor(i / 2) + if(i % 2 === 0){ + const label = `${_.padStart(hour + 9, 2, 0)}:00hrs` + return + } else { + const label = `${_.padStart(hour + 9, 2, 0)}:30hrs` + return + } + + }) + + return ( + + {pickerItems} + + ) + } +} + +const styles = StyleSheet.create({ + picker: { + } +}) + +export default TimePicker diff --git a/app/package.json b/app/package.json new file mode 100644 index 0000000..6f70a3d --- /dev/null +++ b/app/package.json @@ -0,0 +1,21 @@ +{ + "name": "app", + "main": "node_modules/expo/AppEntry.js", + "private": true, + "scripts": { + "start": "expo start", + "android": "expo start --android", + "ios": "expo start --ios", + "eject": "expo eject" + }, + "dependencies": { + "expo": "^31.0.2", + "lodash": "^4.17.11", + "react": "16.5.0", + "react-native": "https://github.com/expo/react-native/archive/sdk-31.0.0.tar.gz", + "react-navigation": "^3.0.0" + }, + "devDependencies": { + "babel-preset-expo": "^5.0.0" + } +} diff --git a/app/utils/NotificationsManager.js b/app/utils/NotificationsManager.js new file mode 100644 index 0000000..a760615 --- /dev/null +++ b/app/utils/NotificationsManager.js @@ -0,0 +1,56 @@ +import { Notifications } from 'expo' + +import _ from 'lodash' + +const defaultNotif = { + ios: { + sound: true, + }, + android: { + channelId: 'default', + icon: '', + } +} + +const defaultChannel = { + name: 'Clinic Appointments', + sound: true, + priority: 'high', + vibrate: true, + badge: true +} + +const createDefaultChannel = () => { + Notifications.createChannelAndroidAsync('default', defaultChannel) +} + +const scheduleAppointmentConfirmationPN = () => { + const appointmentConfirmationNotif = _.merge({ + title: 'Can you make it?', + body: "Looks like you're still some ways away. Please confirm you can still make your appointment." + }, defaultNotif) + + Notifications.scheduleLocalNotificationAsync(appointmentConfirmationNotif, { + time: (new Date()).getTime() + 3000 + }) +} + +const scheduleAvailableAppointment = () => { + const availableAppointmentNotif = _.merge({ + title: 'Available Appointment @ 0900hrs', + body: 'Snap up this slot now!', + data: { + availableAppointment: true + } + }, defaultNotif) + + Notifications.scheduleLocalNotificationAsync(availableAppointmentNotif, { + time: (new Date()).getTime() + 3000 + }) +} + +export default { + createDefaultChannel, + scheduleAppointmentConfirmationPN, + scheduleAvailableAppointment +} \ No newline at end of file diff --git a/app/views/AppointmentBookedView.js b/app/views/AppointmentBookedView.js new file mode 100644 index 0000000..02c4da3 --- /dev/null +++ b/app/views/AppointmentBookedView.js @@ -0,0 +1,26 @@ +import React from 'react' +import { View, StyleSheet } from 'react-native' + +import HeaderText from 'app/components/HeaderText' + +class AppointmentBookedView extends React.Component { + render(){ + return ( + + Appointment Booked + 1100hrs @ Westminster Clinic + + ) + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#fff', + alignItems: 'center', + justifyContent: 'center', + } +}) + +export default AppointmentBookedView diff --git a/app/views/BookAppointmentView.js b/app/views/BookAppointmentView.js new file mode 100644 index 0000000..5477b95 --- /dev/null +++ b/app/views/BookAppointmentView.js @@ -0,0 +1,60 @@ +import React from 'react' +import { View, StyleSheet, Alert, Button } from 'react-native' + +import HeaderText from 'app/components/HeaderText' +import NormalText from 'app/components/NormalText' +import TimePicker from 'app/components/TimePicker' + +class BookAppointmentView extends React.Component { + static navigationOptions = { + title: 'Book an Appointment' + } + constructor(){ + super() + this.state = { + startTime: '09:00hrs', + endTime: '17:00hrs' + } + } + render(){ + const { startTime, endTime } = this.state + return ( + + Westminster Clinic + + Notify me if there are available appointments between: + + + + and + + +