Task #737: fix reversed ص/م (AM/PM) in Arabic booking time ranges

- Root cause: time-range containers forced dir="ltr" while the strings mix
  Latin digits with Arabic ص/م, so the bidi algorithm flipped the segments
  (showed "م - 1:30 م 12:30" instead of "12:30 م – 1:30 م").
- artifacts/tx-os/src/pages/protocol.tsx:
  - fmtTimeOnly now uses "ar-u-nu-latn" in Arabic (Latin digits kept) and
    is rendered in the natural RTL flow.
  - Removed dir="ltr" from: bookings list time cell, day-grid booking block
    time, and details dialog time range.
- fmtSlotRange / fmtSlotLabel callsites already use locale-aware dir (rtl
  in Arabic) — unchanged. English display unchanged.
- tsc clean; architect review passed.
This commit is contained in:
Replit Agent
2026-07-09 09:36:45 +00:00
parent 9e3200e2de
commit a1acbc8017
+8 -4
View File
@@ -621,7 +621,7 @@ function BookingDayGrid({
{roomName(ev.b.roomId)}
</div>
{height >= 44 && (
<div className="truncate opacity-70" dir="ltr">
<div className="truncate opacity-70">
{timeLabel(ev.b.startsAt)} {timeLabel(ev.b.endsAt)}
</div>
)}
@@ -1024,8 +1024,12 @@ export default function ProtocolPage() {
new Date(iso).toLocaleDateString(isAr ? "ar" : "en", {
dateStyle: "medium",
});
// Latin digits even in Arabic (ar-u-nu-latn) so times look like "12:30 م".
// Rendered inside RTL containers WITHOUT dir="ltr": forcing LTR on text
// that mixes Latin digits with Arabic ص/م makes the bidi algorithm flip
// the order (e.g. "م 1:30 م 12:30").
const fmtTimeOnly = (iso: string) =>
new Date(iso).toLocaleTimeString(isAr ? "ar" : "en", {
new Date(iso).toLocaleTimeString(isAr ? "ar-u-nu-latn" : "en", {
timeStyle: "short",
});
@@ -1096,7 +1100,7 @@ export default function ProtocolPage() {
<TableCell className="whitespace-nowrap text-center align-middle text-slate-600">
<div className="flex flex-col items-center gap-0.5 leading-tight">
<div>{fmtDateOnly(b.startsAt)}</div>
<div className="text-xs text-slate-400" dir="ltr">
<div className="text-xs text-slate-400">
{fmtTimeOnly(b.startsAt)} {fmtTimeOnly(b.endsAt)}
</div>
</div>
@@ -2320,7 +2324,7 @@ export default function ProtocolPage() {
<DetailRow
label={t("protocol.bookings.details.time")}
value={
<span dir="ltr">
<span>
{fmtTimeOnly(detailsBooking.startsAt)} {" "}
{fmtTimeOnly(detailsBooking.endsAt)}
</span>