diff --git a/assets/dbp-signature-verification-full.metadata.json b/assets/dbp-signature-verification-full.metadata.json
new file mode 100644
index 0000000000000000000000000000000000000000..6af586ad5da4fb98730c1c2fa00b32fe0addfb9f
--- /dev/null
+++ b/assets/dbp-signature-verification-full.metadata.json
@@ -0,0 +1,17 @@
+{
+  "element": "dbp-signature-verification-full",
+  "module_src": "dbp-signature-verification-full.js",
+  "routing_name": "signature-verification-full",
+  "name": {
+    "de": "Signierte Dokumente verifizieren",
+    "en": "Verify signed documents"
+  },
+  "short_name": {
+    "de": "Signierte Dokumente verifizieren",
+    "en": "Verify signed documents"
+  },
+  "description": {
+    "de": "Erlaubt das Verifizieren von signierten PDF-Dokumenten",
+    "en": "Allows verification of signed PDF-documents"
+  }
+}
diff --git a/assets/dbp-signature.topic.metadata.json.ejs b/assets/dbp-signature.topic.metadata.json.ejs
index facd50e4c60dc008c940103637735dcbdbf66e08..0428d609a8c2b1a0513dab25aebd4fa899ea8bf8 100644
--- a/assets/dbp-signature.topic.metadata.json.ejs
+++ b/assets/dbp-signature.topic.metadata.json.ejs
@@ -17,6 +17,8 @@
      "visible": <%= environment == "local" || environment == "development" || environment == "demo" %>},
     {"path": "dbp-qualified-signature-pdf-upload.metadata.json"},
     {"path": "dbp-signature-verification.metadata.json",
+     "visible": <%= environment == "local" || environment == "development" %>},
+    {"path": "dbp-signature-verification-full.metadata.json",
      "visible": <%= environment == "local" || environment == "development" %>}
   ],
   "attributes": []
