mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 10:19:51 -06:00
fix: tweak ai ui (#3964)
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user