* MED-151: add profile view and working smoking dashboard card * update zod * move some components to shared * move some components to shared * remove console.logs * remove unused password form components * only check null for variant * use pathsconfig
153 lines
4.3 KiB
TypeScript
153 lines
4.3 KiB
TypeScript
'use client';
|
|
|
|
import { useMemo } from 'react';
|
|
|
|
import Link from 'next/link';
|
|
|
|
import { StoreCart } from '@medusajs/types';
|
|
import { Cross, Menu, Shield, ShoppingCart } from 'lucide-react';
|
|
|
|
import { usePersonalAccountData } from '@kit/accounts/hooks/use-personal-account-data';
|
|
import { ApplicationRoleEnum } from '@kit/accounts/types/accounts';
|
|
import { pathsConfig } from '@kit/shared/config';
|
|
import { useSignOut } from '@kit/supabase/hooks/use-sign-out';
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuGroup,
|
|
DropdownMenuItem,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from '@kit/ui/dropdown-menu';
|
|
import { If } from '@kit/ui/if';
|
|
import { Trans } from '@kit/ui/trans';
|
|
|
|
import SignOutDropdownItem from '@kit/shared/components/sign-out-dropdown-item';
|
|
import DropdownLink from '@kit/shared/components/ui/dropdown-link';
|
|
import { UserWorkspace } from '../../_lib/server/load-user-workspace';
|
|
import { routes } from './settings-sidebar';
|
|
|
|
export function SettingsMobileNavigation(props: {
|
|
workspace: UserWorkspace;
|
|
cart: StoreCart | null;
|
|
}) {
|
|
const user = props.workspace.user;
|
|
|
|
const signOut = useSignOut();
|
|
const { data: personalAccountData } = usePersonalAccountData(user.id);
|
|
|
|
const Links = [
|
|
{
|
|
children: [{ path: pathsConfig.app.home, label: 'common:routes.home' }],
|
|
},
|
|
]
|
|
.concat(routes)
|
|
.map((item, index) => {
|
|
if ('children' in item) {
|
|
return item.children.map((child) => {
|
|
return (
|
|
<DropdownLink
|
|
key={child.path}
|
|
path={child.path}
|
|
label={child.label}
|
|
/>
|
|
);
|
|
});
|
|
}
|
|
|
|
if ('divider' in item) {
|
|
return <DropdownMenuSeparator key={index} />;
|
|
}
|
|
});
|
|
|
|
const hasTotpFactor = useMemo(() => {
|
|
const factors = user?.factors ?? [];
|
|
return factors.some(
|
|
(factor) => factor.factor_type === 'totp' && factor.status === 'verified',
|
|
);
|
|
}, [user?.factors]);
|
|
|
|
const isSuperAdmin = useMemo(() => {
|
|
const hasAdminRole =
|
|
personalAccountData?.application_role === ApplicationRoleEnum.SuperAdmin;
|
|
|
|
return hasAdminRole && hasTotpFactor;
|
|
}, [user, personalAccountData, hasTotpFactor]);
|
|
|
|
const isDoctor = useMemo(() => {
|
|
const hasDoctorRole =
|
|
personalAccountData?.application_role === ApplicationRoleEnum.Doctor;
|
|
|
|
return hasDoctorRole && hasTotpFactor;
|
|
}, [user, personalAccountData, hasTotpFactor]);
|
|
|
|
const cartQuantityTotal =
|
|
props.cart?.items?.reduce((acc, item) => acc + item.quantity, 0) ?? 0;
|
|
const hasCartItems = cartQuantityTotal > 0;
|
|
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger>
|
|
<Menu className={'h-9'} />
|
|
</DropdownMenuTrigger>
|
|
|
|
<DropdownMenuContent sideOffset={10} className={'w-screen rounded-none'}>
|
|
<If condition={props.cart && hasCartItems}>
|
|
<DropdownMenuGroup>
|
|
<DropdownLink
|
|
path={pathsConfig.app.cart}
|
|
label="common:shoppingCartCount"
|
|
Icon={<ShoppingCart className="stroke-[1.5px]" />}
|
|
labelOptions={{ count: cartQuantityTotal }}
|
|
/>
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
</If>
|
|
|
|
<DropdownMenuGroup>{Links}</DropdownMenuGroup>
|
|
|
|
<If condition={isSuperAdmin}>
|
|
<DropdownMenuSeparator />
|
|
|
|
<DropdownMenuItem asChild>
|
|
<Link
|
|
className={
|
|
's-full flex cursor-pointer items-center space-x-2 text-yellow-700 dark:text-yellow-500'
|
|
}
|
|
href={pathsConfig.app.admin}
|
|
>
|
|
<Shield className={'h-5'} />
|
|
|
|
<span>Super Admin</span>
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
</If>
|
|
|
|
<If condition={isDoctor}>
|
|
<DropdownMenuSeparator />
|
|
|
|
<DropdownMenuItem asChild>
|
|
<Link
|
|
className={
|
|
'flex h-full cursor-pointer items-center space-x-2 text-yellow-700 dark:text-yellow-500'
|
|
}
|
|
href={pathsConfig.app.doctor}
|
|
>
|
|
<Cross className={'h-5'} />
|
|
|
|
<span>
|
|
<Trans i18nKey="common:doctor" />
|
|
</span>
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
</If>
|
|
<DropdownMenuSeparator />
|
|
|
|
<SignOutDropdownItem onSignOut={() => signOut.mutateAsync()} />
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
);
|
|
}
|
|
|
|
|