diff --git a/rollup.config.js b/rollup.config.js
index c462df7a1869d91a7bfdee599860e2efedc84faa..b9b1cd02ab61cbc60f46e9ba9bf682db582b2f9e 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -150,6 +150,7 @@ export default {
       'src/dbp-official-signature-pdf-upload.js',
       'src/dbp-qualified-signature-pdf-upload.js',
       'src/dbp-signature-verification.js',
+      'src/dbp-signature-verification-full.js',
     ] : glob.sync('test/**/*.js'),
     output: {
       dir: 'dist',
diff --git a/src/dbp-signature-verification-full.js b/src/dbp-signature-verification-full.js
new file mode 100644
index 0000000000000000000000000000000000000000..c551dbf5920aa731eb734f3ff882f80691b1271b
--- /dev/null
+++ b/src/dbp-signature-verification-full.js
@@ -0,0 +1,829 @@
+import {createI18nInstance} from './i18n.js';
+import {humanFileSize} from 'dbp-common/i18next.js';
+import {css, html} from 'lit-element';
+import {ScopedElementsMixin} from '@open-wc/scoped-elements';
+import DBPSignatureLitElement from "./dbp-signature-lit-element";
+import {PdfPreview} from "./dbp-pdf-preview";
+import * as commonUtils from 'dbp-common/utils';
+import {Icon, MiniSpinner, Button} from 'dbp-common';
+import * as commonStyles from 'dbp-common/styles';
+import {classMap} from 'lit-html/directives/class-map.js';
+import {FileSource} from 'dbp-file-handling';
+import JSONLD from "dbp-common/jsonld";
+import nextcloudWebAppPasswordURL from 'consts:nextcloudWebAppPasswordURL';
+import nextcloudWebDavURL from 'consts:nextcloudWebDavURL';
+import nextcloudName from 'consts:nextcloudName';
+
+const i18n = createI18nInstance();
+
+class SignatureVerificationFull extends ScopedElementsMixin(DBPSignatureLitElement) {
+    constructor() {
+        super();
+        this.lang = i18n.language;
+        this.entryPointUrl = commonUtils.getAPiUrl();
+        this.verifiedFiles = [];
+        this.verifiedFilesCount = 0;
+        this.errorFiles = [];
+        this.errorFilesCount = 0;
+        this.uploadStatusFileName = "";
+        this.uploadStatusText = "";
+        this.currentFile = {};
+        this.currentFileName = "";
+        this.currentFilePlacementMode = "";
+        this.currentFileSignaturePlacement = {};
+        this.verificationProcessEnabled = false;
+        this.verificationProcessActive = false;
+        this.previewInProgress = false;
+        this.currentPreviewQueueKey = '';
+
+        // will be set in function update
+        this.verificationUrl = "";
+    }
+
+    static get scopedElements() {
+        return {
+            'dbp-icon': Icon,
+            'dbp-file-source': FileSource,
+            'dbp-pdf-preview': PdfPreview,
+            'dbp-mini-spinner': MiniSpinner,
+            'dbp-button': Button,
+        };
+    }
+
+    static get properties() {
+        return {
+            lang: { type: String },
+            entryPointUrl: { type: String, attribute: 'entry-point-url' },
+            verifiedFiles: { type: Array, attribute: false },
+            verifiedFilesCount: { type: Number, attribute: false },
+            queuedFilesCount: { type: Number, attribute: false },
+            errorFiles: { type: Array, attribute: false },
+            errorFilesCount: { type: Number, attribute: false },
+            uploadInProgress: { type: Boolean, attribute: false },
+            uploadStatusFileName: { type: String, attribute: false },
+            uploadStatusText: { type: String, attribute: false },
+            verificationProcessEnabled: { type: Boolean, attribute: false },
+            verificationProcessActive: { type: Boolean, attribute: false },
+            queueBlockEnabled: { type: Boolean, attribute: false },
+            currentFile: { type: Object, attribute: false },
+            currentFileName: { type: String, attribute: false },
+            previewInProgress: { type: Boolean, attribute: false },
+            isSignaturePlacement: { type: Boolean, attribute: false },
+        };
+    }
+
+    connectedCallback() {
+        super.connectedCallback();
+        // needs to be called in a function to get the variable scope of "this"
+        setInterval(() => { this.handleQueuedFiles(); }, 1000);
+    }
+
+    /**
+     * Processes queued files
+     */
+    async handleQueuedFiles() {
+        this.endVerificationProcessIfQueueEmpty();
+        if (this.queuedFilesCount === 0) {
+            // reset verificationProcessEnabled button
+            this.verificationProcessEnabled = false;
+            return;
+        }
+
+        if (!this.verificationProcessEnabled || this.uploadInProgress) {
+            return;
+        }
+
+        this.previewInProgress = false;
+
+        const key = Object.keys(this.queuedFiles)[0];
+
+        // take the file off the queue
+        let file = this.takeFileFromQueue(key);
+        this.currentFile = file;
+
+        this.uploadInProgress = true;
+        let params = {};
+
+        this.uploadStatusText = i18n.t('signature-verification.upload-status-file-text', {
+            fileName: file.name,
+            fileSize: humanFileSize(file.size, false),
+        });
+
+        await this.uploadFile(file, params);
+        this.uploadInProgress = false;
+    }
+
+    /**
+     * Called when preview is "canceled"
+     *
+     * @param event
+     */
+    hidePDF(event) {
+        this.previewInProgress = false;
+    }
+
+    /**
+     * Decides if the "beforeunload" event needs to be canceled
+     *
+     * @param event
+     */
+    onReceiveBeforeUnload(event) {
+        // we don't need to stop if there are no signed files
+        if (this.verifiedFilesCount === 0) {
+            return;
+        }
+
+        // we need to handle custom events ourselves
+        if (!event.isTrusted) {
+            // note that this only works with custom event since calls of "confirm" are ignored
+            // in the non-custom event, see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
+            const result = confirm(i18n.t('signature-verification.confirm-page-leave'));
+
+            // don't stop the page leave if the user wants to leave
+            if (result) {
+                return;
+            }
+        }
+
+        // Cancel the event as stated by the standard
+        event.preventDefault();
+
+        // Chrome requires returnValue to be set
+        event.returnValue = '';
+    }
+
+    endVerificationProcessIfQueueEmpty() {
+        if (this.queuedFilesCount === 0 && this.verificationProcessActive) {
+            this.verificationProcessActive = false;
+        }
+    }
+
+    /**
+     * @param ev
+     */
+    onFileSelected(ev) {
+        console.log("File was selected: ev", ev);
+        this.queueFile(ev.detail.file);
+    }
+
+    addToErrorFiles(file) {
+        this.endVerificationProcessIfQueueEmpty();
+
+        // this doesn't seem to trigger an update() execution
+        this.errorFiles[Math.floor(Math.random() * 1000000)] = file;
+        // this triggers the correct update() execution
+        this.errorFilesCount++;
+
+        if (window._paq !== undefined) {
+            window._paq.push(['trackEvent', 'officiallyVerification', 'VerificationFailed', file.json["hydra:description"]]);
+        }
+    }
+
+    /**
+     * @param data
+     */
+    onFileUploadFinished(data) {
+        if (data.status !== 201) {
+            this.addToErrorFiles(data);
+        } else if (data.json["@type"] === "https://schema.tugraz.at/ElectronicSignatureVerificationReport" ) {
+            // this doesn't seem to trigger an update() execution
+            this.verifiedFiles.push(data.json);
+            // this triggers the correct update() execution
+            this.verifiedFilesCount++;
+            const entryPoint = data.json;
+            this.currentFileName = entryPoint.name;
+            this.endVerificationProcessIfQueueEmpty();
+        }
+    }
+
+    update(changedProperties) {
+        changedProperties.forEach((oldValue, propName) => {
+            switch (propName) {
+                case "lang":
+                    i18n.changeLanguage(this.lang);
+                    break;
+                case "entryPointUrl":
+                    JSONLD.initialize(this.entryPointUrl, (jsonld) => {
+                        const apiUrlBase = jsonld.getApiUrlForEntityName("ElectronicSignatureVerificationReport");
+                        this.fileSourceUrl = apiUrlBase + "/create";
+                    });
+                    break;
+            }
+
+            // console.log(propName, oldValue);
+        });
+
+        super.update(changedProperties);
+    }
+
+    onLanguageChanged(e) {
+        this.lang = e.detail.lang;
+    }
+
+    /**
+     * Re-Upload all failed files
+     */
+    reUploadAllClickHandler() {
+        const that = this;
+
+        // we need to make a copy and reset the queue or else our queue will run crazy
+        const errorFilesCopy = {...this.errorFiles};
+        this.errorFiles = [];
+        this.errorFilesCount = 0;
+
+        commonUtils.asyncObjectForEach(errorFilesCopy, async (file, id) => {
+            await this.fileQueueingClickHandler(file.file, id);
+        });
+
+        that._("#re-upload-all-button").stop();
+    }
+
+    /**
+     * Queues a failed pdf-file again
+     *
+     * @param file
+     * @param id
+     */
+    async fileQueueingClickHandler(file, id) {
+        this.takeFailedFileFromQueue(id);
+        return this.queueFile(file);
+    }
+
+    /**
+     * Shows the preview
+     *
+     * @param key
+     */
+    async showPreview(key) {
+        if (this.verificationProcessEnabled) {
+            return;
+        }
+
+        const file = this.getQueuedFile(key);
+        this.currentFile = file;
+        this.currentPreviewQueueKey = key;
+        console.log(file);
+        // start signature placement process
+        this.previewInProgress = true;
+        const previewTag = this.constructor.getScopedTagName("dbp-pdf-preview");
+        await this._(previewTag).showPDF(file);
+    }
+
+    /**
+     * Takes a failed file off of the queue
+     *
+     * @param key
+     */
+    takeFailedFileFromQueue(key) {
+        const file = this.errorFiles.splice(key, 1);
+        this.errorFilesCount = Object.keys(this.errorFiles).length;
+        return file;
+    }
+
+    clearVerifiedFiles() {
+        this.verifiedFiles = [];
+        this.verifiedFilesCount = 0;
+    }
+
+    clearErrorFiles() {
+        this.errorFiles = [];
+        this.errorFilesCount = 0;
+    }
+
+    isUserInterfaceDisabled() {
+        return this.previewInProgress || this.externalAuthInProgress || this.uploadInProgress;
+    }
+
+    static get styles() {
+        // language=css
+        return css`
+            ${commonStyles.getThemeCSS()}
+            ${commonStyles.getGeneralCSS(false)}
+            ${commonStyles.getButtonCSS()}
+            ${commonStyles.getNotificationCSS()}
+
+            #pdf-preview {
+                min-width: 320px;
+            }
+
+            h2:first-child {
+                margin-top: 0;
+            }
+
+            h2 {
+                margin-bottom: 10px;
+            }
+
+            strong {
+                font-weight: 600;
+            }
+
+            #pdf-preview .box-header {
+                border: 1px solid #000;
+                border-bottom-width: 0;
+                padding: 0.5em 0.5em 0 0.5em;
+            }
+
+            .hidden {
+                display: none;
+            }
+
+            .files-block.field:not(:last-child) {
+                margin-bottom: 40px;
+            }
+
+            .files-block .file {
+                margin: 10px 0;
+            }
+
+            .error-files .file {
+                display: grid;
+                grid-template-columns: 40px auto;
+            }
+
+            .files-block .file .button-box {
+                display: flex;
+                align-items: center;
+            }
+
+            .files-block .file .info {
+                display: inline-block;
+                vertical-align: middle;
+            }
+
+            .file .info strong {
+                font-weight: 600;
+            }
+
+            .notification dbp-mini-spinner {
+                position: relative;
+                top: 2px;
+                margin-right: 5px;
+            }
+
+            .error, #cancel-verification-process {
+                color: #e4154b;
+            }
+            
+            #cancel-verification-process:hover {
+                color: white;
+            }
+
+            /* using dbp-icon doesn't work */
+            button > [name=close], a > [name=close] {
+                font-size: 0.8em;
+            }
+
+            a > [name=close] {
+                color: red;
+            }
+
+            .empty-queue {
+                margin: 10px 0;
+            }
+
+            #grid-container {
+                display: flex;
+                flex-flow: row wrap;
+            }
+
+            #grid-container > div {
+                margin-right: 20px;
+            }
+
+            #grid-container > div:last-child {
+                margin-right: 0;
+                flex: 1 0;
+            }
+
+            .file-block {
+                max-width: 320px;
+            }
+
+            .file-block, .box {
+                border: solid 1px black;
+                padding: 10px;
+            }
+
+            .file-block, .box .file {
+                margin-top: 0;
+            }
+
+            .file-block {
+                margin-bottom: 10px;
+            }
+
+            .file-block .header {
+                display: grid;
+                align-items: center;
+                grid-template-columns: auto 40px;
+                grid-gap: 10px;
+            }
+
+            .file-block.error .header {
+                grid-template-columns: auto 80px;
+            }
+
+            .file-block.error .header .buttons {
+                white-space: nowrap;
+            }
+
+            .file-block div.bottom-line {
+                display: grid;
+                align-items: center;
+                grid-template-columns: auto 190px;
+                grid-gap: 10px;
+                margin-top: 10px;
+            }
+
+            .file-block.error div.bottom-line {
+                display: block;
+            }
+
+            .file-block div.bottom-line .headline {
+                text-align: right;
+            }
+
+            .file-block .filename, .file-block div.bottom-line .headline {
+                text-overflow: ellipsis;
+                overflow: hidden;
+            }
+
+            .file-block .filename {
+                white-space: nowrap;
+            }
+
+            #pdf-preview .button.is-cancel {
+                color: #e4154b;
+            }
+
+            .is-right {
+                float: right;
+            }
+
+            .error-files .header {
+                color: black;
+            }
+
+            /* prevent hovering of disabled default button */
+            .button[disabled]:not(.is-primary):hover {
+                background-color: inherit;
+                color: inherit;
+            }
+
+            .is-disabled, .is-disabled.button[disabled] {
+                opacity: 0.2;
+                pointer-events: none;
+            }
+
+            #pdf-preview .box-header {
+                display: flex;
+                justify-content: space-between;
+                align-items: start;
+            }
+
+            #pdf-preview .box-header .filename {
+                overflow: hidden;
+                text-overflow: ellipsis;
+                margin-right: 0.5em;
+            }
+
+            table.signatures {
+                margin-top: 10px;
+            }
+
+            .verified-files .file-block {
+                max-width: inherit;
+            }
+
+            .verification-ok {
+                background-color: #a4ffa4;
+            }
+            
+            #grid-container{
+                margin-top: 2rem;
+                padding-top: 2rem;
+            }
+            
+            .border{
+                border-top: 1px solid black;
+            }
+
+            /* Handling for small displays (like mobile devices) */
+            @media (max-width: 680px) {
+                /* Modal preview, upload and external auth */
+                div.right-container > * {
+                    position: fixed;
+                    padding: 10px;
+                    top: 0;
+                    left: 0;
+                    right: 0;
+                    bottom: 0;
+                    background-color: white;
+                    overflow-y: scroll;
+                }
+
+                /* Don't use the whole screen for the upload progress */
+                #upload-progress {
+                    top: 10px;
+                    left: 10px;
+                    right: 10px;
+                    bottom: inherit;
+                }
+
+                #grid-container > div {
+                    margin-right: 0;
+                    width: 100%;
+                }
+
+                .file-block {
+                    max-width: inherit;
+                }
+            }
+        `;
+    }
+
+    /**
+     * Returns the list of queued files
+     *
+     * @returns {*[]} Array of html templates
+     */
+    getQueuedFilesHtml() {
+        const ids = Object.keys(this.queuedFiles);
+        let results = [];
+
+        ids.forEach((id) => {
+            const file = this.queuedFiles[id];
+
+            results.push(html`
+                <div class="file-block">
+                    <div class="header">
+                        <span class="filename"><strong>${file.name}</strong> (${humanFileSize(file.size)})</span>
+                        <button class="button close"
+                            ?disabled="${this.verificationProcessEnabled}"
+                            title="${i18n.t('signature-verification.remove-queued-file-button-title')}"
+                            @click="${() => { this.takeFileFromQueue(id); }}">
+                            <dbp-icon name="trash"></dbp-icon></button>
+                    </div>
+                    <div class="bottom-line">
+                        <div></div>
+                        <button class="button"
+                            ?disabled="${this.verificationProcessEnabled}"
+                            @click="${() => { this.showPreview(id); }}">${i18n.t('signature-verification.show-preview')}</button>
+                    </div>
+                </div>
+            `);
+        });
+
+        return results;
+    }
+
+    /**
+     * Returns the list of successfully signed files
+     *
+     * @returns {*[]} Array of html templates
+     */
+    getVerifiedFilesHtml() {
+        const ids = Object.keys(this.verifiedFiles);
+        let results = [];
+
+        ids.forEach((id) => {
+            const report = this.verifiedFiles[id];
+            console.log("report", report);
+            let signatures = [];
+
+            report.signatures.forEach((signature) => {
+                console.log("signature", signature);
+
+                signatures.push(html`
+                    <tr>
+                        <td>${signature.givenName}</td>
+                        <td>${signature.familyName}</td>
+                        <td>${signature.nationality}</td>
+                        <td>${signature.serialNumber}</td>
+                        <td class="${classMap({"verification-ok": signature.valueMessage === "OK"})}">${signature.valueMessage}</td>
+                    </tr>
+                `);
+            });
+
+            results.push(html`
+                <div class="file-block">
+                    <div class="header">
+                        <span class="filename"><strong>${report.name}</strong></span>
+                    </div>
+                    <table class="signatures ${classMap({hidden: signatures.length === 0})}">
+                        <thead>
+                            <th>${i18n.t('signature-verification.given-name')}</th>
+                            <th>${i18n.t('signature-verification.last-name')}</th>
+                            <th>${i18n.t('signature-verification.nationality')}</th>
+                            <th>${i18n.t('signature-verification.serial-number')}</th>
+                            <th>${i18n.t('signature-verification.value-message')}</th>
+                        </thead>
+                        <tbody>
+                            ${signatures}
+                        </tbody>
+                    </table>
+                    <div class="${classMap({hidden: signatures.length !== 0})}">
+                        ${i18n.t('signature-verification.no-signatures-found')}
+                    </div>
+                </div>
+            `);
+        });
+
+        return results;
+    }
+
+    /**
+     * Returns the list of files of failed signature processes
+     *
+     * @returns {*[]} Array of html templates
+     */
+    getErrorFilesHtml() {
+        const ids = Object.keys(this.errorFiles);
+        let results = [];
+
+        ids.forEach((id) => {
+            const data = this.errorFiles[id];
+
+            results.push(html`
+                <div class="file-block error">
+                    <div class="header">
+                        <span class="filename"><strong>${data.file.name}</strong> (${humanFileSize(data.file.size)})</span>
+                        <div class="buttons">
+                            <button class="button"
+                                    title="${i18n.t('signature-verification.re-upload-file-button-title')}"
+                                    @click="${() => {this.fileQueueingClickHandler(data.file, id);}}"><dbp-icon name="reload"></dbp-icon></button>
+                            <button class="button"
+                                title="${i18n.t('signature-verification.remove-failed-file-button-title')}"
+                                @click="${() => { this.takeFailedFileFromQueue(id); }}">
+                                <dbp-icon name="trash"></dbp-icon></button>
+                        </div>
+                    </div>
+                    <div class="bottom-line">
+                        <strong class="error">${data.json["hydra:description"]}</strong>
+                    </div>
+                </div>
+            `);
+        });
+
+        return results;
+    }
+
+    hasSignaturePermissions() {
+        return this._hasSignaturePermissions('ROLE_SCOPE_OFFICIAL-SIGNATURE');
+    }
+
+    render() {
+        const placeholderUrl = commonUtils.getAssetURL('local/dbp-signature/official-signature-placeholder.png');
+
+        return html`
+            <div class="${classMap({hidden: !this.isLoggedIn() || !this.hasSignaturePermissions() || this.isLoading()})}">
+                <div class="field">
+                    <h2>${i18n.t('signature-verification.upload-field-label')}</h2>
+                    <div class="control">
+                        <p>
+                            ${i18n.t('qualified-pdf-upload.upload-text')}
+                        </p>
+                        <button @click="${() => { this._("#file-source").setAttribute("dialog-open", ""); }}"
+                                ?disabled="${this.signingProcessActive}"
+                                class="button is-primary">
+                            ${i18n.t('qualified-pdf-upload.upload-button-label')}
+                        </button>
+                        <dbp-file-source
+                            id="file-source"
+                            allowed-mime-types="application/pdf"
+                            enabled-sources="local${this.showTestNextcloudFilePicker ? ",nextcloud" : ""}"
+                            nextcloud-auth-url="${nextcloudWebAppPasswordURL}"
+                            nextcloud-web-dav-url="${nextcloudWebDavURL}"
+                            nextcloud-name="${nextcloudName}"
+                            decompress-zip
+                            lang="${this.lang}"
+                            ?disabled="${this.verificationProcessActive}"
+                            text="${i18n.t('signature-verification.upload-area-text')}"
+                            button-label="${i18n.t('signature-verification.upload-button-label')}"
+                            @dbp-file-source-file-selected="${this.onFileSelected}"
+                            ></dbp-file-source>
+                    </div>
+                </div>
+                <div id="grid-container" class="${classMap({"border": this.queueBlockEnabled})}">
+                    <div class="left-container">
+                        <div class="files-block field ${classMap({hidden: !this.queueBlockEnabled})}">
+                            <!-- Queued files headline and queueing spinner -->
+                            <h2 class="${classMap({"is-disabled": this.isUserInterfaceDisabled()})}">
+                                ${i18n.t('signature-verification.queued-files-label')}
+                            </h2>
+                            <!-- Buttons to start/stop verification process and clear queue -->
+                            <div class="control field">
+                                <button @click="${this.clearQueuedFiles}"
+                                        ?disabled="${this.queuedFilesCount === 0 || this.verificationProcessActive || this.isUserInterfaceDisabled()}"
+                                        class="button ${classMap({"is-disabled": this.isUserInterfaceDisabled()})}">
+                                    ${i18n.t('signature-verification.clear-all')}
+                                </button>
+                                <button @click="${() => { this.verificationProcessEnabled = true; this.verificationProcessActive = true; }}"
+                                        ?disabled="${this.queuedFilesCount === 0}"
+                                        class="button is-right is-primary ${classMap(
+                                            {
+                                                "is-disabled": this.isUserInterfaceDisabled(),
+                                                hidden: this.verificationProcessActive
+                                            })}">
+                                    ${i18n.t('signature-verification.start-verification-process-button')}
+                                </button>
+                                <!-- -->
+                                <button @click="${this.stopVerificationProcess}"
+                                        ?disabled="${this.uploadInProgress}"
+                                        id="cancel-verification-process"
+                                        class="button is-right ${classMap({hidden: !this.verificationProcessActive})}">
+                                    ${i18n.t('signature-verification.stop-verification-process-button')}
+                                </button>
+                                <!-- -->
+                            </div>
+                            <!-- List of queued files -->
+                            <div class="control file-list ${classMap({"is-disabled": this.isUserInterfaceDisabled()})}">
+                                ${this.getQueuedFilesHtml()}
+                            </div>
+                            <!-- Text "queue empty" -->
+                            <div class="empty-queue control ${classMap({hidden: this.queuedFilesCount !== 0, "is-disabled": this.isUserInterfaceDisabled()})}">
+                                ${i18n.t('signature-verification.queued-files-empty1')}<br />
+                                ${i18n.t('signature-verification.queued-files-empty2')}
+                            </div>
+                        </div>
+                        <!-- List of errored files -->
+                        <div class="files-block error-files field ${classMap({hidden: this.errorFilesCount === 0, "is-disabled": this.isUserInterfaceDisabled()})}">
+                            <h2>${i18n.t('signature-verification.error-files-label')}</h2>
+                            <!-- Button to upload errored files again -->
+                            <div class="field ${classMap({hidden: this.errorFilesCount === 0})}">
+                                <div class="control">
+                                    <button @click="${this.clearErrorFiles}"
+                                            class="button">
+                                        ${i18n.t('signature-verification.clear-all')}
+                                    </button>
+                                    <dbp-button id="re-upload-all-button"
+                                                ?disabled="${this.uploadInProgress}"
+                                                value="${i18n.t('signature-verification.re-upload-all-button')}"
+                                                title="${i18n.t('signature-verification.re-upload-all-button-title')}"
+                                                class="is-right"
+                                                @click="${this.reUploadAllClickHandler}"
+                                                type="is-primary"></dbp-button>
+                                </div>
+                            </div>
+                            <div class="control">
+                                ${this.getErrorFilesHtml()}
+                            </div>
+                        </div>
+                    </div>
+                    <div class="right-container">
+                        <!-- PDF preview -->
+                        <div id="pdf-preview" class="field ${classMap({hidden: !this.previewInProgress})}">
+                            <h2>${i18n.t('signature-verification.preview-label')}</h2>
+                            <div class="box-header">
+                                <div class="filename">
+                                    <strong>${this.currentFile.name}</strong> (${humanFileSize(this.currentFile !== undefined ? this.currentFile.size : 0)})
+                                </div>
+                                <button class="button is-cancel"
+                                    @click="${this.hidePDF}"><dbp-icon name="close"></dbp-icon></button>
+                            </div>
+                            <dbp-pdf-preview lang="${this.lang}"
+                                             signature-placeholder-image-src="${placeholderUrl}"
+                                             signature-width="146"
+                                             signature-height="42"
+                                             @dbp-pdf-preview-cancel="${this.hidePDF}"></dbp-pdf-preview>
+                        </div>
+                        <!-- File upload progress -->
+                        <div id="upload-progress" class="field notification is-info ${classMap({hidden: !this.uploadInProgress})}">
+                            <dbp-mini-spinner></dbp-mini-spinner>
+                            <strong>${this.uploadStatusFileName}</strong>
+                            ${this.uploadStatusText}
+                        </div>
+                    </div>
+                </div>
+                <!-- List of verified PDFs -->
+                <div class="verified-files files-block field ${classMap({hidden: this.verifiedFilesCount === 0, "is-disabled": this.isUserInterfaceDisabled()})}">
+                    <h2>${i18n.t('signature-verification.verified-files-label')}</h2>
+                    <!-- Button to clear verified PDFs -->
+                    <div class="field ${classMap({hidden: this.verifiedFilesCount === 0})}">
+                        <div class="control">
+                            <button @click="${this.clearVerifiedFiles}"
+                                    class="button">
+                                ${i18n.t('signature-verification.clear-all')}
+                            </button>
+                        </div>
+                    </div>
+                    <div class="control">
+                        ${this.getVerifiedFilesHtml()}
+                    </div>
+                </div>
+            </div>
+            <div class="notification is-warning ${classMap({hidden: this.isLoggedIn() || this.isLoading()})}">
+                ${i18n.t('error-login-message')}
+            </div>
+            <div class="notification is-danger ${classMap({hidden: this.hasSignaturePermissions() || !this.isLoggedIn() || this.isLoading()})}">
+                ${i18n.t('error-permission-message')}
+            </div>
+            <div class="${classMap({hidden: !this.isLoading()})}">
+                <dbp-mini-spinner></dbp-mini-spinner>
+            </div>
+        `;
+    }
+}
+
+commonUtils.defineCustomElement('dbp-signature-verification-full', SignatureVerificationFull);
diff --git a/src/dbp-signature-verification.js b/src/dbp-signature-verification.js
index fa85c0d18be1fc12f0c5c8a30aa51874aaabdac6..0f29b1ec63ef8d5a036df02fbd939e351c62bb08 100644
--- a/src/dbp-signature-verification.js
+++ b/src/dbp-signature-verification.js
@@ -1,18 +1,9 @@
 import {createI18nInstance} from './i18n.js';
-import {humanFileSize} from 'dbp-common/i18next.js';
 import {css, html} from 'lit-element';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
 import DBPSignatureLitElement from "./dbp-signature-lit-element";
-import {PdfPreview} from "./dbp-pdf-preview";
 import * as commonUtils from 'dbp-common/utils';
-import {Icon, MiniSpinner, Button} from 'dbp-common';
 import * as commonStyles from 'dbp-common/styles';
-import {classMap} from 'lit-html/directives/class-map.js';
-import {FileSource} from 'dbp-file-handling';
-import JSONLD from "dbp-common/jsonld";
-import nextcloudWebAppPasswordURL from 'consts:nextcloudWebAppPasswordURL';
-import nextcloudWebDavURL from 'consts:nextcloudWebDavURL';
-import nextcloudName from 'consts:nextcloudName';
 
 const i18n = createI18nInstance();
 
@@ -20,808 +11,63 @@ class SignatureVerification extends ScopedElementsMixin(DBPSignatureLitElement)
     constructor() {
         super();
         this.lang = i18n.language;
-        this.entryPointUrl = commonUtils.getAPiUrl();
-        this.verifiedFiles = [];
-        this.verifiedFilesCount = 0;
-        this.errorFiles = [];
-        this.errorFilesCount = 0;
-        this.uploadStatusFileName = "";
-        this.uploadStatusText = "";
-        this.currentFile = {};
-        this.currentFileName = "";
-        this.currentFilePlacementMode = "";
-        this.currentFileSignaturePlacement = {};
-        this.verificationProcessEnabled = false;
-        this.verificationProcessActive = false;
-        this.previewInProgress = false;
-        this.currentPreviewQueueKey = '';
-
-        // will be set in function update
-        this.verificationUrl = "";
     }
 
     static get scopedElements() {
-        return {
-            'dbp-icon': Icon,
-            'dbp-file-source': FileSource,
-            'dbp-pdf-preview': PdfPreview,
-            'dbp-mini-spinner': MiniSpinner,
-            'dbp-button': Button,
-        };
+        return { };
     }
 
     static get properties() {
         return {
             lang: { type: String },
-            entryPointUrl: { type: String, attribute: 'entry-point-url' },
-            verifiedFiles: { type: Array, attribute: false },
-            verifiedFilesCount: { type: Number, attribute: false },
-            queuedFilesCount: { type: Number, attribute: false },
-            errorFiles: { type: Array, attribute: false },
-            errorFilesCount: { type: Number, attribute: false },
-            uploadInProgress: { type: Boolean, attribute: false },
-            uploadStatusFileName: { type: String, attribute: false },
-            uploadStatusText: { type: String, attribute: false },
-            verificationProcessEnabled: { type: Boolean, attribute: false },
-            verificationProcessActive: { type: Boolean, attribute: false },
-            queueBlockEnabled: { type: Boolean, attribute: false },
-            currentFile: { type: Object, attribute: false },
-            currentFileName: { type: String, attribute: false },
-            previewInProgress: { type: Boolean, attribute: false },
-            isSignaturePlacement: { type: Boolean, attribute: false },
         };
     }
 
-    connectedCallback() {
-        super.connectedCallback();
-        // needs to be called in a function to get the variable scope of "this"
-        setInterval(() => { this.handleQueuedFiles(); }, 1000);
-    }
-
-    /**
-     * Processes queued files
-     */
-    async handleQueuedFiles() {
-        this.endVerificationProcessIfQueueEmpty();
-        if (this.queuedFilesCount === 0) {
-            // reset verificationProcessEnabled button
-            this.verificationProcessEnabled = false;
-            return;
-        }
-
-        if (!this.verificationProcessEnabled || this.uploadInProgress) {
-            return;
-        }
-
-        this.previewInProgress = false;
-
-        const key = Object.keys(this.queuedFiles)[0];
-
-        // take the file off the queue
-        let file = this.takeFileFromQueue(key);
-        this.currentFile = file;
-
-        this.uploadInProgress = true;
-        let params = {};
-
-        this.uploadStatusText = i18n.t('signature-verification.upload-status-file-text', {
-            fileName: file.name,
-            fileSize: humanFileSize(file.size, false),
-        });
-
-        await this.uploadFile(file, params);
-        this.uploadInProgress = false;
-    }
-
-    /**
-     * Called when preview is "canceled"
-     *
-     * @param event
-     */
-    hidePDF(event) {
-        this.previewInProgress = false;
-    }
-
-    /**
-     * Decides if the "beforeunload" event needs to be canceled
-     *
-     * @param event
-     */
-    onReceiveBeforeUnload(event) {
-        // we don't need to stop if there are no signed files
-        if (this.verifiedFilesCount === 0) {
-            return;
-        }
-
-        // we need to handle custom events ourselves
-        if (!event.isTrusted) {
-            // note that this only works with custom event since calls of "confirm" are ignored
-            // in the non-custom event, see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
-            const result = confirm(i18n.t('signature-verification.confirm-page-leave'));
-
-            // don't stop the page leave if the user wants to leave
-            if (result) {
-                return;
-            }
-        }
-
-        // Cancel the event as stated by the standard
-        event.preventDefault();
-
-        // Chrome requires returnValue to be set
-        event.returnValue = '';
-    }
-
-    endVerificationProcessIfQueueEmpty() {
-        if (this.queuedFilesCount === 0 && this.verificationProcessActive) {
-            this.verificationProcessActive = false;
-        }
-    }
-
-    /**
-     * @param ev
-     */
-    onFileSelected(ev) {
-        console.log("File was selected: ev", ev);
-        this.queueFile(ev.detail.file);
-    }
-
-    addToErrorFiles(file) {
-        this.endVerificationProcessIfQueueEmpty();
-
-        // this doesn't seem to trigger an update() execution
-        this.errorFiles[Math.floor(Math.random() * 1000000)] = file;
-        // this triggers the correct update() execution
-        this.errorFilesCount++;
-
-        if (window._paq !== undefined) {
-            window._paq.push(['trackEvent', 'officiallyVerification', 'VerificationFailed', file.json["hydra:description"]]);
-        }
-    }
-
-    /**
-     * @param data
-     */
-    onFileUploadFinished(data) {
-        if (data.status !== 201) {
-            this.addToErrorFiles(data);
-        } else if (data.json["@type"] === "https://schema.tugraz.at/ElectronicSignatureVerificationReport" ) {
-            // this doesn't seem to trigger an update() execution
-            this.verifiedFiles.push(data.json);
-            // this triggers the correct update() execution
-            this.verifiedFilesCount++;
-            const entryPoint = data.json;
-            this.currentFileName = entryPoint.name;
-            this.endVerificationProcessIfQueueEmpty();
-        }
-    }
-
     update(changedProperties) {
         changedProperties.forEach((oldValue, propName) => {
             switch (propName) {
                 case "lang":
                     i18n.changeLanguage(this.lang);
                     break;
-                case "entryPointUrl":
-                    JSONLD.initialize(this.entryPointUrl, (jsonld) => {
-                        const apiUrlBase = jsonld.getApiUrlForEntityName("ElectronicSignatureVerificationReport");
-                        this.fileSourceUrl = apiUrlBase + "/create";
-                    });
-                    break;
             }
-
-            // console.log(propName, oldValue);
         });
 
         super.update(changedProperties);
     }
 
-    onLanguageChanged(e) {
-        this.lang = e.detail.lang;
-    }
-
-    /**
-     * Re-Upload all failed files
-     */
-    reUploadAllClickHandler() {
-        const that = this;
-
-        // we need to make a copy and reset the queue or else our queue will run crazy
-        const errorFilesCopy = {...this.errorFiles};
-        this.errorFiles = [];
-        this.errorFilesCount = 0;
-
-        commonUtils.asyncObjectForEach(errorFilesCopy, async (file, id) => {
-            await this.fileQueueingClickHandler(file.file, id);
-        });
-
-        that._("#re-upload-all-button").stop();
-    }
-
-    /**
-     * Queues a failed pdf-file again
-     *
-     * @param file
-     * @param id
-     */
-    async fileQueueingClickHandler(file, id) {
-        this.takeFailedFileFromQueue(id);
-        return this.queueFile(file);
-    }
-
-    /**
-     * Shows the preview
-     *
-     * @param key
-     */
-    async showPreview(key) {
-        if (this.verificationProcessEnabled) {
-            return;
-        }
-
-        const file = this.getQueuedFile(key);
-        this.currentFile = file;
-        this.currentPreviewQueueKey = key;
-        console.log(file);
-        // start signature placement process
-        this.previewInProgress = true;
-        const previewTag = this.constructor.getScopedTagName("dbp-pdf-preview");
-        await this._(previewTag).showPDF(file);
-    }
-
-    /**
-     * Takes a failed file off of the queue
-     *
-     * @param key
-     */
-    takeFailedFileFromQueue(key) {
-        const file = this.errorFiles.splice(key, 1);
-        this.errorFilesCount = Object.keys(this.errorFiles).length;
-        return file;
-    }
-
-    clearVerifiedFiles() {
-        this.verifiedFiles = [];
-        this.verifiedFilesCount = 0;
-    }
-
-    clearErrorFiles() {
-        this.errorFiles = [];
-        this.errorFilesCount = 0;
-    }
-
-    isUserInterfaceDisabled() {
-        return this.previewInProgress || this.externalAuthInProgress || this.uploadInProgress;
-    }
-
     static get styles() {
         // language=css
         return css`
             ${commonStyles.getThemeCSS()}
             ${commonStyles.getGeneralCSS(false)}
-            ${commonStyles.getButtonCSS()}
-            ${commonStyles.getNotificationCSS()}
-
-            #pdf-preview {
-                min-width: 320px;
-            }
-
-            h2:first-child {
-                margin-top: 0;
-            }
-
-            h2 {
-                margin-bottom: 10px;
-            }
-
-            strong {
-                font-weight: 600;
-            }
-
-            #pdf-preview .box-header {
-                border: 1px solid #000;
-                border-bottom-width: 0;
-                padding: 0.5em 0.5em 0 0.5em;
-            }
-
-            .hidden {
-                display: none;
-            }
-
-            .files-block.field:not(:last-child) {
-                margin-bottom: 40px;
-            }
-
-            .files-block .file {
-                margin: 10px 0;
-            }
-
-            .error-files .file {
-                display: grid;
-                grid-template-columns: 40px auto;
-            }
-
-            .files-block .file .button-box {
-                display: flex;
-                align-items: center;
-            }
-
-            .files-block .file .info {
-                display: inline-block;
-                vertical-align: middle;
-            }
-
-            .file .info strong {
-                font-weight: 600;
-            }
 
-            .notification dbp-mini-spinner {
-                position: relative;
-                top: 2px;
-                margin-right: 5px;
+            a {
+                border-bottom: 1px solid rgba(0,0,0,0.3);
+                padding: 0;
             }
 
-            .error, #cancel-verification-process {
-                color: #e4154b;
-            }
-            
-            #cancel-verification-process:hover {
-                color: white;
-            }
-
-            /* using dbp-icon doesn't work */
-            button > [name=close], a > [name=close] {
-                font-size: 0.8em;
-            }
-
-            a > [name=close] {
-                color: red;
-            }
-
-            .empty-queue {
-                margin: 10px 0;
-            }
-
-            #grid-container {
-                display: flex;
-                flex-flow: row wrap;
-            }
-
-            #grid-container > div {
-                margin-right: 20px;
+            a:hover {
+                color: #fff;
+                background-color: #000;
             }
 
-            #grid-container > div:last-child {
-                margin-right: 0;
-                flex: 1 0;
-            }
-
-            .file-block {
-                max-width: 320px;
-            }
-
-            .file-block, .box {
-                border: solid 1px black;
-                padding: 10px;
-            }
-
-            .file-block, .box .file {
+            h2:first-child {
                 margin-top: 0;
             }
 
-            .file-block {
+            h2 {
                 margin-bottom: 10px;
             }
-
-            .file-block .header {
-                display: grid;
-                align-items: center;
-                grid-template-columns: auto 40px;
-                grid-gap: 10px;
-            }
-
-            .file-block.error .header {
-                grid-template-columns: auto 80px;
-            }
-
-            .file-block.error .header .buttons {
-                white-space: nowrap;
-            }
-
-            .file-block div.bottom-line {
-                display: grid;
-                align-items: center;
-                grid-template-columns: auto 190px;
-                grid-gap: 10px;
-                margin-top: 10px;
-            }
-
-            .file-block.error div.bottom-line {
-                display: block;
-            }
-
-            .file-block div.bottom-line .headline {
-                text-align: right;
-            }
-
-            .file-block .filename, .file-block div.bottom-line .headline {
-                text-overflow: ellipsis;
-                overflow: hidden;
-            }
-
-            .file-block .filename {
-                white-space: nowrap;
-            }
-
-            #pdf-preview .button.is-cancel {
-                color: #e4154b;
-            }
-
-            .is-right {
-                float: right;
-            }
-
-            .error-files .header {
-                color: black;
-            }
-
-            /* prevent hovering of disabled default button */
-            .button[disabled]:not(.is-primary):hover {
-                background-color: inherit;
-                color: inherit;
-            }
-
-            .is-disabled, .is-disabled.button[disabled] {
-                opacity: 0.2;
-                pointer-events: none;
-            }
-
-            #pdf-preview .box-header {
-                display: flex;
-                justify-content: space-between;
-                align-items: start;
-            }
-
-            #pdf-preview .box-header .filename {
-                overflow: hidden;
-                text-overflow: ellipsis;
-                margin-right: 0.5em;
-            }
-
-            table.signatures {
-                margin-top: 10px;
-            }
-
-            .verified-files .file-block {
-                max-width: inherit;
-            }
-
-            .verification-ok {
-                background-color: #a4ffa4;
-            }
-            
-            #grid-container{
-                margin-top: 2rem;
-                padding-top: 2rem;
-            }
-            
-            .border{
-                border-top: 1px solid black;
-            }
-
-            /* Handling for small displays (like mobile devices) */
-            @media (max-width: 680px) {
-                /* Modal preview, upload and external auth */
-                div.right-container > * {
-                    position: fixed;
-                    padding: 10px;
-                    top: 0;
-                    left: 0;
-                    right: 0;
-                    bottom: 0;
-                    background-color: white;
-                    overflow-y: scroll;
-                }
-
-                /* Don't use the whole screen for the upload progress */
-                #upload-progress {
-                    top: 10px;
-                    left: 10px;
-                    right: 10px;
-                    bottom: inherit;
-                }
-
-                #grid-container > div {
-                    margin-right: 0;
-                    width: 100%;
-                }
-
-                .file-block {
-                    max-width: inherit;
-                }
-            }
         `;
     }
 
-    /**
-     * Returns the list of queued files
-     *
-     * @returns {*[]} Array of html templates
-     */
-    getQueuedFilesHtml() {
-        const ids = Object.keys(this.queuedFiles);
-        let results = [];
-
-        ids.forEach((id) => {
-            const file = this.queuedFiles[id];
-
-            results.push(html`
-                <div class="file-block">
-                    <div class="header">
-                        <span class="filename"><strong>${file.name}</strong> (${humanFileSize(file.size)})</span>
-                        <button class="button close"
-                            ?disabled="${this.verificationProcessEnabled}"
-                            title="${i18n.t('signature-verification.remove-queued-file-button-title')}"
-                            @click="${() => { this.takeFileFromQueue(id); }}">
-                            <dbp-icon name="trash"></dbp-icon></button>
-                    </div>
-                    <div class="bottom-line">
-                        <div></div>
-                        <button class="button"
-                            ?disabled="${this.verificationProcessEnabled}"
-                            @click="${() => { this.showPreview(id); }}">${i18n.t('signature-verification.show-preview')}</button>
-                    </div>
-                </div>
-            `);
-        });
-
-        return results;
-    }
-
-    /**
-     * Returns the list of successfully signed files
-     *
-     * @returns {*[]} Array of html templates
-     */
-    getVerifiedFilesHtml() {
-        const ids = Object.keys(this.verifiedFiles);
-        let results = [];
-
-        ids.forEach((id) => {
-            const report = this.verifiedFiles[id];
-            console.log("report", report);
-            let signatures = [];
-
-            report.signatures.forEach((signature) => {
-                console.log("signature", signature);
-
-                signatures.push(html`
-                    <tr>
-                        <td>${signature.givenName}</td>
-                        <td>${signature.familyName}</td>
-                        <td>${signature.nationality}</td>
-                        <td>${signature.serialNumber}</td>
-                        <td class="${classMap({"verification-ok": signature.valueMessage === "OK"})}">${signature.valueMessage}</td>
-                    </tr>
-                `);
-            });
-
-            results.push(html`
-                <div class="file-block">
-                    <div class="header">
-                        <span class="filename"><strong>${report.name}</strong></span>
-                    </div>
-                    <table class="signatures ${classMap({hidden: signatures.length === 0})}">
-                        <thead>
-                            <th>${i18n.t('signature-verification.given-name')}</th>
-                            <th>${i18n.t('signature-verification.last-name')}</th>
-                            <th>${i18n.t('signature-verification.nationality')}</th>
-                            <th>${i18n.t('signature-verification.serial-number')}</th>
-                            <th>${i18n.t('signature-verification.value-message')}</th>
-                        </thead>
-                        <tbody>
-                            ${signatures}
-                        </tbody>
-                    </table>
-                    <div class="${classMap({hidden: signatures.length !== 0})}">
-                        ${i18n.t('signature-verification.no-signatures-found')}
-                    </div>
-                </div>
-            `);
-        });
-
-        return results;
-    }
-
-    /**
-     * Returns the list of files of failed signature processes
-     *
-     * @returns {*[]} Array of html templates
-     */
-    getErrorFilesHtml() {
-        const ids = Object.keys(this.errorFiles);
-        let results = [];
-
-        ids.forEach((id) => {
-            const data = this.errorFiles[id];
-
-            results.push(html`
-                <div class="file-block error">
-                    <div class="header">
-                        <span class="filename"><strong>${data.file.name}</strong> (${humanFileSize(data.file.size)})</span>
-                        <div class="buttons">
-                            <button class="button"
-                                    title="${i18n.t('signature-verification.re-upload-file-button-title')}"
-                                    @click="${() => {this.fileQueueingClickHandler(data.file, id);}}"><dbp-icon name="reload"></dbp-icon></button>
-                            <button class="button"
-                                title="${i18n.t('signature-verification.remove-failed-file-button-title')}"
-                                @click="${() => { this.takeFailedFileFromQueue(id); }}">
-                                <dbp-icon name="trash"></dbp-icon></button>
-                        </div>
-                    </div>
-                    <div class="bottom-line">
-                        <strong class="error">${data.json["hydra:description"]}</strong>
-                    </div>
-                </div>
-            `);
-        });
-
-        return results;
-    }
-
-    hasSignaturePermissions() {
-        return this._hasSignaturePermissions('ROLE_SCOPE_OFFICIAL-SIGNATURE');
-    }
-
     render() {
-        const placeholderUrl = commonUtils.getAssetURL('local/dbp-signature/official-signature-placeholder.png');
-
         return html`
-            <div class="${classMap({hidden: !this.isLoggedIn() || !this.hasSignaturePermissions() || this.isLoading()})}">
-                <div class="field">
-                    <h2>${i18n.t('signature-verification.upload-field-label')}</h2>
-                    <div class="control">
-                        <p>
-                            ${i18n.t('qualified-pdf-upload.upload-text')}
-                        </p>
-                        <button @click="${() => { this._("#file-source").setAttribute("dialog-open", ""); }}"
-                                ?disabled="${this.signingProcessActive}"
-                                class="button is-primary">
-                            ${i18n.t('qualified-pdf-upload.upload-button-label')}
-                        </button>
-                        <dbp-file-source
-                            id="file-source"
-                            allowed-mime-types="application/pdf"
-                            enabled-sources="local${this.showTestNextcloudFilePicker ? ",nextcloud" : ""}"
-                            nextcloud-auth-url="${nextcloudWebAppPasswordURL}"
-                            nextcloud-web-dav-url="${nextcloudWebDavURL}"
-                            nextcloud-name="${nextcloudName}"
-                            decompress-zip
-                            lang="${this.lang}"
-                            ?disabled="${this.verificationProcessActive}"
-                            text="${i18n.t('signature-verification.upload-area-text')}"
-                            button-label="${i18n.t('signature-verification.upload-button-label')}"
-                            @dbp-file-source-file-selected="${this.onFileSelected}"
-                            ></dbp-file-source>
-                    </div>
-                </div>
-                <div id="grid-container" class="${classMap({"border": this.queueBlockEnabled})}">
-                    <div class="left-container">
-                        <div class="files-block field ${classMap({hidden: !this.queueBlockEnabled})}">
-                            <!-- Queued files headline and queueing spinner -->
-                            <h2 class="${classMap({"is-disabled": this.isUserInterfaceDisabled()})}">
-                                ${i18n.t('signature-verification.queued-files-label')}
-                            </h2>
-                            <!-- Buttons to start/stop verification process and clear queue -->
-                            <div class="control field">
-                                <button @click="${this.clearQueuedFiles}"
-                                        ?disabled="${this.queuedFilesCount === 0 || this.verificationProcessActive || this.isUserInterfaceDisabled()}"
-                                        class="button ${classMap({"is-disabled": this.isUserInterfaceDisabled()})}">
-                                    ${i18n.t('signature-verification.clear-all')}
-                                </button>
-                                <button @click="${() => { this.verificationProcessEnabled = true; this.verificationProcessActive = true; }}"
-                                        ?disabled="${this.queuedFilesCount === 0}"
-                                        class="button is-right is-primary ${classMap(
-                                            {
-                                                "is-disabled": this.isUserInterfaceDisabled(),
-                                                hidden: this.verificationProcessActive
-                                            })}">
-                                    ${i18n.t('signature-verification.start-verification-process-button')}
-                                </button>
-                                <!-- -->
-                                <button @click="${this.stopVerificationProcess}"
-                                        ?disabled="${this.uploadInProgress}"
-                                        id="cancel-verification-process"
-                                        class="button is-right ${classMap({hidden: !this.verificationProcessActive})}">
-                                    ${i18n.t('signature-verification.stop-verification-process-button')}
-                                </button>
-                                <!-- -->
-                            </div>
-                            <!-- List of queued files -->
-                            <div class="control file-list ${classMap({"is-disabled": this.isUserInterfaceDisabled()})}">
-                                ${this.getQueuedFilesHtml()}
-                            </div>
-                            <!-- Text "queue empty" -->
-                            <div class="empty-queue control ${classMap({hidden: this.queuedFilesCount !== 0, "is-disabled": this.isUserInterfaceDisabled()})}">
-                                ${i18n.t('signature-verification.queued-files-empty1')}<br />
-                                ${i18n.t('signature-verification.queued-files-empty2')}
-                            </div>
-                        </div>
-                        <!-- List of errored files -->
-                        <div class="files-block error-files field ${classMap({hidden: this.errorFilesCount === 0, "is-disabled": this.isUserInterfaceDisabled()})}">
-                            <h2>${i18n.t('signature-verification.error-files-label')}</h2>
-                            <!-- Button to upload errored files again -->
-                            <div class="field ${classMap({hidden: this.errorFilesCount === 0})}">
-                                <div class="control">
-                                    <button @click="${this.clearErrorFiles}"
-                                            class="button">
-                                        ${i18n.t('signature-verification.clear-all')}
-                                    </button>
-                                    <dbp-button id="re-upload-all-button"
-                                                ?disabled="${this.uploadInProgress}"
-                                                value="${i18n.t('signature-verification.re-upload-all-button')}"
-                                                title="${i18n.t('signature-verification.re-upload-all-button-title')}"
-                                                class="is-right"
-                                                @click="${this.reUploadAllClickHandler}"
-                                                type="is-primary"></dbp-button>
-                                </div>
-                            </div>
-                            <div class="control">
-                                ${this.getErrorFilesHtml()}
-                            </div>
-                        </div>
-                    </div>
-                    <div class="right-container">
-                        <!-- PDF preview -->
-                        <div id="pdf-preview" class="field ${classMap({hidden: !this.previewInProgress})}">
-                            <h2>${i18n.t('signature-verification.preview-label')}</h2>
-                            <div class="box-header">
-                                <div class="filename">
-                                    <strong>${this.currentFile.name}</strong> (${humanFileSize(this.currentFile !== undefined ? this.currentFile.size : 0)})
-                                </div>
-                                <button class="button is-cancel"
-                                    @click="${this.hidePDF}"><dbp-icon name="close"></dbp-icon></button>
-                            </div>
-                            <dbp-pdf-preview lang="${this.lang}"
-                                             signature-placeholder-image-src="${placeholderUrl}"
-                                             signature-width="146"
-                                             signature-height="42"
-                                             @dbp-pdf-preview-cancel="${this.hidePDF}"></dbp-pdf-preview>
-                        </div>
-                        <!-- File upload progress -->
-                        <div id="upload-progress" class="field notification is-info ${classMap({hidden: !this.uploadInProgress})}">
-                            <dbp-mini-spinner></dbp-mini-spinner>
-                            <strong>${this.uploadStatusFileName}</strong>
-                            ${this.uploadStatusText}
-                        </div>
-                    </div>
-                </div>
-                <!-- List of verified PDFs -->
-                <div class="verified-files files-block field ${classMap({hidden: this.verifiedFilesCount === 0, "is-disabled": this.isUserInterfaceDisabled()})}">
-                    <h2>${i18n.t('signature-verification.verified-files-label')}</h2>
-                    <!-- Button to clear verified PDFs -->
-                    <div class="field ${classMap({hidden: this.verifiedFilesCount === 0})}">
-                        <div class="control">
-                            <button @click="${this.clearVerifiedFiles}"
-                                    class="button">
-                                ${i18n.t('signature-verification.clear-all')}
-                            </button>
-                        </div>
-                    </div>
-                    <div class="control">
-                        ${this.getVerifiedFilesHtml()}
-                    </div>
-                </div>
-            </div>
-            <div class="notification is-warning ${classMap({hidden: this.isLoggedIn() || this.isLoading()})}">
-                ${i18n.t('error-login-message')}
-            </div>
-            <div class="notification is-danger ${classMap({hidden: this.hasSignaturePermissions() || !this.isLoggedIn() || this.isLoading()})}">
-                ${i18n.t('error-permission-message')}
-            </div>
-            <div class="${classMap({hidden: !this.isLoading()})}">
-                <dbp-mini-spinner></dbp-mini-spinner>
-            </div>
+            <h2>${i18n.t('signature-verification-extern.headline')}</h2>
+            <p>
+                ${i18n.t('signature-verification-extern.description-text')}
+            </p>
+            <a target="_blank" rel="noopener" href="https://www.signatur.rtr.at/${this.lang}/vd/Pruefung">${i18n.t('signature-verification-extern.link-label')}</a>.
         `;
     }
 }
