Files
OTSSignsTheme/views/dashboard-icon-page.twig
Matt Batchelder e44a77b284 Restructure
2026-02-11 21:07:22 -05:00

462 lines
20 KiB
Twig
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{#
/**
* OTS Signage Theme - Icon Dashboard Override
*
* Custom stylized icon dashboard that uses card-based buttons
* matching the OTS dashboard design system.
*
* Based on Xibo CMS dashboard-icon-page.twig
*/
#}
{% extends "authed.twig" %}
{% import "inline.twig" as inline %}
{% block pageContent %}
{% include "theme-dashboard-message.twig" ignore missing %}
<div class="dashboard-page">
<div class="page-header">
<h1>{% trans "Dashboard" %}</h1>
<p class="text-muted">{% trans "Quick access to all areas of your signage network" %}</p>
</div>
{# ── Scheduling ────────────────────────────────────────────── #}
{% set scheduleCount = currentUser.featureEnabledCount(["schedule.view", "daypart.view"]) %}
{% if scheduleCount > 0 %}
<div class="icon-dash-section">
<h3 class="section-title"><i class="fa fa-calendar"></i> {% trans "Scheduling" %}</h3>
<div class="icon-dash-grid">
{% if currentUser.featureEnabled("schedule.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("schedule.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--blue">
<i class="fa fa-calendar-check-o"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Schedule" %}</span>
<span class="icon-dash-card-desc">{% trans "Manage event schedules" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.featureEnabled("daypart.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("daypart.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--indigo">
<i class="fa fa-clock-o"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Dayparting" %}</span>
<span class="icon-dash-card-desc">{% trans "Define time slots" %}</span>
</div>
</a>
{% endif %}
</div>
</div>
{% endif %}
{# ── Design ────────────────────────────────────────────────── #}
{% set countViewable = currentUser.featureEnabledCount(["campaign.view", "layout.view", "template.view", "resolution.view"]) %}
{% if countViewable > 0 %}
<div class="icon-dash-section">
<h3 class="section-title"><i class="fa fa-paint-brush"></i> {% trans "Design" %}</h3>
<div class="icon-dash-grid">
{% if currentUser.featureEnabled("campaign.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("campaign.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--green">
<i class="fa fa-bullhorn"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Campaigns" %}</span>
<span class="icon-dash-card-desc">{% trans "Organise layout playlists" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.featureEnabled("layout.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("layout.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--blue">
<i class="fa fa-columns"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Layouts" %}</span>
<span class="icon-dash-card-desc">{% trans "Design screen layouts" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.featureEnabled("template.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("template.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--purple">
<i class="fa fa-clone"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Templates" %}</span>
<span class="icon-dash-card-desc">{% trans "Reusable layout templates" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.featureEnabled("resolution.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("resolution.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--teal">
<i class="fa fa-expand"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Resolutions" %}</span>
<span class="icon-dash-card-desc">{% trans "Screen resolution presets" %}</span>
</div>
</a>
{% endif %}
</div>
</div>
{% endif %}
{# ── Library ───────────────────────────────────────────────── #}
{% set countViewable = currentUser.featureEnabledCount(["library.view", "playlist.view", "dataset.view", "menuBoard.view"]) %}
{% if countViewable > 0 %}
<div class="icon-dash-section">
<h3 class="section-title"><i class="fa fa-picture-o"></i> {% trans "Library" %}</h3>
<div class="icon-dash-grid">
{% if currentUser.featureEnabled("library.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("library.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--orange">
<i class="fa fa-image"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Library" %}</span>
<span class="icon-dash-card-desc">{% trans "Upload & manage media" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.featureEnabled("playlist.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("playlist.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--blue">
<i class="fa fa-list"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Playlists" %}</span>
<span class="icon-dash-card-desc">{% trans "Content playlists" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.featureEnabled("dataset.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("dataset.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--indigo">
<i class="fa fa-database"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "DataSets" %}</span>
<span class="icon-dash-card-desc">{% trans "Tabular data sources" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.featureEnabled("menuBoard.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("menuBoard.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--red">
<i class="fa fa-cutlery"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Menu Boards" %}</span>
<span class="icon-dash-card-desc">{% trans "Digital menu management" %}</span>
</div>
</a>
{% endif %}
</div>
</div>
{% endif %}
{# ── Displays ──────────────────────────────────────────────── #}
{% set countViewable = currentUser.featureEnabledCount(["displays.view", "displaygroup.view", "displayprofile.view"]) %}
{% if countViewable > 0 %}
<div class="icon-dash-section">
<h3 class="section-title"><i class="fa fa-desktop"></i> {% trans "Displays" %}</h3>
<div class="icon-dash-grid">
{% if currentUser.featureEnabled("displays.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("display.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--green">
<i class="fa fa-desktop"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Displays" %}</span>
<span class="icon-dash-card-desc">{% trans "Manage all screens" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.featureEnabled("displaygroup.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("displaygroup.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--blue">
<i class="fa fa-object-group"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Display Groups" %}</span>
<span class="icon-dash-card-desc">{% trans "Organise screen groups" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.featureEnabled("displayprofile.view") %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("displayprofile.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--purple">
<i class="fa fa-cog"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Display Settings" %}</span>
<span class="icon-dash-card-desc">{% trans "Player configuration profiles" %}</span>
</div>
</a>
{% endif %}
</div>
</div>
{% endif %}
{# ── Administration ────────────────────────────────────────── #}
{% set showAdmin = false %}
{% if currentUser.featureEnabled("users.view") and (currentUser.isGroupAdmin() or currentUser.isSuperAdmin()) %}
{% set showAdmin = true %}
{% endif %}
{% if currentUser.isSuperUser() %}
{% set showAdmin = true %}
{% endif %}
{% if showAdmin %}
<div class="icon-dash-section">
<h3 class="section-title"><i class="fa fa-cogs"></i> {% trans "Administration" %}</h3>
<div class="icon-dash-grid">
{% if currentUser.featureEnabled("users.view") and (currentUser.isGroupAdmin() or currentUser.isSuperAdmin()) %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("user.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--indigo">
<i class="fa fa-users"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Users" %}</span>
<span class="icon-dash-card-desc">{% trans "User accounts & permissions" %}</span>
</div>
</a>
{% endif %}
{% if currentUser.isSuperUser() %}
<a class="icon-dash-card dashboard-card" href="{{ url_for("admin.view") }}">
<div class="icon-dash-card-icon icon-dash-card-icon--orange">
<i class="fa fa-cogs"></i>
</div>
<div class="icon-dash-card-body">
<span class="icon-dash-card-title">{% trans "Settings" %}</span>
<span class="icon-dash-card-desc">{% trans "CMS system configuration" %}</span>
</div>
</a>
{% endif %}
</div>
</div>
{% endif %}
<style>
/* ===================================================================
ICON DASHBOARD Card Button Styles
Matches the OTS dashboard-card design system
=================================================================== */
/* Section spacing */
.icon-dash-section {
margin-top: 32px;
}
.icon-dash-section:first-of-type {
margin-top: 24px;
}
/* Grid layout responsive card grid */
.icon-dash-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 18px;
}
/* Individual card inherits .dashboard-card base from override.css */
.icon-dash-card {
display: flex;
flex-direction: row;
align-items: center;
gap: 18px;
padding: 22px 24px;
text-decoration: none !important;
color: var(--color-text-primary) !important;
cursor: pointer;
position: relative;
overflow: hidden;
/* Override rigid dashboard-card flex-direction:column if set */
flex-direction: row !important;
}
/* Subtle radial glow matching kpi-card--modern */
.icon-dash-card::after {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(circle at top right, rgba(59, 130, 246, 0.10), transparent 60%);
pointer-events: none;
transition: opacity 0.3s ease;
opacity: 0;
}
.icon-dash-card:hover::after {
opacity: 1;
}
/* Icon container */
.icon-dash-card-icon {
flex-shrink: 0;
width: 52px;
height: 52px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 14px;
font-size: 22px;
transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.icon-dash-card:hover .icon-dash-card-icon {
transform: scale(1.08);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
}
/* Icon colour variants */
.icon-dash-card-icon--blue {
background: linear-gradient(135deg, rgba(59, 130, 246, 0.28), rgba(59, 130, 246, 0.12));
color: #60a5fa;
}
.icon-dash-card-icon--green {
background: linear-gradient(135deg, rgba(16, 185, 129, 0.28), rgba(16, 185, 129, 0.12));
color: #34d399;
}
.icon-dash-card-icon--orange {
background: linear-gradient(135deg, rgba(245, 158, 11, 0.28), rgba(245, 158, 11, 0.12));
color: #fbbf24;
}
.icon-dash-card-icon--red {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.28), rgba(239, 68, 68, 0.12));
color: #f87171;
}
.icon-dash-card-icon--purple {
background: linear-gradient(135deg, rgba(124, 58, 237, 0.28), rgba(124, 58, 237, 0.12));
color: #a78bfa;
}
.icon-dash-card-icon--indigo {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.28), rgba(99, 102, 241, 0.12));
color: #818cf8;
}
.icon-dash-card-icon--teal {
background: linear-gradient(135deg, rgba(20, 184, 166, 0.28), rgba(20, 184, 166, 0.12));
color: #2dd4bf;
}
/* Text area */
.icon-dash-card-body {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
/* Reset inherited dashboard-card body padding */
padding: 0 !important;
background: transparent !important;
}
.icon-dash-card-title {
font-size: 15px;
font-weight: 700;
color: var(--color-text-primary);
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.icon-dash-card-desc {
font-size: 12px;
font-weight: 400;
color: var(--color-text-tertiary);
line-height: 1.4;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Hover effects matching action-card--modern */
.icon-dash-card:hover {
border-color: rgba(59, 130, 246, 0.45) !important;
transform: translateY(-3px);
box-shadow: 0 20px 40px rgba(8, 15, 30, 0.45) !important;
}
.icon-dash-card:active {
transform: translateY(0px);
box-shadow: 0 10px 20px rgba(8, 15, 30, 0.35) !important;
}
/* Section title with icon */
.icon-dash-section .section-title i {
margin-right: 8px;
opacity: 0.65;
}
/* ── Light mode overrides ─────────────────────────────────────── */
body.ots-light-mode .icon-dash-card {
background: linear-gradient(180deg, #ffffff, #f8fafc) !important;
border-color: rgba(148, 163, 184, 0.25) !important;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06) !important;
}
body.ots-light-mode .icon-dash-card:hover {
background: linear-gradient(180deg, #ffffff, #f1f5f9) !important;
border-color: rgba(59, 130, 246, 0.4) !important;
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.1) !important;
}
body.ots-light-mode .icon-dash-card-desc {
color: #64748b;
}
/* ── Responsive adjustments ───────────────────────────────────── */
@media (max-width: 768px) {
.icon-dash-grid {
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.icon-dash-card {
padding: 16px 18px;
gap: 14px;
}
.icon-dash-card-icon {
width: 44px;
height: 44px;
font-size: 18px;
border-radius: 12px;
}
.icon-dash-card-title {
font-size: 13px;
}
.icon-dash-card-desc {
display: none;
}
}
@media (max-width: 480px) {
.icon-dash-grid {
grid-template-columns: 1fr;
}
.icon-dash-card-desc {
display: block;
}
}
</style>
{% endblock %}