瀏覽代碼

make slot grid responsive

subDesTagesMitExtraKaese 2 年之前
父節點
當前提交
ecc4541fdc
共有 3 個文件被更改,包括 72 次插入48 次删除
  1. 16 9
      zitap/helpers.py
  2. 46 22
      zitap/static/zitap/css/event.css
  3. 10 17
      zitap/templates/zitap/event.html

+ 16 - 9
zitap/helpers.py

@@ -42,7 +42,7 @@ def slots2grid( event : Event ) -> dict :
     data = {
         'rows': [],
         'days': [],
-        'slot_height': 30 * (event.slot_interval.total_seconds() / 3600),
+        'colors': [],
         'n_days': event.date_set.count(),
     }
     # Get the timespan of the event
@@ -67,16 +67,24 @@ def slots2grid( event : Event ) -> dict :
                     slot_participants[j].append(participant)
         # Fill the slots of the day
         slots = []
+        last_hour = None
+        last_half_hour = None
         for j, ps in enumerate(slot_participants):
             slot_begin = (start_time + j * event.slot_interval).strftime('%H:%M')
             slot_end = (start_time + (j+1) * event.slot_interval).strftime('%H:%M')
+            current_time = start_time + j * event.slot_interval
             slots.append({
                 'tooltip': f"{slot_begin} - {slot_end} \n{', '.join([p.user.username for p in ps])}",
-                'occupancy': len(ps),
                 'offset': n*slots_per_day + j,
                 'date': date.date,
+                'time': current_time,
+                'class': f'color_{len(ps)}',
+                'is_full_hour': current_time.hour != last_hour,
+                'is_half_hour': current_time.minute // 30 != last_half_hour,
             })
             max_occupancy = max(max_occupancy, len(ps))
+            last_hour = current_time.hour
+            last_half_hour = current_time.minute // 30
         
         day = {
             'date': date.date,
@@ -89,21 +97,20 @@ def slots2grid( event : Event ) -> dict :
     for i in range(slots_per_day):
         current_time = start_time + i * event.slot_interval
         data['rows'].append({
-            'days': [day['slots'][i] for day in data['days']],
             'time': current_time,
             'is_full_hour': current_time.hour != last_hour,
         })
         last_hour = current_time.hour
+
     data['rows'].append({
-        'days': [None for day in data['days']],
         'time': end_time,
         'is_full_hour': True,
     })
-    data['max_value'] = max_occupancy
 
     # create a color for each slot from white to dark green
-    for row in data['rows']:
-        for day in row['days']:
-            if day is not None:
-                day['color'] = f"hsl(120, 100%, {100 - 70 * day['occupancy'] / max_occupancy}%)"
+    for i in range(max_occupancy+1):
+        data['colors'].append({
+            'color': f"hsl(120, 100%, {100 - 70 * i / max_occupancy}%)",
+            'name': f'color_{i}'
+        })
     return data

+ 46 - 22
zitap/static/zitap/css/event.css

@@ -1,38 +1,62 @@
 .occupancy-grid {
-  display: grid;
+  --slot-witdh: 3.5rem;
+  --slot-gap: 1rem;
+  display: flex;
   user-select: none;
   width: fit-content;
-  margin: 10px;
+  margin: 1rem;
+  padding-left: 4rem;
+  gap: var(--slot-gap);
+  font-size: 1em;
+  flex-wrap: wrap;
+  flex-direction: row-reverse;
+  background-color: white;
 }
+.occupancy-grid .slot-column {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  height: 20rem;
+  z-index: 20;
+  background-color: white;
+}
+
 .occupancy-grid .day {
   font-weight: bold;
   align-self: center;
   justify-self: center;
+  height: 2rem;
 }
-.occupancy-grid .time {
-  position: relative;
-  width: 50px;
-}
-.occupancy-grid .time>.time-label{
-  position: absolute;
+.occupancy-grid .time-label{
   font-weight: bold;
-  transform: translate(0, -50%);
+  position: absolute;
+  transform: translate(-4rem, -50%);
+  z-index: 1;
 }
 .occupancy-grid .slot {
-  width: 70px;
   transition: background-color .2s ease;
-  display: grid;
-  justify-items: center;
-  align-items: center;
-  border-left: 1px solid #000;
-  border-right: 1px solid #000;
-  margin: 0 5px;
-}
-.occupancy-grid .slot.full-hour {
-  border-top: 1px solid #000;
-}
-.occupancy-grid .slot.last {
-  height: 0;
+  position: relative;
+  width: var(--slot-witdh);
+  flex-grow: 1;
+  border-left: 1px solid #0000007d;
+  border-right: 1px solid #0000007d;
+}
+.occupancy-grid .slot.half-hour::after {
+  content: " ";
+  border-top: 1px solid #0000002b;
+  position: absolute;
+  width: calc(var(--slot-witdh) + var(--slot-gap) + 3rem + 1px);
+  left: calc(-1 * var(--slot-gap) - 3rem - 1px);
+}
+.occupancy-grid .slot.full-hour::after {
+  content: " ";
+  border-top: 1px solid #0000007d;
+  position: absolute;
+  width: calc(var(--slot-witdh) + var(--slot-gap) + 1px);
+  left: calc(-1 * var(--slot-gap) - 1px);
+}
+.occupancy-grid .slot:last-child {
+  border-bottom: 1px solid #0000007d;
 }
 .occupancy-grid .slot:hover {
   background-color: rgb(214, 93, 93) !important;

+ 10 - 17
zitap/templates/zitap/event.html

@@ -7,12 +7,11 @@
 {% block head %}
     <link rel="stylesheet" href="{% static 'zitap/css/event.css' %}">
     <style type="text/css">
-        .occupancy-grid {
-            grid-template-columns: auto repeat({{ grid.n_days }}, 1fr);
-        }
-        .occupancy-grid .slot {
-            height: {{ grid.slot_height }}px;
-        }
+        {% for color in grid.colors %}
+            .occupancy-grid .slot.{{ color.name }} {
+                background-color: {{ color.color }};
+            }
+        {% endfor %}
     </style>
 {% endblock %}
 
@@ -20,21 +19,15 @@
 <h1>{{ event.name }}</h1>
 
 <div class="occupancy-grid">
-    <div></div>
     {% for day in grid.days %}
+    <div class="slot-column">
         <div class="day">{{ day.date|date:"M d" }}</div>
-    {% endfor %}
-    {% for row in grid.rows %}
-        <div class="time">
-            {% if row.is_full_hour %}<div class="time-label">{{ row.time|date:"H:i" }}</div>{% endif %}
+        {% for slot in day.slots %}
+        <div class="slot {{ slot.class }}{% if slot.is_full_hour %} full-hour{% elif slot.is_half_hour %} half-hour{% endif %}" id="grid_slot_{{ slot.offset }}" title="{{ slot.tooltip }}">
+            {% if slot.is_full_hour %}<div class="time-label">{{ slot.time|date:"H:i" }}</div>{% endif %}
         </div>
-        {% for day in row.days %}
-            {% if day %}
-            <div class="slot{% if row.is_full_hour %} full-hour{% endif %}" id="grid_slot_{{ day.offset }}" title="{{ day.tooltip }}" style="background-color: {{ day.color }};"></div>
-            {% else %}
-            <div class="slot full-hour last"></div>
-            {% endif %}
         {% endfor %}
+    </div>
     {% endfor %}
 </div>