groupBy('category') ->map(function ($items) { return $items->map(function ($item) { return [ 'id' => $item->id, 'name' => $item->name, 'photo' => $item->photo, 'category' => $item->category ]; }); }); return $specializations; } /** * Register pelanggan */ public function registerPelanggan(Request $request) { try { $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8', 'phone_number' => 'required|string|max:15', 'address' => 'required|string|max:500', 'preferred_specializations' => 'nullable|array', 'preferred_specializations.*' => 'exists:tailor_specializations,id', 'latitude' => 'required|numeric|between:-90,90', 'longitude' => 'required|numeric|between:-180,180' ]); if ($validator->fails()) { return $this->sendError('Error validasi.', $validator->errors(), 422); } $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), 'role' => 'pelanggan', 'phone_number' => $request->phone_number, 'address' => $request->address, 'latitude' => $request->latitude, 'longitude' => $request->longitude ]); if ($request->has('preferred_specializations') && !empty($request->preferred_specializations)) { $user->preferredSpecializations()->attach($request->preferred_specializations); } // Send verification email $user->sendEmailVerificationNotification(); $token = $user->createToken('auth_token', ['pelanggan'])->plainTextToken; // Get all specializations with photos $specializations = $this->getSpecializationData(); return $this->sendResponse([ 'user' => $user, 'access_token' => $token, 'token_type' => 'Bearer', 'specializations' => $specializations, 'selected_specializations' => $user->preferredSpecializations ], 'Registrasi pelanggan berhasil. Silakan cek email Anda untuk verifikasi.'); } catch (\Exception $e) { return $this->sendError('Error registrasi.', ['error' => $e->getMessage()], 500); } } /** * Register penjahit */ public function registerPenjahit(Request $request) { try { $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8', 'phone_number' => 'required|string|max:15', 'address' => 'required|string|max:500', 'shop_description' => 'required|string|max:1000', 'specializations' => 'required|array|min:1', 'specializations.*' => 'exists:tailor_specializations,id', 'latitude' => 'required|numeric|between:-90,90', 'longitude' => 'required|numeric|between:-180,180' ]); if ($validator->fails()) { return $this->sendError('Error validasi.', $validator->errors(), 422); } $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), 'role' => 'penjahit', 'phone_number' => $request->phone_number, 'address' => $request->address, 'latitude' => $request->latitude, 'longitude' => $request->longitude, 'shop_description' => $request->shop_description ]); // Attach specializations $user->specializations()->attach($request->specializations); // Send verification email $user->sendEmailVerificationNotification(); $token = $user->createToken('auth_token', ['penjahit'])->plainTextToken; return $this->sendResponse([ 'user' => $user, 'access_token' => $token, 'token_type' => 'Bearer' ], 'Registrasi penjahit berhasil. Silakan cek email Anda untuk verifikasi.'); } catch (\Exception $e) { return $this->sendError('Error.', ['error' => 'Terjadi kesalahan saat registrasi'], 500); } } /** * Login pelanggan */ public function loginPelanggan(Request $request) { try { $validator = Validator::make($request->all(), [ 'email' => 'required|email', 'password' => 'required' ]); if ($validator->fails()) { return $this->sendError('Error validasi.', $validator->errors(), 422); } if (!Auth::attempt($request->only('email', 'password'))) { return $this->sendError('Unauthorized.', ['error' => 'Email atau password salah'], 401); } $user = Auth::user(); // Check if user is pelanggan if (!$user->isPelanggan()) { Auth::logout(); return $this->sendError('Unauthorized.', ['error' => 'Akun ini bukan akun pelanggan'], 401); } // Check if email is verified if (!$user->hasVerifiedEmail()) { // Resend verification email $user->sendEmailVerificationNotification(); Auth::logout(); return $this->sendError('Unauthorized.', [ 'error' => 'Email belum diverifikasi. Kami telah mengirim ulang email verifikasi ke ' . $user->email ], 401); } $token = $user->createToken('auth_token', ['pelanggan'])->plainTextToken; // Get all specializations with photos $specializations = $this->getSpecializationData(); return $this->sendResponse([ 'user' => $user, 'access_token' => $token, 'token_type' => 'Bearer', 'specializations' => $specializations, 'selected_specializations' => $user->preferredSpecializations ], 'Login pelanggan berhasil.'); } catch (\Exception $e) { return $this->sendError('Error login.', ['error' => $e->getMessage()], 500); } } /** * Login penjahit */ public function loginPenjahit(Request $request) { try { $validator = Validator::make($request->all(), [ 'email' => 'required|email', 'password' => 'required|string' ]); if ($validator->fails()) { return $this->sendError('Error validasi.', $validator->errors(), 422); } if (!Auth::attempt($request->only('email', 'password'))) { return $this->sendError('Unauthorized.', ['error' => 'Email atau password salah'], 401); } $user = User::where('email', $request->email)->firstOrFail(); if ($user->role !== 'penjahit') { return $this->sendError('Unauthorized.', ['error' => 'Akun ini bukan akun penjahit'], 401); } // Check if email is verified if (!$user->hasVerifiedEmail()) { // Resend verification email $user->sendEmailVerificationNotification(); Auth::logout(); return $this->sendError('Unauthorized.', [ 'error' => 'Email belum diverifikasi. Kami telah mengirim ulang email verifikasi ke ' . $user->email ], 401); } $token = $user->createToken('auth_token', ['penjahit'])->plainTextToken; return $this->sendResponse([ 'user' => $user, 'access_token' => $token, 'token_type' => 'Bearer' ], 'Login penjahit berhasil'); } catch (\Exception $e) { return $this->sendError('Error.', ['error' => 'Terjadi kesalahan saat login'], 500); } } /** * Login admin */ public function loginAdmin(Request $request) { try { $validator = Validator::make($request->all(), [ 'email' => 'required|email', 'password' => 'required' ]); if ($validator->fails()) { return $this->sendError('Error validasi.', $validator->errors(), 422); } if (!Auth::attempt($request->only('email', 'password'))) { return $this->sendError('Unauthorized.', ['error' => 'Email atau password salah'], 401); } $user = Auth::user(); if (!$user->isAdmin()) { Auth::logout(); return $this->sendError('Unauthorized.', ['error' => 'Akun ini bukan akun admin'], 401); } $token = $user->createToken('auth_token', ['admin'])->plainTextToken; return $this->sendResponse([ 'user' => $user, 'access_token' => $token, 'token_type' => 'Bearer' ], 'Login admin berhasil.'); } catch (\Exception $e) { return $this->sendError('Error login.', ['error' => $e->getMessage()], 500); } } /** * Logout user */ public function logout() { try { auth()->user()->tokens()->delete(); return $this->sendResponse([], 'Logout berhasil'); } catch (\Exception $e) { return $this->sendError('Error.', ['error' => 'Terjadi kesalahan saat logout'], 500); } } /** * Get user profile */ public function profile() { try { $user = Auth::user(); if ($user->role === 'penjahit') { $user->load('specializations'); } return $this->sendResponse($user, 'Data profil berhasil diambil'); } catch (\Exception $e) { return $this->sendError('Error.', ['error' => 'Terjadi kesalahan saat mengambil profil'], 500); } } /** * Get all specializations */ public function getSpecializations() { try { $specializations = \App\Models\TailorSpecialization::all(); return $this->sendResponse($specializations, 'Data spesialisasi berhasil diambil'); } catch (\Exception $e) { return $this->sendError('Error.', ['error' => 'Terjadi kesalahan saat mengambil data spesialisasi'], 500); } } /** * Upload foto profil */ public function uploadProfilePhoto(Request $request) { try { $validator = Validator::make($request->all(), [ 'profile_photo' => 'required|image|mimes:jpeg,png,jpg|max:2048' ]); if ($validator->fails()) { return $this->sendError('Error validasi.', $validator->errors(), 422); } $user = Auth::user(); // Hapus foto profil lama jika ada if ($user->profile_photo) { $oldPhotoPath = str_replace('/storage/', '', $user->profile_photo); if (Storage::disk('public')->exists($oldPhotoPath)) { Storage::disk('public')->delete($oldPhotoPath); } } // Upload dan simpan foto baru $photo = $request->file('profile_photo'); $fileName = time() . '_' . $user->id . '.' . $photo->getClientOriginalExtension(); $photo->storeAs('profile_photos', $fileName, 'public'); // Update path foto di database $user->profile_photo = '/storage/profile_photos/' . $fileName; $user->save(); return $this->sendResponse([ 'profile_photo' => $user->profile_photo ], 'Foto profil berhasil diupload.'); } catch (\Exception $e) { return $this->sendError('Error upload foto.', ['error' => $e->getMessage()], 500); } } /** * Update user profile */ public function updateProfile(Request $request) { try { $user = Auth::user(); // Different validation rules based on user role $validationRules = [ 'name' => 'string|max:255', 'phone_number' => 'string|max:15', 'address' => 'string|max:500', 'current_password' => 'string', 'new_password' => 'string|min:8|confirmed', ]; // Add penjahit specific validation rules if ($user->isPenjahit()) { $validationRules['shop_description'] = 'string|max:1000'; $validationRules['specializations'] = 'array'; $validationRules['specializations.*'] = 'exists:tailor_specializations,id'; } // Add pelanggan specific validation rules if ($user->isPelanggan()) { $validationRules['preferred_specializations'] = 'array'; $validationRules['preferred_specializations.*'] = 'exists:tailor_specializations,id'; $validationRules['latitude'] = 'numeric|between:-90,90'; $validationRules['longitude'] = 'numeric|between:-180,180'; } $validator = Validator::make($request->all(), $validationRules); if ($validator->fails()) { return $this->sendError('Error validasi.', $validator->errors(), 422); } // Check if password update is requested if ($request->has('current_password') && $request->has('new_password')) { // Verify current password if (!Hash::check($request->current_password, $user->password)) { return $this->sendError('Error validasi.', ['current_password' => 'Password saat ini tidak sesuai'], 422); } // Update to new password $user->password = Hash::make($request->new_password); } // Update basic profile fields if ($request->has('name')) { $user->name = $request->name; } if ($request->has('phone_number')) { $user->phone_number = $request->phone_number; } if ($request->has('address')) { $user->address = $request->address; } // Update penjahit specific fields if ($user->isPenjahit()) { if ($request->has('shop_description')) { $user->shop_description = $request->shop_description; } // Update specializations if provided if ($request->has('specializations')) { $user->specializations()->sync($request->specializations); } } // Update pelanggan specific fields if ($user->isPelanggan()) { if ($request->has('latitude')) { $user->latitude = $request->latitude; } if ($request->has('longitude')) { $user->longitude = $request->longitude; } // Update preferred specializations if provided if ($request->has('preferred_specializations')) { $user->preferredSpecializations()->sync($request->preferred_specializations); } } $user->save(); // Load relationships based on user role if ($user->isPenjahit()) { $user->load('specializations'); } elseif ($user->isPelanggan()) { $user->load('preferredSpecializations'); } return $this->sendResponse($user, 'Profil berhasil diperbarui'); } catch (\Exception $e) { return $this->sendError('Error.', ['error' => 'Terjadi kesalahan saat memperbarui profil: ' . $e->getMessage()], 500); } } }