pre-tags
This commit is contained in:
48
src/lib/components/Modal.svelte
Normal file
48
src/lib/components/Modal.svelte
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
export let isOpen = false;
|
||||||
|
export let title = '';
|
||||||
|
export let maxWidth = 'max-w-md';
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
function handleBackdropClick(event) {
|
||||||
|
if (event.target === event.currentTarget) {
|
||||||
|
dispatch('close');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleKeydown(event) {
|
||||||
|
if (event.key === 'Escape' && isOpen) {
|
||||||
|
dispatch('close');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:window on:keydown={handleKeydown} />
|
||||||
|
|
||||||
|
{#if isOpen}
|
||||||
|
<div
|
||||||
|
class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50 transition-opacity"
|
||||||
|
on:click={handleBackdropClick}
|
||||||
|
on:keydown={handleKeydown}
|
||||||
|
role="dialog"
|
||||||
|
aria-modal="true"
|
||||||
|
aria-labelledby="modal-title"
|
||||||
|
tabindex="-1"
|
||||||
|
>
|
||||||
|
<div class="relative top-20 mx-auto p-5 border w-11/12 {maxWidth} shadow-lg rounded-md bg-white">
|
||||||
|
<div class="mt-3">
|
||||||
|
{#if title}
|
||||||
|
<h3 class="text-lg font-medium text-gray-900 mb-4" id="modal-title">
|
||||||
|
{title}
|
||||||
|
</h3>
|
||||||
|
{/if}
|
||||||
|
<div>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
115
src/lib/components/OverallRatingModal.svelte
Normal file
115
src/lib/components/OverallRatingModal.svelte
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
import Modal from './Modal.svelte';
|
||||||
|
|
||||||
|
export let isOpen = false;
|
||||||
|
export let audioFilename = '';
|
||||||
|
export let isSubmitting = false;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
let overallRating = 50;
|
||||||
|
|
||||||
|
function handleClose() {
|
||||||
|
if (isSubmitting) return; // Prevent closing while submitting
|
||||||
|
dispatch('close');
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSubmit() {
|
||||||
|
dispatch('submit', { overallRating });
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRatingChange() {
|
||||||
|
// Optional: add any real-time feedback here
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal {isOpen} title="Overall Performance Rating" maxWidth="max-w-lg" on:close={handleClose}>
|
||||||
|
<div class="space-y-6">
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-indigo-100 mb-4">
|
||||||
|
<i class="fas fa-star text-indigo-600 text-xl"></i>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-gray-600">
|
||||||
|
You've completed rating: <strong>{audioFilename}</strong>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<h4 class="text-center text-lg font-medium text-gray-900">
|
||||||
|
How good was this performance overall?
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
bind:value={overallRating}
|
||||||
|
on:input={handleRatingChange}
|
||||||
|
disabled={isSubmitting}
|
||||||
|
class="slider h-3 w-full cursor-pointer appearance-none rounded-lg bg-gray-200 {isSubmitting ? 'opacity-50' : ''}"
|
||||||
|
/>
|
||||||
|
<div class="flex justify-between text-sm text-gray-600">
|
||||||
|
<span>Poor (0)</span>
|
||||||
|
<span class="font-semibold text-indigo-600">Rating: {overallRating}</span>
|
||||||
|
<span>Excellent (100)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex space-x-3 justify-end">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
on:click={handleClose}
|
||||||
|
disabled={isSubmitting}
|
||||||
|
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
on:click={handleSubmit}
|
||||||
|
disabled={isSubmitting}
|
||||||
|
class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 border border-transparent rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed flex items-center"
|
||||||
|
>
|
||||||
|
{#if isSubmitting}
|
||||||
|
<div class="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
|
||||||
|
Submitting...
|
||||||
|
{:else}
|
||||||
|
Submit Overall Rating
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.slider::-webkit-slider-thumb {
|
||||||
|
appearance: none;
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #4f46e5;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider::-moz-range-thumb {
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #4f46e5;
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider:disabled::-webkit-slider-thumb {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider:disabled::-moz-range-thumb {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user