feature: localization's first implmentation done. all frontend hardcoded text is now localized.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import type { AppointmentColumnProvider, AppointmentRecord } from '@/types/appointment';
|
||||
import {
|
||||
SCHEDULE_SLOT_MINUTES,
|
||||
@@ -91,6 +92,7 @@ export function AppointmentScheduleGrid({
|
||||
onAppointmentClick,
|
||||
onAppointmentOutsideHours,
|
||||
}: AppointmentScheduleGridProps) {
|
||||
const t = useTranslations('appointments');
|
||||
const [overlapPopover, setOverlapPopover] = useState<OverlapPopoverState | null>(null);
|
||||
|
||||
const visibleRange = useMemo(() => {
|
||||
@@ -159,18 +161,13 @@ export function AppointmentScheduleGrid({
|
||||
|
||||
if (providers.length === 0) {
|
||||
return (
|
||||
<div className="surface-card p-6 text-sm text-text-muted">
|
||||
No providers available. Add staff with treatment edit access to see columns here.
|
||||
</div>
|
||||
<div className="surface-card p-6 text-sm text-text-muted">{t('noProviders')}</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!snappedRange || slotStarts.length === 0) {
|
||||
return (
|
||||
<div className="surface-card p-6 text-sm text-text-muted">
|
||||
No working hours are configured for this day. Set provider working hours in Staff
|
||||
management.
|
||||
</div>
|
||||
<div className="surface-card p-6 text-sm text-text-muted">{t('noWorkingHours')}</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -188,12 +185,12 @@ export function AppointmentScheduleGrid({
|
||||
{p.name}
|
||||
{!p.hasWorkingHours && (
|
||||
<span className="block text-[10px] font-normal text-text-muted mt-0.5">
|
||||
No hours set
|
||||
{t('noHoursSet')}
|
||||
</span>
|
||||
)}
|
||||
{p.hasWorkingHours && p.dayBlocks.length === 0 && (
|
||||
<span className="block text-[10px] font-normal text-text-muted mt-0.5">
|
||||
Off today
|
||||
{t('offToday')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -252,13 +249,15 @@ export function AppointmentScheduleGrid({
|
||||
title={
|
||||
columnFullyDisabled
|
||||
? p.hasWorkingHours
|
||||
? 'Provider is off today'
|
||||
: 'Working hours not configured'
|
||||
? t('slotOffToday')
|
||||
: t('slotHoursNotConfigured')
|
||||
: !slotActive
|
||||
? 'Outside working hours'
|
||||
? t('slotOutsideHours')
|
||||
: slotDisabled
|
||||
? 'You cannot create appointments'
|
||||
: `Book ${formatMinuteLabel(slotStartMinute)}`
|
||||
? t('slotCannotCreate')
|
||||
: t('slotBookAt', {
|
||||
time: formatMinuteLabel(slotStartMinute),
|
||||
})
|
||||
}
|
||||
className={`absolute left-0 right-0 border-b border-border/50 transition-colors ${
|
||||
slotDisabled
|
||||
@@ -297,8 +296,10 @@ export function AppointmentScheduleGrid({
|
||||
const patientName = `${apt.patient.firstName} ${apt.patient.lastName}`;
|
||||
const bannerTitle = [
|
||||
patientName,
|
||||
outsideHours ? 'Outside working hours — editing blocked' : null,
|
||||
clusterSize > 1 ? `${clusterSize} overlapping — click to choose` : null,
|
||||
outsideHours ? t('outsideHoursBlocked') : null,
|
||||
clusterSize > 1
|
||||
? t('overlappingChoose', { count: clusterSize })
|
||||
: null,
|
||||
!isUnderOneHour && apt.patient.phone ? apt.patient.phone : null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
@@ -345,7 +346,7 @@ export function AppointmentScheduleGrid({
|
||||
)}
|
||||
{!isUnderOneHour && clusterSize > 1 && (
|
||||
<span className="block w-full truncate pointer-events-none text-[9px] leading-tight opacity-75">
|
||||
{clusterSize} overlapping
|
||||
{t('overlapping', { count: clusterSize })}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user