deploy commit
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Filters\V1\AccountFilter;
|
||||
use App\Http\Controllers\Api\Controller;
|
||||
use App\Http\Requests\V1\StoreAccountRequest;
|
||||
use App\Http\Requests\V1\UpdateAccountRequest;
|
||||
use App\Http\Resources\V1\AccountCollection;
|
||||
use App\Http\Resources\V1\AccountResource;
|
||||
use App\Http\Resources\V1\DoctorListResource;
|
||||
use App\Models\Account;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth:sanctum');
|
||||
$this->authorizeResource(Account::class,'account');
|
||||
}
|
||||
public function index(Request $request)
|
||||
{
|
||||
$filter = new AccountFilter();
|
||||
$filterItems = $filter->transform($request);
|
||||
|
||||
$includeSubmissions = $request->query('includeSubmissions');
|
||||
$includeDoctorProfiles = $request->query('includeDoctorProfiles');
|
||||
|
||||
$accounts = Account::where($filterItems);
|
||||
|
||||
if ($includeSubmissions) {
|
||||
$accounts = $accounts->with('submission');
|
||||
}
|
||||
if ($includeDoctorProfiles) {
|
||||
$accounts = $accounts->with('doctorProfile');
|
||||
}
|
||||
return new AccountCollection($accounts->paginate()->appends($request->query()));
|
||||
}
|
||||
|
||||
public function listDoctors(Request $request)
|
||||
{
|
||||
$search = $request->query('search');
|
||||
|
||||
$query = Account::where('role', 'doctor');
|
||||
|
||||
if ($search) {
|
||||
$query->where('name', 'like', "%{$search}%");
|
||||
}
|
||||
|
||||
if ($limit = (int) $request->query('limit', 0)) {
|
||||
$query->limit($limit);
|
||||
}
|
||||
|
||||
$doctors = $query->orderBy('name')->get(['id', 'name']);
|
||||
|
||||
return DoctorListResource::collection($doctors);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function welcome(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$firstName = explode(' ', trim($user->name))[0] ?? $user->name;
|
||||
|
||||
$id = $user->id;
|
||||
$role = ucfirst($user->role);
|
||||
$message = "Welcome back, {$firstName}! (You are logged in as {$role})";
|
||||
|
||||
return response()->json([
|
||||
'accountId' => $id,
|
||||
'message' => $message,
|
||||
'firstName' => $firstName,
|
||||
'role' => $user->role,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(StoreAccountRequest $request)
|
||||
{
|
||||
//
|
||||
return new AccountResource(Account::create($request->all()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Account $account)
|
||||
{
|
||||
//
|
||||
$includeSubmissions = request()->query('includeSubmissions');
|
||||
if ($includeSubmissions) {
|
||||
$account->loadMissing('submission');
|
||||
}
|
||||
$includeDoctorProfiles = request()->query('includeDoctorProfiles');
|
||||
if ($includeDoctorProfiles) {
|
||||
$account->loadMissing('doctorProfile');
|
||||
}
|
||||
return new AccountResource($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(Account $account)
|
||||
{
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(UpdateAccountRequest $request, Account $account)
|
||||
{
|
||||
//
|
||||
$account->update($request->validated());
|
||||
return new AccountResource($account->fresh());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(Account $account)
|
||||
{
|
||||
//
|
||||
$account->delete();
|
||||
return response()->json(['message' => 'Account deleted.']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Api\Controller;
|
||||
use App\Http\Requests\V1\LoginRequest;
|
||||
use App\Http\Requests\V1\RegisterDoctorRequest;
|
||||
use App\Http\Requests\V1\RegisterRequest;
|
||||
use App\Models\Account;
|
||||
use App\Models\DoctorProfile;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
// POST /api/v1/auth/register/doctor
|
||||
public function registerDoctor(RegisterDoctorRequest $request)
|
||||
{
|
||||
|
||||
$acct = Account::create([
|
||||
'name' => $request->name,
|
||||
'email' => $request->email,
|
||||
'phone' => $request->phone,
|
||||
'role' => 'doctor',
|
||||
'password' => Hash::make($request->password),
|
||||
]);
|
||||
|
||||
$licensePath = $request->file('license_file')
|
||||
->store('doctor_profiles/licenses','public');
|
||||
$diplomaPath = $request->file('diploma_file')
|
||||
->store('doctor_profiles/diplomas','public');
|
||||
$certPath = $request->file('certification_file')
|
||||
->store('doctor_profiles/certifications','public');
|
||||
|
||||
$profile = DoctorProfile::create([
|
||||
'user_id' => $acct->id,
|
||||
'specialization' => $request->specialization,
|
||||
'license_number' => $request->license_number,
|
||||
'license_file_path' => $licensePath,
|
||||
'diploma_file_path' => $diplomaPath,
|
||||
'certification_file_path' => $certPath,
|
||||
'current_institution' => $request->current_institution,
|
||||
'work_history' => $request->work_history,
|
||||
'publications' => $request->publications,
|
||||
'practice_address' => $request->practice_address,
|
||||
]);
|
||||
|
||||
$token = $acct->createToken('doctor-token', ['create','update','delete'])->plainTextToken;
|
||||
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'account' => [
|
||||
'id' => $acct->id,
|
||||
'name' => $acct->name,
|
||||
'email' => $acct->email,
|
||||
'phone' => $acct->phone,
|
||||
],
|
||||
'profile' => [
|
||||
'specialization' => $profile->specialization,
|
||||
'licenseNumber' => $profile->license_number,
|
||||
'licenseFileUrl' => asset("storage/{$profile->license_file_path}"),
|
||||
'diplomaFileUrl' => asset("storage/{$profile->diploma_file_path}"),
|
||||
'certificationUrl' => asset("storage/{$profile->certification_file_path}"),
|
||||
'currentInstitution' => $profile->current_institution,
|
||||
'workHistory' => $profile->work_history,
|
||||
'publications' => $profile->publications,
|
||||
'practiceAddress' => $profile->practice_address,
|
||||
],
|
||||
'token' => $token,
|
||||
]
|
||||
], 201);
|
||||
}
|
||||
|
||||
// POST /api/v1/auth/register/patient
|
||||
public function register(RegisterRequest $req)
|
||||
{
|
||||
$data = $req->validated();
|
||||
$data['password'] = Hash::make($data['password']);
|
||||
$data['role'] = 'patient';
|
||||
$account = Account::create($data);
|
||||
|
||||
$token = $account->createToken('auth-token')->plainTextToken;
|
||||
|
||||
return response()->json([
|
||||
'data' => $account,
|
||||
'token' => $token
|
||||
], 201);
|
||||
}
|
||||
|
||||
// POST /api/v1/auth/login
|
||||
public function login(LoginRequest $req)
|
||||
{
|
||||
$creds = $req->validated();
|
||||
$account = Account::where('email', $creds['email'])->first();
|
||||
|
||||
if (!$account || !Hash::check($creds['password'], $account->password)) {
|
||||
return response()->json(['message' => 'Invalid credentials'], 401);
|
||||
}
|
||||
|
||||
$token = $account->createToken('auth-token')->plainTextToken;
|
||||
return response()->json([
|
||||
'data' => $account,
|
||||
'token' => $token
|
||||
]);
|
||||
}
|
||||
|
||||
// POST /api/v1/auth/logout
|
||||
public function logout(Request $req)
|
||||
{
|
||||
// Hapus token yang dipakai saat ini
|
||||
$req->user()->currentAccessToken()->delete();
|
||||
return response()->json(['message'=>'Logged out']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Api\Controller;
|
||||
use App\Http\Resources\V1\SubmissionListResource;
|
||||
use App\Models\Submission;
|
||||
use App\Models\Account;
|
||||
use App\Http\Resources\V1\DashboardStatsResource;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DoctorDashboardController extends Controller
|
||||
{
|
||||
public function stats(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$totalPatients = Submission::where('doctor_id', $user->id)
|
||||
->distinct('patient_id')
|
||||
->count('patient_id');
|
||||
|
||||
$pendingCount = Submission::where('doctor_id', $user->id)
|
||||
->where('status', 'pending')
|
||||
->count();
|
||||
|
||||
$verifiedCount = Submission::where('doctor_id', $user->id)
|
||||
->where('status', 'verified')
|
||||
->count();
|
||||
|
||||
return new DashboardStatsResource(compact(
|
||||
'totalPatients', 'pendingCount', 'verifiedCount'
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
public function pendingVerifications(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
$limit = (int) $request->query('limit', 0);
|
||||
|
||||
$query = Submission::pending()
|
||||
->where('doctor_id', $user->id)
|
||||
->with('patient:id,name')
|
||||
->orderBy('submitted_at', 'desc');
|
||||
|
||||
if ($limit > 0) {
|
||||
$subs = $query->limit($limit)->get();
|
||||
} else {
|
||||
$subs = $query->get();
|
||||
}
|
||||
|
||||
return SubmissionListResource::collection($subs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Api\Controller;
|
||||
use App\Models\Account;
|
||||
use App\Http\Resources\V1\PatientListResource;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DoctorPatientController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$doctorId = $request->user()->id;
|
||||
$limit = (int) $request->query('limit', 0);
|
||||
|
||||
$query = Account::where('role', 'patient')
|
||||
->whereHas('submission', fn($q) => $q->where('doctor_id', $doctorId))
|
||||
->withCount(['submission as submission_count' => fn($q) => $q->where('doctor_id', $doctorId)])
|
||||
->orderBy('name');
|
||||
|
||||
if ($limit > 0) {
|
||||
$patients = $query->limit($limit)->get(['id','name','phone']);
|
||||
} else {
|
||||
$patients = $query->get(['id','name','phone']);
|
||||
}
|
||||
|
||||
return PatientListResource::collection($patients);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Filters\V1\DoctorProfileFilter;
|
||||
use App\Http\Controllers\Api\Controller;
|
||||
use App\Http\Requests\V1\StoreDoctorProfileRequest;
|
||||
use App\Http\Requests\V1\UpdateDoctorProfileRequest;
|
||||
use App\Http\Resources\V1\DoctorProfileCollection;
|
||||
use App\Http\Resources\V1\DoctorProfileResource;
|
||||
use App\Models\DoctorProfile;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DoctorProfileController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth:sanctum');
|
||||
$this->authorizeResource(DoctorProfile::class,'doctorProfile');
|
||||
}
|
||||
public function index(Request $r)
|
||||
{
|
||||
$this->authorize('viewAny', DoctorProfile::class);
|
||||
|
||||
// kalau dokter, return hanya profil dia sendiri:
|
||||
if ($r->user()->role==='doctor') {
|
||||
$p = DoctorProfile::where('user_id',$r->user()->id)->firstOrFail();
|
||||
return new DoctorProfileCollection(collect([$p]));
|
||||
}
|
||||
|
||||
// kalau admin, bisa lihat semua:
|
||||
return new DoctorProfileCollection(DoctorProfile::paginate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(StoreDoctorProfileRequest $request)
|
||||
{
|
||||
//
|
||||
return new DoctorProfileResource(DoctorProfile::create($request->validated()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(DoctorProfile $doctorProfile)
|
||||
{
|
||||
//
|
||||
return new DoctorProfileResource($doctorProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(DoctorProfile $doctorProfile)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(UpdateDoctorProfileRequest $request, DoctorProfile $doctorProfile)
|
||||
{
|
||||
//
|
||||
$doctorProfile->update($request->validated());
|
||||
return new DoctorProfileResource($doctorProfile->fresh());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(DoctorProfile $doctorProfile)
|
||||
{
|
||||
//
|
||||
$doctorProfile->delete();
|
||||
return response()->json(['message' => 'Doctor profile deleted successfully'], 200);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Api\Controller;
|
||||
use App\Http\Requests\V1\DoctorUpdateSubmissionRequest;
|
||||
use App\Http\Resources\V1\DoctorHistorySubmissionResource;
|
||||
use App\Http\Resources\V1\SubmissionResource;
|
||||
use App\Models\Submission;
|
||||
use App\Http\Resources\V1\SubmissionListResource;
|
||||
use App\Http\Resources\V1\SubmissionDetailResource;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DoctorSubmissionController extends Controller
|
||||
{
|
||||
public function update(DoctorUpdateSubmissionRequest $request, Submission $submission)
|
||||
{
|
||||
$this->authorize('update', $submission);
|
||||
|
||||
$valid = $request->validated();
|
||||
|
||||
$data = [
|
||||
'diagnosis' => $valid['diagnosis'],
|
||||
'doctor_note' => $valid['doctorNote'],
|
||||
'doctor_id' => $request->user()->id,
|
||||
'status' => 'verified',
|
||||
'verified_at' => now(),
|
||||
];
|
||||
|
||||
|
||||
$submission->update($data);
|
||||
|
||||
return new SubmissionDetailResource(
|
||||
$submission->fresh()->load('patient')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function pending(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$request->merge(['only_percentage' => true]);
|
||||
|
||||
$subs = Submission::pending()
|
||||
->where('doctor_id', $user->id)
|
||||
->whereHas('patient', function ($q) use ($request) {
|
||||
if ($search = $request->query('search')) {
|
||||
$q->where('name', 'like', "%{$search}%");
|
||||
}
|
||||
})
|
||||
->with('patient:id,name')
|
||||
->orderBy('submitted_at','desc')
|
||||
->get();
|
||||
|
||||
return SubmissionListResource::collection($subs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function history(Request $request)
|
||||
{
|
||||
$this->authorize('viewAny', Submission::class);
|
||||
|
||||
$doctorId = $request->user()->id;
|
||||
$limit = (int) $request->query('limit', 0);
|
||||
|
||||
$query = Submission::where('status', 'verified')
|
||||
->where('doctor_id', $doctorId)
|
||||
->whereHas('patient', function ($q) use ($request) {
|
||||
if ($search = $request->query('search')) {
|
||||
$q->where('name', 'like', "%{$search}%");
|
||||
}
|
||||
})
|
||||
->with('patient:id,name')
|
||||
->orderBy('verified_at', 'desc');
|
||||
|
||||
if ($limit > 0) {
|
||||
$subs = $query->limit($limit)->get();
|
||||
} else {
|
||||
$subs = $query->get();
|
||||
}
|
||||
|
||||
return DoctorHistorySubmissionResource::collection($subs);
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
$sub = Submission::with('patient')
|
||||
->findOrFail($id);
|
||||
|
||||
return new SubmissionDetailResource($sub);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Api\Controller;
|
||||
use App\Http\Requests\V1\PublicDetectionRequest;
|
||||
use App\Services\SkinAiService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PublicDetectionController extends Controller
|
||||
{
|
||||
public function detect(PublicDetectionRequest $request): JsonResponse
|
||||
{
|
||||
$image = $request->file('image');
|
||||
|
||||
$pct = SkinAiService::predict($image);
|
||||
|
||||
$threshold = config('ai.threshold');
|
||||
$labelPos = config('ai.label_positive');
|
||||
$labelNeg = config('ai.label_negative');
|
||||
$label = is_numeric($pct)
|
||||
? ($pct >= $threshold ? $labelPos : $labelNeg)
|
||||
: null;
|
||||
|
||||
return response()->json([
|
||||
'percentage' => $pct,
|
||||
'diagnosisAi' => $label,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Filters\V1\SubmissionFilter;
|
||||
use App\Http\Controllers\Api\Controller;
|
||||
use App\Http\Requests\V1\StoreSubmissionRequest;
|
||||
use App\Http\Requests\V1\UpdateSubmissionRequest;
|
||||
use App\Http\Resources\V1\PatientDetectionDetailResource;
|
||||
use App\Http\Resources\V1\PatientDetectionHistoryResource;
|
||||
use App\Http\Resources\V1\PatientSubmissionDetailResource;
|
||||
use App\Http\Resources\V1\PatientSubmissionHistoryResource;
|
||||
use App\Http\Resources\V1\SubmissionCollection;
|
||||
use App\Http\Resources\V1\SubmissionResource;
|
||||
use App\Models\Submission;
|
||||
use App\Services\SkinAiService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class SubmissionController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth:sanctum');
|
||||
//$this->authorizeResource(Submission::class,'submission');
|
||||
}
|
||||
|
||||
public function pending(Request $request)
|
||||
{
|
||||
$this->authorize('viewAny', Submission::class);
|
||||
|
||||
$query = Submission::with('patient')
|
||||
->where('status', 'pending');
|
||||
|
||||
$subs = $query->paginate()
|
||||
->appends($request->query());
|
||||
|
||||
return new SubmissionCollection($subs);
|
||||
}
|
||||
|
||||
public function history(Request $request)
|
||||
{
|
||||
$this->authorize('viewAny', Submission::class);
|
||||
|
||||
$query = Submission::with('patient')
|
||||
->where('status', '!=', 'pending');
|
||||
|
||||
$subs = $query->paginate()
|
||||
->appends($request->query());
|
||||
|
||||
return new SubmissionCollection($subs);
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('viewAny', Submission::class);
|
||||
|
||||
$filter = new SubmissionFilter();
|
||||
$filterItems = $filter->transform($request);
|
||||
|
||||
$query = Submission::where($filterItems);
|
||||
|
||||
if ($request->user()->role === 'patient') {
|
||||
$query->where('patient_id', $request->user()->id);
|
||||
}
|
||||
|
||||
$statusCounts = (clone $query)
|
||||
->selectRaw('status, count(*) as total')
|
||||
->groupBy('status')
|
||||
->pluck('total', 'status')
|
||||
->toArray();
|
||||
|
||||
$subs = $query
|
||||
->paginate()
|
||||
->appends($request->query());
|
||||
|
||||
return (new SubmissionCollection($subs))
|
||||
->additional(['statusCounts' => $statusCounts]);
|
||||
}
|
||||
|
||||
public function detectionHistory(Request $r)
|
||||
{
|
||||
$user = $r->user();
|
||||
|
||||
//$this->authorize('viewAny', Submission::class);
|
||||
$subs = Submission::where('patient_id',$user->id)
|
||||
->orderBy('submitted_at','desc')->get();
|
||||
|
||||
return PatientDetectionHistoryResource::collection($subs);
|
||||
}
|
||||
|
||||
public function submissionHistory(Request $r)
|
||||
{
|
||||
$user = $r->user();
|
||||
|
||||
$this->authorize('viewAny', Submission::class);
|
||||
$subs = Submission::where('patient_id',$user->id)
|
||||
->where('status','!=','pending')
|
||||
->orderBy('verified_at','desc')->get();
|
||||
|
||||
return PatientSubmissionHistoryResource::collection($subs);
|
||||
}
|
||||
|
||||
public function detectionDetail($id)
|
||||
{
|
||||
$submission = Submission::findOrFail($id);
|
||||
|
||||
$this->authorize('viewAny', $submission);
|
||||
|
||||
return new PatientDetectionDetailResource($submission);
|
||||
}
|
||||
|
||||
public function submissionDetail($id)
|
||||
{
|
||||
$submission = Submission::findOrFail($id);
|
||||
|
||||
$this->authorize('viewAny', $submission);
|
||||
|
||||
return new PatientSubmissionDetailResource($submission);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(StoreSubmissionRequest $request)
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$path = $request->file('image')->store('submissions', 'public');
|
||||
$data['image_path'] = $path;
|
||||
|
||||
$data['submitted_at'] = Carbon::now();
|
||||
|
||||
$percentage = SkinAiService::predict($request->file('image'));
|
||||
$data['percentage'] = $percentage;
|
||||
|
||||
$submission = Submission::create($data);
|
||||
|
||||
return (new SubmissionResource($submission))
|
||||
->response()
|
||||
->setStatusCode(201);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Submission $submission)
|
||||
{
|
||||
//
|
||||
return new SubmissionResource($submission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(Submission $submission)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(UpdateSubmissionRequest $request, Submission $submission)
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
if ($request->has('doctorId')) {
|
||||
$data['doctor_id'] = $request->input('doctorId');
|
||||
}
|
||||
|
||||
// kalau pasien/sudah submit, set is_submitted
|
||||
if (in_array($request->user()->role, ['patient','admin'])) {
|
||||
$data['is_submitted'] = 'Sudah';
|
||||
}
|
||||
|
||||
// untuk dokter/admin saat verifikasi
|
||||
if (in_array($request->user()->role, ['doctor','admin'])
|
||||
&& isset($data['status'])
|
||||
&& $data['status'] === 'verified'
|
||||
&& ! $submission->verified_at
|
||||
) {
|
||||
$data['verified_at'] = now();
|
||||
}
|
||||
|
||||
$submission->update($data);
|
||||
|
||||
return new SubmissionResource($submission->refresh());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(Submission $submission)
|
||||
{
|
||||
$submission->delete();
|
||||
|
||||
return response()->json(['message' => 'Submission deleted'], 200);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Requests\V1\StoreVerificationRequest;
|
||||
use App\Http\Requests\V1\UpdateVerificationRequest;
|
||||
use App\Models\Verification;
|
||||
|
||||
class VerificationController
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(StoreVerificationRequest $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Verification $verification)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(Verification $verification)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(UpdateVerificationRequest $request, Verification $verification)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(Verification $verification)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class DoctorUpdateSubmissionRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'diagnosis' => ['required', Rule::in(['Melanoma', 'Bukan Melanoma'])],
|
||||
'doctorNote' => ['required','string'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class LoginRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'email' => ['required','email'],
|
||||
'password' => ['required'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class PublicDetectionRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'image' => ['required','image','max:2048'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class RegisterDoctorRequest extends FormRequest
|
||||
{
|
||||
public function authorize() { return true; }
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required','string'],
|
||||
'email' => ['required','email','unique:accounts,email'],
|
||||
'phone' => ['required','string','unique:accounts,phone'],
|
||||
'password' => ['required','string','min:8','confirmed'],
|
||||
|
||||
'practice_address' => ['required','string'],
|
||||
'specialization' => ['required','string'],
|
||||
'license_number' => ['required','string','unique:doctor_profiles,license_number'],
|
||||
'license_file' => ['required','file','mimes:pdf,jpg,png','max:4096'],
|
||||
'diploma_file' => ['required','file','mimes:pdf,jpg,png','max:4096'],
|
||||
'certification_file' => ['sometimes','file','mimes:pdf,jpg,png','max:5120'],
|
||||
'current_institution'=> ['required','string'],
|
||||
'work_history' => ['required','string'],
|
||||
'publications' => ['sometimes','string'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class RegisterRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required','string'],
|
||||
'email' => ['required','email','unique:accounts,email'],
|
||||
'phone' => ['required','string','unique:accounts,phone'],
|
||||
'dob' => ['required','date'],
|
||||
'password' => ['required','min:6','confirmed'],
|
||||
//'role' => ['required', Rule::in(['patient','doctor'])],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreAccountRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required'],
|
||||
'email' => ['required', 'email'],
|
||||
'phone' => ['required'],
|
||||
'dob' => ['required'],
|
||||
'role' => ['required', Rule::in(['patient', 'doctor', 'admin'])],
|
||||
'password' => ['required'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreDoctorProfileRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'user_id' => ['required'],
|
||||
'specialization' => ['required'],
|
||||
'license_number' => ['required'],
|
||||
'license_file_path' => ['required'],
|
||||
'diploma_file_path' => ['required'],
|
||||
'certification' => ['required'],
|
||||
'current_institution' => ['required'],
|
||||
//'years_of_experience' => ['required'],
|
||||
'work_history' => ['required'],
|
||||
'publications' => ['required'],
|
||||
'practice_address' => ['required'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation() {
|
||||
$data = [];
|
||||
|
||||
foreach ($this->validated() as $key => $obj) {
|
||||
$obj['user_id'] = $obj['userId'] ?? null;
|
||||
$obj['license_number'] = $obj['licenseNumber'] ?? null;
|
||||
$obj['license_file_path'] = $obj['licenseFilePath'] ?? null;
|
||||
$obj['diploma_file_path'] = $obj['diplomaFilePath'] ?? null;
|
||||
$obj['current_institution'] = $obj['currentInstitution'] ?? null;
|
||||
//$obj['years_of_experience'] = $obj['yearsOfExperience'] ?? null;
|
||||
$obj['work_history'] = $obj['workHistory'] ?? null;
|
||||
$data[] = $obj;
|
||||
}
|
||||
$this->merge($data);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreSubmissionRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'patient_id' => ['required', 'integer'],
|
||||
'doctor_id' => ['sometimes', 'integer'],
|
||||
'image' => ['required', 'image', 'max:2048'],
|
||||
'complaint' => ['sometimes', 'string'],
|
||||
'status' => ['sometimes', Rule::in(['pending','verified','rejected'])],
|
||||
'diagnosis' => ['sometimes','string'],
|
||||
'doctor_note'=> ['sometimes','string'],
|
||||
// 'submitted_at' => ['sometimes','date'],
|
||||
// 'verified_at' => ['sometimes','date'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreVerificationRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateAccountRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$method = $this->method();
|
||||
if ($method == 'PUT') {
|
||||
return [
|
||||
'name' => ['required'],
|
||||
'email' => ['required', 'email'],
|
||||
'phone' => ['required'],
|
||||
'dob' => ['required'],
|
||||
'role' => ['required', Rule::in(['patient', 'doctor', 'admin'])],
|
||||
'password' => ['required'],
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'name' => ['sometimes', 'required'],
|
||||
'email' => ['sometimes', 'required', 'email'],
|
||||
'phone' => ['sometimes', 'required'],
|
||||
'dob' => ['sometimes', 'required'],
|
||||
'role' => ['sometimes', 'required', Rule::in(['patient', 'doctor', 'admin'])],
|
||||
'password' => ['sometimes', 'required'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateDoctorProfileRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$method = $this->method();
|
||||
if ($method == 'PUT') {
|
||||
return [
|
||||
'userId' => ['required'],
|
||||
'specialization' => ['required'],
|
||||
'licenseNumber' => ['required'],
|
||||
'licenseFilePath' => ['required'],
|
||||
'diplomaFilePath' => ['required'],
|
||||
'certification' => ['required'],
|
||||
'currentInstitution' => ['required'],
|
||||
//'yearsOfExperience' => ['required'],
|
||||
'workHistory' => ['required'],
|
||||
'publications' => ['required']
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'userId' => ['sometimes', 'required'],
|
||||
'specialization' => ['sometimes', 'required'],
|
||||
'licenseNumber' => ['sometimes', 'required'],
|
||||
'licenseFilePath' => ['sometimes', 'required'],
|
||||
'diplomaFilePath' => ['sometimes', 'required'],
|
||||
'certification' => ['sometimes', 'required'],
|
||||
'currentInstitution' => ['sometimes', 'required'],
|
||||
//'yearsOfExperience' => ['sometimes', 'required'],
|
||||
'workHistory' => ['sometimes', 'required'],
|
||||
'publications' => ['sometimes', 'required'],
|
||||
'practice_address' => ['sometimes', 'required'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$data = $this->all();
|
||||
$data['user_id'] = $data['userId'] ?? $data['user_id'] ?? null;
|
||||
$data['license_number'] = $data['licenseNumber'] ?? $data['license_number'] ?? null;
|
||||
$data['license_file_path'] = $data['licenseFilePath'] ?? $data['license_file_path'] ?? null;
|
||||
$data['diploma_file_path'] = $data['diplomaFilePath'] ?? $data['diploma_file_path'] ?? null;
|
||||
$data['current_institution'] = $data['currentInstitution'] ?? $data['current_institution'] ?? null;
|
||||
//$data['years_of_experience'] = $data['yearsOfExperience'] ?? $data['years_of_experience'] ?? null;
|
||||
$data['work_history'] = $data['workHistory'] ?? $data['work_history'] ?? null;
|
||||
|
||||
$this->merge($data);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateSubmissionRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$method = $this->method();
|
||||
if ($method == 'PUT') {
|
||||
return [
|
||||
'doctorId' => ['required'],
|
||||
'status' => ['required', Rule::in(['pending', 'verified', 'rejected'])],
|
||||
'diagnosis' => ['required'],
|
||||
'doctorNote' => ['required'],
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'doctorId' => ['required'],
|
||||
'status' => ['sometimes', 'required', Rule::in(['pending', 'verified', 'rejected'])],
|
||||
'diagnosis' => ['sometimes', 'required'],
|
||||
'doctorNote' => ['sometimes', 'required'],
|
||||
'complaint' => ['sometimes', 'required'],
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$mapped = [];
|
||||
|
||||
if ($this->has('doctorId')) {
|
||||
$mapped['doctor_id'] = $this->input('doctorId');
|
||||
}
|
||||
if ($this->has('doctorNote')) {
|
||||
$mapped['doctor_note'] = $this->input('doctorNote');
|
||||
}
|
||||
if ($this->has('isSubmitted')) {
|
||||
$mapped['is_submitted'] = $this->input('isSubmitted');
|
||||
}
|
||||
|
||||
$this->merge($mapped);
|
||||
} */
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateVerificationRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class AccountCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
// return [
|
||||
// 'data' => $this->collection,
|
||||
// 'status' => true,
|
||||
// ];
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class AccountResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'email' => $this->email,
|
||||
'phone' => $this->phone,
|
||||
'dob' => $this->dob,
|
||||
'role' => $this->role,
|
||||
'doctorProfile' => DoctorProfileResource::make($this->whenLoaded('doctorProfile')),
|
||||
'submission' => SubmissionResource::collection($this->whenLoaded('submission')),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
||||
class DashboardStatsResource extends JsonResource
|
||||
{
|
||||
public function toArray(Request $request)
|
||||
{
|
||||
return [
|
||||
'totalPatients' => $this['totalPatients'],
|
||||
'pending' => $this['pendingCount'],
|
||||
'verified' => $this['verifiedCount'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class DoctorHistorySubmissionResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'patientId' => $this->patient->id,
|
||||
'submittedAt' => optional($this->submitted_at)->format('Y-m-d'),
|
||||
'patientName' => $this->patient->name,
|
||||
'diagnosisAi' => $this->getDiagnosisAi(),
|
||||
'diagnosis' => $this->diagnosis,
|
||||
'doctorNote' => $this->doctor_note,
|
||||
];
|
||||
}
|
||||
|
||||
private function getDiagnosisAi(): ?string
|
||||
{
|
||||
$pct = $this->percentage;
|
||||
$threshold = config('ai.threshold');
|
||||
$labelPos = config('ai.label_positive');
|
||||
$labelNeg = config('ai.label_negative');
|
||||
|
||||
return is_numeric($pct)
|
||||
? sprintf('%d%% %s', round($pct * 1), $pct >= $threshold ? $labelPos : $labelNeg)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class DoctorListResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class DoctorProfileCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class DoctorProfileResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request)
|
||||
{
|
||||
return [
|
||||
'userId' =>$this->user_id,
|
||||
'specialization' =>$this->specialization,
|
||||
'licenseNumber' =>$this->license_number,
|
||||
'licenseFilePath' =>$this->license_file_path,
|
||||
'diplomaFilePath' =>$this->diploma_file_path,
|
||||
'certification' =>$this->certification,
|
||||
'currentInstitution' =>$this->current_institution,
|
||||
//'yearsOfExperience' =>$this->years_of_experience,
|
||||
'workHistory' =>$this->work_history,
|
||||
'publications' =>$this->publications
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PatientDetectionDetailResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'doctorId' => $this->doctor_id,
|
||||
'imageUrl' => Storage::disk('public')->url($this->image_path),
|
||||
'diagnosis' => $this->diagnosis ?? 'Belum dapat dipastikan',
|
||||
'diagnosisAi' => $this->getDiagnosisAi(),
|
||||
'isSubmitted' => $this->is_submitted,
|
||||
'status' => $this->status,
|
||||
];
|
||||
}
|
||||
private function getDiagnosisAi(): ?string
|
||||
{
|
||||
$pct = $this->percentage;
|
||||
$threshold = config('ai.threshold');
|
||||
$labelPos = config('ai.label_positive');
|
||||
$labelNeg = config('ai.label_negative');
|
||||
|
||||
return is_numeric($pct)
|
||||
? sprintf('%d%% %s', round($pct * 1), $pct >= $threshold ? $labelPos : $labelNeg)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PatientDetectionHistoryResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'submittedAt' => optional($this->submitted_at)->format('Y-m-d'),
|
||||
'diagnosisAi' => $this->getDiagnosisAi(),
|
||||
'imageUrl' => Storage::disk('public')->url($this->image_path),
|
||||
'isSubmitted' => $this->is_submitted,
|
||||
'status' => $this->status,
|
||||
'complaint' => $this->complaint,
|
||||
];
|
||||
}
|
||||
|
||||
private function getDiagnosisAi(): ?string
|
||||
{
|
||||
$pct = $this->percentage;
|
||||
$threshold = config('ai.threshold');
|
||||
$labelPos = config('ai.label_positive');
|
||||
$labelNeg = config('ai.label_negative');
|
||||
|
||||
return is_numeric($pct)
|
||||
? sprintf('%d%% %s', round($pct * 1), $pct >= $threshold ? $labelPos : $labelNeg)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PatientListResource extends JsonResource
|
||||
{
|
||||
public function toArray(Request $request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'phone' => $this->phone,
|
||||
'submissionCount' => $this->submission_count,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PatientSubmissionDetailResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
$user = $this->patient;
|
||||
|
||||
return [
|
||||
'imageUrl' => Storage::disk('public')->url($this->image_path),
|
||||
'verifiedBy' => $this->doctor?->name,
|
||||
'patient' => [
|
||||
'name' => $user->name,
|
||||
'phone' => $user->phone,
|
||||
'email' => $user->email,
|
||||
'dob' => optional($user->dob)->format('Y-m-d'),
|
||||
],
|
||||
'complaint' => $this->complaint,
|
||||
'diagnosis' => $this->diagnosis,
|
||||
'diagnosisAi' => $this->getDiagnosisAi(),
|
||||
'status' => $this->status,
|
||||
'doctorNote' => $this->doctor_note,
|
||||
];
|
||||
}
|
||||
private function getDiagnosisAi(): ?string
|
||||
{
|
||||
$pct = $this->percentage;
|
||||
$threshold = config('ai.threshold');
|
||||
$labelPos = config('ai.label_positive');
|
||||
$labelNeg = config('ai.label_negative');
|
||||
|
||||
return is_numeric($pct)
|
||||
? sprintf('%d%% %s', round($pct * 1), $pct >= $threshold ? $labelPos : $labelNeg)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PatientSubmissionHistoryResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'submittedAt' => optional($this->submitted_at)->format('Y-m-d'),
|
||||
'diagnosisAi' => $this->getDiagnosisAi(),
|
||||
'imageUrl' => Storage::disk('public')->url($this->image_path),
|
||||
'complaint' => $this->complaint,
|
||||
'status' => $this->status,
|
||||
'verifiedAt' => optional($this->verified_at)->format('Y-m-d'),
|
||||
'verifiedBy' => $this->doctor?->name,
|
||||
'diagnosis' => $this->diagnosis,
|
||||
'doctorNote' => $this->doctor_note,
|
||||
];
|
||||
}
|
||||
|
||||
private function getDiagnosisAi(): ?string
|
||||
{
|
||||
$pct = $this->percentage;
|
||||
$threshold = config('ai.threshold');
|
||||
$labelPos = config('ai.label_positive');
|
||||
$labelNeg = config('ai.label_negative');
|
||||
|
||||
return is_numeric($pct)
|
||||
? sprintf('%d%% %s', round($pct * 1), $pct >= $threshold ? $labelPos : $labelNeg)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PendingVerificationResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class SubmissionCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class SubmissionDetailResource extends JsonResource
|
||||
{
|
||||
public function toArray(Request $request)
|
||||
{
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'doctorId' => $this->doctor_id,
|
||||
'patientId' => $this->patient->id,
|
||||
'patientName' => $this->patient->name,
|
||||
'patientPhone' => $this->patient->phone,
|
||||
'patientEmail' => $this->patient->email,
|
||||
'patientDob' => $this->patient->dob,
|
||||
'imageUrl' => Storage::disk('public')->url($this->image_path),
|
||||
'complaint' => $this->complaint,
|
||||
'status' => $this->status,
|
||||
'percentage' => $this->percentage,
|
||||
'diagnosis' => $this->diagnosis ?? 'Belum dapat dipastikan',
|
||||
'diagnosisAi' => $this->getDiagnosisAi(),
|
||||
'doctorNote' => $this->doctor_note,
|
||||
'isSubmitted' => $this->is_submitted,
|
||||
'submittedAt' => optional($this->submitted_at)->format('Y-m-d'),
|
||||
'verifiedAt' => optional($this->verified_at)->format('Y-m-d'),
|
||||
];
|
||||
}
|
||||
|
||||
private function getDiagnosisAi(): ?string
|
||||
{
|
||||
$pct = $this->percentage;
|
||||
$threshold = config('ai.threshold');
|
||||
$labelPos = config('ai.label_positive');
|
||||
$labelNeg = config('ai.label_negative');
|
||||
|
||||
return is_numeric($pct)
|
||||
? sprintf('%d%% %s', round($pct * 1), $pct >= $threshold ? $labelPos : $labelNeg)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class SubmissionListResource extends JsonResource
|
||||
{
|
||||
public function toArray(Request $request)
|
||||
{
|
||||
$onlyPercentage = $request->get('only_percentage', false);
|
||||
|
||||
if ($onlyPercentage) {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'patientId' => $this->patient->id,
|
||||
'patientName' => $this->patient->name,
|
||||
'submittedAt' => optional($this->submitted_at)->format('Y-m-d'),
|
||||
'imageUrl' => Storage::disk('public')->url($this->image_path),
|
||||
'diagnosisAi' => $this->percentage,
|
||||
];
|
||||
}
|
||||
|
||||
// versi full list
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'patientName' => $this->patient->name,
|
||||
'submittedAt' => optional($this->submitted_at)->format('Y-m-d'),
|
||||
'diagnosisAi' => $this->getDiagnosisAi(),
|
||||
];
|
||||
}
|
||||
|
||||
private function getDiagnosisAi(): ?string
|
||||
{
|
||||
$pct = $this->percentage;
|
||||
$threshold = config('ai.threshold');
|
||||
$labelPos = config('ai.label_positive');
|
||||
$labelNeg = config('ai.label_negative');
|
||||
|
||||
return is_numeric($pct)
|
||||
? sprintf('%d%% %s', round($pct * 1), $pct >= $threshold ? $labelPos : $labelNeg)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V1;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class SubmissionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request)
|
||||
{
|
||||
$threshold = config('ai.threshold');
|
||||
$labelPos = config('ai.label_positive');
|
||||
$labelNeg = config('ai.label_negative');
|
||||
|
||||
$pct = $this->percentage;
|
||||
$diagnosisAi = is_numeric($pct)
|
||||
? ($pct >= $threshold ? $labelPos : $labelNeg)
|
||||
: null;
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'patientId' => $this->patient_id,
|
||||
'patientName' =>$this->patient->name,
|
||||
'doctorId' => $this->doctor_id,
|
||||
'imageUrl' => Storage::disk('public')->url($this->image_path),
|
||||
'complaint' => $this->complaint,
|
||||
'status' => $this->status,
|
||||
'diagnosis' => $this->diagnosis ?? 'Belum dapat dipastikan',
|
||||
'doctorNote' => $this->doctor_note,
|
||||
'isSubmitted' => $this->is_submitted,
|
||||
'submittedAt' => optional($this->submitted_at)->format('Y-m-d'),
|
||||
'verifiedAt' => optional($this->verified_at)->format('Y-m-d'),
|
||||
'percentage' => $this->percentage,
|
||||
'diagnosisAi' => $diagnosisAi,
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user