@@ -313,11 +313,53 @@ const StatementItem: React.FC<StatementItemProps> = ({
313313 </ div >
314314 </ div >
315315
316- { /* Mobile layout - vertical stack */ }
317- < div className = 'md:hidden flex flex-col space-y-4' >
318- { /* Statement header with privacy toggle */ }
319- < div className = 'flex items-center justify-between pb-2 border-b border-gray-300' >
320- < h3 className = 'text-sm font-semibold text-gray-700' > Edit Statement</ h3 >
316+ { /* Intermediate layout (640px-768px) - Two rows */ }
317+ < div className = 'hidden sm:flex md:hidden flex-col space-y-3' >
318+ { /* Top row: Subject, Verb, Object, Category */ }
319+ < div className = 'flex flex-wrap gap-2' >
320+ { /* Subject */ }
321+ < div
322+ onClick = { ( ) => onPartClick ( 'subject' , draft . id ) }
323+ className = 'cursor-pointer p-2 rounded bg-subjectSelector hover:bg-subjectSelectorHover'
324+ >
325+ < span className = 'font-medium' > { draft . atoms . subject } </ span >
326+ </ div >
327+
328+ { /* Verb */ }
329+ < div
330+ onClick = { ( ) => onPartClick ( 'verb' , draft . id ) }
331+ className = 'cursor-pointer p-2 rounded bg-verbSelector hover:bg-verbSelectorHover'
332+ >
333+ < span className = 'font-medium' > { getVerbName ( draft . atoms . verb ) } </ span >
334+ </ div >
335+
336+ { /* Object */ }
337+ < div
338+ onClick = { ( ) => onPartClick ( 'object' , draft . id ) }
339+ className = 'cursor-pointer p-2 rounded bg-objectInput hover:bg-objectInputHover'
340+ >
341+ < span className = 'font-medium' > { draft . atoms . object } </ span >
342+ </ div >
343+
344+ { /* Category */ }
345+ < div
346+ onClick = { ( ) => onPartClick ( 'category' , draft . id ) }
347+ className = 'cursor-pointer p-2 rounded bg-categorySelector hover:bg-categorySelectorHover flex items-center'
348+ >
349+ < span className = 'mr-1' > 📁</ span >
350+ < span className = 'font-medium' >
351+ { draft . category &&
352+ draft . category . toLowerCase ( ) !== 'uncategorized' &&
353+ draft . category . toLowerCase ( ) !== 'uncategorised'
354+ ? getCategoryDisplayName ( draft . category )
355+ : 'Uncategorized' }
356+ </ span >
357+ </ div >
358+ </ div >
359+
360+ { /* Bottom row: Privacy toggle (left), Action buttons (right) */ }
361+ < div className = 'flex items-center justify-between pt-3 border-t border-gray-300' >
362+ { /* Left: Privacy toggle */ }
321363 < Button
322364 variant = { draft . isPublic ? 'success' : 'destructive' }
323365 size = 'compact'
@@ -331,48 +373,97 @@ const StatementItem: React.FC<StatementItemProps> = ({
331373 className = 'p-2 transition-colors shadow-sm'
332374 >
333375 { draft . isPublic ?
334- < > < MailPlus size = { 16 } /> < span className = "hidden sm:inline ml-1 text-xs" > Public</ span > </ > :
335- < > < MailX size = { 16 } /> < span className = "hidden sm:inline ml-1 text-xs" > Private</ span > </ >
376+ < > < MailPlus size = { 16 } /> < span className = "ml-1 text-xs" > Public</ span > </ > :
377+ < > < MailX size = { 16 } /> < span className = "ml-1 text-xs" > Private</ span > </ >
336378 }
337379 </ Button >
380+
381+ { /* Right: Action buttons */ }
382+ < div className = 'flex items-center space-x-2' >
383+ { /* Delete button */ }
384+ < Button
385+ variant = 'destructive'
386+ size = 'compact'
387+ onClick = { ( ) => onDelete ( draft . id ) }
388+ className = 'px-2 py-1 flex items-center'
389+ >
390+ < Trash2 size = { 16 } className = "mr-1" />
391+ < span className = "text-xs" > Delete</ span >
392+ </ Button >
393+
394+ { /* Cancel button */ }
395+ < Button
396+ variant = 'outline'
397+ size = 'compact'
398+ onClick = { ( ) => {
399+ setDraft ( JSON . parse ( JSON . stringify ( initialDraft ) ) ) ;
400+ if ( onCancel ) onCancel ( statement . id ) ;
401+ } }
402+ className = 'px-2 py-1 flex items-center'
403+ >
404+ < PenOff size = { 16 } className = "mr-1" />
405+ < span className = "text-xs" > Cancel</ span >
406+ </ Button >
407+
408+ { /* Save button */ }
409+ < Button
410+ variant = 'success'
411+ size = 'compact'
412+ onClick = { async ( ) => {
413+ setIsSaving ( true ) ;
414+ const updatedDraft = { ...draft } ;
415+ updatedDraft . input = `${ draft . atoms . subject } ${ getVerbName (
416+ draft . atoms . verb
417+ ) } ${ draft . atoms . object } `;
418+ await onLocalSave ( updatedDraft ) ;
419+ setIsSaving ( false ) ;
420+ } }
421+ disabled = { ! hasChanged || isSaving }
422+ className = 'px-2 py-1 flex items-center'
423+ >
424+ < Save size = { 16 } className = "mr-1" />
425+ < span className = "text-xs" > Save</ span >
426+ </ Button >
427+ </ div >
338428 </ div >
429+ </ div >
430+
431+ { /* Mobile layout - vertical stack */ }
432+ < div className = 'sm:hidden flex flex-col space-y-4' >
339433
340- { /* Statement parts grid */ }
341- < div className = 'grid grid-cols-2 gap -2' >
434+ { /* Statement parts column - single column vertical layout */ }
435+ < div className = 'flex flex-col space-y -2' >
342436 { /* Subject */ }
343437 < div
344438 onClick = { ( ) => onPartClick ( 'subject' , draft . id ) }
345- className = 'cursor-pointer p-3 rounded bg-subjectSelector hover:bg-subjectSelectorHover flex flex-col '
439+ className = 'cursor-pointer p-3 rounded bg-subjectSelector hover:bg-subjectSelectorHover'
346440 >
347- < span className = 'text-xs mb-1 opacity-70' > Subject</ span >
348- < span className = 'font-medium truncate' > { draft . atoms . subject } </ span >
441+ < span className = 'font-medium' > { draft . atoms . subject } </ span >
349442 </ div >
350443
351444 { /* Verb */ }
352445 < div
353446 onClick = { ( ) => onPartClick ( 'verb' , draft . id ) }
354- className = 'cursor-pointer p-3 rounded bg-verbSelector hover:bg-verbSelectorHover flex flex-col '
447+ className = 'cursor-pointer p-3 rounded bg-verbSelector hover:bg-verbSelectorHover'
355448 >
356- < span className = 'text-xs mb-1 opacity-70' > Verb</ span >
357- < span className = 'font-medium truncate' > { getVerbName ( draft . atoms . verb ) } </ span >
449+ < span className = 'font-medium' > { getVerbName ( draft . atoms . verb ) } </ span >
358450 </ div >
359451
360452 { /* Object */ }
361453 < div
362454 onClick = { ( ) => onPartClick ( 'object' , draft . id ) }
363- className = 'cursor-pointer p-3 rounded bg-objectInput hover:bg-objectInputHover flex flex-col '
455+ className = 'cursor-pointer p-3 rounded bg-objectInput hover:bg-objectInputHover'
364456 >
365- < span className = 'text-xs mb-1 opacity-70' > Object</ span >
366- < span className = 'font-medium truncate' > { draft . atoms . object } </ span >
457+ < span className = 'font-medium' > { draft . atoms . object } </ span >
367458 </ div >
368459
369460 { /* Category */ }
370461 < div
371462 onClick = { ( ) => onPartClick ( 'category' , draft . id ) }
372- className = 'cursor-pointer p-3 rounded bg-categorySelector hover:bg-categorySelectorHover flex flex-col '
463+ className = 'cursor-pointer p-3 rounded bg-categorySelector hover:bg-categorySelectorHover flex items-center '
373464 >
374- < span className = 'text-xs mb-1 opacity-70' > Category </ span >
375- < span className = 'font-medium truncate ' >
465+ < span className = 'mr-1' > 📁 </ span >
466+ < span className = 'font-medium' >
376467 { draft . category &&
377468 draft . category . toLowerCase ( ) !== 'uncategorized' &&
378469 draft . category . toLowerCase ( ) !== 'uncategorised'
@@ -384,18 +475,38 @@ const StatementItem: React.FC<StatementItemProps> = ({
384475
385476 { /* Action buttons - bottom fixed bar */ }
386477 < div className = 'flex justify-between items-center pt-3 mt-2 border-t border-gray-300' >
387- { /* Delete button */ }
478+ { /* Left: Privacy toggle */ }
388479 < Button
389- variant = ' destructive'
480+ variant = { draft . isPublic ? 'success' : ' destructive'}
390481 size = 'compact'
391- onClick = { ( ) => onDelete ( draft . id ) }
482+ onClick = { ( ) => {
483+ setDraft ( ( prevDraft ) => {
484+ const newDraft = JSON . parse ( JSON . stringify ( prevDraft ) ) ;
485+ newDraft . isPublic = ! prevDraft . isPublic ;
486+ return newDraft ;
487+ } ) ;
488+ } }
392489 className = 'min-w-[40px] xs:px-3 py-2 flex justify-center'
393490 >
394- < Trash2 size = { 16 } className = "xs:mr-1" />
395- < span className = "hidden xs:inline text-xs" > Delete</ span >
491+ { draft . isPublic ?
492+ < > < MailPlus size = { 16 } className = "xs:mr-1" /> < span className = "hidden xs:inline text-xs" > Public</ span > </ > :
493+ < > < MailX size = { 16 } className = "xs:mr-1" /> < span className = "hidden xs:inline text-xs" > Private</ span > </ >
494+ }
396495 </ Button >
397496
497+ { /* Right: Action buttons */ }
398498 < div className = 'flex space-x-2' >
499+ { /* Delete button */ }
500+ < Button
501+ variant = 'destructive'
502+ size = 'compact'
503+ onClick = { ( ) => onDelete ( draft . id ) }
504+ className = 'min-w-[40px] xs:px-3 py-2 flex justify-center'
505+ >
506+ < Trash2 size = { 16 } className = "xs:mr-1" />
507+ < span className = "hidden xs:inline text-xs" > Delete</ span >
508+ </ Button >
509+
399510 { /* Cancel button */ }
400511 < Button
401512 variant = 'outline'
0 commit comments