Selaa lähdekoodia

rudimentary version of notes is done. Upload is still missing

Warafear 7 kuukautta sitten
vanhempi
commit
a7febd25ba

+ 97 - 32
src/app/journal/journal-notes/journal-notes.component.html

@@ -1,37 +1,102 @@
 <div class="entries-container">
-  <div class="entry">ENtry1</div>
-  <div class="entry">entry 2</div>
-  <div class="entry"></div>
-  <div class="entry"></div>
-  <div class="entry"></div>
+  @for (entry of entries; let index = $index; track entry) {
+    <div
+      (click)="activateEntry(index)"
+      [ngClass]="currentEntryIndex === index ? 'active' : ''"
+      class="entry"
+    >
+      <div class="entry-title">
+        @if (entries[index].title !== "") {
+          {{ entries[index].title }}
+        } @else {
+          Kein Titel
+        }
+      </div>
+      <div class="entry-date">
+        {{ entries[index].created | date: "shortDate" : "" : "de" }}
+      </div>
+    </div>
+  }
+  <div class="entry add-button" (click)="addEntry()">
+    <img src="assets/icons/UIIcons/add.svg" />
+  </div>
 </div>
 
-<!-- Title -->
-<!-- <mat-label>{{ "notes.title" | translate }}</mat-label> -->
-<mat-form-field class="title" appearance="outline">
-  <input matInput name="name" />
-</mat-form-field>
+@if (currentEntryIndex !== -1) {
+  <div class="entry-container">
+    @if (isInEditMode) {
+      <!-- Title -->
+      <mat-form-field class="title-write" appearance="outline">
+        <input
+          matInput
+          name="name"
+          placeholder="Titel des Eintrags"
+          [(ngModel)]="currentEntry.title"
+        />
+      </mat-form-field>
 
-<!-- Datepicker -->
-<mat-form-field class="date" appearance="outline">
-  <mat-label>Choose a date</mat-label>
-  <input matInput [matDatepicker]="picker" />
-  <mat-hint>MM/DD/YYYY</mat-hint>
-  <mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
-  <mat-datepicker #picker></mat-datepicker>
-</mat-form-field>
-<!-- Entry -->
-<div class="entry-container"></div>
+      <!-- Datepicker -->
+      <mat-form-field class="date-write" appearance="outline">
+        <input
+          matInput
+          [matDatepicker]="picker"
+          placeholder="TT.MM.JJJJ"
+          [(ngModel)]="currentEntry.created"
+        />
+        <mat-datepicker-toggle
+          matIconSuffix
+          [for]="picker"
+        ></mat-datepicker-toggle>
+        <mat-datepicker #picker></mat-datepicker>
+      </mat-form-field>
+      <div class="NgxEditor__Wrapper">
+        <ngx-editor-menu [editor]="editor" [toolbar]="toolbar">
+        </ngx-editor-menu>
+        <ngx-editor
+          [editor]="editor"
+          [placeholder]="'notes.placeholder' | translate"
+          [(ngModel)]="currentEntry.content"
+        ></ngx-editor>
+      </div>
+    } @else {
+      <div class="title-row">
+        <div class="title-read">{{ entries[currentEntryIndex].title }}</div>
+        <div class="date-read">
+          {{ currentEntry.created | date: "longDate" : "" : "de" }}
+        </div>
+      </div>
+      <div class="read-container" [innerHTML]="currentEntry.content"></div>
+    }
+    <div class="button-row">
+      @if (isInEditMode) {
+        @if (isNewEntry) {
+          <ui-button width="w16" (click)="saveEntry()">Speichern</ui-button>
+          <ui-button width="w16" (click)="deleteEntry()">Löschen</ui-button>
+        } @else {
+          <ui-button width="w16" (click)="saveEntry()">Speichern</ui-button>
+          <ui-button width="w16" (click)="discardEntry()">Verwerfen</ui-button>
+        }
+      } @else {
+        <ui-button width="w16" (click)="isInEditMode = true"
+          >Bearbeiten</ui-button
+        >
+        <ui-button width="w16" (click)="deleteEntry()"
+          >Eintrag löschen</ui-button
+        >
+      }
 
-<!-- <div class="NgxEditor__Wrapper">
-  <ngx-editor-menu [editor]="editor"> </ngx-editor-menu>
-  <ngx-editor
-    [editor]="editor"
-    [(ngModel)]="html"
-    [disabled]="false"
-    [placeholder]="'Coming soon...'"
-  ></ngx-editor>
-</div>
-<p [innerHTML]="htmlString"></p>
-
-<div [innerHTML]="html"></div> -->
+      <!-- <ui-button width="w16" (click)="isInEditMode = false"
+        >Zur Leseansicht</ui-button
+      >
+    } @else {
+      <ui-button width="w16" (click)="isInEditMode = true"
+        >Bearbeiten</ui-button
+      >
+    } -->
+      <!-- <ui-button style="width: 10rem" (click)="discardChanges()">Verwerfen</ui-button>
+    <ui-button style="width: 10rem" (click)="editEntry()">Bearbeiten</ui-button> -->
+    </div>
+  </div>
+} @else {
+  <div class="empty">Noch kein Eintrag vorhanden</div>
+}

