more visual tweaks

This commit is contained in:
Kyle Corbitt
2023-07-19 06:54:07 -07:00
parent 5c6ed22f1d
commit d02482468d
7 changed files with 84 additions and 84 deletions

View File

@@ -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
View File

@@ -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

View File

@@ -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">
<VStack
as={Link} as={Link}
href={{ pathname: "/experiments/[id]", query: { id: exp.id } }}
bg="gray.50" bg="gray.50"
_hover={{ bg: "gray.100" }} _hover={{ bg: "gray.100" }}
transition="background 0.2s" transition="background 0.2s"
cursor="pointer" cursor="pointer"
href={{ pathname: "/experiments/[id]", query: { id: exp.id } }} borderColor="gray.200"
borderWidth={1}
p={4}
justify="space-between"
> >
<CardHeader>
<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"
justify="center"
_hover={{ cursor: "pointer", bg: "gray.50" }}
transition="background 0.2s"
cursor="pointer"
borderColor="gray.200"
borderWidth={1}
p={4}
onClick={createExperiment}
>
<Icon as={isLoading ? Spinner : BsPlusSquare} boxSize={8} /> <Icon as={isLoading ? Spinner : BsPlusSquare} boxSize={8} />
<Text display={{ base: "none", md: "block" }} ml={2}> <Text display={{ base: "none", md: "block" }} ml={2}>
New Experiment New Experiment
</Text> </Text>
</VStack> </VStack>
</AspectRatio> </AspectRatio>
</Card>
); );
}; };

View File

@@ -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">{label}</Text> <Text fontWeight="bold" fontSize="sm">
{label}
</Text>
</HStack> </HStack>
</Box>
); );
}; };
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}
height="100%"
w={{ base: "56px", md: "200px" }}
overflow="hidden"
>
<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 OpenPipe
</Heading> </Heading>
</HStack> </HStack>
</Link>
<Divider />
<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 />
</GridItem> <Box h="100%" flex={1} overflowY="auto">
<GridItem area="main" overflowY="auto">
{props.children} {props.children}
</GridItem> </Box>
</Grid> </Flex>
); );
} }

View File

@@ -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} />
); );

View File

@@ -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">

View File

@@ -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"';