Add Fortify auth, Flux dark mode, demo seed, and Docker hot reload.

Protect recordings per user, seed a demo login on container start, and bind-mount the app with Vite HMR for local Compose development.
This commit is contained in:
ben
2026-08-12 18:38:53 +02:00
parent accb721811
commit bfcfc12f58
78 changed files with 3942 additions and 186 deletions
+20 -11
View File
@@ -3,15 +3,15 @@
*/
const BADGE_CLASSES = {
done: 'bg-teal-50 text-teal-800 ring-teal-600/20',
processing: 'bg-amber-50 text-amber-800 ring-amber-600/20',
pending: 'bg-amber-50 text-amber-800 ring-amber-600/20',
failed: 'bg-red-50 text-red-800 ring-red-600/20',
cancelled: 'bg-stone-100 text-stone-700 ring-stone-500/20',
done: 'bg-teal-50 text-teal-800 ring-teal-600/20 dark:bg-teal-950 dark:text-teal-200 dark:ring-teal-400/30',
processing: 'bg-amber-50 text-amber-800 ring-amber-600/20 dark:bg-amber-950 dark:text-amber-200 dark:ring-amber-400/30',
pending: 'bg-amber-50 text-amber-800 ring-amber-600/20 dark:bg-amber-950 dark:text-amber-200 dark:ring-amber-400/30',
failed: 'bg-red-50 text-red-800 ring-red-600/20 dark:bg-red-950 dark:text-red-200 dark:ring-red-400/30',
cancelled: 'bg-stone-100 text-stone-700 ring-stone-500/20 dark:bg-zinc-800 dark:text-zinc-300 dark:ring-zinc-500/30',
};
export function badgeClassFor(status) {
return BADGE_CLASSES[status] || 'bg-stone-100 text-stone-700 ring-stone-500/20';
return BADGE_CLASSES[status] || 'bg-stone-100 text-stone-700 ring-stone-500/20 dark:bg-zinc-800 dark:text-zinc-300 dark:ring-zinc-500/30';
}
export function formatElapsed(seconds) {
@@ -56,17 +56,26 @@ function formatWordCount(count) {
return n > 0 ? n.toLocaleString() : '—';
}
function subscribeToRecordings(handler) {
function subscribeToRecording(recordingId, handler) {
if (!window.Echo) {
return () => {};
}
const channel = window.Echo.channel('recordings');
const channelName = 'recording.' + recordingId;
const channel = window.Echo.private(channelName);
channel.listen('.RecordingTranscriptionUpdated', handler);
return () => {
window.Echo.leave('recordings');
window.Echo.leave(channelName);
};
}
function subscribeToRecordings(recordingIds, handler) {
const leaveFns = recordingIds.map((id) => subscribeToRecording(id, handler));
return () => {
leaveFns.forEach((leave) => leave());
};
}
@@ -94,7 +103,7 @@ export function transcriptionMonitor({ statusUrl, initial }) {
},
start() {
this.leaveChannel = subscribeToRecordings((event) => {
this.leaveChannel = subscribeToRecording(this.status.id, (event) => {
if (Number(event.id) !== Number(this.status.id)) {
return;
}
@@ -202,7 +211,7 @@ export function recordingsIndex({ recordings, pendingCount }) {
leaveChannel: null,
start() {
this.leaveChannel = subscribeToRecordings((event) => {
this.leaveChannel = subscribeToRecordings(Object.keys(this.rows), (event) => {
this.applyPayload(event);
});
},