bea71ab85b
- Resolve 57 merge conflicts from codebase restructure - Port dev feature code to new directory structure: * Update import paths to use @/ aliases * Add backward-compatible API signatures (createInstance, startInstance, deleteInstance) * Add missing type exports (ProjectWithRepos, InstanceHealth, Branch, BranchesResponse) * Extend Session and GitRepository types for dev features * Extend TerminalComponent props for mobile terminal wrapper * Add missing icon names (bell, drag, undo) Quality gates: tsc pass (0 errors), build pass, 127/131 tests pass (4 pre-existing failures unrelated to merge)
77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
import { Icon } from "@/components/ui/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>
|
|
);
|
|
};
|