subject_detail.html 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. {% extends "base.html" %}
  2. {% block title %}{{ subject.name }} - 满意错题本{% endblock %}
  3. {% block page_title %}{{ subject.name }}{% endblock %}
  4. {% block content %}
  5. <div class="flex items-center gap-3 mb-6">
  6. <a href="/subjects" class="text-sm text-gray-400 hover:text-gray-600 transition flex items-center gap-1">
  7. <i class="fa-solid fa-arrow-left"></i>返回
  8. </a>
  9. <span class="w-2.5 h-2.5 rounded-full" style="background-color:{{ subject.color }}"></span>
  10. <span class="text-xs text-gray-400">{{ images|length }} 条记录</span>
  11. </div>
  12. <!-- Date nav -->
  13. <div class="bg-white rounded-2xl border border-gray-100 p-4 mb-6">
  14. <div class="flex items-center gap-3 overflow-x-auto pb-1">
  15. {% if prev_date %}
  16. <a href="?date={{ prev_date }}" class="flex-shrink-0 w-9 h-9 rounded-xl bg-gray-50 hover:bg-gray-100 flex items-center justify-center text-gray-500 transition" title="上一日期">
  17. <i class="fa-solid fa-chevron-left text-sm"></i>
  18. </a>
  19. {% else %}
  20. <span class="flex-shrink-0 w-9 h-9 rounded-xl bg-gray-50 flex items-center justify-center text-gray-200">
  21. <i class="fa-solid fa-chevron-left text-sm"></i>
  22. </span>
  23. {% endif %}
  24. {% for d in dates %}
  25. <a href="?date={{ d }}" class="date-chip flex-shrink-0 px-3 py-1.5 rounded-xl text-xs font-medium transition {% if d == current_date %}bg-primary text-white shadow-sm{% else %}bg-gray-50 text-gray-500 hover:bg-gray-100{% endif %}">
  26. {{ d }}
  27. </a>
  28. {% endfor %}
  29. {% if next_date %}
  30. <a href="?date={{ next_date }}" class="flex-shrink-0 w-9 h-9 rounded-xl bg-gray-50 hover:bg-gray-100 flex items-center justify-center text-gray-500 transition" title="下一日期">
  31. <i class="fa-solid fa-chevron-right text-sm"></i>
  32. </a>
  33. {% else %}
  34. <span class="flex-shrink-0 w-9 h-9 rounded-xl bg-gray-50 flex items-center justify-center text-gray-200">
  35. <i class="fa-solid fa-chevron-right text-sm"></i>
  36. </span>
  37. {% endif %}
  38. <span class="text-gray-200 flex-shrink-0">|</span>
  39. <form method="GET" action="" class="flex-shrink-0 flex items-center gap-2">
  40. <input type="date" name="date" value="{{ current_date }}"
  41. onchange="this.form.submit()"
  42. class="border border-gray-200 rounded-xl px-3 py-1.5 text-xs focus:outline-none focus:ring-2 focus:ring-primary/30 text-gray-500">
  43. </form>
  44. </div>
  45. </div>
  46. <!-- Upload form -->
  47. <div class="bg-white rounded-2xl border border-dashed border-gray-200 p-5 mb-6">
  48. <h4 class="font-semibold text-gray-700 text-sm mb-3"><i class="fa-solid fa-cloud-arrow-up mr-2 text-primary"></i>上传错题图片</h4>
  49. <form method="POST" action="/subject/{{ subject.id }}/upload" enctype="multipart/form-data" id="uploadForm">
  50. <input type="hidden" name="date" value="{{ current_date }}">
  51. <div class="flex items-start gap-4">
  52. <label class="flex-1 cursor-pointer">
  53. <div class="border-2 border-dashed border-gray-200 rounded-xl p-6 text-center hover:border-primary/50 hover:bg-indigo-50/30 transition" id="dropZone">
  54. <i class="fa-solid fa-images text-2xl text-gray-300 mb-2 block"></i>
  55. <p class="text-sm text-gray-500">点击选择或拖拽图片到此</p>
  56. <p class="text-xs text-gray-300 mt-1">支持 JPG、PNG、WEBP,可多选</p>
  57. <input type="file" name="files" multiple accept="image/*" class="hidden" id="fileInput" onchange="updateFileLabel()">
  58. </div>
  59. </label>
  60. <button type="submit" class="flex-shrink-0 bg-primary text-white px-5 py-2.5 rounded-xl text-sm font-medium hover:bg-indigo-600 transition shadow-sm">
  61. <i class="fa-solid fa-upload mr-1.5"></i>上传
  62. </button>
  63. </div>
  64. <p id="fileLabel" class="text-xs text-primary mt-2 min-h-[18px]"></p>
  65. </form>
  66. </div>
  67. <!-- Image grid -->
  68. {% if images %}
  69. <div class="mb-4 flex items-center justify-between">
  70. <h3 class="font-semibold text-gray-700 text-sm">{{ current_date }} 的错题({{ images|length }} 张)</h3>
  71. <span class="text-xs text-gray-400">点击可放大查看</span>
  72. </div>
  73. <div class="grid grid-cols-4 gap-4">
  74. {% for img in images %}
  75. <div class="image-card group relative aspect-[3/4] rounded-2xl overflow-hidden bg-gray-100 shadow-sm cursor-pointer" onclick="openLightbox('/static/uploads/{{ img.filename }}','{{ img.original_name }}',lbAllImages,{{ loop.index0 }})">
  76. <img src="/static/uploads/{{ img.filename }}" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" loading="lazy">
  77. <div class="image-actions absolute inset-0 bg-black/30 opacity-0 transition flex items-center justify-center gap-2">
  78. <button onclick="event.stopPropagation();openLightbox('/static/uploads/{{ img.filename }}','{{ img.original_name }}',lbAllImages,{{ loop.index0 }})" class="w-9 h-9 rounded-full bg-white/90 flex items-center justify-center text-gray-700 hover:bg-white transition" title="查看">
  79. <i class="fa-solid fa-magnifying-glass-plus text-sm"></i>
  80. </button>
  81. <form method="POST" action="/image/{{ img.id }}/delete" onsubmit="return confirm('确定删除这张错题图片?')" onclick="event.stopPropagation()">
  82. <button type="submit" class="w-9 h-9 rounded-full bg-white/90 flex items-center justify-center text-red-500 hover:bg-red-50 transition" title="删除">
  83. <i class="fa-solid fa-trash-can text-sm"></i>
  84. </button>
  85. </form>
  86. </div>
  87. <div class="absolute bottom-2 left-2 right-2">
  88. <p class="text-[10px] text-white/80 truncate px-1.5 py-0.5 bg-black/30 rounded">{{ img.original_name }}</p>
  89. </div>
  90. </div>
  91. {% endfor %}
  92. </div>
  93. {% else %}
  94. <div class="bg-white rounded-2xl border border-gray-100 p-12 text-center">
  95. <div class="text-5xl text-gray-200 mb-4"><i class="fa-regular fa-folder-open"></i></div>
  96. <p class="text-gray-400 text-sm">该日期暂无错题记录</p>
  97. </div>
  98. {% endif %}
  99. {% endblock %}
  100. {% block extra_js %}
  101. <script>
  102. const lbAllImages = [
  103. {% for img in images %}
  104. "/static/uploads/{{ img.filename }}",
  105. {% endfor %}
  106. ];
  107. function updateFileLabel(){
  108. const f=document.getElementById('fileInput').files;
  109. document.getElementById('fileLabel').textContent=f.length?f.length+' 个文件已选择':'';
  110. }
  111. const dz=document.getElementById('dropZone');
  112. dz.addEventListener('dragover',e=>{e.preventDefault();dz.classList.add('border-primary','bg-indigo-50/30');});
  113. dz.addEventListener('dragleave',()=>dz.classList.remove('border-primary','bg-indigo-50/30'));
  114. dz.addEventListener('drop',e=>{e.preventDefault();dz.classList.remove('border-primary','bg-indigo-50/30');document.getElementById('fileInput').files=e.dataTransfer.files;updateFileLabel();});
  115. </script>
  116. {% endblock %}