1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
import type { FileSummary } from "../../lib/api";
interface FileListProps {
files: FileSummary[];
loading: boolean;
onSelect: (id: string) => void;
onDelete: (id: string) => void;
onCreate: () => void;
}
function formatDuration(seconds: number | null): string {
if (seconds === null) return "-";
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs.toString().padStart(2, "0")}`;
}
function formatDate(dateStr: string): string {
const date = new Date(dateStr);
return date.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
});
}
export function FileList({
files,
loading,
onSelect,
onDelete,
onCreate,
}: FileListProps) {
if (loading) {
return (
<div className="panel h-full flex items-center justify-center">
<div className="font-mono text-[#9bc3ff] text-sm">Loading files...</div>
</div>
);
}
return (
<div className="panel h-full flex flex-col">
<div className="flex items-center justify-between p-4 pb-2 border-b border-dashed border-[rgba(117,170,252,0.35)]">
<div className="font-mono text-xs text-[#9bc3ff] tracking-wide uppercase">
FILES//
</div>
<button
onClick={onCreate}
className="px-3 py-1 font-mono text-xs text-[#9bc3ff] border border-[rgba(117,170,252,0.25)] hover:border-[#3f6fb3] hover:bg-[rgba(117,170,252,0.05)] transition-colors uppercase"
>
+ New
</button>
</div>
<div className="flex-1 overflow-y-auto">
{files.length === 0 ? (
<div className="text-center text-[#9bc3ff] text-sm font-mono opacity-60 py-8">
No saved files yet. Start recording to create one.
</div>
) : (
<div className="divide-y divide-[rgba(117,170,252,0.15)]">
{files.map((file) => (
<div
key={file.id}
className="p-4 hover:bg-[rgba(117,170,252,0.05)] transition-colors"
>
<div className="flex items-start justify-between gap-4">
<button
onClick={() => onSelect(file.id)}
className="flex-1 text-left"
>
<h3 className="font-mono text-sm text-[#dbe7ff] mb-1">
{file.name}
</h3>
{file.description && (
<p className="font-mono text-xs text-[#9bc3ff] mb-2 line-clamp-2">
{file.description}
</p>
)}
<div className="flex gap-4 font-mono text-[10px] text-[#75aafc]">
<span>{file.transcriptCount} segments</span>
<span>{formatDuration(file.duration)}</span>
<span>{formatDate(file.createdAt)}</span>
</div>
</button>
<button
onClick={(e) => {
e.stopPropagation();
onDelete(file.id);
}}
className="px-2 py-1 font-mono text-[10px] text-red-400 hover:bg-red-400/10 border border-red-400/30 hover:border-red-400/50 transition-colors uppercase"
>
Delete
</button>
</div>
</div>
))}
</div>
)}
</div>
</div>
);
}
|