From 4476f4d664d2c0dc7b88281fdc28d51fd0857ec0 Mon Sep 17 00:00:00 2001 From: Mahen Date: Fri, 6 Feb 2026 13:12:16 +0700 Subject: [PATCH] perf: modularize comps folder --- src/app/auth/login/page.tsx | 9 +-- src/app/dashboard/page.tsx | 20 ++--- .../components}/dashboards/BrandFilter.tsx | 0 .../components}/dashboards/Header.tsx | 3 +- .../components}/dashboards/ModelInfo.tsx | 5 +- .../components}/dashboards/ReviewTable.tsx | 6 +- .../dashboards/SentimentAnalyzer.tsx | 6 +- .../components}/dashboards/SentimentChart.tsx | 0 .../components}/dashboards/StatCard.tsx | 0 .../components}/dashboards/TrendChart.tsx | 0 .../components}/dashboards/WordCloud.tsx | 0 .../skeletons/ModelInfoSkeleton.tsx | 2 +- {components => src/components}/ui/badge.tsx | 0 {components => src/components}/ui/button.tsx | 0 {components => src/components}/ui/card.tsx | 0 .../components}/ui/combobox.tsx | 4 +- .../components}/ui/dropdown-menu.tsx | 0 {components => src/components}/ui/field.tsx | 74 +++++++++---------- .../components}/ui/input-group.tsx | 48 ++++++------ {components => src/components}/ui/input.tsx | 0 {components => src/components}/ui/item.tsx | 2 +- {components => src/components}/ui/label.tsx | 0 {components => src/components}/ui/select.tsx | 0 .../components}/ui/separator.tsx | 0 {components => src/components}/ui/table.tsx | 0 .../components}/ui/textarea.tsx | 0 26 files changed, 88 insertions(+), 91 deletions(-) rename {components => src/components}/dashboards/BrandFilter.tsx (100%) rename {components => src/components}/dashboards/Header.tsx (98%) rename {components => src/components}/dashboards/ModelInfo.tsx (96%) rename {components => src/components}/dashboards/ReviewTable.tsx (95%) rename {components => src/components}/dashboards/SentimentAnalyzer.tsx (98%) rename {components => src/components}/dashboards/SentimentChart.tsx (100%) rename {components => src/components}/dashboards/StatCard.tsx (100%) rename {components => src/components}/dashboards/TrendChart.tsx (100%) rename {components => src/components}/dashboards/WordCloud.tsx (100%) rename {components => src/components}/skeletons/ModelInfoSkeleton.tsx (96%) rename {components => src/components}/ui/badge.tsx (100%) rename {components => src/components}/ui/button.tsx (100%) rename {components => src/components}/ui/card.tsx (100%) rename {components => src/components}/ui/combobox.tsx (98%) rename {components => src/components}/ui/dropdown-menu.tsx (100%) rename {components => src/components}/ui/field.tsx (89%) rename {components => src/components}/ui/input-group.tsx (92%) rename {components => src/components}/ui/input.tsx (100%) rename {components => src/components}/ui/item.tsx (98%) rename {components => src/components}/ui/label.tsx (100%) rename {components => src/components}/ui/select.tsx (100%) rename {components => src/components}/ui/separator.tsx (100%) rename {components => src/components}/ui/table.tsx (100%) rename {components => src/components}/ui/textarea.tsx (100%) diff --git a/src/app/auth/login/page.tsx b/src/app/auth/login/page.tsx index 509d32a..35854ea 100644 --- a/src/app/auth/login/page.tsx +++ b/src/app/auth/login/page.tsx @@ -1,19 +1,18 @@ import { cn } from "@/lib/utils"; -import { Button } from "@/components/ui/button"; +import { Button } from "../../../components/ui/button"; import { Card, CardContent, - CardDescription, CardHeader, CardTitle, -} from "@/components/ui/card"; +} from "../../../components/ui/card"; import { Field, FieldDescription, FieldGroup, FieldLabel, -} from "@/components/ui/field"; -import { Input } from "@/components/ui/input"; +} from "../../../components/ui/field"; +import { Input } from "../../../components/ui/input"; export function LoginPage({ className, diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index 085b1f2..d6a3307 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -7,7 +7,7 @@ import { trendData, wordCloudData, } from "./lib/data"; -import { Header } from "@/components/dashboards/Header"; +import { Header } from "../../components/dashboards/Header"; import { MessageSquareText, Minus, @@ -15,17 +15,17 @@ import { ThumbsUp, TrendingUp, } from "lucide-react"; -import { StatCard } from "@/components/dashboards/StatCard"; -import { TrendChart } from "@/components/dashboards/TrendChart"; -import { SentimentChart } from "@/components/dashboards/SentimentChart"; -import { WordCloud } from "@/components/dashboards/WordCloud"; -import { ModelInfo } from "@/components/dashboards/ModelInfo"; -import { SentimentAnalyzer } from "@/components/dashboards/SentimentAnalyzer"; -import { BrandFilter } from "@/components/dashboards/BrandFilter"; -import { ReviewTable } from "@/components/dashboards/ReviewTable"; +import { StatCard } from "../../components/dashboards/StatCard"; +import { TrendChart } from "../../components/dashboards/TrendChart"; +import { SentimentChart } from "../../components/dashboards/SentimentChart"; +import { WordCloud } from "../../components/dashboards/WordCloud"; +import { ModelInfo } from "../../components/dashboards/ModelInfo"; +import { SentimentAnalyzer } from "../../components/dashboards/SentimentAnalyzer"; +import { BrandFilter } from "../../components/dashboards/BrandFilter"; +import { ReviewTable } from "../../components/dashboards/ReviewTable"; import { getClassificationReport } from "./lib/actions"; import { ModelDB } from "@/src/types"; -import { ModelInfoSkeleton } from "@/components/skeletons/ModelInfoSkeleton"; +import { ModelInfoSkeleton } from "../../components/skeletons/ModelInfoSkeleton"; export default function DashboardPage() { const [selectedBrand, setSelectedBrand] = useState(null); diff --git a/components/dashboards/BrandFilter.tsx b/src/components/dashboards/BrandFilter.tsx similarity index 100% rename from components/dashboards/BrandFilter.tsx rename to src/components/dashboards/BrandFilter.tsx diff --git a/components/dashboards/Header.tsx b/src/components/dashboards/Header.tsx similarity index 98% rename from components/dashboards/Header.tsx rename to src/components/dashboards/Header.tsx index 96f904a..ae89339 100644 --- a/components/dashboards/Header.tsx +++ b/src/components/dashboards/Header.tsx @@ -3,11 +3,10 @@ import { Database, Laptop, LogOut, - RefreshCw, User, UserCircle, } from "lucide-react"; -import { Button } from "@/components/ui/button"; +import { Button } from "../../components/ui/button"; import { useState } from "react"; import { cn } from "@/lib/utils"; import { diff --git a/components/dashboards/ModelInfo.tsx b/src/components/dashboards/ModelInfo.tsx similarity index 96% rename from components/dashboards/ModelInfo.tsx rename to src/components/dashboards/ModelInfo.tsx index 5d0b177..2d90be1 100644 --- a/components/dashboards/ModelInfo.tsx +++ b/src/components/dashboards/ModelInfo.tsx @@ -1,14 +1,13 @@ "use client"; -import { useState } from "react"; -import { Badge } from "@/components/ui/badge"; +import { Badge } from "../../components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, -} from "@/components/ui/select"; +} from "../../components/ui/select"; import { ModelDB } from "@/src/types"; import { useModelInfo } from "@/src/hooks/useModelInfo"; diff --git a/components/dashboards/ReviewTable.tsx b/src/components/dashboards/ReviewTable.tsx similarity index 95% rename from components/dashboards/ReviewTable.tsx rename to src/components/dashboards/ReviewTable.tsx index 6ee19a2..b7c4587 100644 --- a/components/dashboards/ReviewTable.tsx +++ b/src/components/dashboards/ReviewTable.tsx @@ -5,8 +5,8 @@ import { TableHead, TableHeader, TableRow, -} from "@/components/ui/table"; -import { Badge } from "@/components/ui/badge"; +} from "../../components/ui/table"; +import { Badge } from "../../components/ui/badge"; import { cn } from "@/lib/utils"; import { Star } from "lucide-react"; @@ -59,7 +59,7 @@ export function ReviewTable({ reviews }: ReviewTableProps) { "h-4 w-4", i < rating ? "fill-sentiment-neutral text-sentiment-neutral" - : "fill-muted text-muted" + : "fill-muted text-muted", )} /> ))} diff --git a/components/dashboards/SentimentAnalyzer.tsx b/src/components/dashboards/SentimentAnalyzer.tsx similarity index 98% rename from components/dashboards/SentimentAnalyzer.tsx rename to src/components/dashboards/SentimentAnalyzer.tsx index 9864568..52d8bb3 100644 --- a/components/dashboards/SentimentAnalyzer.tsx +++ b/src/components/dashboards/SentimentAnalyzer.tsx @@ -1,7 +1,7 @@ import { useMemo, useState } from "react"; -import { Button } from "@/components/ui/button"; -import { Textarea } from "@/components/ui/textarea"; -import { Badge } from "@/components/ui/badge"; +import { Button } from "../../components/ui/button"; +import { Textarea } from "../../components/ui/textarea"; +import { Badge } from "../../components/ui/badge"; import { cn } from "@/lib/utils"; import { Loader2, diff --git a/components/dashboards/SentimentChart.tsx b/src/components/dashboards/SentimentChart.tsx similarity index 100% rename from components/dashboards/SentimentChart.tsx rename to src/components/dashboards/SentimentChart.tsx diff --git a/components/dashboards/StatCard.tsx b/src/components/dashboards/StatCard.tsx similarity index 100% rename from components/dashboards/StatCard.tsx rename to src/components/dashboards/StatCard.tsx diff --git a/components/dashboards/TrendChart.tsx b/src/components/dashboards/TrendChart.tsx similarity index 100% rename from components/dashboards/TrendChart.tsx rename to src/components/dashboards/TrendChart.tsx diff --git a/components/dashboards/WordCloud.tsx b/src/components/dashboards/WordCloud.tsx similarity index 100% rename from components/dashboards/WordCloud.tsx rename to src/components/dashboards/WordCloud.tsx diff --git a/components/skeletons/ModelInfoSkeleton.tsx b/src/components/skeletons/ModelInfoSkeleton.tsx similarity index 96% rename from components/skeletons/ModelInfoSkeleton.tsx rename to src/components/skeletons/ModelInfoSkeleton.tsx index ede7923..e7f533f 100644 --- a/components/skeletons/ModelInfoSkeleton.tsx +++ b/src/components/skeletons/ModelInfoSkeleton.tsx @@ -1,4 +1,4 @@ -import { ArrowDown, ChevronDown } from "lucide-react"; +import { ChevronDown } from "lucide-react"; export function ModelInfoSkeleton() { return ( diff --git a/components/ui/badge.tsx b/src/components/ui/badge.tsx similarity index 100% rename from components/ui/badge.tsx rename to src/components/ui/badge.tsx diff --git a/components/ui/button.tsx b/src/components/ui/button.tsx similarity index 100% rename from components/ui/button.tsx rename to src/components/ui/button.tsx diff --git a/components/ui/card.tsx b/src/components/ui/card.tsx similarity index 100% rename from components/ui/card.tsx rename to src/components/ui/card.tsx diff --git a/components/ui/combobox.tsx b/src/components/ui/combobox.tsx similarity index 98% rename from components/ui/combobox.tsx rename to src/components/ui/combobox.tsx index a8d0c36..c5496ea 100644 --- a/components/ui/combobox.tsx +++ b/src/components/ui/combobox.tsx @@ -5,13 +5,13 @@ import { Combobox as ComboboxPrimitive } from "@base-ui/react"; import { CheckIcon, ChevronDownIcon, XIcon } from "lucide-react"; import { cn } from "@/lib/utils"; -import { Button } from "@/components/ui/button"; +import { Button } from "../../components/ui/button"; import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, -} from "@/components/ui/input-group"; +} from "../../components/ui/input-group"; const Combobox = ComboboxPrimitive.Root; diff --git a/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx similarity index 100% rename from components/ui/dropdown-menu.tsx rename to src/components/ui/dropdown-menu.tsx diff --git a/components/ui/field.tsx b/src/components/ui/field.tsx similarity index 89% rename from components/ui/field.tsx rename to src/components/ui/field.tsx index 235d00e..0543eb8 100644 --- a/components/ui/field.tsx +++ b/src/components/ui/field.tsx @@ -1,11 +1,11 @@ -"use client" +"use client"; -import { useMemo } from "react" -import { cva, type VariantProps } from "class-variance-authority" +import { useMemo } from "react"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "@/lib/utils" -import { Label } from "@/components/ui/label" -import { Separator } from "@/components/ui/separator" +import { cn } from "@/lib/utils"; +import { Label } from "../../components/ui/label"; +import { Separator } from "../../components/ui/separator"; function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) { return ( @@ -14,11 +14,11 @@ function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) { className={cn( "flex flex-col gap-6", "has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3", - className + className, )} {...props} /> - ) + ); } function FieldLegend({ @@ -34,11 +34,11 @@ function FieldLegend({ "mb-3 font-medium", "data-[variant=legend]:text-base", "data-[variant=label]:text-sm", - className + className, )} {...props} /> - ) + ); } function FieldGroup({ className, ...props }: React.ComponentProps<"div">) { @@ -47,11 +47,11 @@ function FieldGroup({ className, ...props }: React.ComponentProps<"div">) { data-slot="field-group" className={cn( "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4", - className + className, )} {...props} /> - ) + ); } const fieldVariants = cva( @@ -75,8 +75,8 @@ const fieldVariants = cva( defaultVariants: { orientation: "vertical", }, - } -) + }, +); function Field({ className, @@ -91,7 +91,7 @@ function Field({ className={cn(fieldVariants({ orientation }), className)} {...props} /> - ) + ); } function FieldContent({ className, ...props }: React.ComponentProps<"div">) { @@ -100,11 +100,11 @@ function FieldContent({ className, ...props }: React.ComponentProps<"div">) { data-slot="field-content" className={cn( "group/field-content flex flex-1 flex-col gap-1.5 leading-snug", - className + className, )} {...props} /> - ) + ); } function FieldLabel({ @@ -118,11 +118,11 @@ function FieldLabel({ "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50", "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4", "has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10", - className + className, )} {...props} /> - ) + ); } function FieldTitle({ className, ...props }: React.ComponentProps<"div">) { @@ -131,11 +131,11 @@ function FieldTitle({ className, ...props }: React.ComponentProps<"div">) { data-slot="field-label" className={cn( "flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50", - className + className, )} {...props} /> - ) + ); } function FieldDescription({ className, ...props }: React.ComponentProps<"p">) { @@ -146,11 +146,11 @@ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) { "text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance", "last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5", "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4", - className + className, )} {...props} /> - ) + ); } function FieldSeparator({ @@ -158,7 +158,7 @@ function FieldSeparator({ className, ...props }: React.ComponentProps<"div"> & { - children?: React.ReactNode + children?: React.ReactNode; }) { return (
@@ -180,7 +180,7 @@ function FieldSeparator({ )}
- ) + ); } function FieldError({ @@ -189,37 +189,37 @@ function FieldError({ errors, ...props }: React.ComponentProps<"div"> & { - errors?: Array<{ message?: string } | undefined> + errors?: Array<{ message?: string } | undefined>; }) { const content = useMemo(() => { if (children) { - return children + return children; } if (!errors?.length) { - return null + return null; } const uniqueErrors = [ ...new Map(errors.map((error) => [error?.message, error])).values(), - ] + ]; if (uniqueErrors?.length == 1) { - return uniqueErrors[0]?.message + return uniqueErrors[0]?.message; } return ( - ) - }, [children, errors]) + ); + }, [children, errors]); if (!content) { - return null + return null; } return ( @@ -231,7 +231,7 @@ function FieldError({ > {content} - ) + ); } export { @@ -245,4 +245,4 @@ export { FieldSet, FieldContent, FieldTitle, -} +}; diff --git a/components/ui/input-group.tsx b/src/components/ui/input-group.tsx similarity index 92% rename from components/ui/input-group.tsx rename to src/components/ui/input-group.tsx index 3d1f9d9..17940f9 100644 --- a/components/ui/input-group.tsx +++ b/src/components/ui/input-group.tsx @@ -1,12 +1,12 @@ -"use client" +"use client"; -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "@/lib/utils" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import { Textarea } from "@/components/ui/textarea" +import { cn } from "@/lib/utils"; +import { Button } from "../../components/ui/button"; +import { Input } from "../../components/ui/input"; +import { Textarea } from "../../components/ui/textarea"; function InputGroup({ className, ...props }: React.ComponentProps<"div">) { return ( @@ -29,11 +29,11 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) { // Error state. "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40", - className + className, )} {...props} /> - ) + ); } const inputGroupAddonVariants = cva( @@ -54,8 +54,8 @@ const inputGroupAddonVariants = cva( defaultVariants: { align: "inline-start", }, - } -) + }, +); function InputGroupAddon({ className, @@ -70,13 +70,13 @@ function InputGroupAddon({ className={cn(inputGroupAddonVariants({ align }), className)} onClick={(e) => { if ((e.target as HTMLElement).closest("button")) { - return + return; } - e.currentTarget.parentElement?.querySelector("input")?.focus() + e.currentTarget.parentElement?.querySelector("input")?.focus(); }} {...props} /> - ) + ); } const inputGroupButtonVariants = cva( @@ -94,8 +94,8 @@ const inputGroupButtonVariants = cva( defaultVariants: { size: "xs", }, - } -) + }, +); function InputGroupButton({ className, @@ -113,7 +113,7 @@ function InputGroupButton({ className={cn(inputGroupButtonVariants({ size }), className)} {...props} /> - ) + ); } function InputGroupText({ className, ...props }: React.ComponentProps<"span">) { @@ -121,11 +121,11 @@ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) { - ) + ); } function InputGroupInput({ @@ -137,11 +137,11 @@ function InputGroupInput({ data-slot="input-group-control" className={cn( "flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent", - className + className, )} {...props} /> - ) + ); } function InputGroupTextarea({ @@ -153,11 +153,11 @@ function InputGroupTextarea({ data-slot="input-group-control" className={cn( "flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent", - className + className, )} {...props} /> - ) + ); } export { @@ -167,4 +167,4 @@ export { InputGroupText, InputGroupInput, InputGroupTextarea, -} +}; diff --git a/components/ui/input.tsx b/src/components/ui/input.tsx similarity index 100% rename from components/ui/input.tsx rename to src/components/ui/input.tsx diff --git a/components/ui/item.tsx b/src/components/ui/item.tsx similarity index 98% rename from components/ui/item.tsx rename to src/components/ui/item.tsx index 1899a60..6e1d295 100644 --- a/components/ui/item.tsx +++ b/src/components/ui/item.tsx @@ -3,7 +3,7 @@ import { cva, type VariantProps } from "class-variance-authority" import { Slot } from "radix-ui" import { cn } from "@/lib/utils" -import { Separator } from "@/components/ui/separator" +import { Separator } from "../../components/ui/separator" function ItemGroup({ className, ...props }: React.ComponentProps<"div">) { return ( diff --git a/components/ui/label.tsx b/src/components/ui/label.tsx similarity index 100% rename from components/ui/label.tsx rename to src/components/ui/label.tsx diff --git a/components/ui/select.tsx b/src/components/ui/select.tsx similarity index 100% rename from components/ui/select.tsx rename to src/components/ui/select.tsx diff --git a/components/ui/separator.tsx b/src/components/ui/separator.tsx similarity index 100% rename from components/ui/separator.tsx rename to src/components/ui/separator.tsx diff --git a/components/ui/table.tsx b/src/components/ui/table.tsx similarity index 100% rename from components/ui/table.tsx rename to src/components/ui/table.tsx diff --git a/components/ui/textarea.tsx b/src/components/ui/textarea.tsx similarity index 100% rename from components/ui/textarea.tsx rename to src/components/ui/textarea.tsx