Skip to content

Commit 769c7e5

Browse files
committed
manual entry use case: database and upload flow
1 parent 648df51 commit 769c7e5

7 files changed

Lines changed: 251 additions & 46 deletions

File tree

frontend/src/components/upload/FileUploadSection.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ interface FileUploadSectionProps {
99
file: File | null;
1010
preview: string | null;
1111
imageType: string;
12+
isManualMode: boolean;
1213
onFileChange: (file: File | undefined) => void;
1314
onRemoveImage: (index: number) => void;
1415
onAddImage: () => void;
1516
onImageTypeChange: (value: string | undefined) => void;
16-
17+
onManualModeChange: (value: boolean) => void;
1718
onChangeFile?: (file: File | undefined) => void;
1819
}
1920

@@ -22,11 +23,12 @@ export default function FileUploadSection({
2223
file,
2324
preview,
2425
imageType,
26+
isManualMode,
2527
onFileChange,
2628
onRemoveImage,
2729
onAddImage,
2830
onImageTypeChange,
29-
31+
onManualModeChange,
3032
onChangeFile,
3133
}: FileUploadSectionProps) {
3234
const onDrop = (e: DragEvent<HTMLDivElement>) => {
@@ -71,6 +73,23 @@ export default function FileUploadSection({
7173
/>
7274
</Container>
7375
</div>
76+
77+
{/* Manual / Generate Mode Selection */}
78+
<div className="flex justify-center">
79+
<Container withInternalPadding className="bg-transparent border-none shadow-none">
80+
<SegmentInput
81+
name="mode"
82+
value={isManualMode ? 'manual' : 'generate'}
83+
onChange={(value) => onManualModeChange(value === 'manual')}
84+
options={[
85+
{ key: 'manual', label: 'Manual' },
86+
{ key: 'generate', label: 'Generate' }
87+
]}
88+
keySelector={(o) => o.key}
89+
labelSelector={(o) => o.label}
90+
/>
91+
</Container>
92+
</div>
7493

7594
<div
7695
className={`${styles.dropZone} ${file ? styles.hasFile : ''}`}

frontend/src/components/upload/GeneratedTextSection.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ interface GeneratedTextSectionProps {
77
description: string;
88
analysis: string;
99
recommendedActions: string;
10+
isManualMode?: boolean;
1011
onDescriptionChange: (value: string | undefined) => void;
1112
onAnalysisChange: (value: string | undefined) => void;
1213
onRecommendedActionsChange: (value: string | undefined) => void;
@@ -22,6 +23,7 @@ export default function GeneratedTextSection({
2223
description,
2324
analysis,
2425
recommendedActions,
26+
isManualMode = false,
2527
onDescriptionChange,
2628
onAnalysisChange,
2729
onRecommendedActionsChange,
@@ -37,9 +39,15 @@ export default function GeneratedTextSection({
3739

3840
// Update local state when props change (e.g., when AI generates new content)
3941
useEffect(() => {
40-
const formattedText = `Description:\n${description || 'AI-generated description will appear here...'}\n\nAnalysis:\n${analysis || 'AI-generated analysis will appear here...'}\n\nRecommended Actions:\n${recommendedActions || 'AI-generated recommended actions will appear here...'}`;
41-
setTextareaValue(formattedText);
42-
}, [description, analysis, recommendedActions]);
42+
// For manual mode, don't show placeholders - use empty strings
43+
if (isManualMode) {
44+
const formattedText = `Description:\n${description}\n\nAnalysis:\n${analysis}\n\nRecommended Actions:\n${recommendedActions}`;
45+
setTextareaValue(formattedText);
46+
} else {
47+
const formattedText = `Description:\n${description || 'AI-generated description will appear here...'}\n\nAnalysis:\n${analysis || 'AI-generated analysis will appear here...'}\n\nRecommended Actions:\n${recommendedActions || 'AI-generated recommended actions will appear here...'}`;
48+
setTextareaValue(formattedText);
49+
}
50+
}, [description, analysis, recommendedActions, isManualMode]);
4351

4452
const handleTextChange = (value: string | undefined) => {
4553
if (value !== undefined) {
@@ -84,7 +92,7 @@ export default function GeneratedTextSection({
8492
value={textareaValue}
8593
onChange={handleTextChange}
8694
rows={12}
87-
placeholder="AI-generated content will appear here..."
95+
placeholder={isManualMode ? "" : "AI-generated content will appear here..."}
8896
/>
8997
</div>
9098
</div>

frontend/src/components/upload/MetadataFormSection.tsx

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ export default function MetadataFormSection({
116116
value={title}
117117
onChange={onTitleChange}
118118
placeholder="Enter a title for all images..."
119-
required
120119
/>
121120
</div>
122121
{files.map((file, index) => (
@@ -137,7 +136,7 @@ export default function MetadataFormSection({
137136
options={sources}
138137
keySelector={(o) => o.s_code}
139138
labelSelector={(o) => o.label}
140-
required
139+
placeholder="Please select"
141140
/>
142141
)}
143142
<SelectInput
@@ -148,7 +147,7 @@ export default function MetadataFormSection({
148147
options={types}
149148
keySelector={(o) => o.t_code}
150149
labelSelector={(o) => o.label}
151-
required={imageType !== 'drone_image'}
150+
placeholder="Please select"
152151
/>
153152
<SelectInput
154153
label="EPSG"
@@ -158,8 +157,7 @@ export default function MetadataFormSection({
158157
options={spatialReferences}
159158
keySelector={(o) => o.epsg}
160159
labelSelector={(o) => `${o.srid} (EPSG:${o.epsg})`}
161-
placeholder="EPSG"
162-
required={imageType !== 'drone_image'}
160+
placeholder="Please select"
163161
/>
164162
<MultiSelectInput
165163
label="Countries (optional)"
@@ -289,7 +287,6 @@ export default function MetadataFormSection({
289287
value={title}
290288
onChange={onTitleChange}
291289
placeholder="Enter a title for this map..."
292-
required
293290
/>
294291
</div>
295292
{imageType !== 'drone_image' && (
@@ -301,7 +298,7 @@ export default function MetadataFormSection({
301298
options={sources}
302299
keySelector={(o) => o.s_code}
303300
labelSelector={(o) => o.label}
304-
required
301+
placeholder="Please select"
305302
/>
306303
)}
307304
<SelectInput
@@ -312,7 +309,7 @@ export default function MetadataFormSection({
312309
options={types}
313310
keySelector={(o) => o.t_code}
314311
labelSelector={(o) => o.label}
315-
required={imageType !== 'drone_image'}
312+
placeholder="Please select"
316313
/>
317314
<SelectInput
318315
label="EPSG"
@@ -322,8 +319,7 @@ export default function MetadataFormSection({
322319
options={spatialReferences}
323320
keySelector={(o) => o.epsg}
324321
labelSelector={(o) => `${o.srid} (EPSG:${o.epsg})`}
325-
placeholder="EPSG"
326-
required={imageType !== 'drone_image'}
322+
placeholder="Please select"
327323
/>
328324
<SelectInput
329325
label="Image Type"
@@ -333,7 +329,6 @@ export default function MetadataFormSection({
333329
options={imageTypes}
334330
keySelector={(o) => o.image_type}
335331
labelSelector={(o) => o.label}
336-
required
337332
/>
338333
<MultiSelectInput
339334
label="Countries (optional)"

0 commit comments

Comments
 (0)