mirror of
https://github.com/wahyd4/links.git
synced 2026-08-08 21:04:53 +10:00
Update logic
This commit is contained in:
@@ -35,48 +35,54 @@
|
||||
</div>
|
||||
|
||||
<!-- Collection Header -->
|
||||
<div class="flex justify-between items-start mb-6">
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-gray-900">{{ collection.name }}</h1>
|
||||
<div class="flex flex-col space-y-4 sm:space-y-0 sm:flex-row sm:justify-between sm:items-start mb-6">
|
||||
<!-- Title and Description -->
|
||||
<div class="flex-1">
|
||||
<h1 class="text-2xl sm:text-3xl font-bold text-gray-900">{{ collection.name }}</h1>
|
||||
{% if collection.description %}
|
||||
<p class="mt-2 text-gray-600">{{ collection.description }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="flex space-x-2">
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="flex flex-wrap gap-2 sm:space-x-2">
|
||||
<button type="button"
|
||||
onclick="document.getElementById('uploadModal').classList.remove('hidden')"
|
||||
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
class="inline-flex items-center px-3 py-2 sm:px-4 sm:py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700">
|
||||
<svg class="w-5 h-5 sm:mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"/>
|
||||
</svg>
|
||||
{% trans "Upload Images" %}
|
||||
<span class="hidden sm:inline">{% trans "Upload Images" %}</span>
|
||||
</button>
|
||||
|
||||
<a href="{% url 'collection-update' collection.pk %}"
|
||||
class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md shadow-sm text-gray-700 bg-white hover:bg-gray-50">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
class="inline-flex items-center px-3 py-2 sm:px-4 sm:py-2 border border-gray-300 text-sm font-medium rounded-md shadow-sm text-gray-700 bg-white hover:bg-gray-50">
|
||||
<svg class="w-5 h-5 sm:mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
|
||||
</svg>
|
||||
{% trans "Edit Collection" %}
|
||||
<span class="hidden sm:inline">{% trans "Edit Collection" %}</span>
|
||||
</a>
|
||||
|
||||
<button type="button"
|
||||
onclick="deleteCollection('{{ collection.pk }}')"
|
||||
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-red-600 hover:bg-red-700">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
class="inline-flex items-center px-3 py-2 sm:px-4 sm:py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-red-600 hover:bg-red-700">
|
||||
<svg class="w-5 h-5 sm:mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
|
||||
</svg>
|
||||
{% trans "Delete Collection" %}
|
||||
<span class="hidden sm:inline">{% trans "Delete Collection" %}</span>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
onclick="window.location.href='{% url 'collection-slideshow' collection.pk %}'"
|
||||
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
class="inline-flex items-center px-3 py-2 sm:px-4 sm:py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700">
|
||||
<svg class="w-5 h-5 sm:mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
{% trans "Slideshow" %}
|
||||
<span class="hidden sm:inline">{% trans "Slideshow" %}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
{% load static %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-bold text-gray-900">{% trans "Image Collections" %}</h1>
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 sm:py-8">
|
||||
<div class="flex justify-between items-center mb-4 sm:mb-6">
|
||||
<h1 class="text-xl sm:text-2xl font-bold text-gray-900">{% trans "Image Collections" %}</h1>
|
||||
<a href="{% url 'collection-create' %}"
|
||||
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
class="inline-flex items-center px-3 py-1.5 sm:px-4 sm:py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700">
|
||||
<svg class="w-4 h-4 sm:w-5 sm:h-5 mr-1.5 sm:mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
|
||||
</svg>
|
||||
{% trans "New Collection" %}
|
||||
@@ -16,28 +16,29 @@
|
||||
</div>
|
||||
|
||||
<!-- Collections Grid -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-8 gap-y-10">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 sm:gap-6 md:gap-8">
|
||||
{% for collection in collections %}
|
||||
<div class="group relative bg-white rounded-lg shadow-sm overflow-hidden hover:shadow-md transition-all duration-200">
|
||||
<a href="{% url 'collection-detail' collection.pk %}"
|
||||
class="block">
|
||||
<!-- Collection Preview (first 4 images) -->
|
||||
<!-- Collection Preview (2 images on mobile, 4 on desktop) -->
|
||||
<div class="aspect-w-16 aspect-h-12 bg-gradient-to-br from-gray-50 to-gray-100">
|
||||
<div class="grid grid-cols-2 gap-2 p-3">
|
||||
<div class="grid grid-cols-2 gap-1.5 sm:gap-2 p-2 sm:p-3">
|
||||
{% with images=collection.images.all|slice:":4" %}
|
||||
{% for image in images %}
|
||||
<div class="aspect-w-1 aspect-h-1 overflow-hidden rounded-lg bg-gray-200 shadow-sm">
|
||||
<div class="aspect-w-1 aspect-h-1 overflow-hidden rounded-lg bg-gray-200 shadow-sm
|
||||
{% if forloop.counter > 2 %}hidden sm:block{% endif %}">
|
||||
<img src="{{ image.get_url }}"
|
||||
alt="{{ image.title }}"
|
||||
class="object-cover w-full h-full">
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col-span-2 flex flex-col items-center justify-center h-full bg-gradient-to-br from-gray-50 to-gray-100 rounded-lg border-2 border-dashed border-gray-200">
|
||||
<svg class="w-12 h-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg class="w-8 h-8 sm:w-12 sm:h-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
<p class="mt-2 text-sm text-gray-500">{% trans "No images yet" %}</p>
|
||||
<p class="mt-1 sm:mt-2 text-xs sm:text-sm text-gray-500">{% trans "No images yet" %}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
@@ -45,33 +46,33 @@
|
||||
</div>
|
||||
|
||||
<!-- Collection Info -->
|
||||
<div class="p-4">
|
||||
<h3 class="text-lg font-medium text-gray-900 group-hover:text-blue-600 transition-colors duration-200">
|
||||
<div class="p-3 sm:p-4">
|
||||
<h3 class="text-base sm:text-lg font-medium text-gray-900 group-hover:text-blue-600 transition-colors duration-200">
|
||||
{{ collection.name }}
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
<p class="mt-0.5 sm:mt-1 text-xs sm:text-sm text-gray-500">
|
||||
{{ collection.images.count }} {% trans "images" %}
|
||||
</p>
|
||||
{% if collection.description %}
|
||||
<p class="mt-2 text-sm text-gray-600 line-clamp-2">{{ collection.description }}</p>
|
||||
<p class="mt-1 sm:mt-2 text-xs sm:text-sm text-gray-600 line-clamp-2">{{ collection.description }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="absolute top-2 right-2 flex space-x-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
||||
<div class="absolute top-1.5 sm:top-2 right-1.5 sm:right-2 flex space-x-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
||||
<a href="{% url 'collection-update' collection.pk %}"
|
||||
class="p-1.5 bg-white text-gray-600 hover:text-blue-600 rounded-full hover:bg-blue-50 shadow-sm transition-colors duration-200"
|
||||
class="p-1 sm:p-1.5 bg-white text-gray-600 hover:text-blue-600 rounded-full hover:bg-blue-50 shadow-sm transition-colors duration-200"
|
||||
title="{% trans 'Edit Collection' %}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg class="w-4 h-4 sm:w-5 sm:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<button onclick="deleteCollection('{{ collection.pk }}'); event.preventDefault();"
|
||||
class="p-1.5 bg-white text-gray-600 hover:text-red-600 rounded-full hover:bg-red-50 shadow-sm transition-colors duration-200"
|
||||
class="p-1 sm:p-1.5 bg-white text-gray-600 hover:text-red-600 rounded-full hover:bg-red-50 shadow-sm transition-colors duration-200"
|
||||
title="{% trans 'Delete Collection' %}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg class="w-4 h-4 sm:w-5 sm:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
|
||||
</svg>
|
||||
|
||||
Vendored
+132
-5
@@ -645,6 +645,14 @@ video {
|
||||
top: 100%;
|
||||
}
|
||||
|
||||
.right-1\.5 {
|
||||
right: 0.375rem;
|
||||
}
|
||||
|
||||
.top-1\.5 {
|
||||
top: 0.375rem;
|
||||
}
|
||||
|
||||
.z-0 {
|
||||
z-index: 0;
|
||||
}
|
||||
@@ -767,6 +775,10 @@ video {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.mt-0\.5 {
|
||||
margin-top: 0.125rem;
|
||||
}
|
||||
|
||||
.line-clamp-2 {
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
@@ -853,6 +865,10 @@ video {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.h-8 {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.w-12 {
|
||||
width: 3rem;
|
||||
}
|
||||
@@ -889,6 +905,10 @@ video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.w-8 {
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.min-w-0 {
|
||||
min-width: 0px;
|
||||
}
|
||||
@@ -989,6 +1009,10 @@ video {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.items-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
@@ -1021,6 +1045,10 @@ video {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.gap-1\.5 {
|
||||
gap: 0.375rem;
|
||||
}
|
||||
|
||||
.gap-x-4 {
|
||||
-moz-column-gap: 1rem;
|
||||
column-gap: 1rem;
|
||||
@@ -1291,6 +1319,11 @@ video {
|
||||
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-green-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(22 163 74 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-purple-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(243 232 255 / var(--tw-bg-opacity));
|
||||
@@ -1340,11 +1373,6 @@ video {
|
||||
background-color: rgb(254 249 195 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-green-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(22 163 74 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-opacity-50 {
|
||||
--tw-bg-opacity: 0.5;
|
||||
}
|
||||
@@ -1494,6 +1522,11 @@ video {
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.py-1\.5 {
|
||||
padding-top: 0.375rem;
|
||||
padding-bottom: 0.375rem;
|
||||
}
|
||||
|
||||
.pl-3 {
|
||||
padding-left: 0.75rem;
|
||||
}
|
||||
@@ -2121,6 +2154,14 @@ video {
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.sm\:right-2 {
|
||||
right: 0.5rem;
|
||||
}
|
||||
|
||||
.sm\:top-2 {
|
||||
top: 0.5rem;
|
||||
}
|
||||
|
||||
.sm\:col-span-1 {
|
||||
grid-column: span 1 / span 1;
|
||||
}
|
||||
@@ -2150,6 +2191,22 @@ video {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.sm\:mb-6 {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.sm\:mr-2 {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.sm\:mt-1 {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.sm\:mt-2 {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.sm\:block {
|
||||
display: block;
|
||||
}
|
||||
@@ -2170,6 +2227,14 @@ video {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.sm\:h-12 {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
.sm\:h-5 {
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
.sm\:w-10 {
|
||||
width: 2.5rem;
|
||||
}
|
||||
@@ -2182,6 +2247,14 @@ video {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.sm\:w-12 {
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.sm\:w-5 {
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
.sm\:grid-cols-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
@@ -2214,6 +2287,14 @@ video {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.sm\:gap-2 {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.sm\:gap-6 {
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.sm\:space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||
@@ -2244,6 +2325,18 @@ video {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.sm\:p-1\.5 {
|
||||
padding: 0.375rem;
|
||||
}
|
||||
|
||||
.sm\:p-3 {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.sm\:p-4 {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.sm\:px-6 {
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
@@ -2259,6 +2352,21 @@ video {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.sm\:px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.sm\:py-2 {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.sm\:py-8 {
|
||||
padding-top: 2rem;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.sm\:text-left {
|
||||
text-align: left;
|
||||
}
|
||||
@@ -2272,6 +2380,21 @@ video {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
.sm\:text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.sm\:text-lg {
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
|
||||
.sm\:text-3xl {
|
||||
font-size: 1.875rem;
|
||||
line-height: 2.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
@@ -2290,6 +2413,10 @@ video {
|
||||
.md\:grid-cols-4 {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.md\:gap-8 {
|
||||
gap: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
|
||||
Reference in New Issue
Block a user