diff --git a/surfsense_web/app/(home)/login/LocalLoginForm.tsx b/surfsense_web/app/(home)/login/LocalLoginForm.tsx index ad649848f..9481976a9 100644 --- a/surfsense_web/app/(home)/login/LocalLoginForm.tsx +++ b/surfsense_web/app/(home)/login/LocalLoginForm.tsx @@ -165,6 +165,7 @@ export function LocalLoginForm() { id="email" type="email" required + placeholder="you@example.com" value={username} onChange={(e) => setUsername(e.target.value)} className={`mt-1 block w-full rounded-md border px-3 py-1.5 md:py-2 shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 dark:bg-gray-800 dark:text-white transition-all ${ @@ -188,6 +189,7 @@ export function LocalLoginForm() { id="password" type={showPassword ? "text" : "password"} required + placeholder="Enter your password" value={password} onChange={(e) => setPassword(e.target.value)} className={`mt-1 block w-full rounded-md border pr-10 px-3 py-1.5 md:py-2 shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 dark:bg-gray-800 dark:text-white transition-all ${ diff --git a/surfsense_web/app/(home)/register/page.tsx b/surfsense_web/app/(home)/register/page.tsx index b7109080f..35fa2b668 100644 --- a/surfsense_web/app/(home)/register/page.tsx +++ b/surfsense_web/app/(home)/register/page.tsx @@ -231,6 +231,7 @@ export default function RegisterPage() { id="email" type="email" required + placeholder="you@example.com" value={email} onChange={(e) => setEmail(e.target.value)} className={`mt-1 block w-full rounded-md border px-3 py-1.5 md:py-2 shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 dark:bg-gray-800 dark:text-white transition-all ${ @@ -253,6 +254,7 @@ export default function RegisterPage() { id="password" type="password" required + placeholder="Enter your password" value={password} onChange={(e) => setPassword(e.target.value)} className={`mt-1 block w-full rounded-md border px-3 py-1.5 md:py-2 shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 dark:bg-gray-800 dark:text-white transition-all ${ @@ -275,6 +277,7 @@ export default function RegisterPage() { id="confirmPassword" type="password" required + placeholder="Confirm your password" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} className={`mt-1 block w-full rounded-md border px-3 py-1.5 md:py-2 shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 dark:bg-gray-800 dark:text-white transition-all ${ diff --git a/surfsense_web/components/assistant-ui/user-message.tsx b/surfsense_web/components/assistant-ui/user-message.tsx index c01e8e486..61cecd1a2 100644 --- a/surfsense_web/components/assistant-ui/user-message.tsx +++ b/surfsense_web/components/assistant-ui/user-message.tsx @@ -1,6 +1,6 @@ import { ActionBarPrimitive, AuiIf, MessagePrimitive, useAuiState } from "@assistant-ui/react"; import { useAtomValue } from "jotai"; -import { CheckIcon, CopyIcon, FileText, Pen } from "lucide-react"; +import { FileText, Pen } from "lucide-react"; import Image from "next/image"; import { type FC, useState } from "react"; import { messageDocumentsMapAtom } from "@/atoms/chat/mentioned-documents.atom"; @@ -30,7 +30,7 @@ const UserAvatar: FC = ({ displayName, avatarUrl }) => { alt={displayName || "User"} width={32} height={32} - className="size-8 rounded-full object-cover select-none" + className="size-8 rounded-full object-cover" referrerPolicy="no-referrer" onError={() => setHasError(true)} unoptimized diff --git a/surfsense_web/components/homepage/hero-section.tsx b/surfsense_web/components/homepage/hero-section.tsx index 830f9febf..3e7bccccb 100644 --- a/surfsense_web/components/homepage/hero-section.tsx +++ b/surfsense_web/components/homepage/hero-section.tsx @@ -277,21 +277,24 @@ const CollisionMechanism = ({ }, [cycleCollisionDetected, parentRef]); useEffect(() => { - if (collision.detected && collision.coordinates) { - setTimeout(() => { - setCollision({ detected: false, coordinates: null }); - setCycleCollisionDetected(false); - // Set beam opacity to 0 - if (beamRef.current) { - beamRef.current.style.opacity = "1"; - } - }, 2000); + if (!collision.detected || !collision.coordinates) return; - // Reset the beam animation after a delay - setTimeout(() => { - setBeamKey((prevKey) => prevKey + 1); - }, 2000); - } + const timer1 = setTimeout(() => { + setCollision({ detected: false, coordinates: null }); + setCycleCollisionDetected(false); + if (beamRef.current) { + beamRef.current.style.opacity = "1"; + } + }, 2000); + + const timer2 = setTimeout(() => { + setBeamKey((prevKey) => prevKey + 1); + }, 2000); + + return () => { + clearTimeout(timer1); + clearTimeout(timer2); + }; }, [collision]); return ( diff --git a/surfsense_web/components/layout/ui/sidebar/SidebarHeader.tsx b/surfsense_web/components/layout/ui/sidebar/SidebarHeader.tsx index 9d6642623..2c8539dc8 100644 --- a/surfsense_web/components/layout/ui/sidebar/SidebarHeader.tsx +++ b/surfsense_web/components/layout/ui/sidebar/SidebarHeader.tsx @@ -1,7 +1,6 @@ "use client"; import { ChevronsUpDown, Settings, UserPen } from "lucide-react"; -import { useParams, useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; import { Button } from "@/components/ui/button"; import { @@ -29,9 +28,6 @@ export function SidebarHeader({ className, }: SidebarHeaderProps) { const t = useTranslations("sidebar"); - const router = useRouter(); - const params = useParams(); - const searchSpaceId = params.search_space_id as string; return (
diff --git a/surfsense_web/components/pricing.tsx b/surfsense_web/components/pricing.tsx index 0023a3eaf..9a8e29c32 100644 --- a/surfsense_web/components/pricing.tsx +++ b/surfsense_web/components/pricing.tsx @@ -103,7 +103,7 @@ export function Pricing({ > {plans.map((plan, index) => (
    - {plan.features.map((feature, idx) => ( -
  • + {plan.features.map((feature) => ( +
  • {feature}
  • diff --git a/surfsense_web/components/public-chat/public-thread.tsx b/surfsense_web/components/public-chat/public-thread.tsx index 3a224374e..bee0496f6 100644 --- a/surfsense_web/components/public-chat/public-thread.tsx +++ b/surfsense_web/components/public-chat/public-thread.tsx @@ -8,6 +8,7 @@ import { useAuiState, } from "@assistant-ui/react"; import { CheckIcon, CopyIcon } from "lucide-react"; +import Image from "next/image"; import { type FC, type ReactNode, useState } from "react"; import { MarkdownText } from "@/components/assistant-ui/markdown-text"; import { ToolFallback } from "@/components/assistant-ui/tool-fallback"; @@ -79,10 +80,11 @@ const UserAvatar: FC void } if (avatarUrl && !hasError) { return ( - // biome-ignore lint/performance/noImgElement: external OAuth/profile avatar URL - {displayName { - setTimeout(() => { + if (!hasCopied) return; + const timer = setTimeout(() => { setHasCopied(false); }, 2000); + return () => clearTimeout(timer); }, [hasCopied]); return ( diff --git a/surfsense_web/components/ui/link-toolbar.tsx b/surfsense_web/components/ui/link-toolbar.tsx index 4f5988ded..f44b5a1d1 100644 --- a/surfsense_web/components/ui/link-toolbar.tsx +++ b/surfsense_web/components/ui/link-toolbar.tsx @@ -187,6 +187,7 @@ function LinkOpenButton() { }} aria-label="Open link in a new tab" target="_blank" + rel="noopener noreferrer" > diff --git a/surfsense_web/components/ui/spotlight.tsx b/surfsense_web/components/ui/spotlight.tsx index 2258e8814..3047559e1 100644 --- a/surfsense_web/components/ui/spotlight.tsx +++ b/surfsense_web/components/ui/spotlight.tsx @@ -48,14 +48,17 @@ export function Spotlight({ useEffect(() => { if (!parentElement) return; + const handleEnter = () => setIsHovered(true); + const handleLeave = () => setIsHovered(false); + parentElement.addEventListener("mousemove", handleMouseMove); - parentElement.addEventListener("mouseenter", () => setIsHovered(true)); - parentElement.addEventListener("mouseleave", () => setIsHovered(false)); + parentElement.addEventListener("mouseenter", handleEnter); + parentElement.addEventListener("mouseleave", handleLeave); return () => { parentElement.removeEventListener("mousemove", handleMouseMove); - parentElement.removeEventListener("mouseenter", () => setIsHovered(true)); - parentElement.removeEventListener("mouseleave", () => setIsHovered(false)); + parentElement.removeEventListener("mouseenter", handleEnter); + parentElement.removeEventListener("mouseleave", handleLeave); }; }, [parentElement, handleMouseMove]);