feat: mobile-responsive mail plugin UI
This commit is contained in:
@@ -91,7 +91,7 @@ export function MailDetail({
|
||||
return (
|
||||
<div className="flex flex-col h-full" data-testid="mail-detail">
|
||||
{/* Toolbar */}
|
||||
<div className="flex items-center gap-2 px-4 py-3 border-b border-secondary-200" data-testid="mail-detail-toolbar">
|
||||
<div className="flex items-center gap-1 sm:gap-2 px-3 py-2 md:px-4 md:py-3 border-b border-secondary-200 overflow-x-auto" data-testid="mail-detail-toolbar">
|
||||
<Button variant="secondary" size="sm" onClick={() => onReply(mail)} icon={
|
||||
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
|
||||
@@ -135,9 +135,9 @@ export function MailDetail({
|
||||
</div>
|
||||
|
||||
{/* Headers */}
|
||||
<div className="px-4 py-3 border-b border-secondary-200" data-testid="mail-detail-headers">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<h2 className="text-lg font-semibold text-secondary-900 flex-1">{mail.subject || t('mail.noSubject')}</h2>
|
||||
<div className="px-3 py-2 md:px-4 md:py-3 border-b border-secondary-200" data-testid="mail-detail-headers">
|
||||
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-2 sm:gap-4">
|
||||
<h2 className="text-base md:text-lg font-semibold text-secondary-900 flex-1">{mail.subject || t('mail.noSubject')}</h2>
|
||||
{mail.labels && mail.labels.length > 0 && (
|
||||
<div className="flex gap-1 flex-shrink-0">
|
||||
{mail.labels.map((label) => (
|
||||
@@ -148,30 +148,30 @@ export function MailDetail({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-2 space-y-1 text-sm text-secondary-600">
|
||||
<div className="flex gap-2">
|
||||
<span className="font-medium text-secondary-500">{t('mail.from')}:</span>
|
||||
<span>{mail.from_name ? `${mail.from_name} <${mail.from_address}>` : mail.from_address}</span>
|
||||
<div className="mt-2 space-y-1 text-xs md:text-sm text-secondary-600">
|
||||
<div className="flex flex-col sm:flex-row sm:gap-2">
|
||||
<span className="font-medium text-secondary-500 flex-shrink-0">{t('mail.from')}:</span>
|
||||
<span className="break-words">{mail.from_name ? `${mail.from_name} <${mail.from_address}>` : mail.from_address}</span>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<span className="font-medium text-secondary-500">{t('mail.to')}:</span>
|
||||
<span>{mail.to_addresses.join(', ')}</span>
|
||||
<div className="flex flex-col sm:flex-row sm:gap-2">
|
||||
<span className="font-medium text-secondary-500 flex-shrink-0">{t('mail.to')}:</span>
|
||||
<span className="break-words">{mail.to_addresses.join(', ')}</span>
|
||||
</div>
|
||||
{mail.cc_addresses.length > 0 && (
|
||||
<div className="flex gap-2">
|
||||
<span className="font-medium text-secondary-500">{t('mail.cc')}:</span>
|
||||
<span>{mail.cc_addresses.join(', ')}</span>
|
||||
<div className="flex flex-col sm:flex-row sm:gap-2">
|
||||
<span className="font-medium text-secondary-500 flex-shrink-0">{t('mail.cc')}:</span>
|
||||
<span className="break-words">{mail.cc_addresses.join(', ')}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex gap-2">
|
||||
<span className="font-medium text-secondary-500">{t('mail.date')}:</span>
|
||||
<div className="flex flex-col sm:flex-row sm:gap-2">
|
||||
<span className="font-medium text-secondary-500 flex-shrink-0">{t('mail.date')}:</span>
|
||||
<span>{formatFullDate(mail.date)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Body */}
|
||||
<div className="flex-1 overflow-y-auto px-4 py-4" data-testid="mail-detail-body">
|
||||
<div className="flex-1 overflow-y-auto px-3 py-3 md:px-4 md:py-4" data-testid="mail-detail-body">
|
||||
{safeHtml && isSafe ? (
|
||||
<div
|
||||
className="prose prose-sm max-w-none text-secondary-800"
|
||||
@@ -190,9 +190,9 @@ export function MailDetail({
|
||||
|
||||
{/* Attachments */}
|
||||
{mail.attachments && mail.attachments.length > 0 && (
|
||||
<div className="px-4 py-3 border-t border-secondary-200" data-testid="mail-detail-attachments">
|
||||
<div className="px-3 py-2 md:px-4 md:py-3 border-t border-secondary-200" data-testid="mail-detail-attachments">
|
||||
<h3 className="text-sm font-semibold text-secondary-700 mb-2">{t('mail.attachments')}</h3>
|
||||
<ul className="space-y-2">
|
||||
<ul className="space-y-1 md:space-y-2">
|
||||
{mail.attachments.map((att) => (
|
||||
<li key={att.id} className="flex items-center gap-3 p-2 rounded-md hover:bg-secondary-50 min-h-touch">
|
||||
<svg className="w-5 h-5 text-secondary-400 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
||||
|
||||
Reference in New Issue
Block a user