style: make night mode visibility
This commit is contained in:
parent
be2b6d7fcd
commit
f367b1c3ad
|
|
@ -7,7 +7,7 @@ import { Button } from "../ui/button";
|
|||
import ResultSection from "./ResultSection";
|
||||
import UrlInputList from "./UrlInputList";
|
||||
|
||||
export default function AnalysisClient() {
|
||||
export default function AnalysisClient({ isDark }: { isDark: boolean }) {
|
||||
const {
|
||||
isValid,
|
||||
errors,
|
||||
|
|
@ -28,23 +28,31 @@ export default function AnalysisClient() {
|
|||
<div className="w-full mx-auto">
|
||||
<form
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
className="bg-white p-6 rounded-lg border mb-8"
|
||||
className={`p-6 rounded-lg mb-8 ${isDark ? "bg-gray-800" : "bg-white border border-gray-200"} transition-all duration-500`}
|
||||
>
|
||||
<div className="mb-4 flex items-center gap-2">
|
||||
<Sparkles className="h-5 w-5 text-primary" />
|
||||
<h3 className="text-lg font-semibold">Analisis Sentimen Real-time</h3>
|
||||
<Sparkles
|
||||
className={`h-5 w-5 text-primary ${isDark ? "text-white" : "text-black"} transition-all duration-500`}
|
||||
/>
|
||||
<h3
|
||||
className={`text-lg font-semibold ${isDark ? "text-white" : "text-black"} transition-all duration-500`}
|
||||
>
|
||||
Analisis Sentimen Real-time
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="w-full">
|
||||
<label className="block mb-1 text-sm font-medium text-gray-700">
|
||||
<label
|
||||
className={`block mb-1 text-sm font-medium ${isDark ? "text-white" : "text-gray-700"} transition-all duration-500`}
|
||||
>
|
||||
Tautan Produk 1
|
||||
</label>
|
||||
<Input
|
||||
type="url"
|
||||
placeholder="Contoh: https://tokopedia.com/..."
|
||||
className={`${errors.url1 ? "border-sentiment-negative" : "focus:ring-primary"}`}
|
||||
className={`${errors.url1 ? "border-sentiment-negative" : "focus:ring-primary"} ${isDark ? "bg-gray-800 text-white" : "bg-white"} transition-all duration-500 w-full`}
|
||||
{...register("url1")}
|
||||
/>
|
||||
{errors.url1 && (
|
||||
|
|
@ -55,13 +63,15 @@ export default function AnalysisClient() {
|
|||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<label className="block mb-1 text-sm font-medium text-gray-700">
|
||||
<label
|
||||
className={`block mb-1 text-sm font-medium ${isDark ? "text-white" : "text-gray-700"} transition-all duration-500`}
|
||||
>
|
||||
Tautan Produk 2
|
||||
</label>
|
||||
<Input
|
||||
type="url"
|
||||
placeholder="Contoh: https://tokopedia.com/..."
|
||||
className={`w-full ${errors.url2 ? "border-sentiment-negative" : "focus:ring-primary"}`}
|
||||
className={`${errors.url2 ? "border-sentiment-negative" : "focus:ring-primary"} ${isDark ? "bg-gray-800 text-white" : "bg-white"} transition-all duration-500 w-full`}
|
||||
{...register("url2")}
|
||||
/>
|
||||
{errors.url2 && (
|
||||
|
|
@ -77,6 +87,7 @@ export default function AnalysisClient() {
|
|||
urlDatas={urlDatas}
|
||||
visibleFields={visibleFields}
|
||||
setVisibleFields={setVisibleFields}
|
||||
isDark={isDark}
|
||||
/>
|
||||
|
||||
{visibleFields < 2 && (
|
||||
|
|
@ -90,10 +101,11 @@ export default function AnalysisClient() {
|
|||
type="button"
|
||||
onClick={() => setVisibleFields((prev) => prev + 1)}
|
||||
className={`
|
||||
h-max bg-card text-primary hover:bg-[#F8FBFF]
|
||||
h-max bg-card text-primary
|
||||
border-dashed border border-primary/20 shadow-xs
|
||||
transition-all duration-500 animate-in fade-in zoom-in-95
|
||||
${visibleFields === 0 ? "w-full md:w-1/2" : "w-full"}
|
||||
${isDark ? "bg-gray-800 text-white hover:bg-gray-900 border-dashed border border-white" : "text-black hover:bg-[#F8FBFF] "}
|
||||
`}
|
||||
>
|
||||
{visibleFields === 0
|
||||
|
|
@ -136,7 +148,7 @@ export default function AnalysisClient() {
|
|||
type="submit"
|
||||
hidden={loading}
|
||||
disabled={!isValid}
|
||||
className="w-full md:w-max bg-primary text-white px-6 py-3 mt-6 rounded-md transition-colors disabled:bg-gray-400"
|
||||
className={`w-full md:w-max bg-primary text-white px-6 py-3 mt-6 rounded-md transition-colors disabled:bg-gray-400`}
|
||||
>
|
||||
<Sparkles className="h-4 w-4" />
|
||||
{loading ? "Menganalisis..." : "Analisis Sekarang"}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export function BrandFilter() {
|
|||
<SelectValue placeholder="Pilih Brand" />
|
||||
</SelectTrigger>
|
||||
<SelectContent
|
||||
className="bg-card border-border shadow-lg"
|
||||
className="bg-card shadow-lg"
|
||||
position="popper"
|
||||
>
|
||||
<SelectItem
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
Frown,
|
||||
Meh,
|
||||
MessageSquareText,
|
||||
Moon,
|
||||
Smile,
|
||||
Sparkles,
|
||||
} from "lucide-react";
|
||||
|
|
@ -30,13 +31,21 @@ export default function DashboardClient() {
|
|||
neutralCount,
|
||||
loading,
|
||||
modelData,
|
||||
darkMode,
|
||||
setDarkMode,
|
||||
percentage,
|
||||
scrollToResult,
|
||||
} = useDashboards();
|
||||
|
||||
const toggleDarkMode = () => {
|
||||
setDarkMode((prevMode) => !prevMode);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#F8FBFF]" suppressHydrationWarning>
|
||||
<Header />
|
||||
<div
|
||||
className={`min-h-screen ${darkMode ? "bg-gray-900 text-white" : "bg-[#F8FBFF]"} suppressHydrationWarning} transition-all duration-500`}
|
||||
>
|
||||
<Header onToggle={toggleDarkMode} isDark={darkMode} />
|
||||
|
||||
<main className="container mx-auto px-4 py-8">
|
||||
<div
|
||||
|
|
@ -67,6 +76,7 @@ export default function DashboardClient() {
|
|||
value={totalReviews}
|
||||
icon={MessageSquareText}
|
||||
delay={0}
|
||||
isDark={darkMode}
|
||||
/>
|
||||
|
||||
<StatCard
|
||||
|
|
@ -76,6 +86,7 @@ export default function DashboardClient() {
|
|||
icon={Smile}
|
||||
variant="positive"
|
||||
delay={100}
|
||||
isDark={darkMode}
|
||||
/>
|
||||
|
||||
<StatCard
|
||||
|
|
@ -85,6 +96,7 @@ export default function DashboardClient() {
|
|||
icon={Frown}
|
||||
variant="negative"
|
||||
delay={200}
|
||||
isDark={darkMode}
|
||||
/>
|
||||
|
||||
<StatCard
|
||||
|
|
@ -94,6 +106,7 @@ export default function DashboardClient() {
|
|||
icon={Meh}
|
||||
variant="neutral"
|
||||
delay={300}
|
||||
isDark={darkMode}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
@ -111,24 +124,34 @@ export default function DashboardClient() {
|
|||
</div> */}
|
||||
|
||||
<div className="mb-8 grid gap-4 lg:grid-cols-2">
|
||||
<div className="rounded-xl border bg-card p-6">
|
||||
<div
|
||||
className={`rounded-xl border ${darkMode ? "border-transparent" : "border-gray-200"} bg-card p-6 ${darkMode ? "bg-gray-800" : "bg-white"} transition-all duration-500`}
|
||||
>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<FileLock className="h-5 w-5 text-primary" />
|
||||
<h3 className="text-lg font-semibold">Kata Kunci Populer</h3>
|
||||
<FileLock
|
||||
className={`h-5 w-5 text-primary ${darkMode ? "text-white" : "text-black"} transition-all duration-500`}
|
||||
/>
|
||||
<h3
|
||||
className={`text-lg font-semibold ${darkMode ? "text-white" : "text-neutral"} transition-all duration-500`}
|
||||
>
|
||||
Kata Kunci Populer
|
||||
</h3>
|
||||
</div>
|
||||
<p className="mb-4 text-sm text-muted-foreground">
|
||||
<p
|
||||
className={`mb-4 text-sm ${darkMode ? "text-white" : "text-neutral"} transition-all duration-500`}
|
||||
>
|
||||
Kata-kata yang sering muncul dalam ulasan berdasarkan kategori
|
||||
sentimen
|
||||
</p>
|
||||
<WordCloud />
|
||||
<WordCloud isDark={darkMode} />
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<ModelInfoSkeleton />
|
||||
) : modelData.length > 0 ? (
|
||||
<ModelInfo data={modelData} />
|
||||
<ModelInfo data={modelData} isDark={darkMode} />
|
||||
) : (
|
||||
<div className="rounded-xl border bg-card p-6 text-center text-muted-foreground">
|
||||
<div className="rounded-xl border border-gray-200 bg-card p-6 text-center text-muted-foreground">
|
||||
Data model tidak tersedia.
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -136,7 +159,7 @@ export default function DashboardClient() {
|
|||
|
||||
<section id="analysis-form" className="scroll-mt-60">
|
||||
<div className="mb-8 ">
|
||||
<AnalysisClient />
|
||||
<AnalysisClient isDark={darkMode} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import {
|
|||
Database,
|
||||
Laptop,
|
||||
LogOut,
|
||||
Moon,
|
||||
User,
|
||||
UserCircle,
|
||||
} from "lucide-react";
|
||||
|
|
@ -19,14 +20,23 @@ import { signOut } from "next-auth/react";
|
|||
import Link from "next/link";
|
||||
import { useHeader } from "@/src/hooks/useHeader";
|
||||
import { useDashboards } from "@/src/hooks/useDashboard";
|
||||
import { useState } from "react";
|
||||
|
||||
export function Header() {
|
||||
export function Header({
|
||||
onToggle,
|
||||
isDark,
|
||||
}: {
|
||||
onToggle: () => void;
|
||||
isDark: boolean;
|
||||
}) {
|
||||
const { open, setOpen, session, mounted, productCount } = useHeader();
|
||||
const { totalReviews } = useDashboards();
|
||||
|
||||
if (!mounted) return null;
|
||||
return (
|
||||
<header className="border-b bg-[#F8FBFF]/50 backdrop-blur-sm sticky top-0 z-1">
|
||||
<header
|
||||
className={`border-b ${isDark ? "bg-gray-900 text-white" : "bg-[#F8FBFF]/50"} backdrop-blur-sm sticky top-0 z-10 transition-all duration-500`}
|
||||
>
|
||||
<div className="container mx-auto px-4 py-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Link href="/" className="flex items-center gap-3 cursor-pointer">
|
||||
|
|
@ -86,6 +96,7 @@ export function Header() {
|
|||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
<Moon onClick={onToggle} className="h-4 w-4 cursor-pointer" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,13 @@ import {
|
|||
import { ModelDB } from "@/src/types";
|
||||
import { useModelInfo } from "@/src/hooks/useModelInfo";
|
||||
|
||||
export function ModelInfo({ data }: { data: ModelDB[] }) {
|
||||
export function ModelInfo({
|
||||
data,
|
||||
isDark,
|
||||
}: {
|
||||
data: ModelDB[];
|
||||
isDark: boolean;
|
||||
}) {
|
||||
const { selectedIndex, metrics, setSelectedIndex, currentModel } =
|
||||
useModelInfo({ data });
|
||||
|
||||
|
|
@ -26,25 +32,29 @@ export function ModelInfo({ data }: { data: ModelDB[] }) {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border bg-card p-6">
|
||||
<div
|
||||
className={`rounded-xl border ${isDark ? "border-transparent" : "border-gray-200"} bg-card p-6 ${isDark ? "bg-gray-800" : "bg-white"} transition-all duration-500`}
|
||||
>
|
||||
<div className="mb-4 flex items-center justify-between gap-4">
|
||||
<Select
|
||||
value={selectedIndex.toString()}
|
||||
onValueChange={(val) => setSelectedIndex(parseInt(val))}
|
||||
>
|
||||
<SelectTrigger className="w-fit justify-start gap-3 text-md font-semibold border-border bg-card shadow-sm">
|
||||
<SelectTrigger
|
||||
className={`w-fit justify-start gap-3 text-md font-semibold border border-gray-200 bg-card ${isDark ? "bg-gray-900" : "bg-white"} transition-all duration-500`}
|
||||
>
|
||||
<SelectValue placeholder="Pilih Model" />
|
||||
</SelectTrigger>
|
||||
|
||||
<SelectContent
|
||||
className="bg-card border-border shadow-lg"
|
||||
className={`bg-card shadow-lg ${isDark ? "bg-gray-900 text-white" : "bg-white"}`}
|
||||
position="popper"
|
||||
>
|
||||
{data.map((model, index) => (
|
||||
<SelectItem
|
||||
key={model.modelName + index}
|
||||
value={index.toString()}
|
||||
className="cursor-pointer hover:bg-primary hover:text-card focus:bg-primary focus:text-card"
|
||||
className={`cursor-pointer hover:bg-primary hover:text-card focus:bg-primary focus:text-card ${isDark ? "bg-gray-900 text-white" : "bg-white"} transition-all duration-500`}
|
||||
>
|
||||
{model.modelName}
|
||||
</SelectItem>
|
||||
|
|
@ -54,7 +64,7 @@ export function ModelInfo({ data }: { data: ModelDB[] }) {
|
|||
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className={`bg-sentiment-positive-light text-sentiment-positive ${currentModel.isActive ? "bg-sentiment-positive-light text-sentiment-positive" : "bg-primary/10 text-primary"}`}
|
||||
className={`${currentModel.isActive ? `${isDark ? "bg-sentiment-positive/10 text-sentiment-positive" : "bg-sentiment-positive-light text-sentiment-positive"}` : `${isDark ? "bg-gray-900 text-white" : "bg-primary/10 text-primary"}`} transition-all duration-500`}
|
||||
>
|
||||
{currentModel.isActive === true ? "Active" : "Inactive"}
|
||||
</Badge>
|
||||
|
|
@ -70,8 +80,12 @@ export function ModelInfo({ data }: { data: ModelDB[] }) {
|
|||
key={metric.label}
|
||||
className="flex items-center gap-3 rounded-lg p-3 bg-secondary/50 border border-border/40"
|
||||
>
|
||||
<div className="rounded-lg bg-primary/10 p-2">
|
||||
<metric.icon className="h-4 w-4 text-primary" />
|
||||
<div
|
||||
className={`rounded-lg p-2 ${isDark ? "bg-gray-600" : "bg-primary/10 "} transition-all duration-500`}
|
||||
>
|
||||
<metric.icon
|
||||
className={`h-4 w-4 text-primary ${isDark ? "text-white" : "text-black"} transition-all duration-500`}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs text-muted-foreground">{metric.label}</p>
|
||||
|
|
@ -85,7 +99,9 @@ export function ModelInfo({ data }: { data: ModelDB[] }) {
|
|||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-6 space-y-2 text-sm text-muted-foreground border-t pt-4">
|
||||
<div
|
||||
className={`mt-6 space-y-2 text-sm text-muted-foreground border-t border-gray-200 pt-4`}
|
||||
>
|
||||
<div className="flex justify-between">
|
||||
<span>Preprocessing</span>
|
||||
<span className="text-foreground">
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ export function ReviewTable() {
|
|||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="rounded-xl border bg-card">
|
||||
<div className="rounded-xl border border-gray-200 bg-card">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="hover:bg-transparent">
|
||||
|
|
@ -155,7 +155,7 @@ export function ReviewTable() {
|
|||
</Table>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<div className="border-t bg-muted/20 px-6 py-4">
|
||||
<div className="border-t border-t-gray-200 bg-muted/20 px-6 py-4">
|
||||
<Pagination className="justify-center sm:justify-end">
|
||||
<PaginationContent>
|
||||
<PaginationItem>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export function StatCard({
|
|||
trend,
|
||||
variant = "default",
|
||||
delay = 0,
|
||||
isDark,
|
||||
}: StatCardProps) {
|
||||
const { isVisible, displayValue } = useStatCard({ value, delay });
|
||||
|
||||
|
|
@ -20,18 +21,28 @@ export function StatCard({
|
|||
"relative overflow-hidden rounded-xl border p-6 card-elevated transition-all duration-500",
|
||||
variantStyles[variant],
|
||||
isVisible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4",
|
||||
isDark ? "bg-gray-800" : "bg-white",
|
||||
isDark ? "border-transparent" : "border-gray-200",
|
||||
)}
|
||||
>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm font-medium text-muted-foreground">{title}</p>
|
||||
<p
|
||||
className={`text-sm font-medium text-muted-foreground ${isDark ? "text-white" : "text-neutral"}`}
|
||||
>
|
||||
{title}
|
||||
</p>
|
||||
|
||||
<div className="flex items-baseline gap-1">
|
||||
<span className="text-3xl font-bold tracking-tight">
|
||||
<span
|
||||
className={`text-3xl font-bold tracking-tight ${isDark ? "text-white" : "text-neutral"}`}
|
||||
>
|
||||
{displayValue.toLocaleString()}
|
||||
</span>
|
||||
{suffix && (
|
||||
<span className="text-lg font-medium text-muted-foreground">
|
||||
<span
|
||||
className={`text-lg font-medium ${isDark ? "text-white" : "text-neutral"}`}
|
||||
>
|
||||
{suffix}
|
||||
</span>
|
||||
)}
|
||||
|
|
@ -55,7 +66,7 @@ export function StatCard({
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className={cn("rounded-xl p-3", iconStyles[variant])}>
|
||||
<div className={cn("rounded-xl p-3 transition-all duration-500", iconStyles(isDark)[variant])}>
|
||||
<Icon className="h-6 w-6" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,10 +7,13 @@ const UrlInputItem = ({
|
|||
index,
|
||||
visibleFields,
|
||||
onRemove,
|
||||
isDark,
|
||||
}: UrlInputItemProps) => {
|
||||
return (
|
||||
<div className="animate-in fade-in slide-in-from-bottom-2 duration-300">
|
||||
<label className="block mb-1 text-sm font-medium text-gray-700">
|
||||
<label
|
||||
className={`block mb-1 text-sm font-medium ${isDark ? "text-white" : "text-gray-700"} transition-all duration-500`}
|
||||
>
|
||||
{item.labels}
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
|
|
@ -18,16 +21,15 @@ const UrlInputItem = ({
|
|||
<Input
|
||||
type="url"
|
||||
placeholder="Contoh: https://tokopedia.com/..."
|
||||
className={`${item.errors ? "border-sentiment-negative" : "focus:ring-primary"}`}
|
||||
className={`${item.errors ? "border-sentiment-negative" : "focus:ring-primary"} ${isDark ? "bg-gray-800 text-white" : "bg-white"} transition-all duration-500 w-full`}
|
||||
{...item.title}
|
||||
/>
|
||||
</div>
|
||||
{index === visibleFields - 1 && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
onClick={onRemove}
|
||||
className="text-sentiment-negative hover:text-sentiment-negative hover:bg-sentiment-negative-light shrink-0"
|
||||
className={`shrink-0 ${isDark ? "text-sentiment-negative bg-transparent hover:text-sentiment-negative hover:bg-sentiment-negative/10" : "text-sentiment-negative bg-card hover:text-sentiment-negative hover:bg-sentiment-negative-light"} transition-all duration-500`}
|
||||
>
|
||||
✕
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ const UrlInputList = ({
|
|||
urlDatas,
|
||||
visibleFields,
|
||||
setVisibleFields,
|
||||
isDark,
|
||||
}: UrlInputListProps) => {
|
||||
return (
|
||||
<>
|
||||
|
|
@ -15,6 +16,7 @@ const UrlInputList = ({
|
|||
index={index}
|
||||
visibleFields={visibleFields}
|
||||
onRemove={() => setVisibleFields((prev) => prev - 1)}
|
||||
isDark={isDark}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { useWordCloud } from "@/src/hooks/useWordCloud";
|
|||
import WordCloudItem from "./WordCloudItem";
|
||||
import { Inbox } from "lucide-react";
|
||||
|
||||
export function WordCloud() {
|
||||
export function WordCloud({ isDark }: { isDark: boolean }) {
|
||||
const { maxValue, minValue, shuffledWords, isEmpty } = useWordCloud();
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|||
type={type}
|
||||
data-slot="input"
|
||||
className={cn(
|
||||
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border border-gray-200 bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
||||
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
className
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export const useDashboards = () => {
|
|||
negative: 0,
|
||||
neutral: 0,
|
||||
});
|
||||
const [darkMode, setDarkMode] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchStats() {
|
||||
|
|
@ -84,6 +85,8 @@ export const useDashboards = () => {
|
|||
selectedBrand,
|
||||
loading,
|
||||
modelData,
|
||||
darkMode,
|
||||
setDarkMode,
|
||||
setSelectedBrand,
|
||||
percentage,
|
||||
scrollToResult,
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ export interface StatCardProps {
|
|||
};
|
||||
variant?: "default" | "positive" | "negative" | "neutral";
|
||||
delay?: number;
|
||||
isDark: boolean;
|
||||
}
|
||||
|
||||
interface TrendData {
|
||||
|
|
@ -385,10 +386,12 @@ export type UrlInputItemProps = {
|
|||
index: number;
|
||||
visibleFields: number;
|
||||
onRemove: () => void;
|
||||
isDark: boolean;
|
||||
};
|
||||
|
||||
export type UrlInputListProps = {
|
||||
urlDatas: UrlData[];
|
||||
visibleFields: number;
|
||||
setVisibleFields: React.Dispatch<React.SetStateAction<number>>;
|
||||
isDark: boolean;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ const variantStyles = {
|
|||
neutral: "bg-sentiment-neutral-light border-sentiment-neutral/20",
|
||||
};
|
||||
|
||||
const iconStyles = {
|
||||
default: "bg-primary/10 text-primary",
|
||||
positive: "bg-sentiment-positive/10 text-sentiment-positive",
|
||||
negative: "bg-sentiment-negative/10 text-sentiment-negative",
|
||||
neutral: "bg-sentiment-neutral/10 text-sentiment-neutral",
|
||||
const iconStyles = (isDark: boolean) => {
|
||||
return {
|
||||
default: `bg-primary/10 text-primary ${isDark ? "text-white" : "text-neutral"} ${isDark ? "bg-gray-900" : "bg-primary/10"}`,
|
||||
positive: "bg-sentiment-positive/10 text-sentiment-positive",
|
||||
negative: "bg-sentiment-negative/10 text-sentiment-negative",
|
||||
neutral: "bg-sentiment-neutral/10 text-sentiment-neutral",
|
||||
};
|
||||
};
|
||||
|
||||
export { variantStyles, iconStyles };
|
||||
|
|
|
|||
Loading…
Reference in New Issue