subjects.html 5.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. {% extends "base.html" %}
  2. {% block title %}科目管理 - 满意错题本{% endblock %}
  3. {% block page_title %}科目管理{% endblock %}
  4. {% block content %}
  5. <div class="flex items-center justify-between mb-6">
  6. <div>
  7. <p class="text-xs text-gray-400">管理你的所有科目</p>
  8. </div>
  9. <button onclick="openModal()" class="inline-flex items-center gap-2 bg-primary text-white px-5 py-2.5 rounded-xl text-sm font-medium hover:bg-indigo-600 transition shadow-sm">
  10. <i class="fa-solid fa-plus"></i>新建科目
  11. </button>
  12. </div>
  13. <!-- Subject list -->
  14. {% if subjects %}
  15. <div class="grid grid-cols-3 gap-5">
  16. {% for subject in subjects %}
  17. <div class="bg-white rounded-2xl shadow-sm border border-gray-100 p-5 hover:shadow-md transition group">
  18. <div class="flex items-start justify-between mb-4">
  19. <div class="flex items-center gap-3">
  20. <span class="w-4 h-4 rounded-full shadow-sm flex-shrink-0" style="background-color:{{ subject.color }};box-shadow:0 0 0 3px {{ subject.color }}20"></span>
  21. <h3 class="font-bold text-gray-800 text-base">{{ subject.name }}</h3>
  22. </div>
  23. <form method="POST" action="/subjects/{{ subject.id }}/delete" onsubmit="return confirm('确定删除「{{ subject.name }}」?将同时删除所有错题记录。')">
  24. <button type="submit" class="text-gray-300 hover:text-red-400 transition opacity-0 group-hover:opacity-100" title="删除科目">
  25. <i class="fa-solid fa-trash-can"></i>
  26. </button>
  27. </form>
  28. </div>
  29. <div class="flex items-center gap-4 text-xs text-gray-400 mb-5">
  30. <span><i class="fa-solid fa-image mr-1"></i>{{ subject.error_images|length }} 条记录</span>
  31. <span><i class="fa-solid fa-calendar mr-1"></i>{{ subject.created_at.strftime('%Y-%m-%d') }}</span>
  32. </div>
  33. <a href="/subject/{{ subject.id }}" class="block w-full text-center bg-gray-50 hover:bg-indigo-50 text-gray-600 hover:text-primary py-2.5 rounded-xl text-sm font-medium transition">
  34. <i class="fa-solid fa-arrow-right-to-bracket mr-1"></i>进入科目
  35. </a>
  36. </div>
  37. {% endfor %}
  38. </div>
  39. {% else %}
  40. <div class="bg-white rounded-2xl border border-gray-100 p-16 text-center">
  41. <div class="text-6xl text-gray-200 mb-4"><i class="fa-solid fa-folder-open"></i></div>
  42. <p class="text-gray-400 mb-6">还没有科目,先创建一个吧</p>
  43. <button onclick="openModal()" class="inline-flex items-center gap-2 bg-primary text-white px-6 py-3 rounded-xl text-sm font-medium hover:bg-indigo-600 transition">
  44. <i class="fa-solid fa-plus"></i>新建第一个科目
  45. </button>
  46. </div>
  47. {% endif %}
  48. <!-- Create modal -->
  49. <div id="createModal" class="fixed inset-0 z-50 items-center justify-center modal-overlay bg-black/40" style="display:none">
  50. <div class="bg-white rounded-2xl w-full max-w-md mx-4 shadow-2xl">
  51. <div class="px-6 py-5 border-b border-gray-100 flex items-center justify-between sticky top-0 bg-white z-10 rounded-t-2xl">
  52. <h3 class="font-bold text-gray-800">新建科目</h3>
  53. <button onclick="closeModal()" class="text-gray-400 hover:text-gray-600"><i class="fa-solid fa-xmark text-lg"></i></button>
  54. </div>
  55. <form method="POST" action="/subjects/create" class="p-6">
  56. <div class="mb-5">
  57. <label class="block text-sm font-medium text-gray-600 mb-2">科目名称</label>
  58. <input type="text" name="name" required placeholder="例如:数学、英语、物理..."
  59. class="w-full border border-gray-200 rounded-xl px-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary transition">
  60. </div>
  61. <div class="mb-6">
  62. <label class="block text-sm font-medium text-gray-600 mb-2">主题色</label>
  63. <div class="flex gap-2 flex-wrap">
  64. {% for c in colors %}
  65. <label class="cursor-pointer">
  66. <input type="radio" name="color" value="{{ c }}" {% if loop.first %}checked{% endif %} class="hidden peer">
  67. <span class="w-8 h-8 rounded-full block peer-checked:ring-2 peer-checked:ring-offset-2 peer-checked:ring-gray-400 transition hover:scale-110"
  68. style="background-color:{{ c }};"></span>
  69. </label>
  70. {% endfor %}
  71. </div>
  72. </div>
  73. <div class="flex gap-3">
  74. <button type="button" onclick="closeModal()" class="flex-1 border border-gray-200 text-gray-600 py-2.5 rounded-xl text-sm font-medium hover:bg-gray-50 transition">取消</button>
  75. <button type="submit" class="flex-1 bg-primary text-white py-2.5 rounded-xl text-sm font-medium hover:bg-indigo-600 transition">创建</button>
  76. </div>
  77. </form>
  78. </div>
  79. </div>
  80. {% endblock %}
  81. {% block extra_js %}
  82. <script>
  83. function openModal(){const m=document.getElementById('createModal');m.style.display='flex';}
  84. function closeModal(){const m=document.getElementById('createModal');m.style.display='none';}
  85. document.querySelectorAll('input[name="color"]').forEach(r=>{
  86. r.addEventListener('change',function(){
  87. document.querySelectorAll('input[name="color"]~span').forEach(s=>s.style.boxShadow='none');
  88. this.nextElementSibling.style.boxShadow='0 0 0 3px '+this.value+'40';
  89. });
  90. });
  91. // Init color ring
  92. document.querySelector('input[name="color"]:checked')?.nextElementSibling.style.boxShadow='0 0 0 3px '+document.querySelector('input[name="color"]:checked').value+'40';
  93. </script>
  94. {% endblock %}