);
@@ -17,13 +17,13 @@ function DiffViewer({ diff, fileName, isMobile, wrapText }) {
return (
{line}
diff --git a/src/components/FileTree.jsx b/src/components/FileTree.jsx
index 643d8eb..c966fcf 100644
--- a/src/components/FileTree.jsx
+++ b/src/components/FileTree.jsx
@@ -3,12 +3,263 @@ import { useTranslation } from 'react-i18next';
import { ScrollArea } from './ui/scroll-area';
import { Button } from './ui/button';
import { Input } from './ui/input';
-import { Folder, FolderOpen, File, FileText, FileCode, List, TableProperties, Eye, Search, X } from 'lucide-react';
+import {
+ Folder, FolderOpen, File, FileText, FileCode, List, TableProperties, Eye, Search, X,
+ ChevronRight,
+ FileJson, FileType, FileSpreadsheet, FileArchive,
+ Hash, Braces, Terminal, Database, Globe, Palette, Music2, Video, Archive,
+ Lock, Shield, Settings, Image, BookOpen, Cpu, Box, Gem, Coffee,
+ Flame, Hexagon, FileCode2, Code2, Cog, FileWarning, Binary, SquareFunction,
+ Scroll, FlaskConical, NotebookPen, FileCheck, Workflow, Blocks
+} from 'lucide-react';
import { cn } from '../lib/utils';
import CodeEditor from './CodeEditor';
import ImageViewer from './ImageViewer';
import { api } from '../utils/api';
+// ─── File Icon Registry ──────────────────────────────────────────────
+// Maps file extensions (and special filenames) to { icon, colorClass } pairs.
+// Uses lucide-react icons mapped semantically to file types.
+
+const ICON_SIZE = 'w-4 h-4 flex-shrink-0';
+
+const FILE_ICON_MAP = {
+ // ── JavaScript / TypeScript ──
+ js: { icon: FileCode, color: 'text-yellow-500' },
+ jsx: { icon: FileCode, color: 'text-yellow-500' },
+ mjs: { icon: FileCode, color: 'text-yellow-500' },
+ cjs: { icon: FileCode, color: 'text-yellow-500' },
+ ts: { icon: FileCode2, color: 'text-blue-500' },
+ tsx: { icon: FileCode2, color: 'text-blue-500' },
+ mts: { icon: FileCode2, color: 'text-blue-500' },
+
+ // ── Python ──
+ py: { icon: Code2, color: 'text-emerald-500' },
+ pyw: { icon: Code2, color: 'text-emerald-500' },
+ pyi: { icon: Code2, color: 'text-emerald-400' },
+ ipynb:{ icon: NotebookPen, color: 'text-orange-500' },
+
+ // ── Rust ──
+ rs: { icon: Cog, color: 'text-orange-600' },
+ toml: { icon: Settings, color: 'text-gray-500' },
+
+ // ── Go ──
+ go: { icon: Hexagon, color: 'text-cyan-500' },
+
+ // ── Ruby ──
+ rb: { icon: Gem, color: 'text-red-500' },
+ erb: { icon: Gem, color: 'text-red-400' },
+
+ // ── PHP ──
+ php: { icon: Blocks, color: 'text-violet-500' },
+
+ // ── Java / Kotlin ──
+ java: { icon: Coffee, color: 'text-red-600' },
+ jar: { icon: Coffee, color: 'text-red-500' },
+ kt: { icon: Hexagon, color: 'text-violet-500' },
+ kts: { icon: Hexagon, color: 'text-violet-400' },
+
+ // ── C / C++ ──
+ c: { icon: Cpu, color: 'text-blue-600' },
+ h: { icon: Cpu, color: 'text-blue-400' },
+ cpp: { icon: Cpu, color: 'text-blue-700' },
+ hpp: { icon: Cpu, color: 'text-blue-500' },
+ cc: { icon: Cpu, color: 'text-blue-700' },
+
+ // ── C# ──
+ cs: { icon: Hexagon, color: 'text-purple-600' },
+
+ // ── Swift ──
+ swift:{ icon: Flame, color: 'text-orange-500' },
+
+ // ── Lua ──
+ lua: { icon: SquareFunction, color: 'text-blue-500' },
+
+ // ── R ──
+ r: { icon: FlaskConical, color: 'text-blue-600' },
+
+ // ── Web ──
+ html: { icon: Globe, color: 'text-orange-600' },
+ htm: { icon: Globe, color: 'text-orange-600' },
+ css: { icon: Hash, color: 'text-blue-500' },
+ scss: { icon: Hash, color: 'text-pink-500' },
+ sass: { icon: Hash, color: 'text-pink-400' },
+ less: { icon: Hash, color: 'text-indigo-500' },
+ vue: { icon: FileCode2, color: 'text-emerald-500' },
+ svelte:{ icon: FileCode2, color: 'text-orange-500' },
+
+ // ── Data / Config ──
+ json: { icon: Braces, color: 'text-yellow-600' },
+ jsonc:{ icon: Braces, color: 'text-yellow-500' },
+ json5:{ icon: Braces, color: 'text-yellow-500' },
+ yaml: { icon: Settings, color: 'text-purple-400' },
+ yml: { icon: Settings, color: 'text-purple-400' },
+ xml: { icon: FileCode, color: 'text-orange-500' },
+ csv: { icon: FileSpreadsheet, color: 'text-green-600' },
+ tsv: { icon: FileSpreadsheet, color: 'text-green-500' },
+ sql: { icon: Database, color: 'text-blue-500' },
+ graphql:{ icon: Workflow, color: 'text-pink-500' },
+ gql: { icon: Workflow, color: 'text-pink-500' },
+ proto:{ icon: Box, color: 'text-green-500' },
+ env: { icon: Shield, color: 'text-yellow-600' },
+
+ // ── Documents ──
+ md: { icon: BookOpen, color: 'text-blue-500' },
+ mdx: { icon: BookOpen, color: 'text-blue-400' },
+ txt: { icon: FileText, color: 'text-gray-500' },
+ doc: { icon: FileText, color: 'text-blue-600' },
+ docx: { icon: FileText, color: 'text-blue-600' },
+ pdf: { icon: FileCheck, color: 'text-red-600' },
+ rtf: { icon: FileText, color: 'text-gray-500' },
+ tex: { icon: Scroll, color: 'text-teal-600' },
+ rst: { icon: FileText, color: 'text-gray-400' },
+
+ // ── Shell / Scripts ──
+ sh: { icon: Terminal, color: 'text-green-500' },
+ bash: { icon: Terminal, color: 'text-green-500' },
+ zsh: { icon: Terminal, color: 'text-green-400' },
+ fish: { icon: Terminal, color: 'text-green-400' },
+ ps1: { icon: Terminal, color: 'text-blue-400' },
+ bat: { icon: Terminal, color: 'text-gray-500' },
+ cmd: { icon: Terminal, color: 'text-gray-500' },
+
+ // ── Images ──
+ png: { icon: Image, color: 'text-purple-500' },
+ jpg: { icon: Image, color: 'text-purple-500' },
+ jpeg: { icon: Image, color: 'text-purple-500' },
+ gif: { icon: Image, color: 'text-purple-400' },
+ webp: { icon: Image, color: 'text-purple-400' },
+ ico: { icon: Image, color: 'text-purple-400' },
+ bmp: { icon: Image, color: 'text-purple-400' },
+ tiff: { icon: Image, color: 'text-purple-400' },
+ svg: { icon: Palette, color: 'text-amber-500' },
+
+ // ── Audio ──
+ mp3: { icon: Music2, color: 'text-pink-500' },
+ wav: { icon: Music2, color: 'text-pink-500' },
+ ogg: { icon: Music2, color: 'text-pink-400' },
+ flac: { icon: Music2, color: 'text-pink-400' },
+ aac: { icon: Music2, color: 'text-pink-400' },
+ m4a: { icon: Music2, color: 'text-pink-400' },
+
+ // ── Video ──
+ mp4: { icon: Video, color: 'text-rose-500' },
+ mov: { icon: Video, color: 'text-rose-500' },
+ avi: { icon: Video, color: 'text-rose-500' },
+ webm: { icon: Video, color: 'text-rose-400' },
+ mkv: { icon: Video, color: 'text-rose-400' },
+
+ // ── Fonts ──
+ ttf: { icon: FileType, color: 'text-red-500' },
+ otf: { icon: FileType, color: 'text-red-500' },
+ woff: { icon: FileType, color: 'text-red-400' },
+ woff2:{ icon: FileType, color: 'text-red-400' },
+ eot: { icon: FileType, color: 'text-red-400' },
+
+ // ── Archives ──
+ zip: { icon: Archive, color: 'text-amber-600' },
+ tar: { icon: Archive, color: 'text-amber-600' },
+ gz: { icon: Archive, color: 'text-amber-600' },
+ bz2: { icon: Archive, color: 'text-amber-600' },
+ rar: { icon: Archive, color: 'text-amber-500' },
+ '7z': { icon: Archive, color: 'text-amber-500' },
+
+ // ── Lock files ──
+ lock: { icon: Lock, color: 'text-gray-500' },
+
+ // ── Binary / Executable ──
+ exe: { icon: Binary, color: 'text-gray-500' },
+ bin: { icon: Binary, color: 'text-gray-500' },
+ dll: { icon: Binary, color: 'text-gray-400' },
+ so: { icon: Binary, color: 'text-gray-400' },
+ dylib:{ icon: Binary, color: 'text-gray-400' },
+ wasm: { icon: Binary, color: 'text-purple-500' },
+
+ // ── Misc config ──
+ ini: { icon: Settings, color: 'text-gray-500' },
+ cfg: { icon: Settings, color: 'text-gray-500' },
+ conf: { icon: Settings, color: 'text-gray-500' },
+ log: { icon: Scroll, color: 'text-gray-400' },
+ map: { icon: File, color: 'text-gray-400' },
+};
+
+// Special full-filename matches (highest priority)
+const FILENAME_ICON_MAP = {
+ 'Dockerfile': { icon: Box, color: 'text-blue-500' },
+ 'docker-compose.yml': { icon: Box, color: 'text-blue-500' },
+ 'docker-compose.yaml': { icon: Box, color: 'text-blue-500' },
+ '.dockerignore': { icon: Box, color: 'text-gray-500' },
+ '.gitignore': { icon: Settings, color: 'text-gray-500' },
+ '.gitmodules': { icon: Settings, color: 'text-gray-500' },
+ '.gitattributes': { icon: Settings, color: 'text-gray-500' },
+ '.editorconfig': { icon: Settings, color: 'text-gray-500' },
+ '.prettierrc': { icon: Settings, color: 'text-pink-400' },
+ '.prettierignore': { icon: Settings, color: 'text-gray-500' },
+ '.eslintrc': { icon: Settings, color: 'text-violet-500' },
+ '.eslintrc.js': { icon: Settings, color: 'text-violet-500' },
+ '.eslintrc.json': { icon: Settings, color: 'text-violet-500' },
+ '.eslintrc.cjs': { icon: Settings, color: 'text-violet-500' },
+ 'eslint.config.js': { icon: Settings, color: 'text-violet-500' },
+ 'eslint.config.mjs':{ icon: Settings, color: 'text-violet-500' },
+ '.env': { icon: Shield, color: 'text-yellow-600' },
+ '.env.local': { icon: Shield, color: 'text-yellow-600' },
+ '.env.development': { icon: Shield, color: 'text-yellow-500' },
+ '.env.production': { icon: Shield, color: 'text-yellow-600' },
+ '.env.example': { icon: Shield, color: 'text-yellow-400' },
+ 'package.json': { icon: Braces, color: 'text-green-500' },
+ 'package-lock.json':{ icon: Lock, color: 'text-gray-500' },
+ 'yarn.lock': { icon: Lock, color: 'text-blue-400' },
+ 'pnpm-lock.yaml': { icon: Lock, color: 'text-orange-400' },
+ 'bun.lockb': { icon: Lock, color: 'text-gray-400' },
+ 'Cargo.toml': { icon: Cog, color: 'text-orange-600' },
+ 'Cargo.lock': { icon: Lock, color: 'text-orange-400' },
+ 'Gemfile': { icon: Gem, color: 'text-red-500' },
+ 'Gemfile.lock': { icon: Lock, color: 'text-red-400' },
+ 'Makefile': { icon: Terminal, color: 'text-gray-500' },
+ 'CMakeLists.txt': { icon: Cog, color: 'text-blue-500' },
+ 'tsconfig.json': { icon: Braces, color: 'text-blue-500' },
+ 'jsconfig.json': { icon: Braces, color: 'text-yellow-500' },
+ 'vite.config.ts': { icon: Flame, color: 'text-purple-500' },
+ 'vite.config.js': { icon: Flame, color: 'text-purple-500' },
+ 'webpack.config.js':{ icon: Cog, color: 'text-blue-500' },
+ 'tailwind.config.js':{ icon: Hash, color: 'text-cyan-500' },
+ 'tailwind.config.ts':{ icon: Hash, color: 'text-cyan-500' },
+ 'postcss.config.js':{ icon: Cog, color: 'text-red-400' },
+ 'babel.config.js': { icon: Settings, color: 'text-yellow-500' },
+ '.babelrc': { icon: Settings, color: 'text-yellow-500' },
+ 'README.md': { icon: BookOpen, color: 'text-blue-500' },
+ 'LICENSE': { icon: FileCheck, color: 'text-gray-500' },
+ 'LICENSE.md': { icon: FileCheck, color: 'text-gray-500' },
+ 'CHANGELOG.md': { icon: Scroll, color: 'text-blue-400' },
+ 'requirements.txt': { icon: FileText, color: 'text-emerald-400' },
+ 'go.mod': { icon: Hexagon, color: 'text-cyan-500' },
+ 'go.sum': { icon: Lock, color: 'text-cyan-400' },
+};
+
+function getFileIconData(filename) {
+ // 1. Exact filename match
+ if (FILENAME_ICON_MAP[filename]) {
+ return FILENAME_ICON_MAP[filename];
+ }
+
+ // 2. Check for .env prefix pattern
+ if (filename.startsWith('.env')) {
+ return { icon: Shield, color: 'text-yellow-600' };
+ }
+
+ // 3. Extension-based lookup
+ const ext = filename.split('.').pop()?.toLowerCase();
+ if (ext && FILE_ICON_MAP[ext]) {
+ return FILE_ICON_MAP[ext];
+ }
+
+ // 4. Fallback
+ return { icon: File, color: 'text-muted-foreground' };
+}
+
+
+// ─── Component ───────────────────────────────────────────────────────
+
function FileTree({ selectedProject }) {
const { t } = useTranslation();
const [files, setFiles] = useState([]);
@@ -16,7 +267,7 @@ function FileTree({ selectedProject }) {
const [expandedDirs, setExpandedDirs] = useState(new Set());
const [selectedFile, setSelectedFile] = useState(null);
const [selectedImage, setSelectedImage] = useState(null);
- const [viewMode, setViewMode] = useState('detailed'); // 'simple', 'detailed', 'compact'
+ const [viewMode, setViewMode] = useState('detailed');
const [searchQuery, setSearchQuery] = useState('');
const [filteredFiles, setFilteredFiles] = useState([]);
@@ -26,7 +277,6 @@ function FileTree({ selectedProject }) {
}
}, [selectedProject]);
- // Load view mode preference from localStorage
useEffect(() => {
const savedViewMode = localStorage.getItem('file-tree-view-mode');
if (savedViewMode && ['simple', 'detailed', 'compact'].includes(savedViewMode)) {
@@ -34,7 +284,6 @@ function FileTree({ selectedProject }) {
}
}, []);
- // Filter files based on search query
useEffect(() => {
if (!searchQuery.trim()) {
setFilteredFiles(files);
@@ -42,7 +291,6 @@ function FileTree({ selectedProject }) {
const filtered = filterFiles(files, searchQuery.toLowerCase());
setFilteredFiles(filtered);
- // Auto-expand directories that contain matches
const expandMatches = (items) => {
items.forEach(item => {
if (item.type === 'directory' && item.children && item.children.length > 0) {
@@ -55,7 +303,6 @@ function FileTree({ selectedProject }) {
}
}, [files, searchQuery]);
- // Recursively filter files and directories based on search query
const filterFiles = (items, query) => {
return items.reduce((filtered, item) => {
const matchesName = item.name.toLowerCase().includes(query);
@@ -65,9 +312,6 @@ function FileTree({ selectedProject }) {
filteredChildren = filterFiles(item.children, query);
}
- // Include item if:
- // 1. It matches the search query, or
- // 2. It's a directory with matching children
if (matchesName || filteredChildren.length > 0) {
filtered.push({
...item,
@@ -83,14 +327,14 @@ function FileTree({ selectedProject }) {
setLoading(true);
try {
const response = await api.getFiles(selectedProject.name);
-
+
if (!response.ok) {
const errorText = await response.text();
console.error('❌ File fetch failed:', response.status, errorText);
setFiles([]);
return;
}
-
+
const data = await response.json();
setFiles(data);
} catch (error) {
@@ -111,13 +355,11 @@ function FileTree({ selectedProject }) {
setExpandedDirs(newExpanded);
};
- // Change view mode and save preference
const changeViewMode = (mode) => {
setViewMode(mode);
localStorage.setItem('file-tree-view-mode', mode);
};
- // Format file size
const formatFileSize = (bytes) => {
if (!bytes || bytes === 0) return '0 B';
const k = 1024;
@@ -126,7 +368,6 @@ function FileTree({ selectedProject }) {
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
};
- // Format date as relative time
const formatRelativeTime = (date) => {
if (!date) return '-';
const now = new Date();
@@ -140,65 +381,6 @@ function FileTree({ selectedProject }) {
return past.toLocaleDateString();
};
- const renderFileTree = (items, level = 0) => {
- return items.map((item) => (
-
-
-
- {item.type === 'directory' &&
- expandedDirs.has(item.path) &&
- item.children &&
- item.children.length > 0 && (
-
- {renderFileTree(item.children, level + 1)}
-
- )}
-
- ));
- };
-
const isImageFile = (filename) => {
const ext = filename.split('.').pop()?.toLowerCase();
const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'ico', 'bmp'];
@@ -206,208 +388,289 @@ function FileTree({ selectedProject }) {
};
const getFileIcon = (filename) => {
- const ext = filename.split('.').pop()?.toLowerCase();
-
- const codeExtensions = ['js', 'jsx', 'ts', 'tsx', 'py', 'java', 'cpp', 'c', 'php', 'rb', 'go', 'rs'];
- const docExtensions = ['md', 'txt', 'doc', 'pdf'];
- const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'ico', 'bmp'];
-
- if (codeExtensions.includes(ext)) {
- return
;
- } else if (docExtensions.includes(ext)) {
- return
;
- } else if (imageExtensions.includes(ext)) {
- return
;
+ const { icon: Icon, color } = getFileIconData(filename);
+ return
;
+ };
+
+ // ── Click handler shared across all view modes ──
+ const handleItemClick = (item) => {
+ if (item.type === 'directory') {
+ toggleDirectory(item.path);
+ } else if (isImageFile(item.name)) {
+ setSelectedImage({
+ name: item.name,
+ path: item.path,
+ projectPath: selectedProject.path,
+ projectName: selectedProject.name
+ });
} else {
- return
;
+ setSelectedFile({
+ name: item.name,
+ path: item.path,
+ projectPath: selectedProject.path,
+ projectName: selectedProject.name
+ });
}
};
- // Render detailed view with table-like layout
+ // ── Indent guide + folder/file icon rendering ──
+ const renderIndentGuides = (level) => {
+ if (level === 0) return null;
+ return (
+
+ {Array.from({ length: level }).map((_, i) => (
+
+ ))}
+
+ );
+ };
+
+ const renderItemIcons = (item) => {
+ const isDir = item.type === 'directory';
+ const isOpen = expandedDirs.has(item.path);
+
+ if (isDir) {
+ return (
+
+
+ {isOpen ? (
+
+ ) : (
+
+ )}
+
+ );
+ }
+
+ return (
+
+ {getFileIcon(item.name)}
+
+ );
+ };
+
+ // ─── Simple (Tree) View ────────────────────────────────────────────
+ const renderFileTree = (items, level = 0) => {
+ return items.map((item) => {
+ const isDir = item.type === 'directory';
+ const isOpen = isDir && expandedDirs.has(item.path);
+
+ return (
+
+
handleItemClick(item)}
+ >
+ {renderItemIcons(item)}
+
+ {item.name}
+
+
+
+ {isDir && isOpen && item.children && item.children.length > 0 && (
+
+
+ {renderFileTree(item.children, level + 1)}
+
+ )}
+
+ );
+ });
+ };
+
+ // ─── Detailed View ────────────────────────────────────────────────
const renderDetailedView = (items, level = 0) => {
- return items.map((item) => (
-
-
{
- if (item.type === 'directory') {
- toggleDirectory(item.path);
- } else if (isImageFile(item.name)) {
- setSelectedImage({
- name: item.name,
- path: item.path,
- projectPath: selectedProject.path,
- projectName: selectedProject.name
- });
- } else {
- setSelectedFile({
- name: item.name,
- path: item.path,
- projectPath: selectedProject.path,
- projectName: selectedProject.name
- });
- }
- }}
- >
-
- {item.type === 'directory' ? (
- expandedDirs.has(item.path) ? (
-
- ) : (
-
- )
- ) : (
- getFileIcon(item.name)
+ return items.map((item) => {
+ const isDir = item.type === 'directory';
+ const isOpen = isDir && expandedDirs.has(item.path);
+
+ return (
+
+
- {item.name}
-
-
-
- {item.type === 'file' ? formatFileSize(item.size) : '-'}
-
-
- {formatRelativeTime(item.modified)}
-
-
- {item.permissionsRwx || '-'}
+ style={{ paddingLeft: `${level * 16 + 4}px` }}
+ onClick={() => handleItemClick(item)}
+ >
+
+ {renderItemIcons(item)}
+
+ {item.name}
+
+
+
+ {item.type === 'file' ? formatFileSize(item.size) : ''}
+
+
+ {formatRelativeTime(item.modified)}
+
+
+ {item.permissionsRwx || ''}
+
+
+ {isDir && isOpen && item.children && (
+
+
+ {renderDetailedView(item.children, level + 1)}
+
+ )}
-
- {item.type === 'directory' &&
- expandedDirs.has(item.path) &&
- item.children &&
- renderDetailedView(item.children, level + 1)}
-
- ));
+ );
+ });
};
- // Render compact view with inline details
+ // ─── Compact View ──────────────────────────────────────────────────
const renderCompactView = (items, level = 0) => {
- return items.map((item) => (
-
-
{
+ const isDir = item.type === 'directory';
+ const isOpen = isDir && expandedDirs.has(item.path);
+
+ return (
+
+
handleItemClick(item)}
+ >
+
+ {renderItemIcons(item)}
+
+ {item.name}
+
+
+
+ {item.type === 'file' && (
+ <>
+ {formatFileSize(item.size)}
+ {item.permissionsRwx}
+ >
+ )}
+
+
+
+ {isDir && isOpen && item.children && (
+
+
+ {renderCompactView(item.children, level + 1)}
+
)}
- style={{ paddingLeft: `${level * 16 + 12}px` }}
- onClick={() => {
- if (item.type === 'directory') {
- toggleDirectory(item.path);
- } else if (isImageFile(item.name)) {
- setSelectedImage({
- name: item.name,
- path: item.path,
- projectPath: selectedProject.path,
- projectName: selectedProject.name
- });
- } else {
- setSelectedFile({
- name: item.name,
- path: item.path,
- projectPath: selectedProject.path,
- projectName: selectedProject.name
- });
- }
- }}
- >
-
- {item.type === 'directory' ? (
- expandedDirs.has(item.path) ? (
-
- ) : (
-
- )
- ) : (
- getFileIcon(item.name)
- )}
-
- {item.name}
-
-
-
- {item.type === 'file' && (
- <>
- {formatFileSize(item.size)}
- {item.permissionsRwx}
- >
- )}
-
-
- {item.type === 'directory' &&
- expandedDirs.has(item.path) &&
- item.children &&
- renderCompactView(item.children, level + 1)}
-
- ));
+ );
+ });
};
+ // ─── Loading state ─────────────────────────────────────────────────
if (loading) {
return (
-
+
{t('fileTree.loading')}
);
}
+ // ─── Main render ───────────────────────────────────────────────────
return (
- {/* Header with Search and View Mode Toggle */}
-
+ {/* Header */}
+
-
{t('fileTree.files')}
-
+
+ {t('fileTree.files')}
+
+
{/* Search Bar */}
-
+
setSearchQuery(e.target.value)}
- className="pl-8 pr-8 h-8 text-sm"
+ className="pl-7 pr-7 h-7 text-xs"
/>
{searchQuery && (