mirror of
https://github.com/temetro/temetro.git
synced 2026-08-28 03:17:05 +00:00
frontend: clinical UI fixes + chat/composer polish
- chat composer: attach works with text (sr-only file input); lighter bordered input box - messages: defer "+" menu actions past close so file/appointment pickers fire - tasks: top-level New task button - chat: condensed appointment card with "View in calendar" deep-link; appointments page auto-opens the month calendar from ?calendar=&date= - lab: work-queue rows expand to show task detail + complete - inventory: clickable item detail dialog - pharmacy: Dispense action records a dispense + "Recently dispensed" feed; expiring badge uses endDate and only flags <=2 days left - prescriptions: keyboard nav in patient search, inventory-backed medication combobox (free-text fallback), optional start/end dates; thread dates through - sidebar: whole nav scrolls as one - i18n keys for all new strings Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
Stethoscope,
|
||||
Users,
|
||||
} from "lucide-react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { type ReactNode, useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@@ -192,8 +193,14 @@ function Section({
|
||||
|
||||
export function AppointmentsView() {
|
||||
const { t } = useTranslation();
|
||||
// Deep-link from the AI chat appointment card: `?calendar=1&date=YYYY-MM-DD`
|
||||
// opens the month calendar on that date.
|
||||
const searchParams = useSearchParams();
|
||||
const dateParam = searchParams.get("date");
|
||||
const [addOpen, setAddOpen] = useState(false);
|
||||
const [calendarOpen, setCalendarOpen] = useState(false);
|
||||
const [calendarOpen, setCalendarOpen] = useState(
|
||||
() => searchParams.get("calendar") != null,
|
||||
);
|
||||
const [appointments, setAppointments] = useState<Appointment[]>([]);
|
||||
const [query, setQuery] = useState("");
|
||||
const [selectedAppt, setSelectedAppt] = useState<Appointment | null>(null);
|
||||
@@ -381,6 +388,7 @@ export function AppointmentsView() {
|
||||
|
||||
<CalendarDialog
|
||||
appointments={appointments}
|
||||
initialDate={dateParam}
|
||||
onOpenChange={setCalendarOpen}
|
||||
open={calendarOpen}
|
||||
/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import {
|
||||
@@ -53,18 +53,32 @@ export function CalendarDialog({
|
||||
open,
|
||||
onOpenChange,
|
||||
appointments,
|
||||
initialDate,
|
||||
}: {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
appointments: Appointment[];
|
||||
// Optional deep-link target (YYYY-MM-DD): when set, the calendar opens on this
|
||||
// date's month with the day selected (e.g. from the AI chat appointment card).
|
||||
initialDate?: string | null;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
// First-of-month for the displayed month; defaults to TODAY's month.
|
||||
const startKey =
|
||||
initialDate && /^\d{4}-\d{2}-\d{2}$/.test(initialDate) ? initialDate : TODAY;
|
||||
// First-of-month for the displayed month; defaults to the deep-link/TODAY month.
|
||||
const [viewMonth, setViewMonth] = useState<Date>(() => {
|
||||
const t = parseKey(TODAY);
|
||||
return new Date(t.getFullYear(), t.getMonth(), 1);
|
||||
const d = parseKey(startKey);
|
||||
return new Date(d.getFullYear(), d.getMonth(), 1);
|
||||
});
|
||||
const [selectedKey, setSelectedKey] = useState<string>(TODAY);
|
||||
const [selectedKey, setSelectedKey] = useState<string>(startKey);
|
||||
|
||||
// When opened via a deep-link date, jump the view to that month/day.
|
||||
useEffect(() => {
|
||||
if (!open || !initialDate || !/^\d{4}-\d{2}-\d{2}$/.test(initialDate)) return;
|
||||
const d = parseKey(initialDate);
|
||||
setViewMonth(new Date(d.getFullYear(), d.getMonth(), 1));
|
||||
setSelectedKey(initialDate);
|
||||
}, [open, initialDate]);
|
||||
|
||||
const byDate = useMemo(() => {
|
||||
const map = new Map<string, Appointment[]>();
|
||||
|
||||
Reference in New Issue
Block a user