fix: tweak ai ui (#3964)

This commit is contained in:
Johannes
2024-10-21 15:13:21 -07:00
committed by GitHub
parent 9872d17abe
commit d9e2267a3a
9 changed files with 82 additions and 63 deletions

View File

@@ -5,6 +5,7 @@ import { SparklesIcon } from "lucide-react";
import { useState } from "react";
import toast from "react-hot-toast";
import { Alert, AlertDescription, AlertTitle } from "@formbricks/ui/components/Alert";
import { Badge } from "@formbricks/ui/components/Badge";
import { Button } from "@formbricks/ui/components/Button";
interface EnableInsightsBannerProps {
@@ -27,30 +28,34 @@ export const EnableInsightsBanner = ({
};
return (
<Alert className="w-1/2 bg-white">
<SparklesIcon className="h-4 w-4" />
<AlertTitle>
<span>Ready to enable insights?</span>
</AlertTitle>
<AlertDescription className="flex items-start justify-between gap-4">
<span>
<Alert className="mb-6 mt-4 flex items-center gap-4 border-slate-400 bg-white">
<div>
<SparklesIcon strokeWidth={1.5} className="size-7 text-slate-700" />
</div>
<div className="flex-1">
<AlertTitle>
<span className="mr-2">Ready to test AI insights?</span>
<Badge text="Beta" type="gray" size="normal" />
</AlertTitle>
<AlertDescription className="flex items-start justify-between gap-4">
You can enable the new insights feature for the survey to get AI-based insights for your open-text
responses.
</span>
<Button
variant="secondary"
size="sm"
className="shrink-0"
onClick={handleInsightGeneration}
disabled={surveyResponseCount > maxResponseCount || isGeneratingInsights}
tooltip={
surveyResponseCount > maxResponseCount
? "Kindly contact us at hola@formbricks.com to generate insights for this survey"
: undefined
}>
Enable Insights
</Button>
</AlertDescription>
</AlertDescription>
</div>
<Button
variant="primary"
size="sm"
className="shrink-0"
onClick={handleInsightGeneration}
loading={isGeneratingInsights}
disabled={surveyResponseCount > maxResponseCount || isGeneratingInsights}
tooltip={
surveyResponseCount > maxResponseCount
? "Kindly contact us at hola@formbricks.com to generate insights for this survey"
: undefined
}>
Enable insights
</Button>
</Alert>
);
};

View File

@@ -101,7 +101,7 @@ export const InsightView = ({
</TableHeader>
<TableBody>
{isFetching ? null : insights.length === 0 ? (
<TableRow>
<TableRow className="pointer-events-none">
<TableCell colSpan={4} className="py-8 text-center">
<p className="text-slate-500">
No insights found. Collect more survey responses or enable insights for your existing
@@ -110,7 +110,7 @@ export const InsightView = ({
</TableCell>
</TableRow>
) : localInsights.length === 0 ? (
<TableRow>
<TableRow className="pointer-events-none">
<TableCell colSpan={4} className="py-8 text-center">
<p className="text-slate-500">No insights found for this filter.</p>
</TableCell>
@@ -119,7 +119,7 @@ export const InsightView = ({
localInsights.slice(0, visibleInsights).map((insight) => (
<TableRow
key={insight.id}
className="cursor-pointer hover:bg-slate-50"
className="group cursor-pointer hover:bg-slate-50"
onClick={() => {
setCurrentInsight(insight);
setIsInsightSheetOpen(true);
@@ -128,7 +128,9 @@ export const InsightView = ({
{insight._count.documentInsights} <UserIcon className="ml-2 h-4 w-4" />
</TableCell>
<TableCell className="font-medium">{insight.title}</TableCell>
<TableCell>{insight.description}</TableCell>
<TableCell className="underline-offset-2 group-hover:underline">
{insight.description}
</TableCell>
<TableCell>
{insight.category === "complaint" ? (
<Badge text="Complaint" type="error" size="tiny" />

View File

@@ -10,7 +10,7 @@ import { useState } from "react";
import { TEnvironment } from "@formbricks/types/environment";
import { TProduct } from "@formbricks/types/product";
import { TUser } from "@formbricks/types/user";
import { ToggleGroup, ToggleGroupItem } from "@formbricks/ui/components/ToggleGroup";
import { Tabs, TabsList, TabsTrigger } from "@formbricks/ui/components/Tabs";
interface DashboardProps {
user: TUser;
@@ -32,26 +32,29 @@ export const Dashboard = ({
return (
<div className="container mx-auto space-y-6 p-4">
<Greeting userName={user.name} />
<ToggleGroup
type="single"
<hr className="border-slate-200" />
<Tabs
value={statsPeriod}
onValueChange={(value) => value && setStatsPeriod(value as TStatsPeriod)}>
<ToggleGroupItem value="day" aria-label="Toggle day">
Today
</ToggleGroupItem>
<ToggleGroupItem value="week" aria-label="Toggle week">
This week
</ToggleGroupItem>
<ToggleGroupItem value="month" aria-label="Toggle month">
This month
</ToggleGroupItem>
<ToggleGroupItem value="quarter" aria-label="Toggle quarter">
This quarter
</ToggleGroupItem>
<ToggleGroupItem value="all" aria-label="Toggle all">
All time
</ToggleGroupItem>
</ToggleGroup>
onValueChange={(value) => value && setStatsPeriod(value as TStatsPeriod)}
className="flex justify-center">
<TabsList>
<TabsTrigger value="day" aria-label="Toggle day">
Today
</TabsTrigger>
<TabsTrigger value="week" aria-label="Toggle week">
This week
</TabsTrigger>
<TabsTrigger value="month" aria-label="Toggle month">
This month
</TabsTrigger>
<TabsTrigger value="quarter" aria-label="Toggle quarter">
This quarter
</TabsTrigger>
<TabsTrigger value="all" aria-label="Toggle all">
All time
</TabsTrigger>
</TabsList>
</Tabs>
<ExperiencePageStats statsFrom={statsFrom} environmentId={environment.id} />
<InsightsCard
statsFrom={statsFrom}

View File

@@ -134,7 +134,7 @@ export const InsightView = ({
</TableHeader>
<TableBody>
{insights.length === 0 && !isFetching ? (
<TableRow>
<TableRow className="pointer-events-none">
<TableCell colSpan={4} className="py-8 text-center">
<p className="text-slate-500">
No insights found. Collect more survey responses or enable insights for your existing
@@ -146,7 +146,7 @@ export const InsightView = ({
insights.map((insight) => (
<TableRow
key={insight.id}
className="cursor-pointer hover:bg-slate-50"
className="group cursor-pointer hover:bg-slate-50"
onClick={() => {
setCurrentInsight(insight);
setIsInsightSheetOpen(true);
@@ -155,7 +155,9 @@ export const InsightView = ({
{insight._count.documentInsights} <UserIcon className="ml-2 h-4 w-4" />
</TableCell>
<TableCell className="font-medium">{insight.title}</TableCell>
<TableCell>{insight.description}</TableCell>
<TableCell className="underline-offset-2 group-hover:underline">
{insight.description}
</TableCell>
<TableCell>
{insight.category === "complaint" ? (
<Badge text="Complaint" type="error" size="tiny" />

View File

@@ -3,7 +3,7 @@ import * as React from "react";
import { cn } from "@formbricks/lib/cn";
const alertVariants = cva(
"relative w-full rounded-lg border p-3 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-3 [&>svg]:top-3 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-9",
"relative w-full rounded-xl border p-3 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-3 [&>svg]:top-3 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-9",
{
variants: {
variant: {
@@ -34,7 +34,7 @@ const AlertTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement> & { dangerouslySetInnerHTML?: { __html: string } }
>(({ className, ...props }, ref) => (
<h5 ref={ref} className={cn("mb-1 font-medium leading-none tracking-tight", className)} {...props} />
<h5 ref={ref} className={cn("mb-1 cursor-default font-medium leading-none", className)} {...props} />
));
AlertTitle.displayName = "AlertTitle";
@@ -42,7 +42,7 @@ const AlertDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement> & { dangerouslySetInnerHTML?: { __html: string } }
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("text-sm [&_p]:leading-relaxed", className)} {...props} />
<div ref={ref} className={cn("cursor-default text-sm [&_p]:leading-relaxed", className)} {...props} />
));
AlertDescription.displayName = "AlertDescription";

View File

@@ -5,7 +5,7 @@ const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElemen
({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("bg-card text-card-foreground rounded-lg border shadow-sm", className)}
className={cn("text-card-foreground rounded-xl border border-slate-200 bg-white shadow-sm", className)}
{...props}
/>
)
@@ -49,4 +49,4 @@ const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDiv
);
CardFooter.displayName = "CardFooter";
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };

View File

@@ -12,7 +12,11 @@ Table.displayName = "Table";
const TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
({ className, ...props }, ref) => (
<thead ref={ref} className={cn("bg-slate-200 text-slate-800 [&_tr]:border-b", className)} {...props} />
<thead
ref={ref}
className={cn("pointer-events-none text-slate-800 [&_tr]:border-b", className)}
{...props}
/>
)
);
TableHeader.displayName = "TableHeader";

View File

@@ -13,7 +13,7 @@ const TabsList = React.forwardRef<
<TabsPrimitive.List
ref={ref}
className={cn(
"inline-flex h-10 items-center justify-center rounded-md bg-slate-100 p-1 text-slate-500 dark:bg-slate-800 dark:text-slate-400",
"inline-flex h-10 items-center justify-center rounded-lg bg-slate-100 p-1 text-slate-500 dark:bg-slate-800 dark:text-slate-400",
className
)}
{...props}
@@ -28,7 +28,7 @@ const TabsTrigger = React.forwardRef<
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-white transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white data-[state=active]:text-slate-950 data-[state=active]:shadow-sm dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300 dark:data-[state=active]:bg-slate-950 dark:data-[state=active]:text-slate-50",
"inline-flex items-center justify-center whitespace-nowrap rounded-lg px-3 py-1.5 text-sm font-medium ring-offset-white transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white data-[state=active]:text-slate-950 data-[state=active]:shadow-sm dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300 dark:data-[state=active]:bg-slate-950 dark:data-[state=active]:text-slate-50",
className
)}
{...props}
@@ -51,4 +51,4 @@ const TabsContent = React.forwardRef<
));
TabsContent.displayName = TabsPrimitive.Content.displayName;
export { Tabs, TabsList, TabsTrigger, TabsContent };
export { Tabs, TabsContent, TabsList, TabsTrigger };

View File

@@ -6,7 +6,10 @@ const H1 = forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElemen
<h1
{...props}
ref={ref}
className={cn("scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl", props.className)}>
className={cn(
"scroll-m-20 text-4xl font-bold tracking-tight text-slate-800 lg:text-4xl",
props.className
)}>
{props.children}
</h1>
);
@@ -21,7 +24,7 @@ const H2 = forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElemen
{...props}
ref={ref}
className={cn(
"scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0",
"scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight text-slate-800 first:mt-0",
props.className
)}>
{props.children}
@@ -37,7 +40,7 @@ const H3 = forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElemen
<h3
{...props}
ref={ref}
className={cn("scroll-m-20 text-2xl font-semibold tracking-tight", props.className)}>
className={cn("scroll-m-20 text-2xl font-semibold tracking-tight text-slate-800", props.className)}>
{props.children}
</h3>
);
@@ -51,7 +54,7 @@ const H4 = forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElemen
<h4
{...props}
ref={ref}
className={cn("scroll-m-20 text-xl font-semibold tracking-tight", props.className)}>
className={cn("scroll-m-20 text-xl font-semibold tracking-tight text-slate-800", props.className)}>
{props.children}
</h4>
);
@@ -62,7 +65,7 @@ export { H4 };
const Lead = forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>((props, ref) => {
return (
<p {...props} ref={ref} className={cn("text-muted-foreground text-xl", props.className)}>
<p {...props} ref={ref} className={cn("text-muted-foreground text-xl text-slate-800", props.className)}>
{props.children}
</p>
);