diff --git a/data/db.sqlite3 b/data/db.sqlite3 index 140ec13..81c688a 100644 Binary files a/data/db.sqlite3 and b/data/db.sqlite3 differ diff --git a/links/forms.py b/links/forms.py index fe301cc..9e48c91 100644 --- a/links/forms.py +++ b/links/forms.py @@ -88,9 +88,10 @@ class MultipleFileField(forms.FileField): class ImageCollectionForm(forms.ModelForm): class Meta: model = ImageCollection - fields = ['name', 'description'] + fields = ['name', 'description', 'tags'] widgets = { 'description': forms.Textarea(attrs={'rows': 3}), + 'tags': forms.SelectMultiple(attrs={'class': 'select2'}), } class ImageUploadForm(forms.ModelForm): diff --git a/links/migrations/0028_imagecollection_tags.py b/links/migrations/0028_imagecollection_tags.py new file mode 100644 index 0000000..74599c9 --- /dev/null +++ b/links/migrations/0028_imagecollection_tags.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.9 on 2024-12-19 05:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('links', '0027_remove_tag_color'), + ] + + operations = [ + migrations.AddField( + model_name='imagecollection', + name='tags', + field=models.ManyToManyField(blank=True, related_name='image_collections', to='links.tag', verbose_name='Tags'), + ), + ] diff --git a/links/models.py b/links/models.py index 1858d92..0f39898 100644 --- a/links/models.py +++ b/links/models.py @@ -275,6 +275,7 @@ class ImageCollection(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) name = models.CharField(_('Name'), max_length=200) description = models.TextField(_('Description'), blank=True) + tags = models.ManyToManyField('Tag', verbose_name=_('Tags'), blank=True, related_name='image_collections') created_at = models.DateTimeField(_('Created at'), auto_now_add=True) updated_at = models.DateTimeField(_('Updated at'), auto_now=True) diff --git a/links/templates/links/collection_detail.html b/links/templates/links/collection_detail.html index da68076..0abafab 100644 --- a/links/templates/links/collection_detail.html +++ b/links/templates/links/collection_detail.html @@ -176,10 +176,25 @@
-

{{ collection.name }}

{% if collection.description %} -

{{ collection.description }}

+
+

{% trans "Description" %}

+

{{ collection.description }}

+
{% endif %} + + +
+
+ {% for tag in collection.tags.all %} + + {{ tag.name }} + + {% empty %} + {% trans "No tags" %} + {% endfor %} +
+
@@ -319,6 +334,14 @@ {% block extra_js %} + + +{% endblock %} diff --git a/links/templates/links/collection_list.html b/links/templates/links/collection_list.html index 6a10ee8..657c648 100644 --- a/links/templates/links/collection_list.html +++ b/links/templates/links/collection_list.html @@ -49,17 +49,17 @@
-

- {{ collection.name }} -

-

- {{ collection.images.count }} {% trans "images" %} -

- {% if collection.description %} -

- {{ collection.description }} +

+

{{ collection.name }}

+ {% if collection.description %} +

{{ collection.description }}

+ {% endif %} + + +

+ {{ collection.images.count }} {% trans "images" %}

- {% endif %} +
@@ -142,6 +142,32 @@ function deleteCollection(collectionId) { }); } } + +document.addEventListener('DOMContentLoaded', function() { + const colors = [ + 'bg-blue-50 hover:bg-blue-100 text-blue-700', + 'bg-green-50 hover:bg-green-100 text-green-700', + 'bg-yellow-50 hover:bg-yellow-100 text-yellow-700', + 'bg-red-50 hover:bg-red-100 text-red-700', + 'bg-indigo-50 hover:bg-indigo-100 text-indigo-700', + 'bg-purple-50 hover:bg-purple-100 text-purple-700', + 'bg-pink-50 hover:bg-pink-100 text-pink-700', + 'bg-cyan-50 hover:bg-cyan-100 text-cyan-700', + 'bg-orange-50 hover:bg-orange-100 text-orange-700', + 'bg-teal-50 hover:bg-teal-100 text-teal-700', + 'bg-lime-50 hover:bg-lime-100 text-lime-700', + 'bg-emerald-50 hover:bg-emerald-100 text-emerald-700', + 'bg-sky-50 hover:bg-sky-100 text-sky-700', + 'bg-violet-50 hover:bg-violet-100 text-violet-700', + 'bg-rose-50 hover:bg-rose-100 text-rose-700', + 'bg-amber-50 hover:bg-amber-100 text-amber-700' + ]; + + document.querySelectorAll('.tag-card').forEach(tag => { + const randomColor = colors[Math.floor(Math.random() * colors.length)]; + tag.classList.add(...randomColor.split(' ')); + }); +}); {% endblock %} {% endblock %} diff --git a/new_theme/static/css/dist/styles.css b/new_theme/static/css/dist/styles.css index 3450973..40a1531 100644 --- a/new_theme/static/css/dist/styles.css +++ b/new_theme/static/css/dist/styles.css @@ -795,6 +795,14 @@ video { margin-top: 2rem; } +.-ml-4 { + margin-left: -1rem; +} + +.mb-3 { + margin-bottom: 0.75rem; +} + .line-clamp-1 { overflow: hidden; display: -webkit-box; @@ -916,6 +924,14 @@ video { min-height: 100vh; } +.min-h-0 { + min-height: 0px; +} + +.min-h-\[120px\] { + min-height: 120px; +} + .w-12 { width: 3rem; } @@ -1046,6 +1062,10 @@ video { user-select: all; } +.resize-y { + resize: vertical; +} + .resize { resize: both; } @@ -1120,6 +1140,10 @@ video { gap: 1.5rem; } +.gap-3 { + gap: 0.75rem; +} + .gap-x-4 { -moz-column-gap: 1rem; column-gap: 1rem; @@ -1248,6 +1272,10 @@ video { border-radius: 0.375rem; } +.rounded-xl { + border-radius: 0.75rem; +} + .rounded-l-md { border-top-left-radius: 0.375rem; border-bottom-left-radius: 0.375rem; @@ -1514,6 +1542,18 @@ video { background-color: rgb(245 243 255 / var(--tw-bg-opacity)); } +.bg-black\/50 { + background-color: rgb(0 0 0 / 0.5); +} + +.bg-black\/75 { + background-color: rgb(0 0 0 / 0.75); +} + +.bg-gray-900\/75 { + background-color: rgb(17 24 39 / 0.75); +} + .bg-opacity-20 { --tw-bg-opacity: 0.2; } @@ -1792,6 +1832,10 @@ video { line-height: 1.25; } +.leading-relaxed { + line-height: 1.625; +} + .tracking-normal { letter-spacing: 0em; } @@ -2898,4 +2942,8 @@ video { .xl\:grid-cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); } + + .xl\:grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } }