mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-11 16:52:38 +02:00
Merge commit '59e21db42b' into dev
This commit is contained in:
commit
ccf8454db5
10 changed files with 42 additions and 30 deletions
|
|
@ -165,6 +165,7 @@ export function LocalLoginForm() {
|
||||||
id="email"
|
id="email"
|
||||||
type="email"
|
type="email"
|
||||||
required
|
required
|
||||||
|
placeholder="you@example.com"
|
||||||
value={username}
|
value={username}
|
||||||
onChange={(e) => setUsername(e.target.value)}
|
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 ${
|
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"
|
id="password"
|
||||||
type={showPassword ? "text" : "password"}
|
type={showPassword ? "text" : "password"}
|
||||||
required
|
required
|
||||||
|
placeholder="Enter your password"
|
||||||
value={password}
|
value={password}
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
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 ${
|
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 ${
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,7 @@ export default function RegisterPage() {
|
||||||
id="email"
|
id="email"
|
||||||
type="email"
|
type="email"
|
||||||
required
|
required
|
||||||
|
placeholder="you@example.com"
|
||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
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 ${
|
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"
|
id="password"
|
||||||
type="password"
|
type="password"
|
||||||
required
|
required
|
||||||
|
placeholder="Enter your password"
|
||||||
value={password}
|
value={password}
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
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 ${
|
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"
|
id="confirmPassword"
|
||||||
type="password"
|
type="password"
|
||||||
required
|
required
|
||||||
|
placeholder="Confirm your password"
|
||||||
value={confirmPassword}
|
value={confirmPassword}
|
||||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
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 ${
|
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 ${
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { ActionBarPrimitive, AuiIf, MessagePrimitive, useAuiState } from "@assistant-ui/react";
|
import { ActionBarPrimitive, AuiIf, MessagePrimitive, useAuiState } from "@assistant-ui/react";
|
||||||
import { useAtomValue } from "jotai";
|
import { useAtomValue } from "jotai";
|
||||||
import { CheckIcon, CopyIcon, FileText, Pen } from "lucide-react";
|
import { FileText, Pen } from "lucide-react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { type FC, useState } from "react";
|
import { type FC, useState } from "react";
|
||||||
import { messageDocumentsMapAtom } from "@/atoms/chat/mentioned-documents.atom";
|
import { messageDocumentsMapAtom } from "@/atoms/chat/mentioned-documents.atom";
|
||||||
|
|
@ -30,7 +30,7 @@ const UserAvatar: FC<AuthorMetadata> = ({ displayName, avatarUrl }) => {
|
||||||
alt={displayName || "User"}
|
alt={displayName || "User"}
|
||||||
width={32}
|
width={32}
|
||||||
height={32}
|
height={32}
|
||||||
className="size-8 rounded-full object-cover select-none"
|
className="size-8 rounded-full object-cover"
|
||||||
referrerPolicy="no-referrer"
|
referrerPolicy="no-referrer"
|
||||||
onError={() => setHasError(true)}
|
onError={() => setHasError(true)}
|
||||||
unoptimized
|
unoptimized
|
||||||
|
|
|
||||||
|
|
@ -277,21 +277,24 @@ const CollisionMechanism = ({
|
||||||
}, [cycleCollisionDetected, parentRef]);
|
}, [cycleCollisionDetected, parentRef]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (collision.detected && collision.coordinates) {
|
if (!collision.detected || !collision.coordinates) return;
|
||||||
setTimeout(() => {
|
|
||||||
|
const timer1 = setTimeout(() => {
|
||||||
setCollision({ detected: false, coordinates: null });
|
setCollision({ detected: false, coordinates: null });
|
||||||
setCycleCollisionDetected(false);
|
setCycleCollisionDetected(false);
|
||||||
// Set beam opacity to 0
|
|
||||||
if (beamRef.current) {
|
if (beamRef.current) {
|
||||||
beamRef.current.style.opacity = "1";
|
beamRef.current.style.opacity = "1";
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
// Reset the beam animation after a delay
|
const timer2 = setTimeout(() => {
|
||||||
setTimeout(() => {
|
|
||||||
setBeamKey((prevKey) => prevKey + 1);
|
setBeamKey((prevKey) => prevKey + 1);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timer1);
|
||||||
|
clearTimeout(timer2);
|
||||||
|
};
|
||||||
}, [collision]);
|
}, [collision]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { ChevronsUpDown, Settings, UserPen } from "lucide-react";
|
import { ChevronsUpDown, Settings, UserPen } from "lucide-react";
|
||||||
import { useParams, useRouter } from "next/navigation";
|
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
|
|
@ -29,9 +28,6 @@ export function SidebarHeader({
|
||||||
className,
|
className,
|
||||||
}: SidebarHeaderProps) {
|
}: SidebarHeaderProps) {
|
||||||
const t = useTranslations("sidebar");
|
const t = useTranslations("sidebar");
|
||||||
const router = useRouter();
|
|
||||||
const params = useParams();
|
|
||||||
const searchSpaceId = params.search_space_id as string;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("flex min-w-0 flex-1 items-center", className)}>
|
<div className={cn("flex min-w-0 flex-1 items-center", className)}>
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ export function Pricing({
|
||||||
>
|
>
|
||||||
{plans.map((plan, index) => (
|
{plans.map((plan, index) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
key={index}
|
key={plan.name}
|
||||||
initial={{ y: 50, opacity: 1 }}
|
initial={{ y: 50, opacity: 1 }}
|
||||||
whileInView={
|
whileInView={
|
||||||
isDesktop
|
isDesktop
|
||||||
|
|
@ -193,8 +193,8 @@ export function Pricing({
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul className="mt-5 gap-2 flex flex-col">
|
<ul className="mt-5 gap-2 flex flex-col">
|
||||||
{plan.features.map((feature, idx) => (
|
{plan.features.map((feature) => (
|
||||||
<li key={idx} className="flex items-start gap-2">
|
<li key={feature} className="flex items-start gap-2">
|
||||||
<Check className="h-4 w-4 text-primary mt-1 flex-shrink-0" />
|
<Check className="h-4 w-4 text-primary mt-1 flex-shrink-0" />
|
||||||
<span className="text-left">{feature}</span>
|
<span className="text-left">{feature}</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
useAuiState,
|
useAuiState,
|
||||||
} from "@assistant-ui/react";
|
} from "@assistant-ui/react";
|
||||||
import { CheckIcon, CopyIcon } from "lucide-react";
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
||||||
|
import Image from "next/image";
|
||||||
import { type FC, type ReactNode, useState } from "react";
|
import { type FC, type ReactNode, useState } from "react";
|
||||||
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
|
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
|
||||||
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
|
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
|
||||||
|
|
@ -79,10 +80,11 @@ const UserAvatar: FC<AuthorMetadata & { hasError: boolean; onError: () => void }
|
||||||
|
|
||||||
if (avatarUrl && !hasError) {
|
if (avatarUrl && !hasError) {
|
||||||
return (
|
return (
|
||||||
// biome-ignore lint/performance/noImgElement: external OAuth/profile avatar URL
|
<Image
|
||||||
<img
|
|
||||||
src={avatarUrl}
|
src={avatarUrl}
|
||||||
alt={displayName || "User"}
|
alt={displayName || "User"}
|
||||||
|
width={32}
|
||||||
|
height={32}
|
||||||
className="size-8 rounded-full object-cover"
|
className="size-8 rounded-full object-cover"
|
||||||
referrerPolicy="no-referrer"
|
referrerPolicy="no-referrer"
|
||||||
onError={onError}
|
onError={onError}
|
||||||
|
|
|
||||||
|
|
@ -143,9 +143,11 @@ function CopyButton({
|
||||||
const [hasCopied, setHasCopied] = React.useState(false);
|
const [hasCopied, setHasCopied] = React.useState(false);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setTimeout(() => {
|
if (!hasCopied) return;
|
||||||
|
const timer = setTimeout(() => {
|
||||||
setHasCopied(false);
|
setHasCopied(false);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
}, [hasCopied]);
|
}, [hasCopied]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,7 @@ function LinkOpenButton() {
|
||||||
}}
|
}}
|
||||||
aria-label="Open link in a new tab"
|
aria-label="Open link in a new tab"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
<ExternalLink width={18} />
|
<ExternalLink width={18} />
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,17 @@ export function Spotlight({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!parentElement) return;
|
if (!parentElement) return;
|
||||||
|
|
||||||
|
const handleEnter = () => setIsHovered(true);
|
||||||
|
const handleLeave = () => setIsHovered(false);
|
||||||
|
|
||||||
parentElement.addEventListener("mousemove", handleMouseMove);
|
parentElement.addEventListener("mousemove", handleMouseMove);
|
||||||
parentElement.addEventListener("mouseenter", () => setIsHovered(true));
|
parentElement.addEventListener("mouseenter", handleEnter);
|
||||||
parentElement.addEventListener("mouseleave", () => setIsHovered(false));
|
parentElement.addEventListener("mouseleave", handleLeave);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
parentElement.removeEventListener("mousemove", handleMouseMove);
|
parentElement.removeEventListener("mousemove", handleMouseMove);
|
||||||
parentElement.removeEventListener("mouseenter", () => setIsHovered(true));
|
parentElement.removeEventListener("mouseenter", handleEnter);
|
||||||
parentElement.removeEventListener("mouseleave", () => setIsHovered(false));
|
parentElement.removeEventListener("mouseleave", handleLeave);
|
||||||
};
|
};
|
||||||
}, [parentElement, handleMouseMove]);
|
}, [parentElement, handleMouseMove]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue