Browse Source

Add notes-module;

modulation
Nero Ignis 3 years ago
parent
commit
0c2cb6c44a
  1. 62
      package-lock.json
  2. BIN
      public/fonts/NotePaper-regular.otf
  3. 5
      src/css/app.scss
  4. 6
      src/router/index.js
  5. 22
      src/store/index.js
  6. 14
      src/views/Menu.vue
  7. 125
      src/views/Notes.vue

62
package-lock.json generated

@ -5,6 +5,7 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ttrack",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.0", "@popperjs/core": "^2.11.0",
@ -17,7 +18,8 @@
"moment": "^2.29.1", "moment": "^2.29.1",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0" "vuex": "^4.0.0-0",
"vuex-persist": "^3.1.3"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-babel": "~4.5.0",
@ -2375,7 +2377,6 @@
"thread-loader": "^2.1.3", "thread-loader": "^2.1.3",
"url-loader": "^2.2.0", "url-loader": "^2.2.0",
"vue-loader": "^15.9.2", "vue-loader": "^15.9.2",
"vue-loader-v16": "npm:vue-loader@^16.1.0",
"vue-style-loader": "^4.1.2", "vue-style-loader": "^4.1.2",
"webpack": "^4.0.0", "webpack": "^4.0.0",
"webpack-bundle-analyzer": "^3.8.0", "webpack-bundle-analyzer": "^3.8.0",
@ -2536,7 +2537,6 @@
"merge-source-map": "^1.1.0", "merge-source-map": "^1.1.0",
"postcss": "^7.0.36", "postcss": "^7.0.36",
"postcss-selector-parser": "^6.0.2", "postcss-selector-parser": "^6.0.2",
"prettier": "^1.18.2 || ^2.0.0",
"source-map": "~0.6.1", "source-map": "~0.6.1",
"vue-template-es2015-compiler": "^1.9.0" "vue-template-es2015-compiler": "^1.9.0"
}, },
@ -4103,7 +4103,6 @@
"dependencies": { "dependencies": {
"anymatch": "~3.1.2", "anymatch": "~3.1.2",
"braces": "~3.0.2", "braces": "~3.0.2",
"fsevents": "~2.3.2",
"glob-parent": "~5.1.2", "glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0", "is-binary-path": "~2.1.0",
"is-glob": "~4.0.1", "is-glob": "~4.0.1",
@ -9140,9 +9139,6 @@
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true, "dev": true,
"dependencies": {
"graceful-fs": "^4.1.6"
},
"optionalDependencies": { "optionalDependencies": {
"graceful-fs": "^4.1.6" "graceful-fs": "^4.1.6"
} }
@ -15514,16 +15510,39 @@
"vue": "^3.0.2" "vue": "^3.0.2"
} }
}, },
"node_modules/vuex-persist": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/vuex-persist/-/vuex-persist-3.1.3.tgz",
"integrity": "sha512-QWOpP4SxmJDC5Y1+0+Yl/F4n7z27syd1St/oP+IYCGe0X0GFio0Zan6kngZFufdIhJm+5dFGDo3VG5kdkCGeRQ==",
"dependencies": {
"deepmerge": "^4.2.2",
"flatted": "^3.0.5"
},
"peerDependencies": {
"vuex": ">=2.5"
}
},
"node_modules/vuex-persist/node_modules/deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/vuex-persist/node_modules/flatted": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
"integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg=="
},
"node_modules/watchpack": { "node_modules/watchpack": {
"version": "1.7.5", "version": "1.7.5",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
"integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"chokidar": "^3.4.1",
"graceful-fs": "^4.1.2", "graceful-fs": "^4.1.2",
"neo-async": "^2.5.0", "neo-async": "^2.5.0"
"watchpack-chokidar2": "^2.0.1"
}, },
"optionalDependencies": { "optionalDependencies": {
"chokidar": "^3.4.1", "chokidar": "^3.4.1",
@ -15585,7 +15604,6 @@
"anymatch": "^2.0.0", "anymatch": "^2.0.0",
"async-each": "^1.0.1", "async-each": "^1.0.1",
"braces": "^2.3.2", "braces": "^2.3.2",
"fsevents": "^1.2.7",
"glob-parent": "^3.1.0", "glob-parent": "^3.1.0",
"inherits": "^2.0.3", "inherits": "^2.0.3",
"is-binary-path": "^1.0.0", "is-binary-path": "^1.0.0",
@ -15892,7 +15910,6 @@
"anymatch": "^2.0.0", "anymatch": "^2.0.0",
"async-each": "^1.0.1", "async-each": "^1.0.1",
"braces": "^2.3.2", "braces": "^2.3.2",
"fsevents": "^1.2.7",
"glob-parent": "^3.1.0", "glob-parent": "^3.1.0",
"inherits": "^2.0.3", "inherits": "^2.0.3",
"is-binary-path": "^1.0.0", "is-binary-path": "^1.0.0",
@ -28964,6 +28981,27 @@
"@vue/devtools-api": "^6.0.0-beta.11" "@vue/devtools-api": "^6.0.0-beta.11"
} }
}, },
"vuex-persist": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/vuex-persist/-/vuex-persist-3.1.3.tgz",
"integrity": "sha512-QWOpP4SxmJDC5Y1+0+Yl/F4n7z27syd1St/oP+IYCGe0X0GFio0Zan6kngZFufdIhJm+5dFGDo3VG5kdkCGeRQ==",
"requires": {
"deepmerge": "^4.2.2",
"flatted": "^3.0.5"
},
"dependencies": {
"deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
},
"flatted": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
"integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg=="
}
}
},
"watchpack": { "watchpack": {
"version": "1.7.5", "version": "1.7.5",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",

BIN
public/fonts/NotePaper-regular.otf

Binary file not shown.

5
src/css/app.scss

@ -1,6 +1,11 @@
@import '~izitoast/dist/css/iziToast.min.css'; @import '~izitoast/dist/css/iziToast.min.css';
@import "~bootswatch/dist/materia/bootstrap.min.css"; @import "~bootswatch/dist/materia/bootstrap.min.css";
@font-face {
font-family: 'NotePaper';
src: url('/fonts/NotePaper-regular.otf');
}
body { body {
background-color: #e7e7e7; background-color: #e7e7e7;
} }

6
src/router/index.js

@ -3,6 +3,7 @@ import Trackers from "../views/Trackers";
import Settings from "../views/Settings"; import Settings from "../views/Settings";
import TrackersDetail from "../views/TrackersDetail"; import TrackersDetail from "../views/TrackersDetail";
import Archive from "../views/Archive"; import Archive from "../views/Archive";
import Notes from "../views/Notes";
Array.prototype.pushToBeginning = function (toPush) { Array.prototype.pushToBeginning = function (toPush) {
return this.unshift.apply(this, [toPush]); return this.unshift.apply(this, [toPush]);
@ -24,6 +25,11 @@ const routes = [
name: 'Archive', name: 'Archive',
component: Archive component: Archive
}, },
{
path: '/notes',
name: 'Notes',
component: Notes
},
{ {
path: '/settings', path: '/settings',
name: 'Settings', name: 'Settings',

22
src/store/index.js

@ -1,4 +1,5 @@
import {createStore} from 'vuex' import {createStore} from 'vuex'
import moment from "moment";
export default createStore({ export default createStore({
state: { state: {
@ -9,7 +10,8 @@ export default createStore({
}, },
trashed: {}, trashed: {},
selectedTracker: {}, selectedTracker: {},
tasks: [] tasks: [],
notes: []
}, },
mutations: { mutations: {
loadSavedData(state) { loadSavedData(state) {
@ -28,6 +30,11 @@ export default createStore({
state.tasks = JSON.parse(storedTasks); state.tasks = JSON.parse(storedTasks);
} }
let storedNotes = localStorage.getItem('notes');
if (storedNotes !== null && storedNotes !== undefined) {
state.notes = JSON.parse(storedNotes);
}
let storedSettings = localStorage.getItem('settings'); let storedSettings = localStorage.getItem('settings');
state.settings = storedSettings == null ? { state.settings = storedSettings == null ? {
theme: '', theme: '',
@ -97,6 +104,19 @@ export default createStore({
}, },
selectTracker(state, tracker) { selectTracker(state, tracker) {
state.selectedTracker = tracker; state.selectedTracker = tracker;
},
saveNotes(state) {
localStorage.setItem('notes', JSON.stringify(state.notes));
},
createNote(state, content = '') {
state.notes.pushToBeginning({
body: content,
color: '#ffea77',
created: moment()
});
},
deleteNote(state, index) {
state.notes.splice(index, 1);
} }
} }
}) })

14
src/views/Menu.vue

@ -45,6 +45,16 @@
<i class="fas fa-archive"></i> <i class="fas fa-archive"></i>
</router-link> </router-link>
</div> </div>
<div class="left-menu-item">
<router-link to="/notes"
type="button"
class="btn btn-warning bottom-menu-item"
style="background-color: #ffea77;"
data-bs-placement="left"
title="Notizen">
<i class="fas fa-pen"></i>
</router-link>
</div>
<div class="left-menu-item" v-if="($store.state.trackers.length + $store.state.archive.length) > 0"> <div class="left-menu-item" v-if="($store.state.trackers.length + $store.state.archive.length) > 0">
<a type="button" <a type="button"
class="btn btn-info text-light bottom-menu-item" class="btn btn-info text-light bottom-menu-item"
@ -112,4 +122,8 @@ export default {
margin-bottom: 1em; margin-bottom: 1em;
} }
.fas, .far {
text-shadow: 1px 1px grey;
}
</style> </style>

125
src/views/Notes.vue

@ -0,0 +1,125 @@
<template>
<div class="row">
<div class="col-sm-12">
<div class="float-end">
<a href="javascript:" v-on:click="createNote()" class="btn btn-sm btn-success">Neue Notiz</a>
</div>
<h5><i class="fa fa-pen"></i> Notizen</h5>
</div>
<div id="note-container" class="row">
<div class="col-lg-4 col-md-6" v-for="(note, noteIndex) in $store.state.notes" v-bind:key="noteIndex">
<div class="card">
<div class="card-body note" :style="'background-color:' + note.color ?? '#ffea77'">
<textarea v-model="note.body" spellcheck="false" @keydown="this.$store.commit('saveNotes')"></textarea>
<div class="color-changer">
<span v-for="color in noteColors"
v-bind:key="color">
<span href="javascript:"
@click="note.color = color;"
class="color-change-button"
v-if="color !== note.color"
:style="'background-color: ' + color">
</span>
</span>
</div>
<div class="float-end">
<a href="javascript:" class="delete-button" @click="$store.commit('deleteNote', noteIndex)"><i class="fas fa-trash"></i></a>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "Notes",
data() {
return {
noteColors: ['#ffea77', '#ee6352', '#59cd90', '#3fa7d6', '#fac05e', '#f79d84']
}
},
methods: {
createNote() {
let component = this;
axios.get(
'https://api.quotable.io/random'
).then((response) => {
component.$store.commit('createNote', response.data.content + '\n - ' + response.data.author);
component.$store.commit('saveNotes');
}).catch(() => {
component.$store.commit('createNote', '');
component.$store.commit('saveNotes');
})
}
}
}
</script>
<style scoped>
.card-body {
font-family: NotePaper, sans-serif;
}
#note-container {
margin-top: 1em;
}
textarea {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
background-color: transparent;
border: 0 solid transparent;
min-height: 10em;
}
textarea:focus {
outline: none;
}
.color-changer {
position: absolute;
bottom: -0.8em;
z-index: 1000;
}
.color-change-button {
margin-right: 0.2em;
background-color: red;
border-radius: 25px;
padding: 0.2em 0.7em;
text-decoration: none;
}
.color-change-button:hover {
opacity: 0.9;
cursor: pointer;
}
.delete-button {
position: absolute;
bottom: -1.5em;
right: 0.5em;
text-align: right;
background-color: red;
border-radius: 25px;
z-index: 1000;
}
.delete-button i {
margin: 1em;
color: black;
}
.delete-button:hover * {
color: white;
}
</style>
Loading…
Cancel
Save