added the cropping library
This commit is contained in:
parent
7a18eb6588
commit
2ee4b76599
@ -474,46 +474,51 @@ class FamilyController extends Controller
|
|||||||
public function uploadFamilyMemberPicture(Request $request, $id)
|
public function uploadFamilyMemberPicture(Request $request, $id)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:5120', // 5MB max
|
'image' => 'required',
|
||||||
|
'folder' => 'required|string',
|
||||||
|
'filename' => 'required|string',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user = Auth::user();
|
try {
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
// Verify the family member belongs to the authenticated user
|
// Verify the family member belongs to the authenticated user
|
||||||
$relationship = UserRelationship::where('guardian_user_id', $user->id)
|
$relationship = UserRelationship::where('guardian_user_id', $user->id)
|
||||||
->where('dependent_user_id', $id)
|
->where('dependent_user_id', $id)
|
||||||
->firstOrFail();
|
->firstOrFail();
|
||||||
|
|
||||||
$familyMember = User::findOrFail($id);
|
$familyMember = User::findOrFail($id);
|
||||||
|
|
||||||
if ($request->hasFile('image')) {
|
// Handle base64 image from cropper
|
||||||
$image = $request->file('image');
|
$imageData = $request->image;
|
||||||
|
$imageParts = explode(";base64,", $imageData);
|
||||||
|
$imageTypeAux = explode("image/", $imageParts[0]);
|
||||||
|
$extension = $imageTypeAux[1];
|
||||||
|
$imageBinary = base64_decode($imageParts[1]);
|
||||||
|
|
||||||
// Generate unique filename
|
$folder = trim($request->folder, '/');
|
||||||
$filename = 'profile_' . $familyMember->id . '_' . time() . '.' . $image->getClientOriginalExtension();
|
$fileName = $request->filename . '.' . $extension;
|
||||||
|
$fullPath = $folder . '/' . $fileName;
|
||||||
// Store in public/images/profiles
|
|
||||||
$path = $image->storeAs('images/profiles', $filename, 'public');
|
|
||||||
|
|
||||||
// Delete old profile picture if exists
|
// Delete old profile picture if exists
|
||||||
if ($familyMember->profile_picture && \Storage::disk('public')->exists($familyMember->profile_picture)) {
|
if ($familyMember->profile_picture && \Storage::disk('public')->exists($familyMember->profile_picture)) {
|
||||||
\Storage::disk('public')->delete($familyMember->profile_picture);
|
\Storage::disk('public')->delete($familyMember->profile_picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update family member
|
// Store in the public disk (storage/app/public)
|
||||||
$familyMember->update(['profile_picture' => $path]);
|
\Storage::disk('public')->put($fullPath, $imageBinary);
|
||||||
|
|
||||||
|
// Update family member's profile_picture field
|
||||||
|
$familyMember->update(['profile_picture' => $fullPath]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'message' => 'Profile picture uploaded successfully.',
|
'path' => $fullPath,
|
||||||
'path' => $path,
|
'url' => asset('storage/' . $fullPath)
|
||||||
]);
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json([
|
|
||||||
'success' => false,
|
|
||||||
'message' => 'No image file provided.',
|
|
||||||
], 400);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -20,8 +20,8 @@
|
|||||||
<div class="d-flex align-items-start gap-3">
|
<div class="d-flex align-items-start gap-3">
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<div class="rounded-circle border border-4 border-white shadow" style="width: 80px; height: 80px; overflow: hidden; box-shadow: 0 0 0 2px {{ $relationship->dependent->gender == 'm' ? 'rgba(147, 51, 234, 0.3)' : 'rgba(214, 51, 132, 0.3)' }} !important;">
|
<div class="rounded-circle border border-4 border-white shadow" style="width: 80px; height: 80px; overflow: hidden; box-shadow: 0 0 0 2px {{ $relationship->dependent->gender == 'm' ? 'rgba(147, 51, 234, 0.3)' : 'rgba(214, 51, 132, 0.3)' }} !important;">
|
||||||
@if($relationship->dependent->media_gallery[0] ?? false)
|
@if($relationship->dependent->profile_picture)
|
||||||
<img src="{{ $relationship->dependent->media_gallery[0] }}" alt="{{ $relationship->dependent->full_name }}" class="w-100 h-100" style="object-fit: cover;">
|
<img src="{{ asset('storage/' . $relationship->dependent->profile_picture) }}" alt="{{ $relationship->dependent->full_name }}" class="w-100 h-100" style="object-fit: cover;">
|
||||||
@else
|
@else
|
||||||
<div class="w-100 h-100 d-flex align-items-center justify-content-center text-white fw-bold fs-4" style="background: linear-gradient(135deg, {{ $relationship->dependent->gender == 'm' ? '#8b5cf6 0%, #7c3aed 100%' : '#d63384 0%, #a61e4d 100%' }});">
|
<div class="w-100 h-100 d-flex align-items-center justify-content-center text-white fw-bold fs-4" style="background: linear-gradient(135deg, {{ $relationship->dependent->gender == 'm' ? '#8b5cf6 0%, #7c3aed 100%' : '#d63384 0%, #a61e4d 100%' }});">
|
||||||
{{ strtoupper(substr($relationship->dependent->full_name, 0, 1)) }}
|
{{ strtoupper(substr($relationship->dependent->full_name, 0, 1)) }}
|
||||||
|
|||||||
@ -12,14 +12,27 @@
|
|||||||
<!-- Profile Picture Section -->
|
<!-- Profile Picture Section -->
|
||||||
<div class="mb-4 text-center">
|
<div class="mb-4 text-center">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<img src="{{ $relationship->dependent->profile_picture ? asset('storage/' . $relationship->dependent->profile_picture) : asset('images/default-avatar.png') }}"
|
@if($relationship->dependent->profile_picture)
|
||||||
alt="Profile Picture"
|
<img src="{{ asset('storage/' . $relationship->dependent->profile_picture) }}"
|
||||||
class="rounded-circle"
|
alt="Profile Picture"
|
||||||
style="width: 120px; height: 120px; object-fit: cover; border: 3px solid #dee2e6;">
|
class="rounded-circle"
|
||||||
|
style="width: 120px; height: 120px; object-fit: cover; border: 3px solid #dee2e6;">
|
||||||
|
@else
|
||||||
|
<div class="rounded-circle d-inline-flex align-items-center justify-content-center text-white fw-bold"
|
||||||
|
style="width: 120px; height: 120px; font-size: 3rem; background: linear-gradient(135deg, {{ $relationship->dependent->gender == 'm' ? '#0d6efd 0%, #0a58ca 100%' : '#d63384 0%, #a61e4d 100%' }}); border: 3px solid #dee2e6;">
|
||||||
|
{{ strtoupper(substr($relationship->dependent->full_name, 0, 1)) }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#profilePictureModal">
|
<x-takeone-cropper
|
||||||
<i class="fas fa-camera"></i> Change Profile Picture
|
id="family_member_{{ $relationship->dependent->id }}"
|
||||||
</button>
|
width="300"
|
||||||
|
height="400"
|
||||||
|
shape="square"
|
||||||
|
folder="images/profiles"
|
||||||
|
filename="profile_{{ $relationship->dependent->id }}"
|
||||||
|
uploadUrl="{{ route('family.upload-picture', $relationship->dependent->id) }}"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="POST" action="{{ route('family.update', $relationship->dependent->id) }}">
|
<form method="POST" action="{{ route('family.update', $relationship->dependent->id) }}">
|
||||||
@ -246,14 +259,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Profile Picture Upload Modal -->
|
|
||||||
<x-image-upload-modal
|
|
||||||
id="profilePictureModal"
|
|
||||||
aspectRatio="1"
|
|
||||||
maxSizeMB="1"
|
|
||||||
title="Upload Profile Picture"
|
|
||||||
uploadUrl="{{ route('family.upload-picture', $relationship->dependent->id) }}"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@ -279,6 +279,22 @@
|
|||||||
.nav-icon-btn.dropdown-toggle::after {
|
.nav-icon-btn.dropdown-toggle::after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Vertical alignment fix for navbar items */
|
||||||
|
.navbar-nav {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav .nav-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav .nav-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@stack('styles')
|
@stack('styles')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user