1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js"; 2import { a as api } from "./index-w5lXls15.js"; 3import { cl as HardDrive, cf as Plus, cd as Save, bN as History, b7 as Check, c2 as Copy, b2 as Upload, bM as Clock, c4 as RotateCcw, bi as Sparkles, aW as X, cC as ChevronDown, bF as ChevronRight, b4 as FolderOpen, du as Folder, fk as FileCode, fX as FileType, fY as FileBraces, b0 as FileText, d9 as Image } from "./vendor-D0P4XgNj.js"; 4import "./vendor-i18n-BC7ZMXWQ.js"; 5const buildFileTree = (files) => { 6 const root = []; 7 files.forEach((file) => { 8 const parts = file.path.split("/").filter((p) => p); 9 let currentLevel = root; 10 parts.forEach((part, index) => { 11 const isFile = index === parts.length - 1; 12 const existingNode = currentLevel.find((n) => n.name === part); 13 if (existingNode) { 14 if (!isFile && existingNode.type === "folder") { 15 currentLevel = existingNode.children; 16 } 17 } else { 18 const newNode = { 19 name: part, 20 path: "/" + parts.slice(0, index + 1).join("/"),
21 type: isFile ? "file" : "folder", 22 children: [], 23 file: isFile ? file : void 0 24 }; 25 currentLevel.push(newNode); 26 if (!isFile) { 27 currentLevel = newNode.children; 28 } 29 } 30 }); 31 }); 32 const sortNodes = (nodes) => { 33 nodes.sort((a, b) => { 34 if (a.type === b.type) return a.name.localeCompare(b.name); 35 return a.type === "folder" ? -1 : 1; 36 }); 37 nodes.forEach((n) => { 38 if (n.children.length > 0) sortNodes(n.children); 39 }); 40 }; 41 sortNodes(root); 42 return root; 43}; 44const getFileIcon = (filename, type) => { 45 if (filename.endsWith(".tsx") || filename.endsWith(".ts")) return /* @__PURE__ */ jsxRuntimeExports.jsx(FileCode, { size: 14, className: "text-blue-500" }); 46 if (filename.endsWith(".css")) return /* @__PURE__ */ jsxRuntimeExports.jsx(FileType, { size: 14, className: "text-sky-400" }); 47 if (filename.endsWith(".json")) return /* @__PURE__ */ jsxRuntimeExports.jsx(FileBraces, { size: 14, className: "text-yellow-500" }); 48 if (filename.endsWith(".html")) return /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { size: 14, className: "text-orange-500" }); 49 if (filename.endsWith(".py")) return /* @__PURE__ */ jsxRuntimeExports.jsx(FileCode, { size: 14, className: "text-green-500" }); 50 if (type === "image") return /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { size: 14, className: "text-purple-500" }); 51 return /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { size: 14, className: "text-zinc-500" }); 52}; 53const FileExplorer = ({ refreshTrigger, filterType = "all", initialPath }) => { 54 const [files, setFiles] = reactExports.useState([]); 55 const [selectedFile, setSelectedFile] = reactExports.useState(null); 56 const [isMockMode, setIsMockMode] = reactExports.useState(false); 57 const [editContent, setEditContent] = reactExports.useState(""); 58 const [isEditing, setIsEditing] = reactExports.useState(false); 59 const [showHistory, setShowHistory] = reactExports.useState(false); 60 const [showUploadModal, setShowUploadModal] = reactExports.useState(false); 61 const [showCreateModal, setShowCreateModal] = reactExports.useState(false); 62 const [newCodeInput, setNewCodeInput] = reactExports.useState(""); 63 const [newFileName, setNewFileName] = reactExports.useState(""); 64 const [newFileFolder, setNewFileFolder] = reactExports.useState("/web/src/pages/AdminModules/"); 65 const [copied, setCopied] = reactExports.useState(false); 66 const [expandedFolders, setExpandedFolders] = reactExports.useState(/* @__PURE__ */ new Set(["/", "/web", "/web/src", "/web/src/pages", "/web/src/pages/AdminModules"])); 67 const [localRefreshTrigger, setLocalRefreshTrigger] = reactExports.useState(0); 68 const refresh = () => setLocalRefreshTrigger((prev) => prev + 1); 69 reactExports.useEffect(() => { 70 const fetchFiles = async () => { 71 const data = await api.getFileSystem(); 72 setFiles(data); 73 }; 74 fetchFiles(); 75 }, [refreshTrigger, localRefreshTrigger]); 76 reactExports.useEffect(() => { 77 if (initialPath) { 78 const f = files.find((f2) => f2.path === initialPath); 79 if (f) { 80 setSelectedFile(f); 81 setEditContent(f.content); 82 const parts = initialPath.split("/").filter((p) => p); 83 const pathsToExpand = new Set(expandedFolders); 84 let currentPath = "";
85 parts.slice(0, -1).forEach((part) => { 86 currentPath += "/" + part; 87 pathsToExpand.add(currentPath); 88 }); 89 setExpandedFolders(pathsToExpand); 90 } 91 } 92 }, [initialPath, files]); 93 const filteredFiles = reactExports.useMemo(() => files.filter((f) => { 94 if (filterType === "all") return true; 95 if (filterType === "module") return f.isModule; 96 if (filterType === "image") return f.type === "image"; 97 return f.type === filterType; 98 }), [files, filterType]); 99 const fileTree = reactExports.useMemo(() => buildFileTree(filteredFiles), [filteredFiles]); 100 const handleSelectFile = (file) => { 101 setSelectedFile(file); 102 setEditContent(file.content); 103 setIsEditing(false); 104 setShowHistory(false); 105 }; 106 const toggleFolder = (path) => { 107 setExpandedFolders((prev) => { 108 const next = new Set(prev); 109 if (next.has(path)) next.delete(path); 110 else next.add(path); 111 return next; 112 }); 113 }; 114 const handleCopyForGemini = () => { 115 if (selectedFile) { 116 const prompt = `System Prompt: You are an expert developer. Update the following module code based on the user's request. 117Module: ${selectedFile.path} 118Description: ${selectedFile.description || "No description"} 119 120Current Code: 121${selectedFile.content}`; 122 navigator.clipboard.writeText(prompt); 123 setCopied(true); 124 setTimeout(() => setCopied(false), 2e3); 125 } 126 }; 127 const handleSave = async () => { 128 if (!selectedFile) return; 129 try { 130 await api.commitDevAgentFile({ [selectedFile.path]: editContent }, "Manual Edit"); 131 refresh(); 132 setIsEditing(false); 133 } catch (e) { 134 console.error("Save failed", e); 135 alert("Failed to save file"); 136 } 137 }; 138 const handleApplyUpload = async () => { 139 if (!selectedFile || !newCodeInput) return; 140 try { 141 await api.commitDevAgentFile({ [selectedFile.path]: newCodeInput }, "AI Update"); 142 refresh(); 143 setShowUploadModal(false); 144 setNewCodeInput(""); 145 } catch (e) { 146 console.error("Upload apply failed", e); 147 alert("Failed to apply update"); 148 } 149 }; 150 const handleCreateFile = async () => { 151 if (!newFileName) return; 152 const fullPath = `${newFileFolder.replace(/\/$/, "")}/${newFileName.replace(/^\//, "")}`; 153 const content = `import React from 'react'; 154 155export default function ${newFileName.split(".")[0]}() { 156 return <div>New Module</div>; 157}`; 158 try { 159 await api.commitDevAgentFile({ [fullPath]: content }, "Create new file"); 160 refresh(); 161 setShowCreateModal(false); 162 setNewFileName(""); 163 } catch (e) { 164 console.error("Create file failed", e); 165 alert("Failed to create file"); 166 } 167 }; 168 const handleRestore = async (version) => { 169 if (!confirm(`Restore version from ${version.timestamp}?`)) return; 170 if (!selectedFile) return; 171 try { 172 await api.commitDevAgentFile({ [selectedFile.path]: version.content }, `Restored to ${version.timestamp}`); 173 refresh(); 174 setShowHistory(false); 175 } catch (e) { 176 console.error("Restore failed", e); 177 alert("Failed to restore version"); 178 } 179 }; 180 const renderTreeNodes = (nodes, depth = 0) => { 181 return nodes.map((node) => { 182 var _a; 183 const isExpanded = expandedFolders.has(node.path); 184 const isSelected = (selectedFile == null ? void 0 : selectedFile.path) === node.path; 185 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
186 /* @__PURE__ */ jsxRuntimeExports.jsxs( 187 "div", 188 { 189 className: `flex items-center gap-1.5 px-2 py-1 cursor-pointer select-none text-xs transition-colors whitespace-nowrap ${isSelected ? "bg-indigo-100 dark:bg-indigo-900/40 text-indigo-700 dark:text-indigo-300" : "text-zinc-600 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800"}`, 190 style: { paddingLeft: `${depth * 16 + 8}px` }, 191 onClick: () => node.type === "folder" ? toggleFolder(node.path) : handleSelectFile(node.file), 192 children: [ 193 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "opacity-50", children: node.type === "folder" ? isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { size: 12 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 12 }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-3" }) }), 194 node.type === "folder" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-500 dark:text-zinc-400", children: isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { size: 14, className: "fill-zinc-200 dark:fill-zinc-700 text-zinc-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { size: 14, className: "fill-zinc-200 dark:fill-zinc-700 text-zinc-400" }) }) : getFileIcon(node.name, ((_a = node.file) == null ? void 0 : _a.type) || "file"),
195 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `truncate ${node.type === "folder" ? "font-bold" : ""}`, children: node.name }) 196 ] 197 } 198 ), 199 node.type === "folder" && isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: renderTreeNodes(node.children, depth + 1) }) 200 ] }, node.path); 201 }); 202 }; 203 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-zinc-900 rounded-xl border border-zinc-200 dark:border-zinc-800 flex flex-col h-full overflow-hidden shadow-sm", children: [ 204 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-14 border-b border-zinc-200 dark:border-zinc-800 flex items-center justify-between px-4 bg-zinc-50 dark:bg-zinc-950 shrink-0", children: [ 205 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [ 206 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-bold text-sm text-zinc-500 uppercase tracking-wider flex items-center gap-2", children: [
207 /* @__PURE__ */ jsxRuntimeExports.jsx(HardDrive, { size: 16 }), 208 " File System" 209 ] }), 210 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShowCreateModal(true), className: "p-1 hover:bg-zinc-200 dark:hover:bg-zinc-800 rounded text-indigo-600 dark:text-indigo-400", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { size: 16 }) }) 211 ] }), 212 selectedFile && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 213 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-mono text-zinc-500 mr-2 hidden md:inline", children: selectedFile.path }), 214 isEditing ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 215 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setIsEditing(false), className: "px-3 py-1.5 rounded-lg text-xs font-bold text-zinc-600 hover:bg-zinc-200 dark:text-zinc-400 dark:hover:bg-zinc-800", children: "Cancel" }), 216 /* @__P
216URE__ */ jsxRuntimeExports.jsxs("button", { onClick: handleSave, className: "px-3 py-1.5 rounded-lg text-xs font-bold bg-indigo-600 text-white hover:bg-indigo-700 flex items-center gap-1", children: [ 217 /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { size: 12 }), 218 " Save" 219 ] }) 220 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setIsEditing(true), className: "px-3 py-1.5 rounded-lg text-xs font-bold bg-zinc-200 dark:bg-zinc-800 hover:bg-zinc-300 dark:hover:bg-zinc-700 text-zinc-700 dark:text-zinc-300", children: "Edit" }) 221 ] }) 222 ] }), 223 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex min-h-0 overflow-hidden", children: [ 224 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-64 border-r border-zinc-200 dark:border-zinc-800 bg-zinc-50/50 dark:bg-zinc-950/30 flex flex-col shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-y-auto flex-1 custom-scrollbar py-2", children: renderTreeNodes(fileTree) }) }),
225 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex flex-col bg-white dark:bg-zinc-900 relative min-w-0", children: selectedFile ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 226 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-10 border-b border-zinc-200 dark:border-zinc-800 flex items-center justify-between px-4 bg-zinc-50 dark:bg-zinc-950", children: [ 227 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { onClick: () => setShowHistory(!showHistory), className: `flex items-center gap-1.5 px-3 py-1 rounded text-xs font-bold transition-colors ${showHistory ? "bg-zinc-200 dark:bg-zinc-800 text-black dark:text-white" : "text-zinc-500 hover:text-black dark:hover:text-white"}`, children: [ 228 /* @__PURE__ */ jsxRuntimeExports.jsx(History, { size: 14 }), 229 " History" 230 ] }) }), 231 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
232 /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { onClick: handleCopyForGemini, className: "flex items-center gap-1.5 px-3 py-1 rounded text-xs font-bold text-indigo-600 dark:text-indigo-400 hover:bg-indigo-50 dark:hover:bg-indigo-900/20 transition-colors", children: [ 233 copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 14 }), 234 " ", 235 copied ? "Copied" : "Copy Prompt" 236 ] }), 237 /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { onClick: () => setShowUploadModal(true), className: "flex items-center gap-1.5 px-3 py-1 rounded text-xs font-bold bg-indigo-600 text-white hover:bg-indigo-700 transition-colors", children: [ 238 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { size: 14 }), 239 " Update" 240 ] }) 241 ] }) 242 ] }), 243 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden relative flex", children: showHistory ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute inset-0 z-10 bg-zinc-50 dark:bg-zinc-900 p-6 overflow-y-auto", children: [
244 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "font-bold text-lg mb-4 flex items-center gap-2 text-zinc-900 dark:text-white", children: [ 245 /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { size: 20 }), 246 " Version History" 247 ] }), 248 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 max-w-3xl", children: [ 249 selectedFile.history.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-500 italic", children: "No edit history found." }), 250 selectedFile.history.map((ver, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-black border border-zinc-200 dark:border-zinc-800 rounded-lg p-4 flex justify-between items-start hover:shadow-md transition-shadow", children: [ 251 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 252 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [ 253 /* @__P
253URE__ */ jsxRuntimeExports.jsxs("span", { className: "font-bold text-zinc-900 dark:text-white", children: [ 254 "Version ", 255 ver.version 256 ] }), 257 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs bg-zinc-100 dark:bg-zinc-800 px-2 py-0.5 rounded text-zinc-500", children: ver.timestamp }) 258 ] }), 259 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-zinc-600 dark:text-zinc-400", children: [ 260 "By ", 261 ver.author 262 ] }), 263 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-zinc-400 mt-2 font-mono", children: ver.changeLog }) 264 ] }), 265 /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { onClick: () => handleRestore(ver), className: "px-3 py-1.5 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 rounded text-xs font-bold text-zinc-700 dark:text-zinc-300 flex items-center gap-1", children: [
266 /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 12 }), 267 " Restore" 268 ] }) 269 ] }, i)) 270 ] }) 271 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("textarea", { value: isEditing ? editContent : selectedFile.content, onChange: (e) => setEditContent(e.target.value), readOnly: !isEditing, className: `w-full h-full p-4 font-mono text-xs outline-none resize-none ${isEditing ? "bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white" : "bg-zinc-50 dark:bg-black text-zinc-600 dark:text-zinc-400"}`, spellCheck: false }) }) 272 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col items-center justify-center text-zinc-400 gap-4", children: [ 273 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 h-16 bg-zinc-100 dark:bg-zinc-800 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 32, className: "text-zinc-300 dark:text-zinc-700" }) }), 274 /* @__P
274URE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "Select a file from the explorer to view or edit." }) 275 ] }) }) 276 ] }), 277 showUploadModal && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[100] flex items-center justify-center p-4", children: [ 278 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: () => setShowUploadModal(false) }), 279 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative w-full max-w-3xl bg-white dark:bg-zinc-900 rounded-xl shadow-2xl flex flex-col h-[600px] animate-in zoom-in-95 border border-zinc-200 dark:border-zinc-800", children: [ 280 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-b border-zinc-200 dark:border-zinc-800 flex justify-between items-center bg-zinc-50 dark:bg-zinc-950", children: [ 281 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "font-bold text-lg text-zinc-900 dark:text-white", children: [ 282 "Update Code for ", 283 selectedFile == null ? void 0 : selectedFile.path 284 ] }),
285 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShowUploadModal(false), children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "text-zinc-500" }) }) 286 ] }), 287 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 p-4 flex flex-col", children: [ 288 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-indigo-50 dark:bg-indigo-900/20 p-3 rounded-lg mb-4 text-xs text-indigo-800 dark:text-indigo-300", children: "Paste the updated code generated by Gemini below. This will create a new version in the history." }), 289 /* @__PURE__ */ jsxRuntimeExports.jsx("textarea", { value: newCodeInput, onChange: (e) => setNewCodeInput(e.target.value), className: "flex-1 bg-zinc-50 dark:bg-black border border-zinc-300 dark:border-zinc-700 rounded-lg p-4 font-mono text-xs outline-none focus:border-indigo-500 text-zinc-900 dark:text-white", placeholder: "// Paste updated code here..." }) 290 ] }), 291 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-t border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-950 flex justify-end gap-3", children: [
292 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShowUploadModal(false), className: "px-4 py-2 rounded-lg font-bold text-zinc-600 hover:bg-zinc-200 dark:text-zinc-400 dark:hover:bg-zinc-800", children: "Cancel" }), 293 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: handleApplyUpload, disabled: !newCodeInput, className: "px-4 py-2 rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white font-bold disabled:opacity-50", children: "Apply Changes" }) 294 ] }) 295 ] }) 296 ] }), 297 showCreateModal && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[100] flex items-center justify-center p-4", children: [ 298 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: () => setShowCreateModal(false) }), 299 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative w-full max-w-md bg-white dark:bg-zinc-900 rounded-xl shadow-2xl animate-in zoom-in-95 border border-zinc-200 dark:border-zinc-800 p-6", children: [
300 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-bold text-lg text-zinc-900 dark:text-white mb-4", children: "Create New Module" }), 301 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 302 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 303 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-bold text-zinc-500 uppercase", children: "Path" }), 304 /* @__PURE__ */ jsxRuntimeExports.jsx("input", { type: "text", value: newFileFolder, onChange: (e) => setNewFileFolder(e.target.value), className: "w-full mt-1 p-2 rounded border dark:bg-zinc-950 dark:border-zinc-800 text-zinc-900 dark:text-white text-sm font-mono" }) 305 ] }), 306 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 307 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs font-bold text-zinc-500 uppercase", children: "Filename" }), 308 /* @__PURE__ */ jsxRuntimeExports.jsx("input", { type: "text", value: newFileName, onChange: (e) => setNewFileName(e.target.value), placeholder: "MyNewModule.tsx", className: "w-full mt-1 p-2 rounded border dark:bg-zinc-950 dark:border-zinc-800 text-zinc-900 dark:text-white text-sm font-mono" }) 309 ] }),
310 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-end gap-2 pt-2", children: [ 311 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShowCreateModal(false), className: "px-4 py-2 rounded-lg text-zinc-600 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:bg-zinc-800 font-bold text-sm", children: "Cancel" }), 312 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: handleCreateFile, disabled: !newFileName, className: "px-4 py-2 rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white font-bold text-sm", children: "Create" }) 313 ] }) 314 ] }) 315 ] }) 316 ] }) 317 ] }); 318}; 319export { 320 FileExplorer as default 321};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.