mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-20 10:20:15 +01:00
🔗 feat: Enhance Share Functionality, Optimize DataTable & Fix Critical Bugs (#5220)
* 🔄 refactor: frontend and backend share link logic; feat: qrcode for share link; feat: refresh link * 🐛 fix: Conditionally render shared link and refactor share link creation logic * 🐛 fix: Correct conditional check for shareId in ShareButton component * 🔄 refactor: Update shared links API and data handling; improve query parameters and response structure * 🔄 refactor: Update shared links pagination and response structure; replace pageNumber with cursor for improved data fetching * 🔄 refactor: DataTable performance optimization * fix: delete shared link cache update * 🔄 refactor: Enhance shared links functionality; add conversationId to shared link model and update related components * 🔄 refactor: Add delete functionality to SharedLinkButton; integrate delete mutation and confirmation dialog * 🔄 feat: Add AnimatedSearchInput component with gradient animations and search functionality; update search handling in API and localization * 🔄 refactor: Improve SharedLinks component; enhance delete functionality and loading states, optimize AnimatedSearchInput, and refine DataTable scrolling behavior * fix: mutation type issues with deleted shared link mutation * fix: MutationOptions types * fix: Ensure only public shared links are retrieved in getSharedLink function * fix: `qrcode.react` install location * fix: ensure non-public shared links are not fetched when checking for existing shared links, and remove deprecated .exec() method for queries * fix: types and import order * refactor: cleanup share button UI logic, make more intuitive --------- Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
460cde0c0b
commit
fa9e778399
55 changed files with 1779 additions and 1975 deletions
106
client/src/components/ui/AnimatedSearchInput.tsx
Normal file
106
client/src/components/ui/AnimatedSearchInput.tsx
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Search } from 'lucide-react';
|
||||
|
||||
const AnimatedSearchInput = ({ value, onChange, isSearching: searching, placeholder }) => {
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
const isSearching = searching === true;
|
||||
|
||||
return (
|
||||
<div className="relative w-full">
|
||||
<div className="relative rounded-lg transition-all duration-500 ease-in-out">
|
||||
{/* Background gradient effect */}
|
||||
<div
|
||||
className={`
|
||||
absolute inset-0 rounded-lg
|
||||
bg-gradient-to-r from-blue-500/20 via-purple-500/20 to-blue-500/20
|
||||
transition-all duration-500 ease-in-out
|
||||
${isSearching ? 'opacity-100 blur-sm' : 'opacity-0 blur-none'}
|
||||
`}
|
||||
/>
|
||||
|
||||
<div className="relative">
|
||||
<div className="absolute left-3 top-1/2 z-10 -translate-y-1/2">
|
||||
<Search
|
||||
className={`
|
||||
h-4 w-4 transition-all duration-500 ease-in-out
|
||||
${isFocused ? 'text-blue-500' : 'text-gray-400'}
|
||||
${isSearching ? 'text-blue-400' : ''}
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Input field with background transitions */}
|
||||
<input
|
||||
type="text"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onFocus={() => setIsFocused(true)}
|
||||
onBlur={() => setIsFocused(false)}
|
||||
placeholder={placeholder}
|
||||
className={`
|
||||
w-full rounded-lg px-10 py-2
|
||||
transition-all duration-500 ease-in-out
|
||||
placeholder:text-gray-400
|
||||
focus:outline-none focus:ring-0
|
||||
${isFocused ? 'bg-white/10' : 'bg-white/5'}
|
||||
${isSearching ? 'bg-white/15' : ''}
|
||||
backdrop-blur-sm
|
||||
`}
|
||||
/>
|
||||
|
||||
{/* Animated loading indicator */}
|
||||
<div
|
||||
className={`
|
||||
absolute right-3 top-1/2 -translate-y-1/2
|
||||
transition-all duration-500 ease-in-out
|
||||
${isSearching ? 'scale-100 opacity-100' : 'scale-0 opacity-0'}
|
||||
`}
|
||||
>
|
||||
<div className="relative h-2 w-2">
|
||||
<div className="absolute inset-0 animate-ping rounded-full bg-blue-500/60" />
|
||||
<div className="absolute inset-0 rounded-full bg-blue-500" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Outer glow effect */}
|
||||
<div
|
||||
className={`
|
||||
absolute -inset-8 -z-10
|
||||
transition-all duration-700 ease-in-out
|
||||
${isSearching ? 'scale-105 opacity-100' : 'scale-100 opacity-0'}
|
||||
`}
|
||||
>
|
||||
<div className="absolute inset-0">
|
||||
<div
|
||||
className={`
|
||||
bg-gradient-radial absolute inset-0 from-blue-500/10 to-transparent
|
||||
transition-opacity duration-700 ease-in-out
|
||||
${isSearching ? 'animate-pulse-slow opacity-100' : 'opacity-0'}
|
||||
`}
|
||||
/>
|
||||
<div
|
||||
className={`
|
||||
absolute inset-0 bg-gradient-to-r from-purple-500/5 via-blue-500/5 to-purple-500/5
|
||||
blur-xl transition-all duration-700 ease-in-out
|
||||
${isSearching ? 'animate-gradient-x opacity-100' : 'opacity-0'}
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Focus state background glow */}
|
||||
<div
|
||||
className={`
|
||||
absolute inset-0 -z-20 bg-gradient-to-r from-blue-500/10
|
||||
via-purple-500/10 to-blue-500/10 blur-xl
|
||||
transition-all duration-500 ease-in-out
|
||||
${isFocused ? 'scale-105 opacity-100' : 'scale-100 opacity-0'}
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AnimatedSearchInput;
|
||||
Loading…
Add table
Add a link
Reference in a new issue