diff --git a/backupDatabase.sh b/backupDatabase.sh
index 409403e..b5d1372 100755
--- a/backupDatabase.sh
+++ b/backupDatabase.sh
@@ -1,12 +1,15 @@
#!/bin/bash
+# Take all variables in .env and turn them into local variables for this script
+source ~/.env
+
BACKUPDIR="/home/mab/databaseBackupSolidScribe"
mkdir -p $BACKUPDIR
cd $BACKUPDIR
NOW=$(date +"%Y-%m-%d_%H-%M")
-ssh mab@solidscribe.com -p 13328 "mysqldump --all-databases --single-transaction --user root -pRootPass1234!" > "backup-$NOW.sql"
+ssh mab@solidscribe.com -p 13328 "mysqldump --all-databases --single-transaction --user root -p$PROD_DB_PASS" > "backup-$NOW.sql"
gzip "backup-$NOW.sql"
# cp "backup-$NOW.sql" "/mnt/Windows Data/DatabaseBackups/backup-$NOW.sql"
@@ -25,4 +28,4 @@ echo "Database Backup Complete on $NOW"
# Crontab setup
##
-# 0 2 * * * /bin/bash /home/mab/ss/backupDatabase.sh 1> /home/mab/databaseBackupLog.txt
\ No newline at end of file
+# 0 2 * * * /bin/bash /home/mab/ss/backupDatabase.sh 1> /home/mab/databaseBackupLog.txt
diff --git a/client/src/assets/semantic-helper.css b/client/src/assets/semantic-helper.css
index 3f090fe..3bf4456 100644
--- a/client/src/assets/semantic-helper.css
+++ b/client/src/assets/semantic-helper.css
@@ -146,6 +146,9 @@ body {
.ui.dividing.header {
border-bottom-color: var(--dark_border_color);
}
+.ui.dividing.header > .sub.header {
+ color: var(--dark_border_color);
+}
.ui.icon.input > i.icon {
color: var(--text_color);
}
@@ -180,10 +183,15 @@ i.green.icon.icon.icon.icon, i.green.icon.icon.icon.icon.icon {
.button {
box-shadow: 2px 2px 4px -2px rgba(40, 40, 40, 0.89) !important;
transition: all 0.9s ease;
+ position: relative;
}
.button:hover {
- box-shadow: 3px 2px 5px -2px rgba(40, 40, 40, 0.95) !important;
+ box-shadow: 3px 2px 3px -2px rgba(40, 40, 40, 0.95) !important;
}
+.button:active {
+ transform: translateY(1px);
+}
+
.ui.green.buttons, .ui.green.button, .ui.green.button:hover {
background-color: var(--main-accent);
}
diff --git a/client/src/components/GlobalSiteMenu.vue b/client/src/components/GlobalSiteMenu.vue
index c6eb872..d57657f 100644
--- a/client/src/components/GlobalSiteMenu.vue
+++ b/client/src/components/GlobalSiteMenu.vue
@@ -15,7 +15,7 @@
box-sizing: border-box;
display: block;
position: fixed;
- z-index: 111;
+ z-index: 900;
top: 0;
left: 0;
bottom: 0;
@@ -66,7 +66,7 @@
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.7);
- z-index: 100;
+ z-index: 899;
cursor: pointer;
}
.top-menu-bar {
@@ -526,8 +526,11 @@
location.reload(true)
},
getVersionIcon(){
+ if(!this.version){
+ return 'radiation alternate'
+ }
const icons = ['cat','crow','dog','dove','dragon','fish','frog','hippo','horse','kiwi bird','otter','spider', 'smile', 'robot', 'hat wizard', 'microchip', 'atom', 'grin tongue squint', 'radiation', 'ghost', 'dna', 'burn', 'brain', 'moon', 'torii gate']
- const index = ( parseInt(this.version.replace(/\./g,'')) % (icons.length))
+ const index = ( parseInt(String(this.version).replace(/\./g,'')) % (icons.length))
return icons[index]
}
diff --git a/client/src/components/ModalComponent.vue b/client/src/components/ModalComponent.vue
new file mode 100644
index 0000000..6197576
--- /dev/null
+++ b/client/src/components/ModalComponent.vue
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/components/SearchInput.vue b/client/src/components/SearchInput.vue
index a81b852..dd8ba5c 100644
--- a/client/src/components/SearchInput.vue
+++ b/client/src/components/SearchInput.vue
@@ -35,7 +35,6 @@
-
diff --git a/client/src/pages/CycletrackingPage.vue b/client/src/pages/CycletrackingPage.vue
deleted file mode 100644
index d8f78b6..0000000
--- a/client/src/pages/CycletrackingPage.vue
+++ /dev/null
@@ -1,1430 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ dateCode.split('.').shift() }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Modified
-
-
- Saving
-
-
- Saved
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{{calendar.monthName}}, {{calendar.year}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
- Period in Progress
-
-
-
- 1
-
-
-
-
- Amount of cervical mucus
-
-
-
- 1
-
-
-
-
-
-
-
- Had sex with contraception
-
-
-
- 1
-
-
-
-
-
-
-
- Had sex without contraception
-
-
-
- 1
-
-
- No Data entered
-
-
-
-
-
-
-
-
-
-
- Additional Notes
-
-
-
-
- Cervical mucus may not be a useful metric with an IUD or other forms of similar birth control.
-
-
- Follicular phase
- Luteal phase
-
-
- Ovulation is detected by sustained temperate elevation.
- Ovulation can only be determined in hindsight, as progesterone is what makes the temperatures rise, and progesterone is only produced in abundance post-ovulation.
-
-
- Some people may find that their temperature drops the day before or the day their period arrives. This is a very helpful sign in knowing that your period is on it’s way!
-
-
- About halfway through your menstrual cycle, your hormones tell one of your ovaries to release a mature egg — this is called ovulation. Most people don’t feel it when they ovulate, but some ovulation symptoms are bloating, spotting, or a little pain in your lower belly that you may only feel on one side.
-
-
- If you do get pregnant, your body needs the lining — that’s why your period stops during pregnancy. Your period comes back when you’re not pregnant anymore.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Create new Metric to track
-
-
-
-
-
-
-
-
- {{ mapFormTerm(key) }}
-
-
-
-
-
-
-
- {{ mapFormTerm(option) }}
-
-
-
-
-
-
-
-
-
-
- Save it!
-
-
- Save it!
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ userFields[fieldId]?.label }}
-
-
-
- {{ userFields[fieldId]?.customOptions }}
-
-
- {{ userFields[fieldId]?.type }}
-
-
-
-
-
-
-
-
-
-
- {{ userFields[fieldId]?.label }}
-
-
- {{ userFields[fieldId]?.type }}
-
-
-
-
-
-
- {{ defaultFields[fieldId]?.label }}
-
-
- {{ defaultFields[fieldId]?.type }}
-
-
-
-
-
-
-
-
-
-
-
- Data Management Options
-
-
-
-
-
You can backup your metric data for safe keeping or to restore later. This data is not encrypted when you download it.
-
-
- Download Backup
-
-
-
-
-
-
You can restore data from a past backup here. Paste the data from the file into the text area below and click import.
-
-
-
-
-
-
- Import Backup
-
-
-
-
-
This will delete all metric data. It will not delete your personal backups.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/client/src/pages/HomePage.vue b/client/src/pages/HomePage.vue
index 9224557..30847eb 100644
--- a/client/src/pages/HomePage.vue
+++ b/client/src/pages/HomePage.vue
@@ -12,7 +12,12 @@
animation: fadeorama 16s ease infinite;
height: 350px;
- text-shadow: 1px 1px 2px black;
+ text-shadow:
+ 1px 1px 1px rgba(69,69,69,0.1),
+ -1px -1px 1px rgba(69,69,69,0.1),
+ -1px 1px 1px rgba(69,69,69,0.1),
+ 1px -1px 1px rgba(69,69,69,0.1)
+ ;
}
.shine {
position: absolute;
@@ -492,6 +497,8 @@
Solid Scribe was created by Max Gialanella
Check out my Resume
+ OR
+ Check out my Programming Blog
I was tired of all my data being owned by big companies, having it farmed out for marketing, and leaving the contents of my life exposed to corporations.
diff --git a/client/src/pages/NotesPage.vue b/client/src/pages/NotesPage.vue
index 28945da..8d79d09 100644
--- a/client/src/pages/NotesPage.vue
+++ b/client/src/pages/NotesPage.vue
@@ -11,6 +11,12 @@
+
+
+
+ Metric Track
+
+
@@ -110,7 +116,7 @@
- Hide Menu
+ Hide List
@@ -154,7 +160,8 @@
-
+
diff --git a/client/src/router/index.js b/client/src/router/index.js
index a35b480..7f93db0 100644
--- a/client/src/router/index.js
+++ b/client/src/router/index.js
@@ -120,7 +120,7 @@ export default new Router({
path: '/metrictrack',
name: 'Metric Tracking',
meta: {title:'Metric Tracking'},
- component: () => import(/* webpackChunkName: "CycletrackingPage" */ '@/pages/CycletrackingPage')
+ component: () => import(/* webpackChunkName: "MetrictrackingPage" */ '@/pages/MetrictrackingPage')
},
]
})
diff --git a/client/src/stores/mainStore.js b/client/src/stores/mainStore.js
index baf8fa6..434e8ae 100644
--- a/client/src/stores/mainStore.js
+++ b/client/src/stores/mainStore.js
@@ -10,7 +10,7 @@ export default new Vuex.Store({
nightMode: false,
isUserOnMobile: false,
fetchTotalsTimeout: null,
- userTotals: null,
+ userTotals: null, // {} // setting this to object breaks reactivity
activeSessions: 0,
},
mutations: {
@@ -101,8 +101,23 @@ export default new Vuex.Store({
state.socket = socket
},
setUserTotals(state, totalsObject){
- //Save all the totals for the user
- state.userTotals = totalsObject
+
+ if(!state.userTotals){
+ state.userTotals = {}
+ }
+
+ // retain old values loaded on initial, extended options load
+ let oldMissingValues = {}
+ Object.keys(state.userTotals).forEach(key => {
+ if(!totalsObject[key] && totalsObject[key] !== 0){
+ oldMissingValues[key] = state.userTotals[key]
+ }
+ })
+
+ // combine old settings with updated settings
+ let oldAndNew = Object.assign(oldMissingValues, totalsObject)
+
+ state.userTotals = oldAndNew
//Set computer version from server
const currentVersion = localStorage.getItem('currentVersion')
@@ -126,6 +141,11 @@ export default new Vuex.Store({
setActiveSessions(state, countData){
//Count of the number of active socket.io sessions for this user
state.activeSessions = countData
+ },
+ hideMetricTrackingReminder(state){
+ if(state.userTotals){
+ state.userTotals['showTrackMetricsButton'] = false
+ }
}
},
getters: {
@@ -159,7 +179,11 @@ export default new Vuex.Store({
fetchAndUpdateUserTotals ({ commit, state }) {
clearTimeout(state.fetchTotalsTimeout)
state.fetchTotalsTimeout = setTimeout(() => {
- axios.post('/api/user/totals')
+ // load extended options on initial load
+ let postData = {
+ extendedOptions: !state.userTotals
+ }
+ axios.post('/api/user/totals', postData)
.then( ({data}) => {
commit('setUserTotals', data)
})
diff --git a/server/models/MetricTracking.js b/server/models/MetricTracking.js
index 910090e..b008e94 100644
--- a/server/models/MetricTracking.js
+++ b/server/models/MetricTracking.js
@@ -2,7 +2,7 @@ let db = require('@config/database')
let Note = require('@models/Note')
-let MetricTracking = module.exports = {}
+let MetricTracking = module.exports = {};
MetricTracking.get = (userId, masterKey) => {
@@ -23,31 +23,36 @@ MetricTracking.get = (userId, masterKey) => {
})
} else {
- //Or create a new note
- let finalId = null
- return Note.create(userId, 'Metric Tracking', '', masterKey)
- .then(insertedId => {
- finalId = insertedId
- db.promise().query('UPDATE note SET quick_note = 2 WHERE id = ? AND user_id = ?',[insertedId, userId])
- .then((rows, fields) => {
-
- const note = Note.get(userId, finalId, masterKey)
- .then(noteData => {
- return resolve(noteData)
- })
-
- })
- })
-
+ return resolve('no data')
}
-
})
.catch(console.log)
})
}
-MetricTracking.save = (userId, cycleData, masterKey) => {
+MetricTracking.create = (userId, masterKey) => {
+ return new Promise((resolve, reject) => {
+ let finalId = null
+ return Note.create(userId, 'Metric Tracking', '', masterKey)
+ .then(insertedId => {
+ finalId = insertedId
+ db.promise().query('UPDATE note SET quick_note = 2 WHERE id = ? AND user_id = ?',[insertedId, userId])
+ .then((rows, fields) => {
+
+ const note = Note.get(userId, finalId, masterKey)
+ .then(noteData => {
+ return resolve(noteData)
+ })
+
+ })
+ })
+ .catch(console.log)
+ })
+}
+
+
+MetricTracking.save = (userId, metricData, masterKey) => {
return new Promise((resolve, reject) => {
let finalId = null
@@ -55,7 +60,7 @@ MetricTracking.save = (userId, cycleData, masterKey) => {
MetricTracking.get(userId, masterKey)
.then(noteObject => {
- return Note.update(userId, noteObject.id, cycleData, noteObject.title, noteObject.color, noteObject.pinned, noteObject.archived, null, masterKey)
+ return Note.update(userId, noteObject.id, metricData, noteObject.title, noteObject.color, noteObject.pinned, noteObject.archived, null, masterKey)
})
.then( saveResults => {
diff --git a/server/models/User.js b/server/models/User.js
index a7de2ca..292f619 100644
--- a/server/models/User.js
+++ b/server/models/User.js
@@ -9,7 +9,7 @@ const speakeasy = require('speakeasy')
let User = module.exports = {}
-const version = '3.6.2'
+const version = '3.6.3'
//Login a user, if that user does not exist create them
//Issues login token
@@ -193,13 +193,13 @@ User.register = (username, password) => {
}
//Counts notes, pinned notes, archived notes, shared notes, unread notes, total files and types
-User.getCounts = (userId) => {
+User.getCounts = (userId, extendedOptions) => {
return new Promise((resolve, reject) => {
let countTotals = {
tags: {}
}
- const userHash = cs.hash(String(userId)).toString('base64')
+ // const userHash = cs.hash(String(userId)).toString('base64')
db.promise().query(
`SELECT
@@ -279,7 +279,38 @@ User.getCounts = (userId) => {
countTotals['currentVersion'] = version
- resolve(countTotals)
+ // Allow for extended options set on page load
+ if(extendedOptions){
+
+ db.promise().query(
+ `SELECT updated FROM note
+ JOIN note_raw_text ON note_raw_text.id = note.note_raw_text_id
+ WHERE note.quick_note = 2
+ AND user_id = ?`, [userId])
+ .then( (rows, fields) => {
+
+
+
+ if(rows[0][0] && rows[0][0].updated){
+ const lastOpened = rows[0][0].updated
+ const timeDiff = Math.round(((+new Date) - (lastOpened))/1000)
+ const hoursInSeconds = (12 * 60 * 60) //12 hours
+
+ // Show metric tracking button if its been 12 hours since last entry
+ if(lastOpened && timeDiff > hoursInSeconds){
+ countTotals['showTrackMetricsButton'] = true
+ }
+ }
+
+
+ resolve(countTotals)
+ })
+
+
+ } else {
+ resolve(countTotals)
+ }
+
})
})
diff --git a/server/routes/metrictrackingController.js b/server/routes/metrictrackingController.js
index da84262..f6fe21d 100644
--- a/server/routes/metrictrackingController.js
+++ b/server/routes/metrictrackingController.js
@@ -25,12 +25,16 @@ router.use(function setUserId (req, res, next) {
}
})
-//Get quick note text
router.post('/get', function (req, res) {
MetricTracking.get(userId, masterKey)
.then( data => res.send(data) )
})
+router.post('/create', function (req, res) {
+ MetricTracking.create(userId, masterKey)
+ .then( data => res.send(data) )
+})
+
//Push text to quick note
router.post('/save', function (req, res) {
MetricTracking.save(userId, req.body.cycleData, masterKey)
diff --git a/server/routes/userController.js b/server/routes/userController.js
index 8c0d856..8162ee3 100644
--- a/server/routes/userController.js
+++ b/server/routes/userController.js
@@ -53,7 +53,7 @@ router.post('/revokesessions', function(req, res) {
// fetch counts of users notes
router.post('/totals', function (req, res) {
- User.getCounts(req.headers.userId)
+ User.getCounts(req.headers.userId, req.body.extendedOptions)
.then( countsObject => res.send( countsObject ))
})
diff --git a/updatedomain.sh b/updatedomain.sh
index 2611308..7c07b09 100755
--- a/updatedomain.sh
+++ b/updatedomain.sh
@@ -1,4 +1,7 @@
-#!/bin/sh
+#!/bin/bash
+
+# Setup env variables
+source ~/.env
# Send updated dynamic IP address to Namecheap, in order to update subdomains.
# This uses curl (separate pkg) to send the change; Namecheap automatically detects source IP if the ip field (like domain, password) ..
@@ -9,12 +12,7 @@ info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
info "Starting IP update for subdomains"
-PASSWORD="12a35d53c2c54d6281265e3e086e541b"
-HOST="maxg.cc"
-SUBDOMAIN="x.maxg.cc"
+echo "https://dynamicdns.park-your-domain.com/update?host=$DYDNS_DOMAIN&domain=$DYDNS_HOST&password=$DYDNS_PASSWORD"
+curl "https://dynamicdns.park-your-domain.com/update?host=$DYDNS_DOMAIN&domain=$DYDNS_HOST&password=$DYDNS_PASSWORD"
-
-#echo "https://dynamicdns.park-your-domain.com/update?host=$SUBDOMAIN&domain=$HOST&password=$PASSWORD"
-curl "https://dynamicdns.park-your-domain.com/update?host=$SUBDOMAIN&domain=$HOST&password=$PASSWORD"
-
-info "IP update done"
\ No newline at end of file
+info "IP update done"