Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ ENV MEDIA_ROOT=/app/data/media

WORKDIR /app

# Install cron and other system dependencies
# Install cron, gettext and other system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
cron \
gettext \
&& rm -rf /var/lib/apt/lists/*

# Install uv
Expand Down Expand Up @@ -68,6 +69,9 @@ RUN echo "PATH=/usr/local/bin:/usr/bin:/bin" > /etc/cron.d/datakult-backup && \
COPY scripts/entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh

# Compile translation messages
RUN uv run ./src/manage.py compilemessages

# Collect static files with production settings
# Set DEBUG=false to use CompressedManifestStaticFilesStorage during collectstatic
# This ensures the manifest file is created for production use
Expand Down
17 changes: 13 additions & 4 deletions src/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

def _resolve_sorting(request):
"""Return validated sorting info: selected field, sort string (with sign), and ordering."""
default_field = "created_at"
default_field = "review_date"
sort = request.GET.get("sort") or request.GET.get("order_by") or f"-{default_field}"

raw_field = sort.lstrip("-")
Expand Down Expand Up @@ -51,6 +51,15 @@ def _extract_filters(request):
filters["review_to"],
]
)

# Add display names for active filters
if filters["type"]:
filters["type_display"] = dict(Media.media_type.field.choices).get(filters["type"], filters["type"])
if filters["status"]:
filters["status_display"] = dict(Media.status.field.choices).get(filters["status"], filters["status"])
if filters["score"] and filters["score"] != "none":
filters["score_display"] = dict(Media.score.field.choices).get(int(filters["score"]), filters["score"])

return filters


Expand Down Expand Up @@ -100,7 +109,7 @@ def _apply_filters(queryset, filters):
def index(request):
"""Main view for displaying media list."""
# Get query parameters
view_mode = request.GET.get("view_mode", "list") # 'list' or 'grid'
view_mode = request.GET.get("view_mode", "grid") # 'list' or 'grid'
sort_field, sort, ordering = _resolve_sorting(request)
filters = _extract_filters(request)

Expand Down Expand Up @@ -193,7 +202,7 @@ def media_delete(request, pk):
@login_required
def load_more_media(request):
"""HTMX view: load next page of media items for infinite scrolling."""
view_mode = request.GET.get("view_mode", "list")
view_mode = request.GET.get("view_mode", "grid")
sort_field, sort, ordering = _resolve_sorting(request)
filters = _extract_filters(request)
query = request.GET.get("search", "")
Expand Down Expand Up @@ -228,7 +237,7 @@ def load_more_media(request):
@login_required
def search_media(request):
query = request.GET.get("search", "")
view_mode = request.GET.get("view_mode", "list")
view_mode = request.GET.get("view_mode", "grid")
sort_field, sort, ordering = _resolve_sorting(request)
filters = _extract_filters(request)

Expand Down
103 changes: 66 additions & 37 deletions src/locale/fr/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-01-04 14:32+0100\n"
"POT-Creation-Date: 2026-01-04 15:45+0100\n"
"PO-Revision-Date: 2026-01-04 10:45+0100\n"
"Last-Translator: Pascal Repond <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -124,23 +124,23 @@ msgstr ""
msgid "Status"
msgstr "Statut"

#: src/core/models.py:152
#: src/core/models.py:152 src/templates/partials/sidebar-nav.html:23
msgid "Planned"
msgstr "Prévu"

#: src/core/models.py:153
#: src/core/models.py:153 src/templates/partials/sidebar-nav.html:31
msgid "In progress"
msgstr "En cours"

#: src/core/models.py:154
#: src/core/models.py:154 src/templates/partials/sidebar-nav.html:39
msgid "Completed"
msgstr "Terminé"

#: src/core/models.py:155
#: src/core/models.py:155 src/templates/partials/sidebar-nav.html:47
msgid "Paused"
msgstr "En pause"

#: src/core/models.py:156
#: src/core/models.py:156 src/templates/partials/sidebar-nav.html:55
msgid "Did not finish"
msgstr "Pas fini"

Expand Down Expand Up @@ -267,7 +267,7 @@ msgid "Backup import failed: %(error)s"
msgstr "Échec de l'importation du backup : %(error)s"

#: src/templates/accounts/profile_edit.html:4
#: src/templates/accounts/profile_edit.html:8 src/templates/base.html:78
#: src/templates/accounts/profile_edit.html:8
msgid "Edit Profile"
msgstr "Modifier le profil"

Expand Down Expand Up @@ -461,9 +461,8 @@ msgid ""
"This action will DELETE ALL your current data and replace it with the backup "
"data. Are you absolutely sure you want to continue?"
msgstr ""
"Cette action va SUPPRIMER TOUTES vos données actuelles et les "
"remplacer par les données de la sauvegarde. Êtes-vous absolument sûr de "
"vouloir continuer ?"
"Cette action va SUPPRIMER TOUTES vos données actuelles et les remplacer par "
"les données de la sauvegarde. Êtes-vous absolument sûr de vouloir continuer ?"

#: src/templates/backup_manage.html:155
msgid "Yes, import backup"
Expand All @@ -477,27 +476,7 @@ msgstr "Échec de la création de la sauvegarde. Veuillez réessayer."
msgid "Unknown error"
msgstr "Erreur inconnue"

#: src/templates/base.html:40
msgid "System"
msgstr "Système"

#: src/templates/base.html:47
msgid "Light"
msgstr "Clair"

#: src/templates/base.html:54
msgid "Dark"
msgstr "Sombre"

#: src/templates/base.html:84
msgid "Backups"
msgstr "Sauvegardes"

#: src/templates/base.html:93
msgid "Log Out"
msgstr "Se déconnecter"

#: src/templates/media.html:3 src/templates/media.html:54
#: src/templates/media.html:3 src/templates/media.html:55
msgid "Search"
msgstr "Recherche"

Expand All @@ -514,7 +493,7 @@ msgstr "Date de création"
msgid "Score"
msgstr "Note"

#: src/templates/media.html:65
#: src/templates/media.html:66
msgid "Add"
msgstr "Ajouter"

Expand Down Expand Up @@ -655,18 +634,65 @@ msgstr "Note :"
msgid "out of 10"
msgstr "sur 10"

#: src/templates/partials/sidebar-nav.html:11
msgid "All"
msgstr "Tout"

#: src/templates/partials/sidebar-nav.html:16
msgid "By status"
msgstr "Par statut"

#: src/templates/partials/sidebar-nav.html:60
msgid "Settings"
msgstr "Paramètres"

#: src/templates/partials/sidebar-nav.html:66
msgid "Profile"
msgstr "Profil"

#: src/templates/partials/sidebar-nav.html:72
msgid "Backups"
msgstr "Sauvegardes"

#: src/templates/partials/sidebar-nav.html:80
msgid "Theme"
msgstr "Thème"

#: src/templates/partials/sidebar-nav.html:89
#: src/templates/partials/sidebar-nav.html:91
msgid "System"
msgstr "Système"

#: src/templates/partials/sidebar-nav.html:99
#: src/templates/partials/sidebar-nav.html:101
msgid "Light"
msgstr "Clair"

#: src/templates/partials/sidebar-nav.html:109
#: src/templates/partials/sidebar-nav.html:111
msgid "Dark"
msgstr "Sombre"

#: src/templates/partials/sidebar-nav.html:123
msgid "Logout"
msgstr "Déconnexion"

#: src/templates/partials/sidebar-nav.html:129
msgid "Login"
msgstr "Se connecter"

#: src/templates/partials/spinner.html:17
msgid "Loading..."
msgstr "Chargement..."

#: src/templates/partials/view-mode-toggle.html:15
msgid "List"
msgstr "Liste"

#: src/templates/partials/view-mode-toggle.html:24
#: src/templates/partials/view-mode-toggle.html:14
msgid "Grid"
msgstr "Grille"

#: src/templates/partials/view-mode-toggle.html:21
msgid "List"
msgstr "Liste"

#: src/templates/registration/login.html:4
#: src/templates/registration/login.html:11
#: src/templates/registration/login.html:24
Expand All @@ -676,3 +702,6 @@ msgstr "Se connecter"
#: src/templates/registration/login.html:21
msgid "Password"
msgstr "Mot de passe"

#~ msgid "Log Out"
#~ msgstr "Se déconnecter"
Binary file added src/static/images/bookshelf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 9 additions & 9 deletions src/static/js/base.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// THEME SWITCHER
document.addEventListener("DOMContentLoaded", () => {
const htmlElement = document.documentElement;
const themeRadios = document.querySelectorAll('input[name="theme-dropdown"]');
const themeRadios = document.querySelectorAll('input[name="theme-sidebar"]');

const applyTheme = (theme) => {
if (theme === "default") {
Expand All @@ -13,30 +13,30 @@ document.addEventListener("DOMContentLoaded", () => {
}
};

// initialise theme
// Initialize theme
const currentTheme = localStorage.getItem("theme") || "default";
applyTheme(currentTheme);

// activate the menu item of the current theme
const currentRadio = document.querySelector(`input[value="${currentTheme}"]`);
// Activate the radio button of the current theme
const currentRadio = document.querySelector(`input[name="theme-sidebar"][value="${currentTheme}"]`);
if (currentRadio) {
currentRadio.checked = true;
}

// add an event listener to each menu item
// Add event listener to each radio button
themeRadios.forEach((radio) => {
radio.addEventListener("change", (event) => {
const selectedTheme = event.target.value;
applyTheme(selectedTheme);
const selectedTheme = event.target.value;
applyTheme(selectedTheme);
});
});
});

// CLEAN URL - Remove default/empty parameters from URL
// Default values that should not appear in URL
const DEFAULT_PARAMS = {
'view_mode': 'list',
'sort': '-created_at',
'view_mode': 'grid',
'sort': '-review_date',
};

// Remove empty and default parameters before HTMX sends the request
Expand Down
13 changes: 8 additions & 5 deletions src/templates/accounts/profile_edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ <h2 class="card-title">{% translate "Profile Information" %}</h2>
</label>
{{ profile_form.email }}
<label class="label" id="error-email">
{% if profile_form.email.errors %}<span class="label-text-alt text-error">{{ profile_form.email.errors.0 }}</span>{% endif %}
{% if profile_form.email.errors %}
<span class="label-text-alt text-error">{{ profile_form.email.errors.0 }}</span>
{% endif %}
</label>
</div>
<div class="form-control">
Expand Down Expand Up @@ -72,17 +74,18 @@ <h2 class="card-title">{% translate "Profile Information" %}</h2>
<div class="card bg-base-200 shadow-xl mb-8">
<div class="card-body">
<h2 class="card-title">{% translate "Language Preference" %}</h2>
<form method="post" action="{% url 'accounts:set_language' %}" class="space-y-6">
<form method="post"
action="{% url 'accounts:set_language' %}"
class="space-y-6">
{% csrf_token %}
<div class="form-control">
<label class="label" for="language">
<span class="label-text">{% translate "Choose your preferred language" %}</span>
</label>
<select name="language" id="language" class="select select-bordered w-full">
{% for lang_code, lang_name in languages %}
<option value="{{ lang_code }}"{% if current_language == lang_code %} selected{% endif %}>
{{ lang_name }}
</option>
<option value="{{ lang_code }}"
{% if current_language == lang_code %}selected{% endif %}>{{ lang_name }}</option>
{% endfor %}
</select>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/templates/backup_manage.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h1 class="text-3xl font-bold mb-8">{% translate "Backup Management" %}</h1>
<div class="mb-6">
{% for message in messages %}
<div role="alert"
class="alert {% if message.tags == 'error' %}alert-error{% elif message.tags == 'success' %}alert-success{% else %}alert-info{% endif %} mb-2">
class="alert {% if message.tags == 'error' %}alert-error {% elif message.tags == 'success' %}alert-success {% else %}alert-info {% endif %}mb-2">
<span>{{ message }}</span>
</div>
{% endfor %}
Expand Down
Loading