Skip to content

Commit 5db6837

Browse files
committed
feat: implemented auto-scroll when change category on statement
1 parent 34416d1 commit 5db6837

File tree

4 files changed

+68
-15
lines changed

4 files changed

+68
-15
lines changed

src/components/ui/simple-dropdown.tsx

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,32 @@ const SimpleDropdownMenuTrigger: React.FC<SimpleDropdownMenuTriggerProps> = ({
8484
...props
8585
}) => {
8686
if (asChild && React.isValidElement(children)) {
87-
// If asChild is true, clone the child element and add the onClick handler
88-
return React.cloneElement(children, {
89-
...props,
90-
onClick: (e: React.MouseEvent) => {
91-
// Preserve original onClick if it exists
92-
if (children.props.onClick) {
93-
children.props.onClick(e);
94-
}
95-
// Call our onClick handler
96-
if (onClick) {
97-
onClick(e);
98-
}
87+
// Create a merged handler that combines the existing handler and our new one
88+
const mergedClickHandler = (e: React.MouseEvent) => {
89+
// Call the child's original onClick if it exists
90+
if (children.props.onClick) {
91+
children.props.onClick(e);
92+
}
93+
// Call our onClick handler
94+
if (onClick) {
95+
onClick(e);
9996
}
100-
});
97+
};
98+
99+
// Create a new props object with our merged handler
100+
const mergedProps = {
101+
...props,
102+
};
103+
104+
// Create a clone with a properly typed handler
105+
return React.cloneElement(
106+
children,
107+
{
108+
...mergedProps,
109+
// Just use the child's props directly
110+
onClick: mergedClickHandler,
111+
} as React.HTMLAttributes<HTMLElement>
112+
);
101113
}
102114

103115
// Otherwise, wrap the children in a div with the onClick handler

src/features/statements/components/StatementItem.tsx

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ const StatementItem: React.FC<StatementItemProps> = ({
112112
originalCategory: externalOriginalCategory, // Get original category from parent
113113
}) => {
114114
const [isActionsExpanded, setIsActionsExpanded] = React.useState(false);
115+
116+
// Create a ref for the component root element
117+
const itemRef = React.useRef<HTMLDivElement>(null);
118+
119+
// Create refs to track category changes for animations
120+
const prevCategoryRef = React.useRef<string | null>(null);
115121

116122
// Use simple primitive values to store original state
117123
// This way we avoid object reference issues
@@ -169,6 +175,34 @@ const StatementItem: React.FC<StatementItemProps> = ({
169175
}
170176
// eslint-disable-next-line react-hooks/exhaustive-deps
171177
}, [statement, isEditing]);
178+
179+
// Dedicated effect for scrolling when needed
180+
useEffect(() => {
181+
// Check if this statement was updated with a category change (flagged by EditStatementModal)
182+
if (isEditing && (statement as any)._needsScroll) {
183+
console.log('Statement flagged for scrolling:', statement.id);
184+
185+
// Use a longer delay to ensure the DOM has fully updated
186+
const timer = setTimeout(() => {
187+
if (itemRef.current) {
188+
console.log('Executing scroll to element');
189+
// Force scroll to this element
190+
itemRef.current.scrollIntoView({
191+
behavior: 'smooth',
192+
block: 'center'
193+
});
194+
console.log('Scroll instruction sent');
195+
}
196+
}, 500);
197+
198+
return () => clearTimeout(timer);
199+
}
200+
201+
// Keep reference updated for category change tracking
202+
prevCategoryRef.current = statement.category;
203+
// Check this effect whenever the statement reference changes
204+
// eslint-disable-next-line react-hooks/exhaustive-deps
205+
}, [statement, isEditing]);
172206

173207
// Helper function to normalize category values for comparison
174208
const normalizeCategoryForComparison = (
@@ -226,7 +260,10 @@ const StatementItem: React.FC<StatementItemProps> = ({
226260

227261
if (isEditing) {
228262
return (
229-
<div className='bg-gray-100 p-3 rounded-lg shadow'>
263+
<div
264+
ref={itemRef}
265+
id={`statement-${statement.id}`}
266+
className='bg-gray-100 p-3 rounded-lg shadow'>
230267
{/* Desktop layout - horizontal row */}
231268
<div className='hidden md:flex md:items-center md:space-x-2'>
232269
{/* Privacy toggle button */}
@@ -614,6 +651,8 @@ const StatementItem: React.FC<StatementItemProps> = ({
614651
// Static view when not in editing mode.
615652
return (
616653
<div
654+
ref={itemRef}
655+
id={`statement-${statement.id}`}
617656
className={`border rounded-md p-3 space-y-2 relative ${
618657
statement.isResolved
619658
? 'bg-gray-100 border-gray-300 opacity-80'

src/features/statements/context/EntriesProvider.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ const EntriesReducer = (
2424
console.log("[ENTRIES REDUCER] Processing UPDATE_ENTRY action:", {
2525
updatedId: action.payload.id,
2626
updatedCategory: action.payload.category,
27-
updatedTimestamp: action.payload._updateTimestamp
27+
// Use optional chaining to safely access a property that might not exist
28+
updatedTimestamp: (action.payload as any)._updateTimestamp
2829
});
2930

3031
const oldEntry = data.entries.find(entry => entry.id === action.payload.id);

src/features/wizard/components/EditStatementModal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export const EditStatementModal: React.FC<EditStatementModalProps> = ({
8383
...statement,
8484
// Add a timestamp to force detection of changes
8585
_lastModified: Date.now(),
86+
_needsScroll: true, // Flag to indicate this needs scrolling
8687
category: categoryValue,
8788
};
8889

0 commit comments

Comments
 (0)