diff --git a/src/i18n/de/translation.json b/src/i18n/de/translation.json
index 6442e1d8e0178bd872599fe938d89c7aa5d86df9..b1813db56e99e847307c8100cc5b474015f2da5c 100644
--- a/src/i18n/de/translation.json
+++ b/src/i18n/de/translation.json
@@ -77,7 +77,7 @@
     "remove-failed-file-button-title": "Fehlgeschlagenes Dokument entfernen",
     "remove-queued-file-button-title": "Dokument aus der Warteschlange entfernen",
     "clear-all": "Alle entfernen",
-    "start-verification-process-button": "Verifikations starten",
+    "start-verification-process-button": "Verifikation starten",
     "stop-verification-process-button": "Verifikation unterbrechen",
     "show-preview": "Dokument anzeigen",
     "preview-label": "Dokumentenansicht",
@@ -87,7 +87,7 @@
     "re-upload-file-button-title": "Erneut in die Warteschlange stellen",
     "upload-status-file-text": "({{fileSize}}) wird hochgeladen und verifiziert...",
     "re-upload-all-button": "Alle wiederholen",
-    "re-upload-all-button-title": "Alle fehlgeschlagen Verifikationsprozesse erneut in die Warteschlange stellen",
+    "re-upload-all-button-title": "Alle fehlgeschlagenen Verifikationsprozesse erneut in die Warteschlange stellen",
     "given-name": "Vorname",
     "last-name": "Nachname",
     "nationality": "Nationalität",
