├── .gitignore ├── .DS_Store ├── notes ├── src ├── .DS_Store ├── assets │ ├── .DS_Store │ ├── blur.jpg │ ├── Blur-600.jpg │ ├── coffee-shop.jpg │ ├── geometry_@2X.png │ ├── giftly │ │ ├── .DS_Store │ │ ├── giftly.png │ │ └── readme.txt │ ├── geometry │ │ ├── .DS_Store │ │ ├── geometry.png │ │ └── readme.txt │ ├── noun_350980_cc.png │ └── geometry2 │ │ ├── geometry2.png │ │ └── readme.txt ├── stylus │ ├── .DS_Store │ └── main.styl ├── about.js ├── salon.js ├── menu.js ├── createUser.js ├── login.js ├── app.js ├── header.js ├── setupServices.js ├── home.js ├── setup.js ├── setupTime.js ├── times.js └── dashboard.js ├── public ├── .DS_Store └── main.css ├── README.md ├── package.json ├── database-json ├── index.html └── gulpfile.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | public/app.js -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/.DS_Store -------------------------------------------------------------------------------- /notes: -------------------------------------------------------------------------------- 1 | notes 2 | 3 | setupTime: 4 | -allow user to add time for each stylist name 5 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/.DS_Store -------------------------------------------------------------------------------- /public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/public/.DS_Store -------------------------------------------------------------------------------- /src/assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/.DS_Store -------------------------------------------------------------------------------- /src/assets/blur.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/blur.jpg -------------------------------------------------------------------------------- /src/stylus/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/stylus/.DS_Store -------------------------------------------------------------------------------- /src/assets/Blur-600.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/Blur-600.jpg -------------------------------------------------------------------------------- /src/assets/coffee-shop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/coffee-shop.jpg -------------------------------------------------------------------------------- /src/assets/geometry_@2X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/geometry_@2X.png -------------------------------------------------------------------------------- /src/assets/giftly/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/giftly/.DS_Store -------------------------------------------------------------------------------- /src/assets/geometry/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/geometry/.DS_Store -------------------------------------------------------------------------------- /src/assets/giftly/giftly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/giftly/giftly.png -------------------------------------------------------------------------------- /src/assets/noun_350980_cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/noun_350980_cc.png -------------------------------------------------------------------------------- /src/assets/geometry/geometry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/geometry/geometry.png -------------------------------------------------------------------------------- /src/assets/geometry2/geometry2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sylvianguy/walk-in-app/HEAD/src/assets/geometry2/geometry2.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # walk-in-app 2 | Appointment booking app for beauty salons. Built with React and Firebase 🔥 3 | 4 | Live url : https://walk-in-87122.firebaseapp.com/ 5 | -------------------------------------------------------------------------------- /src/about.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | 4 | export default class About extends React.Component { 5 | render() { 6 | return ( 7 |

This is an ABOOT page!

