diff --git a/lib/classes/JsonApi/Routes/Files/FileRefsCreateByUpload.php b/lib/classes/JsonApi/Routes/Files/FileRefsCreateByUpload.php
index 3bb00d1b9ed0b50a7576565e71a811424ae03821..8c18ca1aaaeb4bd4b41cd8054d758e4a2cc60001 100644
--- a/lib/classes/JsonApi/Routes/Files/FileRefsCreateByUpload.php
+++ b/lib/classes/JsonApi/Routes/Files/FileRefsCreateByUpload.php
@@ -22,8 +22,15 @@ class FileRefsCreateByUpload extends NonJsonApiController
             throw new AuthorizationFailedException();
         }
 
+        $term_id = $request->getParsedBody()['term-id'];
+
         $fileRef = $this->handleUpload($request, $folder);
 
+        if ($term_id) {
+            $fileRef->content_terms_of_use_id = $term_id;
+            $fileRef->store();
+        }
+
         return $this->redirectToFileRef($response, $fileRef);
     }
 }
diff --git a/lib/classes/JsonApi/Schemas/ContentTermsOfUse.php b/lib/classes/JsonApi/Schemas/ContentTermsOfUse.php
index b827788e1fcc79b567ba47114b7a0196f9d130ae..23c929437a9ab72532680c5c2e646571a771daa5 100644
--- a/lib/classes/JsonApi/Schemas/ContentTermsOfUse.php
+++ b/lib/classes/JsonApi/Schemas/ContentTermsOfUse.php
@@ -19,6 +19,7 @@ class ContentTermsOfUse extends SchemaProvider
             'name' => (string) $resource['name'],
             'description' => mb_strlen($resource['description']) ? (string) $resource['description'] : null,
             'icon' => $resource['icon'],
+            'is-default' => (bool) $resource['is_default'],
             'download-condition' => (int) $resource['download_condition'],
             'mkdate' => date('c', $resource['mkdate']),
             'chdate' => date('c', $resource['chdate']),
diff --git a/lib/models/Courseware/BlockTypes/Folder.php b/lib/models/Courseware/BlockTypes/Folder.php
index ef0bd2eb5128fa11e540ce9cacd8ccaf7d7f1b1e..b3a0767b0d6a3d2aa21c6323dbe3adfc700fbbf9 100644
--- a/lib/models/Courseware/BlockTypes/Folder.php
+++ b/lib/models/Courseware/BlockTypes/Folder.php
@@ -38,9 +38,59 @@ class Folder extends BlockType
         ];
     }
 
+    /**
+     * Returns the decoded payload of the block associated with this instance.
+     *
+     * @return mixed the decoded payload
+     */
+    public function getPayload()
+    {
+        $user = \User::findCurrent();
+        $payload = $this->decodePayloadString($this->block['payload']);
+
+        $folder = \Folder::find($payload['folder_id']);
+        $payload['folder-type'] = null;
+        $payload['files'] = [];
+
+        if ($folder) {
+            $typedFolder = $folder->getTypedFolder();
+            $payload['folder-type'] = $typedFolder->folder_type;
+
+            foreach ($typedFolder->getFiles() as $folderFile) {
+                $file['id'] = $folderFile->id;
+                $file['attributes'] = [
+                    'name'          => $folderFile->name,
+                    'mime-type'     => $folderFile->mime_type,
+                    'filesize'      => (int) $folderFile->size,
+                    'mkdate'        => date('c', $folderFile->mkdate),
+                ];
+                $file['relationships'] = [
+                    'owner' => [
+                        'data' => ['type' => 'users', 'id' => $folderFile->user_id],
+                        'meta' => ['name' => $folderFile->getFileRef()->getAuthorName()]
+                        ]
+                ];
+                $file['meta'] = [
+                    'download-url'  => $folderFile->getDownloadURL(),
+                ];
+    
+                if ($this->filePermission($typedFolder, $file, $user)) {
+                    array_push($payload['files'], $file);
+                }
+            }
+        }
+
+        return $payload;
+    }
+
+    private function filePermission($typedFolder, $file, $user): bool
+    {
+        return $typedFolder->folder_type !== 'HomeworkFolder' || $user->id === $file['relationships']['owner']['data']['id'] || $typedFolder->isReadable($user->id);
+    }
+
 
     /**
-     * get all files related to this bloc.
+     * get all files related to this block.
      *
      * @return \FileRef[] list of file references realted to this block
      */
