diff --git a/app/Http/Controllers/LandingController.php b/app/Http/Controllers/LandingController.php index b28a135..c7e671f 100644 --- a/app/Http/Controllers/LandingController.php +++ b/app/Http/Controllers/LandingController.php @@ -4,16 +4,29 @@ namespace App\Http\Controllers; +use App\Services\Config as ConfigService; use Inertia\Inertia; use Inertia\Response; final class LandingController extends Controller { /** - * Display the landing page. + * Display the landing page with a flag indicating whether a disclaimer is configured. */ - public function index(): Response + public function index(ConfigService $config): Response { - return Inertia::render('Landing'); + return Inertia::render('Landing', [ + 'hasDisclaimer' => $config->contentDisclaimer !== '', + ]); + } + + /** + * Display the disclaimer page with the configured markdown content. + */ + public function disclaimer(ConfigService $config): Response + { + return Inertia::render('Disclaimer', [ + 'content' => $config->contentDisclaimer, + ]); } } diff --git a/app/Http/Controllers/SessionController.php b/app/Http/Controllers/SessionController.php index 6ee8e44..ab5ad36 100644 --- a/app/Http/Controllers/SessionController.php +++ b/app/Http/Controllers/SessionController.php @@ -205,11 +205,14 @@ public function result(Session $session): InertiaResponse { $session->load('category'); + $durationSeconds = $session->created_at->diffInSeconds($session->completed_at); + return Inertia::render('Session/Result', [ 'session' => $session, 'score' => $session->score, 'result' => $session->result, 'categoryName' => $session->category->name, + 'durationSeconds' => $durationSeconds, ]); } diff --git a/config/nova.php b/config/nova.php index 6e3a328..445c37c 100644 --- a/config/nova.php +++ b/config/nova.php @@ -183,7 +183,7 @@ */ 'actions' => [ - 'resource' => \Laravel\Nova\Actions\ActionResource::class, + 'resource' => null, ], /* diff --git a/package-lock.json b/package-lock.json index b90a24c..2bb58eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "@heroicons/vue": "^2.2.0", "@inertiajs/vue3": "^2.3.13", "@vitejs/plugin-vue": "^6.0.4", + "marked": "^17.0.4", "vue": "^3.5.27" }, "devDependencies": { @@ -3257,6 +3258,18 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/marked": { + "version": "17.0.4", + "resolved": "https://registry.npmjs.org/marked/-/marked-17.0.4.tgz", + "integrity": "sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", diff --git a/package.json b/package.json index 74464e9..50d3052 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@heroicons/vue": "^2.2.0", "@inertiajs/vue3": "^2.3.13", "@vitejs/plugin-vue": "^6.0.4", + "marked": "^17.0.4", "vue": "^3.5.27" } } diff --git a/resources/js/Pages/Disclaimer.vue b/resources/js/Pages/Disclaimer.vue new file mode 100644 index 0000000..4264601 --- /dev/null +++ b/resources/js/Pages/Disclaimer.vue @@ -0,0 +1,257 @@ + + + + + diff --git a/resources/js/Pages/Landing.vue b/resources/js/Pages/Landing.vue index 8015840..a3244da 100644 --- a/resources/js/Pages/Landing.vue +++ b/resources/js/Pages/Landing.vue @@ -1,17 +1,28 @@ diff --git a/resources/js/Pages/Screening/Show.vue b/resources/js/Pages/Screening/Show.vue index eb9344b..c1a44f8 100644 --- a/resources/js/Pages/Screening/Show.vue +++ b/resources/js/Pages/Screening/Show.vue @@ -1,6 +1,7 @@ diff --git a/resources/js/Pages/Session/Result.vue b/resources/js/Pages/Session/Result.vue index 5d98752..f38f522 100644 --- a/resources/js/Pages/Session/Result.vue +++ b/resources/js/Pages/Session/Result.vue @@ -24,6 +24,25 @@ const props = defineProps({ type: String, required: true, }, + durationSeconds: { + type: Number, + default: 0, + }, +}) + +const formattedDuration = computed(() => { + const total = props.durationSeconds + const hours = Math.floor(total / 3600) + const minutes = Math.floor((total % 3600) / 60) + const seconds = total % 60 + + if (hours > 0) { + return `${hours}h ${minutes}m` + } + if (minutes > 0) { + return `${minutes}m ${seconds}s` + } + return `${seconds}s` }) const resultDisplay = computed(() => { @@ -87,14 +106,22 @@ const resultDisplay = computed(() => {

Session Details

-
+
Category
{{ categoryName }}
-
-
Completed
-
{{ new Date(session.completed_at).toLocaleDateString() }}
+
+
+
Completed
+
{{ new Date(session.completed_at).toLocaleDateString() }}
+
+
+
+
+
Duration
+
{{ formattedDuration }}
+
diff --git a/resources/js/Pages/Session/Show.vue b/resources/js/Pages/Session/Show.vue index 866038b..693eb2f 100644 --- a/resources/js/Pages/Session/Show.vue +++ b/resources/js/Pages/Session/Show.vue @@ -76,6 +76,7 @@ const saveAnswer = (questionId) => { }, { preserveScroll: true, preserveState: true, + showProgress: false, only: ['answers'], onStart: () => { processing.value = true }, onFinish: () => { processing.value = false }, @@ -100,6 +101,7 @@ const saveComments = () => { additionalComments.put(`/sessions/${props.session.id}`, { preserveScroll: true, preserveState: true, + showProgress: false, }) }, 1000) } @@ -223,7 +225,7 @@ const completeSession = async () => {
-
+

Basic Information

@@ -242,7 +244,7 @@ const completeSession = async () => {
@@ -269,7 +271,7 @@ const completeSession = async () => {
-
+

Additional Comments