8 | ) 9 | } 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/salon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default class Salon extends React.Component { 4 | 5 | render() { 6 | return ( 7 |

This is the {this.props.params.client} Salon page!

8 | ) 9 | } 10 | } -------------------------------------------------------------------------------- /src/assets/geometry/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ======================================================== 4 | This pattern is downloaded from www.subtlepatterns.com 5 | If you need more, that's where to get'em. 6 | ======================================================== 7 | 8 | -------------------------------------------------------------------------------- /src/assets/giftly/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ======================================================== 4 | This pattern is downloaded from www.subtlepatterns.com 5 | If you need more, that's where to get'em. 6 | ======================================================== 7 | 8 | -------------------------------------------------------------------------------- /src/assets/geometry2/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ======================================================== 4 | This pattern is downloaded from www.subtlepatterns.com 5 | If you need more, that's where to get'em. 6 | ======================================================== 7 | 8 | -------------------------------------------------------------------------------- /src/menu.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | 4 | export default class Menu extends React.Component { 5 | render() { 6 | return ( 7 |
8 |
this.props.addAppointment()}>
9 |
10 | 15 |
16 |
17 | ) 18 | } 19 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "noted", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "babel-preset-es2015": "^6.13.2", 13 | "babel-preset-react": "^6.11.1", 14 | "babelify": "^7.3.0", 15 | "browser-sync": "^2.14.0", 16 | "browserify": "^13.1.0", 17 | "connect-history-api-fallback": "^1.3.0", 18 | "gulp": "^3.9.1", 19 | "gulp-notify": "^2.2.0", 20 | "gulp-plumber": "^1.1.0", 21 | "gulp-stylus": "^2.6.0", 22 | "react": "^15.3.0", 23 | "react-bootstrap-sweetalert": "^3.0.0", 24 | "react-dom": "^15.3.0", 25 | "react-router": "^2.6.1", 26 | "vinyl-buffer": "^1.0.0", 27 | "vinyl-source-stream": "^1.1.0" 28 | }, 29 | "dependencies": { 30 | "moment": "^2.15.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database-json: -------------------------------------------------------------------------------- 1 | { 2 | //firebase.database.ref(salonName) 3 | //.ref(`${salonName}/employees/${name}`).push({}) 4 | //.ref(`${salonName}/employees/maria`).push({}) 5 | "aCs4qMCI5ahJJOdRyPAdinjZ19Z2": { 6 | } 7 | "stylistics": { 8 | "employees": { 9 | "-2fasdfasfef": { 10 | "name": "Maria", 11 | "availbleTime": { 12 | "0ffsfasff": "10:00am", 13 | "0ffsfasff": "10:00am" 14 | } 15 | } 16 | }, 17 | "services": { 18 | "klfa;lsfj": "Hair" 19 | }, 20 | "bookings": { 21 | "kfdlas": { 22 | "customersName": "Ryan", 23 | "stylist": "Maria", 24 | "time": "10:00am", 25 | "service": "Hair", 26 | "notes": "Needs good hair" 27 | }, 28 | "kfdlas": { 29 | "customersName": "Arianne", 30 | "stylist": "Maria", 31 | "time": "10:30am", 32 | "service": "Hair", 33 | "notes": "Needs good hair" 34 | } 35 | } 36 | }, 37 | "nailedit" : { 38 | "employees": { 39 | 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Walkin App 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const gulp = require('gulp'); 3 | const stylus = require('gulp-stylus'); 4 | const babel = require('babelify'); 5 | const browserify = require('browserify'); 6 | const source = require('vinyl-source-stream'); 7 | const buffer = require('vinyl-buffer'); 8 | const browserSync = require('browser-sync'); 9 | const reload = browserSync.reload; 10 | const historyApiFallback = require('connect-history-api-fallback'); 11 | const notify = require('gulp-notify'); 12 | const plumber = require('gulp-plumber'); 13 | // const moment = require('moment'); 14 | 15 | 16 | gulp.task('js', () => { 17 | return browserify('src/app.js') 18 | .transform('babelify', { 19 | presets: ['es2015','react'] 20 | }) 21 | .bundle() 22 | .on('error',notify.onError({ 23 | message: "Error: <%= error.message %>", 24 | title: 'Error in JS 💀' 25 | })) 26 | .pipe(source('app.js')) 27 | .pipe(buffer()) 28 | .pipe(gulp.dest('public/')) 29 | .pipe(reload({stream:true})); 30 | }); 31 | 32 | gulp.task('styl', function() { 33 | gulp.src('./src/stylus/main.styl') 34 | .pipe(stylus()) 35 | .pipe(gulp.dest('./public/')) 36 | .pipe(reload({stream: true})); 37 | }); 38 | 39 | gulp.task('bs', () => { 40 | browserSync.init({ 41 | server: { 42 | baseDir: './' 43 | }, 44 | middleware: [historyApiFallback()] 45 | }); 46 | }); 47 | 48 | gulp.task('default', ['js','bs', 'styl'], () => { 49 | gulp.watch('src/**/*.js',['js']); 50 | gulp.watch('./src/stylus/*.styl', ['styl']); 51 | // gulp.watch('src/stylus/main.css', reload); 52 | }); 53 | 54 | -------------------------------------------------------------------------------- /src/createUser.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | 4 | export default class createUser extends React.Component { 5 | createUser(e) { 6 | e.preventDefault(); 7 | const user = { 8 | name: this.createName.value, 9 | email: this.createEmail.value, 10 | password: this.createPassword.value, 11 | confirm: this.confirmPassword.value 12 | } 13 | 14 | if(user.password === user.confirm) { 15 | firebase.auth().createUserWithEmailAndPassword(user.email, user.password) 16 | .then((data) => { 17 | console.log(data); 18 | var userId = data.uid; 19 | firebase.database().ref(userId).set({ 20 | name:user.name, 21 | password: user.password, 22 | email: user.email 23 | }) 24 | //push to a new router 25 | this.context.router.push('/times'); 26 | 27 | }) 28 | .catch(function(error) { 29 | var errorCode = error.code; 30 | var errorMessage = error.message; 31 | }); 32 | } 33 | } 34 | render() { 35 | return ( 36 |
37 |
this.createUser.call(this, e)}> 38 |

Create User

