diff --git a/messages/en.json b/messages/en.json index 79d9a7b..a5b0ca4 100644 --- a/messages/en.json +++ b/messages/en.json @@ -9,9 +9,8 @@ "admin_contests_card_start": "Start:", "admin_contests_card_tasks": "Tasks", "admin_contests_card_user_prefix": "User #", - "admin_contests_card_view_tasks": "View Contest Tasks", + "admin_contests_card_manage_tasks": "Manage Tasks", "admin_contests_card_view_requests": "Registration Requests", - "admin_contests_card_add_tasks": "Add Tasks to Contest", "admin_contests_create_description": "Set up a new programming contest", "admin_contests_create_error": "Failed to create contest", "admin_contests_create_success": "Contest created successfully!", @@ -80,6 +79,30 @@ "admin_contest_tasks_remove_cancel": "Cancel", "admin_contest_tasks_remove_success": "Task removed from contest successfully!", "admin_contest_tasks_remove_error": "Failed to remove task from contest", + "admin_contest_tasks_manage_title": "Manage Contest Tasks", + "admin_contest_tasks_added": "Added Tasks", + "admin_contest_tasks_search_placeholder": "Search tasks...", + "admin_contest_tasks_no_results_title": "No tasks found", + "admin_contest_tasks_column_creator": "Creator", + "admin_contest_tasks_edit_schedule_title": "Edit Schedule", + "admin_contest_tasks_edit_dialog_title": "Edit Task Schedule", + "admin_contest_tasks_edit_dialog_description": "Update when this task is available in the contest.", + "admin_contest_tasks_update_button": "Save Changes", + "admin_contest_tasks_update_success": "Task schedule updated successfully!", + "admin_contest_tasks_update_error": "Failed to update task schedule", + "admin_contest_tasks_column_id": "ID", + "admin_contest_tasks_column_title": "Title", + "admin_contest_tasks_column_start_at": "Available From", + "admin_contest_tasks_column_end_at": "Available Until", + "admin_contest_tasks_column_created_at": "Created At", + "admin_contest_tasks_column_actions": "Actions", + "admin_contest_tasks_pagination_page": "Page", + "admin_contest_tasks_pagination_of": "of", + "admin_contest_tasks_pagination_rows_per_page": "Rows per page", + "admin_contest_tasks_pagination_total": "{total} total tasks", + "admin_contest_tasks_pagination_prev": "Previous", + "admin_contest_tasks_pagination_next": "Next", + "admin_contest_tasks_pagination_showing_range": "Showing {from}-{to} of {total} tasks", "admin_registration_requests_approve": "Approve", "admin_registration_requests_email": "Email", "admin_registration_requests_load_error": "Failed to load registration requests", diff --git a/messages/pl.json b/messages/pl.json index 87befe4..93fd026 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -9,9 +9,8 @@ "admin_contests_card_start": "Początek:", "admin_contests_card_tasks": "Zadania", "admin_contests_card_user_prefix": "Użytkownik #", - "admin_contests_card_view_tasks": "Zobacz Zadania Konkursu", + "admin_contests_card_manage_tasks": "Zarządzaj Zadania", "admin_contests_card_view_requests": "Prośby o Rejestrację", - "admin_contests_card_add_tasks": "Dodaj Zadania do Konkursu", "admin_contests_create_description": "Skonfiguruj nowy konkurs programistyczny", "admin_contests_create_error": "Nie udało się utworzyć konkursu", "admin_contests_create_success": "Konkurs został pomyślnie utworzony!", @@ -80,6 +79,30 @@ "admin_contest_tasks_remove_cancel": "Anuluj", "admin_contest_tasks_remove_success": "Zadanie zostało pomyślnie usunięte z konkursu!", "admin_contest_tasks_remove_error": "Nie udało się usunąć zadania z konkursu", + "admin_contest_tasks_manage_title": "Zarządzaj Zadaniami Konkursu", + "admin_contest_tasks_added": "Dodane Zadania", + "admin_contest_tasks_search_placeholder": "Szukaj zadań...", + "admin_contest_tasks_no_results_title": "Nie znaleziono zadań", + "admin_contest_tasks_column_creator": "Autor", + "admin_contest_tasks_edit_schedule_title": "Edytuj Harmonogram", + "admin_contest_tasks_edit_dialog_title": "Edytuj Harmonogram Zadania", + "admin_contest_tasks_edit_dialog_description": "Zaktualizuj, kiedy to zadanie będzie dostępne w konkursie.", + "admin_contest_tasks_update_button": "Zapisz Zmiany", + "admin_contest_tasks_update_success": "Harmonogram zadania zaktualizowany pomyślnie!", + "admin_contest_tasks_update_error": "Nie udało się zaktualizować harmonogramu zadania", + "admin_contest_tasks_column_id": "ID", + "admin_contest_tasks_column_title": "Tytuł", + "admin_contest_tasks_column_start_at": "Dostępne od", + "admin_contest_tasks_column_end_at": "Dostępne do", + "admin_contest_tasks_column_created_at": "Utworzono", + "admin_contest_tasks_column_actions": "Akcje", + "admin_contest_tasks_pagination_page": "Strona", + "admin_contest_tasks_pagination_of": "z", + "admin_contest_tasks_pagination_rows_per_page": "Wierszy na stronę", + "admin_contest_tasks_pagination_total": "{total} zadań łącznie", + "admin_contest_tasks_pagination_prev": "Poprzednia", + "admin_contest_tasks_pagination_next": "Następna", + "admin_contest_tasks_pagination_showing_range": "Wyświetlanie {from}-{to} z {total} zadań", "admin_registration_requests_approve": "Zatwierdź", "admin_registration_requests_email": "Email", "admin_registration_requests_load_error": "Nie udało się załadować próśb o rejestrację", diff --git a/src/lib/components/dashboard/admin/contests/AddedContestTasksList.svelte b/src/lib/components/dashboard/admin/contests/AddedContestTasksList.svelte new file mode 100644 index 0000000..8839ef8 --- /dev/null +++ b/src/lib/components/dashboard/admin/contests/AddedContestTasksList.svelte @@ -0,0 +1,288 @@ + + +
+ +
+
+ + +
+ +
+
+ {m.admin_contest_tasks_pagination_showing_range({ + from: total === 0 ? 0 : offset + 1, + to: Math.min(offset + contestTasks.length, total), + total + })} +
+
+ {m.admin_contest_tasks_pagination_rows_per_page()}: + +
+
+ {m.admin_contest_tasks_pagination_page()} + {currentPage} + {m.admin_contest_tasks_pagination_of()} + {totalPages} +
+
+
+ + + + + + + + + + + + + + + + + + + {m.admin_contest_tasks_column_actions()} + + + + + {#if contestTasks.length === 0} + + + {m.admin_contest_tasks_no_results_title()} + + + {:else} + {#each contestTasks as contestTask (contestTask.task.id)} + + {contestTask.task.id} + +
+ + + + + {contestTask.task.title} + + + {contestTask.task.title} + +
+
+ + +
+ + {formatDate(contestTask.startAt)} +
+
+ + {#if contestTask.endAt} +
+ + {formatDate(contestTask.endAt)} +
+ {:else} + {m.admin_contest_tasks_no_end_date()} + {/if} +
+ +
+ + +
+
+
+ {/each} + {/if} +
+
+ + {#if total > 0} +
+ { + if (p && p !== currentPage) offset = getOffset(p, limit); + }} + > + + + {m.admin_contest_tasks_pagination_prev()} + + + {#each paginationPages as p (p)} + {#if p === 'ellipsis'} + + + + {:else} + + + + {/if} + {/each} + + + {m.admin_contest_tasks_pagination_next()} + + + + +
+ {m.admin_contest_tasks_pagination_total({ total })} +
+
+ {/if} +
diff --git a/src/lib/components/dashboard/admin/contests/AssignableContestTasksList.svelte b/src/lib/components/dashboard/admin/contests/AssignableContestTasksList.svelte new file mode 100644 index 0000000..d5b650c --- /dev/null +++ b/src/lib/components/dashboard/admin/contests/AssignableContestTasksList.svelte @@ -0,0 +1,256 @@ + + +
+ +
+
+ + +
+ +
+
+ {m.admin_contest_tasks_pagination_showing_range({ + from: total === 0 ? 0 : offset + 1, + to: Math.min(offset + tasks.length, total), + total + })} +
+
+ {m.admin_contest_tasks_pagination_rows_per_page()}: + +
+
+ {m.admin_contest_tasks_pagination_page()} + {currentPage} + {m.admin_contest_tasks_pagination_of()} + {totalPages} +
+
+
+ + + + + + + + + + + + + + {m.admin_contest_tasks_column_actions()} + + + + + {#if tasks.length === 0} + + + {m.admin_contest_tasks_no_results_title()} + + + {:else} + {#each tasks as task (task.id)} + + {task.id} + +
+ + + + + {task.title} + + + {task.title} + +
+
+ + + + + +
+ {/each} + {/if} +
+
+ + {#if total > 0} +
+ { + if (p && p !== currentPage) offset = getOffset(p, limit); + }} + > + + + {m.admin_contest_tasks_pagination_prev()} + + + {#each paginationPages as p (p)} + {#if p === 'ellipsis'} + + + + {:else} + + + + {/if} + {/each} + + + {m.admin_contest_tasks_pagination_next()} + + + + +
+ {m.admin_contest_tasks_pagination_total({ total })} +
+
+ {/if} +
diff --git a/src/lib/components/dashboard/admin/contests/index.ts b/src/lib/components/dashboard/admin/contests/index.ts index 233ffa3..eaa35cd 100644 --- a/src/lib/components/dashboard/admin/contests/index.ts +++ b/src/lib/components/dashboard/admin/contests/index.ts @@ -10,3 +10,5 @@ export { default as RemoveGroupFromContestButton } from './RemoveGroupFromContes export { default as AddParticipantsToContestButton } from './AddParticipantsToContestButton.svelte'; export { default as RemoveParticipantFromContestButton } from './RemoveParticipantFromContestButton.svelte'; export { default as ParticipantsList } from './ParticipantsList.svelte'; +export { default as AddedContestTasksList } from './AddedContestTasksList.svelte'; +export { default as AssignableContestTasksList } from './AssignableContestTasksList.svelte'; diff --git a/src/lib/components/dashboard/contests/AdminContestCard.svelte b/src/lib/components/dashboard/contests/AdminContestCard.svelte index 55b804b..6e13c28 100644 --- a/src/lib/components/dashboard/contests/AdminContestCard.svelte +++ b/src/lib/components/dashboard/contests/AdminContestCard.svelte @@ -10,7 +10,6 @@ import UserCheck from '@lucide/svelte/icons/user-check'; import FileText from '@lucide/svelte/icons/file-text'; import Edit from '@lucide/svelte/icons/pencil'; - import Plus from '@lucide/svelte/icons/plus'; import type { CreatedContest } from '$lib/dto/contest'; import * as m from '$lib/paraglide/messages'; import { localizeHref } from '$lib/paraglide/runtime'; @@ -138,15 +137,7 @@ href={localizeHref(`${AppRoutes.TeacherContests}/${contest.id}/tasks`)} > - {m.admin_contests_card_view_tasks()} - - - - - - {/each} - - {/if} - - - - - - - - {m.admin_contest_tasks_dialog_title()} - - {m.admin_contest_tasks_dialog_description()} - - - -
-
- -
- - -
- - {m.admin_contests_form_start_date()} - - - - - {startDate - ? df.format(startDate.toDate(getLocalTimeZone())) - : m.admin_contests_form_pick_date()} - - - - - -
- -
- - -
-
- - -
-
- - -
- - {#if hasEndTime} -
- - {m.admin_contests_form_end_date()} - - - - - {endDate - ? df.format(endDate.toDate(getLocalTimeZone())) - : m.admin_contests_form_pick_date()} - - - - - -
- -
- - -
- {/if} -
-
- - - - - -
-
-
diff --git a/src/routes/dashboard/teacher/contests/[contestId]/tasks/+page.svelte b/src/routes/dashboard/teacher/contests/[contestId]/tasks/+page.svelte index 8261cd0..d020596 100644 --- a/src/routes/dashboard/teacher/contests/[contestId]/tasks/+page.svelte +++ b/src/routes/dashboard/teacher/contests/[contestId]/tasks/+page.svelte @@ -1,33 +1,230 @@
@@ -45,155 +242,202 @@
- -
- {#if tasksQuery.error} - tasksQuery.refresh()} - /> - {:else if tasksQuery.loading} - - {:else if tasksQuery.current && tasksQuery.current.length === 0} - - {:else if tasksQuery.current} -
- {#each tasksQuery.current as contestTask (contestTask.task.id)} -
-
- -
-
-
{contestTask.task.title}
-
- {m.admin_contest_tasks_task_id()}: {contestTask.task.id} -
-
-
- {#if contestTask.isSubmissionOpen} - - - {m.admin_contest_tasks_submission_open_yes()} - - {:else} - - - {m.admin_contest_tasks_submission_open_no()} - - {/if} - - tasksQuery.refresh()} - /> -
-
- - -
-
- -
-
- {m.admin_contest_tasks_creator_name()} -
-
- {contestTask.creatorName} -
-
-
- -
- -
-
- {m.admin_contest_tasks_created_at()} -
-
- {formatDate(contestTask.task.createdAt)} -
-
-
- -
- -
-
- {m.admin_contest_tasks_updated_at()} -
-
- {formatDate(contestTask.task.updatedAt)} -
-
-
- -
- -
-
- {m.admin_contest_tasks_start_at()} -
-
- {formatDate(contestTask.startAt)} -
-
-
- -
- -
-
- {m.admin_contest_tasks_end_at()} -
-
- {#if contestTask.endAt} - {formatDate(contestTask.endAt)} - {:else} - {m.admin_contest_tasks_no_end_date()} - {/if} -
-
-
- -
- -
-
- {m.admin_contest_tasks_created_by_id()} -
-
- {contestTask.task.createdBy} -
-
-
-
-
-
- {/each} -
- {/if} +
+ +
+

{m.admin_contest_tasks_added()}

+ + {#if addedTasksQuery.error} + addedTasksQuery.refresh()} + /> + {:else if !addedTasksQuery.current && addedTasksQuery.loading} + + {:else if addedTasksQuery.current} + + {/if} +
+ + +
+

{m.admin_contest_tasks_available()}

+ + {#if assignableTasksQuery.error} + assignableTasksQuery.refresh()} + /> + {:else if !assignableTasksQuery.current && assignableTasksQuery.loading} + + {:else if assignableTasksQuery.current} + + {/if} +
+ + + + + + + {dialogMode === 'edit' + ? m.admin_contest_tasks_edit_dialog_title() + : m.admin_contest_tasks_dialog_title()} + + + {dialogMode === 'edit' + ? m.admin_contest_tasks_edit_dialog_description() + : m.admin_contest_tasks_dialog_description()} + + + +
+
+ +
+ + +
+ + {m.admin_contests_form_start_date()} + + + + + {startDate + ? df.format(startDate.toDate(getLocalTimeZone())) + : m.admin_contests_form_pick_date()} + + + + + +
+ +
+ + +
+
+ + +
+
+ + +
+ + {#if hasEndTime} +
+ + {m.admin_contests_form_end_date()} + + + + + {endDate + ? df.format(endDate.toDate(getLocalTimeZone())) + : m.admin_contests_form_pick_date()} + + + + + +
+ +
+ + +
+ {/if} +
+
+ + + + + +
+
+