diff --git a/resources/assets/stylesheets/scss/courseware.scss b/resources/assets/stylesheets/scss/courseware.scss
index 6f8aadba1762d5444c11fbf8fd6f5f9b54f68717..f7ee74ea7f6f647ed395d434887c50acc8a626bf 100644
--- a/resources/assets/stylesheets/scss/courseware.scss
+++ b/resources/assets/stylesheets/scss/courseware.scss
@@ -3674,16 +3674,22 @@ i f r a m e  b l o c k  e n d
 /* * * * * * * * * * * *
 f o l d e r  b l o c k
 * * * * * * * * * * * */
+.cw-block-folder-info {
+    border: solid thin $content-color-40;
+    padding: 10px 10px 0 10px;
+    overflow: hidden;
+    border-bottom: none;
+}
 .cw-block-folder-list {
-    border: solid thin #ccc;
-    padding: 4px;
+    border: solid thin $content-color-40;
+    padding: 0;
     list-style: none;
 
     .cw-block-folder-file-item {
         list-style: none;
 
         &:not(:last-child) {
-            border-bottom: solid thin #ccc;
+            border-bottom: solid thin $content-color-40;
         }
         a {
             display: block;
@@ -3702,16 +3708,27 @@ f o l d e r  b l o c k
         margin: 1em;
     }
 }
- // for folder and download block
+.cw-block-folder-upload {
+    border: solid thin $content-color-40;
+    padding: 1em 10px;
+    border-top: none;
+
+    .cw-file-input {
+        width: calc(100% - 148px);
+        vertical-align: middle;
+    }
+}
+// for folder and download block
 .cw-block-file-info {
     @include background-icon(file, clickable, 24);
     background-repeat: no-repeat;
 
-    display: inline-block;
-    padding-left: 26px;
-    margin: 1em;
-    line-height: 24px;
-    color: $base-color;
+    display: block;
+    padding: 16px 16px 16px 40px;
+    background-position: 10px 16px;
+    width: calc(100% - 56px);
+    overflow: hidden;
+    text-overflow: ellipsis;
 
     &.cw-block-file-icon-empty {
         color: $black;
@@ -3723,35 +3740,78 @@ f o l d e r  b l o c k
     }
     &.cw-block-file-icon-audio {
         @include background-icon(file-audio, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file-audio, info, 24);
+        }
     }
     &.cw-block-file-icon-pic {
         @include background-icon(file-pic, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file-pic, info, 24);
+        }
     }
     &.cw-block-file-icon-video {
         @include background-icon(file-video, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file-video, info, 24);
+        }
     }
     &.cw-block-file-icon-pdf {
         @include background-icon(file-pdf, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file-pdf, info, 24);
+        }
     }
     &.cw-block-file-icon-word {
         @include background-icon(file-word, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file-word, info, 24);
+        }
     }
     &.cw-block-file-icon-spreadsheet {
         @include background-icon(file-excel, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file-excel, info, 24);
+        }
     }
     &.cw-block-file-icon-text {
         @include background-icon(file-text, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file-text, info, 24);
+        }
     }
     &.cw-block-file-icon-ppt {
         @include background-icon(file-ppt, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file-ppt, info, 24);
+        }
     }
     &.cw-block-file-icon-archive {
         @include background-icon(file-archive, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file-archive, info, 24);
+        }
     }
     &.cw-block-file-icon-file {
         @include background-icon(file, clickable, 24);
+        &.download-disabled {
+            @include background-icon(file, info, 24);
+        }
     }
 }
