Merge branch 'master' into feature/tab-warning-flag

This commit is contained in:
2026-06-22 11:20:17 +03:30
92 changed files with 6547 additions and 1535 deletions

View File

@@ -1,8 +1,8 @@
'use client';
import Link from 'next/link';
import { memo, useMemo } from 'react';
import { usePathname } from 'next/navigation';
import { useTranslations } from 'next-intl';
import { Link, usePathname } from '@/i18n/navigation';
import {
LayoutDashboard,
Users,
@@ -20,56 +20,48 @@ import {
organizationTypeIcon,
} from '@/components/shared/organizationTypeIcon';
const menu = [
{ name: 'Dashboard', path: '/today', icon: LayoutDashboard, read: 'TAB_TODAY_READ' as const },
{ name: 'Staff', path: '/staff', icon: UserCog, read: 'TAB_STAFF_READ' as const },
{ name: 'Patients', path: '/patients', icon: Users, read: 'TAB_PATIENTS_READ' as const },
{ name: 'Appointment', path: '/appointments', icon: Calendar, read: 'TAB_APPOINTMENTS_READ' as const },
{ name: 'Treatment', path: '/treatment', icon: FlaskConical, read: 'TAB_TREATMENT_READ' as const },
{ name: 'Billing', path: '/billing', icon: CreditCard, read: 'TAB_BILLING_READ' as const },
{ name: 'Reports', path: '/reports', icon: FileText, read: 'TAB_REPORTS_READ' as const },
];
function Sidebar() {
const t = useTranslations('nav');
const tCommon = useTranslations('common');
const pathname = usePathname();
const { currentOrganization } = useAuth();
const pendingConnectionsCount = usePendingConnectionsCount();
const counterpartLabel = currentOrganization?.type === 'LAB' ? 'Clinics' : 'Labs';
const organizationsTabIcon = organizationTypeIcon(
counterpartOrganizationType(currentOrganization?.type),
const menu = useMemo(
() => [
{ name: t('dashboard'), path: '/today', icon: LayoutDashboard, read: 'TAB_TODAY_READ' as const },
{ name: t('staff'), path: '/staff', icon: UserCog, read: 'TAB_STAFF_READ' as const },
{
name: currentOrganization?.type === 'LAB' ? t('clinics') : t('labs'),
path: '/organizations',
icon: organizationTypeIcon(counterpartOrganizationType(currentOrganization?.type)),
read: 'TAB_ORGANIZATIONS_READ' as const,
},
{ name: t('patients'), path: '/patients', icon: Users, read: 'TAB_PATIENTS_READ' as const },
{ name: t('appointment'), path: '/appointments', icon: Calendar, read: 'TAB_APPOINTMENTS_READ' as const },
{ name: t('treatment'), path: '/treatment', icon: FlaskConical, read: 'TAB_TREATMENT_READ' as const },
{ name: t('billing'), path: '/billing', icon: CreditCard, read: 'TAB_BILLING_READ' as const },
{ name: t('reports'), path: '/reports', icon: FileText, read: 'TAB_REPORTS_READ' as const },
],
[currentOrganization?.type, t],
);
const visibleMenu = useMemo(
() => {
const withCounterpartTab = [
menu[0],
menu[1],
{
name: counterpartLabel,
path: '/organizations',
icon: organizationsTabIcon,
read: 'TAB_ORGANIZATIONS_READ' as const,
},
menu[2],
menu[3],
menu[4],
menu[5],
menu[6],
];
return withCounterpartTab.filter((item) => {
() =>
menu.filter((item) => {
if (item.path === '/appointments') {
return canAccessAppointmentsSection(currentOrganization);
}
return canViewTab(currentOrganization, item.read);
});
},
[counterpartLabel, organizationsTabIcon, currentOrganization],
}),
[currentOrganization, menu],
);
return (
<aside className="w-64 bg-background-secondary/90 border-r border-border text-text-primary flex flex-col">
<div className="h-[71px] px-4 flex items-center">
<h1 className="text-lg font-medium tracking-tight">DyoLink</h1>
<h1 className="text-lg font-medium tracking-tight">{tCommon('appName')}</h1>
</div>
<div className="mx-4 border-b border-border/70" />
@@ -82,7 +74,7 @@ function Sidebar() {
return (
<Link
key={item.name}
key={item.path}
href={item.path}
prefetch
className={`flex items-center gap-3 px-3 py-2.5 rounded-[var(--radius-sm)] border transition-colors ${
@@ -109,4 +101,4 @@ function Sidebar() {
);
}
export default memo(Sidebar);
export default memo(Sidebar);