diff --git a/src/Portfolio.Web/Components/App.razor b/src/Portfolio.Web/Components/App.razor
index d0c615a..46936de 100644
--- a/src/Portfolio.Web/Components/App.razor
+++ b/src/Portfolio.Web/Components/App.razor
@@ -14,6 +14,9 @@
+
+
+
diff --git a/src/Portfolio.Web/Components/Components/FancyButton.razor b/src/Portfolio.Web/Components/Components/FancyButton.razor
new file mode 100644
index 0000000..7024f39
--- /dev/null
+++ b/src/Portfolio.Web/Components/Components/FancyButton.razor
@@ -0,0 +1,13 @@
+
+ @Text
+
+
+
+
+
+@code {
+
+ [Parameter]
+ public required string Text { get; set; }
+
+}
\ No newline at end of file
diff --git a/src/Portfolio.Web/Components/Components/FancyButton.razor.css b/src/Portfolio.Web/Components/Components/FancyButton.razor.css
new file mode 100644
index 0000000..cb8d6a1
--- /dev/null
+++ b/src/Portfolio.Web/Components/Components/FancyButton.razor.css
@@ -0,0 +1,54 @@
+.button {
+ position: relative;
+ width: 150px;
+ height: 40px;
+ background-color: transparent;
+ border: none;
+ color: var(--text);
+ font-size: 15px;
+ border-radius: 10px;
+ cursor: pointer;
+ max-width: 100%;
+ overflow: hidden;
+ z-index: 1;
+
+ &:before {
+ content: '';
+ position: absolute;
+ background-color: hsl(217, 41%, 15%);
+ border-radius: 50%;
+ width: 150px;
+ height: 150px;
+ transform: scale(0);
+ transition: transform 200ms ease-in-out;
+ z-index: -1;
+
+ top: 50%;
+ left: 50%;
+ translate: -50% -50%;
+ }
+}
+
+button svg {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+}
+
+button rect {
+ stroke: hsl(0, 0%, 70%);
+ stroke-dasharray: 460;
+ stroke-dashoffset: 460;
+ stroke-width: 2px;
+ transition: stroke-dashoffset 500ms ease-in-out;
+}
+
+button:hover rect {
+ stroke-dashoffset: 0;
+}
+
+button:hover:before {
+ transform: scale(1);
+}
diff --git a/src/Portfolio.Web/Components/Components/ProjectView.razor b/src/Portfolio.Web/Components/Components/ProjectView.razor
new file mode 100644
index 0000000..b0693f8
--- /dev/null
+++ b/src/Portfolio.Web/Components/Components/ProjectView.razor
@@ -0,0 +1,45 @@
+@using Portfolio.Shared.Models
+
+
+
+
+
@Project.Name
+
+
+
+ @foreach (var language in Project.Languages) {
+ var imgClass = "devicon-" + language.Identifier + "-" + (!string.IsNullOrEmpty(language.Suffix) ? language.Suffix : "plain");
+
+
+ }
+
+
+
@GetStatusName()
+
+
+
@Project.Description
+
+
+
+
+
+@code {
+
+ [Parameter]
+ public required Project Project { get; set; }
+
+ private string GetStatusName() {
+ return Project.Status switch {
+ ProjectStatus.Finished => "Fertig",
+ ProjectStatus.Canceled => "Abgebrochen",
+ ProjectStatus.Paused => "Angehalten",
+ ProjectStatus.Development => "Aktiv",
+ _ => ""
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/src/Portfolio.Web/Components/Components/ProjectView.razor.css b/src/Portfolio.Web/Components/Components/ProjectView.razor.css
new file mode 100644
index 0000000..74bfc65
--- /dev/null
+++ b/src/Portfolio.Web/Components/Components/ProjectView.razor.css
@@ -0,0 +1,59 @@
+.border {
+ position: relative;
+ width: 400px;
+ height: 500px;
+ background: var(--gradient-straight);
+ border-radius: 30px;
+ overflow: hidden;
+ box-shadow: 0 0 40px -10px var(--primary);
+}
+
+.shell {
+ position: absolute;
+ inset: 1px;
+ padding: 1rem;
+ display: flex;
+ flex-direction: column;
+ background-color: var(--background);
+ border-radius: 30px;
+}
+
+img {
+ width: 100%;
+ height: 190px;
+ border-radius: calc(30px - 1rem);
+ object-fit: cover;
+}
+
+h3 {
+ margin-block: 10px;
+ font-size: 1.25rem;
+ font-weight: normal;
+}
+
+.status, .language-container i, p {
+ color: var(--desc-color);
+}
+
+.info {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 0.5rem;
+}
+
+.language-container {
+ margin-bottom: 10px;
+ display: flex;
+ gap: 5px;
+ font-size: 20px;
+}
+
+p {
+ margin: 0;
+}
+
+.button-container {
+ margin-top: auto;
+ display: flex;
+ justify-content: center;
+}
diff --git a/src/Portfolio.Web/Components/Layout/Navigation.razor.css b/src/Portfolio.Web/Components/Layout/Navigation.razor.css
index 407a864..413a245 100644
--- a/src/Portfolio.Web/Components/Layout/Navigation.razor.css
+++ b/src/Portfolio.Web/Components/Layout/Navigation.razor.css
@@ -6,6 +6,7 @@
background-color: var(--background);
border-bottom: 1px solid var(--border-color);
padding-inline: 0.5rem;
+ z-index: 100;
}
.links {
diff --git a/src/Portfolio.Web/Components/Pages/Home.razor b/src/Portfolio.Web/Components/Pages/Home.razor
index 8902f34..6ec3cf9 100644
--- a/src/Portfolio.Web/Components/Pages/Home.razor
+++ b/src/Portfolio.Web/Components/Pages/Home.razor
@@ -3,5 +3,3 @@
Portfolio von Leon Hoppe
Hello, world!
-
-Welcome to your new app.
\ No newline at end of file
diff --git a/src/Portfolio.Web/Components/Pages/ProjectsPage.razor b/src/Portfolio.Web/Components/Pages/ProjectsPage.razor
new file mode 100644
index 0000000..30dd18f
--- /dev/null
+++ b/src/Portfolio.Web/Components/Pages/ProjectsPage.razor
@@ -0,0 +1,23 @@
+@page "/projects"
+@using Portfolio.Shared.Models
+@using Portfolio.Shared.Services
+@using Portfolio.Web.Components.Components
+
+Alle Projekte
+
+
+ @foreach (var project in _projects) {
+
+ }
+
+
+@inherits CancellableComponent
+@inject IProjectRepository ProjectRepo
+
+@code {
+ private IEnumerable _projects = [];
+
+ protected override async Task OnInitializedAsync() {
+ _projects = await ProjectRepo.GetProjects(TokenSource.Token);
+ }
+}
\ No newline at end of file
diff --git a/src/Portfolio.Web/Components/Pages/ProjectsPage.razor.css b/src/Portfolio.Web/Components/Pages/ProjectsPage.razor.css
new file mode 100644
index 0000000..f4aaa5e
--- /dev/null
+++ b/src/Portfolio.Web/Components/Pages/ProjectsPage.razor.css
@@ -0,0 +1,13 @@
+.project-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 100px;
+ justify-content: space-evenly;
+}
+
+h2 {
+ margin-top: 3rem;
+ margin-bottom: 5rem;
+ font-size: 2rem;
+ font-weight: 600;
+}