Compare commits

..

8 Commits

9 changed files with 366 additions and 106 deletions
+10 -12
View File
@@ -81,12 +81,10 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
<br> <br>
<form action="php/controller/deleteAccount-controller.php" <form action="php/controller/deleteAccount-controller.php" method="POST">
method="POST"
class="confirm-delete-account">
<button type="submit" <button type="submit"
class="button"> class="button"
onclick="return confirm('Möchtest du deinen Account und alle deine Beiträge wirklich unwiderruflich löschen?');">
Account löschen Account löschen
</button> </button>
</form> </form>
@@ -156,16 +154,14 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
Bearbeiten Bearbeiten
</a> </a>
<form action="php/controller/deleteArticle-controller.php" <form action="php/controller/deleteArticle-controller.php" method="POST">
method="POST"
class="confirm-delete-article">
<input type="hidden" <input type="hidden"
name="id" name="id"
value="<?php echo htmlspecialchars($userArticle->getID()); ?>"> value="<?php echo htmlspecialchars($userArticle->getID()); ?>">
<button type="submit" <button type="submit"
class="button"> class="button"
onclick="return confirm('Möchtest du diesen Artikel wirklich löschen?');">
Löschen Löschen
</button> </button>
</form> </form>
@@ -176,9 +172,11 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
<p>Du hast noch keine Beiträge erstellt.</p> <p>Du hast noch keine Beiträge erstellt.</p>
<a href="index.php?pfad=createArticle" class="button"> <button type="button"
class="button"
onclick="window.location.href='index.php?pfad=createArticle';">
Beitrag erstellen! Beitrag erstellen!
</a> </button>
<?php endif; ?> <?php endif; ?>
</div> </div>
+7 -26
View File
@@ -124,9 +124,7 @@ $categories = [
</div> </div>
<noscript> <noscript>
<button type="submit" class="nav__search-button"> <button type="submit" class="nav__search-button">Filter anwenden</button>
Filter anwenden
</button>
</noscript> </noscript>
</form> </form>
@@ -195,34 +193,17 @@ $categories = [
</div> </div>
<nav class="s-res-page-navigation" aria-label="Seitennavigation"> <nav class="s-res-page-navigation" aria-label="Seitennavigation">
<!-- No-JS-Fallback: -->
<noscript> <noscript>
<?php echo renderNoJsPagination( <?php echo renderNoJsPagination($currentPage, $totalPages, $query, $currentSort, $currentCategory, $limit); ?>
$currentPage,
$totalPages,
$query,
$currentSort,
$currentCategory,
$limit
); ?>
</noscript> </noscript>
<div id="js-page-navigation" style="display: none;"> <!-- JS-Version: wird per search-results.js befüllt/eingeblendet: -->
<button type="button" <div id="js-page-navigation" style="display:none;">
class="s-res-page-btn" <button type="button" class="s-res-page-btn" id="prev-page-btn">«</button>
id="prev-page-btn">
«
</button>
<span id="dynamic-page-numbers"></span> <span id="dynamic-page-numbers"></span>
<button type="button" class="s-res-page-btn" id="next-page-btn">»</button>
<button type="button"
class="s-res-page-btn"
id="next-page-btn">
»
</button>
</div> </div>
</nav> </nav>
</div> </div>
+47 -7
View File
@@ -5,6 +5,30 @@ $repliesByParent = [];
$articleObj = null; $articleObj = null;
include_once 'php/controller/showArticle-controller.php'; include_once 'php/controller/showArticle-controller.php';
require_once 'php/model/UserManager.php';
$userManager = UserManager::getInstance();
/**
* Liefert den vollständigen Namen zu einer gespeicherten E-Mail-Adresse.
* Falls kein Benutzer gefunden wird, wird die E-Mail als Ersatz angezeigt.
*/
function getCommentAuthorName($email, $userManager)
{
$email = trim($email);
$user = $userManager->findUser($email);
if ($user === null) {
return $email;
}
$vorname = trim($user["vorname"] ?? "");
$nachname = trim($user["nachname"] ?? "");
$fullName = trim($vorname . " " . $nachname);
return $fullName !== "" ? $fullName : $email;
}
/* /*
* Ermittelt, ob ohne JavaScript auf einen Kommentar * Ermittelt, ob ohne JavaScript auf einen Kommentar
* geantwortet werden soll. * geantwortet werden soll.
@@ -173,7 +197,14 @@ if ($replyAuthor === null) {
<p> <p>
<strong> <strong>
<?php echo htmlspecialchars($comment->getAuthor()); ?> <?php
echo htmlspecialchars(
getCommentAuthorName(
$comment->getAuthor(),
$userManager
)
);
?>
</strong> </strong>
<span> <span>
@@ -237,7 +268,7 @@ if ($replyAuthor === null) {
<form method="post" <form method="post"
action="index.php?pfad=deleteComment" action="index.php?pfad=deleteComment"
class="delete-comment-form confirm-delete-comment"> class="delete-comment-form">
<input type="hidden" <input type="hidden"
name="comment_id" name="comment_id"
@@ -252,7 +283,8 @@ if ($replyAuthor === null) {
); ?>"> ); ?>">
<button type="submit" <button type="submit"
class="delete-comment-button"> class="delete-comment-button"
onclick="return confirm('Möchtest du diesen Kommentar wirklich löschen?');">
Kommentar löschen Kommentar löschen
</button> </button>
</form> </form>
@@ -303,7 +335,14 @@ if ($replyAuthor === null) {
<p> <p>
<strong> <strong>
<?php echo htmlspecialchars($reply->getAuthor()); ?> <?php
echo htmlspecialchars(
getCommentAuthorName(
$reply->getAuthor(),
$userManager
)
);
?>
</strong> </strong>
<span> <span>
@@ -368,7 +407,7 @@ if ($replyAuthor === null) {
<form method="post" <form method="post"
action="index.php?pfad=deleteComment" action="index.php?pfad=deleteComment"
class="delete-comment-form confirm-delete-comment"> class="delete-comment-form">
<input type="hidden" <input type="hidden"
name="comment_id" name="comment_id"
@@ -383,8 +422,9 @@ if ($replyAuthor === null) {
); ?>"> ); ?>">
<button type="submit" <button type="submit"
class="delete-comment-button"> class="delete-comment-button"
Antwort löschen onclick="return confirm('Möchtest du diesen Kommentar wirklich löschen?');">
Kommentar löschen
</button> </button>
</form> </form>
+194 -5
View File
@@ -154,21 +154,32 @@ h1 {
.button { .button {
width: 100%; width: 100%;
padding: 12px; padding: 14px;
background-color: #2563eb; background-color: #2563eb;
color: white; color: white;
border: none; border: 2px solid transparent;
border-radius: 8px; border-radius: 8px;
font-size: 1rem; font-size: 1rem;
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
transition: background-color 0.2s, transform 0.2s, box-shadow 0.2s; transition:
background-color 0.2s ease,
transform 0.2s ease,
box-shadow 0.2s ease,
border-color 0.2s ease;
} }
.button:hover { .button:hover {
background-color: #1e40af;
border-color: #93c5fd;
transform: translateY(-3px) scale(1.01);
box-shadow: 0 8px 18px rgba(37, 99, 235, 0.35);
}
.button:active {
background-color: #1d4ed8; background-color: #1d4ed8;
transform: translateY(-2px); transform: translateY(1px) scale(0.99);
box-shadow: 0 4px 10px rgba(0,0,0,0.15); box-shadow: 0 2px 5px rgba(37, 99, 235, 0.25);
} }
.register-link { .register-link {
@@ -225,4 +236,182 @@ h1 {
text-align: center; text-align: center;
text-decoration: none; text-decoration: none;
box-sizing: border-box; box-sizing: border-box;
}
/* Deutlichere Klickreaktion für Kategorien */
.category-link:active {
transform: translateY(1px);
box-shadow: none;
}
/* Sichtbare Tastatur-Markierung */
.button:focus-visible,
.category-link:focus-visible,
.article-link a:focus-visible,
.register-link a:focus-visible {
outline: 3px solid #fbbf24;
outline-offset: 3px;
}
/* Kommentarbereich */
#comments-list {
display: flex;
flex-direction: column;
gap: 20px;
margin-bottom: 40px;
}
#comments-list > div,
.comment {
background-color: #ffffff;
border: 1px solid #dbe3ec;
border-radius: 12px;
padding: 24px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
transition:
transform 0.2s ease,
box-shadow 0.2s ease,
border-color 0.2s ease;
}
#comments-list > div:hover,
.comment:hover {
transform: translateY(-3px);
border-color: #93c5fd;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
}
#comments-list textarea,
#comment-content {
width: 100%;
box-sizing: border-box;
padding: 14px;
border: 1px solid #cbd5e1;
border-radius: 8px;
font-size: 1rem;
resize: vertical;
transition:
border-color 0.2s ease,
box-shadow 0.2s ease;
}
#comments-list textarea:focus,
#comment-content:focus {
outline: none;
border-color: #2563eb;
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.18);
}
#comments-list a {
color: #2563eb;
font-weight: bold;
text-decoration: none;
border-radius: 4px;
transition:
color 0.2s ease,
background-color 0.2s ease;
}
#comments-list a:hover {
color: #1e40af;
background-color: #dbeafe;
text-decoration: underline;
}
#comments-list button {
cursor: pointer;
}
.delete-comment-button {
display: inline-block;
background: #ffffff;
color: #dc2626;
border: 2px solid #dc2626;
border-radius: 8px;
padding: 10px 18px;
font-size: 0.95rem;
font-weight: 600;
cursor: pointer;
transition:
background-color 0.25s ease,
color 0.25s ease,
transform 0.2s ease,
box-shadow 0.2s ease;
}
.delete-comment-button:hover {
background: #dc2626;
color: #ffffff;
transform: translateY(-2px);
box-shadow: 0 6px 14px rgba(220,38,38,0.25);
}
.delete-comment-button:active {
transform: translateY(1px);
box-shadow: none;
}
.delete-comment-form {
margin-top: 12px;
margin-bottom: 12px;
}
/* Button zum Öffnen der Kommentarbearbeitung */
.edit-comment-button {
display: inline-block;
width: auto;
padding: 10px 18px;
background-color: #2563eb;
color: #ffffff;
border: 2px solid #2563eb;
border-radius: 8px;
font-size: 0.95rem;
font-weight: 600;
cursor: pointer;
list-style: none;
transition:
background-color 0.2s ease,
border-color 0.2s ease,
transform 0.2s ease,
box-shadow 0.2s ease;
}
/* Entfernt das normale Dreieck in einigen Browsern */
.edit-comment-button::-webkit-details-marker {
display: none;
}
/* Eigenes Symbol vor dem Text */
.edit-comment-button::before {
content: "✏ ";
}
.edit-comment-button:hover {
background-color: #1e40af;
border-color: #1e40af;
transform: translateY(-2px);
box-shadow: 0 5px 12px rgba(37, 99, 235, 0.3);
}
.edit-comment-button:active {
transform: translateY(1px);
box-shadow: none;
}
.edit-comment-button:focus-visible {
outline: 3px solid #fbbf24;
outline-offset: 3px;
}
/* Abstand zwischen Bearbeiten und Löschen */
.edit-comment-details {
margin-bottom: 12px;
}
/* Geöffneter Bearbeitungsbereich */
.edit-comment-details[open] .edit-comment-button {
margin-bottom: 12px;
background-color: #1e40af;
}
/* Geändertes Symbol, wenn der Bereich geöffnet ist */
.edit-comment-details[open] .edit-comment-button::before {
content: "▲ ";
} }
+87 -3
View File
@@ -248,9 +248,9 @@ CSS für die navbar
z-index: 1000; z-index: 1000;
transition: left 0.3s ease; transition: left 0.3s ease;
padding: 2rem 1rem; padding: 2rem 1rem;
box-shadow: 2px 0 10px rgba(0,0,0,0.5); box-shadow: 2px 0 10px rgba(0, 0, 0, 0.5);
overflow-y: auto; overflow-y: auto;
/* Genug Abstand oben rechts, damit Links nicht hinter dem X liegen */ /* Genug Abstand oben rechts, damit Links nicht hinter dem X liegen */
padding: 4rem 1.5rem 2rem 1.5rem; padding: 4rem 1.5rem 2rem 1.5rem;
} }
@@ -302,5 +302,89 @@ CSS für die navbar
padding: 0.8rem 1rem; padding: 0.8rem 1rem;
cursor: pointer; cursor: pointer;
} }
}
/* Deutlichere Hover-Effekte für die Navigation */
} .nav__dropdown-toggle,
.nav__link {
border-radius: 6px;
transition:
background-color 0.2s ease,
color 0.2s ease,
transform 0.2s ease;
}
.nav__dropdown-toggle:hover,
.nav__link:hover {
background-color: #ffffff;
color: #1d4ed8;
transform: translateY(-2px);
}
/* Sichtbare Reaktion beim Anklicken */
.nav__dropdown-toggle:active,
.nav__link:active {
transform: translateY(1px);
}
/* Deutlichere Effekte für Anmelden, Registrieren usw. */
.nav__button {
transition:
background-color 0.2s ease,
color 0.2s ease,
transform 0.2s ease,
box-shadow 0.2s ease;
}
.nav__button:hover {
background-color: #2563eb;
color: #ffffff;
transform: translateY(-2px);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}
.nav__button:active {
transform: translateY(1px);
box-shadow: none;
}
/* Deutlichere Hervorhebung der Einträge im Dropdown-Menü */
.nav__dropdown-menu a {
display: block;
transition:
background-color 0.2s ease,
color 0.2s ease,
padding-left 0.2s ease;
}
.nav__dropdown-menu a:hover {
background-color: #dbeafe;
color: #1d4ed8;
padding-left: 1.4rem;
}
/* Effekt für den Suchbutton */
.nav__search-button {
transition:
background-color 0.2s ease,
color 0.2s ease,
transform 0.2s ease;
}
.nav__search-button:hover {
background-color: #2563eb;
color: #ffffff;
}
.nav__search-button:active {
transform: scale(0.95);
}
/* Sichtbare Markierung bei Tastaturbedienung */
.nav a:focus-visible,
.nav button:focus-visible,
.nav input:focus-visible,
.nav label:focus-visible {
outline: 3px solid #fbbf24;
outline-offset: 3px;
}
+1 -2
View File
@@ -24,10 +24,9 @@ include_once "php/controller/index-controller.php";
<link rel="stylesheet" href="css/showCategory.css"> <link rel="stylesheet" href="css/showCategory.css">
<script src="js/comments.js" defer></script> <script src="js/comments.js" defer></script>
<script src="js/profile.js" defer></script>
<script src="js/editor.js" async></script> <script src="js/editor.js" async></script>
<script src="js/search-results.js" async></script>
<script src="js/showCategory.js" async></script> <script src="js/showCategory.js" async></script>
<script src="js/search.js" async></script>
<title>EduForge</title> <title>EduForge</title>
+2 -20
View File
@@ -11,26 +11,6 @@ document.addEventListener("DOMContentLoaded", function () {
const parentCommentInput = document.getElementById("parent-comment-id"); const parentCommentInput = document.getElementById("parent-comment-id");
const replyInfo = document.getElementById("reply-info"); const replyInfo = document.getElementById("reply-info");
/**
* Fragt vor dem Löschen eines Kommentars nach einer Bestätigung.
*
* Der Listener funktioniert auch für Kommentare,
* die später per AJAX eingefügt werden.
*/
document.addEventListener("submit", function (event) {
if (!event.target.classList.contains("delete-comment-form")) {
return;
}
const confirmed = confirm(
"Möchtest du diesen Kommentar wirklich löschen?"
);
if (!confirmed) {
event.preventDefault();
}
});
if (!form || !commentsList || !commentContent || !parentCommentInput) { if (!form || !commentsList || !commentContent || !parentCommentInput) {
return; return;
} }
@@ -172,6 +152,7 @@ document.addEventListener("DOMContentLoaded", function () {
<button <button
type="submit" type="submit"
class="delete-comment-button" class="delete-comment-button"
onclick="return confirm('Möchtest du diesen Kommentar wirklich löschen?');"
> >
Kommentar löschen Kommentar löschen
</button> </button>
@@ -249,6 +230,7 @@ document.addEventListener("DOMContentLoaded", function () {
<button <button
type="submit" type="submit"
class="delete-comment-button" class="delete-comment-button"
onclick="return confirm('Möchtest du diesen Kommentar wirklich löschen?');"
> >
Kommentar löschen Kommentar löschen
</button> </button>
-29
View File
@@ -1,29 +0,0 @@
document.addEventListener("DOMContentLoaded", function () {
const deleteAccountForm = document.querySelector(".confirm-delete-account");
if (deleteAccountForm) {
deleteAccountForm.addEventListener("submit", function (event) {
if (!confirm("Möchtest du deinen Account und alle deine Beiträge wirklich unwiderruflich löschen?")) {
event.preventDefault();
}
});
}
const deleteArticleForms = document.querySelectorAll(".confirm-delete-article");
deleteArticleForms.forEach(function (form) {
form.addEventListener("submit", function (event) {
if (!confirm("Möchtest du diesen Artikel wirklich löschen?")) {
event.preventDefault();
}
});
});
});
+18 -2
View File
@@ -4,6 +4,7 @@ if (session_status() === PHP_SESSION_NONE) {
} }
require_once "../model/CommentManager.php"; require_once "../model/CommentManager.php";
require_once "../model/UserManager.php";
/** /**
* Prüft, ob die Anfrage durch JavaScript per AJAX gesendet wurde. * Prüft, ob die Anfrage durch JavaScript per AJAX gesendet wurde.
@@ -40,7 +41,6 @@ function sendCommentResponse(
$additionalData $additionalData
) )
); );
exit(); exit();
} }
@@ -162,13 +162,29 @@ try {
$parentCommentId $parentCommentId
); );
$userManager = UserManager::getInstance();
$user = $userManager->findUser($_SESSION["user_email"]);
$authorName = $_SESSION["user_email"];
if ($user !== null) {
$vorname = trim($user["vorname"] ?? "");
$nachname = trim($user["nachname"] ?? "");
$fullName = trim($vorname . " " . $nachname);
if ($fullName !== "") {
$authorName = $fullName;
}
}
sendCommentResponse( sendCommentResponse(
true, true,
"Der Kommentar wurde erfolgreich gespeichert.", "Der Kommentar wurde erfolgreich gespeichert.",
$articleId, $articleId,
[ [
"commentId" => $commentId, "commentId" => $commentId,
"author" => $_SESSION["user_email"], "author" => $authorName,
"content" => $content, "content" => $content,
"created" => date("Y-m-d H:i:s"), "created" => date("Y-m-d H:i:s"),
"parentCommentId" => $parentCommentId "parentCommentId" => $parentCommentId