diff --git a/app/@types/nextjs-routes.d.ts b/app/@types/nextjs-routes.d.ts
index fbccfff..79d87f2 100644
--- a/app/@types/nextjs-routes.d.ts
+++ b/app/@types/nextjs-routes.d.ts
@@ -25,6 +25,7 @@ declare module "nextjs-routes" {
| StaticRoute<"/home">
| StaticRoute<"/">
| StaticRoute<"/sentry-example-page">
+ | StaticRoute<"/settings">
| StaticRoute<"/world-champs">
| StaticRoute<"/world-champs/signup">;
diff --git a/app/src/components/nav/AppShell.tsx b/app/src/components/nav/AppShell.tsx
index 2356dca..4dcbdfc 100644
--- a/app/src/components/nav/AppShell.tsx
+++ b/app/src/components/nav/AppShell.tsx
@@ -12,7 +12,7 @@ import {
} from "@chakra-ui/react";
import Head from "next/head";
import Link from "next/link";
-import { BsGithub, BsPersonCircle } from "react-icons/bs";
+import { BsGearFill, BsGithub, BsPersonCircle } from "react-icons/bs";
import { RiDatabase2Line, RiFlaskLine } from "react-icons/ri";
import { signIn, useSession } from "next-auth/react";
import UserMenu from "./UserMenu";
@@ -76,6 +76,21 @@ const NavSidebar = () => {
)}
+
+
+ CONFIGURATION
+
+
+
+
+
{user && }
diff --git a/app/src/components/nav/PageHeaderContainer.tsx b/app/src/components/nav/PageHeaderContainer.tsx
new file mode 100644
index 0000000..944f33d
--- /dev/null
+++ b/app/src/components/nav/PageHeaderContainer.tsx
@@ -0,0 +1,15 @@
+import { Flex, type FlexProps } from "@chakra-ui/react";
+
+const PageHeaderContainer = (props: FlexProps) => {
+ return ;
+};
+
+export default PageHeaderContainer;
diff --git a/app/src/components/nav/UserMenu.tsx b/app/src/components/nav/UserMenu.tsx
index 7abf17b..8960e5b 100644
--- a/app/src/components/nav/UserMenu.tsx
+++ b/app/src/components/nav/UserMenu.tsx
@@ -8,7 +8,6 @@ import {
PopoverTrigger,
PopoverContent,
Link,
- useColorMode,
type StackProps,
} from "@chakra-ui/react";
import { type Session } from "next-auth";
@@ -17,7 +16,6 @@ import { BsBoxArrowRight, BsChevronRight, BsPersonCircle } from "react-icons/bs"
import NavSidebarOption from "./NavSidebarOption";
export default function UserMenu({ user, ...rest }: { user: Session } & StackProps) {
- const { colorMode } = useColorMode();
const profileImage = user.user.image ? (
@@ -28,39 +26,28 @@ export default function UserMenu({ user, ...rest }: { user: Session } & StackPro
return (
<>
-
-
- ACCOUNT
-
-
-
-
- {profileImage}
-
-
- {user.user.name}
-
-
- {/* {user.user.email} */}
-
-
-
-
-
-
-
+
+
+
+ {profileImage}
+
+
+ {user.user.name}
+
+
+ {/* {user.user.email} */}
+
+
+
+
+
+
{/* sign out */}
diff --git a/app/src/pages/data/[id].tsx b/app/src/pages/data/[id].tsx
index 5b68a02..2cb6228 100644
--- a/app/src/pages/data/[id].tsx
+++ b/app/src/pages/data/[id].tsx
@@ -18,6 +18,7 @@ import { api } from "~/utils/api";
import { useDataset, useHandledAsyncCallback } from "~/utils/hooks";
import DatasetEntriesTable from "~/components/datasets/DatasetEntriesTable";
import { DatasetHeaderButtons } from "~/components/datasets/DatasetHeaderButtons/DatasetHeaderButtons";
+import PageHeaderContainer from "~/components/nav/PageHeaderContainer";
export default function Dataset() {
const router = useRouter();
@@ -55,14 +56,8 @@ export default function Dataset() {
return (
-
-
+
+
@@ -88,7 +83,7 @@ export default function Dataset() {
-
+
{datasetId && }
diff --git a/app/src/pages/data/index.tsx b/app/src/pages/data/index.tsx
index 5c9a411..94b5f50 100644
--- a/app/src/pages/data/index.tsx
+++ b/app/src/pages/data/index.tsx
@@ -1,14 +1,12 @@
import {
SimpleGrid,
Icon,
- VStack,
Breadcrumb,
BreadcrumbItem,
Flex,
Center,
Text,
Link,
- HStack,
} from "@chakra-ui/react";
import AppShell from "~/components/nav/AppShell";
import { api } from "~/utils/api";
@@ -19,6 +17,7 @@ import {
DatasetCardSkeleton,
NewDatasetCard,
} from "~/components/datasets/DatasetCard";
+import PageHeaderContainer from "~/components/nav/PageHeaderContainer";
export default function DatasetsPage() {
const datasets = api.datasets.list.useQuery();
@@ -50,34 +49,32 @@ export default function DatasetsPage() {
return (
-
-
-
-
-
- Datasets
-
-
-
-
-
-
- {datasets.data && !datasets.isLoading ? (
- datasets?.data?.map((dataset) => (
-
- ))
- ) : (
- <>
-
-
-
- >
- )}
-
-
+
+
+
+
+ Datasets
+
+
+
+
+
+
+ {datasets.data && !datasets.isLoading ? (
+ datasets?.data?.map((dataset) => (
+
+ ))
+ ) : (
+ <>
+
+
+
+ >
+ )}
+
);
}
diff --git a/app/src/pages/experiments/[id].tsx b/app/src/pages/experiments/[id].tsx
index 83dfcbb..515986b 100644
--- a/app/src/pages/experiments/[id].tsx
+++ b/app/src/pages/experiments/[id].tsx
@@ -23,6 +23,7 @@ import { useAppStore } from "~/state/store";
import { useSyncVariantEditor } from "~/state/sync";
import { ExperimentHeaderButtons } from "~/components/experiments/ExperimentHeaderButtons/ExperimentHeaderButtons";
import Head from "next/head";
+import PageHeaderContainer from "~/components/nav/PageHeaderContainer";
// TODO: import less to fix deployment with server side props
// export const getServerSideProps = async (context: GetServerSidePropsContext<{ id: string }>) => {
@@ -104,15 +105,8 @@ export default function Experiment() {
)}
-
-
+
+
@@ -144,7 +138,7 @@ export default function Experiment() {
-
+
diff --git a/app/src/pages/experiments/index.tsx b/app/src/pages/experiments/index.tsx
index b9915e7..eb66b72 100644
--- a/app/src/pages/experiments/index.tsx
+++ b/app/src/pages/experiments/index.tsx
@@ -1,14 +1,12 @@
import {
SimpleGrid,
Icon,
- VStack,
Breadcrumb,
BreadcrumbItem,
Flex,
Center,
Text,
Link,
- HStack,
} from "@chakra-ui/react";
import { RiFlaskLine } from "react-icons/ri";
import AppShell from "~/components/nav/AppShell";
@@ -19,6 +17,7 @@ import {
NewExperimentCard,
} from "~/components/experiments/ExperimentCard";
import { signIn, useSession } from "next-auth/react";
+import PageHeaderContainer from "~/components/nav/PageHeaderContainer";
export default function ExperimentsPage() {
const experiments = api.experiments.list.useQuery();
@@ -50,29 +49,27 @@ export default function ExperimentsPage() {
return (
-
-
-
-
-
- Experiments
-
-
-
-
-
-
- {experiments.data && !experiments.isLoading ? (
- experiments?.data?.map((exp) => )
- ) : (
- <>
-
-
-
- >
- )}
-
-
+
+
+
+
+ Experiments
+
+
+
+
+
+
+ {experiments.data && !experiments.isLoading ? (
+ experiments?.data?.map((exp) => )
+ ) : (
+ <>
+
+
+
+ >
+ )}
+
);
}
diff --git a/app/src/pages/home/index.tsx b/app/src/pages/home/index.tsx
index b79caec..516a6e8 100644
--- a/app/src/pages/home/index.tsx
+++ b/app/src/pages/home/index.tsx
@@ -1,6 +1,7 @@
-import { Breadcrumb, BreadcrumbItem, HStack, Input } from "@chakra-ui/react";
+import { Breadcrumb, BreadcrumbItem, Input } from "@chakra-ui/react";
import { useEffect, useState } from "react";
import AppShell from "~/components/nav/AppShell";
+import PageHeaderContainer from "~/components/nav/PageHeaderContainer";
import { api } from "~/utils/api";
import { useHandledAsyncCallback, useSelectedOrg } from "~/utils/hooks";
@@ -25,13 +26,7 @@ export default function HomePage() {
}, [selectedOrg?.name]);
return (
-
+
-
+
);
}
diff --git a/app/src/pages/settings/index.tsx b/app/src/pages/settings/index.tsx
new file mode 100644
index 0000000..ef77742
--- /dev/null
+++ b/app/src/pages/settings/index.tsx
@@ -0,0 +1,52 @@
+import { Breadcrumb, BreadcrumbItem, Input } from "@chakra-ui/react";
+import { useEffect, useState } from "react";
+import AppShell from "~/components/nav/AppShell";
+import PageHeaderContainer from "~/components/nav/PageHeaderContainer";
+import { api } from "~/utils/api";
+import { useHandledAsyncCallback, useSelectedOrg } from "~/utils/hooks";
+
+export default function Settings() {
+ const utils = api.useContext();
+ const { data: selectedOrg } = useSelectedOrg();
+
+ const updateMutation = api.organizations.update.useMutation();
+ const [onSaveName] = useHandledAsyncCallback(async () => {
+ if (name && name !== selectedOrg?.name && selectedOrg?.id) {
+ await updateMutation.mutateAsync({
+ id: selectedOrg.id,
+ updates: { name },
+ });
+ await Promise.all([utils.organizations.get.invalidate({ id: selectedOrg.id })]);
+ }
+ }, [updateMutation, selectedOrg]);
+
+ const [name, setName] = useState(selectedOrg?.name);
+ useEffect(() => {
+ setName(selectedOrg?.name);
+ }, [selectedOrg?.name]);
+
+ return (
+
+
+
+
+ setName(e.target.value)}
+ onBlur={onSaveName}
+ borderWidth={1}
+ borderColor="transparent"
+ fontSize={16}
+ px={0}
+ minW={{ base: 100, lg: 300 }}
+ flex={1}
+ _hover={{ borderColor: "gray.300" }}
+ _focus={{ borderColor: "blue.500", outline: "none" }}
+ />
+
+
+
+
+ );
+}