<div id="mediq-dashboard" dir="rtl">
<style>
/* ============================================================
MEDIQ DASHBOARD - PROTOTYPE
============================================================ */
#mediq-dashboard,
#mediq-dashboard * {
box-sizing: border-box;
}
#mediq-dashboard {
--navy: #082f4f;
--navy-2: #123f60;
--text: #173b59;
--muted: #71899d;
--primary: #0bb9b1;
--primary-dark: #079f99;
--bg: #f4f9fb;
--border: #dbe9ef;
--white: #ffffff;
position: fixed;
inset: 0;
width: 100vw;
height: 100vh;
z-index: 9999;
overflow: hidden;
background:
radial-gradient(
circle at 15% 5%,
rgba(11,185,177,.08),
transparent 27%
),
#f4f9fb;
font-family: Tahoma, Arial, sans-serif;
color: var(--text);
direction: rtl;
}
/* ============================================================
HIDE CONFLUENCE
============================================================ */
#footer,
footer,
.aui-footer,
#header,
#main-header,
.breadcrumbs,
#breadcrumbs,
.page-metadata,
#likes-and-labels-container {
display: none !important;
}
html,
body,
#page,
#full-height-container,
#main,
#content,
#main-content,
.aui-page-panel,
.aui-page-panel-inner,
.aui-page-panel-content,
.content-body {
margin: 0 !important;
padding: 0 !important;
width: 100% !important;
height: 100% !important;
max-width: none !important;
}
html,
body {
overflow: hidden !important;
}
/* ============================================================
APP
============================================================ */
.mq-app {
width: 100%;
height: 100%;
display: grid;
grid-template-columns:
minmax(0, 1fr)
260px;
direction: ltr;
}
/* ============================================================
SIDEBAR
============================================================ */
.mq-sidebar {
grid-column: 2;
height: 100vh;
padding: 25px 17px;
background:
linear-gradient(
180deg,
#073252,
#092944
);
color: #fff;
direction: rtl;
display: flex;
flex-direction: column;
box-shadow:
-10px 0 40px
rgba(8,43,75,.08);
}
/* LOGO */
.mq-logo {
padding: 7px 9px 25px;
border-bottom:
1px solid
rgba(255,255,255,.10);
text-align: center;
}
.mq-logo img {
width: 170px;
max-width: 90%;
filter:
drop-shadow(
0 4px 10px
rgba(0,0,0,.10)
);
}
/* USER */
.mq-user {
margin-top: 20px;
padding: 15px;
border-radius: 14px;
background:
rgba(255,255,255,.07);
border:
1px solid
rgba(255,255,255,.08);
}
.mq-user-name {
font-size: 13px;
font-weight: 800;
}
.mq-user-role {
margin-top: 6px;
color:
rgba(255,255,255,.65);
font-size: 11px;
}
/* NAV */
.mq-nav {
margin-top: 23px;
display: flex;
flex-direction: column;
gap: 7px;
}
.mq-nav-item {
min-height: 45px;
padding: 0 13px;
border-radius: 11px;
display: flex;
align-items: center;
gap: 11px;
color:
rgba(255,255,255,.73);
font-size: 12px;
font-weight: 700;
cursor: pointer;
transition: .15s;
}
.mq-nav-item:hover {
background:
rgba(255,255,255,.08);
color: #fff;
}
.mq-nav-item.active {
background:
linear-gradient(
90deg,
#0bb9b1,
#09a7a2
);
color: #fff;
box-shadow:
0 9px 20px
rgba(11,185,177,.20);
}
.mq-nav-icon {
width: 21px;
height: 21px;
display: flex;
align-items: center;
justify-content: center;
}
.mq-nav-icon svg {
width: 20px;
height: 20px;
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
}
/* LOGOUT */
.mq-sidebar-bottom {
margin-top: auto;
}
.mq-logout {
min-height: 43px;
padding: 0 13px;
border-radius: 10px;
display: flex;
align-items: center;
gap: 10px;
color:
rgba(255,255,255,.72);
font-size: 12px;
cursor: pointer;
}
.mq-logout:hover {
background:
rgba(255,255,255,.07);
color: #fff;
}
/* ============================================================
MAIN
============================================================ */
.mq-main {
grid-column: 1;
height: 100vh;
overflow-y: auto;
direction: rtl;
padding:
0
clamp(25px,4vw,55px)
45px;
}
/* ============================================================
HEADER
============================================================ */
.mq-header {
min-height: 90px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
border-bottom:
1px solid
var(--border);
}
.mq-page-title {
color: var(--navy);
font-size: 21px;
font-weight: 900;
}
.mq-page-subtitle {
margin-top: 7px;
color: var(--muted);
font-size: 11px;
font-weight: 600;
}
/* HEADER LEFT */
.mq-header-actions {
display: flex;
align-items: center;
gap: 10px;
}
.mq-hospital {
padding:
10px
14px;
border:
1px solid
var(--border);
border-radius: 11px;
background: #fff;
color: var(--text);
font-size: 11px;
font-weight: 700;
}
/* ============================================================
WELCOME
============================================================ */
.mq-welcome-panel {
margin-top: 25px;
padding:
22px
25px;
border-radius: 17px;
background:
linear-gradient(
100deg,
#073553,
#09666d
);
color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
overflow: hidden;
position: relative;
}
.mq-welcome-panel::after {
content: "";
position: absolute;
width: 230px;
height: 230px;
left: -60px;
top: -120px;
border-radius: 50%;
background:
rgba(25,220,205,.15);
}
.mq-welcome-title {
position: relative;
z-index: 2;
font-size: 17px;
font-weight: 900;
}
.mq-welcome-text {
position: relative;
z-index: 2;
margin-top: 7px;
color:
rgba(255,255,255,.72);
font-size: 11px;
}
/* ============================================================
STATS
============================================================ */
.mq-stats {
margin-top: 20px;
display: grid;
grid-template-columns:
repeat(4,1fr);
gap: 13px;
}
.mq-stat {
padding: 17px;
border:
1px solid
var(--border);
border-radius: 15px;
background: #fff;
box-shadow:
0 8px 25px
rgba(27,73,99,.035);
}
.mq-stat-label {
color: var(--muted);
font-size: 11px;
font-weight: 700;
}
.mq-stat-value {
margin-top: 8px;
color: var(--navy);
font-size: 23px;
font-weight: 900;
}
.mq-stat-note {
margin-top: 5px;
color: #91a4b3;
font-size: 9px;
}
/* ============================================================
SECTION
============================================================ */
.mq-section {
margin-top: 30px;
}
.mq-section-head {
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: space-between;
}
.mq-section-title {
color: var(--navy);
font-size: 15px;
font-weight: 900;
}
.mq-section-description {
margin-top: 5px;
color: var(--muted);
font-size: 10px;
}
/* ============================================================
MODULE GRID
============================================================ */
.mq-modules {
display: grid;
grid-template-columns:
repeat(3,minmax(0,1fr));
gap: 16px;
}
/* ============================================================
MODULE CARD
============================================================ */
.mq-module {
min-height: 245px;
padding: 20px;
border:
1px solid
var(--border);
border-radius: 18px;
background:
rgba(255,255,255,.93);
box-shadow:
0 12px 35px
rgba(23,72,99,.045);
transition:
transform .18s ease,
box-shadow .18s ease,
border-color .18s ease;
}
.mq-module:hover {
transform:
translateY(-3px);
border-color:
rgba(11,185,177,.40);
box-shadow:
0 17px 40px
rgba(23,72,99,.08);
}
/* MODULE HEADER */
.mq-module-header {
display: flex;
align-items: center;
gap: 12px;
padding-bottom: 15px;
border-bottom:
1px solid
#edf3f6;
}
.mq-module-icon {
flex: 0 0 auto;
width: 44px;
height: 44px;
border-radius: 13px;
display: flex;
align-items: center;
justify-content: center;
background:
#e4faf8;
color:
var(--primary-dark);
}
.mq-module-icon svg {
width: 23px;
height: 23px;
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
}
.mq-module-title {
color: var(--navy);
font-size: 14px;
font-weight: 900;
}
.mq-module-subtitle {
margin-top: 4px;
color: var(--muted);
font-size: 9px;
}
/* ============================================================
MODULE ACTIONS
============================================================ */
.mq-actions {
margin-top: 14px;
display: flex;
flex-direction: column;
gap: 4px;
}
.mq-action {
min-height: 35px;
padding:
0
10px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: space-between;
color: #49677e;
font-size: 10px;
font-weight: 700;
cursor: pointer;
transition: .15s;
}
.mq-action:hover {
color:
var(--primary-dark);
background:
#effaf9;
}
.mq-action-arrow {
color: #9ab0bf;
font-size: 15px;
}
/* ============================================================
EMPTY
============================================================ */
.mq-empty {
padding: 40px;
border:
1px dashed
#cbdde6;
border-radius: 15px;
background:
rgba(255,255,255,.60);
text-align: center;
color: var(--muted);
font-size: 12px;
}
/* ============================================================
RESPONSIVE
============================================================ */
@media(max-width:1200px) {
.mq-modules {
grid-template-columns:
repeat(2,1fr);
}
.mq-stats {
grid-template-columns:
repeat(2,1fr);
}
}
</style>
<div class="mq-app">
<!-- =====================================================
MAIN
===================================================== -->
<main class="mq-main">
<header class="mq-header">
<div>
<div class="mq-page-title">
داشبورد مدیکیو
</div>
<div class="mq-page-subtitle">
سامانه جامع مدیریت تجهیزات پزشکی
</div>
</div>
<div class="mq-header-actions">
<div class="mq-hospital">
بیمارستان / مرکز درمانی
</div>
</div>
</header>
<!-- =================================================
WELCOME
================================================= -->
<section class="mq-welcome-panel">
<div>
<div class="mq-welcome-title">
خوش آمدید، <span id="mqWelcomeName">کاربر مدیکیو</span>
</div>
<div class="mq-welcome-text">
ماژولها و امکانات این صفحه بر اساس سطح دسترسی شما نمایش داده میشوند.
</div>
</div>
</section>
<!-- =================================================
STATS
================================================= -->
<section
id="mqStats"
class="mq-stats"
>
<div class="mq-stat">
<div class="mq-stat-label">
کل تجهیزات
</div>
<div class="mq-stat-value">
۱,۲۴۸
</div>
<div class="mq-stat-note">
تجهیزات ثبتشده
</div>
</div>
<div class="mq-stat">
<div class="mq-stat-label">
تجهیزات فعال
</div>
<div class="mq-stat-value">
۱,۱۰۲
</div>
<div class="mq-stat-note">
در حال بهرهبرداری
</div>
</div>
<div class="mq-stat">
<div class="mq-stat-label">
تعمیرات باز
</div>
<div class="mq-stat-value">
۲۳
</div>
<div class="mq-stat-note">
نیازمند پیگیری
</div>
</div>
<div class="mq-stat">
<div class="mq-stat-label">
PM نزدیک
</div>
<div class="mq-stat-value">
۳۷
</div>
<div class="mq-stat-note">
در ۳۰ روز آینده
</div>
</div>
</section>
<!-- =================================================
MODULES
================================================= -->
<section class="mq-section">
<div class="mq-section-head">
<div>
<div class="mq-section-title">
خدمات و ماژولهای من
</div>
<div class="mq-section-description">
فقط بخشهایی که مجوز استفاده از آنها را دارید نمایش داده میشوند.
</div>
</div>
</div>
<div
id="mqModules"
class="mq-modules"
></div>
</section>
</main>
<!-- =====================================================
SIDEBAR
===================================================== -->
<aside class="mq-sidebar">
<div class="mq-logo">
<img
src="/download/attachments/174855060/MediQ%20Heart%20Medical%20Logo.png"
alt="MediQ"
>
</div>
<div class="mq-user">
<div
id="mqUserName"
class="mq-user-name"
>
کاربر مدیکیو
</div>
<div
id="mqUserRole"
class="mq-user-role"
>
کارشناس تجهیزات پزشکی
</div>
</div>
<nav class="mq-nav">
<div class="mq-nav-item active">
<span class="mq-nav-icon">
<svg viewBox="0 0 24 24">
<path d="M3 12l9-8 9 8"></path>
<path d="M5 10v10h14V10"></path>
</svg>
</span>
داشبورد
</div>
<div
class="mq-nav-item"
data-permission="ASSET_VIEW"
>
<span class="mq-nav-icon">
<svg viewBox="0 0 24 24">
<path d="M12 3l7 4-7 4-7-4 7-4z"></path>
<path d="M5 7v9l7 4 7-4V7"></path>
</svg>
</span>
تجهیزات پزشکی
</div>
<div
class="mq-nav-item"
data-permission="MAINTENANCE_VIEW"
>
<span class="mq-nav-icon">
<svg viewBox="0 0 24 24">
<circle cx="12" cy="12" r="3"></circle>
<path d="M12 2v3"></path>
<path d="M12 19v3"></path>
<path d="M2 12h3"></path>
<path d="M19 12h3"></path>
</svg>
</span>
نگهداری و تعمیرات
</div>
<div
class="mq-nav-item"
data-permission="REPORT_VIEW"
>
<span class="mq-nav-icon">
<svg viewBox="0 0 24 24">
<path d="M5 20V10"></path>
<path d="M10 20V5"></path>
<path d="M15 20V13"></path>
<path d="M20 20V8"></path>
</svg>
</span>
گزارشها
</div>
</nav>
<div class="mq-sidebar-bottom">
<div
id="mqLogout"
class="mq-logout"
>
خروج از حساب کاربری
</div>
</div>
</aside>
</div>
<script>
(function () {
"use strict";
/* ============================================================
MEDIQ CONFIG
فعلاً برای تست UI دسترسیها اینجاست.
بعداً این بخش از Backend / Jira / Assets خوانده میشود.
============================================================ */
var CFG = {
user: {
name:
"سیما صیاف",
role:
"مدیر تجهیزات پزشکی"
},
/*
* برای تست:
*
* هر Permission را حذف کنی،
* همان قسمت از Dashboard ناپدید میشود.
*/
permissions: [
"ASSET_VIEW",
"ASSET_CREATE",
"ASSET_PURCHASE",
"ASSET_INVENTORY",
"CONSUMABLE_VIEW",
"MAINTENANCE_VIEW",
"PM_VIEW",
"EM_VIEW",
"CALIBRATION_VIEW",
"CONTRACT_VIEW",
"REQUEST_VIEW",
"REPORT_VIEW"
]
};
/* ============================================================
MODULE DEFINITIONS
============================================================ */
var MODULES = [
/* --------------------------------------------------------
EQUIPMENT
-------------------------------------------------------- */
{
title:
"مدیریت تجهیزات",
subtitle:
"مدیریت چرخه عمر داراییهای پزشکی",
permission:
"ASSET_VIEW",
icon:
'<path d="M12 3l7 4-7 4-7-4 7-4z"></path>' +
'<path d="M5 7v9l7 4 7-4V7"></path>' +
'<path d="M12 11v9"></path>',
actions: [
{
title:
"مدیریت تأمین و لجستیک",
permission:
"ASSET_VIEW"
},
{
title:
"خرید دارایی",
permission:
"ASSET_PURCHASE"
},
{
title:
"ورود دارایی جدید",
permission:
"ASSET_CREATE"
},
{
title:
"اموالگردانی",
permission:
"ASSET_INVENTORY"
},
{
title:
"کالاهای مصرفی",
permission:
"CONSUMABLE_VIEW"
}
]
},
/* --------------------------------------------------------
MAINTENANCE
-------------------------------------------------------- */
{
title:
"نگهداری و تعمیرات",
subtitle:
"PM، تعمیرات و کالیبراسیون",
permission:
"MAINTENANCE_VIEW",
icon:
'<circle cx="12" cy="12" r="3"></circle>' +
'<path d="M12 2v3"></path>' +
'<path d="M12 19v3"></path>' +
'<path d="M2 12h3"></path>' +
'<path d="M19 12h3"></path>',
actions: [
{
title:
"نگهداری پیشگیرانه (PM)",
permission:
"PM_VIEW"
},
{
title:
"درخواست تعمیر",
permission:
"EM_VIEW"
},
{
title:
"تعمیرات در حال انجام",
permission:
"EM_VIEW"
},
{
title:
"سوابق تعمیرات",
permission:
"EM_VIEW"
},
{
title:
"کالیبراسیون",
permission:
"CALIBRATION_VIEW"
}
]
},
/* --------------------------------------------------------
REQUESTS
-------------------------------------------------------- */
{
title:
"درخواستها",
subtitle:
"مدیریت درخواستهای تجهیزات پزشکی",
permission:
"REQUEST_VIEW",
icon:
'<path d="M6 3h12v18H6z"></path>' +
'<path d="M9 8h6"></path>' +
'<path d="M9 12h6"></path>' +
'<path d="M9 16h4"></path>',
actions: [
{
title:
"درخواست جدید",
permission:
"REQUEST_VIEW"
},
{
title:
"درخواستهای من",
permission:
"REQUEST_VIEW"
},
{
title:
"درخواستهای در انتظار بررسی",
permission:
"REQUEST_VIEW"
}
]
},
/* --------------------------------------------------------
CONTRACTS
-------------------------------------------------------- */
{
title:
"قراردادها",
subtitle:
"قراردادهای سرویس و پشتیبانی",
permission:
"CONTRACT_VIEW",
icon:
'<path d="M6 3h9l3 3v15H6z"></path>' +
'<path d="M14 3v4h4"></path>' +
'<path d="M9 12h6"></path>' +
'<path d="M9 16h6"></path>',
actions: [
{
title:
"قراردادهای فعال",
permission:
"CONTRACT_VIEW"
},
{
title:
"ثبت قرارداد",
permission:
"CONTRACT_VIEW"
},
{
title:
"قراردادهای نزدیک به انقضا",
permission:
"CONTRACT_VIEW"
}
]
},
/* --------------------------------------------------------
REPORTS
-------------------------------------------------------- */
{
title:
"گزارشها و تحلیل",
subtitle:
"گزارشهای مدیریتی و عملیاتی",
permission:
"REPORT_VIEW",
icon:
'<path d="M5 20V11"></path>' +
'<path d="M10 20V6"></path>' +
'<path d="M15 20V9"></path>' +
'<path d="M20 20V3"></path>',
actions: [
{
title:
"گزارش وضعیت تجهیزات",
permission:
"REPORT_VIEW"
},
{
title:
"گزارش تعمیرات",
permission:
"REPORT_VIEW"
},
{
title:
"گزارش PM",
permission:
"REPORT_VIEW"
},
{
title:
"داشبورد مدیریتی",
permission:
"REPORT_VIEW"
}
]
}
];
/* ============================================================
PERMISSION
============================================================ */
function hasPermission(permission) {
return (
CFG.permissions.indexOf(
permission
) !== -1
);
}
/* ============================================================
USER
============================================================ */
var userName =
document.getElementById(
"mqUserName"
);
var userRole =
document.getElementById(
"mqUserRole"
);
var welcomeName =
document.getElementById(
"mqWelcomeName"
);
if (userName) {
userName.textContent =
CFG.user.name;
}
if (userRole) {
userRole.textContent =
CFG.user.role;
}
if (welcomeName) {
welcomeName.textContent =
CFG.user.name;
}
/* ============================================================
BUILD MODULES
============================================================ */
var modulesContainer =
document.getElementById(
"mqModules"
);
function buildModules() {
if (!modulesContainer) {
return;
}
modulesContainer.innerHTML =
"";
var visibleModuleCount =
0;
MODULES.forEach(
function (module) {
if (
!hasPermission(
module.permission
)
) {
return;
}
var actionsHtml =
"";
module.actions.forEach(
function (action) {
if (
!hasPermission(
action.permission
)
) {
return;
}
actionsHtml +=
'<div class="mq-action">' +
'<span>' +
action.title +
'</span>' +
'<span class="mq-action-arrow">' +
'‹' +
'</span>' +
'</div>';
}
);
var html =
'<article class="mq-module">' +
'<div class="mq-module-header">' +
'<div class="mq-module-icon">' +
'<svg viewBox="0 0 24 24">' +
module.icon +
'</svg>' +
'</div>' +
'<div>' +
'<div class="mq-module-title">' +
module.title +
'</div>' +
'<div class="mq-module-subtitle">' +
module.subtitle +
'</div>' +
'</div>' +
'</div>' +
'<div class="mq-actions">' +
actionsHtml +
'</div>' +
'</article>';
modulesContainer.insertAdjacentHTML(
"beforeend",
html
);
visibleModuleCount++;
}
);
if (
visibleModuleCount === 0
) {
modulesContainer.innerHTML =
'<div class="mq-empty">' +
'در حال حاضر ماژولی برای حساب کاربری شما فعال نشده است.' +
'</div>';
}
}
buildModules();
/* ============================================================
SIDEBAR PERMISSIONS
============================================================ */
var protectedNavItems =
document.querySelectorAll(
"#mediq-dashboard .mq-nav-item[data-permission]"
);
for (
var i = 0;
i < protectedNavItems.length;
i++
) {
var permission =
protectedNavItems[i]
.getAttribute(
"data-permission"
);
if (
!hasPermission(
permission
)
) {
protectedNavItems[i]
.style.display =
"none";
}
}
/* ============================================================
LOGOUT
============================================================ */
var logout =
document.getElementById(
"mqLogout"
);
if (logout) {
logout.addEventListener(
"click",
function () {
window.location.href =
"/logout.action";
}
);
}
})();
</script>
</div> |