From 9a2391bac1aa029ebbd1fdcc776d5e4f2da4042d Mon Sep 17 00:00:00 2001 From: Cerys Date: Tue, 28 Jan 2025 01:18:47 +0000 Subject: [PATCH] can now like and dislike tunes --- App/Wrappers/DatabaseInteractions.php | 5 ++ App/Wrappers/SQLQueryBuilderWrapper.php | 14 ++++ Pages/tune/uuid.php | 13 ++- Public/API/V1/RateTune.php | 87 +++++++++++++++++++++ Public/Static/CSS/Elements/Rating.css | 29 +++++++ Public/Static/CSS/Mapper.css | 1 + Public/Static/JS/General/APIInteractions.js | 19 ++++- Templates/Bases/StandardWebPage.html.twig | 1 + Templates/Pages/profile.html.twig | 2 +- Templates/Pages/tune/uuid.html.twig | 33 +++++++- 10 files changed, 199 insertions(+), 5 deletions(-) create mode 100644 Public/API/V1/RateTune.php create mode 100644 Public/Static/CSS/Elements/Rating.css diff --git a/App/Wrappers/DatabaseInteractions.php b/App/Wrappers/DatabaseInteractions.php index c3ef5c7..4dc7e1b 100644 --- a/App/Wrappers/DatabaseInteractions.php +++ b/App/Wrappers/DatabaseInteractions.php @@ -68,6 +68,11 @@ class DatabaseInteractions $sth = $this->pdo->prepare($queryBuilder->getStatement()); return $sth->execute($queryBuilder->getBindValues()); } + public function RunUpdate(UpdateInterface $queryBuilder): bool + { + $sth = $this->pdo->prepare($queryBuilder->getStatement()); + return $sth->execute($queryBuilder->getBindValues()); + } public function RunDelete(DeleteInterface $queryBuilder): bool { diff --git a/App/Wrappers/SQLQueryBuilderWrapper.php b/App/Wrappers/SQLQueryBuilderWrapper.php index 3d19b1d..095e862 100644 --- a/App/Wrappers/SQLQueryBuilderWrapper.php +++ b/App/Wrappers/SQLQueryBuilderWrapper.php @@ -38,4 +38,18 @@ class SQLQueryBuilderWrapper ->bindValue(name: "__parent_id__", value: $parentIDValue) ; } + public static function INSERT(string $table) + { + $query_factory = new QueryFactory(db: 'mysql'); + return $query_factory->newInsert() + ->into("$table") + ; + } + public static function UPDATE(string $table) + { + $query_factory = new QueryFactory(db: 'mysql'); + return $query_factory->newUpdate() + ->table(table: "$table") + ; + } } diff --git a/Pages/tune/uuid.php b/Pages/tune/uuid.php index 851d118..c7f7ad3 100644 --- a/Pages/tune/uuid.php +++ b/Pages/tune/uuid.php @@ -12,9 +12,20 @@ $tuneDetails = $db->RunOneSelect( queryBuilder: SQLQueryBuilderWrapper::SELECT_ONE( table: 'Tunes', id: $_GET["tune-id"] - ), + ) + ->cols(cols: [ + 'SUM(CASE WHEN T_TR.Rating = 1 THEN 1 ELSE 0 END) AS Likes', + 'SUM(CASE WHEN T_TR.Rating = -1 THEN 1 ELSE 0 END) AS Dislikes', + ]) + ->join( + join: 'LEFT', + spec: 'TuneRatings AS T_TR', + cond: 'T.ID=T_TR.TuneID', + ) ); + + $dances = $db->RunSelect( queryBuilder: SQLQueryBuilderWrapper::SELECT( table: 'Dances', diff --git a/Public/API/V1/RateTune.php b/Public/API/V1/RateTune.php new file mode 100644 index 0000000..c4c3c12 --- /dev/null +++ b/Public/API/V1/RateTune.php @@ -0,0 +1,87 @@ +value]) +{ + die(); +} + +$ratingValue = 0; +if($_GET['type'] == "LIKE") + $ratingValue = 1; +elseif($_GET['type'] == "DISLIKE") + $ratingValue = -1; +else + die(); + +$db = new DatabaseInteractions(); + +$tuneDetails = $db->RunOneSelect( + queryBuilder: SQLQueryBuilderWrapper::SELECT_ONE( + table: 'Tunes', + id: $_GET['tune-id'] + ) +); + +$existingRating = $db->RunSelect( + queryBuilder: SQLQueryBuilderWrapper::SELECT( + table: 'TuneRatings', + ) + ->where(cond: 'CreatedBy=:__user_id__') + ->where(cond: 'TuneID=:__tune_id__') + ->bindValue(name: '__user_id__', value: $_SESSION[SessionElement::USER_ID->value]) + ->bindValue(name: '__tune_id__', value: $_GET['tune-id']) +); + +if(sizeof($existingRating) == 0) +{ + $db->RunInsert( + queryBuilder: SQLQueryBuilderWrapper::INSERT( + table: 'TuneRatings' + ) + ->set(col: 'CreatedBy', value: ':__user_id__') + ->set(col: 'TuneID', value: ':__tune_id__') + ->set(col: 'Rating', value: ':__rating__') + ->bindValue(name: '__user_id__', value: $_SESSION[SessionElement::USER_ID->value]) + ->bindValue(name: '__tune_id__', value: $_GET['tune-id']) + ->bindValue(name: '__rating__', value: $ratingValue) + ); +} +elseif(sizeof($existingRating) == 1) +{ + $db->RunUpdate( + queryBuilder: SQLQueryBuilderWrapper::UPDATE( + table: 'TuneRatings' + ) + ->set(col: 'Rating', value: ':__rating__') + ->where(cond: 'CreatedBy=:__user_id__') + ->where(cond: 'TuneID=:__tune_id__') + ->bindValue(name: '__user_id__', value: $_SESSION[SessionElement::USER_ID->value]) + ->bindValue(name: '__tune_id__', value: $_GET['tune-id']) + ->bindValue(name: '__rating__', value: $ratingValue) + ); +} + +$tuneRatings = $db->RunSelect( + queryBuilder: SQLQueryBuilderWrapper::SELECT( + table: 'TuneRatings', + ) + ->cols(cols: [ + 'SUM(CASE WHEN T.Rating = 1 THEN 1 ELSE 0 END) AS Likes', + 'SUM(CASE WHEN T.Rating = -1 THEN 1 ELSE 0 END) AS Dislikes', + ]) + ->where(cond: 'TuneID=:__tune_id__') + ->bindValue(name: '__tune_id__', value: $_GET['tune-id']) +); + +echo json_encode([ + "LikeCount" => $tuneRatings[0]["Likes"], + "DislikeCount" => $tuneRatings[0]["Dislikes"], +]); + +die(); diff --git a/Public/Static/CSS/Elements/Rating.css b/Public/Static/CSS/Elements/Rating.css new file mode 100644 index 0000000..39b1c60 --- /dev/null +++ b/Public/Static/CSS/Elements/Rating.css @@ -0,0 +1,29 @@ + + +.RatingButtons { + display: flex; + gap: 1rem; + justify-content: center; + margin-top: 1rem; +} +#RatingContainer button { + background: none; + border: none; + cursor: pointer; + font-size: 2rem; + transition: transform 0.2s, color 0.2s; +} +#RatingContainer button:hover { + transform: scale(1.2); +} +#ThumbUp { + color: green; +} +#ThumbDown { + color: red; +} +.Counts { + margin-top: 1rem; + font-size: 1.2rem; +} + diff --git a/Public/Static/CSS/Mapper.css b/Public/Static/CSS/Mapper.css index 2c1ca18..df35171 100644 --- a/Public/Static/CSS/Mapper.css +++ b/Public/Static/CSS/Mapper.css @@ -13,4 +13,5 @@ @import "/Static/CSS/Elements/DescriptionLists.css"; @import "/Static/CSS/Elements/HomePage.css"; @import "/Static/CSS/Elements/NavBar.css"; +@import "/Static/CSS/Elements/Rating.css"; diff --git a/Public/Static/JS/General/APIInteractions.js b/Public/Static/JS/General/APIInteractions.js index 9344cec..8e70e9f 100644 --- a/Public/Static/JS/General/APIInteractions.js +++ b/Public/Static/JS/General/APIInteractions.js @@ -1,9 +1,9 @@ -const API_SERVER = "https://ceilidhkit.com/API"; +const API_SERVER = "/API"; -async function API_GET(target) { +async function API_GET_TEXT(target) { try { const response = await fetch(API_SERVER + target, { method: 'GET', @@ -16,3 +16,18 @@ async function API_GET(target) { return {error: error.message}; } } + + +async function API_GET(target) { + try { + const response = await fetch(API_SERVER + target, { + method: 'GET', + headers: { + }, + credentials: 'include', + }); + return await response.json(); + } catch (error) { + return {error: error.message}; + } +} diff --git a/Templates/Bases/StandardWebPage.html.twig b/Templates/Bases/StandardWebPage.html.twig index deee8e4..d19866d 100644 --- a/Templates/Bases/StandardWebPage.html.twig +++ b/Templates/Bases/StandardWebPage.html.twig @@ -38,6 +38,7 @@ {% endif %} +

{% block content %}{% endblock %}
diff --git a/Templates/Pages/profile.html.twig b/Templates/Pages/profile.html.twig index 6c0dcce..e4be38f 100644 --- a/Templates/Pages/profile.html.twig +++ b/Templates/Pages/profile.html.twig @@ -45,4 +45,4 @@ -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/Templates/Pages/tune/uuid.html.twig b/Templates/Pages/tune/uuid.html.twig index 87a8108..85177d4 100644 --- a/Templates/Pages/tune/uuid.html.twig +++ b/Templates/Pages/tune/uuid.html.twig @@ -6,6 +6,23 @@ + +
@@ -27,6 +44,20 @@
{{ TuneDetails.Parts|json_encode }}
+
+

{{ "Rating"|translate }}

+
+ + +
+
+ | + 👍 {{ TuneDetails.Likes }} + | + 👎 {{ TuneDetails.Dislikes }} + | +
+
@@ -54,7 +85,7 @@