132 Komitmen 61e76f3359 ... 0b0369e272

Pembuat SHA1 Pesan Tanggal
  Boris K 0b0369e272 test merge dev 5 tahun lalu
  Boris K 7e16f4071d merge 5 tahun lalu
  Boris K 0ac2e4e956 reworked changeUser 5 tahun lalu
  Boris K d4c4141dad reworked changeUser 5 tahun lalu
  Mila-Zagrevskaya 4c543710da change order form 5 tahun lalu
  Alex 0b5e218e74 Merge branch 'Alex' into dev 5 tahun lalu
  Alex b5afb9cd68 fix bug with protected route 5 tahun lalu
  Mila-Zagrevskaya 836fef0944 some 5 tahun lalu
  Alex 66f243a1e7 Merge branch 'dev' of http://gitlab.a-level.com.ua/Entony/FEA_12_CLINIC into dev 5 tahun lalu
  Alex f710f751b7 add user style 5 tahun lalu
  Boris K add06e0cf9 minore changes in changeOrders 5 tahun lalu
  Boris K 8f0ae3beea added confirm button to changeOrders 5 tahun lalu
  Boris K 75a4d641fa finished changeOrder functionality / admin-orders-changeOrders 5 tahun lalu
  Mila-Zagrevskaya dba80fa418 some changes 5 tahun lalu
  Mila-Zagrevskaya 2e0c645843 confirm buttons 5 tahun lalu
  Mila-Zagrevskaya 566d4811c0 changed admin-part orders, users 5 tahun lalu
  Mila-Zagrevskaya 911521b96a some 5 tahun lalu
  Mila-Zagrevskaya df3d508e3b changed select, admin-panel, appoitmet, main-page, page-not-found 5 tahun lalu
  Alex bdbaec2c60 full user component without markup 5 tahun lalu
  Alex 97af7b530f fix merge conflicts 5 tahun lalu
  Alex f5707f272f add user info 5 tahun lalu
  Mila-Zagrevskaya 0b4781cc14 Merge branch 'dev' of http://gitlab.a-level.com.ua/Entony/FEA_12_CLINIC into mila 5 tahun lalu
  Boris K a1634a1419 added orders page to admin. Some minore changes at reducers 5 tahun lalu
  Mila-Zagrevskaya 2bc51f0a5c Merge branch 'dev' of http://gitlab.a-level.com.ua/Entony/FEA_12_CLINIC into mila 5 tahun lalu
  Alex 63e173f401 merge completed 5 tahun lalu
  Alex c41ba08740 ... 5 tahun lalu
  Alex 175719302f add basic, orders, user 5 tahun lalu
  Mila-Zagrevskaya b4ae670b82 some changes 5 tahun lalu
  Boris K df3d0557c1 some minor changes at main reducer 5 tahun lalu
  Boris K 9a53d59804 created new action/reucer for shedule, added auto renew data with all post/put/delete 5 tahun lalu
  Boris K e741a48938 changeUser - deleteUser and changeUser now working properly 5 tahun lalu
  Boris K f2585b73c4 some minor changes 5 tahun lalu
  Mila-Zagrevskaya 6712847bb3 add scroll-bar and some changes 5 tahun lalu
  Mila-Zagrevskaya 20f90ce09c add scroll-bar and some changes 5 tahun lalu
  Boris K d311c23130 added confirm button to Delete 5 tahun lalu
  Boris K 04bc4a4646 some minor changes 5 tahun lalu
  Mila-Zagrevskaya 018ca2dd23 Merge branch 'dev' of http://gitlab.a-level.com.ua/Entony/FEA_12_CLINIC into mila 5 tahun lalu
  Boris K 6d2d492100 finished change user in admin 5 tahun lalu
  Boris K ae6f32d90b working on change user 5 tahun lalu
  Mila-Zagrevskaya c0dad5e8e7 deleted logo 5 tahun lalu
  Mila-Zagrevskaya 7903fd50ab checkbox 5 tahun lalu
  Mila-Zagrevskaya 557d6fd0a4 Merge branch 'dev' of http://gitlab.a-level.com.ua/Entony/FEA_12_CLINIC into mila 5 tahun lalu
  Funky Warrior dafa10ce76 some changes 5 tahun lalu
  Mila-Zagrevskaya bc3fa53959 some 5 tahun lalu
  Mila-Zagrevskaya 4d5640d1ad some 5 tahun lalu
  Boris K ffc22fefa0 reworked Admin-ChangeDoctor, now working properly with checkbox window 5 tahun lalu
  Boris K f92ae8717b testing checkbox field for admin-doctors 5 tahun lalu
  Boris K 583f8c9482 reworked services/categories to seperate action/reducer, some minor changes in components due to knew actions/reducers || cleared database of services, posted knew one with categories 5 tahun lalu
  Boris K a6ccce077a reworked appoitment 5 tahun lalu
  Mila-Zagrevskaya d682a27013 appointment part 5 tahun lalu
  Mila-Zagrevskaya 85df995cbc appointment part 5 tahun lalu
  Mila-Zagrevskaya e1c7e6b4b5 some style changes 5 tahun lalu
  Mila-Zagrevskaya 814a56d8d1 some style changes 5 tahun lalu
  Boris K ffd9a73105 reworked appointment to seperate action/reducer 5 tahun lalu
  Mila-Zagrevskaya 9d49fceff2 doctors card 5 tahun lalu
  Boris K 39942c0173 transfer route array from App.js to utils-formFields 5 tahun lalu
  Boris K 738e2f111e transfer route array from App.js to utils-formFields 5 tahun lalu
  Alex 7f0e03c16d Merge branch 'dev' of http://gitlab.a-level.com.ua/Entony/FEA_12_CLINIC into dev 5 tahun lalu
  Mila-Zagrevskaya 830d4bfaa4 some 5 tahun lalu
  Alex b912842a18 add Private Routing 5 tahun lalu
  Mila-Zagrevskaya f422500e77 some 5 tahun lalu
  danilo 23bbf18e68 test 5 tahun lalu
  danilo 63748911ee reworked appoint 5 tahun lalu
  Boris K 9067ced985 working on change doctor 5 tahun lalu
  Boris K 01485040b4 appoint change 5 tahun lalu
  Boris K 625ef04201 test 5 tahun lalu
  Mila-Zagrevskaya 6a4f6cd240 changed appointment part add time-buttons 5 tahun lalu
  Mila-Zagrevskaya bd8a1b7459 added accordion to services part 5 tahun lalu
  Mila-Zagrevskaya a1dccea1a9 added accordion to services part 5 tahun lalu
  Mila-Zagrevskaya 4e9a9dab22 mobile version 5 tahun lalu
  Mila-Zagrevskaya 66ff46cd13 mobile version 5 tahun lalu
  Mila-Zagrevskaya 6e905b238e mobile version 5 tahun lalu
  Alex d7eccda66d add a little bit private 5 tahun lalu
  Alex 946c400aaa private routing begining 5 tahun lalu
  Boris K c250bf4f5a some 5 tahun lalu
  Mila-Zagrevskaya 7015bd2719 add cards-servises 5 tahun lalu
  Mila-Zagrevskaya d142e05e4b add cards-servises 5 tahun lalu
  Boris K ff3f53df4e reworked appointment-calendar and admin-shedule-calendar for ato renew 5 tahun lalu
  Boris K 24f4269e3a reworked calendar to reducer 5 tahun lalu
  Mila-Zagrevskaya 7e65e9c644 admin part 5 tahun lalu
  Mila-Zagrevskaya bf0135a2e7 shedule 5 tahun lalu
  Mila-Zagrevskaya 5881cecb7b shedule 5 tahun lalu
  Boris K 904bc8a7a3 Admin-shedule added calendar 5 tahun lalu
  Boris K c2ee6542a8 Admin-shedule added check for weekends 5 tahun lalu
  Mila-Zagrevskaya 4cb08971d4 changed admin-shedule block 5 tahun lalu
  Mila-Zagrevskaya 1dcb974aab add scroll on mainPage select calendar 5 tahun lalu
  Mila-Zagrevskaya 74b8885548 some change 5 tahun lalu
  Mila-Zagrevskaya b8ea342c36 some change 5 tahun lalu
  Boris K 5d4e0b6970 some 5 tahun lalu
  Boris K 081352827f reworked apointmen 5 tahun lalu
  Mila-Zagrevskaya 035b499c02 some change 5 tahun lalu
  Mila-Zagrevskaya 54185b7598 Merge branch 'dev' of http://gitlab.a-level.com.ua/Entony/FEA_12_CLINIC into mila 5 tahun lalu
  Mila-Zagrevskaya 74be2bdc0e some change 5 tahun lalu
  Boris K 7c3c46fbbc reworked calendar v2.0 5 tahun lalu
  Boris K 8cb37016f6 some 5 tahun lalu
  Boris K b22bcd97d6 Merge branch 'dev' of http://gitlab.a-level.com.ua/Entony/FEA_12_CLINIC into boris 5 tahun lalu
  Boris K 2ff49cedaf reworked calendar 5 tahun lalu
  Mila-Zagrevskaya e0c17f3df7 choise service 5 tahun lalu
  Mila-Zagrevskaya 58415f139b doctors cards 5 tahun lalu
  Boris K b444f27824 some 5 tahun lalu
  Boris K fb8c4c5e0f some visual changes 5 tahun lalu
  Mila-Zagrevskaya c68c7b0d09 added some changes 5 tahun lalu
  Mila-Zagrevskaya 28752c9753 added some changes 5 tahun lalu
  Boris K 583e9c7091 компоненты переделаны с render на component 5 tahun lalu
  Mila-Zagrevskaya e53529132a add cards doctors and services 5 tahun lalu
  Mila-Zagrevskaya 1b43e3ca67 add cards doctors and services 5 tahun lalu
  Mila-Zagrevskaya 12270efa13 add cards doctors and services 5 tahun lalu
  Mila-Zagrevskaya 81a21e6b11 Merge branch 'mila' into dev 5 tahun lalu
  Mila-Zagrevskaya aef3ae448d add cards doctors 5 tahun lalu
  Mila-Zagrevskaya 0a947ed626 add cards doctors 5 tahun lalu
  Mila-Zagrevskaya cfa26a93c8 some 5 tahun lalu
  Mila-Zagrevskaya 73b91624c5 add style auth 5 tahun lalu
  Mila-Zagrevskaya d8a6a567cb add style auth 5 tahun lalu
  Mila-Zagrevskaya 9beb9382aa add footer 5 tahun lalu
  Mila-Zagrevskaya 55ea98e317 add footer 5 tahun lalu
  danilo c54c3adee6 Merge branch 'dev' of http://gitlab.a-level.com.ua/Entony/FEA_12_CLINIC into 5 tahun lalu
  danilo 2c92e3af45 added serviceArray 5 tahun lalu
  Alex 479a23ef65 some auth refactoring 5 tahun lalu
  Alex 99819f3e3c some auth refactoring 5 tahun lalu
  Alex 1a41b849b5 refactoring auth 5 tahun lalu
  Boris K 506165812a добавленно: добавление/изменение/удаление сервисов 5 tahun lalu
  Boris K f8bc1731d3 few visual changes 5 tahun lalu
  Boris K 859ace7262 работает оформление заказов, частично работает добавление/изменение докторов(не работает поле специальности), работает добавление рассписания врачам(добавляет все выбранные даты пока) 5 tahun lalu
  Boris K af9fed4042 some changes 5 tahun lalu
  Boris K 4ff7c0d089 some new visual changes 5 tahun lalu
  Boris K 1e9c302f95 обьеденненый проект, переименовал router в App добавил раздел Admin работает пока только shedule, переписал actionTypes action и reducer на актуальные. !!! теперь URL ведеть на heroku !!! Работаем с ним 5 tahun lalu
  Mila-Zagrevskaya 42a06943a7 some 5 tahun lalu
  Mila-Zagrevskaya 800af43ee6 some 5 tahun lalu
  Mila-Zagrevskaya e228e82551 add some 5 tahun lalu
  Alex 2940c85919 'someRefactoring' 5 tahun lalu
  Alex 697fd26fd9 'addAuth' 5 tahun lalu
  Alex dabf3ae625 addBranch 5 tahun lalu
100 mengubah file dengan 5265 tambahan dan 465 penghapusan
  1. 0 11
      .idea/workspace.xml
  2. 632 0
      db.json
  3. 1020 86
      package-lock.json
  4. 11 0
      package.json
  5. TEMPAT SAMPAH
      public/images/doctors/alison.jpg
  6. TEMPAT SAMPAH
      public/images/doctors/ericforman.jpg
  7. TEMPAT SAMPAH
      public/images/doctors/gregoryhaus.jpg
  8. TEMPAT SAMPAH
      public/images/doctors/kris_taub.jpg
  9. TEMPAT SAMPAH
      public/images/doctors/lisa.jpg
  10. TEMPAT SAMPAH
      public/images/doctors/lorenskatner.jpg
  11. TEMPAT SAMPAH
      public/images/doctors/robert.jpg
  12. TEMPAT SAMPAH
      public/images/favicon.png
  13. TEMPAT SAMPAH
      public/images/fon1.jpg
  14. TEMPAT SAMPAH
      public/images/fon2.jpg
  15. TEMPAT SAMPAH
      public/images/fon4.jpg
  16. TEMPAT SAMPAH
      public/images/fon6.jpg
  17. TEMPAT SAMPAH
      public/images/fon7.jpg
  18. TEMPAT SAMPAH
      public/images/fon8.jpg
  19. TEMPAT SAMPAH
      public/images/fon9.jpg
  20. TEMPAT SAMPAH
      public/images/loader.gif
  21. TEMPAT SAMPAH
      public/images/logo.png
  22. TEMPAT SAMPAH
      public/images/medical.jpeg
  23. TEMPAT SAMPAH
      public/images/services/endodontics.png
  24. TEMPAT SAMPAH
      public/images/services/endodontics1.png
  25. TEMPAT SAMPAH
      public/images/services/implantologist.png
  26. TEMPAT SAMPAH
      public/images/services/kids.png
  27. TEMPAT SAMPAH
      public/images/services/orthodontist.png
  28. TEMPAT SAMPAH
      public/images/services/surgeon.png
  29. TEMPAT SAMPAH
      public/images/services/therapist.png
  30. 7 2
      public/index.html
  31. 53 60
      src/App.js
  32. 163 0
      src/actions/actions.js
  33. 105 0
      src/actions/appointment.js
  34. 104 0
      src/actions/auth.js
  35. 17 0
      src/actions/calendar.js
  36. 83 0
      src/actions/orders.js
  37. 148 0
      src/actions/services.js
  38. 48 0
      src/actions/shedule.js
  39. 134 0
      src/actions/user.js
  40. 116 0
      src/actionsTypes/actionsTypes.js
  41. TEMPAT SAMPAH
      src/assets/fonts/icomoon.eot
  42. 24 0
      src/assets/fonts/icomoon.svg
  43. TEMPAT SAMPAH
      src/assets/fonts/icomoon.ttf
  44. TEMPAT SAMPAH
      src/assets/fonts/icomoon.woff
  45. TEMPAT SAMPAH
      src/assets/images/Arrows-Down-4-icon.png
  46. TEMPAT SAMPAH
      src/assets/images/bg.jpg
  47. TEMPAT SAMPAH
      src/assets/images/bg2.jpg
  48. TEMPAT SAMPAH
      src/assets/images/checked.png
  49. TEMPAT SAMPAH
      src/assets/images/fon1.jpg
  50. TEMPAT SAMPAH
      src/assets/images/fon2.jpg
  51. TEMPAT SAMPAH
      src/assets/images/fon6.jpg
  52. TEMPAT SAMPAH
      src/assets/images/fon7.jpg
  53. TEMPAT SAMPAH
      src/assets/images/fon8.jpg
  54. TEMPAT SAMPAH
      src/assets/images/logo.png
  55. 258 0
      src/components/Admin/Admin.js
  56. 132 0
      src/components/Admin/ChangeServices-Doctors.js
  57. 135 0
      src/components/Admin/ChangeUser.js
  58. 42 0
      src/components/Admin/CheckBoxWindow.js
  59. 25 0
      src/components/Admin/Input.js
  60. 191 0
      src/components/Admin/Orders/ChangeOrder.js
  61. 121 0
      src/components/Admin/Orders/Orders.js
  62. 75 0
      src/components/Admin/Shedule.js
  63. 0 84
      src/components/Appointment.js
  64. 81 41
      src/components/Calendar.js
  65. 22 0
      src/components/ConfirmButton.js
  66. 0 31
      src/components/Doctors.js
  67. 16 3
      src/components/Footer.js
  68. 0 16
      src/components/Header.js
  69. 24 0
      src/components/Reviews.js
  70. 0 21
      src/components/Service.js
  71. 0 29
      src/components/Services.js
  72. 178 0
      src/components/appointment/Appointment.js
  73. 47 0
      src/components/auth/signIn.js
  74. 48 0
      src/components/auth/signUp.js
  75. 7 0
      src/components/buttons/btn.js
  76. 5 0
      src/components/buttons/button.js
  77. 18 0
      src/components/header/index.js
  78. 67 0
      src/components/header/navigation.js
  79. 9 0
      src/components/hooks/loader.js
  80. 115 0
      src/components/hooks/select.js
  81. 85 0
      src/components/hooks/useForm.js
  82. 13 0
      src/components/input.js
  83. 77 0
      src/components/main/Main.js
  84. 58 0
      src/components/main/aboutUs.js
  85. 56 0
      src/components/main/myMap.js
  86. 38 0
      src/components/main/team.js
  87. 37 0
      src/components/modal.js
  88. 54 0
      src/components/services/Services.js
  89. 64 0
      src/components/services/categories.js
  90. 54 0
      src/components/specialists/Doctors.js
  91. 56 0
      src/components/specialists/MoreInfo.js
  92. 37 0
      src/components/userInfo.js
  93. 25 0
      src/components/userOrders.js
  94. 92 0
      src/containers/auth.js
  95. 89 0
      src/containers/user.js
  96. 0 67
      src/db.json
  97. 23 14
      src/index.js
  98. 21 0
      src/privateRouter.js
  99. 105 0
      src/reducers/appointment.js
  100. 0 0
      src/reducers/auth.js

+ 0 - 11
.idea/workspace.xml

@@ -91,15 +91,4 @@
   <component name="TypeScriptGeneratedFilesManager">
     <option name="version" value="1" />
   </component>
-  <component name="Vcs.Log.Tabs.Properties">
-    <option name="TAB_STATES">
-      <map>
-        <entry key="MAIN">
-          <value>
-            <State />
-          </value>
-        </entry>
-      </map>
-    </option>
-  </component>
 </project>

File diff ditekan karena terlalu besar
+ 632 - 0
db.json


File diff ditekan karena terlalu besar
+ 1020 - 86
package-lock.json


