Files
AdminLTE/src/html/pages/index.astro
Aigars Silkalns 3885daabe1 Release v4.0.0-rc3: Production deployment fixes and cross-platform compatibility
- Fix production build path resolution for CSS/JS/images
- Resolve sidebar navigation layout issues (badges, arrows, spacing)
- Fix RTL CSS processing interference with LTR builds
- Update dependencies (Bootstrap 5.3.7, Bootstrap Icons 1.13.1, OverlayScrollbars 2.11.0)
- Remove CDN integrity attributes to prevent digest mismatches
- Add dist/ to .gitignore to exclude build files from repository
- Implement smart relative path calculation for all deployment scenarios
- Add runtime image path correction for sub-folder deployments
- Ensure development and production environment parity
- Fix all ESLint compliance issues (prefer-global-this, prefer-string-slice)

Major improvements:
 Production builds now work identically to development
 Images, CSS, and JavaScript load correctly in any deployment structure
 Sidebar displays properly with badges and arrow indicators
 Zero console errors from CDN resources
 Full compatibility with FTP/static hosting platforms
2025-06-23 12:45:13 +03:00

781 lines
28 KiB
Plaintext

---
import Head from "@components/_head.astro"
import Footer from "@components/dashboard/_footer.astro"
import Topbar from "@components/dashboard/_topbar.astro"
import Sidenav from "@components/dashboard/_sidenav.astro"
import Scripts from "@components/_scripts.astro"
const title = "AdminLTE v4 | Dashboard"
const path = "../../dist"
const mainPage = "dashboard"
const page = "index";
---
<!doctype html>
<html lang="en">
<!--begin::Head-->
<head>
<Head title={title} path={path} />
<!-- apexcharts -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/apexcharts@3.37.1/dist/apexcharts.css"
integrity="sha256-4MX+61mt9NVvvuPjUWdUdyfZfxSB1/Rf9WtqRHgG5S0="
crossorigin="anonymous"
/>
<!-- jsvectormap -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/jsvectormap@1.5.3/dist/css/jsvectormap.min.css"
integrity="sha256-+uGLJmmTKOqBr+2E6KDYs/NRsHxSkONXFHUL0fy2O/4="
crossorigin="anonymous"
/>
</head>
<!--end::Head-->
<!--begin::Body-->
<body class="layout-fixed sidebar-expand-lg sidebar-open bg-body-tertiary">
<!--begin::App Wrapper-->
<div class="app-wrapper">
<Topbar path={path} />
<Sidenav path={path} mainPage={mainPage} page={page} />
<!--begin::App Main-->
<main class="app-main">
<!--begin::App Content Header-->
<div class="app-content-header">
<!--begin::Container-->
<div class="container-fluid">
<!--begin::Row-->
<div class="row">
<div class="col-sm-6">
<h3 class="mb-0">Dashboard</h3>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-end">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item active" aria-current="page">
Dashboard
</li>
</ol>
</div>
</div>
<!--end::Row-->
</div>
<!--end::Container-->
</div>
<!--end::App Content Header-->
<!--begin::App Content-->
<div class="app-content">
<!--begin::Container-->
<div class="container-fluid">
<!--begin::Row-->
<div class="row">
<!--begin::Col-->
<div class="col-lg-3 col-6">
<!--begin::Small Box Widget 1-->
<div class="small-box text-bg-primary">
<div class="inner">
<h3>150</h3>
<p>New Orders</p>
</div>
<svg
class="small-box-icon"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M2.25 2.25a.75.75 0 000 1.5h1.386c.17 0 .318.114.362.278l2.558 9.592a3.752 3.752 0 00-2.806 3.63c0 .414.336.75.75.75h15.75a.75.75 0 000-1.5H5.378A2.25 2.25 0 017.5 15h11.218a.75.75 0 00.674-.421 60.358 60.358 0 002.96-7.228.75.75 0 00-.525-.965A60.864 60.864 0 005.68 4.509l-.232-.867A1.875 1.875 0 003.636 2.25H2.25zM3.75 20.25a1.5 1.5 0 113 0 1.5 1.5 0 01-3 0zM16.5 20.25a1.5 1.5 0 113 0 1.5 1.5 0 01-3 0z"
></path>
</svg>
<a
href="#"
class="small-box-footer link-light link-underline-opacity-0 link-underline-opacity-50-hover"
>
More info <i class="bi bi-link-45deg"></i>
</a>
</div>
<!--end::Small Box Widget 1-->
</div>
<!--end::Col-->
<div class="col-lg-3 col-6">
<!--begin::Small Box Widget 2-->
<div class="small-box text-bg-success">
<div class="inner">
<h3>53<sup class="fs-5">%</sup></h3>
<p>Bounce Rate</p>
</div>
<svg
class="small-box-icon"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M18.375 2.25c-1.035 0-1.875.84-1.875 1.875v15.75c0 1.035.84 1.875 1.875 1.875h.75c1.035 0 1.875-.84 1.875-1.875V4.125c0-1.036-.84-1.875-1.875-1.875h-.75zM9.75 8.625c0-1.036.84-1.875 1.875-1.875h.75c1.036 0 1.875.84 1.875 1.875v11.25c0 1.035-.84 1.875-1.875 1.875h-.75a1.875 1.875 0 01-1.875-1.875V8.625zM3 13.125c0-1.036.84-1.875 1.875-1.875h.75c1.036 0 1.875.84 1.875 1.875v6.75c0 1.035-.84 1.875-1.875 1.875h-.75A1.875 1.875 0 013 19.875v-6.75z"
></path>
</svg>
<a
href="#"
class="small-box-footer link-light link-underline-opacity-0 link-underline-opacity-50-hover"
>
More info <i class="bi bi-link-45deg"></i>
</a>
</div>
<!--end::Small Box Widget 2-->
</div>
<!--end::Col-->
<div class="col-lg-3 col-6">
<!--begin::Small Box Widget 3-->
<div class="small-box text-bg-warning">
<div class="inner">
<h3>44</h3>
<p>User Registrations</p>
</div>
<svg
class="small-box-icon"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M6.25 6.375a4.125 4.125 0 118.25 0 4.125 4.125 0 01-8.25 0zM3.25 19.125a7.125 7.125 0 0114.25 0v.003l-.001.119a.75.75 0 01-.363.63 13.067 13.067 0 01-6.761 1.873c-2.472 0-4.786-.684-6.76-1.873a.75.75 0 01-.364-.63l-.001-.122zM19.75 7.5a.75.75 0 00-1.5 0v2.25H16a.75.75 0 000 1.5h2.25v2.25a.75.75 0 001.5 0v-2.25H22a.75.75 0 000-1.5h-2.25V7.5z"
></path>
</svg>
<a
href="#"
class="small-box-footer link-dark link-underline-opacity-0 link-underline-opacity-50-hover"
>
More info <i class="bi bi-link-45deg"></i>
</a>
</div>
<!--end::Small Box Widget 3-->
</div>
<!--end::Col-->
<div class="col-lg-3 col-6">
<!--begin::Small Box Widget 4-->
<div class="small-box text-bg-danger">
<div class="inner">
<h3>65</h3>
<p>Unique Visitors</p>
</div>
<svg
class="small-box-icon"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
clip-rule="evenodd"
fill-rule="evenodd"
d="M2.25 13.5a8.25 8.25 0 018.25-8.25.75.75 0 01.75.75v6.75H18a.75.75 0 01.75.75 8.25 8.25 0 01-16.5 0z"
></path>
<path
clip-rule="evenodd"
fill-rule="evenodd"
d="M12.75 3a.75.75 0 01.75-.75 8.25 8.25 0 018.25 8.25.75.75 0 01-.75.75h-7.5a.75.75 0 01-.75-.75V3z"
></path>
</svg>
<a
href="#"
class="small-box-footer link-light link-underline-opacity-0 link-underline-opacity-50-hover"
>
More info <i class="bi bi-link-45deg"></i>
</a>
</div>
<!--end::Small Box Widget 4-->
</div>
<!--end::Col-->
</div>
<!--end::Row-->
<!--begin::Row-->
<div class="row">
<!-- Start col -->
<div class="col-lg-7 connectedSortable">
<div class="card mb-4">
<div class="card-header">
<h3 class="card-title">Sales Value</h3>
</div>
<div class="card-body">
<div id="revenue-chart"></div>
</div>
</div>
<!-- /.card -->
<!-- DIRECT CHAT -->
<div class="card direct-chat direct-chat-primary mb-4">
<div class="card-header">
<h3 class="card-title">Direct Chat</h3>
<div class="card-tools">
<span
title="3 New Messages"
class="badge text-bg-primary"
>
3
</span>
<button
type="button"
class="btn btn-tool"
data-lte-toggle="card-collapse"
>
<i data-lte-icon="expand" class="bi bi-plus-lg"></i>
<i data-lte-icon="collapse" class="bi bi-dash-lg"></i>
</button>
<button
type="button"
class="btn btn-tool"
title="Contacts"
data-lte-toggle="chat-pane"
>
<i class="bi bi-chat-text-fill"></i>
</button>
<button
type="button"
class="btn btn-tool"
data-lte-toggle="card-remove"
>
<i class="bi bi-x-lg"></i>
</button>
</div>
</div>
<!-- /.card-header -->
<div class="card-body">
<!-- Conversations are loaded here -->
<div class="direct-chat-messages">
<!-- Message. Default to the start -->
<div class="direct-chat-msg">
<div class="direct-chat-infos clearfix">
<span class="direct-chat-name float-start">
Alexander Pierce
</span>
<span class="direct-chat-timestamp float-end">
23 Jan 2:00 pm
</span>
</div>
<!-- /.direct-chat-infos -->
<img
class="direct-chat-img"
src="/assets/img/user1-128x128.jpg"
alt="message user image"
/>
<!-- /.direct-chat-img -->
<div class="direct-chat-text">
Is this template really for free? That's unbelievable!
</div>
<!-- /.direct-chat-text -->
</div>
<!-- /.direct-chat-msg -->
<!-- Message to the end -->
<div class="direct-chat-msg end">
<div class="direct-chat-infos clearfix">
<span class="direct-chat-name float-end">
Sarah Bullock
</span>
<span class="direct-chat-timestamp float-start">
23 Jan 2:05 pm
</span>
</div>
<!-- /.direct-chat-infos -->
<img
class="direct-chat-img"
src="/assets/img/user3-128x128.jpg"
alt="message user image"
/>
<!-- /.direct-chat-img -->
<div class="direct-chat-text">
You better believe it!
</div>
<!-- /.direct-chat-text -->
</div>
<!-- /.direct-chat-msg -->
<!-- Message. Default to the start -->
<div class="direct-chat-msg">
<div class="direct-chat-infos clearfix">
<span class="direct-chat-name float-start">
Alexander Pierce
</span>
<span class="direct-chat-timestamp float-end">
23 Jan 5:37 pm
</span>
</div>
<!-- /.direct-chat-infos -->
<img
class="direct-chat-img"
src="/assets/img/user1-128x128.jpg"
alt="message user image"
/>
<!-- /.direct-chat-img -->
<div class="direct-chat-text">
Working with AdminLTE on a great new app! Wanna join?
</div>
<!-- /.direct-chat-text -->
</div>
<!-- /.direct-chat-msg -->
<!-- Message to the end -->
<div class="direct-chat-msg end">
<div class="direct-chat-infos clearfix">
<span class="direct-chat-name float-end">
Sarah Bullock
</span>
<span class="direct-chat-timestamp float-start">
23 Jan 6:10 pm
</span>
</div>
<!-- /.direct-chat-infos -->
<img
class="direct-chat-img"
src="/assets/img/user3-128x128.jpg"
alt="message user image"
/>
<!-- /.direct-chat-img -->
<div class="direct-chat-text">I would love to.</div>
<!-- /.direct-chat-text -->
</div>
<!-- /.direct-chat-msg -->
</div>
<!-- /.direct-chat-messages-->
<!-- Contacts are loaded here -->
<div class="direct-chat-contacts">
<ul class="contacts-list">
<li>
<a href="#">
<img
class="contacts-list-img"
src="/assets/img/user1-128x128.jpg"
alt="User Avatar"
/>
<div class="contacts-list-info">
<span class="contacts-list-name">
Count Dracula
<small class="contacts-list-date float-end">
2/28/2023
</small>
</span>
<span class="contacts-list-msg">
How have you been? I was...
</span>
</div>
<!-- /.contacts-list-info -->
</a>
</li>
<!-- End Contact Item -->
<li>
<a href="#">
<img
class="contacts-list-img"
src="/assets/img/user7-128x128.jpg"
alt="User Avatar"
/>
<div class="contacts-list-info">
<span class="contacts-list-name">
Sarah Doe
<small class="contacts-list-date float-end">
2/23/2023
</small>
</span>
<span class="contacts-list-msg">
I will be waiting for...
</span>
</div>
<!-- /.contacts-list-info -->
</a>
</li>
<!-- End Contact Item -->
<li>
<a href="#">
<img
class="contacts-list-img"
src="/assets/img/user3-128x128.jpg"
alt="User Avatar"
/>
<div class="contacts-list-info">
<span class="contacts-list-name">
Nadia Jolie
<small class="contacts-list-date float-end">
2/20/2023
</small>
</span>
<span class="contacts-list-msg">
I'll call you back at...
</span>
</div>
<!-- /.contacts-list-info -->
</a>
</li>
<!-- End Contact Item -->
<li>
<a href="#">
<img
class="contacts-list-img"
src="/assets/img/user5-128x128.jpg"
alt="User Avatar"
/>
<div class="contacts-list-info">
<span class="contacts-list-name">
Nora S. Vans
<small class="contacts-list-date float-end">
2/10/2023
</small>
</span>
<span class="contacts-list-msg">
Where is your new...
</span>
</div>
<!-- /.contacts-list-info -->
</a>
</li>
<!-- End Contact Item -->
<li>
<a href="#">
<img
class="contacts-list-img"
src="/assets/img/user6-128x128.jpg"
alt="User Avatar"
/>
<div class="contacts-list-info">
<span class="contacts-list-name">
John K.
<small class="contacts-list-date float-end">
1/27/2023
</small>
</span>
<span class="contacts-list-msg">
Can I take a look at...
</span>
</div>
<!-- /.contacts-list-info -->
</a>
</li>
<!-- End Contact Item -->
<li>
<a href="#">
<img
class="contacts-list-img"
src="/assets/img/user8-128x128.jpg"
alt="User Avatar"
/>
<div class="contacts-list-info">
<span class="contacts-list-name">
Kenneth M.
<small class="contacts-list-date float-end">
1/4/2023
</small>
</span>
<span class="contacts-list-msg">
Never mind I found...
</span>
</div>
<!-- /.contacts-list-info -->
</a>
</li>
<!-- End Contact Item -->
</ul>
<!-- /.contacts-list -->
</div>
<!-- /.direct-chat-pane -->
</div>
<!-- /.card-body -->
<div class="card-footer">
<form action="#" method="post">
<div class="input-group">
<input
type="text"
name="message"
placeholder="Type Message ..."
class="form-control"
/>
<span class="input-group-append">
<button type="button" class="btn btn-primary">
Send
</button>
</span>
</div>
</form>
</div>
<!-- /.card-footer-->
</div>
<!-- /.direct-chat -->
</div>
<!-- /.Start col -->
<!-- Start col -->
<div class="col-lg-5 connectedSortable">
<div
class="card text-white bg-primary bg-gradient border-primary mb-4"
>
<div class="card-header border-0">
<h3 class="card-title">Sales Value</h3>
<div class="card-tools">
<button
type="button"
class="btn btn-primary btn-sm"
data-lte-toggle="card-collapse"
>
<i data-lte-icon="expand" class="bi bi-plus-lg"></i>
<i data-lte-icon="collapse" class="bi bi-dash-lg"></i>
</button>
</div>
</div>
<div class="card-body">
<div id="world-map" style="height: 220px"></div>
</div>
<div class="card-footer border-0">
<!--begin::Row-->
<div class="row">
<div class="col-4 text-center">
<div id="sparkline-1" class="text-dark"></div>
<div class="text-white">Visitors</div>
</div>
<div class="col-4 text-center">
<div id="sparkline-2" class="text-dark"></div>
<div class="text-white">Online</div>
</div>
<div class="col-4 text-center">
<div id="sparkline-3" class="text-dark"></div>
<div class="text-white">Sales</div>
</div>
</div>
<!--end::Row-->
</div>
</div>
</div>
<!-- /.Start col -->
</div>
<!-- /.row (main row) -->
</div>
<!--end::Container-->
</div>
<!--end::App Content-->
</main>
<!--end::App Main-->
<Footer />
</div>
<!--end::App Wrapper-->
<!--begin::Script-->
<Scripts path={path} />
<!-- OPTIONAL SCRIPTS -->
<!-- sortablejs -->
<script
src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"
crossorigin="anonymous"></script>
<!-- sortablejs -->
<script is:inline>
new Sortable(document.querySelector('.connectedSortable'), {
group: 'shared',
handle: '.card-header'
})
const cardHeaders = document.querySelectorAll(
'.connectedSortable .card-header'
)
cardHeaders.forEach(cardHeader => {
cardHeader.style.cursor = 'move'
})
</script>
<!-- apexcharts -->
<script
src="https://cdn.jsdelivr.net/npm/apexcharts@3.37.1/dist/apexcharts.min.js"
integrity="sha256-+vh8GkaU7C9/wbSLIcwq82tQ2wTf44aOHA8HlBMwRI8="
crossorigin="anonymous"></script>
<!-- ChartJS -->
<script is:inline>
// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
// IT'S ALL JUST JUNK FOR DEMO
// ++++++++++++++++++++++++++++++++++++++++++
const sales_chart_options = {
series: [
{
name: 'Digital Goods',
data: [28, 48, 40, 19, 86, 27, 90]
},
{
name: 'Electronics',
data: [65, 59, 80, 81, 56, 55, 40]
}
],
chart: {
height: 300,
type: 'area',
toolbar: {
show: false
}
},
legend: {
show: false
},
colors: ['#0d6efd', '#20c997'],
dataLabels: {
enabled: false
},
stroke: {
curve: 'smooth'
},
xaxis: {
type: 'datetime',
categories: [
'2023-01-01',
'2023-02-01',
'2023-03-01',
'2023-04-01',
'2023-05-01',
'2023-06-01',
'2023-07-01'
]
},
tooltip: {
x: {
format: 'MMMM yyyy'
}
}
}
const sales_chart = new ApexCharts(
document.querySelector('#revenue-chart'),
sales_chart_options
)
sales_chart.render()
</script>
<!-- jsvectormap -->
<script
src="https://cdn.jsdelivr.net/npm/jsvectormap@1.5.3/dist/js/jsvectormap.min.js"
integrity="sha256-/t1nN2956BT869E6H4V1dnt0X5pAQHPytli+1nTZm2Y="
crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/jsvectormap@1.5.3/dist/maps/world.js"
integrity="sha256-XPpPaZlU8S/HWf7FZLAncLg2SAkP8ScUTII89x9D3lY="
crossorigin="anonymous"></script>
<!-- jsvectormap -->
<script is:inline>
// World map by jsVectorMap
new jsVectorMap({
selector: '#world-map',
map: 'world'
});
// Sparkline charts
const option_sparkline1 = {
series: [
{
data: [1000, 1200, 920, 927, 931, 1027, 819, 930, 1021]
}
],
chart: {
type: 'area',
height: 50,
sparkline: {
enabled: true
}
},
stroke: {
curve: 'straight'
},
fill: {
opacity: 0.3
},
yaxis: {
min: 0
},
colors: ['#DCE6EC']
}
const sparkline1 = new ApexCharts(
document.querySelector('#sparkline-1'),
option_sparkline1
)
sparkline1.render()
const option_sparkline2 = {
series: [
{
data: [515, 519, 520, 522, 652, 810, 370, 627, 319, 630, 921]
}
],
chart: {
type: 'area',
height: 50,
sparkline: {
enabled: true
}
},
stroke: {
curve: 'straight'
},
fill: {
opacity: 0.3
},
yaxis: {
min: 0
},
colors: ['#DCE6EC']
}
const sparkline2 = new ApexCharts(
document.querySelector('#sparkline-2'),
option_sparkline2
)
sparkline2.render()
const option_sparkline3 = {
series: [
{
data: [15, 19, 20, 22, 33, 27, 31, 27, 19, 30, 21]
}
],
chart: {
type: 'area',
height: 50,
sparkline: {
enabled: true
}
},
stroke: {
curve: 'straight'
},
fill: {
opacity: 0.3
},
yaxis: {
min: 0
},
colors: ['#DCE6EC']
}
const sparkline3 = new ApexCharts(
document.querySelector('#sparkline-3'),
option_sparkline3
)
sparkline3.render()
</script>
<!--end::Script-->
</body><!--end::Body-->
</html>