From 4e7e44169b170ba96708cd0bbcf71425ece47fac Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 18 Dec 2025 19:19:29 +0000
Subject: [PATCH 1/4] Initial plan
From 8e986ab954d62b720fa0bb8fe4ea878ce309d325 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 18 Dec 2025 19:27:10 +0000
Subject: [PATCH 2/4] Add groups listing functionality with remote function and
UI components
Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
---
messages/en.json | 11 +++
messages/pl.json | 11 +++
.../dashboard/admin/groups/GroupsList.svelte | 16 ++++
.../dashboard/admin/groups/index.ts | 1 +
.../dashboard/groups/AdminGroupCard.svelte | 77 +++++++++++++++++++
src/lib/dto/group.ts | 7 ++
src/lib/services/GroupsManagementService.ts | 30 ++++++++
src/lib/services/index.ts | 1 +
.../dashboard/teacher/groups/+page.svelte | 38 +++++++++
.../dashboard/teacher/groups/groups.remote.ts | 17 ++++
10 files changed, 209 insertions(+)
create mode 100644 src/lib/components/dashboard/admin/groups/GroupsList.svelte
create mode 100644 src/lib/components/dashboard/admin/groups/index.ts
create mode 100644 src/lib/components/dashboard/groups/AdminGroupCard.svelte
create mode 100644 src/lib/dto/group.ts
create mode 100644 src/lib/services/GroupsManagementService.ts
create mode 100644 src/routes/dashboard/teacher/groups/+page.svelte
create mode 100644 src/routes/dashboard/teacher/groups/groups.remote.ts
diff --git a/messages/en.json b/messages/en.json
index 7e4a072..4886664 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -559,6 +559,17 @@
"admin_tasks_remove_cancel_button": "Cancel",
"admin_tasks_remove_success": "Task deleted successfully!",
"admin_tasks_remove_error": "Failed to delete task",
+ "admin_groups_title": "Groups Management",
+ "admin_groups_all_groups": "All Groups",
+ "admin_groups_card_created": "Created:",
+ "admin_groups_card_updated": "Updated:",
+ "admin_groups_card_created_by": "Created By:",
+ "admin_groups_card_id_prefix": "#",
+ "admin_groups_card_user_prefix": "User #",
+ "admin_groups_card_view_details": "View Group",
+ "admin_groups_load_error_title": "Failed to load groups",
+ "admin_groups_no_groups_title": "No groups yet",
+ "admin_groups_no_groups_description": "Create your first group to get started",
"task_collaborators_add_title": "Add Collaborator",
"task_collaborators_add_description": "Add a new collaborator to this task",
"task_collaborators_add_dialog_title": "Add Collaborator",
diff --git a/messages/pl.json b/messages/pl.json
index ef78b41..a1bc1c0 100644
--- a/messages/pl.json
+++ b/messages/pl.json
@@ -559,6 +559,17 @@
"admin_tasks_remove_cancel_button": "Anuluj",
"admin_tasks_remove_success": "Zadanie zostało pomyślnie usunięte!",
"admin_tasks_remove_error": "Nie udało się usunąć zadania",
+ "admin_groups_title": "Zarządzanie Grupami",
+ "admin_groups_all_groups": "Wszystkie Grupy",
+ "admin_groups_card_created": "Utworzono:",
+ "admin_groups_card_updated": "Zaktualizowano:",
+ "admin_groups_card_created_by": "Utworzone przez:",
+ "admin_groups_card_id_prefix": "#",
+ "admin_groups_card_user_prefix": "Użytkownik #",
+ "admin_groups_card_view_details": "Zobacz Grupę",
+ "admin_groups_load_error_title": "Nie udało się załadować grup",
+ "admin_groups_no_groups_title": "Brak grup",
+ "admin_groups_no_groups_description": "Utwórz swoją pierwszą grupę, aby zacząć",
"task_collaborators_add_title": "Dodaj Współpracownika",
"task_collaborators_add_description": "Dodaj nowego współpracownika do tego zadania",
"task_collaborators_add_dialog_title": "Dodaj Współpracownika",
diff --git a/src/lib/components/dashboard/admin/groups/GroupsList.svelte b/src/lib/components/dashboard/admin/groups/GroupsList.svelte
new file mode 100644
index 0000000..59e1181
--- /dev/null
+++ b/src/lib/components/dashboard/admin/groups/GroupsList.svelte
@@ -0,0 +1,16 @@
+
+
+
+ {#each groups as group (group.id)}
+
+ {/each}
+
diff --git a/src/lib/components/dashboard/admin/groups/index.ts b/src/lib/components/dashboard/admin/groups/index.ts
new file mode 100644
index 0000000..47bd09b
--- /dev/null
+++ b/src/lib/components/dashboard/admin/groups/index.ts
@@ -0,0 +1 @@
+export { default as GroupsList } from './GroupsList.svelte';
diff --git a/src/lib/components/dashboard/groups/AdminGroupCard.svelte b/src/lib/components/dashboard/groups/AdminGroupCard.svelte
new file mode 100644
index 0000000..b08a08f
--- /dev/null
+++ b/src/lib/components/dashboard/groups/AdminGroupCard.svelte
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+ {m.admin_groups_card_id_prefix()}{group.id}
+
+
+
+
+ {group.name}
+
+
+
+
+
+
+
+
+ {m.admin_groups_card_created()}
+ {formatDate(group.createdAt)}
+
+
+
+
+ {m.admin_groups_card_updated()}
+ {formatDate(group.updatedAt)}
+
+
+
+
+ {m.admin_groups_card_created_by()}
+ {m.admin_groups_card_user_prefix()}{group.createdBy}
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/dto/group.ts b/src/lib/dto/group.ts
new file mode 100644
index 0000000..b3142f4
--- /dev/null
+++ b/src/lib/dto/group.ts
@@ -0,0 +1,7 @@
+export interface Group {
+ id: number;
+ name: string;
+ createdAt: string;
+ updatedAt: string;
+ createdBy: number;
+}
diff --git a/src/lib/services/GroupsManagementService.ts b/src/lib/services/GroupsManagementService.ts
new file mode 100644
index 0000000..445418e
--- /dev/null
+++ b/src/lib/services/GroupsManagementService.ts
@@ -0,0 +1,30 @@
+import { ApiError, type ApiService } from './ApiService';
+import type { ApiResponse, PaginatedData } from '../dto/response';
+import type { Group } from '../dto/group';
+
+export class GroupsManagementService {
+ constructor(private apiClient: ApiService) {}
+
+ async getGroups(): Promise<{
+ success: boolean;
+ status: number;
+ data?: Group[];
+ error?: string;
+ }> {
+ try {
+ const response = await this.apiClient.get>>({
+ url: '/groups-management/groups'
+ });
+ return { success: true, data: response.data.items, status: 200 };
+ } catch (error) {
+ if (error instanceof ApiError) {
+ return {
+ success: false,
+ error: error.getApiMessage(),
+ status: error.getStatus()
+ };
+ }
+ throw error;
+ }
+ }
+}
diff --git a/src/lib/services/index.ts b/src/lib/services/index.ts
index 444f203..843b69e 100644
--- a/src/lib/services/index.ts
+++ b/src/lib/services/index.ts
@@ -6,6 +6,7 @@ export {
ContestsManagementService,
createContestsManagementService
} from './ContestsManagementService';
+export { GroupsManagementService } from './GroupsManagementService';
export { SubmissionService } from './SubmissionService';
export { TaskService, createTaskService } from './TaskService';
export { TasksManagementService } from './TasksManagementService';
diff --git a/src/routes/dashboard/teacher/groups/+page.svelte b/src/routes/dashboard/teacher/groups/+page.svelte
new file mode 100644
index 0000000..69811e8
--- /dev/null
+++ b/src/routes/dashboard/teacher/groups/+page.svelte
@@ -0,0 +1,38 @@
+
+
+
+
+
{m.admin_groups_title()}
+
+
+
+
+
{m.admin_groups_all_groups()}
+
+ {#if groupsQuery.error}
+ groupsQuery.refresh()}
+ />
+ {:else if groupsQuery.loading}
+
+ {:else if groupsQuery.current && groupsQuery.current.length === 0}
+
+ {:else if groupsQuery.current}
+
+ {/if}
+
+
diff --git a/src/routes/dashboard/teacher/groups/groups.remote.ts b/src/routes/dashboard/teacher/groups/groups.remote.ts
new file mode 100644
index 0000000..dfdd025
--- /dev/null
+++ b/src/routes/dashboard/teacher/groups/groups.remote.ts
@@ -0,0 +1,17 @@
+import { query, getRequestEvent } from '$app/server';
+import { createApiClient } from '$lib/services/ApiService';
+import { GroupsManagementService } from '$lib/services/GroupsManagementService';
+import { error } from '@sveltejs/kit';
+
+export const getGroups = query(async () => {
+ const event = getRequestEvent();
+ const apiClient = createApiClient(event.cookies);
+ const groupsManagementService = new GroupsManagementService(apiClient);
+
+ const result = await groupsManagementService.getGroups();
+ if (!result.success || !result.data) {
+ error(result.status, { message: result.error || 'Failed to fetch groups.' });
+ }
+
+ return result.data;
+});
From 5f10c24416bfff19aeac90649be55e148fc7ac8c Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 18 Dec 2025 19:29:08 +0000
Subject: [PATCH 3/4] Fix GroupsManagementService to expect array response
instead of paginated data
Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
---
src/lib/services/GroupsManagementService.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lib/services/GroupsManagementService.ts b/src/lib/services/GroupsManagementService.ts
index 445418e..15b1361 100644
--- a/src/lib/services/GroupsManagementService.ts
+++ b/src/lib/services/GroupsManagementService.ts
@@ -12,10 +12,10 @@ export class GroupsManagementService {
error?: string;
}> {
try {
- const response = await this.apiClient.get>>({
+ const response = await this.apiClient.get>({
url: '/groups-management/groups'
});
- return { success: true, data: response.data.items, status: 200 };
+ return { success: true, data: response.data, status: 200 };
} catch (error) {
if (error instanceof ApiError) {
return {
From 49027e3b8c2de2e4aed6ad23f2de2fb54f5b9a40 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 18 Dec 2025 19:32:35 +0000
Subject: [PATCH 4/4] Remove unused PaginatedData import from
GroupsManagementService
Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
---
src/lib/services/GroupsManagementService.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/services/GroupsManagementService.ts b/src/lib/services/GroupsManagementService.ts
index 15b1361..69da877 100644
--- a/src/lib/services/GroupsManagementService.ts
+++ b/src/lib/services/GroupsManagementService.ts
@@ -1,5 +1,5 @@
import { ApiError, type ApiService } from './ApiService';
-import type { ApiResponse, PaginatedData } from '../dto/response';
+import type { ApiResponse } from '../dto/response';
import type { Group } from '../dto/group';
export class GroupsManagementService {