+ 11 - 0
package.json

@@ -3,11 +3,22 @@
   "version": "0.1.0",
   "private": true,
   "dependencies": {
+    "@fullpage/react-fullpage": "^0.1.15",
+    "axios": "^0.19.0",
+    "google-maps-react": "^2.0.2",
+    "moment": "^2.24.0",
+    "node-sass": "^4.12.0",
     "react": "^16.8.6",
+    "react-accessible-accordion": "^3.0.0",
+    "react-burger-menu": "^2.6.11",
     "react-dom": "^16.8.6",
+    "react-escape-outside": "^0.1.1",
+    "react-full-page": "^0.1.7",
+    "react-history": "^0.18.2",
     "react-redux": "^7.1.0",
     "react-router-dom": "^5.0.1",
     "react-scripts": "3.0.1",
+    "react-scrollchor": "^6.0.0",
     "redux": "^4.0.1",
     "redux-thunk": "^2.3.0"
   },

TEMPAT SAMPAH
public/images/doctors/alison.jpg


TEMPAT SAMPAH
public/images/doctors/ericforman.jpg


TEMPAT SAMPAH
public/images/doctors/gregoryhaus.jpg


TEMPAT SAMPAH
public/images/doctors/kris_taub.jpg


TEMPAT SAMPAH
public/images/doctors/lisa.jpg


TEMPAT SAMPAH
public/images/doctors/lorenskatner.jpg


TEMPAT SAMPAH
public/images/doctors/robert.jpg


TEMPAT SAMPAH
public/images/favicon.png


TEMPAT SAMPAH
public/images/fon1.jpg


TEMPAT SAMPAH
public/images/fon2.jpg


TEMPAT SAMPAH
public/images/fon4.jpg


TEMPAT SAMPAH
public/images/fon6.jpg


TEMPAT SAMPAH
public/images/fon7.jpg


TEMPAT SAMPAH
public/images/fon8.jpg


TEMPAT SAMPAH
public/images/fon9.jpg


TEMPAT SAMPAH
public/images/loader.gif


TEMPAT SAMPAH
public/images/logo.png


TEMPAT SAMPAH
public/images/medical.jpeg


TEMPAT SAMPAH
public/images/services/endodontics.png


TEMPAT SAMPAH
public/images/services/endodontics1.png


TEMPAT SAMPAH
public/images/services/implantologist.png


TEMPAT SAMPAH
public/images/services/kids.png


TEMPAT SAMPAH
public/images/services/orthodontist.png


TEMPAT SAMPAH
public/images/services/surgeon.png


TEMPAT SAMPAH
public/images/services/therapist.png


+ 7 - 2
public/index.html

@@ -1,15 +1,20 @@
 <!DOCTYPE html>
-<html lang="en">
+<html lang="ru">
   <head>
     <meta charset="utf-8" />
     <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
     <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <meta  name="viewport"   content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no" />
+   
     <meta name="theme-color" content="#000000" />
     <!--
       manifest.json provides metadata used when your web app is installed on a
       user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
     -->
     <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
+    <link rel="shortcut icon" href="../images/favicon.png" />
+    <link href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,700i&display=swap" rel="stylesheet">
+    <link href="https://fonts.googleapis.com/css?family=Montserrat:400,400i,700&display=swap" rel="stylesheet">
     <!--
       Notice the use of %PUBLIC_URL% in the tags above.
       It will be replaced with the URL of the `public` folder during the build.
@@ -19,7 +24,7 @@
       work correctly both with client-side routing and a non-root public URL.
       Learn how to configure a non-root public URL by running `npm run build`.
     -->
-    <title>React App</title>
+    <title>Art Dental studio</title>
   </head>
   <body>
     <noscript>You need to enable JavaScript to run this app.</noscript>

+ 53 - 60
src/App.js

@@ -1,90 +1,83 @@
 import React from 'react';
-import {connect} from 'react-redux'
-import {Switch, Route} from "react-router-dom";
+import {connect} from 'react-redux';
+import {Switch} from "react-router-dom";
 
-import {
-    getAll,
-    getDoctors,
-    getServices,
-    setAppointmentDate,
-    setAppointmentDoctor,
-    setAppointmentTime,
-    setAppointmentSpec,
-    setAppointmentComment,
-    clearAppointment,
-    putOrders,
+import {getDoctors} from "./actions/actions";
+import {getServices, getCategories} from "./actions/services";
+import {getUser} from "./actions/auth"
+import {getOrders} from "./actions/orders"
 
-} from "./store/app/actions";
-
-import Header from "./components/Header";
+import Loader from "./components/hooks/loader";
+import Header from "./components/header/index";
 import Footer from "./components/Footer";
-import Doctors from "./components/Doctors"
-import Services from "./components/Services"
-import Service from "./components/Service"
-import Appointment from "./components/Appointment"
+import {route} from './utils/formFields'
+import { PrivateRoute } from "./privateRouter";
+
 
+function  makeHashchange (event) {
+    window.scroll(0, 0)
+} 
 
 export class App extends React.Component {
 
     componentDidMount() {
-        // this.props.getDoctors();
-        // this.props.getServices()
-        this.props.getAll()
+        this.props.getDoctors();
+        this.props.getServices();
+        this.props.getCategories();
+        // this.props.getOrders();
+
+       if(localStorage.getItem('userId')) this.props.getUser()
+
+       window.addEventListener = ( "hashchange", makeHashchange) 
+
+        // fetch ("https://api-clinics.herokuapp.com/api/v1/auth/login", {
+        //     method : "POST",
+        //     credentials: "include",
+        //     headers: {
+        //         "Content-Type": "application/json"
+        //     },
+        //     body: JSON.stringify ({
+        //         email: "test@test.com",
+        //         password: "qwerty"
+        //     })
+        // })
+        //     .then (res => res.json ())
+        //     .then (res => console.log (res))
     }
 
     render() {
-        console.log(this.props.app)
         return (
-            <div className="App">
-                <Header/>
+              <Loader flag={this.props.app.isFetching}>
+                  <Header/>
                     <Switch>
-                        <Route exact path="/" render={() => <div>Main</div>} />
-                        <Route exact path="/doctors" render={() => <Doctors data={this.props.app.doctors} /> } />
-                        <Route exact path="/services" render={() => <Services data={Array.from(Object.values(this.props.app.services))} />} />
-                        <Route exact path="/reviews" render={() => <div>Reviews</div>} />
-                        <Route exact path="/services/:service" render={(props) => <Service
-                            his={props}
-                            data={this.props.app.services}
-                        />} />
-                        <Route  path="/appointment/:doctor" render={(props) => <Appointment
-                            his={props}
-                            dataDoctors={this.props.app.doctors}
-                            dataServices={this.props.app.services}
-                            dataOrders={this.props.app.orders}
-                            appointment={this.props.app.appointment}
-                            setAppointmentDate={this.props.setAppointmentDate}
-                            setAppointmentDoctor={this.props.setAppointmentDoctor}
-                            setAppointmentTime={this.props.setAppointmentTime}
-                            setAppointmentSpec={this.props.setAppointmentSpec}
-                            setAppointmentComment={this.props.setAppointmentComment}
-                            clearAppointment={this.props.clearAppointment}
-                            putOrders={this.props.putOrders}
-                        />} />
+                        {route.map(el => (
+					        <PrivateRoute
+                                protectedRoute={el.protected}
+                                key={el.id}
+                                exact={el.exact}
+                                path={el.path}
+                                component={el.component}
+                            />
+				        ))}
                     </Switch>
-                <Footer/>
-            </div>
+                <Footer />
+             </Loader>
         );
     }
 }
 
 const mapStateToProps = state => {
     return {
-        app:state.app,
+        app:state.app
     }
 };
 
 const mapDispatchToProps = {
-    getAll,
     getDoctors,
     getServices,
-    setAppointmentDate,
-    setAppointmentDoctor,
-    setAppointmentTime,
-    setAppointmentSpec,
-    setAppointmentComment,
-    clearAppointment,
-    putOrders
-
+    getCategories,
+    getUser,
+    getOrders
 };
 
 export default connect (mapStateToProps,mapDispatchToProps)(App)

+ 163 - 0
src/actions/actions.js

