diff --git a/webapp/src/app/app.component.ts b/webapp/src/app/app.component.ts
index 41c404cf..eb7377c8 100644
--- a/webapp/src/app/app.component.ts
+++ b/webapp/src/app/app.component.ts
@@ -2,7 +2,7 @@ import { Component, isDevMode } from '@angular/core';
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental';
import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router';
import { LucideAngularModule, Hammer } from 'lucide-angular';
-import { ThemeSwitcherComponent } from './components/theme-switcher/theme-switcher.component';
+import { ThemeSwitcherComponent } from 'app/core/theme/theme-switcher.component';
@Component({
selector: 'app-root',
diff --git a/webapp/src/app/app.routes.ts b/webapp/src/app/app.routes.ts
index 9060460d..4ddba63d 100644
--- a/webapp/src/app/app.routes.ts
+++ b/webapp/src/app/app.routes.ts
@@ -1,8 +1,8 @@
import { Routes } from '@angular/router';
import { AboutComponent } from 'app/about/about.component';
-import { MainComponent } from 'app/main/main.component';
+import { HomeComponent } from 'app/home/home.component';
export const routes: Routes = [
- { path: '', component: MainComponent },
+ { path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
diff --git a/webapp/src/app/components/leaderboard/leaderboard.component.html b/webapp/src/app/components/leaderboard/leaderboard.component.html
deleted file mode 100644
index 04815e8a..00000000
--- a/webapp/src/app/components/leaderboard/leaderboard.component.html
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
Artemis Leaderboard
- @if (query.isPending()) {
-
Data is loading...
- } @else if (query.error()) {
-
An error has occurred
- }
-
- @if (leaderboard(); as leaderboard) {
-
-
-
-
- Rank |
- Contributor |
- Score |
- Activity |
-
-
-
- @for (entry of leaderboard; track entry.githubName) {
-
- {{ entry.rank }} |
-
-
-
- {{ entry.name }}
-
- |
- {{ entry.score }} |
-
- @if (entry.changesRequested && entry.changesRequested > 0) {
-
-
- {{ entry.changesRequested }}
-
- }
- @if (entry.approvals && entry.approvals > 0) {
-
-
- {{ entry.approvals }}
-
- }
- @if (entry.comments && entry.comments > 0) {
-
-
- {{ entry.comments }}
-
- }
- |
-
- }
-
-
-
- }
-
diff --git a/webapp/src/app/components/leaderboard/leaderboard.component.ts b/webapp/src/app/components/leaderboard/leaderboard.component.ts
deleted file mode 100644
index 24757f6f..00000000
--- a/webapp/src/app/components/leaderboard/leaderboard.component.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
-import { injectQuery } from '@tanstack/angular-query-experimental';
-import { NgIconComponent } from '@ng-icons/core';
-import { octFileDiff, octCheck, octComment } from '@ng-icons/octicons';
-import { LeaderboardEntry, LeaderboardService } from 'app/core/modules/openapi';
-import { TableBodyDirective } from 'app/ui/table/table-body.directive';
-import { TableCaptionDirective } from 'app/ui/table/table-caption.directive';
-import { TableCellDirective } from 'app/ui/table/table-cell.directive';
-import { TableFooterDirective } from 'app/ui/table/table-footer.directive';
-import { TableHeadDirective } from 'app/ui/table/table-head.directive';
-import { TableHeaderDirective } from 'app/ui/table/table-header.directive';
-import { TableRowDirective } from 'app/ui/table/table-row.directive';
-import { TableComponent } from 'app/ui/table/table.component';
-import { lastValueFrom } from 'rxjs';
-
-const defaultData: LeaderboardEntry[] = [
- {
- githubName: 'shadcn',
- avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
- type: LeaderboardEntry.TypeEnum.User,
- name: 'I',
- score: 90,
- changesRequested: 0,
- approvals: 0,
- comments: 0
- },
- {
- githubName: 'shadcn',
- avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
- type: LeaderboardEntry.TypeEnum.User,
- name: 'A',
- score: 10,
- changesRequested: 1,
- approvals: 0,
- comments: 0
- },
- {
- githubName: 'shadcn',
- avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
- type: LeaderboardEntry.TypeEnum.User,
- name: 'B',
- score: 20,
- changesRequested: 0,
- approvals: 1,
- comments: 0
- },
- {
- githubName: 'shadcn',
- avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
- type: LeaderboardEntry.TypeEnum.User,
- name: 'C',
- score: 30,
- changesRequested: 0,
- approvals: 0,
- comments: 1
- },
- {
- githubName: 'shadcn',
- avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
- type: LeaderboardEntry.TypeEnum.User,
- name: 'D',
- score: 40,
- changesRequested: 0,
- approvals: 0,
- comments: 0
- },
- {
- githubName: 'shadcn',
- avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
- type: LeaderboardEntry.TypeEnum.User,
- name: 'E',
- score: 50,
- changesRequested: 0,
- approvals: 0,
- comments: 0
- },
- {
- githubName: 'shadcn',
- avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
- type: LeaderboardEntry.TypeEnum.User,
- name: 'F',
- score: 60,
- changesRequested: 0,
- approvals: 0,
- comments: 0
- },
- {
- githubName: 'shadcn',
- avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
- type: LeaderboardEntry.TypeEnum.User,
- name: 'G',
- score: 70,
- changesRequested: 0,
- approvals: 0,
- comments: 0
- },
- {
- githubName: 'shadcn',
- avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
- type: LeaderboardEntry.TypeEnum.User,
- name: 'H',
- score: 80,
- changesRequested: 0,
- approvals: 0,
- comments: 0
- }
-];
-
-@Component({
- selector: 'app-leaderboard',
- standalone: true,
- imports: [
- TableComponent,
- TableBodyDirective,
- TableCaptionDirective,
- TableCellDirective,
- TableFooterDirective,
- TableHeaderDirective,
- TableHeadDirective,
- TableRowDirective,
- NgIconComponent
- ],
- templateUrl: './leaderboard.component.html',
- changeDetection: ChangeDetectionStrategy.OnPush
-})
-export class LeaderboardComponent {
- protected octFileDiff = octFileDiff;
- protected octCheck = octCheck;
- protected octComment = octComment;
-
- leaderboardService = inject(LeaderboardService);
-
- query = injectQuery(() => ({
- queryKey: ['leaderboard'],
- queryFn: async () => lastValueFrom(this.leaderboardService.getLeaderboard()),
- gcTime: Infinity
- }));
-
- leaderboard = computed(() => {
- return this.query.data() ?? defaultData;
- });
-}
diff --git a/webapp/src/app/components/leaderboard/leaderboard.stories.ts b/webapp/src/app/components/leaderboard/leaderboard.stories.ts
deleted file mode 100644
index 421fb862..00000000
--- a/webapp/src/app/components/leaderboard/leaderboard.stories.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { type Meta, type StoryObj } from '@storybook/angular';
-import { LeaderboardComponent } from './leaderboard.component';
-
-const meta: Meta = {
- title: 'Components/Leaderboard',
- component: LeaderboardComponent,
- tags: ['autodocs']
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Default: Story = {
- render: (args) => ({
- props: args,
- template: ``
- })
-};
diff --git a/webapp/src/app/components/theme-switcher/theme-switcher.component.html b/webapp/src/app/core/theme/theme-switcher.component.html
similarity index 100%
rename from webapp/src/app/components/theme-switcher/theme-switcher.component.html
rename to webapp/src/app/core/theme/theme-switcher.component.html
diff --git a/webapp/src/app/components/theme-switcher/theme-switcher.component.ts b/webapp/src/app/core/theme/theme-switcher.component.ts
similarity index 100%
rename from webapp/src/app/components/theme-switcher/theme-switcher.component.ts
rename to webapp/src/app/core/theme/theme-switcher.component.ts
diff --git a/webapp/src/app/components/theme-switcher/theme-switcher.service.ts b/webapp/src/app/core/theme/theme-switcher.service.ts
similarity index 100%
rename from webapp/src/app/components/theme-switcher/theme-switcher.service.ts
rename to webapp/src/app/core/theme/theme-switcher.service.ts
diff --git a/webapp/src/app/components/theme-switcher/theme-switcher.stories.ts b/webapp/src/app/core/theme/theme-switcher.stories.ts
similarity index 94%
rename from webapp/src/app/components/theme-switcher/theme-switcher.stories.ts
rename to webapp/src/app/core/theme/theme-switcher.stories.ts
index 3f00cdb2..a524cd0c 100644
--- a/webapp/src/app/components/theme-switcher/theme-switcher.stories.ts
+++ b/webapp/src/app/core/theme/theme-switcher.stories.ts
@@ -4,7 +4,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
const meta: Meta = {
- title: 'Components/ThemeSwitcher',
+ title: 'Components/Core/ThemeSwitcher',
component: ThemeSwitcherComponent,
tags: ['autodocs'],
decorators: [
diff --git a/webapp/src/app/home/home.component.html b/webapp/src/app/home/home.component.html
new file mode 100644
index 00000000..470f42fb
--- /dev/null
+++ b/webapp/src/app/home/home.component.html
@@ -0,0 +1,11 @@
+
+
Artemis Leaderboard
+ @if (query.isPending()) {
+
Data is loading...
+ } @else if (query.error()) {
+
An error has occurred
+ }
+ @if (query.data()) {
+
+ }
+
diff --git a/webapp/src/app/home/home.component.ts b/webapp/src/app/home/home.component.ts
new file mode 100644
index 00000000..fe173d4d
--- /dev/null
+++ b/webapp/src/app/home/home.component.ts
@@ -0,0 +1,21 @@
+import { Component, inject } from '@angular/core';
+import { injectQuery } from '@tanstack/angular-query-experimental';
+import { LeaderboardService } from 'app/core/modules/openapi/api/leaderboard.service';
+import { LeaderboardComponent } from 'app/home/leaderboard/leaderboard.component';
+import { lastValueFrom } from 'rxjs';
+
+@Component({
+ selector: 'app-home',
+ standalone: true,
+ imports: [LeaderboardComponent],
+ templateUrl: './home.component.html'
+})
+export class HomeComponent {
+ leaderboardService = inject(LeaderboardService);
+
+ query = injectQuery(() => ({
+ queryKey: ['leaderboard'],
+ queryFn: async () => lastValueFrom(this.leaderboardService.getLeaderboard()),
+ gcTime: Infinity
+ }));
+}
diff --git a/webapp/src/app/home/home.stories.ts b/webapp/src/app/home/home.stories.ts
new file mode 100644
index 00000000..d57e1d07
--- /dev/null
+++ b/webapp/src/app/home/home.stories.ts
@@ -0,0 +1,18 @@
+import { type Meta, type StoryObj } from '@storybook/angular';
+import { HomeComponent } from './home.component';
+
+const meta: Meta = {
+ title: 'Pages/Home',
+ component: HomeComponent,
+ tags: ['autodocs']
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ render: (args) => ({
+ props: args,
+ template: ``
+ })
+};
diff --git a/webapp/src/app/home/leaderboard/leaderboard.component.html b/webapp/src/app/home/leaderboard/leaderboard.component.html
new file mode 100644
index 00000000..af9a5c8d
--- /dev/null
+++ b/webapp/src/app/home/leaderboard/leaderboard.component.html
@@ -0,0 +1,49 @@
+
+
+
+ Rank |
+ Contributor |
+ Score |
+ Activity |
+
+
+
+ @for (entry of leaderboard(); track entry.githubName) {
+
+ {{ entry.rank }} |
+
+
+
+
+
+ {{ entry.name?.slice(0, 1)?.toUpperCase() }}
+
+
+ {{ entry.name }}
+
+ |
+ {{ entry.score }} |
+
+ @if (entry.changesRequested && entry.changesRequested > 0) {
+
+
+ {{ entry.changesRequested }}
+
+ }
+ @if (entry.approvals && entry.approvals > 0) {
+
+
+ {{ entry.approvals }}
+
+ }
+ @if (entry.comments && entry.comments > 0) {
+
+
+ {{ entry.comments }}
+
+ }
+ |
+
+ }
+
+
diff --git a/webapp/src/app/home/leaderboard/leaderboard.component.ts b/webapp/src/app/home/leaderboard/leaderboard.component.ts
new file mode 100644
index 00000000..3feb3dc8
--- /dev/null
+++ b/webapp/src/app/home/leaderboard/leaderboard.component.ts
@@ -0,0 +1,42 @@
+import { Component, input } from '@angular/core';
+import { NgIconComponent } from '@ng-icons/core';
+import { octFileDiff, octCheck, octComment } from '@ng-icons/octicons';
+import { LeaderboardEntry } from 'app/core/modules/openapi';
+import { AvatarFallbackComponent } from 'app/ui/avatar/avatar-fallback.component';
+import { AvatarImageComponent } from 'app/ui/avatar/avatar-image.component';
+import { AvatarComponent } from 'app/ui/avatar/avatar.component';
+import { TableBodyDirective } from 'app/ui/table/table-body.directive';
+import { TableCaptionDirective } from 'app/ui/table/table-caption.directive';
+import { TableCellDirective } from 'app/ui/table/table-cell.directive';
+import { TableFooterDirective } from 'app/ui/table/table-footer.directive';
+import { TableHeadDirective } from 'app/ui/table/table-head.directive';
+import { TableHeaderDirective } from 'app/ui/table/table-header.directive';
+import { TableRowDirective } from 'app/ui/table/table-row.directive';
+import { TableComponent } from 'app/ui/table/table.component';
+
+@Component({
+ selector: 'app-leaderboard',
+ standalone: true,
+ imports: [
+ AvatarComponent,
+ AvatarFallbackComponent,
+ AvatarImageComponent,
+ TableComponent,
+ TableBodyDirective,
+ TableCaptionDirective,
+ TableCellDirective,
+ TableFooterDirective,
+ TableHeaderDirective,
+ TableHeadDirective,
+ TableRowDirective,
+ NgIconComponent
+ ],
+ templateUrl: './leaderboard.component.html'
+})
+export class LeaderboardComponent {
+ protected octFileDiff = octFileDiff;
+ protected octCheck = octCheck;
+ protected octComment = octComment;
+
+ leaderboard = input();
+}
diff --git a/webapp/src/app/home/leaderboard/leaderboard.stories.ts b/webapp/src/app/home/leaderboard/leaderboard.stories.ts
new file mode 100644
index 00000000..c3047a25
--- /dev/null
+++ b/webapp/src/app/home/leaderboard/leaderboard.stories.ts
@@ -0,0 +1,69 @@
+import { argsToTemplate, type Meta, type StoryObj } from '@storybook/angular';
+import { LeaderboardComponent } from './leaderboard.component';
+import { LeaderboardEntry } from 'app/core/modules/openapi/model/leaderboard-entry';
+
+const leaderboardEntries: LeaderboardEntry[] = [
+ {
+ githubName: 'GODrums',
+ avatarUrl: 'https://avatars.githubusercontent.com/u/21990230?v=4',
+ type: LeaderboardEntry.TypeEnum.User,
+ name: 'Armin Stanitzok',
+ score: 100,
+ changesRequested: 3,
+ approvals: 5,
+ comments: 1,
+ rank: 1
+ },
+ {
+ githubName: 'FelixTJDietrich',
+ avatarUrl: 'https://avatars.githubusercontent.com/u/5898705?v=4',
+ type: LeaderboardEntry.TypeEnum.User,
+ name: 'Felix T.J. Dietrich',
+ score: 90,
+ changesRequested: 1,
+ approvals: 1,
+ comments: 14,
+ rank: 2
+ },
+ {
+ githubName: 'krusche',
+ avatarUrl: 'https://avatars.githubusercontent.com/u/744067?v=4',
+ type: LeaderboardEntry.TypeEnum.User,
+ name: 'Stephan Krusche',
+ score: 50,
+ changesRequested: 0,
+ approvals: 3,
+ comments: 1,
+ rank: 3
+ },
+ {
+ githubName: 'shadcn',
+ avatarUrl: 'https://avatars.githubusercontent.com/u/124599?v=4',
+ type: LeaderboardEntry.TypeEnum.User,
+ name: 'shadcn',
+ score: 20,
+ changesRequested: 0,
+ approvals: 0,
+ comments: 1,
+ rank: 4
+ }
+];
+
+const meta: Meta = {
+ title: 'Components/Home/Leaderboard',
+ component: LeaderboardComponent,
+ tags: ['autodocs'],
+ args: {
+ leaderboard: leaderboardEntries
+ }
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ render: (args) => ({
+ props: args,
+ template: ``
+ })
+};
diff --git a/webapp/src/app/main/main.component.html b/webapp/src/app/main/main.component.html
deleted file mode 100644
index 9be02e9a..00000000
--- a/webapp/src/app/main/main.component.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/webapp/src/app/main/main.component.ts b/webapp/src/app/main/main.component.ts
deleted file mode 100644
index b7da7157..00000000
--- a/webapp/src/app/main/main.component.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { Component } from '@angular/core';
-import { LeaderboardComponent } from 'app/components/leaderboard/leaderboard.component';
-
-@Component({
- selector: 'app-main',
- standalone: true,
- imports: [LeaderboardComponent],
- templateUrl: './main.component.html'
-})
-export class MainComponent {}