more visual tweaks
This commit is contained in:
@@ -17,7 +17,8 @@
|
|||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"codegen": "tsx src/codegen/export-openai-types.ts",
|
"codegen": "tsx src/codegen/export-openai-types.ts",
|
||||||
"seed": "tsx prisma/seed.ts"
|
"seed": "tsx prisma/seed.ts",
|
||||||
|
"check": "concurrently 'pnpm lint' 'pnpm tsc' 'pnpm prettier . --check'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/preset-typescript": "^7.22.5",
|
"@babel/preset-typescript": "^7.22.5",
|
||||||
@@ -27,6 +28,7 @@
|
|||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/server": "^11.11.0",
|
"@emotion/server": "^11.11.0",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
|
"@fontsource/inconsolata": "^5.0.5",
|
||||||
"@monaco-editor/loader": "^1.3.3",
|
"@monaco-editor/loader": "^1.3.3",
|
||||||
"@next-auth/prisma-adapter": "^1.0.5",
|
"@next-auth/prisma-adapter": "^1.0.5",
|
||||||
"@prisma/client": "^4.14.0",
|
"@prisma/client": "^4.14.0",
|
||||||
|
|||||||
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
@@ -26,6 +26,9 @@ dependencies:
|
|||||||
'@emotion/styled':
|
'@emotion/styled':
|
||||||
specifier: ^11.11.0
|
specifier: ^11.11.0
|
||||||
version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.6)(react@18.2.0)
|
version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.6)(react@18.2.0)
|
||||||
|
'@fontsource/inconsolata':
|
||||||
|
specifier: ^5.0.5
|
||||||
|
version: 5.0.5
|
||||||
'@monaco-editor/loader':
|
'@monaco-editor/loader':
|
||||||
specifier: ^1.3.3
|
specifier: ^1.3.3
|
||||||
version: 1.3.3(monaco-editor@0.40.0)
|
version: 1.3.3(monaco-editor@0.40.0)
|
||||||
@@ -2261,6 +2264,10 @@ packages:
|
|||||||
'@floating-ui/core': 1.3.1
|
'@floating-ui/core': 1.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@fontsource/inconsolata@5.0.5:
|
||||||
|
resolution: {integrity: sha512-uU9t2j/hq4UweFXTjo+geLPFqhTucDdeei/a4BEHdtFPwJIfXLXmzlHeDrjOatHYGbRlJlydS4Ipr16A4O/e5A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@graphile/logger@0.2.0:
|
/@graphile/logger@0.2.0:
|
||||||
resolution: {integrity: sha512-jjcWBokl9eb1gVJ85QmoaQ73CQ52xAaOCF29ukRbYNl6lY+ts0ErTaDYOBlejcbUs2OpaiqYLO5uDhyLFzWw4w==}
|
resolution: {integrity: sha512-jjcWBokl9eb1gVJ85QmoaQ73CQ52xAaOCF29ukRbYNl6lY+ts0ErTaDYOBlejcbUs2OpaiqYLO5uDhyLFzWw4w==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|||||||
@@ -1,15 +1,4 @@
|
|||||||
import {
|
import { HStack, Icon, VStack, Text, Divider, Spinner, AspectRatio } from "@chakra-ui/react";
|
||||||
Card,
|
|
||||||
CardBody,
|
|
||||||
HStack,
|
|
||||||
Icon,
|
|
||||||
VStack,
|
|
||||||
Text,
|
|
||||||
CardHeader,
|
|
||||||
Divider,
|
|
||||||
Spinner,
|
|
||||||
AspectRatio,
|
|
||||||
} from "@chakra-ui/react";
|
|
||||||
import { RiFlaskLine } from "react-icons/ri";
|
import { RiFlaskLine } from "react-icons/ri";
|
||||||
import { formatTimePast } from "~/utils/dayjs";
|
import { formatTimePast } from "~/utils/dayjs";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
@@ -30,22 +19,24 @@ type ExperimentData = {
|
|||||||
|
|
||||||
export const ExperimentCard = ({ exp }: { exp: ExperimentData }) => {
|
export const ExperimentCard = ({ exp }: { exp: ExperimentData }) => {
|
||||||
return (
|
return (
|
||||||
<Card
|
<AspectRatio ratio={1.2} w="full">
|
||||||
as={Link}
|
<VStack
|
||||||
bg="gray.50"
|
as={Link}
|
||||||
_hover={{ bg: "gray.100" }}
|
href={{ pathname: "/experiments/[id]", query: { id: exp.id } }}
|
||||||
transition="background 0.2s"
|
bg="gray.50"
|
||||||
cursor="pointer"
|
_hover={{ bg: "gray.100" }}
|
||||||
href={{ pathname: "/experiments/[id]", query: { id: exp.id } }}
|
transition="background 0.2s"
|
||||||
>
|
cursor="pointer"
|
||||||
<CardHeader>
|
borderColor="gray.200"
|
||||||
|
borderWidth={1}
|
||||||
|
p={4}
|
||||||
|
justify="space-between"
|
||||||
|
>
|
||||||
<HStack w="full" color="gray.700" justify="center">
|
<HStack w="full" color="gray.700" justify="center">
|
||||||
<Icon as={RiFlaskLine} boxSize={4} />
|
<Icon as={RiFlaskLine} boxSize={4} />
|
||||||
<Text fontWeight="bold">{exp.label}</Text>
|
<Text fontWeight="bold">{exp.label}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
<HStack h="full" spacing={4} flex={1} align="center">
|
||||||
<CardBody>
|
|
||||||
<HStack w="full" mb={8} spacing={4}>
|
|
||||||
<CountLabel label="Variants" count={exp.promptVariantCount} />
|
<CountLabel label="Variants" count={exp.promptVariantCount} />
|
||||||
<Divider h={12} orientation="vertical" />
|
<Divider h={12} orientation="vertical" />
|
||||||
<CountLabel label="Scenarios" count={exp.testScenarioCount} />
|
<CountLabel label="Scenarios" count={exp.testScenarioCount} />
|
||||||
@@ -55,8 +46,8 @@ export const ExperimentCard = ({ exp }: { exp: ExperimentData }) => {
|
|||||||
<Divider h={4} orientation="vertical" />
|
<Divider h={4} orientation="vertical" />
|
||||||
<Text flex={1}>Updated {formatTimePast(exp.updatedAt)}</Text>
|
<Text flex={1}>Updated {formatTimePast(exp.updatedAt)}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardBody>
|
</VStack>
|
||||||
</Card>
|
</AspectRatio>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,7 +66,6 @@ const CountLabel = ({ label, count }: { label: string; count: number }) => {
|
|||||||
|
|
||||||
export const NewExperimentCard = () => {
|
export const NewExperimentCard = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const utils = api.useContext();
|
|
||||||
const createMutation = api.experiments.create.useMutation();
|
const createMutation = api.experiments.create.useMutation();
|
||||||
const [createExperiment, isLoading] = useHandledAsyncCallback(async () => {
|
const [createExperiment, isLoading] = useHandledAsyncCallback(async () => {
|
||||||
const newExperiment = await createMutation.mutateAsync({ label: "New Experiment" });
|
const newExperiment = await createMutation.mutateAsync({ label: "New Experiment" });
|
||||||
@@ -83,15 +73,23 @@ export const NewExperimentCard = () => {
|
|||||||
}, [createMutation, router]);
|
}, [createMutation, router]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card _hover={{ cursor: "pointer", bgColor: "gray.50" }} onClick={createExperiment}>
|
<AspectRatio ratio={1.2} w="full">
|
||||||
<AspectRatio ratio={1} w="full">
|
<VStack
|
||||||
<VStack align="center" justify="center" h="100%" spacing={6}>
|
align="center"
|
||||||
<Icon as={isLoading ? Spinner : BsPlusSquare} boxSize={8} />
|
justify="center"
|
||||||
<Text display={{ base: "none", md: "block" }} ml={2}>
|
_hover={{ cursor: "pointer", bg: "gray.50" }}
|
||||||
New Experiment
|
transition="background 0.2s"
|
||||||
</Text>
|
cursor="pointer"
|
||||||
</VStack>
|
borderColor="gray.200"
|
||||||
</AspectRatio>
|
borderWidth={1}
|
||||||
</Card>
|
p={4}
|
||||||
|
onClick={createExperiment}
|
||||||
|
>
|
||||||
|
<Icon as={isLoading ? Spinner : BsPlusSquare} boxSize={8} />
|
||||||
|
<Text display={{ base: "none", md: "block" }} ml={2}>
|
||||||
|
New Experiment
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</AspectRatio>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,24 +1,22 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
import {
|
import {
|
||||||
Heading,
|
Heading,
|
||||||
VStack,
|
VStack,
|
||||||
Icon,
|
Icon,
|
||||||
HStack,
|
HStack,
|
||||||
Image,
|
Image,
|
||||||
Grid,
|
|
||||||
GridItem,
|
|
||||||
Divider,
|
|
||||||
Text,
|
Text,
|
||||||
Box,
|
Box,
|
||||||
type BoxProps,
|
type BoxProps,
|
||||||
type LinkProps,
|
type LinkProps,
|
||||||
Link,
|
Link,
|
||||||
|
Flex,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { BsGithub, BsPersonCircle } from "react-icons/bs";
|
import { BsGithub, BsPersonCircle } from "react-icons/bs";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { type IconType } from "react-icons";
|
import { type IconType } from "react-icons";
|
||||||
import { RiFlaskLine } from "react-icons/ri";
|
import { RiFlaskLine } from "react-icons/ri";
|
||||||
import { useState, useEffect } from "react";
|
|
||||||
import { signIn, useSession } from "next-auth/react";
|
import { signIn, useSession } from "next-auth/react";
|
||||||
import UserMenu from "./UserMenu";
|
import UserMenu from "./UserMenu";
|
||||||
|
|
||||||
@@ -28,40 +26,48 @@ const IconLink = ({ icon, label, href, target, color, ...props }: IconLinkProps)
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const isActive = href && router.pathname.startsWith(href);
|
const isActive = href && router.pathname.startsWith(href);
|
||||||
return (
|
return (
|
||||||
<Box
|
<HStack
|
||||||
|
w="full"
|
||||||
|
p={4}
|
||||||
|
color={color}
|
||||||
as={Link}
|
as={Link}
|
||||||
href={href}
|
href={href}
|
||||||
target={target}
|
target={target}
|
||||||
w="full"
|
bgColor={isActive ? "gray.200" : "transparent"}
|
||||||
bgColor={isActive ? "gray.300" : "transparent"}
|
|
||||||
_hover={{ bgColor: "gray.200", textDecoration: "none" }}
|
_hover={{ bgColor: "gray.200", textDecoration: "none" }}
|
||||||
py={4}
|
|
||||||
justifyContent="start"
|
justifyContent="start"
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<HStack w="full" px={4} color={color}>
|
<Icon as={icon} boxSize={6} mr={2} />
|
||||||
<Icon as={icon} boxSize={6} mr={2} />
|
<Text fontWeight="bold" fontSize="sm">
|
||||||
<Text fontWeight="bold">{label}</Text>
|
{label}
|
||||||
</HStack>
|
</Text>
|
||||||
</Box>
|
</HStack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Divider = () => <Box h="1px" bgColor="gray.200" />;
|
||||||
|
|
||||||
const NavSidebar = () => {
|
const NavSidebar = () => {
|
||||||
const user = useSession().data;
|
const user = useSession().data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack align="stretch" bgColor="gray.100" py={2} pb={0} height="100%">
|
<VStack
|
||||||
<Link href="/" w="full" _hover={{ textDecoration: "none" }}>
|
align="stretch"
|
||||||
<HStack spacing={0} pl="3">
|
bgColor="gray.100"
|
||||||
<Image src="/logo.svg" alt="" w={8} h={8} />
|
py={2}
|
||||||
<Heading size="md" p={2} pl={{ base: 16, md: 2 }}>
|
pb={0}
|
||||||
OpenPipe
|
height="100%"
|
||||||
</Heading>
|
w={{ base: "56px", md: "200px" }}
|
||||||
</HStack>
|
overflow="hidden"
|
||||||
</Link>
|
>
|
||||||
<Divider />
|
<HStack as={Link} href="/" _hover={{ textDecoration: "none" }} spacing={0} px={4} py={2}>
|
||||||
|
<Image src="/logo.svg" alt="" boxSize={6} mr={4} />
|
||||||
|
<Heading size="md" fontFamily="inconsolata, monospace">
|
||||||
|
OpenPipe
|
||||||
|
</Heading>
|
||||||
|
</HStack>
|
||||||
<VStack spacing={0} align="flex-start" overflowY="auto" overflowX="hidden" flex={1}>
|
<VStack spacing={0} align="flex-start" overflowY="auto" overflowX="hidden" flex={1}>
|
||||||
{user != null && (
|
{user != null && (
|
||||||
<>
|
<>
|
||||||
@@ -115,22 +121,14 @@ export default function AppShell(props: { children: React.ReactNode; title?: str
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid
|
<Flex h={vh} w="100vw">
|
||||||
h={vh}
|
|
||||||
w="100vw"
|
|
||||||
templateColumns={{ base: "56px minmax(0, 1fr)", md: "220px minmax(0, 1fr)" }}
|
|
||||||
templateRows="1fr"
|
|
||||||
templateAreas={'"sidebar main"'}
|
|
||||||
>
|
|
||||||
<Head>
|
<Head>
|
||||||
<title>{props.title ? `${props.title} | OpenPipe` : "OpenPipe"}</title>
|
<title>{props.title ? `${props.title} | OpenPipe` : "OpenPipe"}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<GridItem area="sidebar" overflow="hidden">
|
<NavSidebar />
|
||||||
<NavSidebar />
|
<Box h="100%" flex={1} overflowY="auto">
|
||||||
</GridItem>
|
|
||||||
<GridItem area="main" overflowY="auto">
|
|
||||||
{props.children}
|
{props.children}
|
||||||
</GridItem>
|
</Box>
|
||||||
</Grid>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,13 +15,7 @@ import { BsBoxArrowRight, BsChevronRight, BsPersonCircle } from "react-icons/bs"
|
|||||||
|
|
||||||
export default function UserMenu({ user }: { user: Session }) {
|
export default function UserMenu({ user }: { user: Session }) {
|
||||||
const profileImage = user.user.image ? (
|
const profileImage = user.user.image ? (
|
||||||
<Image
|
<Image src={user.user.image} alt="profile picture" boxSize={8} borderRadius="50%" />
|
||||||
src={user.user.image}
|
|
||||||
alt="profile picture"
|
|
||||||
boxSize={8}
|
|
||||||
borderRadius="50%"
|
|
||||||
// mr={{ base: 2, md: 0 }}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<Icon as={BsPersonCircle} boxSize={6} />
|
<Icon as={BsPersonCircle} boxSize={6} />
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
SimpleGrid,
|
SimpleGrid,
|
||||||
HStack,
|
|
||||||
Icon,
|
Icon,
|
||||||
VStack,
|
VStack,
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
Center,
|
Center,
|
||||||
Text,
|
Text,
|
||||||
Link,
|
Link,
|
||||||
|
HStack,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { RiFlaskLine } from "react-icons/ri";
|
import { RiFlaskLine } from "react-icons/ri";
|
||||||
import AppShell from "~/components/nav/AppShell";
|
import AppShell from "~/components/nav/AppShell";
|
||||||
@@ -43,8 +43,8 @@ export default function ExperimentsPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AppShell title="Experiments">
|
<AppShell title="Experiments">
|
||||||
<VStack alignItems={"flex-start"} m={4} mt={1}>
|
<VStack alignItems={"flex-start"} px={4} py={2}>
|
||||||
<HStack w="full" mb={4}>
|
<HStack minH={8} align="center">
|
||||||
<Breadcrumb flex={1}>
|
<Breadcrumb flex={1}>
|
||||||
<BreadcrumbItem>
|
<BreadcrumbItem>
|
||||||
<Flex alignItems="center">
|
<Flex alignItems="center">
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { extendTheme } from "@chakra-ui/react";
|
import { extendTheme } from "@chakra-ui/react";
|
||||||
|
import "@fontsource/inconsolata";
|
||||||
|
|
||||||
const systemFont =
|
const systemFont =
|
||||||
'ui-sans-serif, -apple-system, "system-ui", "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"';
|
'ui-sans-serif, -apple-system, "system-ui", "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"';
|
||||||
|
|||||||
Reference in New Issue
Block a user