subjects.html 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 id="btnCreate" 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 id="btnCreateEmpty" 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 hidden items-center justify-center modal-overlay bg-black/40">
  50. <div class="bg-white rounded-2xl w-full max-w-md mx-4 shadow-2xl max-h-[90vh] overflow-y-auto">
  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 id="btnCloseModal" 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" data-color="{{ c }}">
  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 ring-transparent"
  68. style="background-color:{{ c }};"></span>
  69. </label>
  70. {% endfor %}
  71. </div>
  72. </div>
  73. <div class="flex gap-3">
  74. <button type="button" id="btnCancel" 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(){
  84. var modal = document.getElementById('createModal');
  85. function openModal(){ if(modal) modal.classList.remove('hidden'); }
  86. function closeModal(){ if(modal) modal.classList.add('hidden'); }
  87. var btns = document.querySelectorAll('#btnCreate, #btnCreateEmpty');
  88. var closeBtns = document.querySelectorAll('#btnCloseModal, #btnCancel');
  89. btns.forEach(function(b){ b.addEventListener('click', openModal); });
  90. closeBtns.forEach(function(b){ b.addEventListener('click', closeModal); });
  91. if(modal){
  92. modal.addEventListener('click', function(e){
  93. if(e.target === modal) closeModal();
  94. });
  95. }
  96. document.querySelectorAll('input[name="color"]').forEach(function(r){
  97. r.addEventListener('change', function(){
  98. document.querySelectorAll('input[name="color"]').forEach(function(el){
  99. el.nextElementSibling.classList.add('ring-transparent');
  100. el.nextElementSibling.classList.remove('ring-2','ring-offset-2','ring-gray-400');
  101. });
  102. this.nextElementSibling.classList.remove('ring-transparent');
  103. this.nextElementSibling.classList.add('ring-2','ring-offset-2','ring-gray-400');
  104. });
  105. });
  106. })();
  107. </script>
  108. {% endblock %}