chore: adjust list details ui (#128)

* chore: detail

* chore: list detail ui

* chore: adjust list details ui
This commit is contained in:
BiggerRain
2025-02-08 15:26:02 +08:00
committed by GitHub
parent cb4d9e7184
commit 17b3b97bec
6 changed files with 58 additions and 78 deletions

View File

@@ -37,7 +37,7 @@ const ChatSwitch: React.FC<ChatSwitchProps> = ({ isChatMode, onChange }) => {
role="switch"
aria-checked={isChatMode}
className={`relative flex items-center justify-between w-10 h-[18px] rounded-full cursor-pointer transition-colors duration-300 ${
isChatMode ? "bg-[#0072ff]" : "bg-[#950599]"
isChatMode ? "bg-[#0072ff]" : "bg-[var(--coco-primary-color)]"
}`}
onClick={handleToggle}
>

View File

@@ -1,6 +1,6 @@
import React from "react";
import {formatter} from "@/utils/index"
import { formatter } from "@/utils/index";
import TypeIcon from "@/components/Common/Icons/TypeIcon";
interface DocumentDetailProps {

View File

@@ -15,6 +15,8 @@ interface DocumentListProps {
input: string;
isChatMode: boolean;
selectedId?: string;
viewMode: "detail" | "list";
setViewMode: (mode: "detail" | "list") => void;
}
const PAGE_SIZE = 20;
@@ -23,6 +25,8 @@ export const DocumentList: React.FC<DocumentListProps> = ({
input,
getDocDetail,
isChatMode,
viewMode,
setViewMode,
}) => {
const sourceData = useSearchStore((state) => state.sourceData);
@@ -196,9 +200,17 @@ export const DocumentList: React.FC<DocumentListProps> = ({
}, [selectedItem]);
return (
<div className="w-[50%] border-r border-gray-200 dark:border-gray-700 flex flex-col h-full">
<div
className={`border-r border-gray-200 dark:border-gray-700 flex flex-col h-full ${
viewMode === "list" ? "w-[100%]" : "w-[50%]"
}`}
>
<div className="px-2 flex-shrink-0">
<SearchHeader total={total} />
<SearchHeader
total={total}
viewMode={viewMode}
setViewMode={setViewMode}
/>
</div>
<div
@@ -220,7 +232,7 @@ export const DocumentList: React.FC<DocumentListProps> = ({
}}
className={`w-full px-2 py-2.5 text-sm flex items-center gap-3 rounded-lg transition-colors cursor-pointer ${
isSelected
? "text-white bg-[#950599] hover:bg-[#950599]"
? "text-white bg-[var(--coco-primary-color)] hover:bg-[var(--coco-primary-color)]"
: "text-[#333] dark:text-[#d8d8d8]"
}`}
>

View File

@@ -219,7 +219,7 @@ function DropdownList({
}
}}
className={`w-full px-2 py-2.5 text-sm flex gap-7 items-center justify-between rounded-lg transition-colors cursor-pointer ${isSelected
? "text-white bg-[#950599] hover:bg-[#950599]"
? "text-white bg-[var(--coco-primary-color)] hover:bg-[var(--coco-primary-color)]"
: "text-[#333] dark:text-[#d8d8d8]"
}`}
>

View File

@@ -1,70 +1,17 @@
import React, { useState } from "react";
import { Menu, MenuButton, MenuItems, MenuItem } from "@headlessui/react";
import { ChevronDown } from "lucide-react";
interface FilterOption {
id: string;
label: string;
}
interface FilterDropdownProps {
label: string;
options: FilterOption[];
value?: string;
onChange: (value: string) => void;
}
const FilterDropdown: React.FC<FilterDropdownProps> = ({
label,
options,
value,
onChange,
}) => {
return (
<Menu as="div" className="relative">
<MenuButton className="inline-flex items-center px-2.5 py-1 text-xs bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-lg border border-gray-200 dark:border-gray-700 font-medium">
{label}
<ChevronDown className="w-3.5 h-3.5 ml-1 text-gray-500 dark:text-gray-400" />
</MenuButton>
<MenuItems className="absolute right-0 mt-1 w-44 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-10 focus:outline-none">
{options.map((option) => (
<MenuItem key={option.id}>
{({ active }) => (
<button
onClick={() => onChange(option.id)}
className={`w-full text-left px-3 py-1.5 text-xs ${
active ? "bg-gray-50 dark:bg-gray-700" : ""
} ${
value === option.id
? "text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/50"
: "text-gray-700 dark:text-gray-300"
}`}
>
{option.label}
</button>
)}
</MenuItem>
))}
</MenuItems>
</Menu>
);
};
const typeOptions: FilterOption[] = [
{ id: "all", label: "All" },
{ id: "doc", label: "Doc" },
{ id: "image", label: "Image" },
{ id: "code", label: "Code" },
];
import React from "react";
import { AlignLeft, Columns2 } from "lucide-react";
interface SearchHeaderProps {
total: number;
viewMode: "detail" | "list";
setViewMode: (mode: "detail" | "list") => void;
}
export const SearchHeader: React.FC<SearchHeaderProps> = ({ total }) => {
const [typeFilter, setTypeFilter] = useState("all");
export const SearchHeader: React.FC<SearchHeaderProps> = ({
total,
viewMode,
setViewMode,
}) => {
return (
<div className="flex items-center justify-between py-1">
<div className="text-xs text-gray-600 dark:text-gray-400">
@@ -75,12 +22,28 @@ export const SearchHeader: React.FC<SearchHeaderProps> = ({ total }) => {
results
</div>
<div className="flex gap-2">
<FilterDropdown
label="Type"
options={typeOptions}
value={typeFilter}
onChange={setTypeFilter}
/>
<div className="flex bg-gray-100 dark:bg-gray-800 rounded-lg p-0.5">
<button
onClick={() => setViewMode("list")}
className={`p-1 rounded ${
viewMode === "list"
? "bg-white dark:bg-gray-700 shadow-sm text-[var(--coco-primary-color)]"
: "text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300"
}`}
>
<AlignLeft className="w-4 h-4" />
</button>
<button
onClick={() => setViewMode("detail")}
className={`p-1 rounded ${
viewMode === "detail"
? "bg-white dark:bg-gray-700 shadow-sm text-[var(--coco-primary-color)]"
: "text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300"
}`}
>
<Columns2 className="w-4 h-4" />
</button>
</div>
</div>
</div>
);

View File

@@ -12,9 +12,10 @@ export function SearchResults({ input, isChatMode }: SearchResultsProps) {
const [selectedDocumentId, setSelectedDocumentId] = useState("1");
const [detailData, setDetailData] = useState<any>({});
const [viewMode, setViewMode] = useState<"detail" | "list">("detail");
function getDocDetail(detail: any) {
setDetailData(detail)
setDetailData(detail);
}
return (
@@ -27,12 +28,16 @@ export function SearchResults({ input, isChatMode }: SearchResultsProps) {
input={input}
getDocDetail={getDocDetail}
isChatMode={isChatMode}
viewMode={viewMode}
setViewMode={setViewMode}
/>
{/* Right Panel */}
{viewMode === "detail" && (
<div className="flex-1 overflow-y-auto custom-scrollbar">
<DocumentDetail document={detailData} />
</div>
)}
</div>
</div>
);