Merge branch 'main' into MED-57
This commit is contained in:
@@ -2,6 +2,7 @@ import { SitePageHeader } from '~/(marketing)/_components/site-page-header';
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
export async function generateMetadata() {
|
export async function generateMetadata() {
|
||||||
const { t } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { SitePageHeader } from '~/(marketing)/_components/site-page-header';
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
export async function generateMetadata() {
|
export async function generateMetadata() {
|
||||||
const { t } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Footer } from '@kit/ui/marketing';
|
import { Footer } from '@kit/ui/marketing';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
import appConfig from '~/config/app.config';
|
import appConfig from '@kit/shared/config/app.config';
|
||||||
|
|
||||||
export function SiteFooter() {
|
export function SiteFooter() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ import { Button } from '@kit/ui/button';
|
|||||||
import { If } from '@kit/ui/if';
|
import { If } from '@kit/ui/if';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import featuresFlagConfig from '~/config/feature-flags.config';
|
import { featureFlagsConfig } from '@kit/shared/config';
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
|
|
||||||
const ModeToggle = dynamic(() =>
|
const ModeToggle = dynamic(() =>
|
||||||
import('@kit/ui/mode-toggle').then((mod) => ({
|
import('@kit/ui/mode-toggle').then((mod) => ({
|
||||||
@@ -30,7 +32,7 @@ const paths = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const features = {
|
const features = {
|
||||||
enableThemeToggle: featuresFlagConfig.enableThemeToggle,
|
enableThemeToggle: featureFlagsConfig.enableThemeToggle,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function SiteHeaderAccountSection({
|
export function SiteHeaderAccountSection({
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { UserWorkspace } from '@/app/home/(user)/_lib/server/load-user-workspace
|
|||||||
|
|
||||||
import { Header } from '@kit/ui/marketing';
|
import { Header } from '@kit/ui/marketing';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
|
||||||
import { SiteHeaderAccountSection } from './site-header-account-section';
|
import { SiteHeaderAccountSection } from './site-header-account-section';
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { createCmsClient } from '@kit/cms';
|
|||||||
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
import { Post } from '../../blog/_components/post';
|
import { Post } from '../../blog/_components/post';
|
||||||
|
|
||||||
interface BlogPageProps {
|
interface BlogPageProps {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { ContactForm } from '~/(marketing)/contact/_components/contact-form';
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
export async function generateMetadata() {
|
export async function generateMetadata() {
|
||||||
const { t } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { SitePageHeader } from '~/(marketing)/_components/site-page-header';
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
export const generateMetadata = async () => {
|
export const generateMetadata = async () => {
|
||||||
const { t } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { SiteFooter } from '~/(marketing)/_components/site-footer';
|
|||||||
import { SiteHeader } from '~/(marketing)/_components/site-header';
|
import { SiteHeader } from '~/(marketing)/_components/site-header';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
import { loadCurrentUserAccounts } from '../home/(user)/_lib/server/load-accounts';
|
import { loadCurrentUserAccounts } from '~/home/(user)/_lib/server/load-accounts';
|
||||||
|
|
||||||
function SiteLayout(props: React.PropsWithChildren) {
|
function SiteLayout(props: React.PropsWithChildren) {
|
||||||
const accounts = use(loadCurrentUserAccounts());
|
const accounts = use(loadCurrentUserAccounts());
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
import { MedReportLogo } from '@/components/med-report-logo';
|
import { MedReportLogo } from '@kit/shared/components/med-report-logo';
|
||||||
import { ArrowRightIcon } from 'lucide-react';
|
import { ArrowRightIcon } from 'lucide-react';
|
||||||
|
|
||||||
import { CtaButton, Hero } from '@kit/ui/marketing';
|
import { CtaButton, Hero } from '@kit/ui/marketing';
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useState } from 'react';
|
|||||||
|
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
import { SubmitButton } from '@/components/ui/submit-button';
|
import { SubmitButton } from '@kit/shared/components/ui/submit-button';
|
||||||
import { sendCompanyOfferEmail } from '@/lib/services/mailer.service';
|
import { sendCompanyOfferEmail } from '@/lib/services/mailer.service';
|
||||||
import { CompanySubmitData } from '@/lib/types/company';
|
import { CompanySubmitData } from '@/lib/types/company';
|
||||||
import { companyOfferSchema } from '@/lib/validations/company-offer.schema';
|
import { companyOfferSchema } from '@/lib/validations/company-offer.schema';
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { MedReportLogo } from '@/components/med-report-logo';
|
import { MedReportLogo } from '@kit/shared/components/med-report-logo';
|
||||||
import { withI18n } from '@/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import CompanyOfferForm from './_components/company-offer-form';
|
import CompanyOfferForm from './_components/company-offer-form';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
function SiteLayout(props: React.PropsWithChildren) {
|
function SiteLayout(props: React.PropsWithChildren) {
|
||||||
return (
|
return (
|
||||||
<div className={'flex min-h-[100vh] flex-col justify-center items-center'}>
|
<div className={'flex min-h-[100vh] flex-col justify-center items-center'}>
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import {
|
|||||||
useSidebar,
|
useSidebar,
|
||||||
} from '@kit/ui/shadcn-sidebar';
|
} from '@kit/ui/shadcn-sidebar';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container';
|
import { ProfileAccountDropdownContainer } from '@kit/shared/components/personal-account-dropdown-container';
|
||||||
|
|
||||||
export function AdminSidebar({
|
export function AdminSidebar({
|
||||||
accounts,
|
accounts,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { enhanceRouteHandler } from '@kit/next/routes';
|
|||||||
import { getLogger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
|
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
|
||||||
|
|
||||||
import billingConfig from '~/config/billing.config';
|
import { billingConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Handle the webhooks from Stripe related to checkouts
|
* @description Handle the webhooks from Stripe related to checkouts
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
|
|||||||
import { Button } from '@kit/ui/button';
|
import { Button } from '@kit/ui/button';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
interface AuthCallbackErrorPageProps {
|
interface AuthCallbackErrorPageProps {
|
||||||
searchParams: Promise<{
|
searchParams: Promise<{
|
||||||
error: string;
|
error: string;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AuthLayoutShell } from '@kit/auth/shared';
|
import { AuthLayoutShell } from '@kit/auth/shared';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
|
||||||
function AuthLayout({ children }: React.PropsWithChildren) {
|
function AuthLayout({ children }: React.PropsWithChildren) {
|
||||||
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import type { NextRequest } from 'next/server';
|
|||||||
import { createAuthCallbackService } from '@kit/supabase/auth';
|
import { createAuthCallbackService } from '@kit/supabase/auth';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
|
|
||||||
export async function GET(request: NextRequest) {
|
export async function GET(request: NextRequest) {
|
||||||
const service = createAuthCallbackService(getSupabaseServerClient());
|
const service = createAuthCallbackService(getSupabaseServerClient());
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AuthLayoutShell } from '@kit/auth/shared';
|
import { AuthLayoutShell } from '@kit/auth/shared';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
|
||||||
function AuthLayout({ children }: React.PropsWithChildren) {
|
function AuthLayout({ children }: React.PropsWithChildren) {
|
||||||
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import { NextRequest, NextResponse } from 'next/server';
|
|||||||
import { createAuthCallbackService } from '@kit/supabase/auth';
|
import { createAuthCallbackService } from '@kit/supabase/auth';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
|
|
||||||
export async function GET(request: NextRequest) {
|
export async function GET(request: NextRequest) {
|
||||||
const service = createAuthCallbackService(getSupabaseServerClient());
|
const service = createAuthCallbackService(getSupabaseServerClient());
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import pathsConfig from '@/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { usePersonalAccountData } from '@kit/accounts/hooks/use-personal-account-data';
|
import { usePersonalAccountData } from '@kit/accounts/hooks/use-personal-account-data';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
async function SiteLayout(props: React.PropsWithChildren) {
|
async function SiteLayout(props: React.PropsWithChildren) {
|
||||||
return (
|
return (
|
||||||
<div className={'flex min-h-[100vh] flex-col items-center justify-center'}>
|
<div className={'flex min-h-[100vh] flex-col items-center justify-center'}>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
import pathsConfig from '@/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AuthLayoutShell } from '@kit/auth/shared';
|
import { AuthLayoutShell } from '@kit/auth/shared';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
|
||||||
function AuthLayout({ children }: React.PropsWithChildren) {
|
function AuthLayout({ children }: React.PropsWithChildren) {
|
||||||
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import { Button } from '@kit/ui/button';
|
|||||||
import { Heading } from '@kit/ui/heading';
|
import { Heading } from '@kit/ui/heading';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
export const generateMetadata = async () => {
|
export const generateMetadata = async () => {
|
||||||
const { t } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AuthLayoutShell } from '@kit/auth/shared';
|
import { AuthLayoutShell } from '@kit/auth/shared';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
|
||||||
function AuthLayout({ children }: React.PropsWithChildren) {
|
function AuthLayout({ children }: React.PropsWithChildren) {
|
||||||
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
import { register } from 'module';
|
|
||||||
|
|
||||||
import { SignInMethodsContainer } from '@kit/auth/sign-in';
|
import { SignInMethodsContainer } from '@kit/auth/sign-in';
|
||||||
|
import { authConfig, pathsConfig } from '@kit/shared/config';
|
||||||
import { Button } from '@kit/ui/button';
|
import { Button } from '@kit/ui/button';
|
||||||
import { Heading } from '@kit/ui/heading';
|
import { Heading } from '@kit/ui/heading';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import authConfig from '~/config/auth.config';
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AuthLayoutShell } from '@kit/auth/shared';
|
import { AuthLayoutShell } from '@kit/auth/shared';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
|
||||||
function AuthLayout({ children }: React.PropsWithChildren) {
|
function AuthLayout({ children }: React.PropsWithChildren) {
|
||||||
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
import { SignUpMethodsContainer } from '@kit/auth/sign-up';
|
import { SignUpMethodsContainer } from '@kit/auth/sign-up';
|
||||||
|
import { authConfig, pathsConfig } from '@kit/shared/config';
|
||||||
import { Button } from '@kit/ui/button';
|
import { Button } from '@kit/ui/button';
|
||||||
import { Heading } from '@kit/ui/heading';
|
import { Heading } from '@kit/ui/heading';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import authConfig from '~/config/auth.config';
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
export const generateMetadata = async () => {
|
export const generateMetadata = async () => {
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import { AccountSubmitData, createAuthApi } from '@kit/auth/api';
|
|||||||
import { enhanceAction } from '@kit/next/actions';
|
import { enhanceAction } from '@kit/next/actions';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
|
|
||||||
import { UpdateAccountSchema } from '../schemas/update-account.schema';
|
import { UpdateAccountSchema } from '../schemas/update-account.schema';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
async function SiteLayout(props: React.PropsWithChildren) {
|
async function SiteLayout(props: React.PropsWithChildren) {
|
||||||
return (
|
return (
|
||||||
<div className={'flex min-h-[100vh] flex-col items-center justify-center'}>
|
<div className={'flex min-h-[100vh] flex-col items-center justify-center'}>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
import { BackButton } from '@/components/back-button';
|
|
||||||
import { MedReportLogo } from '@/components/med-report-logo';
|
|
||||||
import pathsConfig from '@/config/paths.config';
|
|
||||||
import { signOutAction } from '@/lib/actions/sign-out';
|
import { signOutAction } from '@/lib/actions/sign-out';
|
||||||
import { getSupabaseServerClient } from '@/packages/supabase/src/clients/server-client';
|
import { getSupabaseServerClient } from '@/packages/supabase/src/clients/server-client';
|
||||||
|
|
||||||
|
import { BackButton } from '@kit/shared/components/back-button';
|
||||||
|
import { MedReportLogo } from '@kit/shared/components/med-report-logo';
|
||||||
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AuthLayoutShell } from '@kit/auth/shared';
|
import { AuthLayoutShell } from '@kit/auth/shared';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
|
||||||
function AuthLayout({ children }: React.PropsWithChildren) {
|
function AuthLayout({ children }: React.PropsWithChildren) {
|
||||||
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
return <AuthLayoutShell Logo={AppLogo}>{children}</AuthLayoutShell>;
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { MultiFactorChallengeContainer } from '@kit/auth/mfa';
|
|||||||
import { checkRequiresMultiFactorAuthentication } from '@kit/supabase/check-requires-mfa';
|
import { checkRequiresMultiFactorAuthentication } from '@kit/supabase/check-requires-mfa';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|||||||
242
app/doctor/_components/analysis-view.tsx
Normal file
242
app/doctor/_components/analysis-view.tsx
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
|
||||||
|
import { giveFeedbackAction } from '@kit/doctor/actions/doctor-server-actions';
|
||||||
|
import {
|
||||||
|
getDOBWithAgeStringFromPersonalCode,
|
||||||
|
getResultSetName,
|
||||||
|
} from '@kit/doctor/lib/helpers';
|
||||||
|
import {
|
||||||
|
AnalysisResponse,
|
||||||
|
DoctorFeedback,
|
||||||
|
Order,
|
||||||
|
Patient,
|
||||||
|
} from '@kit/doctor/schema/doctor-analysis-detail-view.schema';
|
||||||
|
import {
|
||||||
|
DoctorAnalysisFeedbackForm,
|
||||||
|
doctorAnalysisFeedbackSchema,
|
||||||
|
} from '@kit/doctor/schema/doctor-analysis.schema';
|
||||||
|
import ConfirmationModal from '@kit/shared/components/confirmation-modal';
|
||||||
|
import { getFullName } from '@kit/shared/utils';
|
||||||
|
import { useUser } from '@kit/supabase/hooks/use-user';
|
||||||
|
import { Button } from '@kit/ui/button';
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormMessage,
|
||||||
|
} from '@kit/ui/form';
|
||||||
|
import { toast } from '@kit/ui/sonner';
|
||||||
|
import { Textarea } from '@kit/ui/textarea';
|
||||||
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
|
import Analysis from '~/home/(user)/(dashboard)/analysis-results/_components/analysis';
|
||||||
|
import { bmiFromMetric } from '~/lib/utils';
|
||||||
|
|
||||||
|
export default function AnalysisView({
|
||||||
|
patient,
|
||||||
|
order,
|
||||||
|
analyses,
|
||||||
|
feedback,
|
||||||
|
}: {
|
||||||
|
patient: Patient;
|
||||||
|
order: Order;
|
||||||
|
analyses: AnalysisResponse[];
|
||||||
|
feedback?: DoctorFeedback;
|
||||||
|
}) {
|
||||||
|
const [isConfirmOpen, setIsConfirmOpen] = useState(false);
|
||||||
|
|
||||||
|
const { data: user } = useUser();
|
||||||
|
|
||||||
|
const isInProgress =
|
||||||
|
!!feedback?.status &&
|
||||||
|
feedback?.doctor_user_id &&
|
||||||
|
feedback?.status !== 'COMPLETED';
|
||||||
|
const isReadOnly =
|
||||||
|
!isInProgress ||
|
||||||
|
(!!feedback?.doctor_user_id && feedback?.doctor_user_id !== user?.id);
|
||||||
|
|
||||||
|
const form = useForm({
|
||||||
|
resolver: zodResolver(doctorAnalysisFeedbackSchema),
|
||||||
|
defaultValues: {
|
||||||
|
feedbackValue: feedback?.value ?? '',
|
||||||
|
userId: patient.userId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
if (!patient || !order || !analyses) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = async (
|
||||||
|
data: DoctorAnalysisFeedbackForm,
|
||||||
|
status: 'DRAFT' | 'COMPLETED',
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const feedbackPromise = giveFeedbackAction({
|
||||||
|
...data,
|
||||||
|
analysisOrderId: order.analysisOrderId,
|
||||||
|
status,
|
||||||
|
});
|
||||||
|
|
||||||
|
toast.promise(() => feedbackPromise, {
|
||||||
|
success: <Trans i18nKey={'doctor:updateFeedbackSuccess'} />,
|
||||||
|
error: <Trans i18nKey={'doctor:updateFeedbackError'} />,
|
||||||
|
loading: <Trans i18nKey={'doctor:updateFeedbackLoading'} />,
|
||||||
|
});
|
||||||
|
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
predicate: (query) => query.queryKey.includes('doctor-jobs'),
|
||||||
|
});
|
||||||
|
|
||||||
|
return setIsConfirmOpen(false);
|
||||||
|
} catch (error) {
|
||||||
|
toast.error(<Trans i18nKey="common:genericServerError" />);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDraftSubmit = () => {
|
||||||
|
const formData = form.getValues();
|
||||||
|
onSubmit(formData, 'DRAFT');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCompleteSubmit = () => {
|
||||||
|
setIsConfirmOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmComplete = () => {
|
||||||
|
const formData = form.getValues();
|
||||||
|
onSubmit(formData, 'COMPLETED');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3>
|
||||||
|
<Trans
|
||||||
|
i18nKey={getResultSetName(
|
||||||
|
order.title,
|
||||||
|
order.isPackage,
|
||||||
|
Object.keys(analyses)?.length,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</h3>
|
||||||
|
<div className="grid grid-cols-2">
|
||||||
|
<div className="font-bold">
|
||||||
|
<Trans i18nKey="doctor:name" />
|
||||||
|
</div>
|
||||||
|
<div>{getFullName(patient.firstName, patient.lastName)}</div>
|
||||||
|
<div className="font-bold">
|
||||||
|
<Trans i18nKey="doctor:personalCode" />
|
||||||
|
</div>
|
||||||
|
<div>{patient.personalCode ?? ''}</div>
|
||||||
|
<div className="font-bold">
|
||||||
|
<Trans i18nKey="doctor:dobAndAge" />
|
||||||
|
</div>
|
||||||
|
<div>{getDOBWithAgeStringFromPersonalCode(patient.personalCode)}</div>
|
||||||
|
<div className="font-bold">
|
||||||
|
<Trans i18nKey="doctor:height" />
|
||||||
|
</div>
|
||||||
|
<div>{patient.height}</div>
|
||||||
|
<div className="font-bold">
|
||||||
|
<Trans i18nKey="doctor:weight" />
|
||||||
|
</div>
|
||||||
|
<div>{patient.weight}</div>
|
||||||
|
<div className="font-bold">
|
||||||
|
<Trans i18nKey="doctor:bmi" />
|
||||||
|
</div>
|
||||||
|
<div>{bmiFromMetric(patient?.height ?? 0, patient?.weight ?? 0)}</div>
|
||||||
|
<div className="font-bold">
|
||||||
|
<Trans i18nKey="doctor:smoking" />
|
||||||
|
</div>
|
||||||
|
<div></div>
|
||||||
|
<div className="font-bold">
|
||||||
|
<Trans i18nKey="doctor:phone" />
|
||||||
|
</div>
|
||||||
|
<div>{patient.phone}</div>
|
||||||
|
<div className="font-bold">
|
||||||
|
<Trans i18nKey="doctor:email" />
|
||||||
|
</div>
|
||||||
|
<div>{patient.email}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
<Trans i18nKey="doctor:results" />
|
||||||
|
</h3>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
{analyses.map((analysisData) => {
|
||||||
|
return (
|
||||||
|
<Analysis
|
||||||
|
key={analysisData.id}
|
||||||
|
analysisElement={{
|
||||||
|
analysis_name_lab: analysisData.analysis_name,
|
||||||
|
}}
|
||||||
|
results={analysisData}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
<Trans i18nKey="doctor:feedback" />
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p>{feedback?.value ?? '-'}</p>
|
||||||
|
|
||||||
|
{!isReadOnly && (
|
||||||
|
<Form {...form}>
|
||||||
|
<form className="space-y-4 lg:w-1/2">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="feedbackValue"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormControl>
|
||||||
|
<Textarea {...field} disabled={isReadOnly} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
handleDraftSubmit();
|
||||||
|
}}
|
||||||
|
disabled={isReadOnly}
|
||||||
|
>
|
||||||
|
<Trans i18nKey="common:saveAsDraft" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
handleCompleteSubmit();
|
||||||
|
}}
|
||||||
|
disabled={isReadOnly}
|
||||||
|
>
|
||||||
|
<Trans i18nKey="common:save" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
<ConfirmationModal
|
||||||
|
isOpen={isConfirmOpen}
|
||||||
|
onClose={() => setIsConfirmOpen(false)}
|
||||||
|
onConfirm={confirmComplete}
|
||||||
|
titleKey="doctor:confirmFeedbackModal.title"
|
||||||
|
descriptionKey="doctor:confirmFeedbackModal.description"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
36
app/doctor/_components/doctor-dashboard.tsx
Normal file
36
app/doctor/_components/doctor-dashboard.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
getOpenResponsesAction,
|
||||||
|
getOtherResponsesAction,
|
||||||
|
getUserDoneResponsesAction,
|
||||||
|
getUserInProgressResponsesAction,
|
||||||
|
} from '@kit/doctor/actions/table-data-fetching-actions';
|
||||||
|
import ResultsTableWrapper from './results-table-wrapper';
|
||||||
|
|
||||||
|
export default function Dashboard() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ResultsTableWrapper
|
||||||
|
titleKey="doctor:openReviews"
|
||||||
|
action={getOpenResponsesAction}
|
||||||
|
queryKey="doctor-open-jobs"
|
||||||
|
/>
|
||||||
|
<ResultsTableWrapper
|
||||||
|
titleKey="doctor:myReviews"
|
||||||
|
action={getUserInProgressResponsesAction}
|
||||||
|
queryKey="doctor-in-progress-jobs"
|
||||||
|
/>
|
||||||
|
<ResultsTableWrapper
|
||||||
|
titleKey="doctor:completedReviews"
|
||||||
|
action={getUserDoneResponsesAction}
|
||||||
|
queryKey="doctor-done-jobs"
|
||||||
|
/>
|
||||||
|
<ResultsTableWrapper
|
||||||
|
titleKey="doctor:otherReviews"
|
||||||
|
action={getOtherResponsesAction}
|
||||||
|
queryKey="doctor-other-jobs"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
import { isDoctor } from '../lib/server/utils/is-doctor';
|
import { isDoctor } from '@kit/doctor/lib/server/utils/is-doctor';
|
||||||
|
|
||||||
|
|
||||||
type LayoutOrPageComponent<Params> = React.ComponentType<Params>;
|
type LayoutOrPageComponent<Params> = React.ComponentType<Params>;
|
||||||
@@ -20,8 +20,10 @@ import {
|
|||||||
} from '@kit/ui/shadcn-sidebar';
|
} from '@kit/ui/shadcn-sidebar';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container';
|
import { ProfileAccountDropdownContainer } from '@kit/shared/components/personal-account-dropdown-container';
|
||||||
|
|
||||||
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
export function DoctorSidebar({
|
export function DoctorSidebar({
|
||||||
accounts,
|
accounts,
|
||||||
@@ -33,7 +35,11 @@ export function DoctorSidebar({
|
|||||||
return (
|
return (
|
||||||
<Sidebar collapsible="icon">
|
<Sidebar collapsible="icon">
|
||||||
<SidebarHeader className={'m-2'}>
|
<SidebarHeader className={'m-2'}>
|
||||||
<AppLogo href={'/doctor'} className="max-w-full" compact={!open} />
|
<AppLogo
|
||||||
|
href={pathsConfig.app.doctor}
|
||||||
|
className="max-w-full"
|
||||||
|
compact={!open}
|
||||||
|
/>
|
||||||
</SidebarHeader>
|
</SidebarHeader>
|
||||||
|
|
||||||
<SidebarContent>
|
<SidebarContent>
|
||||||
@@ -44,10 +50,49 @@ export function DoctorSidebar({
|
|||||||
|
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuButton isActive={path === '/doctor'} asChild>
|
<SidebarMenuButton
|
||||||
<Link className={'flex gap-2.5'} href={'/doctor'}>
|
isActive={path === pathsConfig.app.doctor}
|
||||||
|
asChild
|
||||||
|
>
|
||||||
|
<Link className={'flex gap-2.5'} href={pathsConfig.app.doctor}>
|
||||||
<LayoutDashboard className={'h-4'} />
|
<LayoutDashboard className={'h-4'} />
|
||||||
<span>Dashboard</span>
|
<Trans i18nKey={'doctor:sidebar.dashboard'} />
|
||||||
|
</Link>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
<SidebarMenuButton
|
||||||
|
isActive={path === pathsConfig.app.openJobs}
|
||||||
|
asChild
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
className={'flex gap-2.5'}
|
||||||
|
href={pathsConfig.app.openJobs}
|
||||||
|
>
|
||||||
|
<LayoutDashboard className={'h-4'} />
|
||||||
|
<Trans i18nKey={'doctor:sidebar.openReviews'} />
|
||||||
|
</Link>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
<SidebarMenuButton
|
||||||
|
isActive={path === pathsConfig.app.myJobs}
|
||||||
|
asChild
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
className={'flex gap-2.5'}
|
||||||
|
href={pathsConfig.app.myJobs}
|
||||||
|
>
|
||||||
|
<LayoutDashboard className={'h-4'} />
|
||||||
|
<Trans i18nKey={'doctor:sidebar.myReviews'} />
|
||||||
|
</Link>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
<SidebarMenuButton
|
||||||
|
isActive={path === pathsConfig.app.completedJobs}
|
||||||
|
asChild
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
className={'flex gap-2.5'}
|
||||||
|
href={pathsConfig.app.completedJobs}
|
||||||
|
>
|
||||||
|
<LayoutDashboard className={'h-4'} />
|
||||||
|
<Trans i18nKey={'doctor:sidebar.completedReviews'} />
|
||||||
</Link>
|
</Link>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
|
|||||||
@@ -2,13 +2,14 @@ import Link from 'next/link';
|
|||||||
|
|
||||||
import { Menu } from 'lucide-react';
|
import { Menu } from 'lucide-react';
|
||||||
|
|
||||||
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@kit/ui/dropdown-menu';
|
} from '@kit/ui/dropdown-menu';
|
||||||
import pathsConfig from '../../../config/paths.config';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
export function DoctorMobileNavigation() {
|
export function DoctorMobileNavigation() {
|
||||||
return (
|
return (
|
||||||
@@ -19,9 +20,30 @@ export function DoctorMobileNavigation() {
|
|||||||
|
|
||||||
<DropdownMenuContent>
|
<DropdownMenuContent>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
<Link href={pathsConfig.app.doctor}>Home</Link>
|
<Link href={pathsConfig.app.home}>
|
||||||
|
<Trans i18nKey={'common:routes.home'} />
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Link href={pathsConfig.app.doctor}>
|
||||||
|
<Trans i18nKey={'doctor:sidebar.dashboard'} />
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Link href={pathsConfig.app.openJobs}>
|
||||||
|
<Trans i18nKey={'doctor:sidebar.openReviews'} />
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Link href={pathsConfig.app.myJobs}>
|
||||||
|
<Trans i18nKey={'doctor:sidebar.myReviews'} />
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Link href={pathsConfig.app.completedJobs}>
|
||||||
|
<Trans i18nKey={'doctor:sidebar.completedReviews'} />
|
||||||
|
</Link>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
|
|||||||
120
app/doctor/_components/results-table-wrapper.tsx
Normal file
120
app/doctor/_components/results-table-wrapper.tsx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import {
|
||||||
|
PaginatedData,
|
||||||
|
ResponseTable,
|
||||||
|
ServerActionResponse,
|
||||||
|
} from '@kit/doctor/schema/doctor-analysis.schema';
|
||||||
|
import TableSkeleton from '@kit/shared/components/table-skeleton';
|
||||||
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
import { cn } from '@kit/ui/utils';
|
||||||
|
|
||||||
|
import ResultsTable from './results-table';
|
||||||
|
|
||||||
|
const PAGE_SIZE = 10;
|
||||||
|
|
||||||
|
export default function ResultsTableWrapper({
|
||||||
|
titleKey,
|
||||||
|
action,
|
||||||
|
queryKey,
|
||||||
|
}: {
|
||||||
|
titleKey: string;
|
||||||
|
action: ({
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
}: {
|
||||||
|
page: number;
|
||||||
|
pageSize: number;
|
||||||
|
}) => Promise<ServerActionResponse<PaginatedData<ResponseTable>>>;
|
||||||
|
queryKey: string;
|
||||||
|
}) {
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: jobs,
|
||||||
|
isLoading,
|
||||||
|
isError,
|
||||||
|
isFetching,
|
||||||
|
} = useQuery({
|
||||||
|
queryKey: [queryKey, 'doctor-jobs', page],
|
||||||
|
queryFn: async () => await action({ page: page, pageSize: PAGE_SIZE }),
|
||||||
|
placeholderData: (previousData) => previousData,
|
||||||
|
});
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const onJobUpdate = () => {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
predicate: (query) => query.queryKey.includes('doctor-jobs'),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const createPageChangeHandler = (setPage: (page: number) => void) => {
|
||||||
|
return async ({ page }: { page: number; pageSize: number }) => {
|
||||||
|
setPage(page);
|
||||||
|
return { success: true, data: null };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3>
|
||||||
|
<Trans i18nKey={titleKey} />
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div className="relative">
|
||||||
|
<div
|
||||||
|
className={`transition-opacity duration-200 ${
|
||||||
|
isFetching ? 'opacity-50' : 'opacity-100'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<TableSkeleton />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isError) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3>
|
||||||
|
<Trans i18nKey={titleKey} />
|
||||||
|
</h3>
|
||||||
|
<div className="flex items-center justify-center p-8">
|
||||||
|
<div className="text-lg text-red-600">
|
||||||
|
<Trans i18nKey="common:genericServerError" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3>
|
||||||
|
<Trans i18nKey={titleKey} />
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div className="relative">
|
||||||
|
<div
|
||||||
|
className={cn('opacity-100 transition-opacity duration-200', {
|
||||||
|
'opacity-50': isFetching,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<ResultsTable
|
||||||
|
results={jobs?.data?.data || []}
|
||||||
|
pagination={jobs?.data?.pagination}
|
||||||
|
fetchAction={createPageChangeHandler(setPage)}
|
||||||
|
onJobUpdate={onJobUpdate}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
322
app/doctor/_components/results-table.tsx
Normal file
322
app/doctor/_components/results-table.tsx
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useTransition } from 'react';
|
||||||
|
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
|
import { format } from 'date-fns';
|
||||||
|
import { Eye, LoaderCircle } from 'lucide-react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
selectJobAction,
|
||||||
|
unselectJobAction,
|
||||||
|
} from '@kit/doctor/actions/doctor-server-actions';
|
||||||
|
import { getResultSetName } from '@kit/doctor/lib/helpers';
|
||||||
|
import { ResponseTable } from '@kit/doctor/schema/doctor-analysis.schema';
|
||||||
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
import { getFullName } from '@kit/shared/utils';
|
||||||
|
import { useUser } from '@kit/supabase/hooks/use-user';
|
||||||
|
import { Button } from '@kit/ui/button';
|
||||||
|
import { toast } from '@kit/ui/sonner';
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from '@kit/ui/table';
|
||||||
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
|
function DoctorCell({
|
||||||
|
doctorUserId,
|
||||||
|
doctorName,
|
||||||
|
analysisOrderId,
|
||||||
|
userId,
|
||||||
|
isRemovable,
|
||||||
|
onJobUpdate,
|
||||||
|
linkTo,
|
||||||
|
}: {
|
||||||
|
doctorUserId?: string;
|
||||||
|
doctorName?: string;
|
||||||
|
analysisOrderId: number;
|
||||||
|
userId: string;
|
||||||
|
isRemovable?: boolean;
|
||||||
|
linkTo: string;
|
||||||
|
onJobUpdate: () => void;
|
||||||
|
}) {
|
||||||
|
const [isPending, startTransition] = useTransition();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const handleSelectJob = () => {
|
||||||
|
startTransition(async () => {
|
||||||
|
const result = await selectJobAction({
|
||||||
|
analysisOrderId,
|
||||||
|
userId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result?.success) {
|
||||||
|
onJobUpdate();
|
||||||
|
router.push(linkTo);
|
||||||
|
} else {
|
||||||
|
toast.error('common.genericServerError');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUnselectJob = () => {
|
||||||
|
startTransition(async () => {
|
||||||
|
const result = await unselectJobAction({
|
||||||
|
analysisOrderId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result?.success) {
|
||||||
|
onJobUpdate();
|
||||||
|
} else {
|
||||||
|
toast.error('common.genericServerError');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isRemovable) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="w-16"
|
||||||
|
size="sm"
|
||||||
|
variant="destructive"
|
||||||
|
onClick={handleUnselectJob}
|
||||||
|
disabled={isPending}
|
||||||
|
>
|
||||||
|
{isPending ? (
|
||||||
|
<LoaderCircle className="h-4 w-4 animate-spin" />
|
||||||
|
) : (
|
||||||
|
<Trans i18nKey="doctor:unselectJob" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doctorUserId) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="w-16"
|
||||||
|
size="sm"
|
||||||
|
onClick={handleSelectJob}
|
||||||
|
disabled={isPending}
|
||||||
|
>
|
||||||
|
{isPending ? (
|
||||||
|
<LoaderCircle className="h-4 w-4 animate-spin" />
|
||||||
|
) : (
|
||||||
|
<Trans i18nKey="doctor:selectJob" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>{doctorName}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ResultsTable({
|
||||||
|
results = [],
|
||||||
|
pagination = {
|
||||||
|
currentPage: 1,
|
||||||
|
totalPages: 1,
|
||||||
|
totalCount: 0,
|
||||||
|
pageSize: 10,
|
||||||
|
},
|
||||||
|
fetchAction,
|
||||||
|
onJobUpdate,
|
||||||
|
}: {
|
||||||
|
results: ResponseTable[] | null;
|
||||||
|
pagination?: {
|
||||||
|
currentPage: number;
|
||||||
|
totalPages: number;
|
||||||
|
totalCount: number;
|
||||||
|
pageSize: number;
|
||||||
|
};
|
||||||
|
fetchAction: ({
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
}: {
|
||||||
|
page: number;
|
||||||
|
pageSize: number;
|
||||||
|
}) => Promise<{
|
||||||
|
success: boolean;
|
||||||
|
data: null;
|
||||||
|
}>;
|
||||||
|
onJobUpdate: () => void;
|
||||||
|
}) {
|
||||||
|
const [isPending, startTransition] = useTransition();
|
||||||
|
const { data: currentUser } = useUser();
|
||||||
|
|
||||||
|
const fetchPage = async (page: number) => {
|
||||||
|
startTransition(async () => {
|
||||||
|
const result = await fetchAction({
|
||||||
|
page,
|
||||||
|
pageSize: pagination.pageSize,
|
||||||
|
});
|
||||||
|
if (!result.success) {
|
||||||
|
toast.error('common.genericServerError');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNextPage = () => {
|
||||||
|
if (pagination.currentPage < pagination.totalPages) {
|
||||||
|
fetchPage(pagination.currentPage + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePrevPage = () => {
|
||||||
|
if (pagination.currentPage > 1) {
|
||||||
|
fetchPage(pagination.currentPage - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleJobUpdate = () => {
|
||||||
|
onJobUpdate();
|
||||||
|
fetchPage(pagination.currentPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!results?.length) {
|
||||||
|
return (
|
||||||
|
<p>
|
||||||
|
<Trans i18nKey="common:noData" />.
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Table className="border-separate rounded-lg border">
|
||||||
|
<TableHeader className="text-ui-fg-subtle txt-medium-plus">
|
||||||
|
<TableRow>
|
||||||
|
<TableHead className="w-6"></TableHead>
|
||||||
|
<TableHead className="w-20">
|
||||||
|
<Trans i18nKey="doctor:resultsTable.patientName" />
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="w-20">
|
||||||
|
<Trans i18nKey="doctor:resultsTable.serviceName" />
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="w-20">
|
||||||
|
<Trans i18nKey="doctor:resultsTable.orderNr" />
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="w-20">
|
||||||
|
<Trans i18nKey="doctor:resultsTable.time" />
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="w-20">
|
||||||
|
<Trans i18nKey="doctor:resultsTable.resultsStatus" />
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="w-20">
|
||||||
|
<Trans i18nKey="doctor:resultsTable.assignedTo" />
|
||||||
|
</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{results
|
||||||
|
?.sort((a, b) =>
|
||||||
|
(a.created_at ?? '') > (b.created_at ?? '') ? -1 : 1,
|
||||||
|
)
|
||||||
|
.map((result) => {
|
||||||
|
const isCompleted = result.feedback?.status === 'COMPLETED';
|
||||||
|
const isCurrentDoctorJob =
|
||||||
|
!!result.doctor?.primary_owner_user_id &&
|
||||||
|
result.doctor?.primary_owner_user_id === currentUser?.id;
|
||||||
|
|
||||||
|
const resultsReceived = result.elements.length || 0;
|
||||||
|
const elementsInOrder = Array.from(
|
||||||
|
new Set(result.analysis_order_id.analysis_element_ids),
|
||||||
|
)?.length;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRow key={result.order_number}>
|
||||||
|
<TableCell className="text-center">
|
||||||
|
<Link
|
||||||
|
href={`/${pathsConfig.app.analysisDetails}/${result.id}`}
|
||||||
|
>
|
||||||
|
<Eye />
|
||||||
|
</Link>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{getFullName(
|
||||||
|
result.patient?.name,
|
||||||
|
result.patient?.last_name,
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Trans
|
||||||
|
i18nKey={getResultSetName(
|
||||||
|
result.order?.title ?? '-',
|
||||||
|
result.order?.isPackage,
|
||||||
|
result.elements?.length || 0,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>{result.order_number}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{result.firstSampleGivenAt
|
||||||
|
? format(result.firstSampleGivenAt, 'dd.MM.yyyy HH:mm')
|
||||||
|
: '-'}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Trans
|
||||||
|
i18nKey={
|
||||||
|
resultsReceived === elementsInOrder
|
||||||
|
? 'doctor:resultsTable.responsesReceived'
|
||||||
|
: 'doctor:resultsTable.waitingForNr'
|
||||||
|
}
|
||||||
|
values={{
|
||||||
|
nr: elementsInOrder - resultsReceived,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<DoctorCell
|
||||||
|
doctorUserId={result.doctor?.primary_owner_user_id}
|
||||||
|
doctorName={getFullName(
|
||||||
|
result.doctor?.name,
|
||||||
|
result.doctor?.last_name,
|
||||||
|
)}
|
||||||
|
analysisOrderId={result.analysis_order_id?.id}
|
||||||
|
userId={result.patient?.id}
|
||||||
|
isRemovable={!isCompleted && isCurrentDoctorJob}
|
||||||
|
onJobUpdate={handleJobUpdate}
|
||||||
|
linkTo={`/${pathsConfig.app.analysisDetails}/${result.id}`}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
<div className="mt-4 flex items-center justify-between">
|
||||||
|
<Button
|
||||||
|
onClick={handlePrevPage}
|
||||||
|
disabled={pagination.currentPage === 1 || isPending}
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
<Trans i18nKey="common:previous" />
|
||||||
|
</Button>
|
||||||
|
<span className="text-sm text-gray-600">
|
||||||
|
<Trans
|
||||||
|
i18nKey={'common:pageOfPages'}
|
||||||
|
values={{
|
||||||
|
page: pagination.currentPage,
|
||||||
|
total: pagination.totalPages,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
onClick={handleNextPage}
|
||||||
|
disabled={
|
||||||
|
pagination.currentPage === pagination.totalPages || isPending
|
||||||
|
}
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
<Trans i18nKey="common:next" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
38
app/doctor/analysis/[id]/page.tsx
Normal file
38
app/doctor/analysis/[id]/page.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { cache } from 'react';
|
||||||
|
|
||||||
|
import { getAnalysisResultsForDoctor } from '@kit/doctor/services/doctor-analysis.service';
|
||||||
|
import { PageBody, PageHeader } from '@kit/ui/page';
|
||||||
|
import AnalysisView from '../../_components/analysis-view';
|
||||||
|
import { DoctorGuard } from '../../_components/doctor-guard';
|
||||||
|
|
||||||
|
async function AnalysisPage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{
|
||||||
|
id: string;
|
||||||
|
}>;
|
||||||
|
}) {
|
||||||
|
const { id } = await params;
|
||||||
|
const analysisResultDetails = await loadResult(Number(id));
|
||||||
|
|
||||||
|
if (!analysisResultDetails) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHeader />
|
||||||
|
<PageBody>
|
||||||
|
<AnalysisView
|
||||||
|
patient={analysisResultDetails.patient}
|
||||||
|
order={analysisResultDetails.order}
|
||||||
|
analyses={analysisResultDetails.analysisResponse}
|
||||||
|
feedback={analysisResultDetails.doctorFeedback}
|
||||||
|
/>
|
||||||
|
</PageBody>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DoctorGuard(AnalysisPage);
|
||||||
|
const loadResult = cache(getAnalysisResultsForDoctor);
|
||||||
22
app/doctor/completed-jobs/page.tsx
Normal file
22
app/doctor/completed-jobs/page.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { PageBody, PageHeader } from '@kit/ui/page';
|
||||||
|
|
||||||
|
import { getUserDoneResponsesAction } from '@kit/doctor/actions/table-data-fetching-actions';
|
||||||
|
import ResultsTableWrapper from '../_components/results-table-wrapper';
|
||||||
|
import { DoctorGuard } from '../_components/doctor-guard';
|
||||||
|
|
||||||
|
async function CompletedJobsPage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHeader />
|
||||||
|
<PageBody>
|
||||||
|
<ResultsTableWrapper
|
||||||
|
titleKey="doctor:completedReviews"
|
||||||
|
action={getUserDoneResponsesAction}
|
||||||
|
queryKey="doctor-done-jobs"
|
||||||
|
/>
|
||||||
|
</PageBody>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DoctorGuard(CompletedJobsPage);
|
||||||
21
app/doctor/my-jobs/page.tsx
Normal file
21
app/doctor/my-jobs/page.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { getUserInProgressResponsesAction } from '@kit/doctor/actions/table-data-fetching-actions';
|
||||||
|
import { PageBody, PageHeader } from '@kit/ui/page';
|
||||||
|
import ResultsTableWrapper from '../_components/results-table-wrapper';
|
||||||
|
import { DoctorGuard } from '../_components/doctor-guard';
|
||||||
|
|
||||||
|
async function MyReviewsPage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHeader />
|
||||||
|
<PageBody>
|
||||||
|
<ResultsTableWrapper
|
||||||
|
titleKey="doctor:myReviews"
|
||||||
|
action={getUserInProgressResponsesAction}
|
||||||
|
queryKey="doctor-in-progress-jobs"
|
||||||
|
/>
|
||||||
|
</PageBody>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DoctorGuard(MyReviewsPage);
|
||||||
22
app/doctor/open-jobs/page.tsx
Normal file
22
app/doctor/open-jobs/page.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { getOpenResponsesAction } from '@kit/doctor/actions/table-data-fetching-actions';
|
||||||
|
import { PageBody, PageHeader } from '@kit/ui/page';
|
||||||
|
|
||||||
|
import { DoctorGuard } from '../_components/doctor-guard';
|
||||||
|
import ResultsTableWrapper from '../_components/results-table-wrapper';
|
||||||
|
|
||||||
|
async function OpenJobsPage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHeader />
|
||||||
|
<PageBody>
|
||||||
|
<ResultsTableWrapper
|
||||||
|
titleKey="doctor:openReviews"
|
||||||
|
action={getOpenResponsesAction}
|
||||||
|
queryKey="doctor-open-jobs"
|
||||||
|
/>
|
||||||
|
</PageBody>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DoctorGuard(OpenJobsPage);
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
import { DoctorGuard } from '@kit/doctor/components/doctor-guard';
|
|
||||||
import { PageBody, PageHeader } from '@kit/ui/page';
|
import { PageBody, PageHeader } from '@kit/ui/page';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import Dashboard from './_components/doctor-dashboard';
|
||||||
|
import { DoctorGuard } from './_components/doctor-guard';
|
||||||
|
|
||||||
function DoctorPage() {
|
async function DoctorPage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageHeader description={<Trans i18nKey="common:doctor" />} />
|
<PageHeader />
|
||||||
|
|
||||||
<PageBody>
|
<PageBody>
|
||||||
<div>TBD</div>
|
<Dashboard />
|
||||||
</PageBody>
|
</PageBody>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { Heading } from '@kit/ui/heading';
|
|||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import { SiteHeader } from '~/(marketing)/_components/site-header';
|
import { SiteHeader } from '~/(marketing)/_components/site-header';
|
||||||
import { RootProviders } from '~/components/root-providers';
|
import { RootProviders } from '@kit/shared/components/root-providers';
|
||||||
|
|
||||||
const GlobalErrorPage = ({
|
const GlobalErrorPage = ({
|
||||||
error,
|
error,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import React, { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
import { ArrowDown } from 'lucide-react';
|
import { ArrowDown } from 'lucide-react';
|
||||||
|
|
||||||
import { cn } from '@kit/ui/utils';
|
import { cn } from '@kit/ui/utils';
|
||||||
import { UserAnalysisElement } from '@/packages/features/accounts/src/types/accounts';
|
import { AnalysisResultForDisplay } from './analysis';
|
||||||
|
|
||||||
export enum AnalysisResultLevel {
|
export enum AnalysisResultLevel {
|
||||||
VERY_LOW = 0,
|
VERY_LOW = 0,
|
||||||
@@ -63,7 +63,7 @@ const AnalysisLevelBar = ({
|
|||||||
normLowerIncluded?: boolean;
|
normLowerIncluded?: boolean;
|
||||||
normUpperIncluded?: boolean;
|
normUpperIncluded?: boolean;
|
||||||
level: AnalysisResultLevel;
|
level: AnalysisResultLevel;
|
||||||
results: UserAnalysisElement;
|
results: AnalysisResultForDisplay;
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
const { norm_lower: lower, norm_upper: upper, response_value: value } = results;
|
const { norm_lower: lower, norm_upper: upper, response_value: value } = results;
|
||||||
|
|||||||
@@ -16,6 +16,18 @@ import AnalysisLevelBar, {
|
|||||||
AnalysisResultLevel,
|
AnalysisResultLevel,
|
||||||
} from './analysis-level-bar';
|
} from './analysis-level-bar';
|
||||||
|
|
||||||
|
export type AnalysisResultForDisplay = Pick<
|
||||||
|
UserAnalysisElement,
|
||||||
|
| 'norm_status'
|
||||||
|
| 'response_value'
|
||||||
|
| 'unit'
|
||||||
|
| 'norm_lower_included'
|
||||||
|
| 'norm_upper_included'
|
||||||
|
| 'norm_lower'
|
||||||
|
| 'norm_upper'
|
||||||
|
| 'response_time'
|
||||||
|
>;
|
||||||
|
|
||||||
export enum AnalysisStatus {
|
export enum AnalysisStatus {
|
||||||
NORMAL = 0,
|
NORMAL = 0,
|
||||||
MEDIUM = 1,
|
MEDIUM = 1,
|
||||||
@@ -26,8 +38,8 @@ const Analysis = ({
|
|||||||
analysisElement,
|
analysisElement,
|
||||||
results,
|
results,
|
||||||
}: {
|
}: {
|
||||||
analysisElement: AnalysisElement;
|
analysisElement: Pick<AnalysisElement, 'analysis_name_lab'>;
|
||||||
results?: UserAnalysisElement;
|
results?: AnalysisResultForDisplay;
|
||||||
}) => {
|
}) => {
|
||||||
const name = analysisElement.analysis_name_lab || '';
|
const name = analysisElement.analysis_name_lab || '';
|
||||||
const status = results?.norm_status || AnalysisStatus.NORMAL;
|
const status = results?.norm_status || AnalysisStatus.NORMAL;
|
||||||
|
|||||||
@@ -9,17 +9,18 @@ import { Trans } from '@kit/ui/makerkit/trans';
|
|||||||
import { PageBody } from '@kit/ui/page';
|
import { PageBody } from '@kit/ui/page';
|
||||||
import { Button } from '@kit/ui/shadcn/button';
|
import { Button } from '@kit/ui/shadcn/button';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { getAnalysisElements } from '~/lib/services/analysis-element.service';
|
import { getAnalysisElements } from '~/lib/services/analysis-element.service';
|
||||||
import {
|
import {
|
||||||
PAGE_VIEW_ACTION,
|
PAGE_VIEW_ACTION,
|
||||||
createPageViewLog,
|
createPageViewLog,
|
||||||
} from '~/lib/services/audit/pageView.service';
|
} from '~/lib/services/audit/pageView.service';
|
||||||
import { AnalysisOrder, getAnalysisOrders } from '~/lib/services/order.service';
|
import { AnalysisOrder, getAnalysisOrders } from '~/lib/services/order.service';
|
||||||
import { ButtonTooltip } from '~/components/ui/button-tooltip';
|
import { ButtonTooltip } from '@kit/shared/components/ui/button-tooltip';
|
||||||
|
|
||||||
import Analysis from './_components/analysis';
|
|
||||||
import { loadUserAnalysis } from '../../_lib/server/load-user-analysis';
|
import { loadUserAnalysis } from '../../_lib/server/load-user-analysis';
|
||||||
|
import Analysis from './_components/analysis';
|
||||||
|
|
||||||
export const generateMetadata = async () => {
|
export const generateMetadata = async () => {
|
||||||
const i18n = await createI18nServerInstance();
|
const i18n = await createI18nServerInstance();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Trans } from '@kit/ui/trans';
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
||||||
import OrderCards from '../../_components/order-cards';
|
import OrderCards from '../../_components/order-cards';
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,16 @@ import { use } from 'react';
|
|||||||
|
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
|
|
||||||
|
import { retrieveCart } from '@lib/data/cart';
|
||||||
|
import { StoreCart } from '@medusajs/types';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { UserWorkspaceContextProvider } from '@kit/accounts/components';
|
import { UserWorkspaceContextProvider } from '@kit/accounts/components';
|
||||||
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
import { personalAccountNavigationConfig } from '@kit/shared/config';
|
||||||
import { Page, PageMobileNavigation, PageNavigation } from '@kit/ui/page';
|
import { Page, PageMobileNavigation, PageNavigation } from '@kit/ui/page';
|
||||||
import { SidebarProvider } from '@kit/ui/shadcn-sidebar';
|
import { SidebarProvider } from '@kit/ui/shadcn-sidebar';
|
||||||
import { StoreCart } from '@medusajs/types';
|
|
||||||
import { retrieveCart } from '@lib/data/cart';
|
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
|
||||||
import { personalAccountNavigationConfig } from '~/config/personal-account-navigation.config';
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
// home imports
|
// home imports
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ import { Scale } from 'lucide-react';
|
|||||||
|
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
import { Button } from '@kit/ui/button';
|
import { Button } from '@kit/ui/button';
|
||||||
import SelectAnalysisPackages from '@/components/select-analysis-packages';
|
import SelectAnalysisPackages from '@kit/shared/components/select-analysis-packages';
|
||||||
import { PageBody } from '@kit/ui/page';
|
import { PageBody } from '@kit/ui/page';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
import { PageBody } from '@kit/ui/page';
|
import { PageBody } from '@kit/ui/page';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
import { PageBody } from '@kit/ui/page';
|
import { PageBody } from '@kit/ui/page';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ import { PageBody, PageHeader } from '@kit/ui/page';
|
|||||||
|
|
||||||
import { createI18nServerInstance } from '@/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '@/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
import { getOrder } from '~/lib/services/order.service';
|
import { getOrder } from '~/lib/services/order.service';
|
||||||
import { retrieveOrder } from '@lib/data/orders';
|
import { retrieveOrder } from '@lib/data/orders';
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import Divider from "@modules/common/components/divider"
|
import Divider from "@modules/common/components/divider"
|
||||||
import OrderDetails from '@/app/home/(user)/_components/order/order-details';
|
import OrderDetails from '@/app/home/(user)/_components/order/order-details';
|
||||||
import OrderItems from '@/app/home/(user)/_components/order/order-items';
|
import OrderItems from '@/app/home/(user)/_components/order/order-items';
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ import { PageBody, PageHeader } from '@kit/ui/page';
|
|||||||
|
|
||||||
import { createI18nServerInstance } from '@/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '@/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
import { getOrder } from '~/lib/services/order.service';
|
import { getOrder } from '~/lib/services/order.service';
|
||||||
import { retrieveOrder } from '@lib/data/orders';
|
import { retrieveOrder } from '@lib/data/orders';
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import Divider from "@modules/common/components/divider"
|
import Divider from "@modules/common/components/divider"
|
||||||
import OrderDetails from '@/app/home/(user)/_components/order/order-details';
|
import OrderDetails from '@/app/home/(user)/_components/order/order-details';
|
||||||
import OrderItems from '@/app/home/(user)/_components/order/order-items';
|
import OrderItems from '@/app/home/(user)/_components/order/order-items';
|
||||||
|
|||||||
@@ -4,14 +4,15 @@ import { listOrders } from '~/medusa/lib/data/orders';
|
|||||||
import { createI18nServerInstance } from '@/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '@/lib/i18n/i18n.server';
|
||||||
import { listProductTypes } from '@lib/data/products';
|
import { listProductTypes } from '@lib/data/products';
|
||||||
import { PageBody } from '@kit/ui/makerkit/page';
|
import { PageBody } from '@kit/ui/makerkit/page';
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
|
||||||
import { getAnalysisOrders } from '~/lib/services/order.service';
|
import { getAnalysisOrders } from '~/lib/services/order.service';
|
||||||
import OrderBlock from '../../_components/orders/order-block';
|
import OrderBlock from '../../_components/orders/order-block';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Divider } from '@medusajs/ui';
|
import { Divider } from '@medusajs/ui';
|
||||||
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
export async function generateMetadata() {
|
export async function generateMetadata() {
|
||||||
const { t } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ import {
|
|||||||
TableRow,
|
TableRow,
|
||||||
} from '@kit/ui/table';
|
} from '@kit/ui/table';
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { PackageHeader } from '@kit/shared/components/package-header';
|
||||||
import { PackageHeader } from '@/components/package-header';
|
import { InfoTooltip } from '@kit/shared/components/ui/info-tooltip';
|
||||||
import { InfoTooltip } from '@/components/ui/info-tooltip';
|
|
||||||
import { StoreProduct } from '@medusajs/types';
|
import { StoreProduct } from '@medusajs/types';
|
||||||
import { getAnalysisElementMedusaProductIds } from '@/utils/medusa-product';
|
import { getAnalysisElementMedusaProductIds } from '@/utils/medusa-product';
|
||||||
|
import { withI18n } from '@/lib/i18n/with-i18n';
|
||||||
|
|
||||||
const CheckWithBackground = () => {
|
const CheckWithBackground = () => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
import { InfoTooltip } from '@/components/ui/info-tooltip';
|
|
||||||
import type { AccountWithParams } from '@/packages/features/accounts/src/server/api';
|
import type { AccountWithParams } from '@/packages/features/accounts/src/server/api';
|
||||||
import { Database } from '@/packages/supabase/src/database.types';
|
import { Database } from '@/packages/supabase/src/database.types';
|
||||||
import { BlendingModeIcon, RulerHorizontalIcon } from '@radix-ui/react-icons';
|
import { BlendingModeIcon, RulerHorizontalIcon } from '@radix-ui/react-icons';
|
||||||
import Isikukood from 'isikukood';
|
|
||||||
import {
|
import {
|
||||||
Activity,
|
Activity,
|
||||||
Clock9,
|
Clock9,
|
||||||
@@ -17,6 +15,8 @@ import {
|
|||||||
User,
|
User,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
|
import { InfoTooltip } from '@kit/shared/components/ui/info-tooltip';
|
||||||
|
import { getPersonParameters } from '@kit/shared/utils';
|
||||||
import { Button } from '@kit/ui/button';
|
import { Button } from '@kit/ui/button';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@@ -147,19 +147,6 @@ const dummyRecommendations = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const getPersonParameters = (personalCode: string) => {
|
|
||||||
try {
|
|
||||||
const person = new Isikukood(personalCode);
|
|
||||||
return {
|
|
||||||
gender: person.getGender(),
|
|
||||||
age: person.getAge(),
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function Dashboard({
|
export default function Dashboard({
|
||||||
account,
|
account,
|
||||||
bmiThresholds,
|
bmiThresholds,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { useRouter } from 'next/navigation';
|
|||||||
import { AccountSelector } from '@kit/accounts/account-selector';
|
import { AccountSelector } from '@kit/accounts/account-selector';
|
||||||
import { SidebarContext } from '@kit/ui/shadcn-sidebar';
|
import { SidebarContext } from '@kit/ui/shadcn-sidebar';
|
||||||
|
|
||||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
import { pathsConfig, featureFlagsConfig } from '@kit/shared/config';
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
|
|
||||||
const features = {
|
const features = {
|
||||||
enableTeamCreation: featureFlagsConfig.enableTeamCreation,
|
enableTeamCreation: featureFlagsConfig.enableTeamCreation,
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import Link from 'next/link';
|
|||||||
import { ShoppingCart } from 'lucide-react';
|
import { ShoppingCart } from 'lucide-react';
|
||||||
|
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container';
|
import { ProfileAccountDropdownContainer } from '@kit/shared/components/personal-account-dropdown-container';
|
||||||
import { Search } from '~/components/ui/search';
|
import { Search } from '@kit/shared/components/ui/search';
|
||||||
import { SIDEBAR_WIDTH_PROPERTY } from '@/packages/ui/src/shadcn/constants';
|
import { SIDEBAR_WIDTH_PROPERTY } from '@/packages/ui/src/shadcn/constants';
|
||||||
import { Button } from '@kit/ui/button';
|
import { Button } from '@kit/ui/button';
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,13 @@
|
|||||||
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
import { StoreCart } from '@medusajs/types';
|
||||||
import { LogOut, Menu, ShoppingCart } from 'lucide-react';
|
import { LogOut, Menu, ShoppingCart } from 'lucide-react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
featureFlagsConfig,
|
||||||
|
personalAccountNavigationConfig,
|
||||||
|
} from '@kit/shared/config';
|
||||||
import { useSignOut } from '@kit/supabase/hooks/use-sign-out';
|
import { useSignOut } from '@kit/supabase/hooks/use-sign-out';
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
@@ -16,16 +21,15 @@ import {
|
|||||||
} from '@kit/ui/dropdown-menu';
|
} from '@kit/ui/dropdown-menu';
|
||||||
import { If } from '@kit/ui/if';
|
import { If } from '@kit/ui/if';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
import { StoreCart } from '@medusajs/types';
|
|
||||||
|
|
||||||
import featuresFlagConfig from '~/config/feature-flags.config';
|
|
||||||
import { personalAccountNavigationConfig } from '~/config/personal-account-navigation.config';
|
|
||||||
|
|
||||||
// home imports
|
// home imports
|
||||||
import { HomeAccountSelector } from '../_components/home-account-selector';
|
import { HomeAccountSelector } from '../_components/home-account-selector';
|
||||||
import type { UserWorkspace } from '../_lib/server/load-user-workspace';
|
import type { UserWorkspace } from '../_lib/server/load-user-workspace';
|
||||||
|
|
||||||
export function HomeMobileNavigation(props: { workspace: UserWorkspace, cart: StoreCart | null }) {
|
export function HomeMobileNavigation(props: {
|
||||||
|
workspace: UserWorkspace;
|
||||||
|
cart: StoreCart | null;
|
||||||
|
}) {
|
||||||
const signOut = useSignOut();
|
const signOut = useSignOut();
|
||||||
|
|
||||||
const Links = personalAccountNavigationConfig.routes.map((item, index) => {
|
const Links = personalAccountNavigationConfig.routes.map((item, index) => {
|
||||||
@@ -47,7 +51,6 @@ export function HomeMobileNavigation(props: { workspace: UserWorkspace, cart: St
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const cartItemsCount = props.cart?.items?.length ?? 0;
|
const cartItemsCount = props.cart?.items?.length ?? 0;
|
||||||
const hasCartItems = cartItemsCount > 0;
|
const hasCartItems = cartItemsCount > 0;
|
||||||
|
|
||||||
@@ -58,7 +61,7 @@ export function HomeMobileNavigation(props: { workspace: UserWorkspace, cart: St
|
|||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
|
|
||||||
<DropdownMenuContent sideOffset={10} className={'w-screen rounded-none'}>
|
<DropdownMenuContent sideOffset={10} className={'w-screen rounded-none'}>
|
||||||
<If condition={featuresFlagConfig.enableTeamAccounts}>
|
<If condition={featureFlagsConfig.enableTeamAccounts}>
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuLabel>
|
<DropdownMenuLabel>
|
||||||
<Trans i18nKey={'common:yourAccounts'} />
|
<Trans i18nKey={'common:yourAccounts'} />
|
||||||
@@ -113,7 +116,11 @@ function DropdownLink(
|
|||||||
{props.Icon}
|
{props.Icon}
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<Trans i18nKey={props.label} defaults={props.label} values={props.labelOptions} />
|
<Trans
|
||||||
|
i18nKey={props.label}
|
||||||
|
defaults={props.label}
|
||||||
|
values={props.labelOptions}
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { personalAccountNavigationConfig } from '@kit/shared/config';
|
||||||
import {
|
import {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
SidebarContent,
|
SidebarContent,
|
||||||
@@ -6,8 +7,6 @@ import {
|
|||||||
} from '@kit/ui/shadcn-sidebar';
|
} from '@kit/ui/shadcn-sidebar';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import { personalAccountNavigationConfig } from '~/config/personal-account-navigation.config';
|
|
||||||
|
|
||||||
export function HomeSidebar() {
|
export function HomeSidebar() {
|
||||||
const collapsible = personalAccountNavigationConfig.sidebarCollapsedStyle;
|
const collapsible = personalAccountNavigationConfig.sidebarCollapsedStyle;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { StoreProduct, StoreProductVariant } from '@medusajs/types';
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { handleAddToCart } from '~/lib/services/medusaCart.service';
|
import { handleAddToCart } from '~/lib/services/medusaCart.service';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { InfoTooltip } from '~/components/ui/info-tooltip';
|
import { InfoTooltip } from '@kit/shared/components/ui/info-tooltip';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
export default function OrderAnalysesCards({
|
export default function OrderAnalysesCards({
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
import { NotificationsPopover } from '@kit/notifications/components';
|
import { NotificationsPopover } from '@kit/notifications/components';
|
||||||
|
import { featureFlagsConfig } from '@kit/shared/config';
|
||||||
import featuresFlagConfig from '~/config/feature-flags.config';
|
|
||||||
|
|
||||||
export function UserNotifications(props: { userId: string }) {
|
export function UserNotifications(props: { userId: string }) {
|
||||||
if (!featuresFlagConfig.enableNotifications) {
|
if (!featureFlagsConfig.enableNotifications) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NotificationsPopover
|
<NotificationsPopover
|
||||||
accountIds={[props.userId]}
|
accountIds={[props.userId]}
|
||||||
realtime={featuresFlagConfig.realtimeNotifications}
|
realtime={featureFlagsConfig.realtimeNotifications}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import { createAccountsApi } from '@kit/accounts/api';
|
|||||||
import { UserAnalysis } from '@kit/accounts/types/accounts';
|
import { UserAnalysis } from '@kit/accounts/types/accounts';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
export type UserAccount = Awaited<ReturnType<typeof loadUserAnalysis>>;
|
export type UserAnalyses = Awaited<ReturnType<typeof loadUserAnalysis>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name loadUserAccount
|
* @name loadUserAnalysis
|
||||||
* @description
|
* @description
|
||||||
* Load the user account. It's a cached per-request function that fetches the user workspace data.
|
* Load the user's analyses. It's a cached per-request function that fetches the user workspace data.
|
||||||
* It can be used across the server components to load the user workspace data.
|
* It can be used across the server components to load the user workspace data.
|
||||||
*/
|
*/
|
||||||
export const loadUserAnalysis = cache(analysisLoader);
|
export const loadUserAnalysis = cache(analysisLoader);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { cache } from 'react';
|
import { cache } from 'react';
|
||||||
|
|
||||||
import { createAccountsApi } from '@kit/accounts/api';
|
import { createAccountsApi } from '@kit/accounts/api';
|
||||||
|
import { featureFlagsConfig } from '@kit/shared/config';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
|
||||||
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
||||||
|
|
||||||
const shouldLoadAccounts = featureFlagsConfig.enableTeamAccounts;
|
const shouldLoadAccounts = featureFlagsConfig.enableTeamAccounts;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
import { If } from '@kit/ui/if';
|
import { If } from '@kit/ui/if';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import billingConfig from '~/config/billing.config';
|
import { billingConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { createPersonalAccountCheckoutSession } from '../_lib/server/server-actions';
|
import { createPersonalAccountCheckoutSession } from '../_lib/server/server-actions';
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import { redirect } from 'next/navigation';
|
|||||||
import { enhanceAction } from '@kit/next/actions';
|
import { enhanceAction } from '@kit/next/actions';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
|
||||||
|
|
||||||
import { PersonalAccountCheckoutSchema } from '../schema/personal-account-checkout.schema';
|
import { PersonalAccountCheckoutSchema } from '../schema/personal-account-checkout.schema';
|
||||||
import { createUserBillingService } from './user-billing.service';
|
import { createUserBillingService } from './user-billing.service';
|
||||||
|
import { featureFlagsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name enabled
|
* @name enabled
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import { getBillingGatewayProvider } from '@kit/billing-gateway';
|
|||||||
import { getLogger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { requireUser } from '@kit/supabase/require-user';
|
import { requireUser } from '@kit/supabase/require-user';
|
||||||
|
|
||||||
import appConfig from '~/config/app.config';
|
import { appConfig, billingConfig } from '@kit/shared/config';
|
||||||
import billingConfig from '~/config/billing.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
|
|
||||||
import { PersonalAccountCheckoutSchema } from '../schema/personal-account-checkout.schema';
|
import { PersonalAccountCheckoutSchema } from '../schema/personal-account-checkout.schema';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { featureFlagsConfig } from '@kit/shared/config';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
|
||||||
|
|
||||||
function UserBillingLayout(props: React.PropsWithChildren) {
|
function UserBillingLayout(props: React.PropsWithChildren) {
|
||||||
const isEnabled = featureFlagsConfig.enablePersonalAccountBilling;
|
const isEnabled = featureFlagsConfig.enablePersonalAccountBilling;
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import { If } from '@kit/ui/if';
|
|||||||
import { PageBody } from '@kit/ui/page';
|
import { PageBody } from '@kit/ui/page';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import billingConfig from '~/config/billing.config';
|
import { billingConfig } from '@kit/shared/config';
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
|
||||||
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
||||||
|
|
||||||
// local imports
|
// local imports
|
||||||
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
import { HomeLayoutPageHeader } from '../_components/home-page-header';
|
import { HomeLayoutPageHeader } from '../_components/home-page-header';
|
||||||
import { createPersonalAccountBillingPortalSession } from '../billing/_lib/server/server-actions';
|
import { createPersonalAccountBillingPortalSession } from '../billing/_lib/server/server-actions';
|
||||||
import { PersonalAccountCheckoutForm } from './_components/personal-account-checkout-form';
|
import { PersonalAccountCheckoutForm } from './_components/personal-account-checkout-form';
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Trans } from '@kit/ui/trans';
|
|||||||
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
// local imports
|
// local imports
|
||||||
import { HomeLayoutPageHeader } from '../_components/home-page-header';
|
import { HomeLayoutPageHeader } from '../_components/home-page-header';
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import { use } from 'react';
|
import { use } from 'react';
|
||||||
|
|
||||||
import { PersonalAccountSettingsContainer } from '@kit/accounts/personal-account-settings';
|
import { PersonalAccountSettingsContainer } from '@kit/accounts/personal-account-settings';
|
||||||
|
import {
|
||||||
|
authConfig,
|
||||||
|
featureFlagsConfig,
|
||||||
|
pathsConfig,
|
||||||
|
} from '@kit/shared/config';
|
||||||
import { PageBody } from '@kit/ui/page';
|
import { PageBody } from '@kit/ui/page';
|
||||||
|
|
||||||
import authConfig from '~/config/auth.config';
|
|
||||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
|
||||||
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
||||||
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
const features = {
|
const features = {
|
||||||
enableAccountDeletion: featureFlagsConfig.enableAccountDeletion,
|
enableAccountDeletion: featureFlagsConfig.enableAccountDeletion,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { useRouter } from 'next/navigation';
|
|||||||
import { AccountSelector } from '@kit/accounts/account-selector';
|
import { AccountSelector } from '@kit/accounts/account-selector';
|
||||||
import { SidebarContext } from '@kit/ui/shadcn-sidebar';
|
import { SidebarContext } from '@kit/ui/shadcn-sidebar';
|
||||||
|
|
||||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
import { pathsConfig, featureFlagsConfig } from '@kit/shared/config';
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
|
|
||||||
const features = {
|
const features = {
|
||||||
enableTeamCreation: featureFlagsConfig.enableTeamCreation,
|
enableTeamCreation: featureFlagsConfig.enableTeamCreation,
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ import { cn } from '@kit/ui/lib/utils';
|
|||||||
import { Button } from '@kit/ui/shadcn/button';
|
import { Button } from '@kit/ui/shadcn/button';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
import { createPath } from '~/config/team-account-navigation.config';
|
|
||||||
|
import { createPath } from '@kit/shared/config/team-account-navigation.config';
|
||||||
|
|
||||||
interface TeamAccountBenefitStatisticsProps {
|
interface TeamAccountBenefitStatisticsProps {
|
||||||
employeeCount: number;
|
employeeCount: number;
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ import { useRouter } from 'next/navigation';
|
|||||||
import { Home, LogOut, Menu } from 'lucide-react';
|
import { Home, LogOut, Menu } from 'lucide-react';
|
||||||
|
|
||||||
import { AccountSelector } from '@kit/accounts/account-selector';
|
import { AccountSelector } from '@kit/accounts/account-selector';
|
||||||
|
import {
|
||||||
|
featureFlagsConfig,
|
||||||
|
getTeamAccountSidebarConfig,
|
||||||
|
pathsConfig,
|
||||||
|
} from '@kit/shared/config';
|
||||||
import { useSignOut } from '@kit/supabase/hooks/use-sign-out';
|
import { useSignOut } from '@kit/supabase/hooks/use-sign-out';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -23,10 +28,6 @@ import {
|
|||||||
} from '@kit/ui/dropdown-menu';
|
} from '@kit/ui/dropdown-menu';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
import { getTeamAccountSidebarConfig } from '~/config/team-account-navigation.config';
|
|
||||||
|
|
||||||
type Accounts = Array<{
|
type Accounts = Array<{
|
||||||
label: string | null;
|
label: string | null;
|
||||||
value: string | null;
|
value: string | null;
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import {
|
|||||||
SidebarHeader,
|
SidebarHeader,
|
||||||
} from '@kit/ui/shadcn-sidebar';
|
} from '@kit/ui/shadcn-sidebar';
|
||||||
|
|
||||||
import { ProfileAccountDropdownContainer } from '~/components//personal-account-dropdown-container';
|
import { ProfileAccountDropdownContainer } from '@kit/shared/components//personal-account-dropdown-container';
|
||||||
import { getTeamAccountSidebarConfig } from '~/config/team-account-navigation.config';
|
import { getTeamAccountSidebarConfig } from '@kit/shared/config/team-account-navigation.config';
|
||||||
import { TeamAccountNotifications } from '~/home/[account]/_components/team-account-notifications';
|
import { TeamAccountNotifications } from '~/home/[account]/_components/team-account-notifications';
|
||||||
|
|
||||||
import { TeamAccountAccountsSelector } from '../_components/team-account-accounts-selector';
|
import { TeamAccountAccountsSelector } from '../_components/team-account-accounts-selector';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container';
|
import { ProfileAccountDropdownContainer } from '@kit/shared/components/personal-account-dropdown-container';
|
||||||
import { getTeamAccountSidebarConfig } from '~/config/team-account-navigation.config';
|
import { getTeamAccountSidebarConfig } from '@kit/shared/config/team-account-navigation.config';
|
||||||
|
|
||||||
// local imports
|
// local imports
|
||||||
import { TeamAccountWorkspace } from '../_lib/server/team-account-workspace.loader';
|
import { TeamAccountWorkspace } from '../_lib/server/team-account-workspace.loader';
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
import { NotificationsPopover } from '@kit/notifications/components';
|
import { NotificationsPopover } from '@kit/notifications/components';
|
||||||
|
|
||||||
import featuresFlagConfig from '~/config/feature-flags.config';
|
import { featureFlagsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
|
|
||||||
export function TeamAccountNotifications(params: {
|
export function TeamAccountNotifications(params: {
|
||||||
userId: string;
|
userId: string;
|
||||||
accountId: string;
|
accountId: string;
|
||||||
}) {
|
}) {
|
||||||
if (!featuresFlagConfig.enableNotifications) {
|
if (!featureFlagsConfig.enableNotifications) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NotificationsPopover
|
<NotificationsPopover
|
||||||
accountIds={[params.userId, params.accountId]}
|
accountIds={[params.userId, params.accountId]}
|
||||||
realtime={featuresFlagConfig.realtimeNotifications}
|
realtime={featureFlagsConfig.realtimeNotifications}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ import {
|
|||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
} from '@kit/ui/shadcn/popover';
|
} from '@kit/ui/shadcn/popover';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
import { createPath } from '~/config/team-account-navigation.config';
|
|
||||||
|
import { createPath } from '@kit/shared/config/team-account-navigation.config';
|
||||||
|
|
||||||
import TeamAccountBenefitStatistics from './team-account-benefit-statistics';
|
import TeamAccountBenefitStatistics from './team-account-benefit-statistics';
|
||||||
import TeamAccountHealthDetails from './team-account-health-details';
|
import TeamAccountHealthDetails from './team-account-health-details';
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import { redirect } from 'next/navigation';
|
|||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
import { createTeamAccountsApi } from '@kit/team-accounts/api';
|
import { createTeamAccountsApi } from '@kit/team-accounts/api';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
||||||
|
|
||||||
export type TeamAccountWorkspace = Awaited<
|
export type TeamAccountWorkspace = Awaited<
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
} from '@kit/ui/card';
|
} from '@kit/ui/card';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import billingConfig from '~/config/billing.config';
|
import { billingConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { createTeamAccountCheckoutSession } from '../_lib/server/server-actions';
|
import { createTeamAccountCheckoutSession } from '../_lib/server/server-actions';
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import { redirect } from 'next/navigation';
|
|||||||
import { UpdateHealthBenefitData } from '@/packages/features/team-accounts/src/server/types';
|
import { UpdateHealthBenefitData } from '@/packages/features/team-accounts/src/server/types';
|
||||||
|
|
||||||
import { enhanceAction } from '@kit/next/actions';
|
import { enhanceAction } from '@kit/next/actions';
|
||||||
|
import { featureFlagsConfig } from '@kit/shared/config';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
|
||||||
|
|
||||||
// billing imports
|
// billing imports
|
||||||
import {
|
import {
|
||||||
TeamBillingPortalSchema,
|
TeamBillingPortalSchema,
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ import { requireUser } from '@kit/supabase/require-user';
|
|||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
import { createTeamAccountsApi } from '@kit/team-accounts/api';
|
import { createTeamAccountsApi } from '@kit/team-accounts/api';
|
||||||
|
|
||||||
import appConfig from '~/config/app.config';
|
import appConfig from '@kit/shared/config/app.config';
|
||||||
import billingConfig from '~/config/billing.config';
|
import { billingConfig } from '@kit/shared/config';
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
|
|
||||||
import { TeamCheckoutSchema } from '../schema/team-billing.schema';
|
import { TeamCheckoutSchema } from '../schema/team-billing.schema';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
import { featureFlagsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
function TeamAccountBillingLayout(props: React.PropsWithChildren) {
|
function TeamAccountBillingLayout(props: React.PropsWithChildren) {
|
||||||
const isEnabled = featureFlagsConfig.enableTeamAccountBilling;
|
const isEnabled = featureFlagsConfig.enableTeamAccountBilling;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { PageBody } from '@kit/ui/page';
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
import HealthBenefitForm from './_components/health-benefit-form';
|
import HealthBenefitForm from './_components/health-benefit-form';
|
||||||
|
|
||||||
interface TeamAccountBillingPageProps {
|
interface TeamAccountBillingPageProps {
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { notFound, redirect } from 'next/navigation';
|
|||||||
|
|
||||||
import { getBillingGatewayProvider } from '@kit/billing-gateway';
|
import { getBillingGatewayProvider } from '@kit/billing-gateway';
|
||||||
import { BillingSessionStatus } from '@kit/billing-gateway/components';
|
import { BillingSessionStatus } from '@kit/billing-gateway/components';
|
||||||
|
import { billingConfig } from '@kit/shared/config';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
|
|
||||||
import billingConfig from '~/config/billing.config';
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
|
||||||
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
||||||
|
|
||||||
import { EmbeddedCheckoutForm } from '../_components/embedded-checkout-form';
|
import { EmbeddedCheckoutForm } from '../_components/embedded-checkout-form';
|
||||||
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
interface SessionPageProps {
|
interface SessionPageProps {
|
||||||
searchParams: Promise<{
|
searchParams: Promise<{
|
||||||
|
|||||||
@@ -4,22 +4,20 @@ import { cookies } from 'next/headers';
|
|||||||
|
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
import { getTeamAccountSidebarConfig } from '@kit/shared/config';
|
||||||
import {
|
import {
|
||||||
CompanyGuard,
|
CompanyGuard,
|
||||||
TeamAccountWorkspaceContextProvider,
|
TeamAccountWorkspaceContextProvider,
|
||||||
} from '@kit/team-accounts/components';
|
} from '@kit/team-accounts/components';
|
||||||
import { Page, PageMobileNavigation, PageNavigation } from '@kit/ui/page';
|
import { Page, PageMobileNavigation, PageNavigation } from '@kit/ui/page';
|
||||||
import { SidebarProvider } from '@kit/ui/shadcn-sidebar';
|
import { SidebarProvider } from '@kit/ui/shadcn-sidebar';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
|
||||||
import { getTeamAccountSidebarConfig } from '~/config/team-account-navigation.config';
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
|
||||||
|
|
||||||
// local imports
|
// local imports
|
||||||
import { TeamAccountLayoutMobileNavigation } from './_components/team-account-layout-mobile-navigation';
|
import { TeamAccountLayoutMobileNavigation } from './_components/team-account-layout-mobile-navigation';
|
||||||
import { TeamAccountLayoutSidebar } from './_components/team-account-layout-sidebar';
|
import { TeamAccountLayoutSidebar } from './_components/team-account-layout-sidebar';
|
||||||
import { TeamAccountNavigationMenu } from './_components/team-account-navigation-menu';
|
import { TeamAccountNavigationMenu } from './_components/team-account-navigation-menu';
|
||||||
import { loadTeamWorkspace } from './_lib/server/team-account-workspace.loader';
|
import { loadTeamWorkspace } from './_lib/server/team-account-workspace.loader';
|
||||||
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
type TeamWorkspaceLayoutProps = React.PropsWithChildren<{
|
type TeamWorkspaceLayoutProps = React.PropsWithChildren<{
|
||||||
params: Promise<{ account: string }>;
|
params: Promise<{ account: string }>;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { Trans } from '@kit/ui/trans';
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
// local imports
|
// local imports
|
||||||
import { TeamAccountLayoutPageHeader } from '../_components/team-account-layout-page-header';
|
import { TeamAccountLayoutPageHeader } from '../_components/team-account-layout-page-header';
|
||||||
import { loadMembersPageData } from './_lib/server/members-page.loader';
|
import { loadMembersPageData } from './_lib/server/members-page.loader';
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
|
|
||||||
import { Dashboard } from './_components/dashboard';
|
import { Dashboard } from './_components/dashboard';
|
||||||
import { TeamAccountLayoutPageHeader } from './_components/team-account-layout-page-header';
|
import { TeamAccountLayoutPageHeader } from './_components/team-account-layout-page-header';
|
||||||
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
interface TeamAccountHomePageProps {
|
interface TeamAccountHomePageProps {
|
||||||
params: Promise<{ account: string }>;
|
params: Promise<{ account: string }>;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { featureFlagsConfig, pathsConfig } from '@kit/shared/config';
|
||||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||||
import { createTeamAccountsApi } from '@kit/team-accounts/api';
|
import { createTeamAccountsApi } from '@kit/team-accounts/api';
|
||||||
import { TeamAccountSettingsContainer } from '@kit/team-accounts/components';
|
import { TeamAccountSettingsContainer } from '@kit/team-accounts/components';
|
||||||
@@ -5,8 +6,6 @@ import { AppBreadcrumbs } from '@kit/ui/app-breadcrumbs';
|
|||||||
import { PageBody } from '@kit/ui/page';
|
import { PageBody } from '@kit/ui/page';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import featuresFlagConfig from '~/config/feature-flags.config';
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
|
|
||||||
// local imports
|
// local imports
|
||||||
@@ -43,7 +42,7 @@ async function TeamAccountSettingsPage(props: TeamAccountSettingsPageProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const features = {
|
const features = {
|
||||||
enableTeamDeletion: featuresFlagConfig.enableTeamDeletion,
|
enableTeamDeletion: featureFlagsConfig.enableTeamDeletion,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ import { Button } from '@kit/ui/button';
|
|||||||
import { Heading } from '@kit/ui/heading';
|
import { Heading } from '@kit/ui/heading';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
import pathsConfig from '~/config/paths.config';
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
interface JoinTeamAccountPageProps {
|
interface JoinTeamAccountPageProps {
|
||||||
searchParams: Promise<{
|
searchParams: Promise<{
|
||||||
invite_token?: string;
|
invite_token?: string;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { headers } from 'next/headers';
|
import { headers } from 'next/headers';
|
||||||
|
|
||||||
|
import { RootProviders } from '@kit/shared/components/root-providers';
|
||||||
import { Toaster } from '@kit/ui/sonner';
|
import { Toaster } from '@kit/ui/sonner';
|
||||||
|
|
||||||
import { RootProviders } from '~/components/root-providers';
|
|
||||||
import { getFontsClassName } from '~/lib/fonts';
|
import { getFontsClassName } from '~/lib/fonts';
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
|
||||||
import { generateRootMetadata } from '~/lib/root-metdata';
|
import { generateRootMetadata } from '~/lib/root-metdata';
|
||||||
import { getRootTheme } from '~/lib/root-theme';
|
import { getRootTheme } from '~/lib/root-theme';
|
||||||
|
|
||||||
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import '../styles/globals.css';
|
import '../styles/globals.css';
|
||||||
|
|
||||||
export const generateMetadata = () => {
|
export const generateMetadata = () => {
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { Heading } from '@kit/ui/heading';
|
|||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
import { SiteHeader } from '~/(marketing)/_components/site-header';
|
import { SiteHeader } from '~/(marketing)/_components/site-header';
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
|
|
||||||
export const generateMetadata = async () => {
|
export const generateMetadata = async () => {
|
||||||
const i18n = await createI18nServerInstance();
|
const i18n = await createI18nServerInstance();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { MetadataRoute } from 'next';
|
import { MetadataRoute } from 'next';
|
||||||
|
|
||||||
import appConfig from '~/config/app.config';
|
import appConfig from '@kit/shared/config/app.config';
|
||||||
|
|
||||||
export default function robots(): MetadataRoute.Robots {
|
export default function robots(): MetadataRoute.Robots {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
import SelectAnalysisPackages from '@/components/select-analysis-packages';
|
import SelectAnalysisPackages from '@kit/shared/components/select-analysis-packages';
|
||||||
import { CaretRightIcon } from '@radix-ui/react-icons';
|
import { CaretRightIcon } from '@radix-ui/react-icons';
|
||||||
import { Scale } from 'lucide-react';
|
import { Scale } from 'lucide-react';
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@ import { Trans } from '@kit/ui/trans';
|
|||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
|
|
||||||
import { MedReportLogo } from '../../components/med-report-logo';
|
import { MedReportLogo } from '../../components/med-report-logo';
|
||||||
import pathsConfig from '../../config/paths.config';
|
import pathsConfig from '../../config/paths.config';
|
||||||
import ComparePackagesModal from '../home/(user)/_components/compare-packages-modal';
|
import ComparePackagesModal from '../home/(user)/_components/compare-packages-modal';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { getServerSideSitemap } from 'next-sitemap';
|
|||||||
|
|
||||||
import { createCmsClient } from '@kit/cms';
|
import { createCmsClient } from '@kit/cms';
|
||||||
|
|
||||||
import appConfig from '~/config/app.config';
|
import appConfig from '@kit/shared/config/app.config';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description The maximum age of the sitemap in seconds.
|
* @description The maximum age of the sitemap in seconds.
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { UpdatePasswordForm } from '@kit/auth/password-reset';
|
import { UpdatePasswordForm } from '@kit/auth/password-reset';
|
||||||
import { AuthLayoutShell } from '@kit/auth/shared';
|
import { AuthLayoutShell } from '@kit/auth/shared';
|
||||||
|
import { AppLogo } from '@kit/shared/components/app-logo';
|
||||||
|
import { pathsConfig } from '@kit/shared/config';
|
||||||
|
|
||||||
import { AppLogo } from '~/components/app-logo';
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
|
||||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
|
||||||
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
|
||||||
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
|
|
||||||
export const generateMetadata = async () => {
|
export const generateMetadata = async () => {
|
||||||
const { t } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user