diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..be45c67 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 GeorgiaTechTeam18 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 9737b44..a445b11 100644 --- a/README.md +++ b/README.md @@ -1 +1,25 @@ -# SpotifyWrapper \ No newline at end of file +# SpotifyWrapper + +## Deliverables + +### Team Website +https://team18gt.weebly.com/ + +### Spotify Wrapper GitHub repo +https://github.com/GeorgiaTechTeam18/SpotifyWrapper + +### Project management board +https://github.com/orgs/GeorgiaTechTeam18/projects/2/ + +## command reference +#### run the project +```bash +. .venv/bin/activate +python manage.py migrate +python manage.py runserver +``` +#### regenerate files after modifications +```bash +pip3 freeze > requirements.txt +python manage.py makemigrations +``` diff --git a/SpotifyWrapper/settings.py b/SpotifyWrapper/settings.py index 8597bc2..4feb25b 100644 --- a/SpotifyWrapper/settings.py +++ b/SpotifyWrapper/settings.py @@ -43,20 +43,7 @@ LANGUAGE_CODE = "en-us" TIME_ZONE = "America/New_York" -USE_I18N = True -USE_L10N = True -USE_TZ = True -LANGUAGES = [ - ("en", ("English")), - ("de", ("German")), - ("fr", ("French")), - ("sp", ("Spanish")), -] -LOCALE_PATHS = [ - os.path.join(BASE_DIR, "locale"), - os.path.join(BASE_DIR, "UserAuth/locale"), - os.path.join(BASE_DIR, "Wrapped/locale"), -] + # Application definition INSTALLED_APPS = [ @@ -80,8 +67,6 @@ "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", - "django.middleware.locale.LocaleMiddleware", - "django.middleware.common.CommonMiddleware", ] ROOT_URLCONF = "SpotifyWrapper.urls" diff --git a/UserAuth/static/UserAuth/styles.css b/UserAuth/static/UserAuth/styles.css index 722bf75..9d5beb0 100644 --- a/UserAuth/static/UserAuth/styles.css +++ b/UserAuth/static/UserAuth/styles.css @@ -380,6 +380,29 @@ main { color: #A268DB; } +.form-errors { + color: #ff4d4d; /* Red color for errors */ + font-size: 14px; + margin-bottom: 10px; +} + +.error-message { + margin: 5px 0; +} + +.authForm .form-errors { + margin-bottom: 15px; /* Space between the errors and the form */ +} + +.authForm label { + display: block; + margin-top: 10px; +} + +.authForm input, .authForm button { + margin-top: 5px; +} + .login-alternate { display: flex; flex-direction: column; @@ -602,20 +625,41 @@ ul { margin-bottom: 10px; } -.wrap form button { - background-color: #1DB954; - color: white; - border: none; - border-radius: 5px; - padding: 10px 15px; - font-size: 0.9em; - font-weight: bold; +.wrap-buttons { + display: flex; + gap: 10px; /* Space between buttons */ + margin-top: 10px; /* Add some spacing above the buttons */ +} + +.wrap-buttons form { + margin: 0; +} + +.wrap-buttons button { + padding: 8px 12px; + font-size: 14px; + border: 1px solid #ccc; + border-radius: 4px; + background-color: #f8f9fa; cursor: pointer; - transition: background-color 0.3s, transform 0.2s; + transition: background-color 0.3s ease, border-color 0.3s ease; +} + +.wrap-buttons button:hover { + background-color: #e9ecef; + border-color: #bbb; } -.wrap form button:hover { - background-color: #14863E; +.wrap-buttons .like-button { + color: #007bff; +} + +.wrap-buttons .delete-button { + color: #dc3545; +} + +.wrap-buttons .post-button { + color: #28a745; } @media (max-width: 768px) { @@ -671,6 +715,54 @@ ul { } } +/* Share buttons */ +.share-container { + margin-left: auto; +} + +.share-button { + border-radius: .3em; + padding: .3em; + background: #f8f9fa; + margin: 0; + font-size: large; +} + +.share-button:hover { + background: #e3e3e4; +} + +/* View public and liked wraps styling*/ +.header-container { + display: flex; + align-items: center; /* Align items vertically */ + justify-content: space-between; /* Keep the button to the right */ + margin-bottom: 20px; +} + +/* Text container to stack the heading and paragraph */ +.text-container { + display: flex; + flex-direction: column; /* Stack items vertically */ +} + +/* Style the anchor tag like a Spotify button */ +.spotify-button { + background-color: #1DB954; + color: black; + border: none; + border-radius: 50px; + padding: 10px 20px; + text-decoration: none; + font-weight: bold; + transition: background-color 0.3s ease; +} + +/* Add hover effect */ +.spotify-button:hover { + background-color: #1ed760; +} + @media (min-width: 768px) { #hamburger { display: none !important; diff --git a/UserAuth/util.py b/UserAuth/util.py index c7e375e..094e8aa 100644 --- a/UserAuth/util.py +++ b/UserAuth/util.py @@ -1,9 +1,5 @@ -from .models import User, SpotifyToken -from django.utils import timezone import datetime -from requests import post, get import os -from dotenv import load_dotenv from functools import cache from django.utils import timezone diff --git a/UserAuth/views.py b/UserAuth/views.py index c3679d2..8a748f3 100644 --- a/UserAuth/views.py +++ b/UserAuth/views.py @@ -1,10 +1,3 @@ -import secrets - -from django.http import HttpResponseBadRequest -from django.shortcuts import render, redirect -from requests import Request, post, exceptions -from .util import update_or_create_user_tokens, get_top_song_album_covers -from .models import SpotifyToken import os import secrets @@ -12,6 +5,7 @@ from django.contrib import messages from django.contrib.auth import authenticate, get_user_model, login, logout from django.contrib.auth.decorators import login_required +from django.http import HttpResponseBadRequest from django.shortcuts import get_object_or_404, redirect, render from dotenv import load_dotenv from requests import Request, exceptions, post @@ -64,10 +58,7 @@ def authWithSpotify(request): "redirect_uri": REDIRECT_URI, "client_id": CLIENT_ID, }, - ) - .prepare() - .url - ) + ) .prepare() .url) return redirect(url) @@ -75,7 +66,6 @@ def authWithSpotify(request): def login_view(request): if request.method == "POST": form = RegistrationForm(request.POST) - print(form) if form.is_valid(): user_data = form.cleaned_data user = authenticate( @@ -263,5 +253,3 @@ def getSpotifyUserData(access_token): raise Exception( f"Failed to retrieve user info. Status code: {response.status_code}" ) - - diff --git a/Wrapped/migrations/0007_spotifywrap_liked_by.py b/Wrapped/migrations/0007_spotifywrap_liked_by.py new file mode 100644 index 0000000..333d723 --- /dev/null +++ b/Wrapped/migrations/0007_spotifywrap_liked_by.py @@ -0,0 +1,26 @@ +# Generated by Django 5.1.2 on 2024-11-30 23:27 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Wrapped", "0006_alter_spotifywrap_uuid"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name="spotifywrap", + name="liked_by", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="liked_by", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/Wrapped/migrations/0008_remove_spotifywrap_liked_by_spotifywrap_liked_by.py b/Wrapped/migrations/0008_remove_spotifywrap_liked_by_spotifywrap_liked_by.py new file mode 100644 index 0000000..5db60c6 --- /dev/null +++ b/Wrapped/migrations/0008_remove_spotifywrap_liked_by_spotifywrap_liked_by.py @@ -0,0 +1,27 @@ +# Generated by Django 5.1.2 on 2024-11-30 23:51 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Wrapped", "0007_spotifywrap_liked_by"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.RemoveField( + model_name="spotifywrap", + name="liked_by", + ), + migrations.AddField( + model_name="spotifywrap", + name="liked_by", + field=models.ManyToManyField( + blank=True, + related_name="liked_wraps", + to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/Wrapped/migrations/0009_alter_spotifywrap_is_public.py b/Wrapped/migrations/0009_alter_spotifywrap_is_public.py new file mode 100644 index 0000000..c9e18ad --- /dev/null +++ b/Wrapped/migrations/0009_alter_spotifywrap_is_public.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.2 on 2024-12-01 22:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Wrapped", "0008_remove_spotifywrap_liked_by_spotifywrap_liked_by"), + ] + + operations = [ + migrations.AlterField( + model_name="spotifywrap", + name="is_public", + field=models.BooleanField(default=False), + ), + ] diff --git a/Wrapped/models.py b/Wrapped/models.py index e21309c..2943cb2 100644 --- a/Wrapped/models.py +++ b/Wrapped/models.py @@ -15,8 +15,10 @@ class SpotifyWrap(models.Model): artists = models.TextField(default="[]") tracks = models.TextField(default="[]") audio_features = models.TextField(default="{}") - is_public = models.BooleanField(default=True) + is_public = models.BooleanField(default=False) likes = models.IntegerField(default=0) + liked_by = models.ManyToManyField( + User, related_name="liked_wraps", blank=True) def set_top_artists(self, artists_data): self.artists = json.dumps(artists_data) diff --git a/Wrapped/urls.py b/Wrapped/urls.py index 34f3ceb..86fba95 100644 --- a/Wrapped/urls.py +++ b/Wrapped/urls.py @@ -3,17 +3,19 @@ from UserAuth.views import delete_account -from .views import (create_wrap, like_wrap, make_wraps_public, - view_public_wraps, view_wrap, - view_wraps) +from .views import (create_wrap, like_unlike_wrap, make_wraps_private, + make_wraps_public, view_liked_wraps, view_public_wraps, + view_wrap, view_wraps) urlpatterns = [ path("view_wraps/", view_wraps, name="view_wraps"), path("create_wrap/", create_wrap, name="create_wrap"), path("create_wrap/", create_wrap, name="create_wrap"), path("view_wrap/wrap_id_/", view_wrap, name="view_wrap"), - path("like_wrap//", like_wrap, name="like_wrap"), + path("wrap//like", like_unlike_wrap, name="like_unlike_wrap"), path("make_wraps_public/", make_wraps_public, name="make_wraps_public"), path("view_public_wraps/", view_public_wraps, name="view_public_wraps"), path("delete_account/", delete_account, name="delete_account"), + path("liked-wraps/", view_liked_wraps, name="view_liked_wraps"), + path("make_wraps_private/", make_wraps_private, name="make_wraps_private"), ] diff --git a/Wrapped/views.py b/Wrapped/views.py index 12d3f9c..b0f9a4c 100644 --- a/Wrapped/views.py +++ b/Wrapped/views.py @@ -3,11 +3,11 @@ from datetime import datetime import requests -from django.http import JsonResponse, HttpResponseServerError -from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required from django.contrib.auth.models import AnonymousUser -from django.http import HttpResponseNotFound, JsonResponse +from django.db.models import Exists, OuterRef +from django.http import (HttpResponseNotFound, HttpResponseRedirect, + HttpResponseServerError, JsonResponse) from django.shortcuts import get_object_or_404, redirect, render from UserAuth.models import SpotifyToken @@ -29,33 +29,137 @@ def make_wraps_public(request): else: wraps.update(is_public=False) - return redirect("view_public_wraps") + return redirect("profile") -def view_public_wraps(request): - liked = request.GET.get("liked") == "true" - if liked: - public_wraps = SpotifyWrap.objects.filter( - is_public=True, liked_by=request.user) +def make_wraps_private(request): + wrap_ids = request.POST.getlist("wrap_ids") + action = request.POST.get("action") + print(wrap_ids) + wraps = SpotifyWrap.objects.filter(id__in=wrap_ids, user=request.user) + + print(wraps.first()) + + if action == "post": + wraps.update(is_public=False) else: - public_wraps = SpotifyWrap.objects.filter(is_public=True) + wraps.update(is_public=True) + + return redirect("profile") - print(public_wraps) - if request.headers.get("X-Requested-With") == "XMLHttpRequest": - wraps_data = [ +def view_liked_wraps(request): + public_wraps = SpotifyWrap.objects.filter(is_public=True).annotate( + is_liked_by_user=Exists( + SpotifyWrap.liked_by.through.objects.filter( + spotifywrap_id=OuterRef("id"), + user_id=request.user.id, + ) + ) + ) + + public_wraps = public_wraps.filter(is_liked_by_user=True) + + if request.method == "POST": + wrap_uuid = request.POST.get("wrap_uuid") + wrap = get_object_or_404(SpotifyWrap, uuid=wrap_uuid) + + liked = None + if request.user in wrap.liked_by.all(): + wrap.liked_by.remove(request.user) + wrap.likes -= 1 + liked = False + else: + wrap.liked_by.add(request.user) + wrap.likes += 1 + liked = True + + wrap.save() + print(liked) + return JsonResponse( { - "id": wrap.id, - "title": wrap.title, - "csrf_token": request.COOKIES["csrftoken"], + "success": True, + "liked": liked, + "wrap_uuid": wrap.uuid, } - for wrap in public_wraps - ] - return JsonResponse({"wraps": wraps_data}) + ) + return render( + request, + "Wrapped/view_liked_wraps.html", + { + "wraps": public_wraps, + }, + ) + + +def view_public_wraps(request): + public_wraps = SpotifyWrap.objects.filter(is_public=True).annotate( + is_liked_by_user=Exists( + SpotifyWrap.liked_by.through.objects.filter( + spotifywrap_id=OuterRef("id"), + user_id=request.user.id, + ) + ) + ) + + if request.method == "POST": + wrap_uuid = request.POST.get("wrap_uuid") + wrap = get_object_or_404(SpotifyWrap, uuid=wrap_uuid) + + liked = None + if request.user in wrap.liked_by.all(): + wrap.liked_by.remove(request.user) + wrap.likes -= 1 + liked = False + else: + wrap.liked_by.add(request.user) + wrap.likes += 1 + liked = True + + wrap.save() + print(liked) + return JsonResponse( + { + "success": True, + "liked": liked, + "wrap_uuid": wrap.uuid, + } + ) + return render( + request, + "Wrapped/view_public_wraps.html", + { + "wraps": public_wraps, + }, + ) + + +@login_required +def like_unlike_wrap(request, wrap_id): + if request.method == "POST": + wrap = get_object_or_404(SpotifyWrap, uuid=wrap_id) + + # Toggle like/unlike status + if request.user in wrap.liked_by.all(): + wrap.liked_by.remove(request.user) + wrap.likes -= 1 + liked = False + else: + wrap.liked_by.add(request.user) + wrap.likes += 1 + liked = True + + wrap.save() + + return JsonResponse( + { + "success": True, + "liked": liked, + "wrap_uuid": wrap.uuid, + } + ) - return render(request, - "Wrapped/view_public_wraps.html", - {"wraps": public_wraps}) + return JsonResponse({"success": False, "message": "Invalid request."}) def view_wraps(request): @@ -95,6 +199,9 @@ def view_wrap(request, wrap_id): wrap.get_audio_features() ) selected_tracks = select_tracks(tracks, artists, genres) + spotify_webplayback_token = "" + if request.user.is_authenticated and get_user_tokens(request.user): + spotify_webplayback_token = get_user_tokens(request.user).access_token return render( request, "Wrapped/view_wrap.html", @@ -108,12 +215,11 @@ def view_wrap(request, wrap_id): "audio_features_graphs": audio_features_graphs, "audio_features_list": audio_features_list, "selected_tracks": selected_tracks, - "access_token": get_user_tokens(request.user).access_token, + "access_token": spotify_webplayback_token, }, ) -# TODO def like_wrap(request, wrap_id): wrap = get_object_or_404(SpotifyWrap, uuid=wrap_id) @@ -125,7 +231,7 @@ def like_wrap(request, wrap_id): message = "Liked" wrap.save() - return JsonResponse({'message': message}) + return JsonResponse({"message": message}) key_map = { diff --git a/templates/UserAuth/albumScrollDisplay.html b/templates/UserAuth/albumScrollDisplay.html index 7f314c3..286e8f5 100644 --- a/templates/UserAuth/albumScrollDisplay.html +++ b/templates/UserAuth/albumScrollDisplay.html @@ -1,4 +1,3 @@ -{% load i18n %}
@@ -7,14 +6,14 @@ src="{{ album.images.0.url }}" width="100" height="100" - alt="{% trans album.name %}"> + alt="{{ album.name }}"> {% endfor %} {% for album in album_covers %} {% trans album.name %} + alt="{{ album.name }}"> {% endfor %}
diff --git a/templates/UserAuth/base.html b/templates/UserAuth/base.html index 0ae986b..24d342a 100644 --- a/templates/UserAuth/base.html +++ b/templates/UserAuth/base.html @@ -21,6 +21,9 @@ Spotify Wrapper {% if user.is_authenticated %} +
  • + Public Wraps +
  • Generate Wrapped
  • @@ -54,6 +57,9 @@
    {% if user.is_authenticated %}
      +
    • + Public Wraps +
    • Generate Wrapped
    • diff --git a/templates/UserAuth/contactus.html b/templates/UserAuth/contactus.html index 1186409..8eefe55 100644 --- a/templates/UserAuth/contactus.html +++ b/templates/UserAuth/contactus.html @@ -1,54 +1,54 @@ {% extends 'UserAuth/base.html' %} -{% load static i18n %} +{% load static %} {% block body %}
      -

      {% trans "Your trust is important to us, and so we would like to answer your FAQs or contact us." %}

      +

      Your trust is important to us, and so we would like to answer your FAQs or contact us.


      • -

        {% trans "Year-Round Insights" %}

        -

        {% trans "Get personalized listening stats anytime, not just at the end of the year." %}

        +

        Year-Round Insights

        +

        Get personalized listening stats anytime, not just at the end of the year.

      • -

        {% trans "Your Data is Safe" %}

        -

        {% trans "We prioritize your privacy and never share your data with third parties." %}

        +

        Your Data is Safe

        +

        We prioritize your privacy and never share your data with third parties.

      • -

        {% trans "Cross-Platform Support" %}

        -

        {% trans "Use our service on any device—optimized for both iOS and Android." %}

        +

        Cross-Platform Support

        +

        Use our service on any device—optimized for both iOS and Android.

      • -

        {% trans "Custom Insights" %}

        -

        {% trans "Discover your top songs, artists, and genres, or analyze listening trends by time." %}

        +

        Custom Insights

        +

        Discover your top songs, artists, and genres, or analyze listening trends by time.

      • -

        {% trans "Revoke Permissions Anytime" %}

        -

        {% trans "You’re in control—revoke our app’s permissions anytime from Spotify settings." %}

        +

        Revoke Permissions Anytime

        +

        You’re in control—revoke our app’s permissions anytime from Spotify settings.

      -

      {% trans "Contact Us" %}

      +

      Contact Us

      {% csrf_token %} {{ form.as_p }} - +
      {% if messages %}
        @@ -57,4 +57,4 @@

        {% trans "Contact Us" %}

        {% endif %}
      -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/UserAuth/index.html b/templates/UserAuth/index.html index c950bd3..1c12ea4 100644 --- a/templates/UserAuth/index.html +++ b/templates/UserAuth/index.html @@ -18,7 +18,6 @@

      Unwrap at any time.

    {% include "UserAuth/albumScrollDisplay.html" with album_covers=album_covers direction="left" classNames="index-page-albums-mobile" %} -

    Meet the Team

    @@ -72,7 +71,6 @@

    Aneesh Kanaram

    Hi, I'm Aneesh! I helped design our site's ability to post your wrap and see what others have done!

    -
    FAQ / Contact Us diff --git a/templates/UserAuth/login.html b/templates/UserAuth/login.html index 460b8c2..3daca2a 100644 --- a/templates/UserAuth/login.html +++ b/templates/UserAuth/login.html @@ -1,31 +1,41 @@ {% extends 'UserAuth/base.html' %} -{% load static i18n %} +{% load static %} {% block body %} -
    - {% csrf_token %} -

    {% trans "Sign in" %}

    -
    -
    - - {{ form.email.errors }} - {{ form.email }} +
    + + {% csrf_token %} +

    Sign in

    +
    + {% if form.email.errors %} +
    + {% for error in form.email.errors %}

    {{ error }}

    {% endfor %} +
    + {% endif %} +
    + + {{ form.email }} +
    + {% if form.password.errors %} +
    + {% for error in form.password.errors %}

    {{ error }}

    {% endfor %} +
    + {% endif %} + + + + + + -
    - - {{ form.password.errors }} - {{ form.password }} -
    - - - - - -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/UserAuth/profile.html b/templates/UserAuth/profile.html index e049637..10285e5 100644 --- a/templates/UserAuth/profile.html +++ b/templates/UserAuth/profile.html @@ -1,10 +1,9 @@ {% extends 'UserAuth/base.html' %} -{% load i18n %} {% block body %} -

    {{ user.get_username }}'s Profile Page

    +

    {{ user.get_username }}'s Profile


    @@ -41,22 +40,35 @@

    Spotify Wraps

    {{ wrap.title }}

    View this wrap

    Posted by: {{ wrap.user.username }}

    -
    - {% csrf_token %} - -
    -
    - {% csrf_token %} - -
    -
    - {% csrf_token %} - - - -
    +
    +
    + {% csrf_token %} + +
    +
    + {% csrf_token %} + + {% if wrap.is_public %} + + + {% else %} + + + {% endif %} +
    + +
    {% endfor %} @@ -96,6 +108,16 @@

    {{ wrap.title }}

    } }); }); + + function share(text, url) { + const shareData = { + title: "SpotifyWrapped", + text: text, + url: url, + }; + + navigator.share(shareData); + }
    Delete Account diff --git a/templates/UserAuth/signup.html b/templates/UserAuth/signup.html index 30317d4..c90172b 100644 --- a/templates/UserAuth/signup.html +++ b/templates/UserAuth/signup.html @@ -1,5 +1,5 @@ {% extends 'UserAuth/base.html' %} -{% load static i18n %} +{% load static %} {% block body %}
    diff --git a/templates/Wrapped/choose_time_range.html b/templates/Wrapped/choose_time_range.html index d583641..f9fbbcf 100644 --- a/templates/Wrapped/choose_time_range.html +++ b/templates/Wrapped/choose_time_range.html @@ -29,4 +29,4 @@

    Generate your Wrapped

    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/Wrapped/get_top.html b/templates/Wrapped/get_top.html index aa1cd11..b618bb9 100644 --- a/templates/Wrapped/get_top.html +++ b/templates/Wrapped/get_top.html @@ -3,7 +3,7 @@ - {% trans "Top Tracks and Artists" %} + Top Tracks and Artists -

    {% trans "Top Tracks" %}

    +

    Top Tracks

    {% if error %}

    {{ error }}

    {% else %} @@ -62,23 +62,23 @@

    {% trans "Top Tracks" %}

    height="50" />

    - {% trans "Song:" %} {{ track.song_name }} + Song: {{ track.song_name }}

    - {% trans "Artist:" %} {{ track.artist_name }} + Artist: {{ track.artist_name }}

    - {% trans "Album:" %} {{ track.album_name }} + Album: {{ track.album_name }}

    - {% trans "Duration:" %} {{ track.duration_ms }} ms + Duration: {{ track.duration_ms }} ms

    {% endfor %} {% endif %} -

    {% trans "Top Artists" %}

    +

    Top Artists

    {% if error %}

    {{ error }}

    {% else %} @@ -91,10 +91,10 @@

    {% trans "Top Artists" %}

    height="50" />

    - {% trans "Name:" %} {{ artist.name }} + Name: {{ artist.name }}

    - {% trans "Genres:" %} {{ artist.genres|join:", " }} + Genres: {{ artist.genres|join:", " }}

    diff --git a/templates/Wrapped/user_profile.html b/templates/Wrapped/user_profile.html index 69ee7fc..2b96ae2 100644 --- a/templates/Wrapped/user_profile.html +++ b/templates/Wrapped/user_profile.html @@ -1,12 +1,8 @@ {% extends 'Wrapped/base.html' %} {% block title %}User Profile{% endblock %} -{% load i18n %} -{% block title %} - {% trans "User Profile" %} -{% endblock %} {% block content %} -

    {{ user.username }}{% trans "'s Profile" %}

    -

    {% trans "Posted Wraps" %}

    +

    {{ user.username }}'s Profile

    +

    Posted Wraps

      {% for wrap in user.spotifywrap_set.all %}
    • @@ -14,7 +10,7 @@

      {% trans "Posted Wraps" %}

    • {% endfor %}
    -

    {% trans "Liked Wraps" %}

    +

    Liked Wraps

      {% for like in user.like_set.all %}
    • diff --git a/templates/Wrapped/view_liked_wraps.html b/templates/Wrapped/view_liked_wraps.html new file mode 100644 index 0000000..a482a09 --- /dev/null +++ b/templates/Wrapped/view_liked_wraps.html @@ -0,0 +1,103 @@ +{% extends 'UserAuth/base.html' %} +{% block title %}Liked Wraps{% endblock %} +{% block body %} +
      +
      +
      +
      +

      Favorite Wraps

      +
      + Public Wraps +
      + {% if wraps %} +
        + {% for wrap in wraps %} +
      • +

        {{ wrap.title }}

        + View this wrap +

        Posted by: {{ wrap.user.username }}

        +
        + + +
        +
      • + {% endfor %} +
      + {% else %} +
      +

      You haven't liked any wraps yet. Check out some public wraps!

      +
      + {% endif %} + +{% endblock %} diff --git a/templates/Wrapped/view_public_wraps.html b/templates/Wrapped/view_public_wraps.html index d099769..2485140 100644 --- a/templates/Wrapped/view_public_wraps.html +++ b/templates/Wrapped/view_public_wraps.html @@ -1,48 +1,67 @@ {% extends 'UserAuth/base.html' %} -{% load i18n %} -{% block title %} - {% trans "Public Wraps" %} -{% endblock %} +{% block title %}Public Wraps{% endblock %} {% block body %} -

      {% trans "Public Wraps" %}

      - - {{ wraps }} - {% for wrap in wraps %} - {{ wrap }} - {% endfor %} -
        - {% for wrap in wraps %} -
      • - View this wrap - -
      • - {% endfor %} -
      -