8c7affc933
Fixed import paths for 43 components moved into features/ directories. Key fixes: - api/, types/, hooks/, state/, utils/ imports need ../../../ from features/*/ - components/ imports need ../../ from features/*/ - Cross-feature imports use relative paths (e.g., ../tool/tools-bottom-sheet) - app-shell.tsx updated to import from features/ subdirectories Frontend typecheck now passes except for one pre-existing error: xterm-addon-webgl missing type declarations. Quality gates: ruff passed on backend, py_compile passed on all backend files.
77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
import { Icon } from "../../icon";
|
|
import type { IconName } from "../../../utils/icons";
|
|
|
|
interface MobileListItem {
|
|
id: string;
|
|
title: string;
|
|
subtitle?: string;
|
|
icon?: string;
|
|
status?: string;
|
|
}
|
|
|
|
interface MobileListViewProps {
|
|
items: MobileListItem[];
|
|
onItemClick: (id: string) => void;
|
|
onItemDelete?: (id: string) => void;
|
|
onItemDuplicate?: (id: string) => void;
|
|
emptyMessage?: string;
|
|
searchPlaceholder?: string;
|
|
onSearch?: (query: string) => void;
|
|
}
|
|
|
|
export const MobileListView: React.FC<MobileListViewProps> = ({
|
|
items,
|
|
onItemClick,
|
|
emptyMessage = "No items found",
|
|
searchPlaceholder = "Search...",
|
|
onSearch,
|
|
}) => {
|
|
return (
|
|
<div className="mobile-list-view">
|
|
{onSearch && (
|
|
<div className="mobile-list-search">
|
|
<input
|
|
type="search"
|
|
placeholder={searchPlaceholder}
|
|
onChange={(e) => onSearch(e.target.value)}
|
|
className="mobile-list-search-input"
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{items.length === 0 ? (
|
|
<div className="mobile-list-empty">
|
|
<Icon name="folder" size="lg" />
|
|
<p>{emptyMessage}</p>
|
|
</div>
|
|
) : (
|
|
<div className="mobile-list-items">
|
|
{items.map((item) => (
|
|
<button
|
|
key={item.id}
|
|
className="mobile-list-item"
|
|
onClick={() => onItemClick(item.id)}
|
|
type="button"
|
|
>
|
|
{item.icon && (
|
|
<div className="mobile-list-item-icon">
|
|
<Icon name={item.icon as IconName} size="md" />
|
|
</div>
|
|
)}
|
|
<div className="mobile-list-item-content">
|
|
<div className="mobile-list-item-title">{item.title}</div>
|
|
{item.subtitle && (
|
|
<div className="mobile-list-item-subtitle">{item.subtitle}</div>
|
|
)}
|
|
</div>
|
|
<div className="mobile-list-item-actions" style={{ transform: "rotate(180deg)" }}>
|
|
<Icon name="arrow-left" size="sm" />
|
|
</div>
|
|
</button>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|