+ 113 - 22
src/app/journal/journal-notes/journal-notes.component.scss

@@ -21,36 +21,127 @@
       background-image: url("../../../assets/images/texture-5.jpg");
     }
   }
-}
 
-.title {
-  margin-left: calc(50vw - 400px + 9rem);
-  ::ng-deep .mat-mdc-text-field-wrapper {
-    width: 26rem !important;
-    // border: var(--gold-2);
+  .entry-title {
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
   }
-}
-.date {
-  margin-left: 11.75rem;
-  ::ng-deep .mat-mdc-text-field-wrapper {
-    width: 12rem !important;
+
+  .entry-date {
   }
-}
 
+  .add-button {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+}
 
-mdc-text-field{
-    border: 1px solid red
+.active {
+  // border: var(--gold-3) !important;
+  background-image: url("../../../assets/images/texture-20.jpg") !important;
 }
 
 .entry-container {
   width: 800px;
   margin-left: calc(50vw - 400px + 9rem);
-  margin-top: 1rem;
-  height: calc(100vh - 10.5rem);
-  padding: 2rem 2rem;
-  overflow: auto;
-  border-radius: 10px;
-  border: var(--gold-3);
-  background-image: url("/assets/images/texture-0.jpg");
-  box-shadow: var(--shadow);
+  margin-top: 3rem;
+
+  // WRITE VIEW
+  .title-write {
+    border: var(--gold-2);
+    border-radius: 6px;
+    box-shadow: var(--shadow);
+    ::ng-deep .mat-mdc-text-field-wrapper {
+      width: 26rem !important;
+    }
+  }
+  .date-write {
+    border: var(--gold-2);
+    margin-left: 13.5rem;
+    border-radius: 6px;
+    box-shadow: var(--shadow);
+    ::ng-deep .mat-mdc-text-field-wrapper {
+      width: 10rem !important;
+    }
+  }
+
+  ::ng-deep .mat-calendar-body-selected {
+    background-color: var(--primary) !important;
+  }
+
+  .NgxEditor__Wrapper {
+    margin-top: 1.5rem;
+    border: var(--gold-3) !important;
+    border-radius: 6px;
+    box-shadow: var(--shadow);
+  }
+
+  ::ng-deep .NgxEditor__MenuBar {
+    background-image: url("../../../assets/images/texture-10.jpg");
+  }
+  ::ng-deep .ProseMirror {
+    height: calc(100vh - 17rem);
+    background-image: url("../../../assets/images/texture-0.jpg");
+    border-radius: 0 0 4px 4px;
+  }
+
+  // .NgxEditor__Content {
+  //   height: 30rem;
+  // }
+
+  // READ VIEW
+
+  .title-row {
+    display: flex;
+    justify-content: space-between;
+  }
+
+  .title-read {
+    display: inline-block;
+    width: 26rem;
+    height: 3.75rem;
+    display: flex;
+    align-items: center;
+    padding-left: 1rem;
+    font-size: 1.25rem;
+    font-weight: 500;
+    border: var(--gold-3);
+    border-radius: 6px;
+    box-shadow: var(--shadow);
+    background-image: url("../../../assets/images/texture-0.jpg");
+  }
+
+  .date-read {
+    display: inline-block;
+    text-align: center;
+    display: flex;
+    align-items: center;
+    padding: 0 1rem;
+    font-size: 1.25rem;
+    font-weight: 500;
+    height: 3.75rem;
+    border: var(--gold-3);
+    border-radius: 6px;
+    box-shadow: var(--shadow);
+    background-image: url("../../../assets/images/texture-0.jpg");
+  }
+
+  .read-container {
+    margin-top: 1.5rem;
+    height: calc(100vh - 14.375rem);
+    padding: 2rem 2rem;
+    overflow: auto;
+    border-radius: 6px;
+    border: var(--gold-3);
+    background-image: url("/assets/images/texture-0.jpg");
+    box-shadow: var(--shadow);
+  }
+
+  .button-row {
+    display: flex;
+    justify-content: space-around;
+    margin-top: 1rem;
+  }
 }

+ 79 - 15
src/app/journal/journal-notes/journal-notes.component.ts

@@ -1,6 +1,9 @@
-import { Component, OnInit, OnDestroy } from '@angular/core';
+import { Component, OnInit, OnDestroy, Inject } from '@angular/core';
 import { Editor } from 'ngx-editor';
-import { marked } from 'marked';
+import { DateAdapter } from '@angular/material/core';
+import { JournalEntry } from 'src/interfaces/interfaces';
+import localeDe from '@angular/common/locales/de';
+import { registerLocaleData } from '@angular/common';
 
 @Component({
   selector: 'app-journal-notes',
@@ -10,27 +13,88 @@ import { marked } from 'marked';
 export class JournalNotesComponent implements OnInit, OnDestroy {
   editor: Editor = new Editor();
   html = '';
+  isInEditMode = true;
+  currentEntryIndex: number = 0;
+  isNewEntry = false;
 
-  markdownString =
-    ' # Hello \n \
-  this is a test \
-  **hi** \
-   \
-  - 1\
-  - 2';
+  public entries: JournalEntry[] = [
+    {
+      title: 'testtitle',
+      content: 'testcontent',
+      created: new Date(2024, 8, 29),
+    },
+    {
+      title: 'zweiter titel',
+      content: 'zweiter content',
+      created: new Date(2023, 1, 2),
+    },
+  ];
+  currentEntry: JournalEntry = this.entries[this.currentEntryIndex];
 
-  htmlString = '';
+  toolbar: any = [
+    // default value
+    ['bold', 'italic'],
+    ['bullet_list'],
+    [{ heading: ['h3', 'h4', 'h5', 'h6'] }],
+  ];
 
-  constructor() {
-    this.htmlString = marked(this.markdownString);
-    console.log(this.markdownString);
-    console.log(this.htmlString);
+  constructor(private _adapter: DateAdapter<any>) {
+    registerLocaleData(localeDe);
   }
 
-  ngOnInit(): void {}
+  ngOnInit(): void {
+    this._adapter.setLocale('de');
+  }
 
   // make sure to destory the editor
   ngOnDestroy(): void {
     this.editor.destroy();
   }
+
+  public activateEntry(index: number): void {
+    this.currentEntryIndex = index;
+    this.currentEntry = this.entries[index];
+    this.isInEditMode = false;
+  }
+
+  addEntry(): void {
+    this.currentEntry = {
+      title: '',
+      content: '',
+      created: new Date(),
+    };
+    this.isNewEntry = true;
+    this.isInEditMode = true;
+    // Hightlight no entry
+    this.currentEntryIndex = -1;
+  }
+
+  public saveEntry(): void {
+    if (this.isNewEntry) {
+      // Prepend the new JournalEntry
+      this.entries = [this.currentEntry, ...this.entries];
+      this.isNewEntry = false;
+      this.currentEntryIndex = 0;
+    }
+    this.isInEditMode = false;
+  }
+
+  public discardEntry(): void {
+    if (this.isNewEntry) {
+      // this.currentEntryIndex = this.entries.length - 1;
+      this.isNewEntry = false;
+    }
+    this.currentEntry = this.entries[this.currentEntryIndex];
+    this.isInEditMode = false;
+  }
+
+  deleteEntry(): void {
+    this.entries.splice(this.currentEntryIndex, 1);
+    if (this.entries.length === 0) {
+      this.currentEntryIndex = -1;
+    } else {
+      this.currentEntryIndex = Math.max(this.currentEntryIndex - 1, 0);
+      this.currentEntry = this.entries[this.currentEntryIndex];
+    }
+  }
 }

+ 2 - 1
src/assets/i18n/de.json

@@ -821,7 +821,8 @@
     }
   },
   "notes": {
-    "title": "Titel"
+    "title": "Titel",
+    "placeholder": "Hier die Notizen einfügen"
   },
 
   "creator": {

+ 2 - 1
src/assets/i18n/en.json

@@ -816,7 +816,8 @@
     }
   },
   "notes": {
-    "title": "Title"
+    "title": "Title",
+    "placeholder": "Add notes here"
   },
   "creator": {
     "new": "Create New Character",

+ 5 - 0
src/colors.scss

@@ -99,4 +99,9 @@
     0 0 9px #69088f, 0 0 12px #3a088f, 0 0 15px #080a8f;
   --transmutation-border-large: 0 0 0 3px #171314, 0 0 4px #8f088f,
     0 0 5px #7f088f, 0 0 11px #69088f, 0 0 14px #3a088f, 0 0 17px #080a8f;
+
+  --mat-datepicker-calendar-date-selected-state-background-color: var(
+    --primary
+  );
+  --mat-datepicker-toggle-active-state-icon-color: var(--primary);
 }

+ 10 - 0
src/interfaces/interfaces.ts

@@ -165,3 +165,13 @@ export interface Spell {
   heal?: Heal;
 }
 // #endregion
+
+// #region Notes
+
+export interface JournalEntry {
+  title: string;
+  created: Date;
+  content: string;
+  startDate?: string;
+  endDate?: string;
+}

+ 20 - 0
src/services/data/data.service.ts

@@ -10,6 +10,7 @@ import {
   Spell,
   Skill,
   Attribute,
+  JournalEntry,
 } from 'src/interfaces/interfaces';
 import { SpellsService } from '../spells/spells.service';
 
@@ -145,6 +146,10 @@ export class DataService {
     this.traits = traitsData.data;
     this.abilities = abilitiesData.data;
     this.proficiencies = proficienciesData;
+
+    // Notes
+
+    this.notesData = notesData;
   }
 
   // #endregion
@@ -1073,6 +1078,21 @@ export class DataService {
 
   // #endregion
 
+  // #region Notes
+
+  private _notesData: JournalEntry[] = [];
+
+  public get notesData(): JournalEntry[] {
+    return this._notesData;
+  }
+
+  public set notesData(newValue: JournalEntry[]) {
+    this._notesData = newValue;
+    this.setData('notes', newValue);
+  }
+
+  // #endregion
+
   // #region database calls
 
   public async addData(