diff --git a/frontend/src/components/navigation/NavHeader.tsx b/frontend/src/components/navigation/NavHeader.tsx
index bc3876750..68f591141 100644
--- a/frontend/src/components/navigation/NavHeader.tsx
+++ b/frontend/src/components/navigation/NavHeader.tsx
@@ -1,10 +1,7 @@
-import { useEffect, useState } from 'react';
-import { useRouter } from 'next/router';
import { faAngleRight } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { useWorkspace } from '@app/context';
-import getOrganization from '@app/pages/api/organization/GetOrg';
+import { useOrgnization, useWorkspace } from '@app/context';
/**
* This is the component at the top of almost every page.
@@ -22,28 +19,15 @@ export default function NavHeader({
pageName: string;
isProjectRelated?: boolean;
}): JSX.Element {
- const [orgName, setOrgName] = useState('');
- const router = useRouter();
- const projectId = String(router.query.id);
const { currentWorkspace } = useWorkspace();
-
- useEffect(() => {
- (async () => {
- const orgId = localStorage.getItem('orgData.id');
- const org = await getOrganization({
- orgId: orgId || ''
- });
- setOrgName(org.name);
- })();
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [projectId]);
+ const { currentOrg } = useOrgnization();
return (
- {orgName?.charAt(0)}
+ {currentOrg?.name?.charAt(0)}
-
{orgName}
+
{currentOrg?.name}
{isProjectRelated && (
<>
diff --git a/frontend/src/components/v2/Menu/Menu.tsx b/frontend/src/components/v2/Menu/Menu.tsx
index 1497b01fa..cb2625384 100644
--- a/frontend/src/components/v2/Menu/Menu.tsx
+++ b/frontend/src/components/v2/Menu/Menu.tsx
@@ -31,18 +31,19 @@ export const MenuItem =
({
as: Item = 'button',
description,
// wrapping in forward ref with generic component causes the loss of ts definitions on props
- inputRef
+ inputRef,
+ ...props
}: MenuItemProps & ComponentPropsWithRef): JSX.Element => (
- -
- {icon && {icon}}
+
-
+ {icon && {icon}}
{children}
{description && {description}}
diff --git a/frontend/src/components/v2/Select/Select.tsx b/frontend/src/components/v2/Select/Select.tsx
index 86ccc1079..ad0319619 100644
--- a/frontend/src/components/v2/Select/Select.tsx
+++ b/frontend/src/components/v2/Select/Select.tsx
@@ -12,13 +12,14 @@ type Props = {
className?: string;
dropdownContainerClassName?: string;
isLoading?: boolean;
+ position?: 'item-aligned' | 'popper';
};
export type SelectProps = SelectPrimitive.SelectProps & Props;
export const Select = forwardRef(
(
- { children, placeholder, className, isLoading, dropdownContainerClassName, ...props },
+ { children, placeholder, className, isLoading, dropdownContainerClassName, position, ...props },
ref
): JSX.Element => {
return (
@@ -44,6 +45,8 @@ export const Select = forwardRef(
'relative left-4 top-1 overflow-hidden rounded-md bg-bunker-800 font-inter text-bunker-100 shadow-md z-[100]',
dropdownContainerClassName
)}
+ position={position}
+ style={{ width: 'var(--radix-select-trigger-width)' }}
>
diff --git a/frontend/src/layouts/AppLayout/AppLayout.tsx b/frontend/src/layouts/AppLayout/AppLayout.tsx
new file mode 100644
index 000000000..ce5e362ce
--- /dev/null
+++ b/frontend/src/layouts/AppLayout/AppLayout.tsx
@@ -0,0 +1,431 @@
+/* eslint-disable no-nested-ternary */
+/* eslint-disable no-unexpected-multiline */
+/* eslint-disable react-hooks/exhaustive-deps */
+import crypto from 'crypto';
+
+import { useEffect, useState } from 'react';
+import { Controller, useForm } from 'react-hook-form';
+import Link from 'next/link';
+import { useRouter } from 'next/router';
+import { useTranslation } from 'next-i18next';
+import {
+ faBookOpen,
+ faFileLines,
+ faGear,
+ faKey,
+ faMobile,
+ faPlug,
+ faPlus,
+ faUser
+} from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { yupResolver } from '@hookform/resolvers/yup';
+import * as yup from 'yup';
+
+import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider';
+import onboardingCheck from '@app/components/utilities/checks/OnboardingCheck';
+import { tempLocalStorage } from '@app/components/utilities/checks/tempLocalStorage';
+import { encryptAssymmetric } from '@app/components/utilities/cryptography/crypto';
+import {
+ Button,
+ Checkbox,
+ FormControl,
+ Input,
+ Menu,
+ MenuItem,
+ Modal,
+ ModalContent,
+ Select,
+ SelectItem
+} from '@app/components/v2';
+import { useOrgnization, useUser, useWorkspace } from '@app/context';
+import { usePopUp } from '@app/hooks';
+import { fetchOrgUsers, useAddUserToWs, useCreateWorkspace, useUploadWsKey } from '@app/hooks/api';
+import getOrganizations from '@app/pages/api/organization/getOrgs';
+import getOrganizationUserProjects from '@app/pages/api/organization/GetOrgUserProjects';
+
+import { Navbar } from './components/NavBar';
+
+interface LayoutProps {
+ children: React.ReactNode;
+}
+
+const formSchema = yup.object({
+ name: yup.string().required().label('Project Name').trim(),
+ addMembers: yup.bool().required().label('Add Members')
+});
+
+type TAddProjectFormData = yup.InferType;
+
+export const AppLayout = ({ children }: LayoutProps) => {
+ const router = useRouter();
+ const { createNotification } = useNotificationContext();
+
+ const { workspaces, currentWorkspace } = useWorkspace();
+ const { currentOrg } = useOrgnization();
+ const { user } = useUser();
+
+ const createWs = useCreateWorkspace();
+ const uploadWsKey = useUploadWsKey();
+ const addWsUser = useAddUserToWs();
+
+ const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
+ 'addNewWs'
+ ] as const);
+ const {
+ control,
+ formState: { isSubmitting },
+ reset,
+ handleSubmit
+ } = useForm({
+ resolver: yupResolver(formSchema)
+ });
+
+ const [workspaceMapping, setWorkspaceMapping] = useState