@@ -0,0 +1,163 @@
+import * as types from '../actionsTypes/actionsTypes'
+
+const URL = "https://api-clinics.herokuapp.com/api/v1/";
+
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const changeInputValueDoctorForm = payload => ({
+    type: types.CHANGE_INPUT_VALUE_DOCTOR_FORM,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const changeInputValueServiceForm = payload => ({
+    type: types.CHANGE_INPUT_VALUE_SERVICE_FORM,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const changeSelectedDoctorId = payload => ({
+    type: types.CHANGE_SELECTED_DOCTOR_ID,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const changeSelectedServiceId = payload => ({
+    type: types.CHANGE_SELECTED_SERVICE_ID,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const changeSpecialityArray = payload => ({
+    type: types.CHANGE_SPECIALITY_ARRAY,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+// -----------------------------------------------------------------------------------------------------------------
+
+const getDoctorsRequest = payload => ({
+    type: types.GET_DOCTORS_REQUEST,
+    payload
+});
+
+const getDoctorsRequestSuccess = payload => ({
+    type: types.GET_DOCTORS_REQUEST_SUCCESS,
+    payload
+});
+
+const getDoctorsRequestFail = payload => ({
+    type: types.GET_DOCTORS_REQUEST_FAIL,
+    payload
+});
+
+export const getDoctors = () => dispatch => {
+    console.log('get')
+    dispatch(getDoctorsRequest());
+    return fetch(`${URL}doctors`,{
+        credentials:"include"
+    })
+        .then(res => res.json())
+        .then(res => dispatch(getDoctorsRequestSuccess(res)))
+        .catch(err => dispatch(getDoctorsRequestFail(err)));
+};
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const postDoctorsRequest = payload => ({
+    type: types.POST_DOCTORS_REQUEST,
+    payload
+});
+
+const postDoctorsRequestSuccess = payload => ({
+    type: types.POST_DOCTORS_REQUEST_SUCCESS,
+    payload
+});
+
+const postDoctorsRequestFail = payload => ({
+    type: types.POST_DOCTORS_REQUEST_FAIL,
+    payload
+});
+
+export const postDoctors = (payload) => dispatch => {
+    dispatch(postDoctorsRequest());
+    return fetch(`${URL}doctors`, {
+        method: "POST",
+        credentials: "include",
+        headers: {
+            "Content-Type": "application/json"
+        },
+        body: JSON.stringify(payload)
+    })
+        .then(res => res.json())
+        .then(res => dispatch(postDoctorsRequestSuccess(res))).then(dispatch(getDoctors()))
+        .catch(err => dispatch(postDoctorsRequestFail(err)));
+};
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const putDoctorsRequest = payload => ({
+    type: types.PUT_DOCTORS_REQUEST,
+    payload
+});
+
+const putDoctorsRequestSuccess = payload => ({
+    type: types.PUT_DOCTORS_REQUEST_SUCCESS,
+    payload
+});
+
+const putDoctorsRequestFail = payload => ({
+    type: types.PUT_DOCTORS_REQUEST_FAIL,
+    payload
+});
+
+export const putDoctors = (payload) => dispatch => {
+    dispatch(putDoctorsRequest());
+    return fetch(`${URL}doctors/${payload.id}`, {
+        method: "PUT",
+        credentials: "include",
+        headers: {
+            "Content-Type": "application/json"
+        },
+        body: JSON.stringify(payload.data)
+    })
+        .then(res => res.json())
+        .then(res => dispatch(putDoctorsRequestSuccess(res))).then(dispatch(getDoctors()))
+        .catch(err => dispatch(putDoctorsRequestFail(err)));
+};
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const deleteDoctorsRequest = payload => ({
+    type: types.DELETE_DOCTORS_REQUEST,
+    payload
+});
+
+const deleteDoctorsRequestSuccess = payload => ({
+    type: types.DELETE_DOCTORS_REQUEST_SUCCESS,
+    payload
+});
+
+const deleteDoctorsRequestFail = payload => ({
+    type: types.DELETE_DOCTORS_REQUEST_FAIL,
+    payload
+});
+
+export const deleteDoctors = (payload) => dispatch => {
+    dispatch(deleteDoctorsRequest());
+    return fetch(`${URL}doctors/${payload}`, {
+        method: "DELETE",
+        credentials: "include"
+    })
+        .then(res => res.json())
+        .then(res => dispatch(deleteDoctorsRequestSuccess(res))).then(dispatch(getDoctors()))
+        .catch(err => dispatch(deleteDoctorsRequestFail(err)));
+};
+
+// -----------------------------------------------------------------------------------------------------------------
+// -----------------------------------------------------------------------------------------------------------------

+ 105 - 0
src/actions/appointment.js

@@ -0,0 +1,105 @@
+import * as types from "../actionsTypes/actionsTypes";
+
+import axios from 'axios'
+import {getOrders} from "./orders";
+
+const URL = "https://api-clinics.herokuapp.com/api/v1/";
+
+export const setAppointmentShedule = payload => ({
+    type: types.CHANGE_APPOINTMENT_SHEDULE,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const setAppointmentDoctor = payload => ({
+    type: types.CHANGE_APPOINTMENT_DOCTOR,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const setAppointmentTime = payload => ({
+    type: types.CHANGE_APPOINTMENT_TIME,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const setAppointmentSpec = payload => ({
+    type: types.CHANGE_APPOINTMENT_SPEC,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const setAppointmentComment = payload => ({
+    type: types.CHANGE_APPOINTMENT_COMMENT,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const clearAppointment = payload => {
+    localStorage.removeItem('appointment');
+     return  {
+         type: types.CLEAR_APPOINTMENT,
+         payload
+     }
+};
+
+// -----------------------------------------------------------------------------------------------------------------
+// -----------------------------------------------------------------------------------------------------------------
+
+const postOrdersRequest = payload => ({
+    type: types.POST_ORDERS_REQUEST,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const postOrdersSuccess = payload => ({
+    type: types.POST_ORDERS_REQUEST_SUCCESS,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const postOrdersFail = payload => ({
+    type: types.POST_ORDERS_REQUEST_FAIL,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+// export const postOrders = (payload) => dispatch => {
+//     dispatch(postOrdersRequest());
+//     return fetch(`${URL}orders`, {
+//         method: "POST",
+//         credentials:"include",
+//         headers: {
+//             'Content-Type': 'application/json'
+//         },
+//         body: JSON.stringify(payload)
+//     })
+//         .then(res => res.json())
+//         .then(res => dispatch(postOrdersSuccess(res)))
+//         .then(dispatch(clearAppointment()))
+//         .catch(err => dispatch(postOrdersFail(err)));
+// };
+export const postOrders = payload => {
+    return async dispatch => {
+        dispatch(postOrdersRequest());
+        try {
+            const { data } = await axios({
+                method:'POST',
+                url:`${URL}orders`,
+                data: payload  
+            });
+            dispatch(postOrdersSuccess(data));
+            dispatch(clearAppointment());
+        } catch (error){
+            dispatch(postOrdersFail(error));
+        }
+    }
+};

+ 104 - 0
src/actions/auth.js

@@ -0,0 +1,104 @@
+import * as types from '../actionsTypes/actionsTypes'
+
+import axios from 'axios'
+
+const authRequest = payload => ({
+    type: types.AUTH_REQUEST,
+    payload
+})
+
+const authRequestSuccess = payload => ({
+    type: types.AUTH_REQUEST_SUCCESS,
+    payload
+})
+
+const authRequestFail = payload => ({
+    type: types.AUTH_REQUEST_FAIL,
+    payload
+})
+
+export const auth = payload => {
+    return async dispatch => {
+        dispatch(authRequest());
+        try {
+            const { data } = await axios.post("https://api-clinics.herokuapp.com/api/v1/auth/login", payload);
+            localStorage.setItem("userId",data.user._id)
+            dispatch(authRequestSuccess(data));
+
+           
+            
+        } catch (error){
+            dispatch(authRequestFail(error));
+        }
+    }
+}
+
+const registerRequest = payload => ({
+    type:types.REGISTRATION_REQUEST,
+    payload
+})
+
+const registerRequestSuccess = payload => ({
+    type: types.REGISTRATION_REQUEST_SUCCESS,
+    payload
+})
+
+const registrRequestFail = payload => ({
+    type: types.REGISTRATION_REQUEST_FAIL,
+    payload
+})
+
+export const register = payload => {
+    return async dispatch => {
+        dispatch(registerRequest());
+        try {
+            const { data } = await axios.post(
+                "https://api-clinics.herokuapp.com/api/v1/auth/register",
+                payload
+            );
+           
+            dispatch(registerRequestSuccess(data))
+        } catch(error) {
+            dispatch(registrRequestFail(error))
+        }
+    };
+};
+
+
+const getUserRequest = payload => {
+    return {
+    type: types.GET_USER_REQUEST,
+    payload
+}}
+
+const getUserRequestSuccess = payload => ({
+    type: types.GET_USER_REQUEST_SUCCESS,
+    payload
+})
+
+const getUserRequestFail = payload => ({
+    type: types.GET_USER_REQUEST_FAIL,
+    payload
+})
+
+export const getUser = () => dispatch => {
+    dispatch(getUserRequest());
+    return fetch(`https://api-clinics.herokuapp.com/api/v1/users/` + localStorage.getItem('userId'),{
+        credentials:"include"
+    })
+        .then(res => res.json())
+        .then(res => dispatch(getUserRequestSuccess(res)))
+        .catch(err => dispatch(getUserRequestFail(err)));
+};
+
+export const userLogout = payload => ({
+    type: types.USER_LOGOUT,
+    payload
+})
+
+export const changeInputValueUserUserForm = payload => (
+    {
+        type:types.CHANGE_INPUT_VALUE_USER_USER_FORM,
+        payload
+    }
+)

+ 17 - 0
src/actions/calendar.js

@@ -0,0 +1,17 @@
+import * as types from '../actionsTypes/actionsTypes'
+
+export const createCalendarMonthArray = payload => ({
+    type: types.CREATE_CALENDAR_MONTH_ARRAY,
+    payload
+});
+
+export const changeCalendarMonth = payload => ({
+    type: types.CHANGE_CALENDAR_MONTH,
+    payload
+});
+
+export const resetCurrent = payload => ({
+    type: types.RESET_CALENDAR_CURRENT,
+    payload
+});
+

+ 83 - 0
src/actions/orders.js

@@ -0,0 +1,83 @@
+import * as types from "../actionsTypes/actionsTypes";
+import {postOrders} from "./appointment";
+
+const URL = "https://api-clinics.herokuapp.com/api/v1/";
+
+
+export const changeInputFindOrder = payload => ({
+    type:types.CHANGE_INPUT_VALUE_FIND_ORDER,
+    payload
+});
+
+export const findOrdersArray = payload => ({
+    type:types.FIND_ORDERS_ARRAY,
+    payload
+});
+
+export const getUserOrders = payload => ({
+    type: types.USER_ORDERS,
+    payload
+});
+
+export const changeInputValueOrderForm = payload => ({
+    type:types.CHANGE_INPUT_VALUE_ORDER_FORM,
+    payload
+});
+
+
+const getOrdersRequest = payload => ({
+    type: types.GET_ORDERS_REQUEST,
+    payload
+});
+
+const getOrdersSuccess = payload => ({
+    type: types.GET_ORDERS_REQUEST_SUCCESS,
+    payload
+});
+
+const getOrdersFail = payload => ({
+    type: types.GET_ORDERS_REQUEST_FAIL,
+    payload
+});
+
+export const getOrders = (payload) => dispatch => {
+    dispatch(getOrdersRequest());
+    return fetch(`${URL}orders`,{
+        credentials:"include"
+    })
+        .then(res => res.json())
+        .then(res => {
+            dispatch(getOrdersSuccess({res:res,data:payload}));
+        })
+        .catch(err => dispatch(getOrdersFail(err)));
+};
+
+const deleteOrderRequest = payload => ({
+    type: types.DELETE_ORDER_REQUEST,
+    payload
+});
+
+const deleteOrderRequestSuccess = payload => ({
+    type: types.DELETE_ORDER_REQUEST_SUCCESS,
+    payload
+});
+
+const deleteOrderRequestFail = payload => ({
+    type: types.DELETE_ORDER_REQUEST_FAIL,
+    payload
+});
+
+export const deleteOrder = (payload) => dispatch => {
+    dispatch(deleteOrderRequest());
+    return fetch(`${URL}orders/${payload.id}`, {
+        method: "DELETE",
+        credentials: "include"
+    })
+        .then(res => res.json())
+        .then(res => dispatch(deleteOrderRequestSuccess(res)))
+        .then(dispatch(postOrders(payload.newOrder)))
+        .catch(err => dispatch(deleteOrderRequestFail(err)));
+};
+
+
+

+ 148 - 0
src/actions/services.js

@@ -0,0 +1,148 @@
+import * as types from "../actionsTypes/actionsTypes";
+
+const URL = "https://api-clinics.herokuapp.com/api/v1/";
+
+
+const getServicesRequest = payload => ({
+    type: types.GET_SERVICES_REQUEST,
+    payload
+});
+
+const getServicesRequestSuccess = payload => ({
+    type: types.GET_SERVICES_REQUEST_SUCCESS,
+    payload
+});
+
+const getServicesRequestFail = payload => ({
+    type: types.GET_SERVICES_REQUEST_FAIL,
+    payload
+});
+
+export const getServices = () => dispatch => {
+    dispatch(getServicesRequest());
+    return fetch(`${URL}services`,{
+        credentials:"include"
+    })
+        .then(res => res.json())
+        .then(res => dispatch(getServicesRequestSuccess(res)))
+        .catch(err => dispatch(getServicesRequestFail(err)));
+};
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const postServicesRequest = payload => ({
+    type: types.POST_SERVICES_REQUEST,
+    payload
+});
+
+const postServicesRequestSuccess = payload => ({
+    type: types.POST_SERVICES_REQUEST_SUCCESS,
+    payload
+});
+
+const postServicesRequestFail = payload => ({
+    type: types.POST_SERVICES_REQUEST_FAIL,
+    payload
+});
+
+export const postServices = (payload) => dispatch => {
+    dispatch(postServicesRequest());
+    return fetch(`${URL}services`, {
+        method: "POST",
+        credentials: "include",
+        headers: {
+            "Content-Type": "application/json"
+        },
+        body: JSON.stringify(payload)
+    })
+        .then(res => res.json())
+        .then(res =>  dispatch(postServicesRequestSuccess(res))).then(dispatch(getServices()))
+        .catch(err => dispatch(postServicesRequestFail(err)))
+};
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const putServicesRequest = payload => ({
+    type: types.PUT_SERVICES_REQUEST,
+    payload
+});
+
+const putServicesRequestSuccess = payload => ({
+    type: types.PUT_SERVICES_REQUEST_SUCCESS,
+    payload
+});
+
+const putServicesRequestFail = payload => ({
+    type: types.PUT_SERVICES_REQUEST_FAIL,
+    payload
+});
+
+export const putServices = (payload) => dispatch => {
+    dispatch(putServicesRequest());
+    return fetch(`${URL}services/${payload.id}`, {
+        method: "PUT",
+        credentials: "include",
+        headers: {
+            "Content-Type": "application/json"
+        },
+        body: JSON.stringify(payload.data)
+    })
+        .then(res => res.json())
+        .then(res => dispatch(putServicesRequestSuccess(res))).then(dispatch(getServices()))
+        .catch(err => dispatch(putServicesRequestFail(err)));
+};
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const deleteServicesRequest = payload => ({
+    type: types.DELETE_DOCTORS_REQUEST,
+    payload
+});
+
+const deleteServicesRequestSuccess = payload => ({
+    type: types.DELETE_DOCTORS_REQUEST_SUCCESS,
+    payload
+});
+
+const deleteServicesRequestFail = payload => ({
+    type: types.DELETE_DOCTORS_REQUEST_FAIL,
+    payload
+});
+
+export const deleteServices = (payload) => dispatch => {
+    dispatch(deleteServicesRequest());
+    return fetch(`${URL}services/${payload}`, {
+        method: "DELETE",
+        credentials: "include"
+    })
+        .then(res => res.json())
+        .then(res => dispatch(deleteServicesRequestSuccess(res))).then(dispatch(getServices()))
+        .catch(err => dispatch(deleteServicesRequestFail(err)));
+};
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const getCategoriesRequest = payload => ({
+    type: types.GET_CATEGORIES_REQUEST,
+    payload
+});
+
+const getCategoriesRequestSuccess = payload => ({
+    type: types.GET_CATEGORIES_REQUEST_SUCCESS,
+    payload
+});
+
+const getCategoriesRequestFail = payload => ({
+    type: types.GET_CATEGORIES_REQUEST_FAIL,
+    payload
+});
+
+export const getCategories = () => dispatch => {
+    dispatch(getCategoriesRequest());
+    return fetch(`${URL}category`,{
+        credentials:"include"
+    })
+        .then(res => res.json())
+        .then(res => dispatch(getCategoriesRequestSuccess(res)))
+        .catch(err => dispatch(getCategoriesRequestFail(err)));
+};

+ 48 - 0
src/actions/shedule.js

@@ -0,0 +1,48 @@
+import * as types from '../actionsTypes/actionsTypes'
+import {getDoctors} from "./actions";
+
+
+const URL = "https://api-clinics.herokuapp.com/api/v1/";
+
+export const setSheduleDoctor = payload => ({
+    type: types.CHANGE_SHEDULE_DOCTOR,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const postSheduleRequest = payload => ({
+    type: types.POST_SHEDULE_REQUEST,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const postSheduleSuccess = payload => ({
+    type: types.POST_SHEDULE_REQUEST_SUCCESS,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+const postSheduleFail = payload => ({
+    type: types.POST_SHEDULE_REQUEST_FAIL,
+    payload
+});
+
+// -----------------------------------------------------------------------------------------------------------------
+
+export const postShedule = (payload) => dispatch => {
+    dispatch(postSheduleRequest());
+    return fetch(`${URL}shedule`, {
+        method: "POST",
+        credentials:"include",
+        headers: {
+            'Content-Type': 'application/json'
+        },
+        body: JSON.stringify(payload)
+    })
+        .then(res => res.json())
+        .then(res => dispatch(postSheduleSuccess(res))).then(dispatch(getDoctors()))
+        .catch(err => dispatch(postSheduleFail(err)));
+};

+ 134 - 0
src/actions/user.js

@@ -0,0 +1,134 @@
+import * as types from "../actionsTypes/actionsTypes";
+
+const URL = "https://api-clinics.herokuapp.com/api/v1/users/";
+
+
+export const changeFindUserInput = payload => ({
+    type:types.CHANGE_INPUT_VALUE_FIND_USER,
+    payload
+});
+
+export const changeInputValueUserForm = payload => ({
+    type:types.CHANGE_INPUT_VALUE_USER_FORM,
+    payload
+});
+
+const getUsersRequest = payload => ({
+    type: types.GET_USERS_REQUEST,
+    payload
+});
+
+const getUsersRequestSuccess = payload => ({
+    type: types.GET_USERS_REQUEST_SUCCESS,
+    payload
+});
+
+const getUsersRequestFail = payload => ({
+    type: types.GET_USERS_REQUEST_FAIL,
+    payload
+});
+
+export const getUsers = () => dispatch => {
+    dispatch(getUsersRequest());
+    return fetch(`${URL}`,{
+        credentials:"include"
+    })
+        .then(res => res.json())
+        .then(res => {
+            dispatch(getUsersRequestSuccess(res));
+        })
+        .catch(err => dispatch(getUsersRequestFail(err)));
+};
+
+
+const findUserRequest = payload => ({
+    type: types.FIND_USER_REQUEST,
+    payload
+});
+
+const findUserRequestSuccess = payload => ({
+    type: types.FIND_USER_REQUEST_SUCCESS,
+    payload
+});
+
+const findUserRequestFail = payload => ({
+    type: types.FIND_USER_REQUEST_FAIL,
+    payload
+});
+
+export const findUser = (payload) => dispatch => {
+    dispatch(findUserRequest());
+    return fetch(`${URL}`+payload,{
+        credentials:"include"
+    })
+        .then(res => res.json())
+        .then(res => {
+            dispatch(findUserRequestSuccess(res));
+        })
+        .catch(err => dispatch(findUserRequestFail(err)));
+};
+
+
+const deleteUserRequest = payload => ({
+    type: types.DELETE_USER_REQUEST,
+    payload
+});
+
+const deleteUserRequestSuccess = payload => ({
+    type: types.DELETE_USER_REQUEST_SUCCESS,
+    payload
+});
+
+const deleteUserRequestFail = payload => ({
+    type: types.DELETE_USER_REQUEST_FAIL,
+    payload
+});
+
+export const deleteUser = (payload) => dispatch => {
+    dispatch(deleteUserRequest());
+    return fetch(`${URL}${payload}`, {
+        method: "DELETE",
+        credentials: "include"
+    })
+        .then(res => res.json())
+        .then(res => dispatch(deleteUserRequestSuccess(res)))
+        .catch(err => dispatch(deleteUserRequestFail(err)));
+};
+
+
+const putUserRequest = payload => ({
+    type: types.PUT_USER_REQUEST,
+    payload
+});
+
+const putUserRequestSuccess = payload => ({
+    type: types.PUT_USER_REQUEST_SUCCESS,
+    payload
+});
+
+const changeDataInCurrentUser = payload => ({
+    type: types.CHANGE_DATA_IN_CURRENT_USER,
+    payload
+})
+
+const putUserRequestFail = payload => ({
+    type: types.PUT_USER_REQUEST_FAIL,
+    payload
+});
+
+export const putUser = (payload) => dispatch => {
+    dispatch(putUserRequest());
+   
+    return fetch(`${URL}${payload.path}`, {
+        method: "PUT",
+        credentials: "include",
+        headers: {
+            "Content-Type": "application/json"
+        },
+        body: JSON.stringify(payload.data)
+    })
+        .then(res => res.json())
+        .then(res => dispatch(putUserRequestSuccess(res)))
+        .then(dispatch(changeDataInCurrentUser(payload.data)))
+        .catch(err => dispatch(putUserRequestFail(err)));
+};

+ 116 - 0
src/actionsTypes/actionsTypes.js

@@ -0,0 +1,116 @@
+export const FIND_USER_REQUEST = "FIND_USER_REQUEST";
+export const FIND_USER_REQUEST_SUCCESS = "FIND_USER_REQUEST_SUCCESS";
+export const FIND_USER_REQUEST_FAIL = "FIND_USER_REQUEST_FAIL";
+export const CHANGE_INPUT_VALUE_FIND_USER = "CHANGE_INPUT_VALUE_FIND_USER";
+export const CHANGE_INPUT_VALUE_USER_FORM= "CHANGE_INPUT_VALUE_USER_FORM";
+export const CHANGE_INPUT_VALUE_USER_USER_FORM = "CHANGE_INPUT_VALUE_USER_USER_FORM"
+export const CHANGE_DATA_IN_CURRENT_USER = "CHANGE_DATA_IN_CURRENT_USER"
+
+export const FIND_ORDERS_ARRAY = "FIND_ORDERS_ARRAY";
+export const CHANGE_INPUT_VALUE_FIND_ORDER = "CHANGE_INPUT_VALUE_FIND_ORDER";
+export const CHANGE_INPUT_VALUE_ORDER_FORM= "CHANGE_INPUT_VALUE_ORDER_FORM";
+
+export const GET_USERS_REQUEST = "GET_USERS_REQUEST";
+export const GET_USERS_REQUEST_SUCCESS = "GET_USERS_REQUEST_SUCCESS";
+export const GET_USERS_REQUEST_FAIL = "GET_USERS_REQUEST_FAIL";
+
+export const GET_DOCTORS_REQUEST = "GET_DOCTORS_REQUEST";
+export const GET_DOCTORS_REQUEST_SUCCESS = "GET_DOCTORS_REQUEST_SUCCESS";
+export const GET_DOCTORS_REQUEST_FAIL = "GET_DOCTORS_REQUEST_FAIL";
+
+export const GET_SERVICES_REQUEST = "GET_SERVICES_REQUEST";
+export const GET_SERVICES_REQUEST_SUCCESS = "GET_SERVICES_REQUEST_SUCCESS";
+export const GET_SERVICES_REQUEST_FAIL = "GET_SERVICES_REQUEST_FAIL";
+
+export const GET_CATEGORIES_REQUEST = "GET_CATEGORIES_REQUEST";
+export const GET_CATEGORIES_REQUEST_SUCCESS = "GET_CATEGORIES_REQUEST_SUCCESS";
+export const GET_CATEGORIES_REQUEST_FAIL = "GET_CATEGORIES_REQUEST_FAIL";
+
+export const CHANGE_APPOINTMENT_SHEDULE= "CHANGE_APPOINTMENT_SHEDULE";
+export const CHANGE_APPOINTMENT_DOCTOR= "CHANGE_APPOINTMENT_DOCTOR";
+export const CHANGE_APPOINTMENT_TIME= "CHANGE_APPOINTMENT_TIME";
+export const CHANGE_APPOINTMENT_SPEC= "CHANGE_APPOINTMENT_SPEC";
+export const CHANGE_APPOINTMENT_COMMENT= "CHANGE_APPOINTMENT_COMMENT";
+export const CLEAR_APPOINTMENT= "CLEAR_APPOINTMENT";
+
+export const AUTH_REQUEST = "GET_AUTH_REQUEST";
+export const AUTH_REQUEST_SUCCESS = "AUTH_REQUEST_SUCCESS";
+export const AUTH_REQUEST_FAIL = "AUTH_REQUEST_FAIL";
+
+export const REGISTRATION_REQUEST = "REQISTRATION_REQUEST";
+export const REGISTRATION_REQUEST_SUCCESS = "REGISTRATION_REQUEST_SUCCESS";
+export const REGISTRATION_REQUEST_FAIL = "REGISTRATION_REQUEST_FAIL";
+
+export const GET_USER_REQUEST = "GET_USER_REQUEST";
+export const GET_USER_REQUEST_SUCCESS = "GET_USER_REQUEST_SUCESS";
+export const GET_USER_REQUEST_FAIL = "GET_USER_REQUEST_FAIL";
+
+export const USER_LOGOUT = "USER_LOGOUT"
+
+export const POST_DOCTORS_REQUEST = "POST_DOCTORS_REQUEST";
+export const POST_DOCTORS_REQUEST_SUCCESS = "POST_DOCTORS_REQUEST_SUCCESS";
+export const POST_DOCTORS_REQUEST_FAIL = "POST_DOCTORS_REQUEST_FAIL";
+
+export const POST_SERVICES_REQUEST = "POST_SERVICES_REQUEST";
+export const POST_SERVICES_REQUEST_SUCCESS = "POST_SERVICES_REQUEST_SUCCESS";
+export const POST_SERVICES_REQUEST_FAIL = "POST_SERVICES_REQUEST_FAIL";
+
+export const POST_ORDERS_REQUEST = "POST_ORDERS_REQUEST";
+export const POST_ORDERS_REQUEST_SUCCESS = "POST_ORDERS_REQUEST_SUCCESS";
+export const POST_ORDERS_REQUEST_FAIL = "POST_ORDERS_REQUEST_FAIL";
+
+export const POST_SHEDULE_REQUEST = "POST_SHEDULE_REQUEST";
+export const POST_SHEDULE_REQUEST_SUCCESS = "POST_SHEDULE_REQUEST_SUCCESS";
+export const POST_SHEDULE_REQUEST_FAIL = "POST_SHEDULE_REQUEST_FAIL";
+
+export const PUT_DOCTORS_REQUEST = "PUT_DOCTORS_REQUEST";
+export const PUT_DOCTORS_REQUEST_SUCCESS = "PUT_DOCTORS_REQUEST_SUCCESS";
+export const PUT_DOCTORS_REQUEST_FAIL = "PUT_DOCTORS_REQUEST_FAIL";
+
+export const PUT_USER_REQUEST = "PUT_USER_REQUEST";
+export const PUT_USER_REQUEST_SUCCESS = "PUT_USER_REQUEST_SUCCESS";
+export const PUT_USER_REQUEST_FAIL = "PUT_USER_REQUEST_FAIL";
+
+export const PUT_SERVICES_REQUEST = "PUT_DOCTORS_REQUEST";
+export const PUT_SERVICES_REQUEST_SUCCESS = "PUT_DOCTORS_REQUEST_SUCCESS";
+export const PUT_SERVICES_REQUEST_FAIL = "PUT_DOCTORS_REQUEST_FAIL";
+
+export const DELETE_DOCTORS_REQUEST = "DELETE_DOCTORS_REQUEST";
+export const DELETE_DOCTORS_REQUEST_SUCCESS = "DELETE_DOCTORS_REQUEST_SUCCESS";
+export const DELETE_DOCTORS_REQUEST_FAIL = "DELETE_DOCTORS_REQUEST_FAIL";
+
+export const DELETE_SERVICES_REQUEST = "DELETE_DOCTORS_REQUEST";
+export const DELETE_SERVICES_REQUEST_SUCCESS = "DELETE_DOCTORS_REQUEST_SUCCESS";
+export const DELETE_SERVICES_REQUEST_FAIL = "DELETE_DOCTORS_REQUEST_FAIL";
+
+export const DELETE_USER_REQUEST = "DELETE_USER_REQUEST";
+export const DELETE_USER_REQUEST_SUCCESS = "DELETE_USER_REQUEST_SUCCESS";
+export const DELETE_USER_REQUEST_FAIL = "DELETE_USER_REQUEST_FAIL";
+
+export const DELETE_ORDER_REQUEST = "DELETE_ORDER_REQUEST";
+export const DELETE_ORDER_REQUEST_SUCCESS = "DELETE_ORDER_REQUEST_SUCCESS";
+export const DELETE_ORDER_REQUEST_FAIL = "DELETE_ORDER_REQUEST_FAIL";
+
+export const CHANGE_SHEDULE_DOCTOR= "CHANGE_SHEDULE_DOCTOR";
+
+export const CHANGE_INPUT_VALUE_DOCTOR_FORM= "CHANGE_INPUT_VALUE_DOCTOR_FORM";
+export const CHANGE_INPUT_VALUE_SERVICE_FORM= "CHANGE_INPUT_VALUE_SERVICE_FORM";
+export const CHANGE_SELECTED_DOCTOR_ID= "CHANGE_SELECTED_DOCTOR_ID";
+export const CHANGE_SELECTED_SERVICE_ID= "CHANGE_SELECTED_SERVICE_ID";
+export const CHANGE_SPECIALITY_ARRAY= "CHANGE_SPECIALITY_ARRAY";
+
+export const CREATE_CALENDAR_MONTH_ARRAY= "CREATE_CALENDAR_MONTH_ARRAY";
+export const CHANGE_CALENDAR_MONTH= "CHANGE_CALENDAR_MONTH";
+export const RESET_CALENDAR_CURRENT= "RESET_CALENDAR_CURRENT";
+
+export const GET_ORDERS_REQUEST = "GET_ORDERS_REQUEST";
+export const GET_ORDERS_REQUEST_SUCCESS = "GET_ORDERS_REQUEST_SUCCESS";
+export const GET_ORDERS_REQUEST_FAIL = "GET_ORDERS_REQUEST_FAIL";
+export const USER_ORDERS = "USER_ORDERS"
+
+
+
+
+
+
+

TEMPAT SAMPAH
src/assets/fonts/icomoon.eot


File diff ditekan karena terlalu besar
+ 24 - 0
src/assets/fonts/icomoon.svg


TEMPAT SAMPAH
src/assets/fonts/icomoon.ttf


TEMPAT SAMPAH
src/assets/fonts/icomoon.woff


TEMPAT SAMPAH
src/assets/images/Arrows-Down-4-icon.png


TEMPAT SAMPAH
src/assets/images/bg.jpg


TEMPAT SAMPAH
src/assets/images/bg2.jpg


TEMPAT SAMPAH
src/assets/images/checked.png


TEMPAT SAMPAH
src/assets/images/fon1.jpg


TEMPAT SAMPAH
src/assets/images/fon2.jpg


TEMPAT SAMPAH
src/assets/images/fon6.jpg


TEMPAT SAMPAH
src/assets/images/fon7.jpg


TEMPAT SAMPAH
src/assets/images/fon8.jpg


TEMPAT SAMPAH
src/assets/images/logo.png


+ 258 - 0
src/components/Admin/Admin.js

@@ -0,0 +1,258 @@
+import React from 'react';
+import {connect} from 'react-redux'
+import {Link} from 'react-router-dom'
+import {Switch, Route} from "react-router-dom";
+
+import {
+    changeInputValueDoctorForm,
+    changeInputValueServiceForm,
+    postDoctors,
+    changeSelectedDoctorId,
+    changeSelectedServiceId,
+    putDoctors,
+    deleteDoctors,
+    changeSpecialityArray
+} from "../../actions/actions";
+
+import {
+    changeFindUserInput,
+    findUser,
+    deleteUser,
+    changeInputValueUserForm,
+    putUser,
+    getUsers,
+} from "../../actions/user"
+
+import {
+    postServices,
+    putServices,
+    deleteServices
+} from "../../actions/services"
+
+import {
+    setSheduleDoctor,
+    postShedule,
+} from "../../actions/shedule"
+
+import  {
+    getOrders,
+    changeInputFindOrder,
+    findOrdersArray,
+    deleteOrder
+} from "../../actions/orders"
+
+import  {
+    setAppointmentSpec,
+    setAppointmentShedule,
+    setAppointmentDoctor,
+    clearAppointment,
+    setAppointmentTime,
+    setAppointmentComment
+} from "../../actions/appointment"
+
+import Shedule from './Shedule'
+import ChangeUser from './ChangeUser'
+import ChangeServicesDoctors from './ChangeServices-Doctors'
+import Orders from "./Orders/Orders";
+
+
+
+export class Admin extends React.Component {
+
+    render() {
+        const {
+            doctors,
+            postNewShedule,
+            postNewDoctor,
+            postNewService,
+            changeDoctorId,
+            changeServiceId,
+            services,
+            categories,
+            setSheduleDoctor,
+            postShedule,
+            changeInputValueDoctorForm,
+            changeInputValueServiceForm,
+            postDoctors,
+            changeSelectedDoctorId,
+            changeSelectedServiceId,
+            putDoctors,
+            deleteDoctors,
+            putServices,
+            deleteServices,
+            postServices,
+            changeSpecialityArray,
+            specialityArray,
+            user,
+            users,
+            findUserInput,
+            changeFindUserInput,
+            findUser,
+            deleteUser,
+            userError,
+            changeUserForm,
+            changeInputValueUserForm,
+            putUser,
+            getUsers,
+            getOrders,
+            orders,
+            changeInputFindOrder,
+            findOrderInput,
+            findOrdersArray,
+            ordersArray,
+            searching,
+            appointment,
+            timeArray,
+            setAppointmentSpec,
+            setAppointmentShedule,
+            setAppointmentDoctor,
+            clearAppointment,
+            setAppointmentTime,
+            setAppointmentComment,
+            deleteOrder,
+            access
+        } = this.props;
+
+        return (
+            <div className="main">
+                <div className="info-wrap">
+                    <div className = " btn-box">
+                        <Link to='/admin/change-shedule' className = "btn link admin">Расписание</Link>
+                        <Link to='/admin/change-doctors' className = "btn link admin">Сотрудники</Link>
+                        <Link to='/admin/change-services' className = "btn link admin">Сервисы</Link>
+                        <Link to='/admin/change-user' className = "btn link admin">Пользователи</Link>
+                        <Link to='/admin/change-orders' className = "btn link admin">Заказы</Link>
+                    </div>
+                    <Switch>
+                        <Route path='/admin/change-shedule' render={() => <Shedule
+                            doctors={doctors}
+                            postNewShedule={postNewShedule}
+                            setSheduleDoctor={setSheduleDoctor}
+                            postShedule={postShedule}
+                        />} />
+                        <Route path='/admin/change-doctors' render={() => <ChangeServicesDoctors
+                            categories={categories}
+                            data={doctors}
+                            specialityArray={specialityArray}
+                            itemId={changeDoctorId}
+                            changeId={changeSelectedDoctorId}
+                            form={postNewDoctor}
+                            postItem={postDoctors}
+                            putItem={putDoctors}
+                            deleteItem={deleteDoctors}
+                            changeInputValues={changeInputValueDoctorForm}
+                            changeSpecialityArray={changeSpecialityArray}
+                        />} />
+                        <Route path='/admin/change-services' render={() => <ChangeServicesDoctors
+                            data={services}
+                            itemId={changeServiceId}
+                            changeId={changeSelectedServiceId}
+                            form={postNewService}
+                            postItem={postServices}
+                            putItem={putServices}
+                            deleteItem={deleteServices}
+                            changeInputValues={changeInputValueServiceForm}
+                        />} />
+                        <Route path='/admin/change-user' render={() => <ChangeUser
+                            user={user}
+                            access={access}
+                            users={users}
+                            findUserInput={findUserInput}
+                            changeFindUserInput={changeFindUserInput}
+                            findUser={findUser}
+                            deleteUser={deleteUser}
+                            error={userError}
+                            changeUserForm={changeUserForm}
+                            changeInputValueUserForm={changeInputValueUserForm}
+                            putUser={putUser}
+                            getUsers={getUsers}
+                        />} />
+                        <Route path='/admin/change-orders' render={() => <Orders
+                            getOrders={getOrders}
+                            orders={orders}
+                            doctors={doctors}
+                            services={services}
+                            users={users}
+                            findOrderInput={findOrderInput}
+                            ordersArray={ordersArray}
+                            searching={searching}
+                            changeInputFindOrder={changeInputFindOrder}
+                            findOrdersArray={findOrdersArray}
+                            getUsers={getUsers}
+                            appointment={appointment}
+                            timeArray={timeArray}
+                            setAppointmentSpec={setAppointmentSpec}
+                            setAppointmentShedule={setAppointmentShedule}
+                            setAppointmentDoctor={setAppointmentDoctor}
+                            clearAppointment={clearAppointment}
+                            setAppointmentTime={setAppointmentTime}
+                            setAppointmentComment={setAppointmentComment}
+                            deleteOrder={deleteOrder}
+                        />} />
+                    </Switch>
+                </div>
+            </div>
+        );
+    }
+}
+
+const mapStateToProps = state => {
+    return {
+        doctors:state.app.doctors,
+        postNewShedule:state.shedule.postNewShedule,
+        postNewDoctor:state.app.postNewDoctor,
+        postNewService:state.app.postNewService,
+        changeDoctorId:state.app.changeDoctorId,
+        changeServiceId:state.app.changeServiceId,
+        specialityArray:state.app.specialityArray,
+        services: state.services.services,
+        categories: state.services.categories,
+        user:state.user.user,
+        access:state.user.access,
+        findUserInput:state.user.findUserInput,
+        userError:state.user.error,
+        changeUserForm:state.user.changeUserForm,
+        users:state.user.users,
+        orders:state.orders.orders,
+        findOrdersArray:state.orders.findOrdersArray,
+        findOrderInput:state.orders.findOrderInput,
+        ordersArray:state.orders.ordersArray,
+        searching:state.orders.searching,
+        appointment:state.appointment.appointment,
+        timeArray:state.appointment.timeArray
+    }
+};
+
+const mapDispatchToProps = {
+    setSheduleDoctor,
+    postShedule,
+    changeInputValueDoctorForm,
+    changeInputValueServiceForm,
+    postDoctors,
+    changeSelectedDoctorId,
+    changeSelectedServiceId,
+    putDoctors,
+    deleteDoctors,
+    postServices,
+    putServices,
+    deleteServices,
+    changeSpecialityArray,
+    changeFindUserInput,
+    findUser,
+    deleteUser,
+    changeInputValueUserForm,
+    putUser,
+    getUsers,
+    getOrders,
+    changeInputFindOrder,
+    findOrdersArray,
+    setAppointmentSpec,
+    setAppointmentShedule,
+    setAppointmentDoctor,
+    clearAppointment,
+    setAppointmentTime,
+    setAppointmentComment,
+    deleteOrder
+};
+
+export default connect (mapStateToProps,mapDispatchToProps)(Admin)

+ 132 - 0
src/components/Admin/ChangeServices-Doctors.js

@@ -0,0 +1,132 @@
+import React from 'react';
+import Input from './Input'
+import CheckBoxWindow from "./CheckBoxWindow";
+import {CustomSelect} from "../hooks/select";
+import ConfirmButton from "../ConfirmButton";
+
+export default class ChangeServicesDoctors extends React.Component {
+    state = {
+        showConfirm: false,
+        flag: false,
+    };
+
+    changeConfirm = () => {
+        this.setState({showConfirm: !this.state.showConfirm})
+    };
+
+    changeFlag = (e) => {
+        e.preventDefault();
+        this.setState({flag: !this.state.flag})
+    };
+
+    postNewItem = (e) => {
+        const obj = {};
+        e.preventDefault();
+        // eslint-disable-next-line array-callback-return
+        this.props.form.map(el => {
+            obj[el.name] = el.value
+        });
+        this.props.postItem(this.props.categories ? {
+            ...obj,
+            speciality: this.props.specialityArray
+        } : obj)
+    };
+
+    changeItem = (e) => {
+        const obj = {};
+        e.preventDefault();
+        // eslint-disable-next-line array-callback-return
+        this.props.form.map(el => {
+            if (el.value !== '') obj[el.name] = el.value
+        });
+        this.props.putItem({
+            data: this.props.categories ? {
+                ...obj,
+                speciality: this.props.specialityArray
+            } : obj,
+            id: this.props.itemId
+        })
+    };
+
+    deleteItem = () => {
+        this.props.deleteItem(this.props.itemId);
+        this.changeConfirm()
+    };
+
+    changeId = (e) => {
+        this.props.changeId({
+            item: e,
+            data: this.props.data,
+        })
+    };
+
+    render() {
+        const {
+            categories,
+            data,
+            itemId,
+            form,
+            changeInputValues,
+            changeSpecialityArray,
+            specialityArray
+        } = this.props;
+        console.log ( itemId)
+        return (
+            <div className="change-services-doctors">
+                {this.state.flag &&
+                <CheckBoxWindow
+                    categories={categories}
+                    specialityArray={specialityArray}
+                    changeFlag={this.changeFlag}
+                    changeSpecialityArray={changeSpecialityArray}
+                />
+                }
+                <div className="admin-item">
+                    <form className="form-doctors" onSubmit={itemId ? this.changeItem : this.postNewItem}>
+                        {
+                            form.map(el => {
+                                el.required = !itemId;
+                                return (
+                                    <Input
+                                        key={el.id}
+                                        id={el.id}
+                                        el={el}
+                                        className={el.className}
+                                        changeInputValues={changeInputValues}
+                                    />
+                                )
+                            })
+                        }
+                        {categories &&
+                        <button className=" btn service-btn" onClick={this.changeFlag}>Выбрать сервисы</button>}
+                        <input
+                            className="btn link"
+                            type='submit'
+                            value={itemId ? 'Изменить' : 'Добавить'}
+                        />
+                    </form>
+                </div>
+                <div className="admin-item">
+                    <CustomSelect
+                        label="Выбрать"
+                        options={data}
+                        emptyLine = {true}
+                        clickOptionEvent={this.changeId}
+                    />
+                    {itemId &&
+                    <button className="btn link" onClick={this.changeConfirm}
+                            style={{backgroundColor: "#ff9774"}}>Удалить
+                        выбранный элемент</button>
+                    }
+                </div>
+                {this.state.showConfirm &&
+                <ConfirmButton
+                    yes={this.deleteItem}
+                    no={this.changeConfirm}
+                    text={'Подтвердить удаление?'}
+                />
+                }
+            </div>
+        );
+    }
+}

+ 135 - 0
src/components/Admin/ChangeUser.js

@@ -0,0 +1,135 @@
+import React from 'react';
+
+
+import Input from "./Input"
+import ConfirmButton from "../ConfirmButton";
+
+export default class ChangeUser extends React.Component {
+    state = {
+        showConfirm: false,
+    };
+
+    changeUserInput = (e) => {
+        this.props.changeFindUserInput(e.target.value)
+    };
+
+    findUser = () => {
+        this.props.findUser(this.props.findUserInput.includes('@') ? '?email=' + this.props.findUserInput : this.props.findUserInput)
+    };
+
+    enterPressed = (e) => {
+        if (e.key === 'Enter') {
+            this.findUser();
+        }
+    };
+
+    changeUser = (e) => {
+        e.preventDefault();
+        const obj = {};
+        // eslint-disable-next-line array-callback-return
+        this.props.changeUserForm.map(el => {
+            if (el.type !== 'radio') {
+                return obj[el.id] = el.value
+            }
+        });
+        if (this.props.access === 'user') {
+            this.props.putUser({
+                data: {
+                    ...obj,
+                    doctor: false,
+                    role: false
+                },
+                path: this.props.user._id
+            })
+        } else if (this.props.access === 'doctor') {
+            this.props.putUser({
+                data: {
+                    ...obj,
+                    doctor: true,
+                    role: false
+                },
+                path: this.props.user._id
+            })
+        } else if (this.props.access === 'role') {
+            this.props.putUser({
+                data: {
+                    ...obj,
+                    doctor: false,
+                    role: true
+                },
+                path: this.props.user._id
+            })
+        }
+    };
+
+    changeConfirm = (action, text) => {
+        this.setState({showConfirm: !this.state.showConfirm})
+    };
+
+    deleteUser = (e) => {
+        this.props.deleteUser(this.props.user._id);
+        this.changeConfirm()
+    };
+
+    render() {
+        const {
+            user,
+            findUserInput,
+            changeInputValueUserForm,
+            changeUserForm,
+            error
+        } = this.props;
+        console.log(this.props)
+        return (
+            <div className="change-user-container">
+                <div className="input-box">
+                    <input type='text' name='find_user' className=" appointment admin-form"
+                           onKeyDown={this.enterPressed} onChange={this.changeUserInput}/>
+                    {findUserInput &&
+                    <button className="btn service-btn" id='enter' onClick={this.findUser}>Найти пользователя</button>
+                    }
+                    {user &&
+                    <div className="change-user-form">
+                        <form className="change-user-radio">
+                            {changeUserForm.map(el =>
+                                    <div className="input-wrap" key={el.id}>
+                                        <Input
+                                            el={el}
+                                            changeInputValues={changeInputValueUserForm}
+                                            className={el.className}
+                                            id={el.id}
+                                            value={el.value}
+                                        />
+                                        <label htmlFor={el.id}>
+                                            {el.pageValue}
+                                        </label>
+                                    </div>
+
+                                // <label htmlFor={index}>{Object.keys(el)}</label>
+                            )}
+                        </form>
+                        <button className="btn service-btn" onClick={this.changeUser}>Изменить</button>
+                        <button className="btn service-btn" onClick={this.changeConfirm}>Удалить</button>
+                    </div>
+                    }
+
+                    {error &&
+                    <div>
+                        <p>Пользователь не найден</p>
+                    </div>
+                    }
+                </div>
+                <div>
+                    <p>Здесь будет список пользователей </p>
+                </div>
+                {
+                    this.state.showConfirm &&
+                    <ConfirmButton yes={this.deleteUser} no={this.changeConfirm}
+                                   text={'Вы уверены, что хотите удалить пользователя?'}
+                    />
+                }
+            </div>
+        );
+    }
+};
+

+ 42 - 0
src/components/Admin/CheckBoxWindow.js

@@ -0,0 +1,42 @@
+import React from 'react';
+
+
+class CheckBoxWindow extends React.Component {
+    changeSpecialityArray = (e) => {
+        this.props.changeSpecialityArray(e.target)
+    };
+
+    render() {
+        const {categories, changeFlag,specialityArray} = this.props;
+        console.log(this.props)
+        return (
+            <>
+                <div className = "check-container">
+                    {categories.map(el => (
+                        <div className = "check-speciality" key={el._id}>
+                            <h4>{el.name}</h4>
+                            {
+                                el.services.map(item => (
+                                    <div  className = "check-elem" key={item._id} >
+                                        <input
+                                            type="checkbox"
+                                             value={item._id}
+                                             id={item._id}
+                                             defaultChecked={specialityArray.find(el => el === item._id)}
+                                            onChange={this.changeSpecialityArray}
+                                        />
+                                            <label htmlFor={item._id} className = "check">   {item.name}</label>
+                                    </div>
+                                ))
+                            }
+                        </div>
+                    ))
+                    }
+                </div>
+                <div className = "wrap-check-off"  onClick={changeFlag}></div>
+            </>
+        )
+    }
+}
+
+export default CheckBoxWindow;

+ 25 - 0
src/components/Admin/Input.js

@@ -0,0 +1,25 @@
+import React from 'react';
+
+export default class Input extends React.Component {
+    render(){
+        const {el,className,changeInputValues} = this.props;
+        return (
+            <input
+                className = {className ? className : "appointment admin-form"}
+                id={el.id}
+                type={el.type}
+                name={el.name}
+                value={el.value}
+                placeholder={el.placeholder}
+                minLength={el.minLength}
+                maxLength={el.maxLength}
+                required={el.required}
+                pattern={el.pattern}
+                checked={el.checked}
+                defaultChecked={el.defaultChecked}
+                readOnly={el.readOnly}
+                onChange={(e) => changeInputValues(e)}
+            />
+        );
+    }
+};

+ 191 - 0
src/components/Admin/Orders/ChangeOrder.js

@@ -0,0 +1,191 @@
+import React from 'react';
+import {CustomSelect} from "../../hooks/select";
+import Calendar from "../../Calendar";
+import ConfirmButton from "../../ConfirmButton";
+
+class ChangeOrder extends React.Component {
+    state = {
+        order: {
+            spec: '',
+            doctor: '',
+            time: '',
+            comment: '',
+            orderNumber: null,
+            user: '',
+        },
+        flag: false,
+        showConfirm: false,
+    };
+
+    changeConfirm = () => {
+        this.setState({showConfirm: !this.state.showConfirm})
+    };
+
+    componentDidMount() {
+        this.setState({
+            order: {
+                spec: this.props.order.spec,
+                doctor: this.props.order.doctor,
+                time: this.props.order.time,
+                comment: this.props.order.comment,
+                orderNumber: this.props.order.orderNumber,
+                date: this.props.order.date.split('T')[0],
+                user: this.props.order.user,
+            }
+        });
+    }
+
+    componentWillUnmount() {
+        this.props.clearAppointment()
+    }
+
+    changeOrder = () => {
+        this.setState({flag: !this.state.flag})
+    };
+
+    setDoctor = (e) => {
+        this.props.setAppointmentDoctor(this.props.doctors.find(el => el.name === e)._id)
+    };
+
+    setSpec = (e) => {
+        this.props.setAppointmentSpec({services: this.props.services, data: e})
+    };
+
+    setShedule = (e) => {
+        this.props.setAppointmentShedule({
+            data: e.target.id,
+            services: this.props.services,
+            doctors: this.props.doctors
+        })
+    };
+
+    setTime = (e) => {
+        this.props.setAppointmentTime(e.target.value)
+    };
+
+    setComment = (e) => {
+        this.props.setAppointmentComment(e.target.value)
+    };
+
+    deleteAndPostNewOrder = () => {
+        this.props.deleteOrder({
+            id: this.props.order._id,
+            newOrder: {
+                spec: this.props.appointment.specId,
+                doctor: this.props.appointment.doctorId,
+                shedule: this.props.appointment.sheduleId,
+                time: this.props.appointment.time,
+                comment: this.props.appointment.comment,
+                orderNumber: this.state.order.orderNumber,
+                user:this.state.order.user._id
+            }
+        });
+        this.changeConfirm()
+    };
+
+    render() {
+        const {
+            doctors,
+            appointment,
+            timeArray
+        } = this.props;
+        return (
+            <>
+                {this.state.showConfirm &&
+                <ConfirmButton
+                    yes={this.deleteAndPostNewOrder}
+                    no={this.changeConfirm}
+                    text={'Уверены что хотите изменить заказ?'}
+                />
+                }
+                <div className = "change-order-form" >
+
+                    <input  className = "appointment admin-form order-change-input" readOnly={true} id={this.state.order.orderNumber}
+                           defaultValue={this.state.order.orderNumber}
+                    />
+                    <input className = "appointment admin-form" readOnly={true} id={this.state.order.spec._id}
+                           defaultValue={this.state.order.spec.name}
+                    />
+                    <input  className = "appointment admin-form" readOnly={true} id={this.state.order.doctor._id}
+                           defaultValue={this.state.order.doctor.name}
+                    />
+                    <input className = "appointment admin-form" readOnly={true} id={this.state.order.user._id}
+                           defaultValue={this.state.order.user.email}
+                    />
+                    <input className = "appointment admin-form" readOnly={true} id={this.state.order.date}
+                           defaultValue={this.state.order.date}
+                    />
+                    <input  className = "appointment admin-form" readOnly={true} id={this.state.order.time}
+                           defaultValue={this.state.order.time}
+                    />
+                    <input  className = "appointment admin-form" readOnly={true} id={this.state.order.comment}
+                           defaultValue={this.state.order.comment}
+                    />
+                    <button className = "btn service-btn"  onClick={this.changeOrder}>Изменить заказ</button>
+                    {this.state.flag &&
+                    <div className = "order-change-input">
+                        <input className = "appointment admin-form" readOnly={true} id={this.state.order.orderNumber}
+                               defaultValue={this.state.order.orderNumber}
+                        />
+                        <CustomSelect
+                            label="Выбор врача"
+                            emptyLine={false}
+                            options={doctors}
+                            clickOptionEvent={this.setDoctor}
+                        />
+                        {appointment.doctorId &&
+                            <CustomSelect
+                                label="Выбор услуги"
+                                emptyLine={false}
+                                options={appointment.doctorId ? doctors.find(el => el._id === appointment.doctorId).speciality : []}
+                                clickOptionEvent={this.setSpec}
+                            />
+                        }
+                        {appointment.specId &&
+                        <Calendar
+                            doctor={doctors.find(el => el._id === appointment.doctorId)}
+                            action={this.setShedule}
+                        />
+                        }
+                        {appointment.sheduleId && (
+                            <div className="appointment-time">
+                                <div className="btn-box">
+                                    {timeArray.map((el, index) => (
+                                        <div className="radio-btn" key={Object.keys(el)}>
+                                            <input
+                                                type="radio"
+                                                className="radio"
+                                                name="choise-time"
+                                                id={index}
+                                                onChange={this.setTime}
+                                                value={Object.keys(el)}
+                                            />
+                                            <label htmlFor={index}>{Object.keys(el)}</label>
+                                        </div>
+                                    ))}
+                                </div>
+                                {appointment.time && (
+                                    <textarea
+                                        className="appointment comment"
+                                        rows="2"
+                                        placeholder="Добавить комментарий "
+                                        onChange={this.setComment}
+                                    />
+                                )}
+                            </div>
+                        )}
+                        {appointment.time &&
+                        <button className="btn link" onClick={this.changeConfirm}>Подтвердите запись
+                        </button>
+                        }
+                    </div>
+                    }
+                </div>
+
+                <div className="wrap-check-off" onClick={this.props.clearOrder}></div>
+            </>
+        )
+    }
+}
+
+export default ChangeOrder;

+ 121 - 0
src/components/Admin/Orders/Orders.js

@@ -0,0 +1,121 @@
+import React, {Component} from 'react';
+import {Link} from 'react-router-dom'
+import ChangeOrder from "./ChangeOrder";
+
+class Orders extends Component {
+    state={
+        order:null,
+    };
+
+    componentDidMount() {
+        this.props.getUsers();
+    }
+
+    componentDidUpdate(prevProps, prevState, snapshot) {
+        if(this.props.users.length > 0 && this.props.orders.length === 0)
+            this.props.getOrders({doctors:this.props.doctors,services:this.props.services,users:this.props.users});
+    }
+
+    changeInputFindOrder = (e) => {
+        this.props.changeInputFindOrder(e.target.value)
+    };
+
+    findOrders = () => {
+        this.props.findOrdersArray()
+    };
+
+    enterPressed = (e) => {
+        if (e.key === 'Enter') {
+            this.findOrders();
+        }
+    };
+
+    emailPressed = (e) => {
+        this.props.changeInputFindOrder(e.target.innerText);
+        this.findOrders()
+    };
+
+    changeOrder = (e) => {
+        this.setState({
+            order:!this.state.order ? this.props.orders.find(el => el._id === e.target.id) : null
+        })
+    };
+
+    render() {
+        const{ findOrderInput,ordersArray,searching,orders,doctors,services,
+            appointment,
+            timeArray,
+            setAppointmentSpec,
+            setAppointmentShedule,
+            setAppointmentDoctor,
+            clearAppointment,
+            setAppointmentTime,
+            setAppointmentComment,
+            deleteOrder
+        } = this.props;
+        return (
+            <>
+                {this.state.order && <ChangeOrder
+                    doctors={doctors}
+                    services={services}
+                    order={this.state.order}
+                    clearOrder={this.changeOrder}
+                    appointment={appointment}
+                    timeArray={timeArray}
+                    setAppointmentSpec={setAppointmentSpec}
+                    setAppointmentShedule={setAppointmentShedule}
+                    setAppointmentDoctor={setAppointmentDoctor}
+                    clearAppointment={clearAppointment}
+                    setAppointmentTime={setAppointmentTime}
+                    setAppointmentComment={setAppointmentComment}
+                    deleteOrder={deleteOrder}
+                />}
+            <div className = "orders-container">
+                <div className = "orders-item find-order">
+                    <input className = " appointment admin-form" type="text" onKeyDown={this.enterPressed} onChange={this.changeInputFindOrder}/>
+                    {findOrderInput &&
+                    <button className = "btn service-btn"  id='enter' onClick={this.findOrders}>Найти</button>
+                    }
+                    {searching && ordersArray.length === 0 && <p>Заказ не найден</p>}
+                    {ordersArray.map(el => (
+                        <div className = "order"  key={el._id}>
+                            <div className = "order-date">
+                                <Link onClick={this.changeOrder} id={el._id} className = "order-info">{el.orderNumber}</Link>
+                                <p>{el.date.split('T')[0]}</p>
+                                <p>{el.time}</p>
+                            </div>
+                            <div className="name-info">
+                                 <div className="info-serv-doc">
+                                    <Link to={`/user/${el.user._id}`} className = "order-info">{`${el.user.email}`}</Link>
+                                    <Link to={`/doctors/${el.doctor._id}/false`} className = "order-info">{el.doctor.name}</Link>
+                                    <Link to={`/services/${el.spec._id}/false`} className = "order-info">{el.spec.name}</Link>
+                                </div>                                
+                            </div>
+                        </div>
+                    ))}
+                </div>
+                <div className = "orders-item">
+                    {orders.map(el => (
+                        <div  className = "order"  key={el._id} >
+                            <div className = "order-date">
+                                <Link onClick={this.changeOrder} id={el._id} className = "order-info">{el.orderNumber}</Link>
+                                <p>{el.date.split('T')[0]}</p>
+                                <p>{el.time}</p>
+                            </div>
+                            <div className="name-info">
+                                <div className="info-serv-doc">
+                                    <Link onClick={this.emailPressed} className = "order-info">{`${el.user.email}`}</Link>
+                                    <Link to={`/doctors/${el.doctor._id}/false`} className = "order-info">{el.doctor.name}</Link>
+                                    <Link to={`/services/${el.spec._id}/false`} className = "order-info">{el.spec.name}</Link>
+                                </div>
+                            </div>
+                        </div>
+                    ))}
+                </div>
+            </div>
+        </>
+        );
+    }
+}
+
+export default Orders;

+ 75 - 0
src/components/Admin/Shedule.js

@@ -0,0 +1,75 @@
+import React from 'react';
+import moment from "moment";
+
+import { CustomSelect } from "../hooks/select"
+import Calendar from "../Calendar";
+
+export default class Shedule extends React.Component {
+    state ={
+        startDate:null,
+        endDate:null,
+    };
+
+    post = (e) => {
+        e.preventDefault();
+        let current = new Date(this.state.startDate);
+        let end = new Date (this.state.endDate);
+        while (current.toISOString().split('T')[0] <= end.toISOString().split('T')[0]){
+            if (moment(current).day()!==6 && moment(current).day()!==0){
+                this.props.postShedule({
+                    ...this.props.postNewShedule,
+                    data:current.toISOString().split('T')[0],
+                });
+            }
+            current = new Date(+current + 86400000)
+        }
+    };
+
+    changeStart = (e) => {
+        this.setState({startDate:e.target.value } )
+    };
+    changeEnd = (e) => {
+        this.setState ( { endDate:e.target.value } )
+    };
+    setDoctor = (e) => {
+        this.props.setSheduleDoctor({data:e,doctors:this.props.doctors})
+  
+    };
+
+    render() {
+        const {doctors, postNewShedule} = this.props;
+        const doctor = doctors.find(el => el._id === postNewShedule.doctor);
+        return (
+            <div  className = "shedule-container" >
+                <div className = "option" >
+
+                    <CustomSelect
+                        label="Выберите доктора"
+                        options= {doctors }
+                        clickOptionEvent={this.setDoctor}
+                    /> 
+                    
+                    {postNewShedule.doctor &&
+                        <div className = "input-box">
+                            <input className = "shedule-input " type="date" onChange = {this.changeStart}/>
+                            <input className = "shedule-input right" type="date" onChange = {this.changeEnd}/>
+                        </div>
+                    }
+
+                    {(this.state.startDate && this.state.endDate) &&
+                        <button className = "btn admin" onClick = {this.post}> Отправить </button>
+                    }
+                </div>
+
+                {postNewShedule.doctor &&
+                    <Calendar
+                        doctor={doctor}
+                        action = {console.log }
+                    />
+                }
+            </div>
+        );
+    }
+}
+
+  

+ 0 - 84
src/components/Appointment.js

@@ -1,84 +0,0 @@
-import React from 'react';
-
-
-export default class Appointment extends React.Component {
-
-    componentDidMount() {
-        this.props.setAppointmentDoctor(+this.props.his.match.params.doctor)
-    }
-
-    componentWillUnmount() {
-        this.props.clearAppointment()
-    }
-
-    render() {
-        const {his,dataDoctors,dataServices,dataOrders,appointment,
-            setAppointmentDate,
-            setAppointmentTime,
-            setAppointmentSpec,
-            setAppointmentComment,
-            putOrders
-        } = this.props;
-        const timeArray = [];
-        const doctor = dataDoctors.find(el => el.id === +his.match.params.doctor);
-        if (appointment.date.year){
-            for (let index in doctor.schedule[appointment.date.month][appointment.date.day]){
-                timeArray.push({[`${index}`]:doctor.schedule[appointment.date.month][appointment.date.day][`${index}`]})
-            }
-        }
-        return (
-            <>
-                {doctor &&
-                <div style={{display:'flex',flexDirection:'column',width:'400px'}}>
-                    <p>{doctor.photo}</p>
-                    <p>{doctor.name}</p>
-                    <p>{doctor.lastName}</p>
-                    <p>{doctor.skillsDescription}</p>
-                    <select onChange={(e)=>setAppointmentSpec(e.target.value)} defaultValue='choose spec'>
-                        <option disabled >choose spec</option>
-                        {
-                            doctor.speciality.map(el=> (
-                                <option key={el}>{el}</option>
-                            ))
-                        }
-
-                    </select>
-
-                    {appointment.spec && <input type="date" onChange={(e)=>setAppointmentDate(e.target.value)}/>}
-
-                    {appointment.date.year !== 0 &&
-                    <div>
-                        {
-                            ( +appointment.date.month >= new Date().getMonth()+1 && +appointment.date.day >= new Date().getDate() ) ?
-                                doctor.schedule[appointment.date.month][appointment.date.day] ?
-                                    <div>
-                                        <select onChange={(e)=>setAppointmentTime(e.target.value)} defaultValue='choose time'>
-                                            <option disabled >choose time</option>
-                                            {
-                                                timeArray.map(el=> (
-                                                    <option key={Object.keys(el)[0]}>{Object.values(el)[0] ? Object.keys(el)[0] : null}</option>
-                                                ))
-                                            }
-
-                                        </select>
-                                        <input type="time" readOnly placeholder="Time will be calculated" value={appointment.time ? +appointment.time.split(':')[0] + dataServices[appointment.spec].duration + ':00' : ''}/>
-                                    </div>
-                                    : <p>No work today</p>
-                                : <p>Please choose current or future date</p>
-                        }
-                    </div>
-                    }
-
-                    {appointment.time &&
-                    <div style={{display:"flex",flexDirection:"column"}}>
-                        <input type='text' placeholder='Add comments here' onChange={(e)=>setAppointmentComment(e.target.value)}/>
-                        <button onClick={()=>putOrders([...dataOrders,appointment])}>Confirm Appointment</button>
-                    </div>
-                    }
-
-                </div>
-                }
-            </>
-        );
-    }
-}

+ 81 - 41
src/components/Calendar.js

@@ -1,54 +1,94 @@
-import React, {Component} from 'react';
+import React from 'react';
+import moment from "moment";
+import {connect} from "react-redux";
+import 'moment/locale/ru';
 
-class Calendar extends Component {
+import {
+    createCalendarMonthArray,
+    changeCalendarMonth,
+    resetCurrent
 
-    componentDidMount() {
+} from "../actions/calendar";
+
+export class Calendar extends React.Component {
 
+    componentDidMount() {
+        moment.locale('ru');
+        this.props.createCalendarMonthArray(this.props.doctor)
     }
-    setDate = (e) => {
-        console.log(`${new Date().getFullYear()}-${new Date().getMonth() < 10 ? '0' + new Date().getMonth() : new Date().getMonth()}-${e.target.id < 10 ? '0' + e.target.id : e.target.id}`)
-        document.getElementById('inp_date').value=`${new Date().getFullYear()}-${new Date().getMonth() < 10 ? '0' + new Date().getMonth() : new Date().getMonth()}-${e.target.id < 10 ? '0' + e.target.id : e.target.id}`
+    componentDidUpdate(prevProps) {
+        if (prevProps.doctor !== this.props.doctor) this.props.createCalendarMonthArray(this.props.doctor)
     }
 
-    render() {
-        const date = new Date();
-        const start = new Date(2019, 6, 1);
-        const month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
-        const currentMonth = [];
-        const week = ['пн', 'вт', 'ср', 'чт', 'пт', 'сб', 'вс'];
-        for (let x = 1; x <= month[date.getMonth()]; x++) currentMonth.push(x);
-        const startOfMonth = week.indexOf(week.find(el => el === 'чт'));
-        console.log(date.getDate());
+    componentWillUnmount() {
+        this.props.resetCurrent()
+    }
+
+    addMonth = () => {
+        this.props.changeCalendarMonth(1);
+        this.props.createCalendarMonthArray(this.props.doctor)
+    };
+
+    subMonth = () => {
+        this.props.changeCalendarMonth(-1);
+        this.props.createCalendarMonthArray(this.props.doctor)
+    };
 
+    action = (e) => {
+        this.props.action(e)
+    };
+
+    render() {
+        const {current,monthArray} = this.props;
         return (
-            <div>
-                <table cols={7}>
-                    <caption><button>{'<'}</button>{start.toLocaleString('ru', {month: 'short'})}<button>{'>'}</button></caption>
-                    <tbody>
-                    <tr>
-                        {week.map(el => (<th key={el}>{el}</th>))}
-                    </tr>
-                    <tr >
-                        {currentMonth.map(el=> (el >startOfMonth && el<=7) ? <td key={el} className='cal__td'><button id={el -  startOfMonth} onClick={this.setDate}>{el -  startOfMonth}</button></td> : el <=7 ? <td key={el}><button id={el} disabled>none</button></td> : null) }
-                    </tr>
-                    <tr >
-                        {currentMonth.map(el=> (el > 7-startOfMonth && el <= 14-startOfMonth)?(<td key={el} className='cal__td'><button id={el} onClick={this.setDate}>{el}</button></td>):null)}
-                    </tr>
-                    <tr >
-                        {currentMonth.map(el=> (el > 14-startOfMonth && el <= 21-startOfMonth)?(<td key={el} className='cal__td' ><button id={el} onClick={this.setDate}>{el}</button></td>):null)}
-                    </tr>
-                    <tr >
-                        {currentMonth.map(el=> (el > 21-startOfMonth && el <= 28-startOfMonth)?(<td key={el} className='cal__td'><button id={el}  onClick={this.setDate}>{el}</button></td>):null)}
-                    </tr>
-                    <tr >
-                        {currentMonth.map(el=> el > 28-startOfMonth?(<td key={el} className='cal__td'><button id={el} onClick={this.setDate}>{el}</button></td>):null)}
-                    </tr>
-                    </tbody>
-                </table>
-                <input type="date" id='inp_date'/>
+            <div className = "calendar-container">
+                <div className = "calendar-title-box" >
+                    <button className= "btn angle" onClick={this.subMonth}>
+                        <span className="icon-angle-left"></span>
+                    </button>
+                    <h4>{current.format('MMMM-YYYY')}</h4>
+                    <button  className= "btn angle"  onClick={this.addMonth}>
+                        <span className="icon-angle-right"></span>
+                    </button>
+                </div>
+                <div className = "weekdays">
+                    {moment.weekdaysShort(true).map(el => (
+                        <p  key={el}>{el}</p>
+                    ))}
+                </div>
+                <div  className = "days">
+                    {monthArray.map(el => (
+                        <button
+                            key={el.day}
+                            id={el.day}
+                            disabled={el.disabled}
+                            style={{
+                                backgroundColor:el.backgroundColor,
+                                border:el.border
+                            }}
+                            onClick={this.action}
+                        >
+                            {moment(el.day).format('DD')}
+                        </button>
+                    ))}
+                </div>
             </div>
         );
     }
 }
 
-export default Calendar
+const mapStateToProps = state => {
+    return {
+        current:state.calendar.current,
+        monthArray:state.calendar.monthArray
+    }
+};
+
+const mapDispatchToProps = {
+    createCalendarMonthArray,
+    changeCalendarMonth,
+    resetCurrent
+};
+
+export default connect (mapStateToProps,mapDispatchToProps)(Calendar)
+

+ 22 - 0
src/components/ConfirmButton.js

@@ -0,0 +1,22 @@
+import React, {Component} from 'react';
+
+class ConfirmButton extends Component {
+    render(){
+        const {yes,no,text} = this.props;
+        return(
+            <>
+                <div  className = "confirm-button" >
+                    <h3 >{text}</h3>
+                    <div className="btns">
+                        <button className = "btn confirm yes" onClick={() => yes()}>Да</button>
+                        <button className = "btn confirm no" onClick={() => no()}>Нет</button>                        
+                    </div>
+
+                </div>
+                <div className = "wrap-check-off" style={{zIndex:'10'}}  onClick={no}/>
+            </>
+        )
+    }
+}
+
+export default ConfirmButton;

+ 0 - 31
src/components/Doctors.js

@@ -1,31 +0,0 @@
-import React from 'react';
-import {Link} from 'react-router-dom'
-
-export default class Doctors extends React.Component {
-
-
-    render() {
-        const {data} = this.props
-        return (
-            <div style={{display:'flex', justifyContent:'center', flexWrap:'wrap'}}>
-                {data.map(el => (
-                    <div key={el.id}
-                         style={{display: 'flex', flexDirection: 'column', width: '300px', margin: '10px 20px'}}>
-                        <Link to={`/doctors/${el.id}`}>
-                            <p>{el.photo}</p>
-                            <p>{el.name}</p>
-                            <p>{el.lastName}</p>
-                            <p>{el.age}</p>
-                            <p>{el.skillsDescription}</p>
-                        </Link>
-                        {el.speciality.map(el => (
-                            <Link to={`/services/${el}`} key={el}>{el}</Link>
-                        ))}
-                        <Link to={`/appointment/${el.id}`}>Make an appointment</Link>
-                    </div>
-                ))
-                }
-            </div>
-        );
-    }
-}

+ 16 - 3
src/components/Footer.js

@@ -2,9 +2,22 @@ import React from 'react';
 
 const Footer = () => {
     return (
-        <div>
-            <h1>Footer</h1>
-        </div>
+        <footer className = "footer">
+           <div className="footer-part contacts">
+                    <h4 className ="icon-location">Адрес</h4>
+                    <p> г. Харьков</p>
+                    <p>пл. Конституции, 26</p>
+           </div>
+           <div className="footer-part logo-box">
+               <img src="../images/logo.png" alt="logo"/>
+               </div>
+           <div className="footer-part contacts">
+              <h4 className  = "icon-phone"> Контакты</h4>
+              <p>+38 ( 096 ) 123 - 45 - 67</p>
+              <p>+38 ( 050 ) 123 - 45 - 67</p>
+              <p> +38 ( 063 ) 123 - 45 - 67</p>
+            </div>
+        </footer>
     );
 };
 

+ 0 - 16
src/components/Header.js

@@ -1,16 +0,0 @@
-import React from 'react';
-import {Link} from 'react-router-dom'
-
-const Header = () => {
-    return (
-        <div>
-            <Link to="/">Main Page</Link>
-            <Link to="/doctors">Doctors</Link>
-            <Link to="/services">Services</Link>
-            <Link to="/reviews">Reviews</Link>
-            <button>Sing In</button>
-        </div>
-    );
-};
-
-export default Header;

+ 24 - 0
src/components/Reviews.js

@@ -0,0 +1,24 @@
+import React from 'react';
+// import {Link} from 'react-router-dom';
+// import Button from "../buttons/button";
+
+export class Reviews extends React.Component {
+
+    render() {
+        return (
+            <div className = "main">
+                <div className="info-wrap">
+                    <h2>Отзывы</h2>
+                    <div classdescription = "reviews-container">
+                        ЗДЕСЬ БУДУТ ОТЗЫВЫ ПОСЕТИТЕЛЕЙ
+                    </div>
+                </div>
+
+            </div>
+        )
+    }
+}
+
+
+export default Reviews
+

+ 0 - 21
src/components/Service.js

@@ -1,21 +0,0 @@
-import React from 'react';
-import {Link} from "react-router-dom";
-
-
-export default class Service extends React.Component {
-
-
-    render() {
-        const {his,data} = this.props;
-        const path = his.match.params.service;
-        return (
-            <div style={{display:'flex',flexDirection:'column', width:'200px', margin:'10px 20px'}}>
-                {data[path].name}
-                <p>Duration:{data[path].duration}h</p>
-                <p>{data[path].description}</p>
-                <p>Price:{data[path].price}$</p>
-                <Link to={`/appointment/${path}`}>Make an appointment</Link>
-            </div>
-        );
-    }
-}

+ 0 - 29
src/components/Services.js

@@ -1,29 +0,0 @@
-import React from 'react';
-import {Link} from 'react-router-dom'
-
-export default class Services extends React.Component {
-
-
-    render() {
-        const {data} = this.props;
-        return (
-            <div style={{display:'flex', justifyContent:'center', flexWrap:'wrap'}}>
-                {
-                    data.map(el => (
-                        <div key={el.id} style={{display:'flex',flexDirection:'column', width:'200px', margin:'10px 20px'}}>
-                            <p>{el.name}</p>
-                            <p>Duration:{el.duration}h</p>
-                            <p>{el.description}</p>
-                            <p>Price:{el.price}$</p>
-                            <div>
-                            <Link to={`/services/service${el.id}`}>More Info</Link>
-                                <button>Make appointment</button>
-                            </div>
-                        </div>
-                    ))
-                }
-
-            </div>
-        );
-    }
-}

+ 178 - 0
src/components/appointment/Appointment.js

@@ -0,0 +1,178 @@
+import React from "react";
+import {connect} from "react-redux";
+import moment from "moment";
+import { CustomSelect } from "../hooks/select";
+
+import {
+    setAppointmentSpec,
+    setAppointmentShedule,
+    setAppointmentDoctor,
+    clearAppointment,
+    setAppointmentTime,
+    setAppointmentComment,
+    postOrders
+} from "../../actions/appointment";
+
+import Calendar from "../Calendar";
+
+export class Appoint extends React.Component {
+    state = {
+        pickedDate: null
+    };
+
+    componentDidMount() {
+        this.props.setAppointmentDoctor(this.props.match.params.doctorId)
+    }
+
+    componentWillUnmount() {
+        this.props.clearAppointment()
+    }
+
+    setSpec = (e) => {
+        this.props.setAppointmentSpec({
+            data: e,
+            services: this.props.services
+        })
+    };
+
+    setShedule = (e) => {
+        this.setState({pickedDate: e.target.id});
+        this.props.setAppointmentShedule({
+            data: e.target.id,
+            services: this.props.services,
+            doctors: this.props.doctors
+        })
+    };
+
+    setTime = (e) => {
+        this.props.setAppointmentTime(e.target.value)
+    };
+
+    setComment = (e) => {
+        this.props.setAppointmentComment(e.target.value)
+    };
+
+    postOrder = () => {
+        this.props.postOrders({
+            shedule: this.props.appointment.sheduleId,
+            time: this.props.appointment.time,
+            doctor: this.props.appointment.doctorId,
+            spec: this.props.appointment.specId,
+            comment: this.props.appointment.comment,
+            user: this.props.user._id
+        })
+    };
+
+
+    render() {
+        const {appointment, timeArray, doctors, services, match} = this.props;
+        const doctor = doctors.find(el => el._id === match.params.doctorId);
+        let spec;
+        if (appointment.specId) {
+            spec = services.find(el => el._id === appointment.specId)
+        }
+        return (
+            <>
+                <div className="main">
+                    {doctor &&
+                        <div className="info-wrap">
+                            <div className="card">
+                                <div className="card-item present">
+                                    <div className="photo">
+                                        <img src={`.${doctor.photo}`} alt={doctor.name}/>
+                                    </div>
+                                    <div className="order">
+                                        <h3>{doctor.name}</h3>
+                                        <p className="highlights">{doctor.profession}</p>
+                                        <CustomSelect
+                                            label="Выбор услуги"
+                                            emptyLine = {false}
+                                            options={doctor.speciality}
+                                            clickOptionEvent={this.setSpec}
+                                        />
+                                    </div>
+                                </div>
+                                <div className="card-item desc">
+                                    <div className="date-container">
+                                        {appointment.specId &&
+                                            <Calendar
+                                                doctor={doctor}
+                                                action={this.setShedule}
+                                            />
+                                        }
+                                        {appointment.sheduleId && (
+                                            <div className="appointment-time">
+                                                <div className="btn-box">
+                                                    {timeArray.map((el, index) => (
+                                                        <div className="radio-btn" key={Object.keys(el)}>
+                                                            <input
+                                                                type="radio"
+                                                                className="radio"
+                                                                name="choise-time"
+                                                                id={index}
+                                                                onChange={this.setTime}
+                                                                value={Object.keys(el)}
+                                                            />
+                                                            <label htmlFor={index}>{Object.keys(el)}</label>
+                                                        </div>
+                                                    ))}
+                                                </div>
+                                                {appointment.time && (
+                                                    <textarea
+                                                        className="appointment comment"
+                                                        rows="2"
+                                                        placeholder="Добавить комментарий "
+                                                        onChange={this.setComment}
+                                                    />
+                                                )}
+                                            </div>
+                                        )}
+                                    </div>
+                                    {appointment.specId &&
+                                        <div className="order-information">
+                                            <p>{spec.name}</p>
+                                            <p>Длительность: {spec.duration} ч.</p>
+                                            <p>Цена от {spec.price} грн.</p>
+                                            {this.state.pickedDate &&
+                                                <p> {moment(this.state.pickedDate).format("DD-MMMM-YYYY")} </p>
+                                            }
+                                            {appointment.time &&
+                                            <>
+                                                <p>{appointment.time}</p>
+                                                <button className="btn link" onClick={this.postOrder}>Подтвердите запись
+                                                </button>
+                                            </>
+                                            }
+                                        </div>
+                                    }
+                                </div>
+                            </div>
+                        </div>
+                    }
+                </div>
+            </>
+        );
+    }
+}
+
+const mapStateToProps = state => {
+    return {
+        appointment: state.appointment.appointment,
+        timeArray: state.appointment.timeArray,
+        doctors: state.app.doctors,
+        services: state.services.services,
+        user:state.auth.user
+    };
+};
+
+const mapDispatchToProps = {
+    setAppointmentSpec,
+    setAppointmentShedule,
+    setAppointmentDoctor,
+    clearAppointment,
+    setAppointmentTime,
+    setAppointmentComment,
+    postOrders
+};
+
+export default connect(mapStateToProps,mapDispatchToProps)(Appoint);

+ 47 - 0
src/components/auth/signIn.js

@@ -0,0 +1,47 @@
+import React from "react";
+
+import { useForm } from "../hooks/useForm";
+import Input from "../input";
+
+import Button from "../buttons/button";
+import { logInForm } from "../../utils/formFields";
+
+export const SignInForm = ({ error, submitHandler }) => {
+	const [form, { onChangeHandler, returnAllValues, focusEvent, blurEvent }] = useForm(logInForm);
+
+	const submit = e => {
+		e.preventDefault();
+		const values = returnAllValues();
+
+		submitHandler(values);
+	};
+
+	return (
+		<div className="auth__auth-box">
+			<form onSubmit={submit} className="auth__auth-form">
+				{Object.keys(form.form).map(input_name => {
+					return (
+						<Input
+							key={form.form[input_name].id}
+							id={form.form[input_name].id}
+							value={form.form[input_name].value}
+							name={form.form[input_name].name}
+							type={form.form[input_name].type}
+							fail={form.form[input_name].fail}
+							touch={form.form[input_name].touch}
+							label={form.form[input_name].label}
+							onChange={onChangeHandler}
+							onFocus={focusEvent}
+							onBlur={blurEvent}
+							autoComplete="off"
+						/>
+					);
+				})}
+				{error && <p className="auth__error-auth-text">{error}</p>}
+				<div className="auth__control-box">
+					<Button disabled={!form.validForm} className="auth__submit-btn" type="submit" text="Войти" />
+				</div>
+			</form>
+		</div>
+	);
+};

+ 48 - 0
src/components/auth/signUp.js

@@ -0,0 +1,48 @@
+import React from "react";
+
+import { signUpForm } from "../../utils/formFields";
+import { useForm } from "../hooks/useForm";
+
+import Input from "../input";
+import Button from "../buttons/button";
+
+export const SignUpForm = ({ submitHandler, error, successRegister }) => {
+	const [form, { onChangeHandler, returnAllValues, focusEvent, blurEvent }] = useForm(signUpForm);
+
+	const submit = e => {
+		e.preventDefault();
+		const values = returnAllValues();
+
+		submitHandler(values);
+	};
+
+	return (
+		<div>
+			<form onSubmit={submit} className="auth__auth-form">
+				{Object.keys(form.form).map(input_name => {
+					return (
+						<Input
+							key={form.form[input_name].id}
+							id={form.form[input_name].id}
+							value={form.form[input_name].value}
+							name={form.form[input_name].name}
+							type={form.form[input_name].type}
+							fail={form.form[input_name].fail}
+							touch={form.form[input_name].touch}
+							label={form.form[input_name].label}
+							onChange={onChangeHandler}
+							onFocus={focusEvent}
+							onBlur={blurEvent}
+							autoComplete="off"
+						/>
+					);
+				})}
+				{successRegister && <p className="auth__success-auth-text">{successRegister}</p>}
+				{error && <p className="auth__error-auth-text">{error}</p>}
+				<div className="auth__control-box">
+					<Button disabled={!form.validForm} className="auth__submit-btn" type="submit" text="Зарегистрироваться" />
+				</div>
+			</form>
+		</div>
+	);
+};

+ 7 - 0
src/components/buttons/btn.js

@@ -0,0 +1,7 @@
+import React from 'react';
+
+export default ({ text,type = 'button', ...rest }) => (
+    <button type={type} {...rest}>
+        { text }
+    </button>
+);

+ 5 - 0
src/components/buttons/button.js

@@ -0,0 +1,5 @@
+import React from "react";
+
+
+export default ({ text, ...rest }) => 
+<button {...rest}>{text}</button>;

+ 18 - 0
src/components/header/index.js

@@ -0,0 +1,18 @@
+import React from "react";
+import {Link}  from "react-router-dom"
+import logo from "../../assets/images/logo.png";
+import Navigation from "./navigation"
+
+
+
+export default () => (
+	<header className="header">
+		<div className="logo-box">
+				<Link to = "/">
+					<img src= {logo} className = "logo" alt="logo"/>
+				</Link>
+			</div>
+			<Navigation/>
+	</header>
+);
+

+ 67 - 0
src/components/header/navigation.js

@@ -0,0 +1,67 @@
+import React, {Component} from "react";
+import { Link, withRouter } from "react-router-dom";
+import { connect } from "react-redux";
+
+import { userLogout} from "../../actions/auth"
+
+class Header extends Component {
+	state = {
+		
+	}
+
+	logoutHandler  = (e) => {
+		localStorage.removeItem('userId')
+		this.props.userLogout();
+		this.props.history.push('/')
+	};
+
+	render(){
+	const { user } = this.props;
+	const liArr = [
+		{ path: "/", id: 1, text: "Главная", hideWhenAuth:false},
+		{ path: "/doctors",  id: 2,  text: "Специалисты", hideWhenAuth:false },
+		{ path: "/services", id: 3,  text: "Услуги", hideWhenAuth:false},
+		{ path: "/reviews", id: 4, text: "Отзывы", hideWhenAuth:false },
+		{ path: "/auth", id: 5, text: "Войти", hideWhenAuth:true
+		}
+	];
+
+	return (
+		<nav className=" nav icon-dehaze"
+			// onClick = { ( ) => { document.querySelector('.list').style.display = " block"    }  }
+		>
+			<ul className=" list ">
+			{liArr.map(el =>
+				el.hideWhenAuth && user ? null :
+					(
+						<li className="item" key={el.id}>
+							<Link to={el.path}>{el.text}</Link>
+						</li>
+					)
+			)}
+			{Object.keys(user).length > 0 ?
+				user.role ?
+						(<li className="item" key={6}>
+							<Link to={ "/admin"}>{"Admin"} <span  className="icon-exit" onClick={this.logoutHandler}></span></Link>
+						</li>) :
+				user.doctor ?
+					(<li className="item" key={6}>
+						<Link to={ "/doctor"}>{"Reviews"}<span  className="icon-exit" onClick={this.logoutHandler}></span></Link>
+					</li>) :
+					(<li className="item" key={6}>
+						<Link to={ "/user"}>{user.firstName}<span  className="icon-exit" onClick={this.logoutHandler}></span></Link>
+					</li>) :	<li className="item" key={5}>
+										<Link to={"/auth"}>Войти</Link>
+									</li>
+			}
+			</ul>
+		</nav>
+	)
+	}
+}
+
+const mapStateToProps = state => ({
+	user: state.auth.user
+});
+
+export default connect(mapStateToProps,{userLogout})(withRouter(Header));

+ 9 - 0
src/components/hooks/loader.js

@@ -0,0 +1,9 @@
+import React from "react";
+
+export default ({ children, flag }) => (
+    flag ?
+        <div className = "loader-box">
+            <img className = "loader" src="../images/loader.gif" alt="Loading"/>
+            {/* <p>  Loading... </p> */}
+        </div>
+    : children);

+ 115 - 0
src/components/hooks/select.js

@@ -0,0 +1,115 @@
+import React from "react";
+
+
+
+
+
+
+export const CustomSelect = ({ label, options , emptyLine, searchInput = true,  reset, clickOptionEvent = () =>{} }) => {
+
+	const [copyOption, setCopyOption] = React.useState([]);
+	const [show, toggleShow] = React.useState(false);
+	const [value, toggleValue] = React.useState("");
+	const [inputValue, toggleInputValue] = React.useState("");
+	const list = React.createRef();
+
+
+
+	React.useEffect(() => {
+		document.addEventListener("mousedown", handleClickOutSide);
+		return () => document.removeEventListener("mousedown", handleClickOutSide);
+	});
+
+	React.useEffect(() => {
+		if (reset) {
+			toggleValue("");
+			toggleInputValue("");
+			setCopyOption(options);
+
+			toggleShow(false);
+		}
+	}, [options, reset]);
+
+	React.useEffect(() => {
+		setCopyOption(options);
+	}, [options]);
+
+	const handleClickOutSide = e => {
+		if (!show) return;
+
+		if (list.current && !list.current.contains(e.target)) {
+			toggleShow(false);
+		}
+	};
+
+	const toggleEvent = text => {
+		if (typeof clickOptionEvent === "function" ) clickOptionEvent(text);
+		toggleValue(text);
+		toggleInputValue(text);
+		toggleShow(false);
+	};
+
+	const clickOnEptyLine = (text) => {
+		if (typeof clickOptionEvent === "function" ) clickOptionEvent(text);
+		toggleValue("");
+		toggleInputValue("");
+
+		toggleShow(false);
+	};
+
+	const chahgeValueEvent = e => {
+		const { value } = e.target;
+		toggleInputValue(e.target.value);
+
+		if (!value) {
+			setCopyOption(options);
+			toggleInputValue(value);
+		} else {
+			const filtered = copyOption.filter(el => el.name.toLowerCase().indexOf(value.toLowerCase()) >= 0);
+
+			setCopyOption(filtered);
+			toggleInputValue(value);
+		}
+	};
+
+	return (
+		<div className="select ">
+			{label && (
+				<label htmlFor="select" className="select__lable">
+					{label}
+				</label>
+			)}
+			<div className="select__value-box" onClick={() => toggleShow(true)}>
+				{searchInput ? null : <span>{value} &nbsp;</span>}
+				<input
+					value={inputValue}
+					autoComplete="off"
+					type={searchInput ? "text" : "hidden"}
+					readOnly="readonly"
+					onChange={chahgeValueEvent}
+					id="select"
+					className="select__input  icon-angle-down"
+				/>
+				<span className="icon-angle-down"></span>
+			</div>
+			{show && (
+				<ul className="select__list " ref={list}>
+					<div className="scrollbar" id ="style">
+							<div className="force-overflow"></div>
+						
+						{emptyLine && (
+							<li className="select__item" onClick={clickOnEptyLine}>
+								Выбрать 
+							</li>
+						)}
+						{copyOption.map(el => (
+							<li className="select__item" key={el._id} onClick={toggleEvent.bind(null, el.name)}>
+								{el.name}
+							</li>
+						))}
+					</div>
+				</ul>
+			)}
+		</div>
+	);
+};

+ 85 - 0
src/components/hooks/useForm.js

@@ -0,0 +1,85 @@
+import { useState } from "react";
+
+export const useForm = initialValues => {
+	const [form, setFormProp] = useState(initialValues);
+
+	const validator = (rules, value, allForm) => {
+		const valid = Object.keys(rules).reduce((prev, elem) => {
+			if (prev) return true
+			const check = rules[elem].cb(value, allForm[rules[elem].match])
+			if (!prev && check) return check
+
+			return false
+		}, false)
+
+		return valid;
+	};
+
+	const onChangeHandler = e => {
+		const { name, value } = e.target;
+
+		setFormProp(prevState => {
+			const values = Object.keys(prevState.form).reduce((prev, elem) => {
+				if (elem === name) return prev.concat(value);
+				return prev.concat(prevState.form[elem].value);
+			}, []);
+
+			return {
+				...prevState,
+				form: {
+					...prevState.form,
+					[name]: {
+						...prevState.form[name],
+						value
+					}
+				},
+				validForm: values.some(value => value)
+			};
+		});
+	};
+
+	const focusEvent = e => {
+		const { name } = e.target;
+
+		setFormProp(prevState => ({
+			...prevState,
+			form: {
+				...prevState.form,
+				[name]: {
+					...prevState.form[name],
+					touch: true
+				}
+			}
+		}));
+	};
+
+	const blurEvent = e => {
+		const { name, value } = e.target;
+
+		const prevValues = Object.keys(form.form).reduce((prev, elem) => {
+			return { ...prev, [elem]: elem === name ? value : form.form[elem].value };
+		}, {});
+
+		setFormProp(prevState => {
+			const valid = validator(prevState.form[name].validation, value, prevValues);
+			return {
+				...prevState,
+				form: {
+					...prevState.form,
+					[name]: {
+						...prevState.form[name],
+						fail: value ? valid : true
+					}
+				}
+			};
+		});
+	};
+
+	const returnAllValues = () => {
+		return Object.keys(form.form).reduce((prev, elem) => {
+			return { ...prev, [elem]: form.form[elem].value };
+		}, {});
+	};
+
+	return [form, { onChangeHandler, returnAllValues, focusEvent, blurEvent }];
+};

+ 13 - 0
src/components/input.js

@@ -0,0 +1,13 @@
+import React from 'react';
+
+export default ({ id, label, type = "text", fail, touch, ...rest }) => (
+    <label htmlFor={id} className="input-box">
+        {label}
+        <input 
+            className={fail && touch ? 'input-box__input input-box__input--fail' : 'input-box__input'}
+            id={id}
+            type={type}
+            {...rest}
+        />
+    </label>
+);

+ 77 - 0
src/components/main/Main.js

@@ -0,0 +1,77 @@
+import React from 'react';
+import {Link} from 'react-router-dom';
+import Scrollchor from 'react-scrollchor';
+
+// import Button from "../buttons/button";
+import About from "./aboutUs";
+import Team from "./team";
+// import MyMap from "./myMap";
+
+
+import {connect} from 'react-redux'
+
+    
+export class Main extends React.Component {
+ render() {
+
+    return (
+            <main className = "main">
+
+                <aside>
+                    <ul className="sidebar-ul">
+                        <li className="sidebar-item"><Scrollchor to="#" className="nav-link"><span className="icon-lens"></span></Scrollchor></li>
+                        <li className="sidebar-item"><Scrollchor to="#team" className="nav-link"><span className="icon-lens"></span></Scrollchor></li>
+                        <li className="sidebar-item"><Scrollchor to="#banner" className="nav-link"><span className="icon-lens"></span></Scrollchor></li>
+                        <li className="sidebar-item"><Scrollchor to="#about" className="nav-link"><span className="icon-lens"></span></Scrollchor></li>
+                    </ul>
+                </aside>
+
+               <div className="container">
+                    <div className="wrapper">
+                                <div className="title-box">
+                                    <img className = "logotype" src="./images/logo.png" alt=""/>
+                                    <h1>Стоматология для всей семьи</h1>
+                                    <Link to={ `/appointment` } className = "btn ">Записаться на приём</Link>
+                                </div>
+                    </div>
+                </div>
+
+                    <div className="wrapper"  id = "team">
+                        <Team doctorsArr = {this.props.app.doctors} />
+                    </div>
+
+                <div className=" case" id = "banner">
+                        <img className = "banner" src="./images/medical.jpeg" alt="medical"/>
+                        <div className="button-box">
+                        <Link to={`/appointment`} className = "btn">Записаться на приём</Link>
+                        </div>     
+                 </div>
+
+                 <div className="wrapper"  id = "about">
+                    <About/>
+                 </div>
+
+                {/* <div className="case"> */}
+                    {/* <MyMap /> */}
+                {/* </div> */}
+              </main> 
+           
+          
+        )
+    }
+}
+
+    const mapStateToProps = state => {
+        return {
+            app:state.app
+        }
+    };
+    
+    const mapDispatchToProps = {
+        // postDoctors,
+        // postServices
+    };
+    
+    export default connect (mapStateToProps,mapDispatchToProps)(Main)
+
+

+ 58 - 0
src/components/main/aboutUs.js

@@ -0,0 +1,58 @@
+import React from 'react';
+
+
+export default class AboutSection extends React.Component {
+
+
+    render() {
+        return (
+            <>
+                <div className="wrapper">
+                    <h2>О клинике</h2>
+                    <div className="aboutsection">
+                      
+                        <p>Стоматологическая клиника «Art Dental studio» – это современное медучреждение, 
+                            которое оказывает полный спектр стоматологических услуг и использует при этом новейшее 
+                            оборудование ведущих мировых производителей. 
+                        </p>
+                        <p> Нашими постоянными пациентами являются не только взрослые, но и дети. 
+                            Специально для них у нас есть услуги серебрения зубов, удаления молочных зубов, 
+                            стеклоиономерное пломбирование и аппаратное ортодонтическое исправление прикуса
+                            (до 16 лет). Также в нашей клинике Вы можете получить консультацию профессионального 
+                            ортодонта и пародонтолога. Или решить любую проблему, связанную с зубами – наши врачи могут 
+                            поставить хоть фотополимерную пломбу, хоть установить имплант. Дабы Вы не испытывали страха и не 
+                            чувствовали боли, мы используем только эффективную высококачественную анестезию. У нас Вы 
+                            сможете сделать как профессиональную чистку зубов, так и украсить ваши зубки модными украшениями. Если зубной 
+                            ряд нуждается в отбеливании или реставрации, с ними мы тоже справимся без проблем. Стоматологи клиники
+                            «Art Dental studio» поставят коронку, подберут протез, микропротез, проведут шинирование, 
+                            пломбирование и сделают все, чтобы Вы гордились своей улыбкой. У Вас проблемы с прикусом или 
+                            неровные зубы? Обратитесь к нам и убедитесь, что всё реально исправить с помощью грамотно 
+                            подобранной брекет-системы. Вас гарантированно перестанет беспокоить даже чувствительность 
+                            зубов, если с ними поработает наш высококвалифицированный стоматолог.
+                        </p> 
+                        <p>  И это далеко еще не весь спектр наших стоматологических услуг. С полным списком, 
+                            а заодно и расценками, можно ознакомиться в разделе «Услуги». 
+                            Стоматологическая клиника «Art Dental studio» работает со всеми 
+                            страховыми компаниями. Мы любим и ценим наших пациентов, поэтому всегда настоятельно 
+                            рекомендуем им посещать стоматолога не реже двух раз в год. Профилактический осмотр очень 
+                            важен, так что зря многие им пренебрегают. Только так можно предупредить развитие заболеваний 
+                            пародонта и принять своевременные меры по устранению неприятных симптомов и дискомфорта в 
+                            ротовой полости.
+                        </p>
+                        <p>«Art Dental studio» работает на рынке стоматологических услуг не первый год, поэтому мы 
+                            применяем только новейшие технологии и находим индивидуальные решения для каждого 
+                            пациента. Благодаря всему этому Вам будет комфортно с нами сотрудничать. Улыбайтесь на 
+                            здоровье!
+                        </p>
+                    </div>
+                </div>
+            </>
+        )
+    }
+}
+
+
+
+
+
+

+ 56 - 0
src/components/main/myMap.js

@@ -0,0 +1,56 @@
+import React from "react";
+import { compose, withProps } from "recompose";
+import { withScriptjs, withGoogleMap, GoogleMap, Marker } from "react-google-maps";
+// import InfoBox from "react-google-maps/lib/components/addons/InfoBox";
+
+// const { InfoBox } = require("react-google-maps/lib/components/addons/InfoBox");
+ const MyMapComponent = compose(
+  withProps({
+    googleMapURL: "https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places",
+    loadingElement: <div style={{ height: `100%` }} />,
+    containerElement: <div style={{ height: `500px` }} />,
+    mapElement: <div style={{ height: `100%` }} />,
+    mapTypeId: 'hybrid'
+  }),
+  withScriptjs,
+  withGoogleMap
+)((props) =>
+  <GoogleMap
+    defaultZoom={15}
+    defaultCenter={{ lat: 49.992438, lng: 36.232169 }}
+    defaultType = {"hybrid"}
+  >
+    {props.isMarkerShown && <Marker position={{ lat: 49.992438, lng: 36.232169 }} onClick={props.onMarkerClick} />}
+    
+  </GoogleMap>
+)
+
+export default class MyFancyComponent extends React.PureComponent {
+  state = {
+    isMarkerShown: false,
+  }
+
+  componentDidMount() {
+    this.delayedShowMarker()
+  }
+
+  delayedShowMarker = () => {
+    setTimeout(() => {
+      this.setState({ isMarkerShown: true })
+    }, 3000)
+  }
+
+  handleMarkerClick = () => {
+    this.setState({ isMarkerShown: false })
+    this.delayedShowMarker()
+  }
+
+  render() {
+    return (
+      <MyMapComponent
+        isMarkerShown={this.state.isMarkerShown}
+        onMarkerClick={this.handleMarkerClick}
+      />
+    )
+  }
+}

+ 38 - 0
src/components/main/team.js

@@ -0,0 +1,38 @@
+import React from 'react';
+import {Link} from 'react-router-dom';
+// import Button from "../buttons/button";
+
+
+
+export default class Team extends React.Component {
+    render( ) {
+        const {doctorsArr } = this.props
+        // console.log (doctorsArr)
+        return (
+            <>
+                <h2>Наши врачи</h2>
+                <div className = "team-container">
+                    {doctorsArr.map  ( el => 
+                         <div className="item"  key = {el._id} >
+                             <div className="photo">
+                                <img src= {el.photo} alt= {el.name}/>
+                                <Link to = {`/doctors/${el._id}`}>
+                                    <div className="desc">
+                                        <h3>{el.name}</h3>
+                                        <p className="experience">Опыт работы {new Date().toISOString().split('T')[0].split('-')[0] - el.experience.split('T')[0].split('-')[0]} лет</p>
+                                        <p className="rank">{el.profession}</p>
+                                    </div>
+                                </Link>
+                             </div>
+                           
+                             {/* <div className="link-box">
+                                <Link to = "/doctors" className = "btn link more">Подробнее ...</Link>
+                                <Link to ={`/appointment/${el._id}`} className = "btn link ">Записаться на приём</Link>
+                            </div> */}
+                        </div>
+                    ) }
+                 </div>
+            </>
+        ) 
+    }
+}        

+ 37 - 0
src/components/modal.js

@@ -0,0 +1,37 @@
+import React, { Component } from "react";
+import ReactDOM from "react-dom";
+
+
+export default class Modal extends Component {
+	modal = React.createRef();
+
+	componentWillMount() {
+		document.addEventListener("mousedown", this.handleClickOutside);
+	}
+
+	componentWillUnmount() {
+		document.removeEventListener("mousedown", this.handleClickOutside);
+	}
+
+	handleClickOutside = event => {
+		if (!this.props.open) return;
+
+		if (this.modal.current && !this.modal.current.contains(event.target)) {
+			this.props.close();
+		}
+	};
+
+	render() {
+		const { children, open } = this.props;
+		return open
+			? ReactDOM.createPortal(
+					<div className="modal-wrapper">
+						<div className="modal" ref={this.modal}>
+							{children}
+						</div>
+					</div>,
+					document.body
+			  )
+			: null;
+	}
+}

+ 54 - 0
src/components/services/Services.js

@@ -0,0 +1,54 @@
+import React from "react";
+
+import {Link} from 'react-router-dom';
+import {connect} from "react-redux";
+
+export class Services extends React.Component {
+    render() {
+        const {categories} = this.props;
+        return (
+            <div className="main">
+                <div className="wrapper">
+                    <div className="doctors-wrap  services">
+                        <div className="categories" id="accordion">
+                            {categories.map(el => (
+                                
+                                <div className="service-type" key={el._id} id={`item${el._id}`} >
+                                    <a href={`#item${el._id}`} className="categories-link icon-angle-down" key={el._id} >
+                                         {el.name}
+                                    </a>
+
+                                    {el.services.map(item => (
+                                        <div className="servise-name" key={item._id}>
+                                            <p>{item.name}</p>
+                                            <p>Стоимость: {item.price} грн.</p>
+                                            <div>
+                                                <Link to={`/appointment/${item._id}`}
+                                                      className="btn service-btn"> Записаться </Link>
+                                            </div>
+                                        </div>
+                                    ))}
+                                </div>
+
+                            ))}
+                        </div>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+}
+
+const mapStateToProps = state => {
+    return {
+        categories: state.services.categories
+    };
+};
+
+const mapDispatchToProps = {
+  
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(Services);
+
+{/* <Link to={`/services/${item._id}/true`}>{item.name}</Link> */}

+ 64 - 0
src/components/services/categories.js

@@ -0,0 +1,64 @@
+// import React from 'react';
+
+// // import {Link} from 'react-router-dom';
+// import {connect} from 'react-redux';
+
+
+// export class Services extends React.Component {
+    
+//     render() {
+//         const { categories} = this.props;
+//         const servArray =  Object.keys(categories).map(key => {
+//             return [key, categories[key]];
+//         })
+//         // const category = servArray.slice (1, 2 )
+
+//         // console.log ("data:", data);
+//         // console.log ("categories:", Object.values (categories))
+//         console.log ("servArray:", servArray)
+//         // console.log ("category:", category)
+//         // console.log ("this.props:", this.props.app)
+
+//         return (
+//             <div className="main">
+//                 <div className="wrapper">
+//                     <div className = "doctors-wrap">
+//                         {  servArray.map (( el, index )=> (
+//                             <div className = "serv-wrap" key = {index}>
+//                                 {   el[1].map ((item, index) => (
+                                          
+//                                     <div className = "servise-name" key = {index} >
+//                                         <p>{item.name}</p>
+//                                         <p>Длительность: {item.duration} ч.</p> 
+//                                         <p>Цена: {item.price} грн.</p>
+//                                         <div>
+                                            
+//                                             <button className = "btn service-btn"> Записаться на приём </button>
+//                                         </div>
+//                                     </div>
+//                                 ))}
+//                             </div>
+//                         ))
+//                         }
+//                     </div>
+//                 </div>
+//             </div>
+//         );
+//     }
+// }
+
+// const mapStateToProps = state => {
+//     return {
+//         app:state.app,
+//         data:state.services.services,
+//         categories:state.services.categories
+//     }
+// };
+
+// const mapDispatchToProps = {
+
+// };
+
+// export default connect (mapStateToProps,mapDispatchToProps)(Services)
+
+

+ 54 - 0
src/components/specialists/Doctors.js

@@ -0,0 +1,54 @@
+import React from 'react';
+import {Link} from 'react-router-dom'
+import {connect} from 'react-redux'
+
+export class Doctors extends React.Component {
+        render() {
+        const {data} = this.props;
+        return (
+            <div className="main">
+                <div className="wrapper">
+                    <div className = "doctors-wrap">
+                        {
+                            data.map(el => (
+                                <div className="item"  key = {el._id} >
+                                    <div className="photo">
+                                        <Link to = {`/doctors/${el._id}/true`} >
+                                            <img src= {el.photo} alt= {el.name}/>
+                                            <div className="hover-block">
+                                                <div className = "btn link more">Подробнее ... </div>
+                                            </div>
+                                        </Link>
+                                    </div>
+                                    
+                                    <div className="desc">
+                                        <h3>{el.name}</h3>
+                                        <p className="rank">{el.profession}</p>
+                                        <div className="link-box">
+                                            <Link to={`/appointment/${el._id}`} className = "btn link ">Записаться на приём</Link>
+                                        </div>     
+                                    </div>
+
+                                </div>
+                            ))
+                        }
+                    </div>
+                </div>                
+            </div>
+        );
+    }
+}
+
+const mapStateToProps = state => {
+    return {
+        data:state.app.doctors
+    }
+};
+
+const mapDispatchToProps = {
+};
+
+export default connect (mapStateToProps,mapDispatchToProps)(Doctors)
+
+
+

+ 56 - 0
src/components/specialists/MoreInfo.js

@@ -0,0 +1,56 @@
+import React from 'react';
+import {Link} from 'react-router-dom'
+import {connect} from 'react-redux'
+
+export class MoreInfo extends React.Component {
+    
+    render() {
+        const {match,doctors,services} = this.props;
+        const doctor = doctors.find(el => el._id === match.params.doctor);
+        const service = services.find(el => el._id === match.params.service);
+        return (
+            <>
+            <div className="main">
+                {doctor &&
+                    <div className = "info-wrap">
+                        <div className="info">
+                            <div className="info-item">
+                                <img src={`../.${doctor.photo}`} alt={doctor.name}/>
+                            </div>
+                             <div className="info-item info-desc">
+                                 <h3> {doctor.name} </h3>
+                                <p className = "highlights">{doctor.profession}</p>
+                                <p className = "highlights">Опыт работы более {new Date().toISOString().split('T')[0].split('-')[0] - doctor.experience.split('T')[0].split('-')[0]}  лет</p>
+                                {doctor.skillsDescription.split ("<br>").map ( (el, index) => (  <p key= {index}> { el } </p>)  ) }
+                                 {match.params.flag === 'true' && <Link to={`/appointment/${doctor._id}`} className = "btn link">Записаться на приём</Link>}
+                             </div>
+                        </div>
+                    </div>}
+
+                    {service  &&
+                    <div  className = "info-wrap">
+                        {service.name}
+                        <p>Duration: {service.duration} h</p>
+                        <p>{service.description}</p>
+                        <p>Price: {service.price} грн.</p>
+                        {match.params.flag === 'true' && <Link to={`/appointment/${service._id}`} className = "btn link admin">Записаться на приём</Link>}
+
+                    </div>}
+               </div>
+              
+            </>
+        );
+    }
+}
+
+const mapStateToProps = state => {
+    return {
+        doctors:state.app.doctors,
+        services:state.services.services
+    }
+};
+
+const mapDispatchToProps = {
+};
+
+export default connect (mapStateToProps,mapDispatchToProps)(MoreInfo)

+ 37 - 0
src/components/userInfo.js

@@ -0,0 +1,37 @@
+import React from "react";
+import Input from "./Admin/Input";
+
+class UserInfo extends React.Component {
+  changeUser = e => {
+    e.preventDefault();
+    const obj = {};
+    this.props.changeUserUserForm.map(el => {
+      return (obj[el.name] = el.value);
+    });
+    this.props.putUser({ data: obj, path: this.props.user._id });
+  };
+  render() {
+    const { changeUserUserForm, changeInputValueUserUserForm } = this.props;
+    return (
+      <div className="user-info">
+        <div className="admin-item user-item">
+          <form className="form-doctors user-form">
+            {changeUserUserForm.map(el => (
+              <Input
+                key={el.id}
+                el={el}
+                changeInputValues={changeInputValueUserUserForm}
+                className={el.className}
+              />
+            ))}
+          </form>
+          <button onClick={this.changeUser} className="btn link admin user-btn">
+            Изменить
+          </button>
+        </div>
+      </div>
+    );
+  }
+}
+
+export default UserInfo;

+ 25 - 0
src/components/userOrders.js

@@ -0,0 +1,25 @@
+import React, { Component } from "react";
+
+class UserOrders extends Component {
+  render() {
+    const { data } = this.props;
+    console.log(data);
+    return (
+      <div className="user-orders">
+        {data.map(el => (
+          //   console.log(el)
+          <div key={el._id} className="user-orders__content">
+            <h4 className="user-orders__heading">Процедура: {el.spec.name}</h4>
+            <p className="user-orders__paragraph">
+              Дата записи: {el.date.split("T")[0]}
+            </p>
+            <p className="user-orders__paragraph"> Время записи: {el.time}</p>
+            <p className="user-orders__paragraph">Доктор: {el.doctor.name}</p>
+          </div>
+        ))}
+      </div>
+    );
+  }
+}
+
+export default UserOrders;

+ 92 - 0
src/containers/auth.js

@@ -0,0 +1,92 @@
+import React, { Component } from "react";
+import { connect } from 'react-redux';
+import { Redirect } from 'react-router-dom';
+
+import { auth, register } from '../actions/auth';
+
+import {SignUpForm} from '../components/auth/signUp';
+import {SignInForm} from '../components/auth/signIn';
+import Loader from '../components/hooks/loader';
+
+class Auth extends Component {
+  state = { auth: true };
+
+  toggleAuth = () => this.setState(prevState => ({ auth: !prevState.auth}));
+
+  render() {
+    const { auth } = this.state;
+    const { user } = this.props
+
+    
+    if(user) 
+    {if(Object.keys(user).length !== 0 && !user.role && !user.doctor) {
+      return <Redirect to="/user" />
+      }
+
+      if(Object.keys(user).length !== 0 && user.role && !user.doctor) {
+        return <Redirect to="/admin" />
+      }
+      
+      if(Object.keys(user).length !== 0 && user.doctor && !user.role) {
+        return <Redirect to="/reviews" />
+      }
+    }
+
+    return (
+      <div className="main">
+        <div className="auth-wrapper">
+        <Loader flag={this.props.isFetching}>
+            <div className="auth">
+              <div className="auth__content">
+                { auth ? (
+                    // <Loader flag={this.props.isFetching}>
+                      <SignInForm error={this.props.errorFromAuth} submitHandler={this.props.auth} />
+                    // {/* </Loader> */}
+                ) : (
+                    // <Loader flag={this.props.isFetching}>
+                      <SignUpForm 
+                        error={this.props.errorFromAuth}
+                        submitHandler={this.props.register}
+                        successRegister={this.props.successRegister}
+                      />
+                    // {/* </Loader> */}
+                )}
+
+                <div className="auth__additional-content">
+                  {auth ? (
+                    <p className="auth__text">
+                    У вас есть акаунт ? {" "}
+                      <span className="auth__toggle-span" onClick={this.toggleAuth}>
+                        Зарегистрироваться
+                      </span>
+                    </p>
+                  ) : (
+                    <p className="auth__text">
+                      У меня есть акаунт{" "}
+                      <span className="auth__toggle-span" onClick={this.toggleAuth}>
+                       Войти
+                      </span>
+                    </p>
+                  )}
+                </div>
+            </div>
+          </div>        
+          </Loader>
+        </div>
+     </div>
+
+    );
+  }
+}
+
+const mapStateToProps = state => ({
+  user: state.auth.user,
+  isFetching: state.auth.isFetching,
+  errorFromAuth: state.auth.error,
+  successRegister: state.auth.successRegister
+})
+
+export default connect(
+  mapStateToProps,
+  { auth,register }
+)(Auth);

+ 89 - 0
src/containers/user.js

@@ -0,0 +1,89 @@
+import React, { Component } from "react";
+import { connect } from "react-redux";
+import { Link } from "react-router-dom";
+import { Switch, Route } from "react-router-dom";
+
+import UserInfo from "../components/userInfo";
+import UserOrders from "../components/userOrders";
+
+import { getUserOrders, getOrders } from "../actions/orders";
+import { changeInputValueUserUserForm } from "../actions/auth";
+import { putUser } from "../actions/user";
+
+class UserContainer extends Component {
+  componentDidMount() {
+    this.props.getOrders({
+      doctors: this.props.doctors,
+      services: this.props.services,
+      users: this.props.users
+    });
+  }
+  // componentDidUpdate(){
+  //     if(this.props.orders.length > 0 &&)
+  //     // console.log('did update', this.props.orders)
+  //      this.props.getUserOrders(this.props.currentUser)
+  // }
+  componentDidUpdate(prevProps) {
+    if (this.props.orders.length > 0)
+      if (prevProps.orders !== this.props.orders)
+        this.props.getUserOrders(this.props.currentUser);
+  }
+
+  render() {
+    const {
+      currentUser,
+      changeUserUserForm,
+      changeInputValueUserUserForm,
+      putUser,
+      userOrdersArray
+    } = this.props;
+    return (
+      <div className="main">
+        <div className="info-wrap">
+          <h2>Добро пожаловать в личный кабинет, {currentUser.firstName}!</h2>
+          <div className="btn-box user-btn-box">
+            <Link to="/user/orders" className="btn link admin user-link">
+              Мои заказы
+            </Link>
+            <Link to="/user/info" className="btn link admin  user-link">
+              Редактировать профиль
+            </Link>
+          </div>
+          <Switch>
+            <Route
+              path="/user/orders"
+              render={() => <UserOrders data={userOrdersArray} />}
+            />
+            <Route
+              path="/user/info"
+              render={() => (
+                <UserInfo
+                  user={currentUser}
+                  changeUserUserForm={changeUserUserForm}
+                  changeInputValueUserUserForm={changeInputValueUserUserForm}
+                  putUser={putUser}
+                />
+              )}
+            />
+          </Switch>
+        </div>
+      </div>
+    );
+  }
+}
+
+const mapStateToProps = state => {
+  return {
+    currentUser: state.auth.user,
+    changeUserUserForm: state.auth.changeUserForm,
+    orders: state.orders.orders,
+    users: state.user.users,
+    services: state.services.services,
+    doctors: state.app.doctors,
+    userOrdersArray: state.orders.userOrdersArray
+  };
+};
+export default connect(
+  mapStateToProps,
+  { changeInputValueUserUserForm, putUser, getOrders, getUserOrders }
+)(UserContainer);

+ 0 - 67
src/db.json

@@ -1,67 +0,0 @@
-{
-  "doctors": [
-    {
-      "age":30,
-      "id":1,
-      "lastName":"Sidorov",
-      "name":"Ivan",
-      "photo":"some photo here",
-      "skillsDescription":"Lorem ipsum dolor sit amet, consectetur adipisi...",
-      "schedule": {
-        "07": {
-          "09": {
-            "08:00": true,
-            "09:00": true,
-            "10:00": true,
-            "11:00": true,
-            "12:00": true,
-            "13:00": true,
-            "14:00": true,
-            "15:00": true,
-            "16:00": true,
-            "17:00": true
-          },
-          "10": {
-            "08:00": true,
-            "09:00": true,
-            "10:00": true,
-            "11:00": true,
-            "12:00": true,
-            "13:00": true,
-            "14:00": true,
-            "15:00": true,
-            "16:00": true,
-            "17:00": true
-          },
-          "11": {
-            "08:00": true,
-            "09:00": true,
-            "10:00": true,
-            "11:00": true,
-            "12:00": true,
-            "13:00": true,
-            "14:00": true,
-            "15:00": true,
-            "16:00": true,
-            "17:00": true
-          },
-          "12": {
-            "08:00": true,
-            "09:00": true,
-            "10:00": true,
-            "11:00": true,
-            "12:00": true,
-            "13:00": true,
-            "14:00": true,
-            "15:00": true,
-            "16:00": true,
-            "17:00": true
-          },
-          "13": false,
-          "14": false
-        }
-      }
-
-    }
-  ]
-}

+ 23 - 14
src/index.js

@@ -1,20 +1,29 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './App'
-import * as serviceWorker from './serviceWorker';
+import React from "react";
+import ReactDOM from "react-dom";
+import App from "./App";
+import * as serviceWorker from "./serviceWorker";
 
-import {BrowserRouter} from "react-router-dom";
-import {store} from './store'
-import {Provider} from "react-redux";
+import { BrowserRouter } from "react-router-dom";
+import { store } from "./store";
+import { Provider } from "react-redux";
+
+import "./style/normalize.css";
+import "./style/all.scss";
+import "./style/style.css";
+import "./style/select.scss";
+import "./style/calendar.scss";
+import "./style/auth.scss";
+import "./style/modal.scss";
+import "./style/checkBoxWindow.scss";
+import "./style/user.scss";
 
 ReactDOM.render(
-    <Provider store={store}>
-        <BrowserRouter>
-            <App/>
-        </BrowserRouter>
-    </Provider>,
-    document.getElementById('root')
+  <Provider store={store}>
+    <BrowserRouter>
+      <App />
+    </BrowserRouter>
+  </Provider>,
+  document.getElementById("root")
 );
 
-
 serviceWorker.unregister();

+ 21 - 0
src/privateRouter.js

@@ -0,0 +1,21 @@
+import React from "react";
+import { Route, Redirect } from "react-router-dom";
+
+export const PrivateRoute = ({ component: Component, protectedRoute, ...rest }) => {
+	return (
+	<Route
+		{...rest}
+		render={props => {
+			if (protectedRoute) {
+				const token = localStorage.getItem("userId");
+				if (!token) {
+					return <Redirect to="/auth" />;
+				}
+
+				return <Component {...props} />;
+			}
+			return <Component {...props} />;
+		}}
+	/>
+
+)}

+ 105 - 0
src/reducers/appointment.js

@@ -0,0 +1,105 @@
+import * as types from '../actionsTypes/actionsTypes'
+
+const defaultState = {
+    appointment: {
+        sheduleId: null,
+        time: null,
+        doctorId: null,
+        specId: null,
+        comment: ''
+    },
+    timeArray:[]
+};
+
+export const appointmentReducer = (state = defaultState, action) => {
+    switch(action.type){
+
+        case types.CHANGE_APPOINTMENT_SHEDULE : {
+            const timeArray =[];
+            const doctor = action.payload.doctors.find(el => el._id === state.appointment.doctorId);
+            const shedule = doctor.shedule.find(el => el.data === action.payload.data);
+            const duration = action.payload.services.find(el => el._id === state.appointment.specId).duration;
+            for (let index in shedule) {
+                let check = true;
+                for (let x=0;x < duration; x++){
+                    if (shedule[`${+index.split(':')[0]+x < 10 ? '0' +(+index.split(':')[0] + x) + ':00' : +index.split(':')[0]+ x + ':00'}`] !== true){
+                        check = false
+                    }
+                }
+                if (check) timeArray.push({[`${index}`]:shedule[`${index}`]});
+            }
+            return {
+                ...state,
+                appointment:{
+                    ...state.appointment,
+                    sheduleId:shedule._id,
+                    time:null
+                },
+                timeArray:timeArray
+            };
+        }
+
+        case types.CHANGE_APPOINTMENT_DOCTOR : {
+            return {
+                ...state,
+                appointment:{
+                    ...state.appointment,
+                    doctorId:action.payload,
+                    specId:null,
+                    time:null,
+                    comment:null,
+                    sheduleId:null,
+                }
+            };
+        }
+
+        case types.CHANGE_APPOINTMENT_TIME : {
+            return {
+                ...state,
+                appointment:{
+                    ...state.appointment,
+                    time:action.payload
+                }
+            };
+        }
+
+        case types.CHANGE_APPOINTMENT_SPEC : {
+            return {
+                ...state,
+                appointment:{
+                    ...state.appointment,
+                    specId:action.payload.services.find(el => el.name === action.payload.data)._id,
+                    sheduleId:null,
+                    time:null
+                }
+            };
+        }
+
+        case types.CHANGE_APPOINTMENT_COMMENT : {
+            return {
+                ...state,
+                appointment:{
+                    ...state.appointment,
+                    comment:action.payload
+                }
+            };
+        }
+
+        case types.CLEAR_APPOINTMENT : {
+            return {
+                appointment: {
+                    sheduleId: null,
+                    time: null,
+                    doctorId: null,
+                    specId: null,
+                    comment: ''
+                },
+                timeArray:[]
+            };
+        }
+
+
+        default:
+            return state
+    }
+};

+ 0 - 0
src/reducers/auth.js


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini