more visual tweaks
This commit is contained in:
@@ -1,15 +1,4 @@
|
||||
import {
|
||||
Card,
|
||||
CardBody,
|
||||
HStack,
|
||||
Icon,
|
||||
VStack,
|
||||
Text,
|
||||
CardHeader,
|
||||
Divider,
|
||||
Spinner,
|
||||
AspectRatio,
|
||||
} from "@chakra-ui/react";
|
||||
import { HStack, Icon, VStack, Text, Divider, Spinner, AspectRatio } from "@chakra-ui/react";
|
||||
import { RiFlaskLine } from "react-icons/ri";
|
||||
import { formatTimePast } from "~/utils/dayjs";
|
||||
import Link from "next/link";
|
||||
@@ -30,22 +19,24 @@ type ExperimentData = {
|
||||
|
||||
export const ExperimentCard = ({ exp }: { exp: ExperimentData }) => {
|
||||
return (
|
||||
<Card
|
||||
as={Link}
|
||||
bg="gray.50"
|
||||
_hover={{ bg: "gray.100" }}
|
||||
transition="background 0.2s"
|
||||
cursor="pointer"
|
||||
href={{ pathname: "/experiments/[id]", query: { id: exp.id } }}
|
||||
>
|
||||
<CardHeader>
|
||||
<AspectRatio ratio={1.2} w="full">
|
||||
<VStack
|
||||
as={Link}
|
||||
href={{ pathname: "/experiments/[id]", query: { id: exp.id } }}
|
||||
bg="gray.50"
|
||||
_hover={{ bg: "gray.100" }}
|
||||
transition="background 0.2s"
|
||||
cursor="pointer"
|
||||
borderColor="gray.200"
|
||||
borderWidth={1}
|
||||
p={4}
|
||||
justify="space-between"
|
||||
>
|
||||
<HStack w="full" color="gray.700" justify="center">
|
||||
<Icon as={RiFlaskLine} boxSize={4} />
|
||||
<Text fontWeight="bold">{exp.label}</Text>
|
||||
</HStack>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<HStack w="full" mb={8} spacing={4}>
|
||||
<HStack h="full" spacing={4} flex={1} align="center">
|
||||
<CountLabel label="Variants" count={exp.promptVariantCount} />
|
||||
<Divider h={12} orientation="vertical" />
|
||||
<CountLabel label="Scenarios" count={exp.testScenarioCount} />
|
||||
@@ -55,8 +46,8 @@ export const ExperimentCard = ({ exp }: { exp: ExperimentData }) => {
|
||||
<Divider h={4} orientation="vertical" />
|
||||
<Text flex={1}>Updated {formatTimePast(exp.updatedAt)}</Text>
|
||||
</HStack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</VStack>
|
||||
</AspectRatio>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -75,7 +66,6 @@ const CountLabel = ({ label, count }: { label: string; count: number }) => {
|
||||
|
||||
export const NewExperimentCard = () => {
|
||||
const router = useRouter();
|
||||
const utils = api.useContext();
|
||||
const createMutation = api.experiments.create.useMutation();
|
||||
const [createExperiment, isLoading] = useHandledAsyncCallback(async () => {
|
||||
const newExperiment = await createMutation.mutateAsync({ label: "New Experiment" });
|
||||
@@ -83,15 +73,23 @@ export const NewExperimentCard = () => {
|
||||
}, [createMutation, router]);
|
||||
|
||||
return (
|
||||
<Card _hover={{ cursor: "pointer", bgColor: "gray.50" }} onClick={createExperiment}>
|
||||
<AspectRatio ratio={1} w="full">
|
||||
<VStack align="center" justify="center" h="100%" spacing={6}>
|
||||
<Icon as={isLoading ? Spinner : BsPlusSquare} boxSize={8} />
|
||||
<Text display={{ base: "none", md: "block" }} ml={2}>
|
||||
New Experiment
|
||||
</Text>
|
||||
</VStack>
|
||||
</AspectRatio>
|
||||
</Card>
|
||||
<AspectRatio ratio={1.2} w="full">
|
||||
<VStack
|
||||
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} />
|
||||
<Text display={{ base: "none", md: "block" }} ml={2}>
|
||||
New Experiment
|
||||
</Text>
|
||||
</VStack>
|
||||
</AspectRatio>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import {
|
||||
Heading,
|
||||
VStack,
|
||||
Icon,
|
||||
HStack,
|
||||
Image,
|
||||
Grid,
|
||||
GridItem,
|
||||
Divider,
|
||||
Text,
|
||||
Box,
|
||||
type BoxProps,
|
||||
type LinkProps,
|
||||
Link,
|
||||
Flex,
|
||||
} from "@chakra-ui/react";
|
||||
import Head from "next/head";
|
||||
import { BsGithub, BsPersonCircle } from "react-icons/bs";
|
||||
import { useRouter } from "next/router";
|
||||
import { type IconType } from "react-icons";
|
||||
import { RiFlaskLine } from "react-icons/ri";
|
||||
import { useState, useEffect } from "react";
|
||||
import { signIn, useSession } from "next-auth/react";
|
||||
import UserMenu from "./UserMenu";
|
||||
|
||||
@@ -28,40 +26,48 @@ const IconLink = ({ icon, label, href, target, color, ...props }: IconLinkProps)
|
||||
const router = useRouter();
|
||||
const isActive = href && router.pathname.startsWith(href);
|
||||
return (
|
||||
<Box
|
||||
<HStack
|
||||
w="full"
|
||||
p={4}
|
||||
color={color}
|
||||
as={Link}
|
||||
href={href}
|
||||
target={target}
|
||||
w="full"
|
||||
bgColor={isActive ? "gray.300" : "transparent"}
|
||||
bgColor={isActive ? "gray.200" : "transparent"}
|
||||
_hover={{ bgColor: "gray.200", textDecoration: "none" }}
|
||||
py={4}
|
||||
justifyContent="start"
|
||||
cursor="pointer"
|
||||
{...props}
|
||||
>
|
||||
<HStack w="full" px={4} color={color}>
|
||||
<Icon as={icon} boxSize={6} mr={2} />
|
||||
<Text fontWeight="bold">{label}</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
<Icon as={icon} boxSize={6} mr={2} />
|
||||
<Text fontWeight="bold" fontSize="sm">
|
||||
{label}
|
||||
</Text>
|
||||
</HStack>
|
||||
);
|
||||
};
|
||||
|
||||
const Divider = () => <Box h="1px" bgColor="gray.200" />;
|
||||
|
||||
const NavSidebar = () => {
|
||||
const user = useSession().data;
|
||||
|
||||
return (
|
||||
<VStack align="stretch" bgColor="gray.100" py={2} pb={0} height="100%">
|
||||
<Link href="/" w="full" _hover={{ textDecoration: "none" }}>
|
||||
<HStack spacing={0} pl="3">
|
||||
<Image src="/logo.svg" alt="" w={8} h={8} />
|
||||
<Heading size="md" p={2} pl={{ base: 16, md: 2 }}>
|
||||
OpenPipe
|
||||
</Heading>
|
||||
</HStack>
|
||||
</Link>
|
||||
<Divider />
|
||||
<VStack
|
||||
align="stretch"
|
||||
bgColor="gray.100"
|
||||
py={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
|
||||
</Heading>
|
||||
</HStack>
|
||||
<VStack spacing={0} align="flex-start" overflowY="auto" overflowX="hidden" flex={1}>
|
||||
{user != null && (
|
||||
<>
|
||||
@@ -115,22 +121,14 @@ export default function AppShell(props: { children: React.ReactNode; title?: str
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
h={vh}
|
||||
w="100vw"
|
||||
templateColumns={{ base: "56px minmax(0, 1fr)", md: "220px minmax(0, 1fr)" }}
|
||||
templateRows="1fr"
|
||||
templateAreas={'"sidebar main"'}
|
||||
>
|
||||
<Flex h={vh} w="100vw">
|
||||
<Head>
|
||||
<title>{props.title ? `${props.title} | OpenPipe` : "OpenPipe"}</title>
|
||||
</Head>
|
||||
<GridItem area="sidebar" overflow="hidden">
|
||||
<NavSidebar />
|
||||
</GridItem>
|
||||
<GridItem area="main" overflowY="auto">
|
||||
<NavSidebar />
|
||||
<Box h="100%" flex={1} overflowY="auto">
|
||||
{props.children}
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,13 +15,7 @@ import { BsBoxArrowRight, BsChevronRight, BsPersonCircle } from "react-icons/bs"
|
||||
|
||||
export default function UserMenu({ user }: { user: Session }) {
|
||||
const profileImage = user.user.image ? (
|
||||
<Image
|
||||
src={user.user.image}
|
||||
alt="profile picture"
|
||||
boxSize={8}
|
||||
borderRadius="50%"
|
||||
// mr={{ base: 2, md: 0 }}
|
||||
/>
|
||||
<Image src={user.user.image} alt="profile picture" boxSize={8} borderRadius="50%" />
|
||||
) : (
|
||||
<Icon as={BsPersonCircle} boxSize={6} />
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user