improvement: rtl direction, solar calendar and persian formatting added for persian users.
This commit is contained in:
@@ -247,7 +247,7 @@ export function CaseDetailPanel({
|
||||
onAssignTask(task.id, e.target.value ? e.target.value : null)
|
||||
}
|
||||
aria-label={t('assigneeLabel')}
|
||||
className={`${FORM_SELECT_CLASS} max-w-[9.5rem] rounded-md px-2 py-0.5 text-xs`}
|
||||
className={`${FORM_SELECT_CLASS} max-w-[9.5rem] rounded-md py-0.5 text-xs`}
|
||||
>
|
||||
<option value="">{t('assigneeUnassigned')}</option>
|
||||
{assignableStaff.map((staff) => (
|
||||
|
||||
@@ -25,6 +25,7 @@ import { Button } from '@/components/ui/shared/Button';
|
||||
import { MobileDetailBackButton } from '@/components/ui/shared/MobileDetailBackButton';
|
||||
import { FORM_SELECT_CLASS } from '@/components/shared/formSelectStyles';
|
||||
import { SearchBar } from '@/components/ui/shared/SearchBar';
|
||||
import { AppDateInput } from '@/components/ui/shared/AppDateInput';
|
||||
import type { TreatmentCatalogEntry } from '@/types/treatment-catalog';
|
||||
import type {
|
||||
AssignableTaskStaff,
|
||||
@@ -267,7 +268,7 @@ export function CasesPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const filterSelectClass = `${FORM_SELECT_CLASS} w-full rounded-md px-3 py-2`;
|
||||
const filterSelectClass = `${FORM_SELECT_CLASS} w-full min-w-0 rounded-md py-1.5 text-xs sm:py-2 sm:text-sm`;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
@@ -333,11 +334,10 @@ export function CasesPage() {
|
||||
|
||||
<label className="space-y-1">
|
||||
<span className="text-xs font-medium text-text-muted">{t('filterSentFrom')}</span>
|
||||
<input
|
||||
type="date"
|
||||
<AppDateInput
|
||||
value={sentFrom}
|
||||
onChange={(e) => {
|
||||
setSentFrom(e.target.value);
|
||||
onChange={(next) => {
|
||||
setSentFrom(next);
|
||||
setPage(1);
|
||||
}}
|
||||
className={filterSelectClass}
|
||||
@@ -346,11 +346,10 @@ export function CasesPage() {
|
||||
|
||||
<label className="space-y-1">
|
||||
<span className="text-xs font-medium text-text-muted">{t('filterSentTo')}</span>
|
||||
<input
|
||||
type="date"
|
||||
<AppDateInput
|
||||
value={sentTo}
|
||||
onChange={(e) => {
|
||||
setSentTo(e.target.value);
|
||||
onChange={(next) => {
|
||||
setSentTo(next);
|
||||
setPage(1);
|
||||
}}
|
||||
className={filterSelectClass}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Badge } from '@/components/ui/shared/Badge';
|
||||
import { LabCaseDueDateBadge } from '@/components/lab/LabCaseDueDateBadge';
|
||||
import type { CaseTaskGroup } from '@/components/lab/taskListGrouping';
|
||||
import { countCaseTaskProgress } from '@/components/lab/taskListGrouping';
|
||||
import { formatAppDate, APP_DATE } from '@/lib/i18n/format';
|
||||
|
||||
function formatPatientName(patient: { firstName: string; lastName: string }) {
|
||||
return `${patient.firstName} ${patient.lastName}`.trim();
|
||||
@@ -20,11 +21,7 @@ export function TaskCaseGroupHeader({ caseGroup, locale }: TaskCaseGroupHeaderPr
|
||||
const progress = countCaseTaskProgress(caseGroup);
|
||||
|
||||
const sentLabel = caseGroup.caseSentAt
|
||||
? new Intl.DateTimeFormat(locale, {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
}).format(new Date(caseGroup.caseSentAt))
|
||||
? formatAppDate(caseGroup.caseSentAt, locale, APP_DATE.short)
|
||||
: null;
|
||||
|
||||
return (
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
labTaskStatusVariant,
|
||||
} from '@/components/lab/labTaskStatusDisplay';
|
||||
import { LabCaseDueDateBadge } from '@/components/lab/LabCaseDueDateBadge';
|
||||
import { formatAppDate, APP_DATE } from '@/lib/i18n/format';
|
||||
import { notifyTabBadgesChanged } from '@/lib/tabBadgeUtils';
|
||||
import {
|
||||
formatToothList,
|
||||
@@ -64,11 +65,7 @@ export function TaskRow({
|
||||
const canEditStatus = canEditLabTaskStatus(task, currentUserId, canEdit);
|
||||
const assignedToOther =
|
||||
Boolean(task.assignee) && task.assignee!.id !== currentUserId;
|
||||
const taskDate = new Intl.DateTimeFormat(locale, {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
}).format(new Date(task.createdAt));
|
||||
const taskDate = formatAppDate(task.createdAt, locale, APP_DATE.short);
|
||||
|
||||
const rowClassName = [
|
||||
flatMode ? undefined : 'border-b border-border/40 last:border-b-0',
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { Button } from '@/components/ui/shared/Button';
|
||||
import { Checkbox } from '@/components/ui/shared/Checkbox';
|
||||
import { FORM_SELECT_CLASS } from '@/components/shared/formSelectStyles';
|
||||
import { FORM_SELECT_CLASS, FORM_SELECT_COMPACT_CLASS } from '@/components/shared/formSelectStyles';
|
||||
import { SearchBar } from '@/components/ui/shared/SearchBar';
|
||||
import { TaskCaseGroupHeader } from '@/components/ui/lab/TaskCaseGroupHeader';
|
||||
import { TaskProsthesisGroupHeader } from '@/components/ui/lab/TaskProsthesisGroupHeader';
|
||||
@@ -286,7 +286,7 @@ export function TasksPage() {
|
||||
[canEdit, loadTasks, setError, showError, showSuccess, statusFilter, t, tErrors],
|
||||
);
|
||||
|
||||
const filterSelectClass = `${FORM_SELECT_CLASS} w-full min-h-[44px] rounded-md px-2 py-2 text-base sm:min-h-0 sm:py-1.5 sm:text-sm`;
|
||||
const filterSelectClass = `${FORM_SELECT_CLASS} w-full min-w-0 rounded-md py-1.5 text-xs sm:py-2 sm:text-sm`;
|
||||
|
||||
const sortHintKey = useMemo(() => {
|
||||
switch (sortBy) {
|
||||
@@ -366,7 +366,8 @@ export function TasksPage() {
|
||||
onChange={(v) => applyFilterChange(() => setSearch(v))}
|
||||
placeholder={t('searchPlaceholder')}
|
||||
/>
|
||||
<div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<div className="overflow-x-auto">
|
||||
<div className="grid min-w-[44rem] grid-cols-4 gap-2">
|
||||
<label className="space-y-1">
|
||||
<span className="text-xs text-text-muted">{t('filterClinic')}</span>
|
||||
<select
|
||||
@@ -411,16 +412,16 @@ export function TasksPage() {
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<label className="space-y-1">
|
||||
<label className="space-y-1 min-w-0">
|
||||
<span className="text-xs text-text-muted">{t('sortBy')}</span>
|
||||
<div className="flex gap-1.5">
|
||||
<div className="grid grid-cols-[minmax(0,1fr)_auto] gap-1">
|
||||
<select
|
||||
value={sortBy}
|
||||
onChange={(e) => {
|
||||
setSortBy(e.target.value as TaskSortField);
|
||||
clearFocus();
|
||||
}}
|
||||
className={`${filterSelectClass} min-w-0 flex-1`}
|
||||
className={`${filterSelectClass} min-w-0`}
|
||||
>
|
||||
<option value="date">{t('sortDate')}</option>
|
||||
<option value="dueDate">{t('sortDueDate')}</option>
|
||||
@@ -432,7 +433,7 @@ export function TasksPage() {
|
||||
<select
|
||||
value={sortDir}
|
||||
onChange={(e) => setSortDir(e.target.value as 'asc' | 'desc')}
|
||||
className={`${FORM_SELECT_CLASS} w-14 shrink-0 rounded-md px-2 py-1.5 text-sm`}
|
||||
className={`${FORM_SELECT_COMPACT_CLASS} w-11 shrink-0 rounded-md py-1.5 text-sm`}
|
||||
aria-label={t('sortDirection')}
|
||||
>
|
||||
<option value="desc">↓</option>
|
||||
@@ -440,6 +441,7 @@ export function TasksPage() {
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-x-4 gap-y-2">
|
||||
<Checkbox
|
||||
|
||||
Reference in New Issue
Block a user