Improve the appearance and usability of the postpone meeting dialog
Refactor the `PostponeDialog` component to enhance its visual design and user experience, including updated styling for dialog content, headers, tab strips, date/time inputs, and minute chips. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 339e1165-8b3c-4554-ae1b-989743df7fbc Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/IO8TMSC Replit-Helium-Checkpoint-Created: true
This commit is contained in:
@@ -1445,18 +1445,18 @@ function PostponeDialog({
|
||||
<DialogContent
|
||||
dir={isRtl ? "rtl" : "ltr"}
|
||||
data-testid="postpone-dialog"
|
||||
className="sm:max-w-2xl"
|
||||
className="max-w-[min(100%,560px)] sm:max-w-xl md:max-w-2xl bg-white rounded-2xl sm:rounded-3xl shadow-2xl ring-1 ring-slate-200 border-0 p-5 sm:p-6 gap-3"
|
||||
>
|
||||
{/* #563: reserve pr-8 (~2rem) so the Radix close button
|
||||
(positioned right-4 top-4 inside DialogContent) never
|
||||
overlaps the title/description. Physical right padding is
|
||||
correct for BOTH AR (RTL) and LTR because Radix uses CSS
|
||||
physical positioning for the close. */}
|
||||
<DialogHeader className="space-y-1 pr-8">
|
||||
<DialogTitle className="text-base">
|
||||
<DialogHeader className="space-y-1 pr-8 pb-3 border-b border-slate-200">
|
||||
<DialogTitle className="text-lg sm:text-xl text-[#0B1E3F]">
|
||||
{t("executiveMeetings.alert.postponeTitle")}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="truncate text-xs">
|
||||
<DialogDescription className="truncate text-xs sm:text-sm text-slate-600">
|
||||
{t("executiveMeetings.alert.postponeIntro", { title: titleText })}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -1506,7 +1506,7 @@ function PostponeDialog({
|
||||
aria-label={t("executiveMeetings.alert.postponeTitle")}
|
||||
aria-orientation="horizontal"
|
||||
onKeyDown={onTabKeyDown}
|
||||
className="grid grid-cols-3 rounded-md border bg-muted p-0.5 text-xs"
|
||||
className="grid grid-cols-3 rounded-xl border border-slate-200 bg-slate-100 p-1 text-xs sm:text-sm"
|
||||
>
|
||||
{tabs.map((tab) => {
|
||||
const selected = activeTab === tab.key;
|
||||
@@ -1524,10 +1524,10 @@ function PostponeDialog({
|
||||
disabled={busy !== null}
|
||||
onClick={() => switchTab(tab.key)}
|
||||
data-testid={`postpone-tab-${tab.key}`}
|
||||
className={`rounded px-2 py-1.5 font-medium transition-colors ${
|
||||
className={`rounded-lg px-3 py-2 font-semibold transition-colors ${
|
||||
selected
|
||||
? "bg-background text-foreground shadow-sm"
|
||||
: "text-muted-foreground hover:text-foreground"
|
||||
? "bg-white text-[#0B1E3F] shadow ring-1 ring-slate-200"
|
||||
: "text-slate-600 hover:text-[#0B1E3F]"
|
||||
}`}
|
||||
>
|
||||
{t(`executiveMeetings.alert.${tab.labelKey}`)}
|
||||
@@ -1643,7 +1643,7 @@ function PostponeDialog({
|
||||
requestPostpone(n);
|
||||
}}
|
||||
data-testid={`postpone-chip-${n}`}
|
||||
className="h-7 px-2 text-xs"
|
||||
className="h-10 min-w-11 px-3 text-sm rounded-xl border-2"
|
||||
>
|
||||
{n}
|
||||
</Button>
|
||||
@@ -1661,7 +1661,7 @@ function PostponeDialog({
|
||||
)}
|
||||
disabled={noTimeWindow || busy !== null}
|
||||
data-testid="postpone-minutes-input"
|
||||
className="w-24"
|
||||
className="w-24 min-h-11 bg-white border-2 border-slate-300 rounded-xl text-base"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
@@ -1674,6 +1674,7 @@ function PostponeDialog({
|
||||
Number(minutes) <= 0
|
||||
}
|
||||
data-testid="postpone-minutes-apply"
|
||||
className="min-h-11 rounded-xl px-4"
|
||||
>
|
||||
{t("executiveMeetings.alert.postponeMinutesApply", {
|
||||
count: Number(minutes) || 0,
|
||||
@@ -1772,8 +1773,8 @@ function PostponeDialog({
|
||||
inputs respect their cell, and `w-full` on the Input
|
||||
ensures it fills the cell. */}
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-1 min-w-0">
|
||||
<Label className="text-xs">
|
||||
<div className="space-y-1.5 min-w-0">
|
||||
<Label className="text-xs sm:text-sm font-semibold text-slate-700">
|
||||
{t("executiveMeetings.alert.rescheduleDate")}
|
||||
</Label>
|
||||
<Input
|
||||
@@ -1782,7 +1783,7 @@ function PostponeDialog({
|
||||
onChange={(e) => setResDate(e.target.value)}
|
||||
disabled={busy !== null}
|
||||
data-testid="reschedule-date"
|
||||
className="w-full"
|
||||
className="w-full min-h-11 bg-white border-2 border-slate-300 rounded-xl text-base"
|
||||
/>
|
||||
</div>
|
||||
{/* #606: iOS Safari renders <input type="time"> with its
|
||||
@@ -1794,8 +1795,8 @@ function PostponeDialog({
|
||||
thicker border + min-h gives each iOS pill its own
|
||||
clearly-bounded box so the two never collide. */}
|
||||
<div className="grid grid-cols-2 gap-4 sm:gap-6">
|
||||
<div className="space-y-1 min-w-0">
|
||||
<Label className="text-xs">
|
||||
<div className="space-y-1.5 min-w-0">
|
||||
<Label className="text-xs sm:text-sm font-semibold text-slate-700">
|
||||
{t("executiveMeetings.alert.rescheduleStart")}
|
||||
</Label>
|
||||
<Input
|
||||
@@ -1804,11 +1805,11 @@ function PostponeDialog({
|
||||
onChange={(e) => setResStart(e.target.value)}
|
||||
disabled={busy !== null}
|
||||
data-testid="reschedule-start"
|
||||
className="w-full min-h-11 bg-background border-2"
|
||||
className="w-full min-h-11 bg-white border-2 border-slate-300 rounded-xl text-base"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1 min-w-0">
|
||||
<Label className="text-xs">
|
||||
<div className="space-y-1.5 min-w-0">
|
||||
<Label className="text-xs sm:text-sm font-semibold text-slate-700">
|
||||
{t("executiveMeetings.alert.rescheduleEnd")}
|
||||
</Label>
|
||||
<Input
|
||||
@@ -1817,7 +1818,7 @@ function PostponeDialog({
|
||||
onChange={(e) => setResEnd(e.target.value)}
|
||||
disabled={busy !== null}
|
||||
data-testid="reschedule-end"
|
||||
className="w-full min-h-11 bg-background border-2"
|
||||
className="w-full min-h-11 bg-white border-2 border-slate-300 rounded-xl text-base"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1829,6 +1830,7 @@ function PostponeDialog({
|
||||
disabled={busy !== null}
|
||||
rows={2}
|
||||
data-testid="reschedule-note"
|
||||
className="w-full bg-white border-2 border-slate-300 rounded-xl text-base"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
@@ -1836,6 +1838,7 @@ function PostponeDialog({
|
||||
onClick={onReschedule}
|
||||
disabled={busy !== null || !resDate || !resStart || !resEnd}
|
||||
data-testid="reschedule-apply"
|
||||
className="min-h-11 rounded-xl px-5"
|
||||
>
|
||||
{t("executiveMeetings.alert.rescheduleApply")}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user