diff --git a/backend/package-lock.json b/backend/package-lock.json
index 8730dd5..5d66d88 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "ripster-backend",
- "version": "0.10.2-4",
+ "version": "0.10.2-5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster-backend",
- "version": "0.10.2-4",
+ "version": "0.10.2-5",
"dependencies": {
"archiver": "^7.0.1",
"cors": "^2.8.5",
diff --git a/backend/package.json b/backend/package.json
index 3914de6..25c265e 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -1,6 +1,6 @@
{
"name": "ripster-backend",
- "version": "0.10.2-4",
+ "version": "0.10.2-5",
"private": true,
"type": "commonjs",
"scripts": {
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 3e7ee29..d63a6a2 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "ripster-frontend",
- "version": "0.10.2-4",
+ "version": "0.10.2-5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster-frontend",
- "version": "0.10.2-4",
+ "version": "0.10.2-5",
"dependencies": {
"primeicons": "^7.0.0",
"primereact": "^10.9.2",
diff --git a/frontend/package.json b/frontend/package.json
index d31fe0a..8ffabba 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "ripster-frontend",
- "version": "0.10.2-4",
+ "version": "0.10.2-5",
"private": true,
"type": "module",
"scripts": {
diff --git a/frontend/src/pages/DashboardPage.jsx b/frontend/src/pages/DashboardPage.jsx
index 04cca14..81e5fe4 100644
--- a/frontend/src/pages/DashboardPage.jsx
+++ b/frontend/src/pages/DashboardPage.jsx
@@ -6,6 +6,7 @@ import { Button } from 'primereact/button';
import { Tag } from 'primereact/tag';
import { ProgressBar } from 'primereact/progressbar';
import { Dialog } from 'primereact/dialog';
+import { FileUpload } from 'primereact/fileupload';
import { InputNumber } from 'primereact/inputnumber';
import { InputText } from 'primereact/inputtext';
import { api } from '../api/client';
@@ -864,6 +865,7 @@ export default function DashboardPage({
const [queueCatalog, setQueueCatalog] = useState({ scripts: [], chains: [] });
const [insertWaitSeconds, setInsertWaitSeconds] = useState(30);
const toastRef = useRef(null);
+ const audiobookFileUploadRef = useRef(null);
const state = String(pipeline?.state || 'IDLE').trim().toUpperCase();
const currentPipelineJobId = normalizeJobId(pipeline?.activeJobId || pipeline?.context?.jobId);
@@ -2060,13 +2062,8 @@ export default function DashboardPage({
-
+
-
-
@@ -2494,27 +2491,57 @@ export default function DashboardPage({
-
- {
- const nextFile = event.target?.files?.[0] || null;
- setAudiobookUploadFile(nextFile);
- }}
- disabled={audiobookUploadBusy}
- />
-
+ setAudiobookUploadFile(e.files[0] || null)}
+ onClear={() => setAudiobookUploadFile(null)}
+ onRemove={() => setAudiobookUploadFile(null)}
+ chooseLabel="Auswählen"
+ chooseOptions={{ icon: 'pi pi-folder-open' }}
+ cancelOptions={{ icon: 'pi pi-times', className: 'p-button-outlined p-button-secondary' }}
+ headerTemplate={(options) => (
+
+ {options.chooseButton}
+ {options.cancelButton}
+
+ )}
+ itemTemplate={(file, options) => (
+
+
+
+ {file.name}
+ {options.formatSize}
+
+
+ )}
+ emptyTemplate={() => (
+
+
+
AAX-Datei hier ablegen
+
oder oben „Auswählen" klicken
+
+ )}
+ />
{audiobookUploadPhase !== 'idle' ? (
@@ -2542,11 +2569,6 @@ export default function DashboardPage({
) : null}
-
- {audiobookUploadFileName && audiobookUploadPhase === 'idle'
- ? `Ausgewählt: ${audiobookUploadFileName}`
- : 'Unterstützt im MVP: AAX-Upload. Danach erscheint ein eigener Audiobook-Startschritt mit Format- und Qualitätswahl.'}
-
diff --git a/frontend/src/styles/app.css b/frontend/src/styles/app.css
index 719f4bd..c7190ed 100644
--- a/frontend/src/styles/app.css
+++ b/frontend/src/styles/app.css
@@ -683,7 +683,7 @@ body {
.pipeline-queue-grid {
display: grid;
- grid-template-columns: repeat(2, minmax(0, 1fr));
+ grid-template-columns: minmax(0, 1fr);
gap: 0.75rem;
}
@@ -1112,6 +1112,70 @@ body {
white-space: normal;
}
+.aax-upload-header {
+ display: flex;
+ gap: 0.5rem;
+ padding: 0.5rem 0.75rem;
+ border-bottom: 1px solid var(--rip-border);
+ background: var(--rip-panel-soft);
+ border-radius: 0.5rem 0.5rem 0 0;
+}
+
+.aax-drop-zone {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 0.35rem;
+ padding: 2rem 1rem;
+ text-align: center;
+ color: var(--rip-muted);
+}
+
+.aax-drop-zone p {
+ margin: 0;
+ font-size: 0.95rem;
+}
+
+.aax-drop-zone small {
+ font-size: 0.8rem;
+}
+
+.aax-drop-icon {
+ font-size: 2.2rem;
+ color: var(--rip-gold-400);
+}
+
+.aax-file-item {
+ display: flex;
+ align-items: center;
+ gap: 0.65rem;
+ padding: 0.6rem 0.75rem;
+ border-top: 1px solid var(--rip-border);
+}
+
+.aax-file-icon {
+ font-size: 1.4rem;
+ color: var(--rip-brown-600);
+ flex-shrink: 0;
+}
+
+.aax-file-info {
+ display: flex;
+ flex-direction: column;
+ gap: 0.1rem;
+ min-width: 0;
+ flex: 1;
+}
+
+.aax-file-name {
+ font-size: 0.875rem;
+ font-weight: 600;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
.audiobook-upload-status {
margin-top: 0.8rem;
padding: 0.7rem 0.8rem;
diff --git a/package-lock.json b/package-lock.json
index b2f605c..b788389 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "ripster",
- "version": "0.10.2-4",
+ "version": "0.10.2-5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster",
- "version": "0.10.2-4",
+ "version": "0.10.2-5",
"devDependencies": {
"concurrently": "^9.1.2"
}
diff --git a/package.json b/package.json
index b0751e0..c99f797 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "ripster",
"private": true,
- "version": "0.10.2-4",
+ "version": "0.10.2-5",
"scripts": {
"dev": "concurrently \"npm run dev --prefix backend\" \"npm run dev --prefix frontend\"",
"dev:backend": "npm run dev --prefix backend",