Sorry, page not found...
+ + ++
From 6e417770962f5d206f2000f1812d237d5d702aeb Mon Sep 17 00:00:00 2001
From: Paul Gamble Date: {checkinDate} Effort: {effort} Mood: {mood} {selfEval} {notes} Habit name: {habit} Start date: {startDate} Smart habits: Duration (months): {length} Countdown to finish: Happy Tracking! Please enter a number for length Please enter required fields Hello {this.props.providerData[0].displayName} Ability to change data about habit? Button to unlink google account Account: {this.state.user} Current Habit: {this.state.habitTracked.habit}
+
+ No habits currently being tracked. Do you w ant to to delete all of the data
+ and all of your hard work, forever?
+
+
+ Please enter required fields
in check-in.js (#53)
* Update check-in.js
extra closing > removed from
* Update habit-tracker-feature.md
* Update habit-tracker-feature.md
* Update habit-tracker-feature.md
* Update habit-tracker-feature.md
* Create habit-tracker-wip
* Update and rename habit-tracker-wip to habit-tracker-wip.md
* Update habit-tracker-wip.md
* Update habit-tracker-wip.md
* Update habit-tracker-wip.md
* Update habit-tracker-wip.md
* Update habit-tracker-wip.md
* Update habit-tracker-bug.md
* Update habit-tracker-bug.md
* Update habit-tracker-feature.md
* Update habit-tracker-wip.md
* Backend Work for Checkin Submission (#67)
* Update Schema to include Array of checkins
* Add API method to complete a checkin for a given habit
* Add functionality to checkin form
- Basically borrowed all the concepts from the New Habit form, albeit with less validation
- Temporarily added Habit field for manual habit ID entry
- Confirmed that it can update habits on the backend
* CSS clean up (#73)
* deleted based on tutorial
* css consulidated to index.css/ parent level
* new habit css cleaned up
* forms using same styling
* making form styles match
* console errors cleaned up
* bug, login not working see if this fixed
* added dashboard.css to index.css
* default page adjusted and styled
* NewHabit Version 2.0 (#71)
* NewHabit Version 2.0
* New Habit 2.1
* Feature/user settings menu setup (#74)
* π - adding 404 page not found component
Ugly but functional 404 page not found #49
* deleted based on tutorial
* css consulidated to index.css/ parent level
* new habit css cleaned up
* forms using same styling
* making form styles match
* console errors cleaned up
* bug, login not working see if this fixed
* added dashboard.css to index.css
* default page adjusted and styled
* header state
* log out and other buttons moved to header-logged-in
* header google info not showing
* fixed merge conflict
* removed provider (google) name
* commented-out unlink button
* removed heading for 'Connected Social Accounts'
* created footer component; playing with header and layout structure
* testing profile picture in header
* added footer component and HeaderLoggedIn container
* fixed up header format; copied SocialProfileList.css into index.css
* added back logout and unlink buttons for testing
* Fixed syntax error handleUnlinkedProvider; resolve compile errors on className
* π - fixed as per code review
Changed to h2; removed "404 error" from App.js. #72
* β¨ - added 'Enter New Habit' to header for testing
* π - fixed up initial login screen to show header
* π - moved footer to the bottom
* β¨ - Moved profile picture; fixed up headers
This was a combination of a branch @SaraSweetie was working on earlier; and some other bugs... primary purpose was to move the user's profile picture into the top right corner. The hamburger button is currently not working but all the buttons have been place in the header for testing purposes #40
* New Habit 2.2 added close button (#75)
* GET Request (#81)
* New Habit 2.2 added close button
* GET request to retrieve habit info
* New habit edge (#82)
* New Habit 2.2 added close button
* GET request to retrieve habit info
* removed route for newhabit
* hamburger component created
* state not passing to hamburger menu button
* slide out menu positioned and styled
* Feature/widget calendar (#83)
* β¨ - added react-calendar-heatmap
Added a progress component with now holds the first widget, react-calendar-heatmap. #78
* π - fixed up the display copying bootstrap ref
* β - added react-tooltip
* β - added ReactTooltip to client
* π - tweaked footer css; remove bootstrap
* π - made the calendar heatmap a sep component
* π - fixed spacing on NotFound component (#84)
* Added additional supporting backend methods (#85)
* Countdown timer (#86)
* Added additional supporting backend methods
* Call logged in users first habit instead of hardcoded habit
* Add Current Habit info to dashboard
* Countdown for current habit in dashboard
* pushing progress
* not working
* paired programming props passed down -- working
* New User Functionality (#87)
* New Habit 2.2 added close button
* GET request to retrieve habit info
* removed route for newhabit
* New User Functionality
* clean up unused code
* button styling
* duplicate button deleted
merge conflict from hamburger-menu PR. Duplicate buttons.
* Check in (#91)
* New Habit 2.2 added close button
* GET request to retrieve habit info
* removed route for newhabit
* New User Functionality
* Updated Logic on Dashboard
* Fixed New Habit Entry edge case
* Check in - Responsive Update (#93)
* New Habit 2.2 added close button
* GET request to retrieve habit info
* removed route for newhabit
* New User Functionality
* Updated Logic on Dashboard
* Fixed New Habit Entry edge case
* made check in and newhabit forms responsive
* Header sidebar page added, Login Circle fixed (#95)
* layout circle appearing on log in
* text added to login and footer, footer centered
* user settings page shell created
* User settings linked
* user login info centered
* font awesome library updated, close icon added to logout
* hamburger menu hover color added
* unlink button still needs uncommented and moved
* Check in (#96)
* New Habit 2.2 added close button
* GET request to retrieve habit info
* removed route for newhabit
* New User Functionality
* Updated Logic on Dashboard
* Fixed New Habit Entry edge case
* made check in and newhabit forms responsive
* Update to keep checkins to once per day
* Map habit checkins to calendar values (#97)
* Current habit - fix react error (#98)
* switching branches
* unlink button uncommented, styled
* Feature/cal tool tip (#101)
* β¨ - adding tooltip popup; null values now
Using demo reference https://codesandbox.io/s/73mk9wlyx and npm react-calendar-heatmap doc: https://www.npmjs.com/package/react-calendar-heatmap / https://github.com/okize/react-calendar-heatmap #78
* β¨ - tooltip displays effort in pop-up
used reverse lookup function for effort value object: https://stackoverflow.com/questions/9907419/how-to-get-a-key-in-a-javascript-object-by-its-value #78
* π¨ - time added but unable to substring
#101
* Fix formatting on tooltips (#103)
* Make checkins appear immediately (#104)
* Css mobile (#105)
* hamburger button moved for mobile
* header layout for mobile
* sidebar adjusted for mobile because header height adjusted
* circle removed from mobile
* width made responsive % not fixed px value
* Added new CheckiDtail component (#106)
* About Text added, Small CSS changes (#107)
* typo fix, minor wording changes
* about text added, slideout width increased
* log-in page and new-habit module screenshots
* sidebar height adjusted, overflow scrolled added
* heat map font size smaller
* images added to about slideout
* link hover styles added
* screenshots
* Added delete habit button to user settings page (#108)
* Fix/calendar doesnt include today (#109)
* Start calendar 1 day earlier
* Remove unnecessary toDate() call
* Fix minor erros and warnings (#110)
---
.github/ISSUE_TEMPLATE/habit-tracker-bug.md | 3 +-
.gitignore | 30 +-
.travis.yml | 4 +
README.md | 4 +
{habit-tracker => client}/.gitignore | 2 +
{habit-tracker => client}/README.md | 0
{habit-tracker => client}/package.json | 11 +-
{habit-tracker => client}/public/favicon.ico | Bin
{habit-tracker => client}/public/index.html | 4 +-
.../public/manifest.json | 2 +-
{habit-tracker => client}/src/App.test.js | 2 +-
client/src/components/CalHM.js | 63 +
client/src/components/CheckInSubmission.js | 15 +
client/src/components/CheckinDetail.js | 18 +
client/src/components/CurrentHabit.js | 26 +
client/src/components/Dashboard.js | 238 ++
client/src/components/HabitSubmission.js | 15 +
client/src/components/Login.js | 51 +
client/src/components/NewHabit.js | 137 +
client/src/components/NotFound.js | 19 +
client/src/components/Progress.js | 15 +
client/src/components/SocialButtonList.js | 75 +
client/src/components/SocialProfileList.js | 58 +
client/src/components/UserSettings.js | 89 +
client/src/components/check-in.js | 145 +
client/src/components/footer.js | 15 +
client/src/components/header.js | 12 +
client/src/containers/App.js | 31 +
client/src/containers/HeaderLoggedIn.js | 53 +
client/src/containers/Layout.js | 29 +
client/src/containers/withAuthentication.js | 40 +
client/src/firebase/auth.js | 9 +
client/src/firebase/firebase.js | 11 +
client/src/firebase/index.js | 4 +
client/src/images/bg.svg | 630 +++
.../src/images/btn_google_dark_normal_ios.svg | 50 +
client/src/images/checkin-button.png | Bin 0 -> 2207 bytes
client/src/images/gecko.png | Bin 0 -> 32222 bytes
client/src/images/heat-map-sample.png | Bin 0 -> 9913 bytes
client/src/images/user-icon.svg | 114 +
client/src/index.css | 523 +++
{habit-tracker => client}/src/index.js | 2 +-
.../src/serviceWorker.js | 0
habit-tracker/src/App.css | 33 -
habit-tracker/src/App.js | 16 -
habit-tracker/src/index.css | 14 -
habit-tracker/src/logo.svg | 7 -
server/index.js => index.js | 24 +-
{server/Models => models}/Habit.js | 32 +-
server/package.json => package.json | 7 +-
routes/api/habits.js | 86 +
screenshots/checkin-button.png | Bin 0 -> 2207 bytes
screenshots/checkin-module.png | Bin 0 -> 85826 bytes
screenshots/log-in | Bin 0 -> 184466 bytes
screenshots/new-habit-button.png | Bin 0 -> 2809 bytes
screenshots/new-habit-module.png | Bin 0 -> 85380 bytes
server/config/keys.js | 3 -
server/package-lock.json | 3472 -----------------
server/routes/api/habits.js | 30 -
59 files changed, 2677 insertions(+), 3596 deletions(-)
create mode 100644 .travis.yml
rename {habit-tracker => client}/.gitignore (95%)
rename {habit-tracker => client}/README.md (100%)
rename {habit-tracker => client}/package.json (59%)
rename {habit-tracker => client}/public/favicon.ico (100%)
rename {habit-tracker => client}/public/index.html (94%)
rename {habit-tracker => client}/public/manifest.json (99%)
rename {habit-tracker => client}/src/App.test.js (98%)
create mode 100644 client/src/components/CalHM.js
create mode 100644 client/src/components/CheckInSubmission.js
create mode 100644 client/src/components/CheckinDetail.js
create mode 100644 client/src/components/CurrentHabit.js
create mode 100644 client/src/components/Dashboard.js
create mode 100644 client/src/components/HabitSubmission.js
create mode 100644 client/src/components/Login.js
create mode 100644 client/src/components/NewHabit.js
create mode 100644 client/src/components/NotFound.js
create mode 100644 client/src/components/Progress.js
create mode 100644 client/src/components/SocialButtonList.js
create mode 100644 client/src/components/SocialProfileList.js
create mode 100644 client/src/components/UserSettings.js
create mode 100644 client/src/components/check-in.js
create mode 100644 client/src/components/footer.js
create mode 100644 client/src/components/header.js
create mode 100644 client/src/containers/App.js
create mode 100644 client/src/containers/HeaderLoggedIn.js
create mode 100644 client/src/containers/Layout.js
create mode 100644 client/src/containers/withAuthentication.js
create mode 100644 client/src/firebase/auth.js
create mode 100644 client/src/firebase/firebase.js
create mode 100644 client/src/firebase/index.js
create mode 100644 client/src/images/bg.svg
create mode 100644 client/src/images/btn_google_dark_normal_ios.svg
create mode 100644 client/src/images/checkin-button.png
create mode 100644 client/src/images/gecko.png
create mode 100644 client/src/images/heat-map-sample.png
create mode 100644 client/src/images/user-icon.svg
create mode 100644 client/src/index.css
rename {habit-tracker => client}/src/index.js (92%)
rename {habit-tracker => client}/src/serviceWorker.js (100%)
delete mode 100644 habit-tracker/src/App.css
delete mode 100644 habit-tracker/src/App.js
delete mode 100644 habit-tracker/src/index.css
delete mode 100644 habit-tracker/src/logo.svg
rename server/index.js => index.js (51%)
rename {server/Models => models}/Habit.js (57%)
rename server/package.json => package.json (62%)
create mode 100644 routes/api/habits.js
create mode 100644 screenshots/checkin-button.png
create mode 100644 screenshots/checkin-module.png
create mode 100644 screenshots/log-in
create mode 100644 screenshots/new-habit-button.png
create mode 100644 screenshots/new-habit-module.png
delete mode 100644 server/config/keys.js
delete mode 100644 server/package-lock.json
delete mode 100644 server/routes/api/habits.js
diff --git a/.github/ISSUE_TEMPLATE/habit-tracker-bug.md b/.github/ISSUE_TEMPLATE/habit-tracker-bug.md
index 6a1fa4f..4a26a50 100644
--- a/.github/ISSUE_TEMPLATE/habit-tracker-bug.md
+++ b/.github/ISSUE_TEMPLATE/habit-tracker-bug.md
@@ -23,5 +23,4 @@ If applicable, add screenshots to help explain your problem.
## Additional context
-Add any other context about the problem here.
-
+Add any other context about the problem her
diff --git a/.gitignore b/.gitignore
index c5d9255..5303967 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,17 @@
### Node ###
+
+package-lock.json
+yarn.lock
+
+# misc
+.DS_Store
+.env
+.env.test
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
# Logs
logs
*.log
@@ -32,6 +45,7 @@ bower_components
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
+/build
# Dependency directories
node_modules/
@@ -55,10 +69,6 @@ typings/
# Yarn Integrity file
.yarn-integrity
-# dotenv environment variables file
-.env
-.env.test
-
# parcel-bundler cache (https://parceljs.org/)
.cache
@@ -78,4 +88,14 @@ typings/
.fusebox/
# DynamoDB Local files
-.dynamodb/
\ No newline at end of file
+.dynamodb/
+
+#---- copied from CRA; client directory ----
+# dependencies
+
+/.pnp
+.pnp.js
+
+
+
+
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..eb6f204
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - "10"
+script: npm test
\ No newline at end of file
diff --git a/README.md b/README.md
index 34806c4..524793a 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,6 @@
# v8-geckos-team-07
Add-project-description-here | Voyage-8 | https://chingu.io/
+
+# Development Build
+
+https://habit-tracker-gecko-develop.herokuapp.com/
\ No newline at end of file
diff --git a/habit-tracker/.gitignore b/client/.gitignore
similarity index 95%
rename from habit-tracker/.gitignore
rename to client/.gitignore
index 680c904..75bf455 100644
--- a/habit-tracker/.gitignore
+++ b/client/.gitignore
@@ -13,6 +13,7 @@
# misc
.DS_Store
+.env
.env.local
.env.development.local
.env.test.local
@@ -21,4 +22,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+yarn.lock
package-lock.json
diff --git a/habit-tracker/README.md b/client/README.md
similarity index 100%
rename from habit-tracker/README.md
rename to client/README.md
diff --git a/habit-tracker/package.json b/client/package.json
similarity index 59%
rename from habit-tracker/package.json
rename to client/package.json
index adc1e9a..e309f2b 100644
--- a/habit-tracker/package.json
+++ b/client/package.json
@@ -3,9 +3,17 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "axios": "^0.18.0",
+ "firebase": "^5.9.1",
+ "moment": "^2.24.0",
"react": "^16.8.4",
+ "react-countdown-now": "^2.1.0",
+ "react-calendar-heatmap": "^1.8.0",
+ "react-delay": "^0.1.0",
"react-dom": "^16.8.4",
- "react-scripts": "2.1.8"
+ "react-router-dom": "^5.0.0",
+ "react-scripts": "2.1.8",
+ "react-tooltip": "^3.10.0"
},
"scripts": {
"start": "react-scripts start",
@@ -13,6 +21,7 @@
"test": "react-scripts test",
"eject": "react-scripts eject"
},
+ "proxy": "http://localhost:5000",
"eslintConfig": {
"extends": "react-app"
},
diff --git a/habit-tracker/public/favicon.ico b/client/public/favicon.ico
similarity index 100%
rename from habit-tracker/public/favicon.ico
rename to client/public/favicon.ico
diff --git a/habit-tracker/public/index.html b/client/public/index.html
similarity index 94%
rename from habit-tracker/public/index.html
rename to client/public/index.html
index 75980d5..1a707e9 100644
--- a/habit-tracker/public/index.html
+++ b/client/public/index.html
@@ -2,7 +2,6 @@
-
+
- Submission Complete
+
+ Check-in detail:
+ {checkinDate && Self Evaulation:
}
+ {selfEval && Notes:
}
+ {selfEval && No current habits!
)
+ } else {
+ // startDate is a string (for display); endDate is a date object (for countdown)
+ const startDate = moment(new Date(date)).format("MMMM Do YYYY");
+ const endDate = moment(new Date(date)).add(length, 'months').toDate();
+
+ return (
+ Current habit info:
+ {smart.map(item =>
+ Daily Dashboard
+ {newHabitButton}
+ {checkInButton}
+ Submission Complete
+
+ A simple way to measure whether you did a habit.
+
+
+
+ Habit Tracker
+ Sorry, page not found...
+
+
+
+ User Settings
+ Account Info
+ Please confirm!
+ Are you really, really, really sure?
+ Habit Tracker
+
Loading...
+*Jc>9UuE4JM7XjYRa>Yy|Df_?ENH71+_XOpP8<7x!k38FR z+_pL_=B(mUtgKiu9+13lL@qERg{hHv^&GC)MQaGqSc8g5_w9T5LLN~hQppW`t?m=` zVWn3BiMETUEXMECu;Hg>wX;e;p{A(l~Xky9XrYc zTdnj2+{r!J3T&G De4lw>fEHXkH^@$ovOl{~w+HkL~>>t3!L@$a8oDQ^`~ zk}#?&Zp_H?AH|Xo7V-6J67Ad_Mck6spB01U=JonJLlaAB$Zm3EQjJ&kSI>dXLq=?= zdZ!yP$>U+Lt62VGj8<5?=ZU=Hfb@a&a)lMM;o-u#h|rB 8JrLSK=^ zx5Y>AW<-$Ic1?n+Wj?3uR$g%zv!_DFvCiO3WY*=ZuNnGv&NIyA=VR&1&tX{JfV)y} zYtPTwFvY>Auu-t;a+|x3TVDIqjP!LNnrF+^IoP+zjOQv~u!)bU=|$3amo;0KaM9QE z;idib^xpMT8L?#Qpc+BTeN0J)9W);m^Q7Jrz4q90z;``)t*__Mf&Q8m$0bjc_aqE6 zr;ZbAKIVm{QAO&d*Dedb;xs33Zt_J7`eHEL6Z^EWRAGv=eq#9)x>s4_B@rO2 >yDyls3pRj0J} JJZSRpml2}fZUJ?dR1bMq1DrgdnUE!>?_oZX0{Hd;aD>s1F z1W~T-_$PP#Dy7<{Z7j=dONIlO;X519PX~-<+Lv78J>w^X;b&wqV_n2!E@V=Jf`q%4 zDK}Qc7! $W2zR7VlPJ8Xx%!WW%OC7&PVvQKK93GUyR()X9#<>>5}(A>09ro zi(qy@cU^ +XQQd-mzKU}H<6#DPwHelHBNPukjHx$N {(#jq;IDY~PwOb+xA zj!e1-)acpHpY>`-$_@p*M=Ix#)Bi({yI2w`X#3uwfBBTgR~ou{O|}5hQOQ8k(E;Zw zBlW6L3~m|y)?>!MAIZNod`fJL;hy`U#y*`HmLQ;T^{gPU<|zIp1nYpKrpB@Vc`DN? znk+^yk8D<3Tp^Uvl^6R?czE)SV5=n}BLy@)#>tAOCL{T2>_*0mB%zs6Sv_t)yi?GG zcm8znE$QHIi)N?fx3|QWci!|{R@o%H&e*(0S2c@M8iGPbjh;Ow+D#{AnL>EqQt2|_ zH>b<2nWs7>AH%2+3UcD#!9;p?w>jeYn&Cs3Gs1Qyf6`8>FQ=%X E@Y!DZL8ezCA%j-gsYB~h z6-#9+$azM`$-xPhfm;(q7;&+4tx$Iv9YuLt94woQ?Fh~rmsDLwR~iGg=EXP)yUL`# zql)b+UUk~u=S) 8B!&+s62Qja|pc@=%e;pHOY; zIdrlN?-%MhWv8aYy_-H(&b1O#u+5TQrn~Mgd4qZY_gp;GB BHpZp9zvFu2kDW z>hYf5Dqw^$;jQM-DNvfMuFhbVP(_-h<^}dS^vLc9*<4O@ZEZS{O^6TQf93 z@~Lq@BFo~lI(Am*&1tss?^BP5?ZO4~**g}#98Rz+F!FYKjJzintYa+Kged-WN8_{T z$E1`JCd>k{GACtz#mN#+`0dxE6kE$^O+CJi26h@J?=hI_iAQoD14g6?+B7YG@>;X) zA)MtdN?h+92L&BH7S1_DCvQkEPsCLv-V(hlc#J;q4WjFA7Lt%KApXd`0)~P!81mTr zPEBCOmw!OtZQkIgl=etBSv88>{$2V|g-C$>eu~nLppDmty5%;`0_eR88W@XV4SKws z9FD0bl?1M {v*C0NjUQ4AfGRO~f0%F8 zsd2)-y>QKh!g*{O&MIZUsox6}gw7%f)}qB}C%2b=n#)P+CD<+AOv;TJ`Q5kQB$VA& zbB3YYp{>&A?CE3pw`<#~(@YtUUenhjSk&?<4mI2*8BC1^qn(jyH;pzRd`dYsRyO^` z2H9JGl*p$wX)Tyy%8$ms-*_iIfsqaRFNzO@2b0heqSIO&fPlyW%wWyHY|zszPJX2v za9A~hLQ40d9+Jucdc$&${I#|Ao*LX$No#?v2y{8)gg6n-s{-fHX{8+B91tnVee=ch zDgH71(S_-6?`MFtaTr}sD+7_QLQBM~^Ya|v(}zkpJfxo{feY`*ZVib9Q)C~`Y}v^z z=ZvI1w7>swz0q+cyd+YqE#SB=#`b! `Yy?&$=1UFPm0HV;;Q z=Z-M1PlW-CZ8WJw0#bTPF^>{6cHb;9U>-}QHp;{vi5OYrz`lZUH|*10x1yW_kTjm+ z#$@ F>V{G+jrLJ&>IVO54uHD%6H>`e7MlU1mv zsTT4?M?we5`0eg8_*&6ec$~Fpi4oh0HiiLWIMFsehO|iPPUQBmyu$uHxIkDL3p9b4 z4MgN(R;}NSXCRo!CZyCu3yfk$EJXcE$Wzmp5@C^@Okz=&Z)g*b3zk#bwAbi!Gxi}5 zyA;vGr`Q33#G;%q%oM<){jI>S*z{a`Q)sdn?_#;63t93_Rp+e2t!3rj%PB++T3k%B z-y^ul;?Al=Q*&OkNckf~seo%p7N1y=T=>-JOmy&(z4bah5=0%HQ>H?U@B?-e* jBC{#ZJ1#_ctTh{9z|` J$L0x@{biTp1~w(&^2a w1+-biRAWYwhd;&>jwCn64y^YNNquTW9!G;YU1&*I7U8FZ z_s)Acg!wG3>QfU+Q|1;M AVN`IAmXB38r0Km-`c!%Xh>bz*!D zN %*gNa%ABRftHhv(FXJ{7bs@_!2D6}xcS(4x`aKjkQ}r1=Q&EvmfJ ztdya)qpzNr_7(9fzK8BkZbsB(NB}DT?J|^JDXq_REg9bCM-l>=aZ`3r_og^a!HSH| zdb%+uQrGb8Lj~TS3;b={D*_0=dSs&tu$6g=^7{>6>Rq3-t`0>Y_gPDz;gv|(hZI*& zojfvB#^R6N4zm5uLb01)X&9XXI0v0^Kf<~ _dHK9+;tXmQfn#`mD^= zx+qTbbuKgt*1a N9l%1^bkdTGD9WRwl2Z{h3&h(}mQ%%Yc4co={qlrZ z{T%*i@vdql2qrC61Bc>_v}}MDE(CuQzS(CzVh&1fY+wllpubE>-+FjM{8dgkAS+DB z&Z ie-h zz}aVBBpq<$76BS&Bw+s>KZN&BH|~#Kxy}4##6HiD6IAEd4{lurBjj*Ah--@nFWWh? z_lk55zsRE$d j2641pm6U z^x*33$oq4>&8IJeti7c~FpfCs*`#hhE&ayhYMHwu`D^gGU}7r+u}1omPSBBr;fw`w zKJ+OCK6#_bTpG!gBy?WX;ZKkAJd)O$qe21ecqJFLI49Z>#}1KM$OUJzT}YQc=1l3p z&x72s2nBMlvHm!UtIW(xnfzoUzi+EjmKaYTW->_T7)F5EvIoqdg_1lLW@4M-b#i{C zj5dDnQ9h_u+f_|aW0#73$Sw!Wany#~-0M;oSCZdEkoW}gbkDVrOw)2*wy+kS$%I7U zW3~R+fMm(tT`wP{>uOG lB8OGBJuH@k zgFp!C-IccP=M?Lj5BOW!fAvb<-l5~edVdn-x+sN#AznjWLlJ6feJ|-XDKrRp;hL}c z0Y^Fw!thGtJBiL!zEF_Cb-x;fRC2Iv*eDs4U%sS})P8aC-RMWI8PFRiZu6v9k&p>| zn ^zd+m>%MZ(EvR7WJ@%owKi(#;25GS9Jw zC)G7Wf@5t9u>>)@e4GzVu5sf@9aUzCBoBtgZyd%)C4ut#v2n3*a$RI<7& XzLY4p1|E<-qh98mytq1M$>fn>wnn1R~r16ag#G*^Ij#mfqml&n 3RwK%lHhQ!3u&)qD^* !Yb@kx@xX0bI+#in^1BP72PUTufv|64ztd$i=m{vH zx!?ANue8D+mWc|RjcUCO8Pjq$MdIxPzf&*_=ueLfHc3cJl-wcEgXiP18E&a{`SeIB z^5_g?V0%>iu@FP5 AP{=P%6n1uw1z|=Jqgx*#XJz}J+(?kUm%O&q9 z$v}LH(V;4IY3$ac v$8FEA@@v|B# <`;Pj zc{bn~K&UkB1_fQ{FR~GNRJ>k;nrGyNrrz}jyB~C`s}=nm!)EE(&QCtfGXZThkpsDU zEKhvJ1A9iOl`EF~_whzJ=hgbsduv^4U|GcW?1kHDJHr*ZnbXx2Bf1sScT)4Montal zpkBZGpEbNPe5i};5YX?bo?Xc$-s$v$2#$JMcg8a%VY)!-yy$QKxkz`_o@vejw#5CL z+Xd;C_>z7_ Q_3MBSLHjg?zhqP$Jw@ZXA6m2e+| z>HV7H2OX6@j?O}$e%uMG_?1K?+C$DPcg>OUHWGm>wcQ?X@d}q0-g$VD==b(|#pqKR zS7_cm+P#w-SM`Cu{)g2_O$&iE1?~->3>Tj3=SU|Z4ovD@B-g}r{MSXS+?I!(XigaI zF|Ztu>%BE>A2(Y?RODki#iR38LaGwDsvt>swNNCZ*nbSBIVagm7o7cYPx02BRJlN* zGekCT+XnWVN|A_@I3!ZOmKs*1DPk4BA;h8ajoaS`9JW7XW=!JwHFNNHPdzvG;gsYa z>6~<1(6XPS5G`h(vs4(9XsFYeaRMlT1`bP^$0E10!4sG9U>MJBu}~!oU)RTs;Em!E zO~H^F7c(tIRZ5VTkfh8A+;#BAFw8kcsgUC5K>lg8mR`2_Ee=+KMWlecvkXJYrDfr> z(1${hHv2CvrlS;8VAe}+Qw^F%F|-Py(^kZr+5qm`g}NiMXduqzuDK!3cl#&45>{IG zZAU!2kWk6UvfsoyLLE}K_}9EqdK_>ome3*Nn7*UUMwviBi~Y21Ho46rWeK&+^cR(7 z6S#WZ!i$0iFV=SvEjF}})}q2(Xf=)aN$Hoct8b3eT{%8W*5MZ1UD`ed?_i^abafLz z`w!S1#MLOK!#RCpAYRMl&u3DZ#s*EyFoGl6GkeP^HC P8 z70OY~T20z|FZ|ENB=l=u=( 722%>zWa-?l0 zvqk`Go$y*iA6!H`=?Vj1#1#x9*zEwaj6dA?*5UyF?!sQ|=t%8zAo^iLimyzkfOkNo zz!l9DK2lx67`~%1Bgyc9J7S^8Pqs}|{c_EeYzmDNetT{t8dE%D=M0?<)=dZs2WKt% zDgxt81xa;nZdy2_KrY7JeE%I27yNEiZ!1O8(OIP98K0f)#Thn$A*$pPF-+CV=;pgD zkeOOc9~(VE=)GDu`2B~i7~eK&6ptDmR>&McTF{&EvUiw%=LJoS-mReBq-^eU0u=-W zElJ-8>ltC?Gt~~JIshy33aP4)kz&5{qX4)3o6?be9TEj4#cyx;spUWWR-vNdMiCRc z@^ckMErmC|k)5MwlV?HgMVHl!G?YtgD$GJS`Gukm*KCZy^;NuaRn+*JKg^Pj`R|&_ zRS;oip>z}$ejirjh`C=M7;|mKTglB6r$af1J~pn)<1!(b*c5BJ->(hru+;zDG0L<6 z{@kZ2@96Mwx(Rsvz&kyR-$VLX1Ya6ar7oq}xR~<{(Ks2a76pC%7IVu}A0{WvMnLE6 z)M|;`@!m*|20z$P%Dk@9Q3z?(=fTl=DO`(S<4o-1%_>hox9P6OJTef^xig{8Rap=1 zJ>Klj@>gjWOovgt@)1cL-f&PJQMoeq0fhmEt<&Cj8JdrI^`b##_} _YJg`2bPe!Exmi9Ot<;ep{uaeHdum?RY1}9q9B(ggAem8_U=;o+ zUT&JNT<)Gf@oNTorZ&+wtAw!}E)i#!?Cs`Uee9nB)iT^QMY+{A+rf+iaU>B%Ldm_U zf{mr=gz*LcYJxoY#_()=1P_H`OlwNPt2JpOSFyMX3-F@c-W2cA%-iLLht^osV0Fn= zChkcDdkZ@lZrD*b{?OQEmjhU{PmKPi(m?#?x#+E?rLu%a;(ZxYm0}53)|>l_;BIC; zoxo%KJY r|FVH@K!*$?TI?&-h~4uaBuo? zX~G=2A~5NDIvO}Je7k^>g67I3IX*9`9eHcvgbAz`AixG$tKnsjyq% OSDpi4Mg4>A|z9dJ5K2*Le5 z`vnMRitS@+SktS{j&3pS>EZ&U912QhKzJ3LS{bO0OGa*g>e>?8!sf@EAd1nj+5rdL zZwVpLA|0gn3R$2i0;9EK(!wBL4cRy`yK+uG0h aoAB^qR<+nx+rb1$Dq z1(nDU*Ofb``$#?AtP9`1-F_Vvx~c3J1QD3 opN z)VxKj3z~du*OYpig3p{LKQ~dBC6wuuAXR~wnaR2;yWo!FG3iDbp`1KUclJr^jVS@) z7uPv;7M0%T>)~A-V#{rZ7p#W@c|qUqV~gY@k}x~YmCwF86qvyQ%SgxGj}M*y7IO0n la{935=^1`{E4&^En2+Y<&w>MKzSe>O + + diff --git a/client/src/index.css b/client/src/index.css new file mode 100644 index 0000000..da1d1f6 --- /dev/null +++ b/client/src/index.css @@ -0,0 +1,523 @@ +/* Google Fonts */ +/* font-family: 'Life Savers', cursive; */ +@import url('https://fonts.googleapis.com/css?family=Life+Savers'); +@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.1/css/all.min.css'); + +body { + margin: 0; + padding: 0; + background: url('./images/bg.svg') repeat; + background-size: 60px; + font-size: 1em; + font-family: Arial, Helvetica, sans-serif; + line-height: 1.2; + color: #203f49; +} + +/* Home page header */ +header { + background-color: #203f49; + width: 94%; + max-height: 150px; + padding: 15px 3% 10px 3%; + color: #ffffff; +} + +header h1 { + text-align: center; + font-size: 2.3em; + font-family: 'Life Savers', cursive; + line-height: 1.5; + letter-spacing: 1px; +} + +/* Header for when user logged in */ +.headerLogin { + display: flex; + justify-content: space-between; + align-items: center; +} +.headerLogin h1 { + text-align: left; + font-size: 2.3em; +} +.headerLogin .user img, .container__profile--photo { + width: 25px; + height: 20px; + padding: 2%; + display: block; +} + +#userDisplay { + display: flex; + flex-direction: column; + justify-content: center; + align-items: stretch; +} + +/* Font Styles */ +h2 { + font-size: 1.5em; + font-family: 'Life Savers', cursive; + line-height: 1.3; + color: #203f49; +} +h2::after { + content:''; + display: block; + border-bottom: 2px solid #203f49; + max-width: 60%; + padding-bottom: 2px; + margin-bottom: 10px; +} +h3 { + font-size: 1.2em; + font-family: Arial, Helvetica, sans-serif; + line-height: 1.3; + color: #203f49; +} + +a h3:hover { + color: #3367d6; +} + +p { + margin-bottom: 10px; + line-height: 1.3; +} + +/* CSS Styling */ +main { + padding:4% 8%; + max-width: 1200px; + margin: 0 auto; + border: 2px solid #203f49; + border-radius: 20px; + background-color: #ffffff; + margin: 30px 10%; +} +footer { + padding-top: 1rem; + text-align: center; + width: 100%; +} +a { + color: #203f49; + text-decoration: underline; +} +a:hover { + color: #3367d6; +} +button { + /* removes default button styles */ + border: none; + background-color: none; +} + +/* Hamburger Menu and Off Canvas sidebar */ +#sidebar { + width: 400px; + padding: 30px; + margin: 0; + border: 2px solid #203f49; + background-color: #ffffff; + color:#000; + height: calc(100vh - 237px); /*height of header + 30px padding x2 */ + position: absolute; + top: 173px; /*height of header */ + left: 64px; /* 30px padding x2 + 4px border x2 */ + z-index: 1; + overflow: hidden; + -webkit-transform: translate(-120%, 0); + transform: translate(-120%, 0); + transition: transform 0.3s ease; + filter: drop-shadow(5px 4px 4px rgba(33, 33, 33, 0.3) ); + overflow: scroll; +} +#sidebar.open { + -webkit-transform: translate(-15%, 0); + transform: translate(-15%,0); +} +#hamburger-menu { + background-color: #203f49; + color: #fff; + width: 40px; + height: 40px; +} +#hamburger-menu:hover { + color: #fcbf74; +} + +/* Login page Circle */ +.circle { + text-align: center; + background-color:#fff; + padding:10%; + margin:2% auto; + border-radius: 50%; + width: 275px; + height: 275px; + border: 2px solid #203f49; + display: flex; + flex-direction: column; + justify-content: space-around; + } +.circle h2::after { + border-bottom: none; +} +.circle ol { + text-align: left; +} + + +/*Google Buttons for Log-in */ +@import url('https://fonts.googleapis.com/css?family=Roboto:500'); + +.btn__social { + width: 191px; + height: 40px; + margin: 0; + padding: 0; +} +.btn--google { + background-color:#4285F4; + color:#ffffff; + border-radius: 4px; + font-family: 'Roboto', sans-serif; + font-weight: 500; + font-size: 14px; + line-height: 2.8; + margin:0 auto; +} +.btn--google img { + height: 40px; + margin:0 5px 0 0; + padding:0; + float: left; +} +.btn--google:hover { + background-color:#3367d6; +} + +/* Logout Button */ +.btn__logout { + width: 100%; + height: 20px; + margin: 5px auto; + font-size: 0.8rem; + text-transform: uppercase; + border-radius: 2px; + font-family: Arial, Helvetica, sans-serif; + font-weight: 300; + margin-bottom: 0px; + background-color: transparent; + color: #ffffff; +} + +.btn__logout:hover { + cursor: pointer; + background-color: #fcbf74; + color: #203f49; +} + +/* Form Styles */ +.newHabit, .daily-check-in { + color: #203f49; + border: solid 2px; + border-radius: 20px; + width: 50%; + margin: 30px auto; + background-color: white; +} +form { + display: grid; + width: 70%; + margin: auto; + text-align: left; +} +form label:first-of-type { + margin-top: 0; +} +label, fieldset legend { + margin: 20px 0px 5px 0px; + font-weight: 600; + font-family: 'Life Savers', cursive; +} +fieldset label { + font-size: 1em; + font-family: Arial, Helvetica, sans-serif; + font-weight: normal; + vertical-align: middle; +} +fieldset p { + font-size: 0.8em; +} +fieldset input { + vertical-align: middle; +} +input, form button { + height: 15px; + background-color: #d4d4d6; + border: none; + padding: 10px; +} +select { + background-color: #d4d4d6; + height: 35px; +} +textarea { + background-color: #d4d4d6; + height: 50px; +} +fieldset { + border:0; + margin: 0; + padding: 0; + font-size: .8rem; +} + +.buttons { + display: flex; + justify-content: space-between; +} +.button { + width: 110px; + margin-top: 20px; + height: 40px; + border-radius: 5px; + font-family: Arial, Helvetica, sans-serif; + font-weight: 600; + margin-bottom: 20px; +} +.button:hover { + cursor: pointer; + background-color: #fcbf74; +} + + +.submission { + position: fixed; + top: 40%; + left: 30%; + background-color: #203f49; + border: 1px solid #203f49; + border-radius: 5%; + color: white; + padding: 20px; + text-align: center; + font-size: .8rem; +} + +.subdisplay-block { + display: block; +} + +.subdisplay-none { + display: none; +} + +.okbutton { + width: 50px; + height: 40px; +} + +.okbutton:hover { + cursor: pointer; +} + +.modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.6); + overflow-y: scroll; +} + +.display-block { + display: block; +} + +.display-none { + display: none; +} + +.newHabit { + position: fixed; + text-align: center; + font-family: 'Life Savers', cursive; + color: #203f49; + border: solid 2px; + border-radius: 5%; + width: 50%; + height: auto; + top: 50%; + left: 50%; + background-color: white; + transform: translate(-50%, -50%); +} + +.error { + color: red; + font-weight: 600; + font-size: .8rem; + margin: 0; +} + +.header-button-menu { + background: #72B0EC; + border-radius: 1000px; + box-shadow: 0px 1px 5px 0px rgba(0,0,0,0.5); + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; +} + +.confirm { + position: fixed; + text-align: center; + font-family: 'Life Savers', cursive; + color: #203f49; + border: solid 2px; + border-radius: 5%; + width: 50%; + height: auto; + top: 50%; + left: 50%; + background-color: white; + transform: translate(-50%, -50%); +} + +.confirm h2::after { + max-width: 50%; + transform: translateX(50%); +} + +/* Modal Media Queries */ + +@media only screen and (max-width: 600px) { + + .newHabit, .daily-check-in { + width: 80%; + } +} + +/* Heat Map calendar */ +.react-calendar-heatmap text { + font-size: 7px; +} + +/* ------------------------------- copied from SocialProfileList.css -------------------------------*/ + +.btn__profiles--list { + display: flex; + direction: column; + justify-content: center; +} + +/* .container__profile { + display: flex; + flex-direction: row; + align-items: right; + margin: 10px; +} */ + +.container__profile--photo { + border-radius: 50%; + width: 75px; + height: 75px; + margin: 0 auto; +} + +.container__profile p { + width:100%; + margin: 0; + padding: 0; +} +.container__profile--btn { + width: 100%; + height: 20px; + margin: 5px auto; + font-size: 0.8rem; + border-radius: 2px; + font-family: Arial, Helvetica, sans-serif; + font-weight: 300; + margin-bottom: 0px; + background-color: transparent; + color: #ffffff; +} + +.container__profile--btn:hover { + background-color: red; + color: white; +} + +/* --------------------------------------------------------------------------------------------- */ + +.widget { + border-width: thin; + border-style: solid; + display: flex; + justify-content: space-between; + align-items: center; +} + +.habitButton { + padding: 10px; + margin-left: 5px; + margin-bottom: 10px; + font-family: 'Life Savers', cursive; + background-color: #203f49; + color: #ffffff; +} +.habitButton:hover { + cursor: pointer; + box-shadow: 1px 3px #888888; + font-weight: 600; +} + +/* ---------- Header and Log-in Circle adjustments for small screen ---------- */ + +@media screen and (max-width:500px) { + .headerLogin { + position: relative; + align-items: flex-start; + width: 94%; + max-height: 150px; + padding: 5px 3% 10px 3%; + } + .headerLogin h1 { + font-size: 1.5em; + } + #hamburger-menu { + position: absolute; + left: 10px; + bottom: 10px; + } + .container__profile--photo { + width: 35px; + height: 35px; + } + #sidebar { + max-width: 40%; + width: calc(100% - 30px); + padding: 30px; + margin-left: 30px; + position: absolute; + top: 123px; /*height of header */ + left: 0; + } + main { + margin: 15px; + } + .circle { + border-radius: 0; + border-radius: 20px; + width: 70%; + height: auto; + margin: 3% 10%; + padding: 5%; + } +} \ No newline at end of file diff --git a/habit-tracker/src/index.js b/client/src/index.js similarity index 92% rename from habit-tracker/src/index.js rename to client/src/index.js index 87d1be5..12b09b9 100644 --- a/habit-tracker/src/index.js +++ b/client/src/index.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; -import App from './App'; +import App from './containers/App'; import * as serviceWorker from './serviceWorker'; ReactDOM.render( , document.getElementById('root')); diff --git a/habit-tracker/src/serviceWorker.js b/client/src/serviceWorker.js similarity index 100% rename from habit-tracker/src/serviceWorker.js rename to client/src/serviceWorker.js diff --git a/habit-tracker/src/App.css b/habit-tracker/src/App.css deleted file mode 100644 index b41d297..0000000 --- a/habit-tracker/src/App.css +++ /dev/null @@ -1,33 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - animation: App-logo-spin infinite 20s linear; - height: 40vmin; - pointer-events: none; -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/habit-tracker/src/App.js b/habit-tracker/src/App.js deleted file mode 100644 index 6548ce2..0000000 --- a/habit-tracker/src/App.js +++ /dev/null @@ -1,16 +0,0 @@ -import React, { Component } from 'react'; -import './App.css'; - -class App extends Component { - render() { - return ( - -- ); - } -} - -export default App; diff --git a/habit-tracker/src/index.css b/habit-tracker/src/index.css deleted file mode 100644 index cee5f34..0000000 --- a/habit-tracker/src/index.css +++ /dev/null @@ -1,14 +0,0 @@ -body { - margin: 0; - padding: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; -} diff --git a/habit-tracker/src/logo.svg b/habit-tracker/src/logo.svg deleted file mode 100644 index 6b60c10..0000000 --- a/habit-tracker/src/logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/server/index.js b/index.js similarity index 51% rename from server/index.js rename to index.js index d7efec2..61824a1 100644 --- a/server/index.js +++ b/index.js @@ -1,25 +1,39 @@ const express = require('express') const mongoose = require('mongoose') const bodyParser = require('body-parser') - const habits = require('./routes/api/habits') - const app = express(); +var path = require('path'); +// Serve static files from the React app +app.use(express.static(path.join(__dirname, 'client/build'))); + // Bodyparser Middleware app.use(bodyParser.json()); -// DB Config -const db = require('./config/keys').mongoURI; +// DB Config from .env file +require('dotenv').config() +const db = process.env.MONGO_URI //Connect to Mongo -mongoose.connect(db) +mongoose.connect(db, { useNewUrlParser: true }) .then(() => console.log('DB connected...')) .catch(err => console.log(err)); // Use Routes app.use('/api/habits', habits); + +// Point to client's index +app.get('*', function (req, res) { + res.sendFile(path.join(__dirname, '/client/build/index.html'), function (err) { + if (err) { + res.status(500).send(err) + } + }) +}) + + const port = process.env.PORT || 5000; app.listen(port, () => console.log('Server started on port ' + port)); \ No newline at end of file diff --git a/server/Models/Habit.js b/models/Habit.js similarity index 57% rename from server/Models/Habit.js rename to models/Habit.js index 84512fa..7dfb8b0 100644 --- a/server/Models/Habit.js +++ b/models/Habit.js @@ -37,7 +37,37 @@ const HabitSchema = new Schema({ reward: { type: String, required: false - } + }, + // Checkins - each checkin in the app pushes to this array + checkins: [ + { + checkinDate: { + type: String, + required: true + }, + // Effort - killed it, did good, tried, didn't even try + effort: { + type: String, + require: true + + }, + // Mood - I'm doing great, this is hard, why even bother? + mood: { + type: String, + required: true + }, + // Self evaulation - killed it, did good, tried, slept instead + selfEval: { + type: String, + required: false + }, + // Notes - for later in-depth review + notes: { + type: String, + required: false + } + } + ] }); module.exports = Habit = mongoose.model('habit', HabitSchema) \ No newline at end of file diff --git a/server/package.json b/package.json similarity index 62% rename from server/package.json rename to package.json index f199c6a..c58a7cf 100644 --- a/server/package.json +++ b/package.json @@ -4,14 +4,17 @@ "description": "server side of the habit tracker being built with react", "main": "index.js", "scripts": { - "start": "node index.js", - "server": "nodemon index.js" + "start": "concurrently \"node index.js\" \"cd client && npm start\"", + "heroku-postbuild": "cd client && npm install && npm run build", + "server": "nodemon index.js", + "postinstall": "cd client && npm install" }, "author": "patrick connolly", "license": "MIT", "dependencies": { "body-parser": "^1.18.3", "concurrently": "^4.1.0", + "dotenv": "^7.0.0", "express": "^4.16.4", "mongoose": "^5.4.19" }, diff --git a/routes/api/habits.js b/routes/api/habits.js new file mode 100644 index 0000000..16ce75d --- /dev/null +++ b/routes/api/habits.js @@ -0,0 +1,86 @@ +const express = require('express') +const router = express.Router(); + +// Habit Model +const Habit = require('../../models/Habit.js'); + +//@route POST api/items +//@desc Create a habit +//@access Public +router.post('/newhabit', (req, res) => { + const newHabit = new Habit({ + name: req.body.name, + habit: req.body.habit, + smart: req.body.smart, + length: req.body.length, + intervals: req.body.intervals, + reward: req.body.reward + }); + newHabit.save().then(habit => res.json(habit)); +}); + +//@route POST api/checkin +//@desc Perform a checkin for one of your habits +//@access Public +router.post('/checkin', (req, res) => { + const checkin = { + effort: req.body.effort, + mood: req.body.mood, + selfEval: req.body.selfEval, + notes: req.body.notes, + checkinDate: req.body.date + } + // Just to get this off the ground - request should include habit id + // Probably better use combination of user id + habit name + Habit.findOneAndUpdate({_id: req.body.habit}, {$push: {checkins: checkin}},{new: true}) + .then(habit => res.json(habit)); +}); + +// Delete a habit by id +//@route DELETE api/habit +//@desc Delete a given habit +//@access Public +router.delete('/habit/:id', (req, res) => { + const id = req.params.id + + Habit.findByIdAndDelete(id) + .then(habit => { + res.json({ + confimration: 'success', + data: habit + }) + }) + .catch(err => { + res.json({ + confimration: 'fail', + message: 'Habit not found!' + }) + }) + +}); + +// Get first habit for a given user +//@route GET api/first-habit +//@desc Get the first habit that exists for the given user +//@access Public +router.get('/first-habit/:user', (req, res) => { + const user = req.params.user + + Habit.findOne({name: user}) + .then(habit => { + res.json({ + confirmation: 'success', + data: habit + }) + }) + .catch(err => { + res.json({ + confirmation: 'fail', + message: 'No habits found for user' + }) + }) + +}); + + +module.exports = router; \ No newline at end of file diff --git a/screenshots/checkin-button.png b/screenshots/checkin-button.png new file mode 100644 index 0000000000000000000000000000000000000000..ec31f1dc6162147059946b0e5e954a1b10e8994a GIT binary patch literal 2207 zcmYLL2{aUH8y>g(ififq{dJRNn%p8WLlF}u48}f_2`R+bhM2|7wG-K8xj%)XWiI`R zEJIO)vM-T!C^N}0GH6nkGEv_hx6b|F^DXcDe(!mn^FHUi=X_~c2P;`=MQI2GB5RF7 zpBCRK;(cbvHt~rckWzv`By5RzSDLH69g;u_*7outdHZUI2b0C`5Qq^foa{vi@})t& zef^0c#;_&UQy7%!V+?cAvq#vI&3yxim`JLxQ=|i)5E(=;^nsyFq>aLnVt`;@nin)Y z_+m&XGTa#UH!f1_Z>8Zd=-(x@AY+*679rHt9t$-mQGKC$+WJ}qo#P1T2}5lieZ+A+ zoug1)gw6>#LJyA6*FxwZ5e7(I9q12(nMgy8s6Kwk(`d^dWa7ve7C@tsk#KleSeSO$ zF>MmnAFg9)Xb4B>!gY1E#1&eh5g|0MaIKKggIf^aG0?uD1S*kCBa%X(TbN$nBs$F) z27_;rz<;oa+k^kppE&qOA>R- Habit Tracker - -eh_&W5U$7g!nB4b1UwTq3$)%H}}(9~TA+{o?x8_{|CCd2G6i)!2QCs!b3O z&8OBp9bVi7Uq&OJ@~`zTEcfLYp)d>{aCNjQ=54 pCcEokKyhuntDkca5Y(fo=}uAU zS}2TdawVH5;IiBO{9O60n1pbGr;A-xVd{I~B8D2hIoFn0KTtu((o36DnueLoyvKbL zrF18-BD8V9j<9k?oaPzfO6=7xk4JNE@i|kxS0XMGh 7zVaSIGBie8Z!($!X*PIoWKjbzr})AUZrC*odLP!`$kba%VjC};LS zdwBQK43A4F?b0Mf$Ct96)#NO;r>4aduVvDRtxFekt7!4`->?)9QVN5;#$|IGIP }I{=m3*eL}0MBA=`TJXN@OhKz=z^#_@#MJW2BO$kz2d|fP%r{iC?Mq%p7mYk_ z8wT&27dX9vH6x*!_i<=XKb!~o*+RB>7T#K;P4NMf!U;Nlx9P8t55_rPr_A^c+EWfV zYg5Uck`~*y u8=_E%u$5QTfW2`P^F~5NB1D_R~AC#m&+1DXJkS`Sv z^#*o&Dp|r09f=JcW#^c)>Ue5r=+R%cNj~3Y1l`f 6lJaunyVxsO%=aq zwW+J<+26X#7%*XFObNQEx1UGKO0hcgVxY$MmakHVWI8?~q>c3nMQQ&lJ$QJzeD|TH z;5+MV)#(>y{*Z}>hC-Rl-3wW^vTa!xQ>OMfDoGz;ShS`~7)0LC?hZ_LHE4lKEo37K zh;52{(|;NN$v-beYi(tqGl`6;IJ |cPbk1pz$Di xXmk7%H2PY7&$qV==o47))=`YLq<_V#`U2ace{^~ zIvxs;MveZirmu~zsSDc&ZnpmJ*uPnL(}H;HwB8?l)z&w&)R(RKj;4|H@Cc=@LVKLj zr^;6kvPj<=9~FYpz+T!~Tf9eV_WqI`ljWz~KP+l=-n}KF%4aC-;@pwWWf)-1^vXJ~ z3>wRXp`ykwN~v}bx8HX|UN4!??u2_;yH8|B4D|n3fBAXZVS7XM9uxAU8l$n&E4y?? zaI>ai!!UY9XLVI2@45Yx$*)+Mxtm(<(O!A|MptJ(VQ2dVjD}36@N2Nw_%juCLB`Z6 zP5Hb6=R0c0JASn~Ft`@pHy%6R{m$J5>$W$s0eMtwC+Tfgj-0KxWiR(C@zHDKY;f_$ zzlMU`>hN*y0;W>w-~-*>a+Jqh@X0t|gFznUYNNKS&C81Ohbuo1QILwt?=BC>_nC1I z8YJ!SsOylLsK{cbchv4dnUi!Jofi3Wb04Ccf}92;BKl_ABt%MkKRbi3X0a#!KUP16 sD~$#b>~T6EH@&W^%m+#BII1#A0(#^mUU7EY=+?i&+QI={X?7vuFTc`FbpQYW literal 0 HcmV?d00001 diff --git a/screenshots/checkin-module.png b/screenshots/checkin-module.png new file mode 100644 index 0000000000000000000000000000000000000000..b9ad8620dcee0f425d8e3f90be47c5cc92234adc GIT binary patch literal 85826 zcmce+cT|&G&^L+&6%h~+P!Pn>q=a5WQvvBkdI=!C_Yyitk*0tmAYG6qC6OMwQiV`d zN~B9DQ9_X}q1`9w@tpU&-(B}x_m7*kvR3jud(WPkJ$uS;cC40$BH3m7%S1#(WXekN z+C)U>&_qP%uV1 m)lEcng~mZnPD|dw%iY<+pNL4Qry>mo)#;_}!KPljPo=_q zR{OqN_%>Gy-I*VcSXj^8C%Ju9cjbG2xYNC^a2nGyl@-KE3JUU-;Iq4p%=uMSytMCL zZ?coT#s#h??(H{s*e!)f?DeP5_GbqQoeK+RG`Z6+PjluY)j}-jT(i*zNi2^x#oceY zH?@c$&KmGf+#t}ky9`ao!%tj04DH2uSR3A-*s4IycrOyMp7j(IOG_r+KTm|bpm?Y6 zT-Yb_BfQsUBvr^oBZc$CXYaDAitBY}P-&!ArU Nt* 8Bwo>62w+^_+e@Etk9B zdg$DV8>;VG;!fU0QW5oQ*Ew$pW!0BHUAamkx2p7pS%T+gmEeME5M0=-eQ&t)vA~;+ zqb%qxal0@QqRU9<*{dJjc^?*uvvfPXbomN$Fu9)iWMeBlUs1y7C8I>ftpPggCs7GY zM(N$8^z+%x(6*AwSJzrYuUaF&e4-|H`0OE=ZLcaLD|$tc(KFEXf$m59$sS?{84D`` zkVk=h^_c}2C+I}U=t@y)iliuS|BH^)-NFmwLVRF|));L(cCkA;!QtCx(2+GgKd AxmMV$zIfzn3n@WzQSU%j^!?POwdPF{_k@Nsv}se@s+nN%;am- z7!o41zMTs?LmFeDd|{lK@#iESho1|rk~|J0lV_&+8P-)|SFVt?oj^49@HNpPaqLCU zo=Jbz_0797+o3o1`W#7 8+#75cafeOOP(;;o@Q5O**QCZ03i-#lKPP@y zy~2v8R`2m~f4!_`C?9rmE9mymzKA!;_LNVb&6&uw3*EmsM>0p77w=Bd8D9K_=gq_F z{iys~FRS0{ej={kPfXywv9!Vv|KZtd$G|BDSOh-LH!IeOh;)iPp_6nk%&IziW}POk zr#3hfb?YFx sC|3o9Cpr~IOjdZ`3U!` zWK{2Y#BmPHq@_9MXu}F$UwRql^N9NE1>eUluP@&`+jE!E{yg@*f;&x3gvqxvP==Oo zY}bk89$mk8mFm9S^%zKg#C6b83>hX8$r7S;hboqpSy_n-bhq>4S?e3x;V(gxNzzIp zo7|q4C8D7ZAW4BrVqc=0@5$s{S5eT@0*_qEehSGmv%f_DY*1e3^UWF}(**dv`qwny z@72&sN1G|Q<(Yn0^}c%Ul~i}9w*YBB$<~MVN_ie)YK!=HmgQH<-jiFA{WO|=-}o+M zg+-(DhB#?`7*6PF;s*&o^43e{&)ho7ei}Cuw>^f 37vQ207sDYs^fyMJXj?q&x3X#TIA?ax^?| zS9aEBdK*)d;+^E3I- Uujia6 zw87ugX>qq# KEEXBTfTRx~#^=QLLz3j4PnQtg8` z6&Lw>VW`joE}elAnUNd10zPE5FDB$$6oXaYe12-5QzLK8s-wOFv^X}%U%^}-;qCylT6j&5)Db!&=U7lS!aj $Wzl6)!x-v;^H%yDGM@dh<+@veM9C7xz!D;Tk~h%7(|s=mQxkH zfNSS_Dix~R+|@H0)ezD5fjc%VJB;$OcMDry5D-dtO7D49pPtKZul_URedasI_BoPl z>X|Zi-7Veuw=`vp51R^im9q=iigWT>%~~{$o?n1l6bYzXC3I^%Bc(s0)?;tfSWx51 z@pHxmtLqM{32A$^E}0EDWkeWH7@sk|Ur}L *)73&P+t zxO~{FZR1}lXk=mtErS@rw7A zB6=SF5&@*!9lP(=uWXUy??!*NJg CfJdu5uBcy zml~DolZs$xP}9h24)Me-AoO?j)AbL^nGCs2E}GC8iy5|63RKU1eK|Q*Q#g*F rK^<) Ju?T x!5y|DdBU&}E?TPOf z1=s~Jua*p>zTT)Dtz4fEnpc@`#BlWRJ#EW){rtUVi6$#sH~X6A&8#)C;Nk6=8@obr zwo^F{QeJEQsA^$bn?Z=QiG^t3?gs09ZRnTB1w$+DzQlq25_kLqH;H o?4cFBYw raGU>ka8aBQT%tN _7 zFy;3zN()~W-cSwYtKs4S2i5bq8g+P9EUKpN9bWsXqfXhPr0Z=Lg^M%g-bgu2aVc{) za53GfePt3<*jZXozOdyuxXdkUa?-qreJ;Z3G%*G#pKeG%YP?(94M^P4D^w{YE|g{{ zaxIzuIAPelF #PL8kz>*-FiPkU-JMu40G@Puq)RZy-Z |R;y-xOl8 zBON3cCCS7O73Sa^a;6Wz1s(2Zf`^SKcq5@m@6RWgeSO4Ob=nlKh?#Fg&~n^xN@E$h zffHifTynqZXq{v7=7b|c(hT7Sb9MXv>WfFw@SCkEvRMW?w+qwF0o*J4J*%%KVe9?K zVV|_Xy{?x2K*TzB_EyNdh1+u$8!TOlHi;s)3=S>uJ `?(B0N+tvA>B@Txx$s|Yo->|c{x>rUr3&b1&E z5Q;P9A!WyPo7vM%OCMrB^vD^>b*#tBmV}nzzi(IW=u8!3JG^9)W!&~H@r83vAJNe) zMl3A%>tevummj@*&B;mB{PuiUD$ySK&zp*Qs6lgWIcvKIoR3estAsK}ZW5JjpJ%ou zA5-e;@tK|`i!HKq}c {zGsxR zS$`4{UEp-kHS{)ASA$r&x$s(8yII=s`nk9Rqlt*5Wc}PNtekATnJsPX99*SA>rHJS zW(R9&kb#Igzq-4ejlF|XfTxX4fQGJBfRmMkHAq&5S;`Lr5OA^awqW*iad!2B_(_9K z=|X_tgvWd!=F=hGPST)zgaw%m)wP)A+&pcVMR-NQRszEO%wiI}0;2rFA_6?jg8Twv zeEcGO{Gwof0SLc1L{NbF&j$po=4ovU(UyPkXD#5LG|1lD+a1Ek2ZO c#R81$i4UD^CY^ZwEJ5W&%YEOE({HX%N8asR%ZH z4*$}1_4=bHKx2G_H+%xT`~;zXOY7qPmxKQ?($B*Ee+;y?`a90u$J6 rE`OKs@>cK#B>tnj|Ltfm zU4M5QK5ZK>Hy=+c8wFp0O%@O{K?4vi2R|EULwN^)buU1N(jWnTVe$XIGx{IzB!mg- za)-!y+E{qo$OB(#5U|e@V15xWzp$==2t-&2Lij5T;phK7RNc+m!Pfu(K2#JUAPx}% zY~w#e0VA`v@V5AW9c*m{v32uwu>j