121 lines
4.1 KiB
Markdown
121 lines
4.1 KiB
Markdown
# Laravel Image Cropper Installation Summary
|
||
|
||
## Package Installed
|
||
- **Package**: `takeone/cropper` from https://git.innovator.bh/ghassan/laravel-image-cropper
|
||
- **Version**: dev-main
|
||
- **Installation Date**: January 26, 2026
|
||
|
||
## Changes Made
|
||
|
||
### 1. composer.json
|
||
- Added VCS repository for the package
|
||
- Installed `takeone/cropper:@dev`
|
||
|
||
### 2. resources/views/layouts/app.blade.php
|
||
- Added `@stack('modals')` before closing `</body>` tag
|
||
- This allows the cropper modal to be injected into the page
|
||
|
||
### 3. resources/views/family/profile-edit.blade.php
|
||
- Replaced the old `<x-image-upload-modal>` component with `<x-takeone-cropper>`
|
||
- Configured cropper with:
|
||
- **ID**: `profile_picture`
|
||
- **Width**: 300px
|
||
- **Height**: 400px (portrait rectangle - 3:4 ratio)
|
||
- **Shape**: `square` (rectangle viewport)
|
||
- **Folder**: `images/profiles`
|
||
- **Filename**: `profile_{user_id}`
|
||
- **Upload URL**: Custom route `profile.upload-picture`
|
||
- Added image display logic to show current profile picture or placeholder
|
||
|
||
### 4. app/Http/Controllers/FamilyController.php
|
||
- Updated `uploadProfilePicture()` method to handle base64 image data from cropper
|
||
- Method now:
|
||
- Accepts base64 image data instead of file upload
|
||
- Decodes and saves the cropped image
|
||
- Updates user's `profile_picture` field in database
|
||
- Returns JSON response with success status and image path
|
||
|
||
### 5. resources/views/vendor/takeone/components/widget.blade.php
|
||
- Published and customized the package's widget component
|
||
- Added support for custom `uploadUrl` parameter
|
||
- Added page reload after successful upload to display new image
|
||
- Improved error handling with detailed error messages
|
||
|
||
### 6. Storage
|
||
- Ran `php artisan storage:link` to link public storage
|
||
|
||
## How It Works
|
||
|
||
1. User clicks "Change Photo" button on profile edit page
|
||
2. Modal popup appears with file selector
|
||
3. User selects an image file
|
||
4. Cropme.js library loads the image in a cropping interface
|
||
5. User can:
|
||
- Zoom in/out using slider
|
||
- Rotate image using slider
|
||
- Pan/move image within the viewport
|
||
6. Cropping viewport is set to 300x400px (portrait rectangle)
|
||
7. User clicks "Crop & Save Image"
|
||
8. Image is cropped to base64 format
|
||
9. AJAX POST request sent to `/profile/upload-picture`
|
||
10. FamilyController processes the base64 image:
|
||
- Decodes base64 data
|
||
- Saves to `storage/app/public/images/profiles/profile_{user_id}.{ext}`
|
||
- Deletes old profile picture if exists
|
||
- Updates user's `profile_picture` field
|
||
11. Page reloads to display the new profile picture
|
||
|
||
## File Locations
|
||
|
||
- **Uploaded Images**: `storage/app/public/images/profiles/`
|
||
- **Public Access**: `public/storage/images/profiles/` (via symlink)
|
||
- **Database Field**: `users.profile_picture`
|
||
|
||
## Portrait Rectangle Configuration
|
||
|
||
The cropper is configured for portrait orientation:
|
||
- **Aspect Ratio**: 3:4 (300px width × 400px height)
|
||
- **Shape**: `square` (rectangle viewport, not circular)
|
||
- **Viewport**: Displays as a rectangle overlay on the image
|
||
|
||
## Testing Checklist
|
||
|
||
- [x] Package installed successfully
|
||
- [x] Storage linked
|
||
- [x] Modal stack added to layout
|
||
- [x] Cropper component integrated
|
||
- [x] Custom upload route configured
|
||
- [x] Controller method updated
|
||
- [ ] Test image upload
|
||
- [ ] Verify cropped image saves correctly
|
||
- [ ] Confirm image displays after upload
|
||
- [ ] Test portrait rectangle cropping
|
||
- [ ] Verify old images are deleted
|
||
|
||
## Next Steps
|
||
|
||
1. Navigate to http://localhost:8000/profile/edit
|
||
2. Click "Change Photo" button
|
||
3. Select an image
|
||
4. Crop in portrait rectangle shape
|
||
5. Save and verify the image appears correctly
|
||
|
||
## Troubleshooting
|
||
|
||
If the cropper doesn't appear:
|
||
- Check browser console for JavaScript errors
|
||
- Verify `@stack('modals')` is in layout
|
||
- Ensure jQuery is loaded before the cropper script
|
||
|
||
If upload fails:
|
||
- Check `storage/app/public/images/profiles/` directory exists
|
||
- Verify storage is linked: `php artisan storage:link`
|
||
- Check file permissions on storage directory
|
||
- Review Laravel logs in `storage/logs/`
|
||
|
||
## Package Documentation
|
||
|
||
For more details, see:
|
||
- Package README: `vendor/takeone/cropper/README.md`
|
||
- Package Example: `vendor/takeone/cropper/EXAMPLE.md`
|