MIF_E31221305/TA_API/app/Http/Controllers/Api/AuthController.php

480 lines
17 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Models\User;
use App\Models\TailorSpecialization;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class AuthController extends BaseController
{
/**
* Get specialization data with photos
*/
private function getSpecializationData()
{
$specializations = \App\Models\TailorSpecialization::all()
->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);
}
}
}