feat(aether): initial commit – self-hosted Cloud, Phasen 1–7
Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA. Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb, Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming, Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office (Collabora/OnlyOffice). Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort) sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
commit
31a027c93a
225 files changed
+38042
No files matched your search
@@ -0,0 +1,57 @@
|
||||
interface UploadItem {
|
||||
id: string
|
||||
name: string
|
||||
progress: number // 0-100
|
||||
status: 'uploading' | 'done' | 'error'
|
||||
error?: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
items: UploadItem[]
|
||||
onDismiss: (id: string) => void
|
||||
}
|
||||
|
||||
export type { UploadItem }
|
||||
|
||||
export default function UploadQueue({ items, onDismiss }: Props) {
|
||||
if (items.length === 0) return null
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-4 right-4 w-72 space-y-2 z-40">
|
||||
{items.map(item => (
|
||||
<div
|
||||
key={item.id}
|
||||
className="rounded-xl p-3 text-sm shadow-lg border"
|
||||
style={{ background: 'var(--color-surface)', borderColor: 'var(--color-border)' }}>
|
||||
<div className="flex items-center justify-between mb-1.5">
|
||||
<span className="truncate font-medium text-xs" style={{ color: 'var(--color-text)', maxWidth: 180 }}>
|
||||
{item.name}
|
||||
</span>
|
||||
{item.status !== 'uploading' && (
|
||||
<button onClick={() => onDismiss(item.id)}
|
||||
className="ml-2 opacity-50 hover:opacity-100 text-xs shrink-0"
|
||||
style={{ color: 'var(--color-text-muted)' }}>✕</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{item.status === 'uploading' && (
|
||||
<div className="h-1.5 rounded-full overflow-hidden" style={{ background: 'var(--color-surface-2)' }}>
|
||||
<div
|
||||
className="h-full rounded-full transition-all"
|
||||
style={{
|
||||
width: `${item.progress}%`,
|
||||
background: 'linear-gradient(90deg, var(--color-primary), var(--color-accent))',
|
||||
}} />
|
||||
</div>
|
||||
)}
|
||||
{item.status === 'done' && (
|
||||
<p style={{ color: 'var(--color-success)' }} className="text-xs">✓ Uploaded</p>
|
||||
)}
|
||||
{item.status === 'error' && (
|
||||
<p style={{ color: 'var(--color-danger)' }} className="text-xs truncate">✕ {item.error}</p>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user