Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 13 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)
3 changes: 3 additions & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
.expo
*.log
4 changes: 4 additions & 0 deletions app/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { createAppContainer } from 'react-navigation'
import RootNavigator from './RootNavigator'

export default createAppContainer(RootNavigator)
21 changes: 21 additions & 0 deletions app/RootNavigator.js
Original file line number Diff line number Diff line change
@@ -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
27 changes: 27 additions & 0 deletions app/app.json
Original file line number Diff line number Diff line change
@@ -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
}
}
}
Binary file added app/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions app/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = function(api) {
api.cache(true)
return {
"presets": ["babel-preset-expo"]
}
}

18 changes: 18 additions & 0 deletions app/components/HeaderText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'
import { StyleSheet, Text } from 'react-native'

class HeaderText extends React.Component {
render(){
return (
<Text {...this.props} style={styles.headerText} />
)
}
}

const styles = StyleSheet.create({
headerText: {
fontSize: 16
}
})

export default HeaderText
18 changes: 18 additions & 0 deletions app/components/NormalText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'
import { StyleSheet, Text } from 'react-native'

class NormalText extends React.Component {
render(){
return (
<Text {...this.props} style={styles.normalText} />
)
}
}

const styles = StyleSheet.create({
normalText: {
fontSize: 14
}
})

export default NormalText
38 changes: 38 additions & 0 deletions app/components/TimePicker.js
Original file line number Diff line number Diff line change
@@ -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 <Picker.Item key={i} label={label} value={label} />
} else {
const label = `${_.padStart(hour + 9, 2, 0)}:30hrs`
return <Picker.Item key={i} label={label} value={label} />
}

})

return (
<Picker
selectedValue={selectedValue}
style={[styles.picker, style]}
onValueChange={onValueChange}>
{pickerItems}
</Picker>
)
}
}

const styles = StyleSheet.create({
picker: {
}
})

export default TimePicker
21 changes: 21 additions & 0 deletions app/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
56 changes: 56 additions & 0 deletions app/utils/NotificationsManager.js
Original file line number Diff line number Diff line change
@@ -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
}
26 changes: 26 additions & 0 deletions app/views/AppointmentBookedView.js
Original file line number Diff line number Diff line change
@@ -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 (
<View style={styles.container}>
<HeaderText>Appointment Booked</HeaderText>
<NormalText>1100hrs @ Westminster Clinic</NormalText>
</View>
)
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
}
})

export default AppointmentBookedView
60 changes: 60 additions & 0 deletions app/views/BookAppointmentView.js
Original file line number Diff line number Diff line change
@@ -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 (
<View style={styles.container}>
<HeaderText>Westminster Clinic</HeaderText>
<NormalText>
Notify me if there are available appointments between:
</NormalText>
<TimePicker
selectedValue={startTime}
onValueChange={this.onValueChange('startTime')}
/>
<NormalText>
and
</NormalText>
<TimePicker
selectedValue={endTime}
onValueChange={this.onValueChange('endTime')}
/>
<Button
onPress={this.notifyMe}
title="Notify Me"
/>
</View>
)
}
onValueChange = (field) => newVal => this.setState({ [field]: newVal })
notifyMe = () => {
Alert.alert("You're on the waitlist", "We'll notify you if there's an available slot")
this.props.navigation.goBack()
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
padding: 20,
}
})

export default BookAppointmentView
Loading