39 | this.createName = ref} /> 40 | this.createEmail = ref }/> 41 | this.createPassword = ref }/> 42 | this.confirmPassword = ref }/> 43 | 44 |
45 |
46 | ) 47 | } 48 | } 49 | 50 | createUser.contextTypes = { 51 | router: React.PropTypes.object 52 | } 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/login.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | 4 | export default class Login extends React.Component { 5 | constructor() { 6 | super(); 7 | this.state = { 8 | user: { 9 | email: "", 10 | password: "" 11 | }, 12 | errorMessage: false 13 | } 14 | this.handleChange = this.handleChange.bind(this) 15 | this.loginUser = this.loginUser.bind(this) 16 | } 17 | handleChange(e) { 18 | const ogUser = Object.assign({}, this.state.user); 19 | ogUser[e.target.name] = e.target.value 20 | this.setState({ 21 | user: ogUser 22 | }) 23 | } 24 | loginUser(e) { 25 | e.preventDefault(); 26 | const user = this.state.user; 27 | firebase.auth().signInWithEmailAndPassword(user.email, user.password) 28 | .then((res) => { 29 | const userId = res.uid; 30 | firebase.database().ref(userId) 31 | .on('value', (data) => { 32 | // console.log("lalala", data.val()) - 33 | }) 34 | this.context.router.push('/dashboard'); 35 | }) 36 | .catch((err) => { 37 | this.setState({ 38 | errorMessage: true 39 | }) 40 | }) 41 | } 42 | render() { 43 | const errorMessage = ( 44 |

The password is invalid or the user does not have a password

45 | ) 46 | return ( 47 |
this.loginUser(e)}> 48 |

Log-In

49 | 50 | 51 | 52 | {this.state.errorMessage === true ? errorMessage : null} 53 |
54 | 55 | ) 56 | } 57 | } 58 | 59 | Login.contextTypes = { 60 | router: React.PropTypes.object 61 | } -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import { Route, Router, Link, browserHistory, IndexRoute } from 'react-router'; 4 | import About from './about'; 5 | import Salon from './salon'; 6 | import Home from './home'; 7 | import Login from './login'; 8 | import CreateUser from './createUser'; 9 | import Setup from './setup'; 10 | import SetupTime from './setupTime'; 11 | import SetupServices from './setupServices'; 12 | import Dashboard from './dashboard'; 13 | import Header from './header'; 14 | import Times from './times'; 15 | 16 | class App extends React.Component { 17 | constructor() { 18 | super(); 19 | this.state = { 20 | userAuth: [] 21 | }; 22 | var config = { 23 | apiKey: "AIzaSyACnQ3DNs0ye0yrgLGC6ispWgbOeUHFdM8", 24 | authDomain: "walk-in-87122.firebaseapp.com", 25 | databaseURL: "https://walk-in-87122.firebaseio.com", 26 | storageBucket: "walk-in-87122.appspot.com", 27 | messagingSenderId: "789650229559" 28 | }; 29 | firebase.initializeApp(config); 30 | } 31 | 32 | componentDidMount() { 33 | //check to see if user is logged in 34 | 35 | } 36 | 37 | render() { 38 | const header =
39 | return ( 40 |
41 | {header} 42 |
43 | {this.props.children} 44 |
45 |
46 | 47 | ) 48 | } 49 | 50 | } 51 | 52 | ReactDom.render( 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | , document.getElementById('app')); 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | import Menu from './menu'; 4 | 5 | export default class Header extends React.Component{ 6 | constructor() { 7 | super(); 8 | this.state = { 9 | signedIn: false, 10 | userName: '' 11 | } 12 | this.signOut = this.signOut.bind(this) 13 | } 14 | componentDidMount() { 15 | firebase.auth().onAuthStateChanged((user) => { 16 | var userId = user.uid 17 | console.log(user) 18 | firebase.database().ref(userId) 19 | .on('value', (res) => { 20 | // console.log("what", res.val()) 21 | this.setState({ 22 | userName: res.val().name 23 | }) 24 | }) 25 | 26 | const currentUser = firebase.auth().currentUser; 27 | // console.log("curee", currentUser 28 | if(currentUser === null) { 29 | console.log("not logged in") 30 | this.setState({ 31 | signedIn: false 32 | }) 33 | }else { 34 | console.log("logged In") 35 | this.setState({ 36 | signedIn: true 37 | }) 38 | } 39 | }) 40 | } 41 | signOut() { 42 | console.log("sign out") 43 | firebase.auth().signOut() 44 | .then(() => { 45 | console.log("success"); 46 | this.setState({ 47 | signedIn: false 48 | }) 49 | this.context.router.push('/'); 50 | }) 51 | .catch((err) => { 52 | console.log("error"); 53 | }) 54 | } 55 | render() { 56 | const loggedIn = this.signOut()}>Sign Out; 57 | const loggedOut = Sign In; 58 | const createAccount = Create Account; 59 | const greeting =

Hello, {this.state.userName}!

; 60 | const showLoginInfo = ( 61 |
62 | {this.state.signedIn ? greeting : null} 63 | {this.state.signedIn ? null : createAccount} 64 | {this.state.signedIn ? loggedIn : loggedOut} 65 |
66 | ) 67 | return ( 68 |
69 |
70 |

W

71 | {this.props.location !== '/' ? showLoginInfo : null} 72 |
73 |
74 | ) 75 | } 76 | } 77 | 78 | Header.contextTypes = { 79 | router: React.PropTypes.object 80 | } -------------------------------------------------------------------------------- /src/setupServices.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | 4 | export default class setupServices extends React.Component { 5 | constructor() { 6 | super(); 7 | this.state = { 8 | services: [], 9 | currentServices: '' 10 | } 11 | } 12 | 13 | componentDidMount() { 14 | firebase.auth().onAuthStateChanged((user) => { 15 | firebase.database().ref(`${user.uid}/services`) 16 | .on('value', (res) => { 17 | const allData = res.val(); 18 | console.log("what", res.val()) 19 | const allDataArray = []; 20 | for(let key in allData) { 21 | allDataArray.push({ 22 | key: key, 23 | service: allData[key] 24 | }) 25 | } 26 | 27 | this.setState({ 28 | services: allDataArray 29 | }) 30 | 31 | }) 32 | }) 33 | } 34 | 35 | removeServices(serviceToRemove) { 36 | // const currentKey = servicesToRemove.key 37 | const currentUser = firebase.auth().currentUser; 38 | 39 | firebase.database().ref(`${currentUser.uid}/services/${serviceToRemove.key}`).remove(); 40 | } 41 | 42 | addServices(e) { 43 | e.preventDefault(); 44 | const inputValue = this.createService.value; 45 | 46 | const currentState = this.state.services 47 | currentState.push(inputValue); 48 | 49 | 50 | this.setState({ 51 | services: currentState 52 | }) 53 | 54 | 55 | const currentUser = firebase.auth().currentUser; 56 | if(currentUser) { 57 | firebase.database().ref(`${currentUser.uid}/services`) 58 | .push(inputValue) 59 | } 60 | 61 | } 62 | render() { 63 | return ( 64 |
65 |
66 |

Add your services here

67 |
this.addServices.call(this, e)}> 68 | this.createService = ref}/> 69 |
70 | 71 |
72 |
73 |
74 | {this.state.services.map((service, i) =>{ 75 | return ( 76 |
77 | 78 | this.removeServices.call(this, service)}> 79 |

{service.service}

80 |
81 |
82 | ) 83 | })} 84 |
85 | NEXT 86 |
87 | ) 88 | } 89 | } -------------------------------------------------------------------------------- /src/home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | 4 | export default class Home extends React.Component { 5 | constructor() { 6 | super(); 7 | this.state = { 8 | user: { 9 | email: "", 10 | password: "" 11 | } 12 | } 13 | this.handleChange = this.handleChange.bind(this) 14 | this.signInGoogle = this.signInGoogle.bind(this) 15 | this.handleSubmit = this.handleSubmit.bind(this) 16 | this.signInFacebook = this.signInFacebook.bind(this) 17 | this.signInWithEmail = this.signInWithEmail.bind(this) 18 | } 19 | handleChange(e) { 20 | const ogUser = Object.assign({}, this.state.user); 21 | ogUser[e.target.name] = e.target.value 22 | this.setState({ 23 | user: ogUser 24 | }) 25 | } 26 | signInGoogle(e) { 27 | e.preventDefault() 28 | const provider = new firebase.auth.GoogleAuthProvider(); 29 | firebase.auth().signInWithPopup(provider).then(function(result) { 30 | // This gives you a Google Access Token. You can use it to access the Google API. 31 | const token = result.credential.accessToken; 32 | // The signed-in user info. 33 | const user = result.user; 34 | this.context.router.push('/setup'); 35 | // ... 36 | }).catch(function(error) { 37 | // Handle Errors here. 38 | const errorCode = error.code; 39 | const errorMessage = error.message; 40 | // The email of the user's account used. 41 | const email = error.email; 42 | // The firebase.auth.AuthCredential type that was used. 43 | const credential = error.credential; 44 | // ... 45 | }); 46 | } 47 | signInFacebook(e) { 48 | e.preventDefault(); 49 | var provider = new firebase.auth.FacebookAuthProvider(); 50 | firebase.auth().signInWithPopup(provider).then(function(result) { 51 | // This gives you a Facebook Access Token. You can use it to access the Facebook API. 52 | var token = result.credential.accessToken; 53 | // The signed-in user info. 54 | var user = result.user; 55 | // ... 56 | }).catch(function(error) { 57 | // Handle Errors here. 58 | var errorCode = error.code; 59 | var errorMessage = error.message; 60 | // The email of the user's account used. 61 | var email = error.email; 62 | // The firebase.auth.AuthCredential type that was used. 63 | var credential = error.credential; 64 | // ... 65 | }); 66 | } 67 | signInWithEmail() { 68 | // e.preventDefault(); 69 | const user = this.state.user; 70 | firebase.auth().signInWithEmailAndPassword(user.email, user.password) 71 | .then((res) => { 72 | const userId = res.uid; 73 | firebase.database().ref(userId) 74 | .on('value', (data) => { 75 | console.log("lalala", data.val()) 76 | }) 77 | this.context.router.push('/dashboard'); 78 | }) 79 | .catch((err) => { 80 | this.setState({ 81 | errorMessage: true 82 | }) 83 | }) 84 | } 85 | handleSubmit(e) { 86 | console.log("does it work?"); 87 | e.preventDefault(); 88 | } 89 | render() { 90 | return ( 91 |
92 |
93 |
94 |
95 |

Log-In

96 |

Please login with your email and password!

97 | 98 | 99 |
100 | 101 | 102 |
103 |
104 |

OR

105 | 106 | 107 |
108 |
109 |
110 |
111 |

W

112 |

Welcome to the Walk-in app

113 |
114 |
115 |
116 | ) 117 | } 118 | } 119 | 120 | Home.contextTypes = { 121 | router: React.PropTypes.object 122 | } -------------------------------------------------------------------------------- /src/setup.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | 4 | export default class Setup extends React.Component { 5 | 6 | constructor() { 7 | super(); 8 | this.state = { 9 | employees: [], 10 | allTimeSlots: [], 11 | handleModal: false, 12 | employeeKey: '', 13 | } 14 | this.handleModal = this.handleModal.bind(this); 15 | this.displayModal = this.displayModal.bind(this); 16 | this.closeModal = this.closeModal.bind(this); 17 | this.addTime = this.addTime.bind(this) 18 | } 19 | componentDidMount() { 20 | //whenever a value is a changed, tell us about it! 21 | firebase.auth().onAuthStateChanged((user) => { 22 | const theCurrentUser = firebase.auth().currentUser; 23 | firebase.database().ref(`${theCurrentUser.uid}/employees`) 24 | .on('value', (res) => { 25 | const userData = res.val(); 26 | const dataArray = []; 27 | 28 | for(let key in userData) { 29 | userData[key].key = key; 30 | dataArray.push(userData[key]); 31 | } 32 | this.setState({ 33 | employees: dataArray 34 | }) 35 | }); 36 | 37 | firebase.database().ref(`${theCurrentUser.uid}/times`) 38 | .on('value', (res) => { 39 | console.log("value", res.val()) 40 | this.setState({ 41 | allTimeSlots: res.val() 42 | }) 43 | }) 44 | }); 45 | } 46 | 47 | handleModal(employee) { 48 | this.setState({ 49 | handleModal: true, 50 | employeeKey: employee.key 51 | }) 52 | } 53 | 54 | closeModal() { 55 | this.setState({ 56 | handleModal: false 57 | }) 58 | } 59 | 60 | addTime(value) { 61 | console.log(value) 62 | const employeeKey = this.state.employeeKey 63 | const currentUser = firebase.auth().currentUser; 64 | const currentUserId = currentUser.uid; 65 | if(currentUser) { 66 | firebase.database().ref(`${currentUserId}/employees/${employeeKey}/times`) 67 | .push({ 68 | time: value, 69 | booked: false 70 | }); 71 | } 72 | } 73 | 74 | displayModal() { 75 | const timeSlots = this.state.allTimeSlots; 76 | 77 | return ( 78 |
79 |
80 | 81 |
    82 | {timeSlots.map((item, i) => { 83 | return
  • this.addTime(item)} className="timesGrid__single timesGrid__single--inactive">{item}
  • 84 | })} 85 |
86 | 87 |
88 |
89 | ) 90 | 91 | } 92 | 93 | addEmployees(e) { 94 | e.preventDefault(); 95 | 96 | const employee = { 97 | //create this after you have created the ref in input 98 | name: this.createEmployee.value 99 | } 100 | //clear my input on submit 101 | this.createEmployee.value = ""; 102 | let newEmployees = []; 103 | const employeeName = employee.name; 104 | const currentState = this.state.employees; 105 | 106 | newEmployees = currentState; 107 | const pushed = newEmployees.push(employeeName); 108 | 109 | this.setState({ 110 | employees: newEmployees 111 | }) 112 | 113 | const theCurrentUser = firebase.auth().currentUser 114 | const currentUserId = theCurrentUser.uid 115 | 116 | if(theCurrentUser) { 117 | firebase.database().ref(`${currentUserId}/employees`) 118 | //pushing single employee rather than the whole list 119 | .push(employee); 120 | } 121 | } 122 | removeEmployee(employeeToRemove) { 123 | const currentUser = firebase.auth().currentUser; 124 | firebase.database().ref(`${currentUser.uid}/employees/${employeeToRemove.key}`).remove(); 125 | } 126 | render() { 127 | return ( 128 |
129 |

Setup all of your stuff here

130 |
131 |
this.addEmployees.call(this, e)}> 132 | this.addEmployees.call(this, e)}> 133 | this.createEmployee = ref}/> 134 |
135 |

Employees:

136 | {this.state.employees.map((employee, i) => { 137 | return ( 138 |
139 |
140 | this.removeEmployee.call(this, employee) }> 141 |

{employee.name}

142 |
143 |
144 | 145 | 146 |

this.handleModal(employee)}>Add time

147 |
148 |
149 |
150 | ) 151 | })} 152 |
{this.displayModal()}
153 |
154 | NEXT 155 |
156 | ) 157 | } 158 | } -------------------------------------------------------------------------------- /src/setupTime.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | 4 | 5 | export default class setupTime extends React.Component { 6 | 7 | constructor() { 8 | super(); 9 | this.state = { 10 | times: [], 11 | employees: [], 12 | currentEmployee: '', 13 | currentEmployeeName: '', 14 | currentTimeId: [], 15 | color: 'button' 16 | } 17 | } 18 | componentDidMount() { 19 | firebase.auth().onAuthStateChanged((user) => { 20 | const currentUser = firebase.auth().currentUser; 21 | firebase.database().ref(`${currentUser.uid}/employees`) 22 | .on('value', (res) => { 23 | 24 | const employeeData = res.val(); 25 | const dataArray = []; 26 | 27 | //loop over the employeeData 28 | for(let key in employeeData) { 29 | 30 | employeeData[key].key = key; 31 | dataArray.push(employeeData[key]) 32 | } 33 | this.setState({ 34 | employees: dataArray 35 | }) 36 | }) 37 | }) 38 | } 39 | 40 | handleClick(target) { 41 | // const dataArray = target.classList; 42 | target.classList.toggle('button--active'); 43 | } 44 | addTime(e) { 45 | e.preventDefault(); 46 | 47 | //store the value on the input 48 | const time = this.createTime.value 49 | 50 | // console.log("TIME", time); 51 | const timeArray = []; 52 | const totalTimes = timeArray.push(time); 53 | //call FUNCTION and pass in the time value here 54 | 55 | const currentUser = firebase.auth().currentUser; 56 | const currentUserId = currentUser.uid; 57 | if(currentUser) { 58 | firebase.database().ref(`${currentUserId}/employees/${this.state.currentEmployee}/times`) 59 | //pushing single employee rather than the whole list 60 | .push({ 61 | time: time, 62 | booked: false 63 | }); 64 | this.createTime.value = ''; 65 | } 66 | 67 | 68 | // const moment = require('moment'); 69 | // const blah = moment().format('MMMM Do YYYY, h:mm:ss a'); 70 | } 71 | getEmployeeObj(employeeId) { 72 | //get that specific object from the employee from firebase 73 | //get that data from the employee that was clicked on 74 | let employeeInfo = []; 75 | const currentState = this.state.times; 76 | employeeInfo = currentState; 77 | employeeInfo.push(employeeId) 78 | 79 | this.setState({ 80 | times: employeeInfo 81 | }) 82 | 83 | } 84 | 85 | //GETS THE PERSON ID 86 | chooseEmployee(personId,e) { 87 | //Now that we have the employee 88 | //We want to somehow track that that is the one we selected 89 | 90 | //THIS FUNCTIONALITY WILL NOT BE IN HERE! 91 | //We need to save the employee key somehow 92 | const selectedEmployee = personId.key; 93 | const selectedEmployeeName = personId.name 94 | console.log('employee', selectedEmployee); 95 | 96 | console.log("person id", personId) 97 | 98 | this.setState({ 99 | currentEmployee: selectedEmployee 100 | }); 101 | 102 | this.setState({ 103 | currentEmployeeName: selectedEmployeeName 104 | }) 105 | 106 | // this.handleClick.call(this,e.target); 107 | 108 | 109 | //And reference that key(state) in another function. 110 | 111 | 112 | } 113 | removeTime(timeToRemove) { 114 | console.log("time to remove", timeToRemove); 115 | const testing = this.state.currentTimeId; 116 | console.log("what is this?", testing) 117 | 118 | // timeToRemove.remove(); 119 | const currentUser = firebase.auth().currentUser; 120 | //get the key that was clicked on 121 | //use the time to remove after we have found the key 122 | 123 | firebase.database().ref(`${currentUser.uid}/employees/${this.state.currentEmployee}/times/${timeToRemove.key}`).remove(); 124 | console.log(`${currentUser.uid}/employees/${this.state.currentEmployee}/times/${timeToRemove.key}`); 125 | 126 | } 127 | 128 | renderTime(times) { 129 | const timesArray = []; 130 | const keyArray = []; 131 | const combo = []; 132 | 133 | for(let key in times) { 134 | timesArray.push({ 135 | times: times[key], 136 | key: key 137 | }) 138 | keyArray.push(key) 139 | } 140 | console.log(timesArray); 141 | return ( 142 | timesArray.map((item) => { 143 | return ( 144 |
145 | this.removeTime.call(this, item) }> 146 |
  • {item.times.time}
  • 147 |
    148 | ) 149 | }) 150 | 151 | ) 152 | 153 | } 154 | render() { 155 | return ( 156 |
    157 |

    Step 2: Set up available time for employees.

    158 |
    this.addTime.call(this, e)}> 159 | this.createTime = ref} /> 160 |
    161 | 162 |
    163 | 164 |
    165 |
    166 | {this.state.employees.map((item, i) => { 167 | 168 | return ( 169 |
    170 |
    171 | 172 |

    this.chooseEmployee.call(this, item,e)}>{item.name}

    173 |
    174 |
      175 | {this.renderTime(item.times)} 176 |
    177 |
    178 |
    179 | ) 180 | })} 181 | NEXT 182 |
    183 |
    184 | ) 185 | 186 | } 187 | } -------------------------------------------------------------------------------- /src/times.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | import Menu from './menu'; 4 | 5 | export default class Times extends React.Component { 6 | constructor() { 7 | super(); 8 | this.state = { 9 | getStartTime: '', 10 | getEndTime: '', 11 | timeSlots: [], 12 | currentTimeSlots: [], 13 | toggleMenu: false 14 | } 15 | this.increment = this.increment.bind(this); 16 | this.getStartTime = this.getStartTime.bind(this); 17 | this.getEndTime = this.getEndTime.bind(this); 18 | this.renderTimes = this.renderTimes.bind(this); 19 | this.addTimes = this.addTimes.bind(this); 20 | this.showMenu = this.showMenu.bind(this) 21 | this.hideMenu = this.hideMenu.bind(this) 22 | } 23 | componentDidMount() { 24 | firebase.auth().onAuthStateChanged((user) => { 25 | const theCurrentUser = firebase.auth().currentUser; 26 | const currentUserId = theCurrentUser.uid; 27 | console.log(currentUserId) 28 | firebase.database().ref(`${theCurrentUser.uid}/times`) 29 | .on('value', (res) => { 30 | const results = res.val(); 31 | console.log("ressssss", results); 32 | this.setState({ 33 | currentTimeSlots: results 34 | }) 35 | }) 36 | 37 | 38 | }); 39 | function call(pagenum) { 40 | return $.ajax 41 | } 42 | 43 | const arrayOfCalls = [] 44 | 45 | for(i = 0; i < 4; i++) { 46 | arrayOfCalls.push(call(25)) 47 | } 48 | 49 | Promise.All(arrayOfCalls) 50 | .then(res => { 51 | console.log(res); 52 | }) 53 | 54 | 55 | // firebase.auth().onAuthStateChanged((user) => { 56 | // firebase.database().ref(`${theCurrentUser.uid}/employees`) 57 | // .on('value', (res) => { 58 | // console.log("ssss", res.val()) 59 | // // const times = res.val(); 60 | // // const timesArray = Object.keys(times); 61 | // // console.log("key",times[timesArray]) 62 | // // this.setState({ 63 | // // currentTimeSlots: times[timesArray] 64 | // // }) 65 | // // times.timesArray 66 | 67 | 68 | // }) 69 | // }) 70 | } 71 | 72 | showMenu() { 73 | this.setState({ 74 | toggleMenu: true 75 | }) 76 | } 77 | 78 | hideMenu() { 79 | this.setState({ 80 | toggleMenu: false 81 | }) 82 | } 83 | 84 | 85 | addTimes(e) { 86 | e.preventDefault(); 87 | // console.log("lala", this.state.timeSlots) 88 | const currentUser = firebase.auth().currentUser; 89 | 90 | //when you add times 91 | console.log("CURRE", this.state.currentTimeSlots) 92 | //remove times in database 93 | //add times in database 94 | 95 | 96 | if(currentUser) { 97 | firebase.database().ref(`${currentUser.uid}/times`) 98 | 99 | .set(this.state.timeSlots) 100 | } 101 | } 102 | getStartTime(e) { 103 | console.log("this working?") 104 | const startTime = parseInt(e.target.value) 105 | this.setState({ 106 | getStartTime: startTime 107 | }) 108 | } 109 | getEndTime(e) { 110 | const endTime = parseInt(e.target.value); 111 | this.setState({ 112 | getEndTime: endTime 113 | }) 114 | } 115 | 116 | increment(e) { 117 | let incrementBy = parseInt(e.target.value); 118 | console.log("lalalla", incrementBy) 119 | let startTime = this.state.getStartTime; 120 | const endTime = this.state.getEndTime; 121 | const times = []; 122 | var ap = ['AM', 'PM'] 123 | 124 | //get the start and end number i.e 10:00am - 9:00pm 125 | let done = true; 126 | let i = 0; 127 | let startMin = 0; 128 | let hour = startTime; 129 | while(done) { 130 | startMin = startMin + incrementBy; 131 | if(startMin >= 60) { 132 | startMin = 0; 133 | hour++; 134 | } 135 | 136 | times[i] = ('0' + hour) + ':' + (startMin === 0 ? "00" : startMin); 137 | if(hour >= endTime) { 138 | done = false; 139 | } 140 | i++; 141 | } 142 | this.setState({ 143 | timeSlots: times 144 | }) 145 | 146 | this.renderTimes(); 147 | 148 | } 149 | 150 | renderTimes() { 151 | 152 | if(this.state.timeSlots !== '') { 153 | return this.state.currentTimeSlots.map((item, i) => { 154 | console.log("the time") 155 | return
  • {item}
  • 156 | }) 157 | } 158 | } 159 | 160 | render(){ 161 | let saveBtn = () 162 | return ( 163 |
    164 | 165 |
    166 |
    167 | 182 | 197 | 205 |
    206 |

    Available time slots:

    207 |
      208 | {this.renderTimes()} 209 | 210 |
    211 | 212 | Next 213 |
    214 | 215 |
    216 | ) 217 | } 218 | } -------------------------------------------------------------------------------- /src/dashboard.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | import SweetAlert from 'react-bootstrap-sweetalert'; 4 | import Menu from './menu'; 5 | // import {} 6 | 7 | export default class Dashboard extends React.Component { 8 | constructor() { 9 | super(); 10 | this.state = { 11 | currentUser: '', 12 | currentUserId: '', 13 | customerName: [], 14 | selectedObj: [], 15 | stylists: [], 16 | selectedStylist: [], 17 | stylistTimes: {}, 18 | services: [], 19 | chosenTime: "", 20 | service: "", 21 | bookingInfo: [], 22 | removeModal: false, 23 | personId: "", 24 | alert: null, 25 | addAppModal: false, 26 | toggleMenu: false 27 | } 28 | this.customerName = this.customerName.bind(this) 29 | this.bookAppointment = this.bookAppointment.bind(this) 30 | this.addAppointment = this.addAppointment.bind(this) 31 | this.closeAppModal = this.closeAppModal.bind(this) 32 | this.showMenu = this.showMenu.bind(this) 33 | this.hideMenu = this.hideMenu.bind(this) 34 | } 35 | 36 | componentDidMount() { 37 | firebase.auth().onAuthStateChanged((user) => { 38 | const theCurrentUser = firebase.auth().currentUser; 39 | const currentUserId = theCurrentUser.uid; 40 | this.setState({ 41 | currentUser: theCurrentUser, 42 | currentUserId 43 | }) 44 | 45 | firebase.database().ref(`${theCurrentUser.uid}/employees`) 46 | .on('value', (res) => { 47 | const userData = res.val(); 48 | // console.log("current", userData); 49 | const dataArray = []; 50 | const bookingTime = []; 51 | 52 | for(let key in userData) { 53 | const timesObj = userData[key].times; 54 | dataArray.push({ 55 | key: key, 56 | name: userData[key].name, 57 | times: userData[key].times 58 | }) 59 | } 60 | 61 | this.setState({ 62 | stylists: dataArray, 63 | justTimes: bookingTime 64 | }) 65 | 66 | }), 67 | firebase.database().ref(`${theCurrentUser.uid}/services`) 68 | .on('value', (res) => { 69 | const servicesArray = [] 70 | const servicesData = res.val(); 71 | 72 | for(let key in servicesData) { 73 | servicesArray.push({ 74 | key: key, 75 | serviceName: servicesData[key] 76 | }) 77 | 78 | } 79 | 80 | this.setState({ 81 | services: servicesArray 82 | }) 83 | 84 | }) 85 | 86 | }) 87 | } 88 | showMenu() { 89 | console.log("mousing over"); 90 | this.setState({ 91 | toggleMenu: true 92 | }) 93 | } 94 | hideMenu() { 95 | this.setState({ 96 | toggleMenu: false 97 | }) 98 | } 99 | customerName(e) { 100 | console.log(e.target.value); 101 | this.setState({ 102 | customerName: e.target.value 103 | }) 104 | } 105 | 106 | closeAppModal() { 107 | this.setState({ 108 | addAppModal: false, 109 | toggleMenu: false 110 | }) 111 | } 112 | 113 | addAppointment() { 114 | this.setState({ 115 | addAppModal: true, 116 | toggleMenu: true 117 | }) 118 | } 119 | removeAppointment(removedInfo) { 120 | const stylists = this.state.stylists; 121 | const currentUser = this.state.currentUser; 122 | const currentUserId = this.state.currentUserId; 123 | 124 | if(currentUser) { 125 | firebase.database().ref(`${currentUserId}/employees/${this.state.personId}/times/${removedInfo.key}/bookingInfo`).remove(); 126 | } 127 | 128 | if(currentUser) { 129 | firebase.database().ref(`${currentUserId}/employees/${this.state.personId}/times/${removedInfo.key}`).update({ 130 | booked: false 131 | }); 132 | } 133 | 134 | this.setState({ 135 | removeModal: true 136 | }) 137 | } 138 | 139 | bookAppointment(e) { 140 | e.preventDefault(); 141 | const selectedObj = this.state.selectedObj 142 | const currentUser = this.state.currentUser; 143 | const currentUserId = this.state.currentUserId; 144 | const chosenTime = this.state.chosenTime; 145 | const customerName = this.state.customerName; 146 | const notes = this.createNote.value; 147 | const service = this.state.service; 148 | 149 | if(currentUser) { 150 | firebase.database().ref(`${currentUserId}/employees/${selectedObj.key}/times/${chosenTime}/bookingInfo`).set({ 151 | customerName, 152 | service, 153 | notes 154 | }); 155 | } 156 | 157 | if(currentUser) { 158 | firebase.database().ref(`${currentUserId}/employees/${selectedObj.key}/times/${chosenTime}`).update({ 159 | booked:true 160 | }); 161 | } 162 | 163 | } 164 | 165 | getAvailability() { 166 | const stylistName = { 167 | name: this.selectedStylist.value 168 | } 169 | //filtering stylists ??? 170 | let filteredStylist = this.state.stylists.filter((style) => { 171 | return style.name === stylistName.name; 172 | }); 173 | 174 | filteredStylist = filteredStylist[0]; 175 | this.setState({ 176 | selectedStylist: stylistName, 177 | stylistTimes: filteredStylist.times, 178 | selectedObj: filteredStylist 179 | }); 180 | 181 | } 182 | 183 | renderTimes() { 184 | const times = this.state.stylistTimes 185 | const timesArray = [] 186 | for(let key in times) { 187 | timesArray.push({ 188 | key: key, 189 | time: times[key] 190 | }) 191 | } 192 | return ( 193 | timesArray.map((time, i) => { 194 | if(time.time.booked !== true) { 195 | return 196 | 197 | } 198 | }) 199 | ) 200 | } 201 | 202 | chooseTime() { 203 | const time = this.selectedTimes.value; 204 | const stylistList = this.state.stylistTimes; 205 | const timesArray = []; 206 | 207 | for(let key in stylistList) { 208 | timesArray.push({ 209 | key: key, 210 | time: stylistList[key] 211 | }) 212 | } 213 | let filteredTime = timesArray.filter((item) => { 214 | return item.time.time === time; 215 | }) 216 | this.setState({ 217 | chosenTime: filteredTime[0].key 218 | }) 219 | } 220 | 221 | getServices() { 222 | //get list of services from firebase 223 | const services = this.state.services; 224 | 225 | this.setState({ 226 | service: this.selectedService.value 227 | }) 228 | } 229 | getTimes() { 230 | const allTimes = this.state.stylists 231 | return ( 232 | allTimes.map((time) => { 233 | // console.log("what", time) 234 | const timesArray = []; 235 | for(let key in time.times) { 236 | //ONLY display time if it is booked 237 | if( time.times[key].booked !== false) { 238 | timesArray.push(time.times[key].time); 239 | } 240 | } 241 | return ( 242 |
    243 |

    {time.name}

    244 | 253 |
    254 | ) 255 | }) 256 | ) 257 | 258 | } 259 | 260 | displayModal() { 261 | const bookingInfo = this.state.bookingInfo 262 | const allTimes = this.state.stylists 263 | const info = bookingInfo[0]; 264 | const bookingArray = []; 265 | if(info) { 266 | // console.log('displaymodal', info.service) 267 | return ( 268 |
    269 |
    270 | this.closeModal.call(this)} className="fa fa-times" aria-hidden="true"> 271 |

    Stylist: {info.stylistName}

    272 |

    Time: {info.time}

    273 |

    Client Name: {info.clientName}

    274 |

    Service: {info.service}

    275 |

    Notes: {info.notes}

    276 | 277 |
    278 |
    279 | ) 280 | } 281 | 282 | 283 | } 284 | 285 | closeModal() { 286 | this.setState({ 287 | removeModal: true 288 | }) 289 | } 290 | 291 | bookingModal(e,person,bookedTime) { 292 | this.setState({ 293 | removeModal: false, 294 | personId: person.key 295 | }) 296 | const time = bookedTime; 297 | const stylistName = person.name; 298 | const bookedTimes = person.times 299 | const dataArray = []; 300 | 301 | for(let key in bookedTimes){ 302 | // timesArray.push(bookedTimes[key].time) 303 | if (bookedTimes[key].time === time) { 304 | const bookingInfo = bookedTimes[key].bookingInfo; 305 | const customerName = bookingInfo.customerName; 306 | dataArray.push({ 307 | stylistName: stylistName, 308 | clientName: bookingInfo.customerName, 309 | service: bookingInfo.service, 310 | notes: bookingInfo.notes, 311 | time, 312 | key 313 | 314 | }) 315 | 316 | 317 | } 318 | } 319 | this.setState({ 320 | bookingInfo: dataArray 321 | }) 322 | } 323 | 324 | sweetAlert() { 325 | this.setState({ 326 | alert: ( this.hideAlert()}> 327 | Appointment booked! 328 | ) 329 | }); 330 | 331 | } 332 | hideAlert() { 333 | this.setState({ 334 | alert: null, 335 | addAppModal: false 336 | }); 337 | } 338 | render() { 339 | return ( 340 |
    341 |
    342 |
    343 |
    this.bookAppointment(e)}> 344 | this.closeAppModal()}> 345 |
    346 | 350 | 361 | 371 | 372 |
    373 |
    374 | 381 |

    Additional Notes

    382 |