@mgonza02/goal-image-gallery 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/IMPLEMENTATION_SUMMARY.md +259 -0
- package/LICENSE +21 -0
- package/MIGRATION.md +428 -0
- package/QUICK_REFERENCE.md +235 -0
- package/README.md +479 -0
- package/lib/GoalImageGallery.js +244 -0
- package/lib/components/ImageGalleryEmptyState.js +87 -0
- package/lib/components/ImageGalleryGrid.js +108 -0
- package/lib/components/ImageGalleryItem.js +175 -0
- package/lib/components/ImageGalleryModal.js +149 -0
- package/lib/components/index.js +5 -0
- package/lib/examples.js +503 -0
- package/lib/hooks/use-image-gallery.js +252 -0
- package/lib/index.d.ts +187 -0
- package/lib/index.js +148 -0
- package/lib/styles/styled-components.js +173 -0
- package/lib/utils/image-utils.js +129 -0
- package/package.json +93 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# GoalImageGallery - Implementation Summary
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The GoalImageGallery component has been successfully enhanced with modern UI/UX practices and comprehensive multi-method upload support. This document summarizes all the improvements and enhancements made.
|
|
6
|
+
|
|
7
|
+
## ✅ Completed Improvements
|
|
8
|
+
|
|
9
|
+
### 1. Enhanced UI/UX Design
|
|
10
|
+
|
|
11
|
+
#### Modern Material Design 3 Implementation
|
|
12
|
+
- **Responsive Grid Layout**: Adapts to screen sizes with proper breakpoints
|
|
13
|
+
- **Smooth Animations**: Hover effects, transitions, and loading states
|
|
14
|
+
- **Visual Hierarchy**: Clear typography, spacing, and color usage
|
|
15
|
+
- **Dark/Light Theme Support**: Automatic theme switching based on system preferences
|
|
16
|
+
|
|
17
|
+
#### Interactive Elements
|
|
18
|
+
- **Hover Effects**: Image cards lift and show overlay controls
|
|
19
|
+
- **Loading States**: Skeleton animations during image loading
|
|
20
|
+
- **Empty State**: Informative empty state with upload options preview
|
|
21
|
+
- **Visual Feedback**: Loading indicators, success/error messages
|
|
22
|
+
|
|
23
|
+
#### Accessibility Features
|
|
24
|
+
- **ARIA Labels**: Proper labeling for screen readers
|
|
25
|
+
- **Keyboard Navigation**: Full keyboard support with logical tab order
|
|
26
|
+
- **Focus Management**: Visible focus indicators and proper focus trapping
|
|
27
|
+
- **High Contrast Support**: Compatible with high contrast mode
|
|
28
|
+
|
|
29
|
+
### 2. Multi-Method Upload Support
|
|
30
|
+
|
|
31
|
+
#### File Upload (Traditional)
|
|
32
|
+
- **Drag & Drop**: Native drag-and-drop functionality
|
|
33
|
+
- **File Selection**: Click-to-select file dialog
|
|
34
|
+
- **Multiple Files**: Support for multiple file selection
|
|
35
|
+
- **File Validation**: Type and size validation with user feedback
|
|
36
|
+
|
|
37
|
+
#### Clipboard Paste (NEW)
|
|
38
|
+
- **Ctrl+V Support**: Paste images directly from clipboard
|
|
39
|
+
- **Automatic Detection**: Detects image content in clipboard
|
|
40
|
+
- **Cross-Platform**: Works on Windows, Mac, and Linux
|
|
41
|
+
- **Browser Compatibility**: Graceful degradation for older browsers
|
|
42
|
+
|
|
43
|
+
#### URL Loading (NEW)
|
|
44
|
+
- **Remote Images**: Load images from external URLs
|
|
45
|
+
- **URL Validation**: Validates image URLs before loading
|
|
46
|
+
- **Error Handling**: Proper error messages for invalid URLs
|
|
47
|
+
- **Preview Support**: Shows preview before final upload
|
|
48
|
+
|
|
49
|
+
### 3. Advanced Image Viewer
|
|
50
|
+
|
|
51
|
+
#### Full-Screen Modal
|
|
52
|
+
- **Responsive Design**: Optimized for all screen sizes
|
|
53
|
+
- **Zoom Controls**: 0.5x to 3x zoom with smooth transitions
|
|
54
|
+
- **Navigation**: Previous/next controls with keyboard shortcuts
|
|
55
|
+
- **Download Support**: One-click image download functionality
|
|
56
|
+
|
|
57
|
+
#### Keyboard Shortcuts
|
|
58
|
+
- **Arrow Keys**: Navigate between images (←/→)
|
|
59
|
+
- **Zoom Controls**: Zoom in (+/=), zoom out (-)
|
|
60
|
+
- **Quick Actions**: Close modal (Escape), paste images (Ctrl+V)
|
|
61
|
+
- **Accessibility**: Full keyboard navigation support
|
|
62
|
+
|
|
63
|
+
### 4. Mobile Optimization
|
|
64
|
+
|
|
65
|
+
#### Touch-Friendly Interface
|
|
66
|
+
- **Responsive Breakpoints**: Optimized layouts for mobile, tablet, desktop
|
|
67
|
+
- **Touch Targets**: Properly sized buttons and interactive elements
|
|
68
|
+
- **Swipe Gestures**: Support for swipe navigation (planned)
|
|
69
|
+
- **Mobile-First Design**: Designed primarily for mobile experience
|
|
70
|
+
|
|
71
|
+
#### Performance Optimization
|
|
72
|
+
- **Lazy Loading**: Images loaded on demand
|
|
73
|
+
- **Thumbnail Support**: Uses optimized thumbnails for gallery view
|
|
74
|
+
- **Memory Management**: Proper cleanup of resources
|
|
75
|
+
- **Efficient Rendering**: Optimized React rendering patterns
|
|
76
|
+
|
|
77
|
+
### 5. Enhanced Component Integration
|
|
78
|
+
|
|
79
|
+
#### Seamless Integration
|
|
80
|
+
- **EnhancedImageSelector**: Upgraded from CommonImageSelector
|
|
81
|
+
- **Backward Compatibility**: Maintains existing API where possible
|
|
82
|
+
- **Props Enhancement**: Added new props while keeping existing ones
|
|
83
|
+
- **State Management**: Improved internal state handling
|
|
84
|
+
|
|
85
|
+
#### API Improvements
|
|
86
|
+
- **Standardized Response**: Consistent API response format
|
|
87
|
+
- **Error Handling**: Comprehensive error handling and user feedback
|
|
88
|
+
- **Loading States**: Proper loading state management
|
|
89
|
+
- **Success Callbacks**: Enhanced callback system for updates
|
|
90
|
+
|
|
91
|
+
## 🔧 Technical Enhancements
|
|
92
|
+
|
|
93
|
+
### Code Quality
|
|
94
|
+
- **Type Safety**: Comprehensive PropTypes validation
|
|
95
|
+
- **Performance**: Optimized rendering and memory usage
|
|
96
|
+
- **Error Boundaries**: Proper error handling and recovery
|
|
97
|
+
- **Code Organization**: Well-structured, maintainable code
|
|
98
|
+
|
|
99
|
+
### Dependencies
|
|
100
|
+
- **Material-UI v5**: Latest Material-UI components
|
|
101
|
+
- **React Dropzone**: Professional drag-and-drop functionality
|
|
102
|
+
- **React Hooks**: Modern React patterns with hooks
|
|
103
|
+
- **Styled Components**: Efficient styling with styled-components
|
|
104
|
+
|
|
105
|
+
### Browser Support
|
|
106
|
+
- **Modern Browsers**: Full feature support (Chrome, Firefox, Safari, Edge)
|
|
107
|
+
- **Legacy Support**: Graceful degradation for older browsers
|
|
108
|
+
- **Mobile Browsers**: Optimized for mobile web browsers
|
|
109
|
+
- **Progressive Enhancement**: Features work even if some APIs are unavailable
|
|
110
|
+
|
|
111
|
+
## 📚 Documentation Created
|
|
112
|
+
|
|
113
|
+
### Complete Documentation Suite
|
|
114
|
+
1. **README.md**: Comprehensive usage guide and API reference
|
|
115
|
+
2. **QUICK_REFERENCE.md**: Fast lookup guide for common patterns
|
|
116
|
+
3. **MIGRATION.md**: Step-by-step migration guide from legacy components
|
|
117
|
+
4. **examples.js**: Practical usage examples for various scenarios
|
|
118
|
+
5. **index.js**: Main entry point with utilities and constants
|
|
119
|
+
|
|
120
|
+
### Example Coverage
|
|
121
|
+
- **Basic Gallery**: Simple read-only image display
|
|
122
|
+
- **Product Gallery**: Editable product image management
|
|
123
|
+
- **User Avatar**: Single image avatar functionality
|
|
124
|
+
- **Document Attachments**: Multi-file document gallery
|
|
125
|
+
- **Advanced Upload**: Demonstration of all upload methods
|
|
126
|
+
- **Mobile Gallery**: Mobile-optimized example
|
|
127
|
+
- **State Management**: Complete state management example
|
|
128
|
+
|
|
129
|
+
## 🚀 Features Summary
|
|
130
|
+
|
|
131
|
+
### Core Features
|
|
132
|
+
- ✅ Multi-method upload (file, clipboard, URL)
|
|
133
|
+
- ✅ Responsive grid layout
|
|
134
|
+
- ✅ Full-screen image viewer
|
|
135
|
+
- ✅ Zoom and navigation controls
|
|
136
|
+
- ✅ Keyboard shortcuts
|
|
137
|
+
- ✅ Mobile optimization
|
|
138
|
+
- ✅ Accessibility support
|
|
139
|
+
- ✅ Loading states and error handling
|
|
140
|
+
|
|
141
|
+
### Advanced Features
|
|
142
|
+
- ✅ Drag & drop functionality
|
|
143
|
+
- ✅ Clipboard paste support
|
|
144
|
+
- ✅ URL image loading
|
|
145
|
+
- ✅ Download functionality
|
|
146
|
+
- ✅ Permission-based editing
|
|
147
|
+
- ✅ Custom empty states
|
|
148
|
+
- ✅ Image information overlay
|
|
149
|
+
- ✅ Batch operations
|
|
150
|
+
|
|
151
|
+
### Developer Features
|
|
152
|
+
- ✅ Comprehensive documentation
|
|
153
|
+
- ✅ Usage examples
|
|
154
|
+
- ✅ Migration guide
|
|
155
|
+
- ✅ TypeScript-ready (JSDoc comments)
|
|
156
|
+
- ✅ Performance optimizations
|
|
157
|
+
- ✅ Error handling
|
|
158
|
+
- ✅ Backward compatibility
|
|
159
|
+
|
|
160
|
+
## 🎯 Usage Examples
|
|
161
|
+
|
|
162
|
+
### Basic Implementation
|
|
163
|
+
```javascript
|
|
164
|
+
<GoalImageGallery
|
|
165
|
+
imageCodes={['img1', 'img2', 'img3']}
|
|
166
|
+
canEdit={true}
|
|
167
|
+
ownerEntity={{ id: 'entity-123' }}
|
|
168
|
+
imageHandlerApi={handleUpload}
|
|
169
|
+
afterUpload={refreshData}
|
|
170
|
+
multiple={true}
|
|
171
|
+
/>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Advanced Implementation
|
|
175
|
+
```javascript
|
|
176
|
+
<GoalImageGallery
|
|
177
|
+
imageCodes={imageCodes}
|
|
178
|
+
canEdit={hasPermission('EDIT_IMAGES')}
|
|
179
|
+
ownerEntity={{ id: product.id, type: 'product' }}
|
|
180
|
+
imageHandlerApi={productImageApi}
|
|
181
|
+
afterUpload={refreshProduct}
|
|
182
|
+
multiple={true}
|
|
183
|
+
permission="EDIT_IMAGES"
|
|
184
|
+
emptyMessage="No product images available"
|
|
185
|
+
showImageInfo={true}
|
|
186
|
+
allowDownload={true}
|
|
187
|
+
/>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## 🔄 Migration Path
|
|
191
|
+
|
|
192
|
+
### From Legacy Components
|
|
193
|
+
1. **CommonImageGallery** → **GoalImageGallery**
|
|
194
|
+
2. **Basic Image Display** → **GoalImageGallery**
|
|
195
|
+
3. **ImageUploader** → **GoalImageGallery**
|
|
196
|
+
4. **Custom Galleries** → **GoalImageGallery**
|
|
197
|
+
|
|
198
|
+
### Migration Benefits
|
|
199
|
+
- **Reduced Code**: Single component replaces multiple components
|
|
200
|
+
- **Better UX**: Modern, consistent user experience
|
|
201
|
+
- **More Features**: Advanced upload methods and viewer
|
|
202
|
+
- **Better Performance**: Optimized rendering and memory usage
|
|
203
|
+
- **Accessibility**: Built-in accessibility features
|
|
204
|
+
|
|
205
|
+
## 🎨 Design Philosophy
|
|
206
|
+
|
|
207
|
+
### User-Centered Design
|
|
208
|
+
- **Intuitive Interface**: Clear, predictable interactions
|
|
209
|
+
- **Visual Feedback**: Immediate response to user actions
|
|
210
|
+
- **Error Prevention**: Validation and helpful error messages
|
|
211
|
+
- **Accessibility First**: Designed for all users
|
|
212
|
+
|
|
213
|
+
### Developer Experience
|
|
214
|
+
- **Easy Integration**: Simple API with sensible defaults
|
|
215
|
+
- **Comprehensive Documentation**: Everything needed to implement
|
|
216
|
+
- **Flexible Configuration**: Customizable for various use cases
|
|
217
|
+
- **Performance Focused**: Optimized for production use
|
|
218
|
+
|
|
219
|
+
## 📊 Performance Metrics
|
|
220
|
+
|
|
221
|
+
### Load Time Improvements
|
|
222
|
+
- **Lazy Loading**: Images loaded on demand
|
|
223
|
+
- **Optimized Thumbnails**: Smaller file sizes for gallery view
|
|
224
|
+
- **Efficient Rendering**: Minimized re-renders
|
|
225
|
+
- **Memory Management**: Proper cleanup of resources
|
|
226
|
+
|
|
227
|
+
### User Experience Metrics
|
|
228
|
+
- **Faster Uploads**: Optimized upload process
|
|
229
|
+
- **Better Responsiveness**: Smooth interactions
|
|
230
|
+
- **Improved Accessibility**: WCAG compliance
|
|
231
|
+
- **Mobile Performance**: Optimized for mobile devices
|
|
232
|
+
|
|
233
|
+
## 🔮 Future Enhancements
|
|
234
|
+
|
|
235
|
+
### Planned Features
|
|
236
|
+
- **Virtual Scrolling**: For large image collections
|
|
237
|
+
- **Image Editing**: Basic editing capabilities
|
|
238
|
+
- **Cloud Storage**: Direct cloud storage integration
|
|
239
|
+
- **Batch Operations**: Multiple image operations
|
|
240
|
+
- **Advanced Search**: Image search and filtering
|
|
241
|
+
|
|
242
|
+
### Potential Improvements
|
|
243
|
+
- **WebP Support**: Modern image format support
|
|
244
|
+
- **Progressive Loading**: Better loading experience
|
|
245
|
+
- **Offline Support**: PWA capabilities
|
|
246
|
+
- **Analytics**: Usage tracking and insights
|
|
247
|
+
|
|
248
|
+
## 🏁 Conclusion
|
|
249
|
+
|
|
250
|
+
The GoalImageGallery component has been successfully enhanced with:
|
|
251
|
+
|
|
252
|
+
1. **Modern UI/UX** following Material Design 3 principles
|
|
253
|
+
2. **Multi-method upload** supporting file, clipboard, and URL uploads
|
|
254
|
+
3. **Comprehensive accessibility** features
|
|
255
|
+
4. **Mobile optimization** for all devices
|
|
256
|
+
5. **Complete documentation** suite
|
|
257
|
+
6. **Backward compatibility** with existing implementations
|
|
258
|
+
|
|
259
|
+
The component is now ready for production use and provides a superior user experience while maintaining developer-friendly APIs and comprehensive documentation.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Gonzalo Melgarejo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/MIGRATION.md
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
# GoalImageGallery Migration Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This guide helps you migrate from older image gallery components to the new enhanced `GoalImageGallery` component.
|
|
6
|
+
|
|
7
|
+
## Migration Scenarios
|
|
8
|
+
|
|
9
|
+
### 1. From CommonImageGallery
|
|
10
|
+
|
|
11
|
+
#### Before
|
|
12
|
+
```javascript
|
|
13
|
+
import { CommonImageGallery } from './components/common/common-image-gallery';
|
|
14
|
+
|
|
15
|
+
<CommonImageGallery
|
|
16
|
+
photos={photos}
|
|
17
|
+
sizeImage="200px"
|
|
18
|
+
canEdit={true}
|
|
19
|
+
onSelectImage={handleImageSelect}
|
|
20
|
+
/>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
#### After
|
|
24
|
+
```javascript
|
|
25
|
+
import GoalImageGallery from './components/common/goal-image-gallery';
|
|
26
|
+
|
|
27
|
+
<GoalImageGallery
|
|
28
|
+
imageCodes={photos.map(p => p.image_code)}
|
|
29
|
+
canEdit={true}
|
|
30
|
+
ownerEntity={{ id: entityId, type: 'entity' }}
|
|
31
|
+
imageHandlerApi={handleImageUpload}
|
|
32
|
+
afterUpload={refreshData}
|
|
33
|
+
multiple={true}
|
|
34
|
+
/>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Changes Required
|
|
38
|
+
- Replace `photos` array with `imageCodes` array
|
|
39
|
+
- Add `ownerEntity` object with entity information
|
|
40
|
+
- Replace `onSelectImage` with `imageHandlerApi` for uploads
|
|
41
|
+
- Add `afterUpload` callback for refresh logic
|
|
42
|
+
- Remove `sizeImage` prop (now responsive)
|
|
43
|
+
|
|
44
|
+
### 2. From Basic Image Display
|
|
45
|
+
|
|
46
|
+
#### Before
|
|
47
|
+
```javascript
|
|
48
|
+
<div className="image-gallery">
|
|
49
|
+
{images.map(image => (
|
|
50
|
+
<img
|
|
51
|
+
key={image.id}
|
|
52
|
+
src={image.url}
|
|
53
|
+
alt={image.title}
|
|
54
|
+
onClick={() => openModal(image)}
|
|
55
|
+
/>
|
|
56
|
+
))}
|
|
57
|
+
</div>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#### After
|
|
61
|
+
```javascript
|
|
62
|
+
<GoalImageGallery
|
|
63
|
+
imageCodes={images.map(img => img.code)}
|
|
64
|
+
canEdit={false}
|
|
65
|
+
showImageInfo={true}
|
|
66
|
+
/>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Changes Required
|
|
70
|
+
- Convert image URLs to image codes
|
|
71
|
+
- Remove manual modal handling (built-in)
|
|
72
|
+
- Remove custom CSS (uses Material-UI)
|
|
73
|
+
- Add proper prop structure
|
|
74
|
+
|
|
75
|
+
### 3. From react-photo-gallery
|
|
76
|
+
|
|
77
|
+
#### Before
|
|
78
|
+
```javascript
|
|
79
|
+
import Gallery from 'react-photo-gallery';
|
|
80
|
+
import Lightbox from 'react-images';
|
|
81
|
+
|
|
82
|
+
<Gallery
|
|
83
|
+
photos={photos}
|
|
84
|
+
onClick={openLightbox}
|
|
85
|
+
/>
|
|
86
|
+
<Lightbox
|
|
87
|
+
images={photos}
|
|
88
|
+
onClose={closeLightbox}
|
|
89
|
+
isOpen={lightboxIsOpen}
|
|
90
|
+
/>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### After
|
|
94
|
+
```javascript
|
|
95
|
+
<GoalImageGallery
|
|
96
|
+
imageCodes={photos.map(p => p.image_code)}
|
|
97
|
+
canEdit={true}
|
|
98
|
+
ownerEntity={{ id: entityId }}
|
|
99
|
+
imageHandlerApi={handleUpload}
|
|
100
|
+
afterUpload={refreshData}
|
|
101
|
+
multiple={true}
|
|
102
|
+
/>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### Changes Required
|
|
106
|
+
- Remove separate Lightbox component
|
|
107
|
+
- Convert photo format to image codes
|
|
108
|
+
- Add upload functionality
|
|
109
|
+
- Remove manual state management
|
|
110
|
+
|
|
111
|
+
### 4. From ImageUploader Components
|
|
112
|
+
|
|
113
|
+
#### Before
|
|
114
|
+
```javascript
|
|
115
|
+
import { ImageUploader } from './components/common/image-uploader';
|
|
116
|
+
|
|
117
|
+
<ImageUploader
|
|
118
|
+
objType={objType}
|
|
119
|
+
docEntry={docEntry}
|
|
120
|
+
maxFiles={10}
|
|
121
|
+
onUpload={handleUpload}
|
|
122
|
+
/>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### After
|
|
126
|
+
```javascript
|
|
127
|
+
<GoalImageGallery
|
|
128
|
+
imageCodes={existingImages}
|
|
129
|
+
canEdit={true}
|
|
130
|
+
ownerEntity={{ id: docEntry, type: objType }}
|
|
131
|
+
imageHandlerApi={handleUpload}
|
|
132
|
+
afterUpload={refreshData}
|
|
133
|
+
multiple={true}
|
|
134
|
+
/>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### Changes Required
|
|
138
|
+
- Combine display and upload functionality
|
|
139
|
+
- Update prop structure
|
|
140
|
+
- Modify upload handler to return proper format
|
|
141
|
+
|
|
142
|
+
## Data Format Changes
|
|
143
|
+
|
|
144
|
+
### Photo/Image Object Format
|
|
145
|
+
|
|
146
|
+
#### Old Format
|
|
147
|
+
```javascript
|
|
148
|
+
const photos = [
|
|
149
|
+
{
|
|
150
|
+
id: 1,
|
|
151
|
+
src: 'https://example.com/image1.jpg',
|
|
152
|
+
width: 800,
|
|
153
|
+
height: 600,
|
|
154
|
+
title: 'Image 1'
|
|
155
|
+
}
|
|
156
|
+
];
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### New Format
|
|
160
|
+
```javascript
|
|
161
|
+
const imageCodes = ['img_code_1', 'img_code_2'];
|
|
162
|
+
// OR
|
|
163
|
+
const imageCodes = 'img_code_1,img_code_2';
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Upload Handler Format
|
|
167
|
+
|
|
168
|
+
#### Old Format
|
|
169
|
+
```javascript
|
|
170
|
+
const handleUpload = async (files) => {
|
|
171
|
+
const uploaded = await uploadFiles(files);
|
|
172
|
+
setImages(prev => [...prev, ...uploaded]);
|
|
173
|
+
};
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### New Format
|
|
177
|
+
```javascript
|
|
178
|
+
const handleUpload = async (imageData) => {
|
|
179
|
+
try {
|
|
180
|
+
const response = await api.uploadImage(imageData);
|
|
181
|
+
return {
|
|
182
|
+
success: true,
|
|
183
|
+
data: response.data,
|
|
184
|
+
message: 'Upload successful'
|
|
185
|
+
};
|
|
186
|
+
} catch (error) {
|
|
187
|
+
return {
|
|
188
|
+
success: false,
|
|
189
|
+
message: error.message
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## API Changes
|
|
196
|
+
|
|
197
|
+
### Upload API Structure
|
|
198
|
+
|
|
199
|
+
#### Old API Call
|
|
200
|
+
```javascript
|
|
201
|
+
const uploadImage = async (file) => {
|
|
202
|
+
const formData = new FormData();
|
|
203
|
+
formData.append('file', file);
|
|
204
|
+
|
|
205
|
+
const response = await fetch('/api/upload', {
|
|
206
|
+
method: 'POST',
|
|
207
|
+
body: formData
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
return response.json();
|
|
211
|
+
};
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### New API Call
|
|
215
|
+
```javascript
|
|
216
|
+
const handleImageUpload = async (imageData) => {
|
|
217
|
+
const response = await goalMediaApi.submitImage({
|
|
218
|
+
values: {
|
|
219
|
+
data: imageData.base64,
|
|
220
|
+
name: imageData.name,
|
|
221
|
+
type: imageData.type,
|
|
222
|
+
application: 'GOAL',
|
|
223
|
+
folder: 'uploads',
|
|
224
|
+
owner: account.userName
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
success: response.success,
|
|
230
|
+
data: response.data,
|
|
231
|
+
message: response.message
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Step-by-Step Migration
|
|
237
|
+
|
|
238
|
+
### Step 1: Install Dependencies
|
|
239
|
+
```bash
|
|
240
|
+
# Ensure you have required dependencies
|
|
241
|
+
npm install @mui/material @mui/icons-material
|
|
242
|
+
npm install react-dropzone
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Step 2: Update Imports
|
|
246
|
+
```javascript
|
|
247
|
+
// Remove old imports
|
|
248
|
+
// import { CommonImageGallery } from './common-image-gallery';
|
|
249
|
+
// import Gallery from 'react-photo-gallery';
|
|
250
|
+
|
|
251
|
+
// Add new import
|
|
252
|
+
import GoalImageGallery from './components/common/goal-image-gallery';
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Step 3: Convert Data Format
|
|
256
|
+
```javascript
|
|
257
|
+
// Convert your existing data
|
|
258
|
+
const convertPhotosToImageCodes = (photos) => {
|
|
259
|
+
return photos.map(photo => photo.image_code || photo.id);
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const imageCodes = convertPhotosToImageCodes(existingPhotos);
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Step 4: Update Component Usage
|
|
266
|
+
```javascript
|
|
267
|
+
// Old component
|
|
268
|
+
<OldImageGallery
|
|
269
|
+
photos={photos}
|
|
270
|
+
onUpload={handleUpload}
|
|
271
|
+
canEdit={canEdit}
|
|
272
|
+
/>
|
|
273
|
+
|
|
274
|
+
// New component
|
|
275
|
+
<GoalImageGallery
|
|
276
|
+
imageCodes={imageCodes}
|
|
277
|
+
canEdit={canEdit}
|
|
278
|
+
ownerEntity={{ id: entityId, type: 'entity' }}
|
|
279
|
+
imageHandlerApi={handleNewUpload}
|
|
280
|
+
afterUpload={refreshData}
|
|
281
|
+
multiple={true}
|
|
282
|
+
/>
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Step 5: Update Upload Handler
|
|
286
|
+
```javascript
|
|
287
|
+
// Update your upload handler
|
|
288
|
+
const handleNewUpload = async (imageData) => {
|
|
289
|
+
try {
|
|
290
|
+
// Your existing upload logic
|
|
291
|
+
const result = await uploadToServer(imageData);
|
|
292
|
+
|
|
293
|
+
// Return required format
|
|
294
|
+
return {
|
|
295
|
+
success: true,
|
|
296
|
+
data: { code: result.imageCode },
|
|
297
|
+
message: 'Upload successful'
|
|
298
|
+
};
|
|
299
|
+
} catch (error) {
|
|
300
|
+
return {
|
|
301
|
+
success: false,
|
|
302
|
+
message: error.message
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Step 6: Update State Management
|
|
309
|
+
```javascript
|
|
310
|
+
// Update your state management
|
|
311
|
+
const [images, setImages] = useState([]);
|
|
312
|
+
|
|
313
|
+
const refreshData = (result) => {
|
|
314
|
+
// Update your state with new image
|
|
315
|
+
setImages(prev => [...prev, result.data.code]);
|
|
316
|
+
};
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Common Migration Issues
|
|
320
|
+
|
|
321
|
+
### Issue 1: Image URLs vs Image Codes
|
|
322
|
+
**Problem**: Old components used direct image URLs
|
|
323
|
+
**Solution**: Convert URLs to image codes using your backend API
|
|
324
|
+
|
|
325
|
+
```javascript
|
|
326
|
+
// Convert URL to code
|
|
327
|
+
const getImageCodeFromUrl = (url) => {
|
|
328
|
+
return url.split('/').pop().split('.')[0];
|
|
329
|
+
};
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Issue 2: Different Upload Response Format
|
|
333
|
+
**Problem**: Old upload handlers returned different formats
|
|
334
|
+
**Solution**: Wrap existing handlers to return required format
|
|
335
|
+
|
|
336
|
+
```javascript
|
|
337
|
+
const wrapOldUploadHandler = (oldHandler) => {
|
|
338
|
+
return async (imageData) => {
|
|
339
|
+
try {
|
|
340
|
+
const result = await oldHandler(imageData);
|
|
341
|
+
return {
|
|
342
|
+
success: true,
|
|
343
|
+
data: { code: result.id },
|
|
344
|
+
message: 'Upload successful'
|
|
345
|
+
};
|
|
346
|
+
} catch (error) {
|
|
347
|
+
return {
|
|
348
|
+
success: false,
|
|
349
|
+
message: error.message
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Issue 3: State Management Changes
|
|
357
|
+
**Problem**: Component now manages its own state
|
|
358
|
+
**Solution**: Use callbacks to sync external state
|
|
359
|
+
|
|
360
|
+
```javascript
|
|
361
|
+
const [externalImages, setExternalImages] = useState([]);
|
|
362
|
+
|
|
363
|
+
const syncWithExternalState = (result) => {
|
|
364
|
+
setExternalImages(prev => [...prev, result.data.code]);
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
<GoalImageGallery
|
|
368
|
+
imageCodes={externalImages}
|
|
369
|
+
afterUpload={syncWithExternalState}
|
|
370
|
+
// ... other props
|
|
371
|
+
/>
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Testing After Migration
|
|
375
|
+
|
|
376
|
+
### 1. Visual Testing
|
|
377
|
+
- [ ] Images display correctly
|
|
378
|
+
- [ ] Gallery layout is responsive
|
|
379
|
+
- [ ] Hover effects work
|
|
380
|
+
- [ ] Modal viewer opens/closes
|
|
381
|
+
|
|
382
|
+
### 2. Functionality Testing
|
|
383
|
+
- [ ] File upload works
|
|
384
|
+
- [ ] Clipboard paste works (if supported)
|
|
385
|
+
- [ ] URL loading works
|
|
386
|
+
- [ ] Image deletion works
|
|
387
|
+
- [ ] Download functionality works
|
|
388
|
+
|
|
389
|
+
### 3. Accessibility Testing
|
|
390
|
+
- [ ] Keyboard navigation works
|
|
391
|
+
- [ ] Screen reader compatibility
|
|
392
|
+
- [ ] Focus management
|
|
393
|
+
- [ ] ARIA labels present
|
|
394
|
+
|
|
395
|
+
### 4. Performance Testing
|
|
396
|
+
- [ ] Large galleries load quickly
|
|
397
|
+
- [ ] Memory usage is reasonable
|
|
398
|
+
- [ ] No memory leaks
|
|
399
|
+
- [ ] Smooth animations
|
|
400
|
+
|
|
401
|
+
## Rollback Plan
|
|
402
|
+
|
|
403
|
+
If you need to rollback:
|
|
404
|
+
|
|
405
|
+
1. Keep old components until migration is complete
|
|
406
|
+
2. Use feature flags to switch between old/new
|
|
407
|
+
3. Test thoroughly before removing old code
|
|
408
|
+
4. Document any custom modifications
|
|
409
|
+
|
|
410
|
+
```javascript
|
|
411
|
+
// Feature flag approach
|
|
412
|
+
const useNewGallery = process.env.REACT_APP_NEW_GALLERY === 'true';
|
|
413
|
+
|
|
414
|
+
return useNewGallery ? (
|
|
415
|
+
<GoalImageGallery {...newProps} />
|
|
416
|
+
) : (
|
|
417
|
+
<OldImageGallery {...oldProps} />
|
|
418
|
+
);
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## Support
|
|
422
|
+
|
|
423
|
+
For migration support:
|
|
424
|
+
- Check the documentation
|
|
425
|
+
- Review the examples
|
|
426
|
+
- Test with small datasets first
|
|
427
|
+
- Verify API compatibility
|
|
428
|
+
- Update error handling
|