design: implement multi-file selection support for research and existing-project onboarding uploaders

This commit is contained in:
2026-06-08 12:49:03 -07:00
parent f72d27790a
commit ad4872d31c

View File

@@ -211,9 +211,14 @@ function EntrepResearch({ files = [], brief = "", onChange }) {
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const selected = e.target.files?.[0]; const selectedFiles = Array.from(e.target.files ?? []);
if (!selected) return; if (selectedFiles.length === 0) return;
setUploading(selected.name);
const label =
selectedFiles.length === 1
? selectedFiles[0].name
: `${selectedFiles.length} files`;
setUploading(label);
setProgress(0); setProgress(0);
// Simulate a smooth upload progress bar // Simulate a smooth upload progress bar
@@ -222,14 +227,12 @@ function EntrepResearch({ files = [], brief = "", onChange }) {
if (p >= 100) { if (p >= 100) {
clearInterval(interval); clearInterval(interval);
setTimeout(() => { setTimeout(() => {
const newFiles = selectedFiles.map((f) => ({
name: f.name,
size: `${(f.size / 1024).toFixed(1)} KB`,
}));
onChange({ onChange({
files: [ files: [...files, ...newFiles],
...files,
{
name: selected.name,
size: `${(selected.size / 1024).toFixed(1)} KB`,
},
],
}); });
setUploading(null); setUploading(null);
}, 300); }, 300);
@@ -287,6 +290,7 @@ function EntrepResearch({ files = [], brief = "", onChange }) {
<input <input
type="file" type="file"
onChange={handleFileChange} onChange={handleFileChange}
multiple
style={{ display: "none" }} style={{ display: "none" }}
/> />
{uploading ? ( {uploading ? (
@@ -473,8 +477,9 @@ function EntrepExisting({ checklist = {}, onChange }) {
key: "designs" | "code", key: "designs" | "code",
e: React.ChangeEvent<HTMLInputElement>, e: React.ChangeEvent<HTMLInputElement>,
) => { ) => {
const selected = e.target.files?.[0]; const selectedFiles = Array.from(e.target.files ?? []);
if (!selected) return; if (selectedFiles.length === 0) return;
setUploading(key); setUploading(key);
setProgress(0); setProgress(0);
@@ -484,16 +489,14 @@ function EntrepExisting({ checklist = {}, onChange }) {
clearInterval(interval); clearInterval(interval);
setTimeout(() => { setTimeout(() => {
const currentFiles = checklist[`${key}Files`] || []; const currentFiles = checklist[`${key}Files`] || [];
const newFiles = selectedFiles.map((f) => ({
name: f.name,
size: `${(f.size / 1024).toFixed(1)} KB`,
}));
onChange({ onChange({
checklist: { checklist: {
...checklist, ...checklist,
[`${key}Files`]: [ [`${key}Files`]: [...currentFiles, ...newFiles],
...currentFiles,
{
name: selected.name,
size: `${(selected.size / 1024).toFixed(1)} KB`,
},
],
}, },
}); });
setUploading(null); setUploading(null);
@@ -546,6 +549,7 @@ function EntrepExisting({ checklist = {}, onChange }) {
<input <input
type="file" type="file"
onChange={(e) => handleFileChange(key, e)} onChange={(e) => handleFileChange(key, e)}
multiple
style={{ display: "none" }} style={{ display: "none" }}
/> />
{uploading === key ? ( {uploading === key ? (