ui: added subtle tint for alternating rows on tables
This commit is contained in:
@@ -839,13 +839,14 @@ export default function CustomerList() {
|
|||||||
const isLast = index === pagedCustomers.length - 1;
|
const isLast = index === pagedCustomers.length - 1;
|
||||||
const gradient = rowGradient(c, direction);
|
const gradient = rowGradient(c, direction);
|
||||||
const rowBg = hoveredRow === c.id ? "var(--bg-card-hover)" : undefined;
|
const rowBg = hoveredRow === c.id ? "var(--bg-card-hover)" : undefined;
|
||||||
|
const zebraBase = index % 2 === 1 ? "var(--bg-row-alt)" : "transparent";
|
||||||
const rowStyle = {
|
const rowStyle = {
|
||||||
borderBottom: (!isLast && !(notesMode === "expanded" && hasStatus))
|
borderBottom: (!isLast && !(notesMode === "expanded" && hasStatus))
|
||||||
? "1px solid var(--border-secondary)"
|
? "1px solid var(--border-secondary)"
|
||||||
: "none",
|
: "none",
|
||||||
background: rowBg
|
background: rowBg
|
||||||
? rowBg
|
? rowBg
|
||||||
: gradient || "transparent",
|
: gradient || zebraBase,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mainRow = (
|
const mainRow = (
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ export default function OrderList() {
|
|||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
style={{
|
style={{
|
||||||
borderBottom: index < orders.length - 1 ? "1px solid var(--border-secondary)" : "none",
|
borderBottom: index < orders.length - 1 ? "1px solid var(--border-secondary)" : "none",
|
||||||
backgroundColor: hoveredRow === o.id ? "var(--bg-card-hover)" : "transparent",
|
backgroundColor: hoveredRow === o.id ? "var(--bg-card-hover)" : index % 2 === 1 ? "var(--bg-row-alt)" : "transparent",
|
||||||
}}
|
}}
|
||||||
onMouseEnter={() => setHoveredRow(o.id)}
|
onMouseEnter={() => setHoveredRow(o.id)}
|
||||||
onMouseLeave={() => setHoveredRow(null)}
|
onMouseLeave={() => setHoveredRow(null)}
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ export default function ProductList() {
|
|||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
style={{
|
style={{
|
||||||
borderBottom: index < filtered.length - 1 ? "1px solid var(--border-primary)" : "none",
|
borderBottom: index < filtered.length - 1 ? "1px solid var(--border-primary)" : "none",
|
||||||
backgroundColor: hoveredRow === p.id ? "var(--bg-card-hover)" : "transparent",
|
backgroundColor: hoveredRow === p.id ? "var(--bg-card-hover)" : index % 2 === 1 ? "var(--bg-row-alt)" : "transparent",
|
||||||
}}
|
}}
|
||||||
onMouseEnter={() => setHoveredRow(p.id)}
|
onMouseEnter={() => setHoveredRow(p.id)}
|
||||||
onMouseLeave={() => setHoveredRow(null)}
|
onMouseLeave={() => setHoveredRow(null)}
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ export default function AllQuotationsList() {
|
|||||||
// Grid columns: thumbnail | number | customer | title | date | status | total
|
// Grid columns: thumbnail | number | customer | title | date | status | total
|
||||||
const GRID = "90px 120px 180px minmax(0,1fr) 110px 120px 130px";
|
const GRID = "90px 120px 180px minmax(0,1fr) 110px 120px 130px";
|
||||||
|
|
||||||
function renderRow(q) {
|
function renderRow(q, index = 0) {
|
||||||
const isDeleting = deleting === q.id;
|
const isDeleting = deleting === q.id;
|
||||||
const displayDate = q.is_legacy ? (q.legacy_date || q.created_at?.slice(0, 10) || "—") : (q.created_at?.slice(0, 10) || "—");
|
const displayDate = q.is_legacy ? (q.legacy_date || q.created_at?.slice(0, 10) || "—") : (q.created_at?.slice(0, 10) || "—");
|
||||||
|
|
||||||
@@ -251,12 +251,12 @@ export default function AllQuotationsList() {
|
|||||||
borderBottom: "1px solid var(--border-secondary)",
|
borderBottom: "1px solid var(--border-secondary)",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
minHeight: 110,
|
minHeight: 110,
|
||||||
backgroundColor: "var(--bg-card)",
|
backgroundColor: index % 2 === 1 ? "color-mix(in srgb, var(--bg-card) 97%, white)" : "var(--bg-card)",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
}}
|
}}
|
||||||
onClick={() => navigate(`/crm/customers/${q.customer_id}?tab=Quotations`)}
|
onClick={() => navigate(`/crm/customers/${q.customer_id}?tab=Quotations`)}
|
||||||
onMouseEnter={e => e.currentTarget.style.backgroundColor = "var(--bg-card-hover)"}
|
onMouseEnter={e => e.currentTarget.style.backgroundColor = "var(--bg-card-hover)"}
|
||||||
onMouseLeave={e => e.currentTarget.style.backgroundColor = "var(--bg-card)"}
|
onMouseLeave={e => e.currentTarget.style.backgroundColor = index % 2 === 1 ? "color-mix(in srgb, var(--bg-card) 97%, white)" : "var(--bg-card)"}
|
||||||
>
|
>
|
||||||
{/* Thumbnail — stops row click */}
|
{/* Thumbnail — stops row click */}
|
||||||
<div onClick={e => e.stopPropagation()}>
|
<div onClick={e => e.stopPropagation()}>
|
||||||
@@ -406,7 +406,7 @@ export default function AllQuotationsList() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{quotations.map(q => renderRow(q))}
|
{quotations.map((q, i) => renderRow(q, i))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ export default function QuotationList({ customerId, onSend }) {
|
|||||||
// Delete button is a hover-only overlay — no dedicated column needed
|
// Delete button is a hover-only overlay — no dedicated column needed
|
||||||
const GRID = "90px 120px minmax(0,1fr) 130px 130px 130px 90px";
|
const GRID = "90px 120px minmax(0,1fr) 130px 130px 130px 90px";
|
||||||
|
|
||||||
function renderRow(q, isLegacy = false) {
|
function renderRow(q, isLegacy = false, index = 0) {
|
||||||
const hasPdf = isLegacy ? !!q.legacy_pdf_path : !!q.nextcloud_pdf_url;
|
const hasPdf = isLegacy ? !!q.legacy_pdf_path : !!q.nextcloud_pdf_url;
|
||||||
const displayDate = isLegacy ? (q.legacy_date || fmtDate(q.created_at)) : fmtDate(q.created_at);
|
const displayDate = isLegacy ? (q.legacy_date || fmtDate(q.created_at)) : fmtDate(q.created_at);
|
||||||
const isDeleting = deleting === q.id;
|
const isDeleting = deleting === q.id;
|
||||||
@@ -444,10 +444,10 @@ export default function QuotationList({ customerId, onSend }) {
|
|||||||
borderBottom: "1px solid var(--border-secondary)",
|
borderBottom: "1px solid var(--border-secondary)",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
minHeight: 110,
|
minHeight: 110,
|
||||||
backgroundColor: "var(--bg-card)",
|
backgroundColor: index % 2 === 1 ? "color-mix(in srgb, var(--bg-card) 97%, white)" : "var(--bg-card)",
|
||||||
}}
|
}}
|
||||||
onMouseEnter={e => e.currentTarget.style.backgroundColor = "var(--bg-card-hover)"}
|
onMouseEnter={e => e.currentTarget.style.backgroundColor = "var(--bg-card-hover)"}
|
||||||
onMouseLeave={e => e.currentTarget.style.backgroundColor = "var(--bg-card)"}
|
onMouseLeave={e => e.currentTarget.style.backgroundColor = index % 2 === 1 ? "color-mix(in srgb, var(--bg-card) 97%, white)" : "var(--bg-card)"}
|
||||||
>
|
>
|
||||||
{/* Thumbnail */}
|
{/* Thumbnail */}
|
||||||
<div>
|
<div>
|
||||||
@@ -659,7 +659,7 @@ export default function QuotationList({ customerId, onSend }) {
|
|||||||
{!loading && regular.length > 0 && (
|
{!loading && regular.length > 0 && (
|
||||||
<div style={{ borderRadius: 8, border: "1px solid var(--border-primary)", overflow: "hidden", marginBottom: legacy.length > 0 ? 24 : 0 }}>
|
<div style={{ borderRadius: 8, border: "1px solid var(--border-primary)", overflow: "hidden", marginBottom: legacy.length > 0 ? 24 : 0 }}>
|
||||||
<TableHeader />
|
<TableHeader />
|
||||||
{regular.map(q => renderRow(q, false))}
|
{regular.map((q, i) => renderRow(q, false, i))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -681,7 +681,7 @@ export default function QuotationList({ customerId, onSend }) {
|
|||||||
</div>
|
</div>
|
||||||
<div style={{ borderRadius: 8, border: "1px solid var(--border-primary)", overflow: "hidden" }}>
|
<div style={{ borderRadius: 8, border: "1px solid var(--border-primary)", overflow: "hidden" }}>
|
||||||
<TableHeader />
|
<TableHeader />
|
||||||
{legacy.map(q => renderRow(q, true))}
|
{legacy.map((q, i) => renderRow(q, true, i))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -465,14 +465,14 @@ export default function DeviceList() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{pagedDevices.map((device) => (
|
{pagedDevices.map((device, index) => (
|
||||||
<tr
|
<tr
|
||||||
key={device.id}
|
key={device.id}
|
||||||
onClick={() => navigate(`/devices/${device.id}`)}
|
onClick={() => navigate(`/devices/${device.id}`)}
|
||||||
className="cursor-pointer transition-colors"
|
className="cursor-pointer transition-colors"
|
||||||
style={{ borderBottom: "1px solid var(--border-secondary)" }}
|
style={{ borderBottom: "1px solid var(--border-secondary)", backgroundColor: index % 2 === 1 ? "var(--bg-row-alt)" : "transparent" }}
|
||||||
onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = "var(--bg-card-hover)")}
|
onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = "var(--bg-card-hover)")}
|
||||||
onMouseLeave={(e) => (e.currentTarget.style.backgroundColor = "transparent")}
|
onMouseLeave={(e) => (e.currentTarget.style.backgroundColor = index % 2 === 1 ? "var(--bg-row-alt)" : "transparent")}
|
||||||
>
|
>
|
||||||
{activeColumns.map((col) => (
|
{activeColumns.map((col) => (
|
||||||
<td
|
<td
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ export default function NoteList() {
|
|||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
style={{
|
style={{
|
||||||
borderBottom: index < items.length - 1 ? "1px solid var(--border-primary)" : "none",
|
borderBottom: index < items.length - 1 ? "1px solid var(--border-primary)" : "none",
|
||||||
backgroundColor: hoveredRow === note.id ? "var(--bg-card-hover)" : "transparent",
|
backgroundColor: hoveredRow === note.id ? "var(--bg-card-hover)" : index % 2 === 1 ? "var(--bg-row-alt)" : "transparent",
|
||||||
opacity: note.status === "completed" ? 0.6 : 1,
|
opacity: note.status === "completed" ? 0.6 : 1,
|
||||||
}}
|
}}
|
||||||
onMouseEnter={() => setHoveredRow(note.id)}
|
onMouseEnter={() => setHoveredRow(note.id)}
|
||||||
@@ -282,7 +282,7 @@ export default function NoteList() {
|
|||||||
key={msg.id}
|
key={msg.id}
|
||||||
style={{
|
style={{
|
||||||
borderBottom: index < filtered.length - 1 ? "1px solid var(--border-primary)" : "none",
|
borderBottom: index < filtered.length - 1 ? "1px solid var(--border-primary)" : "none",
|
||||||
backgroundColor: hoveredRow === msg.id ? "var(--bg-card-hover)" : "transparent",
|
backgroundColor: hoveredRow === msg.id ? "var(--bg-card-hover)" : index % 2 === 1 ? "var(--bg-row-alt)" : "transparent",
|
||||||
opacity: msg.acknowledged ? 0.6 : 1,
|
opacity: msg.acknowledged ? 0.6 : 1,
|
||||||
}}
|
}}
|
||||||
onMouseEnter={() => setHoveredRow(msg.id)}
|
onMouseEnter={() => setHoveredRow(msg.id)}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
--bg-input: #111827;
|
--bg-input: #111827;
|
||||||
--bg-sidebar: #111827;
|
--bg-sidebar: #111827;
|
||||||
--bg-header: #1f2937;
|
--bg-header: #1f2937;
|
||||||
|
--bg-row-alt: rgba(255, 255, 255, 0.03);
|
||||||
|
|
||||||
--border-primary: #374151;
|
--border-primary: #374151;
|
||||||
--border-secondary: #2d3748;
|
--border-secondary: #2d3748;
|
||||||
|
|||||||
@@ -1300,14 +1300,14 @@ export default function MelodyList() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{pagedRows.map((row) => (
|
{pagedRows.map((row, index) => (
|
||||||
<tr
|
<tr
|
||||||
key={row.id}
|
key={row.id}
|
||||||
onClick={() => navigate(`/melodies/${row.id}`)}
|
onClick={() => navigate(`/melodies/${row.id}`)}
|
||||||
className="cursor-pointer transition-colors"
|
className="cursor-pointer transition-colors"
|
||||||
style={{ borderBottom: "1px solid var(--border-secondary)" }}
|
style={{ borderBottom: "1px solid var(--border-secondary)", backgroundColor: index % 2 === 1 ? "var(--bg-row-alt)" : "transparent" }}
|
||||||
onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = "var(--bg-card-hover)")}
|
onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = "var(--bg-card-hover)")}
|
||||||
onMouseLeave={(e) => (e.currentTarget.style.backgroundColor = "transparent")}
|
onMouseLeave={(e) => (e.currentTarget.style.backgroundColor = index % 2 === 1 ? "var(--bg-row-alt)" : "transparent")}
|
||||||
>
|
>
|
||||||
{activeColumns.map((col) => (
|
{activeColumns.map((col) => (
|
||||||
<td
|
<td
|
||||||
|
|||||||
@@ -465,14 +465,14 @@ export default function ArchetypeList() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{archetypes.map((m) => {
|
{archetypes.map((m, index) => {
|
||||||
const assignedCount = getVerifiedAssignedCount(m);
|
const assignedCount = getVerifiedAssignedCount(m);
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
key={m.id}
|
key={m.id}
|
||||||
onClick={() => navigate(`/melodies/archetypes/${m.id}`)}
|
onClick={() => navigate(`/melodies/archetypes/${m.id}`)}
|
||||||
className="border-b cursor-pointer transition-colors hover:bg-[var(--bg-card-hover)]"
|
className="border-b cursor-pointer transition-colors hover:bg-[var(--bg-card-hover)]"
|
||||||
style={{ borderColor: "var(--border-primary)" }}
|
style={{ borderColor: "var(--border-primary)", backgroundColor: index % 2 === 1 ? "var(--bg-row-alt)" : "transparent" }}
|
||||||
>
|
>
|
||||||
<td className="px-4 py-3 font-medium" style={{ color: "var(--text-heading)" }}>
|
<td className="px-4 py-3 font-medium" style={{ color: "var(--text-heading)" }}>
|
||||||
{m.name}
|
{m.name}
|
||||||
|
|||||||
@@ -141,14 +141,14 @@ export default function StaffList() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{staff.map((member) => (
|
{staff.map((member, index) => (
|
||||||
<tr
|
<tr
|
||||||
key={member.id}
|
key={member.id}
|
||||||
onClick={() => navigate(`/settings/staff/${member.id}`)}
|
onClick={() => navigate(`/settings/staff/${member.id}`)}
|
||||||
className="cursor-pointer transition-colors"
|
className="cursor-pointer transition-colors"
|
||||||
style={{ borderBottom: "1px solid var(--border-secondary)" }}
|
style={{ borderBottom: "1px solid var(--border-secondary)", backgroundColor: index % 2 === 1 ? "var(--bg-row-alt)" : "transparent" }}
|
||||||
onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = "var(--bg-card-hover)")}
|
onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = "var(--bg-card-hover)")}
|
||||||
onMouseLeave={(e) => (e.currentTarget.style.backgroundColor = "transparent")}
|
onMouseLeave={(e) => (e.currentTarget.style.backgroundColor = index % 2 === 1 ? "var(--bg-row-alt)" : "transparent")}
|
||||||
>
|
>
|
||||||
<td className="px-4 py-3">
|
<td className="px-4 py-3">
|
||||||
<span className="font-medium" style={{ color: "var(--text-heading)" }}>{member.name}</span>
|
<span className="font-medium" style={{ color: "var(--text-heading)" }}>{member.name}</span>
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ export default function UserList() {
|
|||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
style={{
|
style={{
|
||||||
borderBottom: index < users.length - 1 ? "1px solid var(--border-primary)" : "none",
|
borderBottom: index < users.length - 1 ? "1px solid var(--border-primary)" : "none",
|
||||||
backgroundColor: hoveredRow === user.id ? "var(--bg-card-hover)" : "transparent",
|
backgroundColor: hoveredRow === user.id ? "var(--bg-card-hover)" : index % 2 === 1 ? "var(--bg-row-alt)" : "transparent",
|
||||||
}}
|
}}
|
||||||
onMouseEnter={() => setHoveredRow(user.id)}
|
onMouseEnter={() => setHoveredRow(user.id)}
|
||||||
onMouseLeave={() => setHoveredRow(null)}
|
onMouseLeave={() => setHoveredRow(null)}
|
||||||
|
|||||||
Reference in New Issue
Block a user