improvement: some new gadgets added to dashboard. some new functionality added to existed gadgets.

This commit is contained in:
2026-07-14 03:06:56 +03:30
parent ec2b23f4b1
commit d383a4abc3
34 changed files with 944 additions and 191 deletions

View File

@@ -1,6 +1,7 @@
'use client';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useSearchParams } from 'next/navigation';
import { useTranslations } from 'next-intl';
import { useRouter } from '@/i18n/navigation';
import {
@@ -37,6 +38,11 @@ import { Table } from '@/components/ui/shared/Table';
import { getUserFacingError } from '@/components/shared/formatApiError';
import { StaffMembersMobileList } from '@/components/ui/staff/StaffMembersMobileList';
import { useToast } from '@/lib/hooks/useToast';
import {
parseHighlightMembershipIds,
STAFF_ROW_HIGHLIGHT_CLASS,
} from '@/components/staff/staffRowHighlight';
import { scrollWithinMainScrollContainer } from '@/components/shared/scrollWithinMain';
type StoredInviteLink = {
membershipId: string;
@@ -145,6 +151,7 @@ function PermissionGrid({
export function StaffPage() {
const router = useRouter();
const searchParams = useSearchParams();
const t = useTranslations('staff');
const tErrors = useTranslations('errors');
const tCommon = useTranslations('common');
@@ -199,6 +206,10 @@ export function StaffPage() {
const [enablingMembershipId, setEnablingMembershipId] = useState<string | null>(null);
const canEdit = useMemo(() => canEditStaff(currentOrganization), [currentOrganization]);
const highlightMembershipIds = useMemo(
() => parseHighlightMembershipIds(searchParams),
[searchParams],
);
const inviteHasTreatmentEdit = useMemo(
() =>
currentOrganization?.type === 'CLINIC' && featureStateHasTreatmentEdit(invitePerms),
@@ -267,6 +278,18 @@ export function StaffPage() {
void load();
}, [load]);
useEffect(() => {
if (loading || highlightMembershipIds.size === 0) return;
const firstMatch = members.find((member) => highlightMembershipIds.has(member.id));
if (!firstMatch) return;
const frame = requestAnimationFrame(() => {
scrollWithinMainScrollContainer(
document.getElementById(`staff-row-${firstMatch.id}`),
);
});
return () => cancelAnimationFrame(frame);
}, [loading, members, highlightMembershipIds]);
useEffect(() => {
if (!currentOrganization) return;
if (!canViewStaff(currentOrganization)) {
@@ -623,6 +646,7 @@ export function StaffPage() {
members={members}
canEdit={canEdit}
organizationType={currentOrganization?.type}
highlightMembershipIds={highlightMembershipIds}
copiedInviteMembershipId={copiedInviteMembershipId}
copyingInviteMembershipId={copyingInviteMembershipId}
enablingMembershipId={enablingMembershipId}
@@ -669,8 +693,19 @@ export function StaffPage() {
}
body={
<>
{members.map((m) => (
<tr key={m.id} className="hover:bg-background-secondary/45">
{members.map((m) => {
const highlighted = highlightMembershipIds.has(m.id);
return (
<tr
key={m.id}
id={`staff-row-${m.id}`}
className={[
'hover:bg-background-secondary/45',
highlighted ? STAFF_ROW_HIGHLIGHT_CLASS : undefined,
]
.filter(Boolean)
.join(' ')}
>
<td className="text-sm text-text-primary">{m.name}</td>
<td className="text-sm text-text-secondary">{m.email}</td>
<td className="text-sm">
@@ -794,7 +829,8 @@ export function StaffPage() {
)}
</td>
</tr>
))}
);
})}
</>
}
/>