From 4e18d91feb6bc98f266260ce06cb0268ec7c411d Mon Sep 17 00:00:00 2001 From: Mary Kate Fain Date: Mon, 16 Mar 2026 14:35:39 -0500 Subject: [PATCH] fix: improve media field placeholder language to emphasize uploading Replace misleading 'URL' placeholder on media fields with action-oriented text like 'Upload audio or paste direct file link' per preset type. Update upload button tooltips to say 'Choose file to upload'. Update Music preset description to say 'Upload' consistently. Each preset now carries its own valuePlaceholder through the form schema to the row component. --- src/pages/ProfileSettings.tsx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/pages/ProfileSettings.tsx b/src/pages/ProfileSettings.tsx index f8498b7e..2e9558bc 100644 --- a/src/pages/ProfileSettings.tsx +++ b/src/pages/ProfileSettings.tsx @@ -97,13 +97,13 @@ const FIELD_PRESETS: FieldPreset[] = [ { id: 'music', label: 'Music', - description: 'Add a song or audio clip', + description: 'Upload a song or audio clip', icon: Music, defaultLabel: '\u{1F3B6}', type: 'media', accept: 'audio/*', formatHint: 'MP3, OGG, WAV, FLAC, AAC, M4A, Opus', - valuePlaceholder: 'Audio URL', + valuePlaceholder: 'Upload audio or paste direct file link', }, { id: 'photo', @@ -114,7 +114,7 @@ const FIELD_PRESETS: FieldPreset[] = [ type: 'media', accept: 'image/*', formatHint: 'JPG, PNG, GIF, WebP, SVG, AVIF', - valuePlaceholder: 'Image URL', + valuePlaceholder: 'Upload image or paste direct file link', }, { id: 'video', @@ -125,7 +125,7 @@ const FIELD_PRESETS: FieldPreset[] = [ type: 'media', accept: 'video/*', formatHint: 'MP4, WebM, MOV', - valuePlaceholder: 'Video URL', + valuePlaceholder: 'Upload video or paste direct file link', }, { id: 'email', @@ -204,6 +204,8 @@ const formSchema = n.metadata().extend({ type: z.enum(['text', 'wallet', 'media']), /** Client-side only — file accept filter for the file picker (not persisted). */ accept: z.string().optional(), + /** Client-side only — placeholder text for the value input (not persisted). */ + placeholder: z.string().optional(), })).optional(), shape: z.string().optional(), }); @@ -224,6 +226,7 @@ interface SortableFieldRowProps { index: number; type: 'text' | 'wallet' | 'media'; accept?: string; + valuePlaceholder?: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any control: any; onRemove: () => void; @@ -231,7 +234,7 @@ interface SortableFieldRowProps { onTickerChange: (ticker: string) => void; } -function SortableFieldRow({ id, index, type, accept, control, onRemove, onMediaPick, onTickerChange }: SortableFieldRowProps) { +function SortableFieldRow({ id, index, type, accept, valuePlaceholder, control, onRemove, onMediaPick, onTickerChange }: SortableFieldRowProps) { const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id }); const style = { transform: CSS.Transform.toString(transform), transition }; @@ -300,7 +303,7 @@ function SortableFieldRow({ id, index, type, accept, control, onRemove, onMediaP
- + @@ -316,9 +319,9 @@ function SortableFieldRow({ id, index, type, accept, control, onRemove, onMediaP {formatHint ? ( - Upload file
{formatHint}
+ Choose file to upload
{formatHint}
) : ( - Upload a media file + Choose a media file to upload )}
@@ -564,6 +567,7 @@ export function ProfileSettings() { value: '', type: preset.type, accept: preset.accept, + placeholder: preset.valuePlaceholder, }); }; @@ -732,6 +736,7 @@ export function ProfileSettings() { index={index} type={form.watch(`fields.${index}.type`) ?? 'text'} accept={form.watch(`fields.${index}.accept`)} + valuePlaceholder={form.watch(`fields.${index}.placeholder`)} control={form.control} onRemove={() => remove(index)} onMediaPick={() => handleMediaPick(index)}