feat: mobile Responsiveness für Suche und Mail-Detailansicht
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -168,11 +168,12 @@ function MailBodyView({ mail }: { mail: MailDetail }) {
|
||||
<div className="space-y-2">
|
||||
{!showExternal && (
|
||||
<Alert>
|
||||
<AlertDescription className="flex items-center justify-between gap-4 text-sm">
|
||||
<AlertDescription className="flex flex-col items-start gap-2 text-sm sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<span>Externe Inhalte (Bilder, Tracker) sind blockiert.</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="w-full sm:w-auto"
|
||||
onClick={() => setShowExternal(true)}
|
||||
>
|
||||
Externe Inhalte laden
|
||||
@@ -346,8 +347,8 @@ export default function MailViewPage({
|
||||
</Button>
|
||||
|
||||
{mail && (
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant="outline" className="font-mono text-xs">
|
||||
<div className="flex w-full flex-wrap items-center gap-2 sm:w-auto">
|
||||
<Badge variant="outline" className="max-w-[40vw] truncate font-mono text-xs sm:max-w-none">
|
||||
{id}
|
||||
</Badge>
|
||||
<Button
|
||||
|
||||
+19
-13
@@ -383,18 +383,18 @@ export default function SearchPage() {
|
||||
{/* Main content */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div className="flex gap-2">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Input
|
||||
placeholder="Volltextsuche..."
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
className="flex-1"
|
||||
className="w-full flex-1 sm:w-auto"
|
||||
aria-label="Suchbegriff"
|
||||
/>
|
||||
<Button type="submit" disabled={searching}>
|
||||
<Button type="submit" disabled={searching} className="flex-1 sm:flex-none">
|
||||
{searching ? "Suche..." : "Suchen"}
|
||||
</Button>
|
||||
<Button type="button" variant="outline" onClick={() => setUploadOpen(true)}>
|
||||
<Button type="button" variant="outline" onClick={() => setUploadOpen(true)} className="flex-1 sm:flex-none">
|
||||
Importieren
|
||||
</Button>
|
||||
{hasActiveSearch && (
|
||||
@@ -596,7 +596,7 @@ export default function SearchPage() {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<Card className="overflow-x-auto">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
@@ -610,12 +610,12 @@ export default function SearchPage() {
|
||||
aria-label="Alle auswählen"
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead className="w-32">Datum</TableHead>
|
||||
<TableHead className="w-56">Von</TableHead>
|
||||
<TableHead className="w-28 sm:w-32">Datum</TableHead>
|
||||
<TableHead className="hidden w-56 md:table-cell">Von</TableHead>
|
||||
<TableHead>Betreff</TableHead>
|
||||
<TableHead className="w-48">An</TableHead>
|
||||
<TableHead className="hidden w-48 lg:table-cell">An</TableHead>
|
||||
<TableHead className="w-8 text-center" title="Anhang">📎</TableHead>
|
||||
<TableHead className="w-20 text-right">Größe</TableHead>
|
||||
<TableHead className="hidden w-20 text-right sm:table-cell">Größe</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
@@ -650,8 +650,8 @@ export default function SearchPage() {
|
||||
? new Date(hit.date).toLocaleString("de-DE", { dateStyle: "short", timeStyle: "short" })
|
||||
: "-"}
|
||||
</TableCell>
|
||||
<TableCell className="max-w-[14rem] truncate text-sm">{hit.from || "-"}</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
<TableCell className="hidden max-w-[14rem] truncate text-sm md:table-cell">{hit.from || "-"}</TableCell>
|
||||
<TableCell className="max-w-[60vw] font-medium sm:max-w-none">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="truncate">{hit.subject || "(kein Betreff)"}</span>
|
||||
{hit.thread_size && hit.thread_size > 1 && (
|
||||
@@ -660,13 +660,19 @@ export default function SearchPage() {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{/* Absender nur auf Mobile, da Spalte "Von" dort ausgeblendet ist */}
|
||||
{hit.from && (
|
||||
<div className="mt-0.5 truncate text-xs text-muted-foreground md:hidden">
|
||||
{hit.from}
|
||||
</div>
|
||||
)}
|
||||
<SnippetLine hit={hit} />
|
||||
</TableCell>
|
||||
<TableCell className="max-w-[12rem] truncate text-sm text-muted-foreground">{hit.to || "-"}</TableCell>
|
||||
<TableCell className="hidden max-w-[12rem] truncate text-sm text-muted-foreground lg:table-cell">{hit.to || "-"}</TableCell>
|
||||
<TableCell className="text-center text-sm">
|
||||
{hit.has_attachments ? "📎" : ""}
|
||||
</TableCell>
|
||||
<TableCell className="text-right text-xs text-muted-foreground whitespace-nowrap">
|
||||
<TableCell className="hidden text-right text-xs text-muted-foreground whitespace-nowrap sm:table-cell">
|
||||
{hit.size ? formatBytes(hit.size) : ""}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
Reference in New Issue
Block a user