Enhance appointment card layout with improved styling and structure

This commit is contained in:
ricky committed 2026-08-11 14:46:50 -04:00
1 parent 7d6cddf5ca
commit fbe3eb7382
2 files changed
+54 -16

No files matched your search

@@ -4,6 +4,7 @@
<div class="appointment-card"> <div class="appointment-card">
<%# Row 1: Avatar | Title %>
<div class="appointment-header"> <div class="appointment-header">
<% if appointment.user %> <% if appointment.user %>
<%= avatar(appointment.user, size: 14, class: "appointment-avatar") %> <%= avatar(appointment.user, size: 14, class: "appointment-avatar") %>
@@ -12,13 +13,24 @@
<span class="appointment-title"> <span class="appointment-title">
<%= link_to(appointment.subject, customer_appointment_path(appointment), class: "appointment-link") %> <%= link_to(appointment.subject, customer_appointment_path(appointment), class: "appointment-link") %>
</span> </span>
</div>
<hr class="appointment-divider" />
<%# Row 2: Time | Hours %>
<div class="appointment-meta">
<span class="appointment-time">
<%= appointment.date.strftime('%I:%M %p') %>
</span>
<span class="appointment-hours"> <span class="appointment-hours">
<%= number_with_precision(appointment.estimated_hours.to_f, precision: 1) %>h <%= number_with_precision(appointment.estimated_hours.to_f, precision: 1) %>h
</span> </span>
</div> </div>
<%# Row 3: Details %>
<% if appointment.customer %> <% if appointment.customer %>
<hr class="appointment-divider" />
<div class="appointment-detail"> <div class="appointment-detail">
<%= appointment.customer.name %> <%= appointment.customer.name %>
<% if appointment.vehicle %> <% if appointment.vehicle %>
+42 -16
View File
@@ -48,7 +48,7 @@ table.cal td {
border-radius: 1px; border-radius: 1px;
} }
/* Card Content Area */ /* Card Content Area (Flex Column Layout) */
.appointment-card { .appointment-card {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -57,9 +57,10 @@ table.cal td {
overflow: hidden; overflow: hidden;
} }
/* Row 1: Header (Avatar + Title) */
.appointment-header { .appointment-header {
display: flex; display: flex;
align-items: flex-start; align-items: center;
gap: 4px; gap: 4px;
font-weight: bold; font-weight: bold;
min-width: 0; min-width: 0;
@@ -67,8 +68,8 @@ table.cal td {
.appointment-avatar { .appointment-avatar {
flex-shrink: 0; flex-shrink: 0;
width: 25px; width: 20px;
height: 25px; height: 20px;
border-radius: 3px; border-radius: 3px;
object-fit: cover; object-fit: cover;
} }
@@ -80,7 +81,7 @@ table.cal td {
overflow-wrap: anywhere; overflow-wrap: anywhere;
word-break: break-word; word-break: break-word;
min-width: 0; min-width: 0;
vertical-align: top; vertical-align: middle;
} }
.appointment-link { .appointment-link {
@@ -88,22 +89,36 @@ table.cal td {
text-decoration: none; text-decoration: none;
} }
.appointment-hours { /* Row 2: Meta Bar (Time + Hours) */
flex-shrink: 0; .appointment-meta {
color: #444; display: flex;
font-size: 0.85em; justify-content: space-between;
align-items: center;
font-weight: bold; font-weight: bold;
margin-left: auto; font-size: 0.85em;
color: #444;
} }
/* Multi-line wrapping for details */ .appointment-time,
.appointment-hours {
flex-shrink: 0;
}
/* Horizontal Dividers */
.appointment-card .appointment-divider {
border: 0;
border-top: 1px solid #c5d8f3;
margin: 3px 0;
width: 100%;
}
/* Row 3: Multi-line wrapping for details */
.appointment-detail { .appointment-detail {
color: #555; color: #555;
font-size: 0.9em; font-size: 0.85em;
white-space: normal; white-space: normal;
overflow-wrap: anywhere; overflow-wrap: anywhere;
word-break: break-word; word-break: break-word;
margin-top: 2px;
min-width: 0; min-width: 0;
} }
@@ -112,7 +127,7 @@ table.cal td {
z-index: 1000 !important; z-index: 1000 !important;
} }
/* Redmine Tooltip Popover (Hidden by Default & on Hover) */ /* Redmine Tooltip Popover */
.appointment-block .tip, .appointment-block .tip,
.appointment-block:hover .tip { .appointment-block:hover .tip {
display: none !important; display: none !important;
@@ -246,11 +261,12 @@ h2 .appointment-title {
vertical-align: middle; vertical-align: middle;
} }
/* Calendar Card Status Colors & Indicator Bars */ /* Calendar Card Status Colors, Borders, and Divider Lines */
/* Scheduled - Blue */ /* Scheduled - Blue */
.appointment-block.scheduled .appointment-bar { background-color: #1f77d0; } .appointment-block.scheduled .appointment-bar { background-color: #1f77d0; }
.appointment-block.scheduled { background: #edf4ff; border-color: #c5d8f3; } .appointment-block.scheduled { background: #edf4ff; border-color: #c5d8f3; }
.appointment-block.scheduled .appointment-divider { border-top-color: #c5d8f3; }
/* CheckedIn - Purple */ /* CheckedIn - Purple */
.appointment-block.checked-in .appointment-bar, .appointment-block.checked-in .appointment-bar,
@@ -259,6 +275,9 @@ h2 .appointment-title {
.appointment-block.checked-in, .appointment-block.checked-in,
.appointment-block.checkedin, .appointment-block.checkedin,
.appointment-block.checked_in { background: #f6f0fa; border-color: #e2d0fb; } .appointment-block.checked_in { background: #f6f0fa; border-color: #e2d0fb; }
.appointment-block.checked-in .appointment-divider,
.appointment-block.checkedin .appointment-divider,
.appointment-block.checked_in .appointment-divider { border-top-color: #e2d0fb; }
/* InProgress - Orange */ /* InProgress - Orange */
.appointment-block.in-progress .appointment-bar, .appointment-block.in-progress .appointment-bar,
@@ -267,20 +286,27 @@ h2 .appointment-title {
.appointment-block.in-progress, .appointment-block.in-progress,
.appointment-block.inprogress, .appointment-block.inprogress,
.appointment-block.in_progress { background: #fff4df; border-color: #fce2b6; } .appointment-block.in_progress { background: #fff4df; border-color: #fce2b6; }
.appointment-block.in-progress .appointment-divider,
.appointment-block.inprogress .appointment-divider,
.appointment-block.in_progress .appointment-divider { border-top-color: #fce2b6; }
/* Ready - Teal */ /* Ready - Teal */
.appointment-block.ready .appointment-bar { background-color: #16a085; } .appointment-block.ready .appointment-bar { background-color: #16a085; }
.appointment-block.ready { background: #e8f8f5; border-color: #a3e4d7; } .appointment-block.ready { background: #e8f8f5; border-color: #a3e4d7; }
.appointment-block.ready .appointment-divider { border-top-color: #a3e4d7; }
/* Completed - Green */ /* Completed - Green */
.appointment-block.completed .appointment-bar { background-color: #2d8a34; } .appointment-block.completed .appointment-bar { background-color: #2d8a34; }
.appointment-block.completed { background: #edf9ee; border-color: #c7eecb; } .appointment-block.completed { background: #edf9ee; border-color: #c7eecb; }
.appointment-block.completed .appointment-divider { border-top-color: #c7eecb; }
/* Cancelled - Red & Strikethrough Subject */ /* Cancelled - Red & Strikethrough Subject */
.appointment-block.cancelled .appointment-bar, .appointment-block.cancelled .appointment-bar,
.appointment-block.canceled .appointment-bar { background-color: #d9534f; } .appointment-block.canceled .appointment-bar { background-color: #d9534f; }
.appointment-block.cancelled, .appointment-block.cancelled,
.appointment-block.canceled { background: #fdf2f2; border-color: #f8c8c8; } .appointment-block.canceled { background: #fdf2f2; border-color: #f8c8c8; }
.appointment-block.cancelled .appointment-divider,
.appointment-block.canceled .appointment-divider { border-top-color: #f8c8c8; }
.appointment-block.cancelled .appointment-title, .appointment-block.cancelled .appointment-title,
.appointment-block.cancelled .appointment-link, .appointment-block.cancelled .appointment-link,
@@ -341,7 +367,7 @@ table.appointments td.status {
transform: translateY(-1px); transform: translateY(-1px);
} }
/* Status Colors (Supports hyphen, underscore, and concatenated naming) */ /* Status Badges Colors */
/* Scheduled - Blue */ /* Scheduled - Blue */
.status-scheduled { .status-scheduled {