File size: 6,957 Bytes
ec4551b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | 'use client';
import React, { ReactNode, useCallback } from 'react';
import { Logo } from '@gitroom/frontend/components/new-layout/logo';
import { Plus_Jakarta_Sans } from 'next/font/google';
const ModeComponent = dynamic(
() => import('@gitroom/frontend/components/layout/mode.component'),
{
ssr: false,
}
);
import clsx from 'clsx';
import dynamic from 'next/dynamic';
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
import { useVariables } from '@gitroom/react/helpers/variable.context';
import { useSearchParams } from 'next/navigation';
import useSWR from 'swr';
import { CheckPayment } from '@gitroom/frontend/components/layout/check.payment';
import { ToolTip } from '@gitroom/frontend/components/layout/top.tip';
import { ShowMediaBoxModal } from '@gitroom/frontend/components/media/media.component';
import { ShowLinkedinCompany } from '@gitroom/frontend/components/launches/helpers/linkedin.component';
import { MediaSettingsLayout } from '@gitroom/frontend/components/launches/helpers/media.settings.component';
import { Toaster } from '@gitroom/react/toaster/toaster';
import { ShowPostSelector } from '@gitroom/frontend/components/post-url-selector/post.url.selector';
import { NewSubscription } from '@gitroom/frontend/components/layout/new.subscription';
import { Support } from '@gitroom/frontend/components/layout/support';
import { ContinueProvider } from '@gitroom/frontend/components/layout/continue.provider';
import { ContextWrapper } from '@gitroom/frontend/components/layout/user.context';
import { CopilotKit } from '@copilotkit/react-core';
import { MantineWrapper } from '@gitroom/react/helpers/mantine.wrapper';
import { Impersonate } from '@gitroom/frontend/components/layout/impersonate';
import { AnnouncementBanner } from '@gitroom/frontend/components/layout/announcement.banner';
import { Title } from '@gitroom/frontend/components/layout/title';
import { TopMenu } from '@gitroom/frontend/components/layout/top.menu';
import { LanguageComponent } from '@gitroom/frontend/components/layout/language.component';
import { ChromeExtensionComponent } from '@gitroom/frontend/components/layout/chrome.extension.component';
import NotificationComponent from '@gitroom/frontend/components/notifications/notification.component';
import { OrganizationSelector } from '@gitroom/frontend/components/layout/organization.selector';
import { StreakComponent } from '@gitroom/frontend/components/layout/streak.component';
import { PreConditionComponent } from '@gitroom/frontend/components/layout/pre-condition.component';
import { AttachToFeedbackIcon } from '@gitroom/frontend/components/new-layout/sentry.feedback.component';
import { FirstBillingComponent } from '@gitroom/frontend/components/billing/first.billing.component';
import { TrialTracker } from '@gitroom/frontend/components/layout/gtm.component';
const jakartaSans = Plus_Jakarta_Sans({
weight: ['600', '500', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
});
export const LayoutComponent = ({ children }: { children: ReactNode }) => {
const fetch = useFetch();
const { backendUrl, billingEnabled, isGeneral } = useVariables();
// Feedback icon component attaches Sentry feedback to a top-bar icon when DSN is present
const searchParams = useSearchParams();
const load = useCallback(async (path: string) => {
return await (await fetch(path)).json();
}, []);
const { data: user, mutate } = useSWR('/user/self', load, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
revalidateIfStale: false,
refreshWhenOffline: false,
refreshWhenHidden: false,
});
if (!user) return null;
return (
<ContextWrapper user={user}>
<CopilotKit
credentials="include"
runtimeUrl={backendUrl + '/copilot/chat'}
showDevConsole={false}
>
<MantineWrapper>
<ToolTip />
<Toaster />
<TrialTracker />
<CheckPayment check={searchParams.get('check') || ''} mutate={mutate}>
<ShowMediaBoxModal />
<ShowLinkedinCompany />
<MediaSettingsLayout />
<ShowPostSelector />
<PreConditionComponent />
<NewSubscription />
<ContinueProvider />
<div
className={clsx(
'flex flex-col min-h-screen min-w-screen text-newTextColor p-[12px]',
jakartaSans.className
)}
>
<div>{user?.admin ? <Impersonate /> : <div />}</div>
{user.tier === 'FREE' && isGeneral && billingEnabled ? (
<FirstBillingComponent />
) : (
<>
<AnnouncementBanner />
<div className="flex-1 flex gap-[8px]">
<Support />
<div className="flex flex-col bg-newBgColorInner w-[80px] rounded-[12px]">
<div
id="left-menu"
className={clsx(
'fixed h-full w-[64px] start-[17px] flex flex-1 top-0',
user?.admin && 'pt-[60px] max-h-[1000px]:w-[500px]'
)}
>
<div className="flex flex-col h-full gap-[32px] flex-1 py-[12px]">
<Logo />
<TopMenu />
</div>
</div>
</div>
<div className="flex-1 bg-newBgLineColor rounded-[12px] overflow-hidden flex flex-col gap-[1px] blurMe">
<div className="flex bg-newBgColorInner h-[80px] px-[20px] items-center">
<div className="text-[24px] font-[600] flex flex-1">
<Title />
</div>
<div className="flex gap-[20px] text-textItemBlur">
<StreakComponent />
<div className="w-[1px] h-[20px] bg-blockSeparator" />
<OrganizationSelector />
<div className="hover:text-newTextColor">
<ModeComponent />
</div>
<div className="w-[1px] h-[20px] bg-blockSeparator" />
<LanguageComponent />
<ChromeExtensionComponent />
<div className="w-[1px] h-[20px] bg-blockSeparator" />
<AttachToFeedbackIcon />
<NotificationComponent />
</div>
</div>
<div className="flex flex-1 gap-[1px]">{children}</div>
</div>
</div>
</>
)}
</div>
</CheckPayment>
</MantineWrapper>
</CopilotKit>
</ContextWrapper>
);
};
|