@@ -96,6 +96,11 @@
     "no-signatures-found": "Es wurden keine Signaturen gefunden.",
     "confirm-page-leave": "Sind Sie sicher, dass Sie die Seite verlassen wollen? Es stehen signierte Dokumente zum Download bereit."
   },
+  "signature-verification-extern": {
+    "headline": "Signierte Dokumente verifizieren",
+    "description-text": "Um eine PDF-Signatur auf ihre Gültigkeit zu überprüfen, benutzen Sie bitte das Verifikationsservice der Rundfunk und Telekom Regulierungs-GmbH. Mit diesem Verifikationsservice können Sie überprüfen, dass das Dokument nicht verändert wurde, welcher Teil des PDFs signiert wurde und von wem.",
+    "link-label": "Zum RTR Verifikationsservice wechseln"
+  },
   "pdf-preview": {
     "first-page": "Erste Seite",
     "previous-page": "Vorherige Seite",
diff --git a/src/i18n/en/translation.json b/src/i18n/en/translation.json
index 1360f51b4c231d03d4cb5fa9b6ccbad5e239463b..281d0f3a14e4edb166f21c740d20d4cc5c6d67a1 100644
--- a/src/i18n/en/translation.json
+++ b/src/i18n/en/translation.json
@@ -95,6 +95,11 @@
     "no-signatures-found": "No signatures were found.",
     "confirm-page-leave": "Are you sure you want to leave this page? There are still signed documents ready to be downloaded."
   },
+  "signature-verification-extern": {
+    "headline": "Verify signed Documents",
+    "description-text": "To check a PDF signature for validity, please use the verification service of the Rundfunk und Telekom Regulierungs-GmbH. With this verification service you can check that the document has not been modified, which part of the PDF has been signed and by whom.",
+    "link-label": "Switch to the RTR verification service"
+  },
   "pdf-preview": {
     "first-page": "First page",
     "previous-page": "Previous page",