Skip to content
Extraits de code Groupes Projets
+page.svelte 5,03 ko
Newer Older
  • Learn to ignore specific revisions
  • Brieuc Dubois's avatar
    Brieuc Dubois a validé
    <script lang="ts">
    	import { t } from '$lib/services/i18n';
    	import type { PageData } from './$types.js';
    	import WeeklySurvey from './WeeklySurvey.svelte';
    	import Chatbox from './Chatbox.svelte';
    
    	import type Task from '$lib/types/tasks';
    	import { toastAlert, toastSuccess } from '$lib/utils/toasts';
    	import { sendTaskStatusAPI } from '$lib/api/tasks';
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    
    	let { data }: { data: PageData } = $props();
    	let user = data.user!;
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	let { session, jwt, tasks, completedTasks } = data;
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	let { onlineUsers } = session;
    
    
    	let level = $state('all');
    	let currentTask: Task | null = $state(data.currentTask);
    	let taskInProgress: boolean = $state(data.currentTask !== null);
    
    	let availableLevels = new Set(tasks.map((task: Task) => task.level));
    
    	async function startTask() {
    		const student = session.student;
    		if (!student || !currentTask) return;
    		const ok = await sendTaskStatusAPI(
    			fetch,
    			'start',
    			student.id,
    			user.id,
    			currentTask.id,
    			session.id
    		);
    		if (!ok) {
    			toastAlert($t('tasks.statusFail'));
    			return;
    		}
    		taskInProgress = true;
    	}
    
    	async function cancelTask() {
    		const student = session.student;
    		if (!student || !currentTask) return;
    		const ok = await sendTaskStatusAPI(
    			fetch,
    			'cancel',
    			student.id,
    			user.id,
    			currentTask.id,
    			session.id
    		);
    		if (!ok) {
    			toastAlert($t('tasks.statusFail'));
    			return;
    		}
    		taskInProgress = false;
    		currentTask = null;
    	}
    
    	async function finishTask() {
    		const student = session.student;
    		if (!student || !currentTask) return;
    		const ok = await sendTaskStatusAPI(
    			fetch,
    			'finish',
    			student.id,
    			user.id,
    			currentTask.id,
    			session.id
    		);
    		if (!ok) {
    			toastAlert($t('tasks.statusFail'));
    			return;
    		}
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    		completedTasks.push(currentTask);
    
    
    		taskInProgress = false;
    		currentTask = null;
    		toastSuccess($t('tasks.taskFinished'));
    	}
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    </script>
    
    
    Dave's avatar
    Dave a validé
    <div class="h-full flex flex-col lg:flex-row pt-2 lg:pt-0 bg-gray-50 relative">
    	<input type="checkbox" id="toggleParticipants" class="hidden peer" />
    
    	<label
    		for="toggleParticipants"
    		class="absolute top-4 right-4 bg-yellow-500 text-white px-2 py-1 rounded-md shadow-md
    		hover:bg-yellow-600 transition focus:outline-none text-sm lg:hidden"
    	>
    		{$t('utils.words.toggle')}
    	</label>
    
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	<div
    
    Dave's avatar
    Dave a validé
    		class="group w-full max-w-md bg-white border rounded-lg shadow-md p-6 mx-4 my-2 h-fit text-base
    		lg:text-lg transition-all duration-300 ease-in-out hidden lg:block peer-checked:block"
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	>
    
    Dave's avatar
    Dave a validé
    		<h2 class="text-xl truncate font-semibold text-gray-700 text-center mb-4">
    			{$t('utils.words.participants')}
    		</h2>
    
    		<div class="space-y-4">
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    			{#each session.users as sessionUser (sessionUser.id)}
    
    Dave's avatar
    Dave a validé
    				<div class="flex items-center gap-4 p-3 rounded-lg hover:bg-gray-100 transition">
    					<div
    						class="w-10 h-10 rounded-full overflow-hidden shadow-md"
    						title={sessionUser.nickname}
    					>
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    						<img
    							src={`https://gravatar.com/avatar/${sessionUser.emailHash}?d=identicon`}
    							alt={sessionUser.nickname}
    
    Dave's avatar
    Dave a validé
    							class="rounded-full border-2 {sessionUser.id == user?.id ||
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    							$onlineUsers.has(sessionUser.id)
    								? 'border-green-500'
    								: 'border-red-500'}"
    						/>
    					</div>
    
    Dave's avatar
    Dave a validé
    					<span class="truncate w-48 lg:w-64 font-medium text-gray-800">
    						{sessionUser.nickname}
    					</span>
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    				</div>
    			{/each}
    		</div>
    
    Dave's avatar
    Dave a validé
    
    		<h2 class="text-lg truncate font-semibold text-gray-700 text-center border-t pt-4 mt-4">
    
    			{$t('utils.words.tasks')}
    
    Dave's avatar
    Dave a validé
    		</h2>
    
    		{#if !taskInProgress || !currentTask}
    			<div class="flex gap-2">
    				<select class="select select-bordered w-32" bind:value={level}>
    					<option value="all">{$t('utils.words.all')}</option>
    					{#each availableLevels as l}
    						<option value={l}>{l}</option>
    					{/each}
    				</select>
    				<select class="select select-bordered flex-1 overflow-hidden" bind:value={currentTask}>
    					{#each availableLevels as l}
    						{#if level === 'all' || l === level}
    							<optgroup label={l}>
    								{#each tasks.filter((task: Task) => task.level === l) as task (task.id)}
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    									<option value={task}>
    										{#if completedTasks.includes(task)}
    
    										{/if}
    										{task.shortTitle}
    									</option>
    
    								{/each}
    							</optgroup>
    						{/if}
    					{/each}
    				</select>
    			</div>
    			<button class="btn mt-2 w-full btn-primary" onclick={startTask}>
    				{$t('button.select')}
    			</button>
    		{:else}
    			<p class="mt-4 font-bold">
    				{$t('tasks.taskInProgress')}:
    			</p>
    			<p>
    				{currentTask.shortTitle}
    			</p>
    			{#if currentTask.instructions}
    				<p class="mt-2 font-bold">
    					{$t('utils.words.instructions')}:
    				</p>
    				<p>
    					{currentTask.instructions}
    				</p>
    			{/if}
    			<p class="mt-2 font-bold">
    				{$t('utils.words.examples')}:
    			</p>
    			<p>
    				{currentTask.examples}
    			</p>
    			<div class="flex gap-2 mt-4">
    				<button class="btn flex-grow" onclick={cancelTask}>
    					{$t('button.cancel')}
    				</button>
    				<button class="btn btn-primary flex-grow" onclick={finishTask}>
    					{$t('button.finish')}
    				</button>
    			</div>
    		{/if}
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	</div>
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	<div class="flex flex-row flex-grow col-span-5">
    		<Chatbox {session} {jwt} {user} />
    	</div>
    </div>
    
    <WeeklySurvey {user} />