+.cw-block-file-details {
+    margin-top: -16px;
+    padding-left: 40px;
+    padding-bottom: 16px;
+    color: $dark-gray-color;
+}
+.cw-block-file-owner,
+.cw-block-file-mkdate {
+    display: block;
+    width: calc(100% - 56px);
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
 /* * * * * * * * * * * * * * *
 f o l d e r  b l o c k  e n d
 * * * * * * * * * * * * * * */
@@ -3763,7 +3823,6 @@ d o w n l o a d  b l o c k
 .cw-block-download {
     .cw-block-download-content {
         border: solid thin $content-color-40;
-        padding: 4px;
         .cw-block-download-file-item {
             a {
                 display: block;
@@ -4766,7 +4825,7 @@ cw tiles end
  .cw-file-input {
      width: stretch;
      border: solid thin $base-color;
-     font-size: 14px;
+     font-size: 13px;
     cursor: pointer;
 
     &::file-selector-button {
diff --git a/resources/vue/components/courseware/CoursewareAudioBlock.vue b/resources/vue/components/courseware/CoursewareAudioBlock.vue
index 7a946fa2088fce303a127a4d1bc047ac454920c1..218f11dc6664352366e9394ac0125c521740068b 100644
--- a/resources/vue/components/courseware/CoursewareAudioBlock.vue
+++ b/resources/vue/components/courseware/CoursewareAudioBlock.vue
@@ -587,28 +587,32 @@ export default {
         async storeRecording() {
             let view = this;
             let user = this.usersById({id: this.userId});
-            let file = {};
             let blob = new Blob(view.chunks, {type: 'audio/webm; codecs:vp9' });
-            file.attributes = {};
-            file.attributes.name = (user.attributes["formatted-name"]).replace(/\s+/g, '_') + '.webm';
-            let fileObj = false;
-            try {
-                 fileObj = await this.createFile({
-                    file: file,
-                    filedata: blob,
-                    folder: {id: this.currentFolderId}
-                });
-            }
-            catch(e) {
-                this.companionError({
-                    info: this.$gettext('Es ist ein Fehler aufgetreten! Die Aufnahme konnte nicht gespeichert werden.')
-                });
-                console.debug(e);
-            }
+            let file = {
+                attributes: {
+                    name: (user.attributes["formatted-name"]).replace(/\s+/g, '_') + '.webm'
+                },
+                relationships: {
+                    'terms-of-use': {
+                        data: {
+                            id: 'SELFMADE_NONPUB'
+                        }
+                    }
+                }
+            };
+            let fileObj = await this.createFile({
+                file: file,
+                filedata: blob,
+                folder: {id: this.currentFolderId}
+            });
             if(fileObj && fileObj.type === 'file-refs') {
                 this.companionSuccess({
                     info: this.$gettext('Die Aufnahme wurde erfolgreich im Dateibereich abgelegt.')
                 });
+            } else {
+                this.companionError({
+                    info: this.$gettext('Es ist ein Fehler aufgetreten! Die Aufnahme konnte nicht gespeichert werden.')
+                });
             }
             this.newRecording = false;
             this.getFolderFiles();
diff --git a/resources/vue/components/courseware/CoursewareCanvasBlock.vue b/resources/vue/components/courseware/CoursewareCanvasBlock.vue
index 79363d51fc83e10f5079c6cd6217d5cf9f841276..de474cee2f9d927b7de96ac6d999eff3998672d0 100644
--- a/resources/vue/components/courseware/CoursewareCanvasBlock.vue
+++ b/resources/vue/components/courseware/CoursewareCanvasBlock.vue
@@ -574,24 +574,20 @@ export default {
                 file.attributes.name = (user.attributes["formatted-name"]).replace(/\s+/g, '_') + '_' + this.block.attributes.title + '_' + this.block.id;
             }
 
-            let img = false;
-            try {
-                 img = await this.createFile({
-                    file: file,
-                    filedata: imageBlob,
-                    folder: {id: this.currentUploadFolderId}
-                });
-            }
-            catch(e) {
-                this.companionError({
-                    info: this.$gettext('Es ist ein Fehler aufgetretten! Das Bild konnte nicht gespeichert werden.')
-                });
-                console.log(e);
-            }
+            let img = await this.createFile({
+                file: file,
+                filedata: imageBlob,
+                folder: {id: this.currentUploadFolderId}
+            });
+
             if(img && img.type === 'file-refs') {
                 this.companionSuccess({
                     info: this.$gettext('Das Bild wurde erfolgreich im Dateibereich abgelegt.')
                 });
+            } else {
+                this.companionError({
+                    info: this.$gettext('Es ist ein Fehler aufgetretten! Das Bild konnte nicht gespeichert werden.')
+                });
             }
         },
     },
diff --git a/resources/vue/components/courseware/CoursewareDownloadBlock.vue b/resources/vue/components/courseware/CoursewareDownloadBlock.vue
index 2094cfa7133cb9b63ae69be7cf98da1dfe32c9d5..1f7a78beb90be2c8392d886361fcd41a47add3b7 100644
--- a/resources/vue/components/courseware/CoursewareDownloadBlock.vue
+++ b/resources/vue/components/courseware/CoursewareDownloadBlock.vue
@@ -19,11 +19,16 @@
                         {{ currentSuccess }}
                     </div>
                     <div class="cw-block-download-file-item">
-                        <a target="_blank" :download="currentFile.name" :href="currentFile.download_url" @click="handleDownload">
+                        <a
+                            target="_blank"
+                            :download="currentFile.name"
+                            :title="$gettext('Datei herunterladen')"
+                            :href="currentFile.download_url"
+                            @click="handleDownload"
+                        >
                             <span class="cw-block-file-info" :class="['cw-block-file-icon-' + currentFile.icon]">
                                 {{ currentFile.name }}
                             </span>
-                            <span class="cw-block-download-download-icon"></span>
                         </a>
                     </div>
                 </div>
diff --git a/resources/vue/components/courseware/CoursewareFolderBlock.vue b/resources/vue/components/courseware/CoursewareFolderBlock.vue
index a1b97490d09da6b5c9e9cbed9df1e5e03fac1c21..2d1f355f5b56d7cfc91c730bb4d317b7cbd1d86e 100644
--- a/resources/vue/components/courseware/CoursewareFolderBlock.vue
+++ b/resources/vue/components/courseware/CoursewareFolderBlock.vue
@@ -10,36 +10,127 @@
         >
             <template #content>
                 <div v-if="currentTitle !== ''" class="cw-block-title">{{ currentTitle }}</div>
+                <div v-if="isHomework" class="cw-block-folder-info">
+                    <p>
+                        {{ $gettext('Dieser Ordner ist ein Hausaufgabenordner. Es können nur Dateien eingestellt werden.') }}
+                    </p>
+                    <p v-if="!isTeacher">
+                        {{ $gettext('Sie selbst haben folgende Dateien in diesen Ordner eingestellt') }}:
+                    </p>
+                </div>
                 <ul class="cw-block-folder-list">
                     <li v-for="file in files" :key="file.id" class="cw-block-folder-file-item">
-                        <a target="_blank" :download="file.name" :href="file.download_url">
-                            <span class="cw-block-file-info" :class="['cw-block-file-icon-' + file.icon]">
-                                {{ file.name }}
+                        <a
+                            v-if="downloadEnabled"
+                            target="_blank"
+                            :download="file.attributes.name"
+                            :title="$gettext('Datei herunterladen')"
+                            :href="file.meta['download-url']"
+                        >
+                            <span class="cw-block-file-info" :class="['cw-block-file-icon-' + getIcon(file.attributes['mime-type'])]">
+                                {{ file.attributes.name }}
                             </span>
-                            <span class="cw-block-folder-download-icon"></span>
+                            <div v-if="isTeacher && isHomework" class="cw-block-file-details">
+                                <span class="cw-block-file-owner">
+                                    {{ file.relationships.owner.meta.name }}
+                                </span>
+                                <span class="cw-block-file-mkdate">
+                                    {{ getFormattedDate(file.attributes.mkdate) }}
+                                </span>
+                            </div>
                         </a>
+                        <template v-else>
+                            <span class="cw-block-file-info download-disabled" :class="['cw-block-file-icon-' + getIcon(file.attributes['mime-type'])]">
+                                {{ file.attributes.name }}
+                            </span>
+                            <div class="cw-block-file-details">
+                                <span class="cw-block-file-mkdate">
+                                    {{ getFormattedDate(file.attributes.mkdate) }}
+                                </span>
+                            </div>
+                        </template>
                     </li>
                     <li v-if="files.length === 0">
                         <span class="cw-block-file-info cw-block-file-icon-empty">
-                            <translate>Dieser Ordner ist leer</translate>
+                            {{ $gettext('Dieser Ordner ist leer') }}
                         </span>
                     </li>
                 </ul>
+                <div v-if="uploadEnabled" class="cw-block-folder-upload">
+                    <form class="default" @submit.prevent="">
+                        <label>
+                            {{ $gettext('Dateien zum Hochladen auswählen') }}
+                            <input class="cw-file-input" ref="uploadFile" type="file" @change="displayTermSelector"/>
+                            <button class="button" @click="uploadFile">
+                                {{ $gettext('Datei hochladen') }}
+                            </button>
+                        </label>
+                    </form>
+                    <studip-dialog
+                        v-if="showTermSelector"
+                        width="780"
+                        height="510"
+                        :title="$gettext('Lizenz auswählen')"
+                        :confirmText="$gettext('Speichern')"
+                        confirmClass="accept"
+                        :closeText="$gettext('Lizenzauswahl abbrechen')"
+                        closeClass="cancel"
+                        @close="showTermSelector = false"
+                        @confirm="selectTerm"
+                    >
+                        <template v-slot:dialogContent>
+                            <form class="default" @submit.prevent="">
+                                <div style="margin-bottom: 1ex;">
+                                    {{ $gettext('Bereitgestellte Dateien können heruntergeladen und ggf. weiterverbreitet werden. Dabei ist das Urheberrecht sowohl beim Hochladen der Datei als auch bei der Nutzung zu beachten. Bitte geben Sie daher an, um welche Art von Bereitstellung es sich handelt. Diese Angabe dient mehreren Zwecken: Beim Herunterladen wird ein Hinweis angezeigt, welche Nutzung der Datei zulässig ist. Beim Hochladen stellt die Angabe eine Entscheidungshilfe dar, damit Sie sichergehen können, dass die Datei tatsächlich bereitgestellt werden darf.') }}
+                                </div>
+                                <fieldset class="select_terms_of_use">
+                                    <template v-for="term in termsOfUse">
+                                        <input
+                                            type="radio"
+                                            name="content_terms_of_use_id"
+                                            :value="term.id"
+                                            v-model="selectedTerm"
+                                            :id="'content_terms_of_use-' + term.id"
+                                            :checked="selectedTerm === term.id"
+                                            :aria-description="term.description"
+                                            :key="term.id + '_input'"
+                                        />
+                                        <label @click="selectedTerm = term.id" :key="term.id + 'label'">
+                                            <div class="icon">
+                                                <studip-icon :shape="term.attributes.icon" size="32"/>
+                                            </div>
+                                            <div class="text">
+                                                {{ term.attributes.name }}
+                                            </div>
+                                            <studip-icon shape="arr_1down" size="24" class="arrow" />
+                                            <studip-icon shape="check-circle" size="24" class="check" />
+                                        </label>
+                                        <div class="terms_of_use_description" :key="term.id + '_description'">
+                                            <div class="description">
+                                                {{ term.attributes.description }}
+                                            </div>
+                                        </div>
+                                    </template>
+                                </fieldset>
+                            </form>
+                        </template>
+                    </studip-dialog>
+                </div>
             </template>
             <template v-if="canEdit" #edit>
                 <form class="default" @submit.prevent="">
                     <label>
-                        <translate>Ãœberschrift</translate>
+                        {{ $gettext('Ãœberschrift') }}
                         <input type="text" v-model="currentTitle" />
                     </label>
                     <label>
-                        <translate>Ordner</translate>
-                        <courseware-folder-chooser v-model="currentFolderId" allowUserFolders />
+                        {{ $gettext('Ordner') }}
+                        <courseware-folder-chooser v-model="currentFolderId" allowUserFolders allowHomeworkFolders />
                     </label>
                 </form>
             </template>
             <template #info>
-                <p><translate>Informationen zum Dateiordner-Block</translate></p>
+                <p>{{ $gettext('Informationen zum Dateiordner-Block') }}</p>
             </template>
         </courseware-default-block>
     </div>
@@ -48,6 +139,7 @@
 <script>
 import CoursewareDefaultBlock from './CoursewareDefaultBlock.vue';
 import CoursewareFolderChooser from './CoursewareFolderChooser.vue';
+import StudipDialog from '../StudipDialog.vue';
 
 import { mapActions, mapGetters } from 'vuex';
 
@@ -56,6 +148,7 @@ export default {
     components: {
         CoursewareDefaultBlock,
         CoursewareFolderChooser,
+        StudipDialog
     },
     props: {
         block: Object,
@@ -66,66 +159,71 @@ export default {
         return {
             currentTitle: '',
             currentFolderId: '',
-            currentFileType: '',
-            files: [],
+            currentFolderType: '',
+            showTermSelector: false,
+            selectedTerm: null,
         };
     },
     computed: {
         ...mapGetters({
-            relatedFileRefs: 'file-refs/related',
-            urlHelper: 'urlHelper',
-            relatedTermOfUse: 'terms-of-use/related',
+            folderById: 'folders/byId',
+            termsOfUse: 'terms-of-use/all'
         }),
         folderType() {
             return this.block?.attributes?.payload?.type;
         },
+        storedFolderType() {
+            return this.block?.attributes?.payload?.folder_type;
+        },
+        folderTypeHasChanged() {
+            return this.folderType === this.storedFolderType;
+        },
         folderId() {
             return this.block?.attributes?.payload?.folder_id;
         },
         title() {
             return this.block?.attributes?.payload?.title;
         },
+        files() {
+            return this.block?.attributes?.payload?.files;
+        },
+        isHomework() {
+            return this.folderType === 'HomeworkFolder';
+        },
+        uploadEnabled() {
+            return !this.isTeacher && this.isHomework;
+        },
+        downloadEnabled() {
+            return this.isTeacher || !this.isHomework;
+        }
     },
-    mounted() {
+    async mounted() {
+        await this.loadTermsOfUse();
         this.initCurrentData();
     },
     methods: {
         ...mapActions({
-            loadRelatedFileRefs: 'file-refs/loadRelated',
+            loadFolder: 'folders/loadById',
+            loadBlock: 'courseware-blocks/loadById',
             updateBlock: 'updateBlockInContainer',
+            createFile: 'createFile',
+            companionWarning: 'companionWarning',
+            companionSuccess: 'companionSuccess',
+            companionError: 'companionError',
+            loadTermsOfUse: 'terms-of-use/loadAll'
         }),
-        initCurrentData() {
+        async initCurrentData() {
             this.currentTitle = this.title;
             this.currentFolderId = this.folderId;
-            this.currentFolderType = this.folderType;
-        },
-        async getFolderFiles() {
-            const parent = { type: 'folders', id: `${this.currentFolderId}` };
-            const relationship = 'file-refs';
-            const options = { include: 'terms-of-use' };
-            await this.loadRelatedFileRefs({ parent, relationship, options });
-            const fileRefs = this.relatedFileRefs({ parent, relationship }) ?? [];
-            this.processFiles(fileRefs);
-        },
-        processFiles(files) {
-            this.files = files
-            .filter((file) => {
-                if (this.relatedTermOfUse({parent: file, relationship: 'terms-of-use'}).attributes['download-condition'] !== 0) {
-                    return false;
-                } else {
-                    return true;
-                }
-            })
-            .map(({ id, attributes }) => ({
-                id,
-                name: attributes.name,
-                icon: this.getIcon(attributes['mime-type']),
-                download_url: this.urlHelper.getURL(
-                    `sendfile.php/`,
-                    { type: 0, file_id: id, file_name: attributes.name },
-                    true
-                ),
-            }));
+            if (this.$refs?.uploadFile) {
+                this.$refs.uploadFile.value = null;
+            }
+            this.selectedTerm = this.getDefaultTerm();
+        },
+        async setCurrentFolderType() {
+            await this.loadFolder({ id: this.currentFolderId });
+            const folder = this.folderById({ id: this.currentFolderId });
+            this.currentFolderType = folder?.attributes['folder-type'];
         },
         getIcon(mimeType) {
             let icon = 'file';
@@ -171,12 +269,22 @@ export default {
 
             return icon;
         },
+        getFormattedDate(unformattedDate) {
+            const date = new Date(unformattedDate);
+            const localeDate = date.toLocaleDateString("de-DE", {
+                year: "numeric",
+                month: "2-digit",
+                day: "2-digit",
+            });
+
+            return `${localeDate} ${date.getHours()}:${(date.getMinutes() < 10 ? '0' : '') + date.getMinutes()}:${(date.getSeconds() < 10 ? '0' : '') + date.getSeconds()}`;
+        },
         storeBlock() {
             let attributes = {};
             attributes.payload = {};
             attributes.payload.title = this.currentTitle;
             attributes.payload.folder_id = this.currentFolderId;
-            attributes.payload.type = this.currentFileType;
+            attributes.payload.type = this.currentFolderType;
 
             this.updateBlock({
                 attributes: attributes,
@@ -184,10 +292,69 @@ export default {
                 containerId: this.block.relationships.container.data.id,
             });
         },
+        displayTermSelector() {
+            this.showTermSelector = true;
+        },
+        selectTerm() {
+            this.showTermSelector = false;
+            this.uploadFile();
+        },
+        async uploadFile() {
+            const userFile = this.$refs?.uploadFile?.files[0];
+            if (!userFile) {
+                this.companionWarning({
+                    info: this.$gettext('Bitte wählen Sie eine Datei aus.')
+                });
+                return;
+            }
+
+            let file = {
+                attributes: {
+                    name: userFile.name.replace(/\s/g, '_')
+                },
+                relationships: {
+                    'terms-of-use': {
+                        data: {
+                            id: this.selectedTerm
+                        }
+                    }
+                }
+            };
+            let fileObj = await this.createFile({
+                file: file,
+                filedata: userFile,
+                folder: { id: this.currentFolderId }
+            });
+            if (fileObj && fileObj.type === 'file-refs') {
+                this.companionSuccess({
+                    info: this.$gettext('Die Datei wurde erfolgreich im Dateibereich abgelegt.')
+                });
+            } else {
+                if (this.folderType !== 'HomeworkFolder') {
+                    this.companionError({
+                        info: this.$gettext('Es ist ein Fehler aufgetretten.')
+                    });
+                }
+            }
+            this.reload();
+        },
+        async reload() {
+            await this.loadBlock({ id: this.block.id });
+            this.initCurrentData();
+        },
+        getDefaultTerm() {
+            const defaultTerm = this.termsOfUse.filter(term => term.attributes['is-default'])[0];
+            if (defaultTerm) {
+                return defaultTerm.id;
+            }
+            return null;
+        }
     },
     watch: {
         currentFolderId() {
-            this.getFolderFiles();
+            if (this.canEdit) {
+                this.setCurrentFolderType();
+            }
         },
     },
 };
diff --git a/resources/vue/store/courseware/courseware.module.js b/resources/vue/store/courseware/courseware.module.js
index 85b7d11ca85bf877e031ca7b3ce275549d849cd9..a211103ffcff4182e934920f26fe034a40fee11b 100644
--- a/resources/vue/store/courseware/courseware.module.js
+++ b/resources/vue/store/courseware/courseware.module.js
@@ -286,8 +286,12 @@ export const actions = {
     },
 
     async createFile(context, { file, filedata, folder }) {
+        const termId = file.relationships['terms-of-use'].data.id;
         const formData = new FormData();
         formData.append('file', filedata, file.attributes.name);
+        if (termId) {
+            formData.append('term-id', termId);
+        }
 
         const url = `folders/${folder.id}/file-refs`;
         let request = await state.httpClient.post(url, formData, {
@@ -295,10 +299,16 @@ export const actions = {
                 'Content-Type': 'multipart/form-data',
             },
         });
+        let response = null;
+        try {
+            response = await state.httpClient.get(request.headers.location);
+        }
+        catch(e) {
+            console.debug(e);
+            response = null;
+        }
 
-        return state.httpClient.get(request.headers.location).then((response) => {
-            return response.data.data;
-        });
+        return response ? response.data.data : response;
     },
 
     async createRootFolder({ dispatch, rootGetters }, { context, folder }) {