diff --git a/app/Http/Controllers/Client/Doctor/ReportController.php b/app/Http/Controllers/Client/Doctor/ReportController.php index 4a44fdb..e855cf9 100644 --- a/app/Http/Controllers/Client/Doctor/ReportController.php +++ b/app/Http/Controllers/Client/Doctor/ReportController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Client\Doctor; use App\Http\Controllers\Controller; use App\Http\Requests\Client\ReportSubmitRequest; +use App\Http\Resources\Client\CaseResource; use App\Http\Resources\Client\ReportResource; use App\Models\Document; use App\Models\Report; @@ -32,8 +33,13 @@ class ReportController extends Controller ->withQueryString() ->onEachSide(1); + $pendingCases = $this->caseService->isDoctor(Auth::user()) + ? CaseResource::collection($this->caseService->pendingForUser(Auth::user())->get()) + : null; + return Inertia::client('Dashboard/Reports/Index', [ 'reports' => ReportResource::collection($reports), + 'pendingCases' => $pendingCases, ]); } diff --git a/app/Http/Controllers/Client/MediaController.php b/app/Http/Controllers/Client/MediaController.php new file mode 100644 index 0000000..83277ad --- /dev/null +++ b/app/Http/Controllers/Client/MediaController.php @@ -0,0 +1,28 @@ +caseService = $caseService; + $this->fileStorageService = $fileStorageService; + } + + public function download(Medium $medium) + { + abort_unless($this->caseService->canAccessMedium($medium, Auth::user()), 403); + + return $this->fileStorageService->downloadFile($medium); + } +} diff --git a/app/Http/Resources/Client/CaseDetailResource.php b/app/Http/Resources/Client/CaseDetailResource.php index 88d953b..179740d 100644 --- a/app/Http/Resources/Client/CaseDetailResource.php +++ b/app/Http/Resources/Client/CaseDetailResource.php @@ -69,7 +69,7 @@ class CaseDetailResource extends JsonResource return [ 'id' => $medium->id, 'filename' => $medium->filename, - 'url' => $medium->url, + 'url' => $medium->isPrivate() ? route('dashboard.media.download', $medium) : $medium->url, 'mime_type' => $medium->mime_type, ]; } diff --git a/app/Services/Document/CaseService.php b/app/Services/Document/CaseService.php index e92b899..961c61f 100644 --- a/app/Services/Document/CaseService.php +++ b/app/Services/Document/CaseService.php @@ -9,6 +9,7 @@ use App\Enums\ReportStatusEnum; use App\Enums\UserEnum; use App\Enums\WalletTransactionReasonEnum; use App\Models\Document; +use App\Models\Medium; use App\Models\Report; use App\Models\User; use App\Services\FileStorageService; @@ -51,6 +52,14 @@ class CaseService || $document->assignments()->where('user_id', $user->id)->exists(); } + public function canAccessMedium(Medium $medium, User $user): bool + { + $documents = $medium->documents()->get() + ->merge($medium->reports()->with('document')->get()->pluck('document')); + + return $documents->contains(fn ($document) => $this->canAccess($document, $user)); + } + public function canReport(Document $document, User $user): bool { return $this->isDoctor($user) @@ -162,7 +171,7 @@ class CaseService ->orWhereHas('assignments', fn ($assignmentQuery) => $assignmentQuery->where('user_id', $user->id)); } - protected function isDoctor(User $user): bool + public function isDoctor(User $user): bool { return $user->level === UserEnum::Doctor->value; } diff --git a/config/services.php b/config/services.php index e40e06d..a5ba2f1 100644 --- a/config/services.php +++ b/config/services.php @@ -44,7 +44,7 @@ return [ 'iranpayamak' => [ 'api_url' => env('IRANPAYAMAK_SMS_API_URL', 'https://api.iranpayamak.com/ws/v1/sms/pattern'), 'line_number' => env('IRANPAYAMAK_SMS_API_URL', '50002178584000'), - 'api_key' => env('IRANPAYAMAK_SMS_API_URL', 'jnCyVq4ein7uGsgIGjHsVRrWz0112IA2v2qbZMHq0kHtEXubsh'), + 'api_key' => env('IRANPAYAMAK_SMS_API_URL', 'jnCyVq4ein7uGsgIGjHsVRrWz0112IA2v2qbZM5q0kHtEXubsh'), 'patterns' => [ diff --git a/resources/css/Client/ui/button.css b/resources/css/Client/ui/button.css index 5d84a77..ad624ca 100644 --- a/resources/css/Client/ui/button.css +++ b/resources/css/Client/ui/button.css @@ -41,19 +41,11 @@ .ui-button--success.p-button { - @apply !bg-success !border-success font-normal !text-white; -} - -.ui-button--success.p-button:hover { - @apply !bg-success-active !border-success-active; -} - -.ui-button--success.p-button:active { - @apply !bg-success-active !border-success-active; + @apply !bg-complement-700 !border-complement-700 !text-white; } .ui-button--success.p-button:focus { - box-shadow: 0 0 0 2px rgb(80 205 137 / 0.25); + box-shadow: 0 0 0 2px rgb(87 105 137 / 0.25); } .ui-button-icon { diff --git a/resources/css/Client/ui/fast-request.css b/resources/css/Client/ui/fast-request.css index 241e092..0f8ff8d 100644 --- a/resources/css/Client/ui/fast-request.css +++ b/resources/css/Client/ui/fast-request.css @@ -41,12 +41,6 @@ padding: 8px 16px !important; } -.fast-request-dialog .ui-button .p-button.p-button-success { - background: #576989 !important; - border-color: #576989 !important; - color: #FFFFFF !important; -} - .fast-request-dialog .p-inputtext::placeholder { color: #6E91C9; } @@ -87,26 +81,3 @@ background: #576989 !important; } -.fast-request-dialog .p-fileupload-choose-button, -.fast-request-dialog .p-fileupload-header { - display: none !important; -} - -.fast-request-dialog .p-fileupload { - width: 100% !important; - height: 100% !important; - display: flex !important; - align-items: center !important; - justify-content: center !important; -} - -.fast-request-dialog .p-fileupload-content { - pointer-events: auto !important; - width: 100%; -} - -.fast-request-dialog .p-fileupload-advanced { - border: 2px solid #C1D0E8 !important; - border-style: dashed !important; - border-radius: 6px !important; -} diff --git a/resources/css/Client/ui/file-upload.css b/resources/css/Client/ui/file-upload.css new file mode 100644 index 0000000..f06745d --- /dev/null +++ b/resources/css/Client/ui/file-upload.css @@ -0,0 +1,41 @@ +.ui-file-upload .p-fileupload { + @apply w-full; + border: 1.5px dashed #C1D0E8; + border-radius: 16px; + background: #F8FAFC; + transition: border-color 0.2s, background-color 0.2s; +} + +.ui-file-upload .p-fileupload-header { + display: none; +} + +.ui-file-upload--filled .p-fileupload { + border-style: solid; + border-color: #DEE3EB; + background: #FFFFFF; +} + +.ui-file-upload:hover .p-fileupload, +.ui-file-upload--dragging .p-fileupload { + border-color: #365891; + background: #EEF2F8; +} + +.ui-file-upload .p-fileupload-content { + @apply w-full p-3; + pointer-events: auto; +} + +.ui-file-upload-dropzone { + @apply w-full min-h-[8.5rem] flex flex-col items-center justify-center gap-1 text-center cursor-pointer; +} + +.ui-file-upload-icon { + @apply w-11 h-11 mb-1 flex items-center justify-center rounded-full bg-[#EEF2F8] text-[#365891] transition-transform; +} + +.ui-file-upload:hover .ui-file-upload-icon, +.ui-file-upload--dragging .ui-file-upload-icon { + @apply scale-110 bg-white; +} diff --git a/resources/css/client.css b/resources/css/client.css index e0c000d..c441f8d 100644 --- a/resources/css/client.css +++ b/resources/css/client.css @@ -8,6 +8,7 @@ @import "./Client/ui/card.css"; @import "./Client/ui/select.css"; @import "./Client/ui/fast-request.css"; +@import "./Client/ui/file-upload.css"; @import "./Client/ui/table.css"; @import "./Shared/shift-calendar.css"; @import "tailwindcss"; diff --git a/resources/js/Client/Pages/Dashboard/Cases/show.vue b/resources/js/Client/Pages/Dashboard/Cases/show.vue index ae27566..ac892f3 100644 --- a/resources/js/Client/Pages/Dashboard/Cases/show.vue +++ b/resources/js/Client/Pages/Dashboard/Cases/show.vue @@ -11,6 +11,7 @@ import ReportSectionCard from '../../../components/dashboard/cases/ReportSection import FileUploadBox from '../../../components/dashboard/fastRequest/FileUploadBox.vue'; import { modalityTitle } from '../../../data/fastRequestOptions'; import { convertEnglishToPersian } from '../../../utils/numberUtils'; +import { downloadFiles } from '../../../utils/fileUtils'; const props = defineProps({ case: { @@ -73,10 +74,6 @@ onMounted(() => { onUnmounted(() => clearInterval(timerId)); -const openFiles = (files) => { - files.forEach((file) => window.open(file.url, '_blank')); -}; - const reportForm = useForm({ document_id: props.case.id, technique: props.case.report?.technique || '', @@ -149,9 +146,9 @@ const submitReject = () => {
{{ props.case.note || 'توضیحی ثبت نشده است.' }}
{{ file.name }}
+{{ formatFileSize(file.size) }}
++ {{ convertEnglishToPersian(String(selectedFiles.length)) }} فایل · {{ formatFileSize(totalSize) }} +
+{{ title }}
-- جهت آپلود تصویر کلیک کنید و یا فایل خود را کشیده و در این قسمت رها (Drag and Drop) کنید. -
-+
مبلغ مورد نظر پس از بررسی و تایید توسط کارشناسان، از کیف پول شما کسر و به کارت انتخابی واریز میشود.
-+ هنوز کارتی ثبت نکردهاید. برای ثبت درخواست برداشت ابتدا یک کارت بانکی اضافه کنید. +
++ {{ formatPrice(numericAmount) }} تومان + به کارت + {{ formatCardNumber(selectedCard.card_number) }} + واریز میشود. +
++ برای ثبت درخواست، کارت مقصد را انتخاب و مبلغ را وارد کنید. +
- هنوز کارتی ثبت نکردهاید. برای ثبت درخواست برداشت ابتدا یک کارت بانکی اضافه کنید. -
- -