update
BIN
assets/images/avatars/1.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
assets/images/avatars/10.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
assets/images/avatars/2.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
assets/images/avatars/3.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
assets/images/avatars/4.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
assets/images/avatars/5.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
assets/images/avatars/6.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
assets/images/avatars/7.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
assets/images/avatars/8.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
assets/images/avatars/9.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
assets/images/logo_hura8.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -1,44 +0,0 @@
|
||||
|
||||
const RowExpand = (function (){
|
||||
|
||||
const $status_expand_all = $("#js-row-expand-all");
|
||||
|
||||
let track_open_rows = [];
|
||||
|
||||
function open_child_row(child_class_name){
|
||||
const $children = $(`.${child_class_name}`);
|
||||
|
||||
if(!track_open_rows.includes(child_class_name)) {
|
||||
$children.css('display', 'table-row');
|
||||
track_open_rows.push(child_class_name);
|
||||
}else{
|
||||
$children.css('display', 'none');
|
||||
track_open_rows = [...Util.removeItemFromArray(track_open_rows, child_class_name)];
|
||||
}
|
||||
}
|
||||
|
||||
function open_all_row(){
|
||||
if(!track_open_rows.includes('expand_all')) {
|
||||
$(".row").css('display', 'table-row');
|
||||
track_open_rows.push('expand_all');
|
||||
|
||||
$status_expand_all.html("[-]");
|
||||
|
||||
}else{
|
||||
// collapse all
|
||||
$(".row").css('display', 'none');
|
||||
// open only first parent
|
||||
$(".parent_0").css('display', 'table-row');
|
||||
|
||||
track_open_rows = [];
|
||||
|
||||
$status_expand_all.html("[+]");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
open_child: open_child_row,
|
||||
open_all: open_all_row
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -1,915 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
@import "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css";
|
||||
:root {
|
||||
--p: 0.48 0.25 263.47;
|
||||
}
|
||||
|
||||
*,
|
||||
::after,
|
||||
::before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
outline: none;
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
color: #000;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
input[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
input[type=date]::-webkit-calendar-picker-indicator {
|
||||
background: transparent;
|
||||
bottom: 0;
|
||||
color: transparent;
|
||||
cursor: pointer;
|
||||
height: auto;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #000;
|
||||
font-family: "Inter", sans-serif;
|
||||
background: #fafafb;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
word-break: break-word;
|
||||
counter-reset: section;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
margin: auto;
|
||||
min-height: 100vh;
|
||||
min-width: 1200px;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table td,
|
||||
table th {
|
||||
padding: 8px !important;
|
||||
border: 1px solid #ececec;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: grey;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.clearfix::after {
|
||||
content: "";
|
||||
clear: both;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.inherit {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.icons {
|
||||
background: url(../images/global-sprite.png) no-repeat;
|
||||
background-size: 400px 400px;
|
||||
background-position: 0 40px;
|
||||
}
|
||||
|
||||
.admin-global-container {
|
||||
margin: auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.admin-menu-container {
|
||||
position: relative;
|
||||
background: #004180;
|
||||
color: #fff;
|
||||
width: 245px;
|
||||
padding: 20px 0;
|
||||
line-height: 20px;
|
||||
height: 100vh;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.admin-menu-container.active {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.admin-menu-container.show {
|
||||
position: fixed;
|
||||
display: block;
|
||||
z-index: 999;
|
||||
}
|
||||
.admin-menu-container a {
|
||||
color: #fff;
|
||||
}
|
||||
.admin-menu-container .menu-logo {
|
||||
display: table;
|
||||
margin-bottom: 25px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
.admin-menu-container .menu-logo img {
|
||||
height: 22px;
|
||||
}
|
||||
.admin-menu-container svg {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
transition: 0.3s all;
|
||||
}
|
||||
.admin-menu-container .item.active {
|
||||
background: #22a2ff;
|
||||
}
|
||||
.admin-menu-container .item.active .icons {
|
||||
filter: brightness(100);
|
||||
}
|
||||
.admin-menu-container .item:hover {
|
||||
background: #22a2ff;
|
||||
}
|
||||
.admin-menu-container .item:hover .icons {
|
||||
filter: brightness(100);
|
||||
}
|
||||
.admin-menu-container .item:hover .hover-menu {
|
||||
display: block;
|
||||
}
|
||||
.admin-menu-container .item .icons {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 13px;
|
||||
}
|
||||
.admin-menu-container .title-main {
|
||||
width: 100%;
|
||||
}
|
||||
.admin-menu-container .box-item:hover .hover-menu {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
left: calc(100% + 10px);
|
||||
}
|
||||
.admin-menu-container .box-item:hover .hover-menu::before {
|
||||
display: block;
|
||||
}
|
||||
.admin-menu-container .sub-menu {
|
||||
position: relative;
|
||||
display: none;
|
||||
}
|
||||
.admin-menu-container .sub-menu a {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
margin-left: 25px;
|
||||
position: relative;
|
||||
}
|
||||
.admin-menu-container .sub-menu a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.admin-menu-container .sub-menu a.current {
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
background: #22a2ff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.admin-menu-container .sub-menu a:last-child::after {
|
||||
display: none;
|
||||
}
|
||||
.admin-menu-container .sub-menu a::before {
|
||||
content: "";
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #79b0e2;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: -16px;
|
||||
z-index: 9;
|
||||
}
|
||||
.admin-menu-container .sub-menu a::after {
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: -12px;
|
||||
}
|
||||
.admin-menu-container .sub-menu.active {
|
||||
display: block;
|
||||
}
|
||||
.admin-menu-container .hover-menu {
|
||||
padding: 10px 22px 10px 15px;
|
||||
border-radius: 6px;
|
||||
background: #004e99;
|
||||
box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.25);
|
||||
white-space: nowrap;
|
||||
z-index: -1;
|
||||
transition: 0.2s all;
|
||||
position: absolute;
|
||||
left: calc(100% + 30px);
|
||||
top: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
min-width: 200px;
|
||||
z-index: 999;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
}
|
||||
.admin-menu-container .hover-menu.bottom {
|
||||
bottom: -30px;
|
||||
top: unset;
|
||||
}
|
||||
.admin-menu-container .hover-menu::before {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
top: 0;
|
||||
width: 30px;
|
||||
height: 100%;
|
||||
content: "";
|
||||
display: none;
|
||||
}
|
||||
.admin-menu-container .hover-menu a {
|
||||
display: block;
|
||||
line-height: 18px;
|
||||
position: relative;
|
||||
padding-bottom: 12px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
.admin-menu-container .hover-menu a::before {
|
||||
content: "";
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #79b0e2;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
.admin-menu-container .hover-menu a::after {
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
}
|
||||
.admin-menu-container .hover-menu a:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.admin-menu-container .hover-menu a:last-child::after {
|
||||
display: none;
|
||||
}
|
||||
.admin-menu-container .hover-menu a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.admin-menu-container .icon-home {
|
||||
background-position: -9px -7px;
|
||||
}
|
||||
.admin-menu-container .box-hover {
|
||||
padding: 10px 22px 10px 15px;
|
||||
border-radius: 6px;
|
||||
background: #004e99;
|
||||
box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.25);
|
||||
white-space: nowrap;
|
||||
position: fixed;
|
||||
left: 240px;
|
||||
top: 0;
|
||||
display: none;
|
||||
min-width: 200px;
|
||||
z-index: 999;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
}
|
||||
.admin-menu-container .box-hover.active {
|
||||
display: block;
|
||||
}
|
||||
.admin-menu-container .box-hover::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -29px;
|
||||
top: 0;
|
||||
width: 37px;
|
||||
height: 100%;
|
||||
}
|
||||
.admin-menu-container .box-hover a {
|
||||
display: block;
|
||||
line-height: 18px;
|
||||
position: relative;
|
||||
padding-bottom: 12px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
.admin-menu-container .box-hover a::before {
|
||||
content: "";
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #79b0e2;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
.admin-menu-container .box-hover a::after {
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
}
|
||||
.admin-menu-container .box-hover a:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.admin-menu-container .box-hover a:last-child::after {
|
||||
display: none;
|
||||
}
|
||||
.admin-menu-container .box-hover a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.admin-menu-container .icon-order {
|
||||
background-position: -45px -7px;
|
||||
}
|
||||
.admin-menu-container .icon-product {
|
||||
background-position: -81px -8px;
|
||||
}
|
||||
.admin-menu-container .icon-customer {
|
||||
background-position: -117px -8px;
|
||||
}
|
||||
.admin-menu-container .icon-marketing {
|
||||
background-position: -154px -8px;
|
||||
}
|
||||
.admin-menu-container .icon-content {
|
||||
background-position: -187px -8px;
|
||||
}
|
||||
.admin-menu-container .icon-stats {
|
||||
background-position: -224px -8px;
|
||||
}
|
||||
.admin-menu-container .icon-system {
|
||||
background-position: -262px -8px;
|
||||
}
|
||||
.admin-menu-container .icon-settings {
|
||||
background-position: -297px -8px;
|
||||
}
|
||||
.admin-menu-container .icon-support {
|
||||
background-position: -332px -7px;
|
||||
}
|
||||
.admin-menu-container .icon-account {
|
||||
background-position: -367px -9px;
|
||||
}
|
||||
.admin-menu-container .icon-logout {
|
||||
background-position: -9px -45px;
|
||||
}
|
||||
.admin-menu-container .icon-close {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
}
|
||||
.admin-menu-container .icon-investor_relation {
|
||||
background-position: -9px -126px;
|
||||
}
|
||||
.admin-menu-container .icon-job {
|
||||
background-position: -52px -126px;
|
||||
}
|
||||
.admin-menu-container .icon-pcbuilder {
|
||||
background-position: -99px -126px;
|
||||
}
|
||||
.admin-menu-container .icon-payinstall {
|
||||
background-position: -142px -125px;
|
||||
}
|
||||
.admin-menu-container .icon-distributor {
|
||||
background-position: -187px -126px;
|
||||
}
|
||||
|
||||
.admin-content-container {
|
||||
width: calc(100% - 245px);
|
||||
overflow: auto;
|
||||
}
|
||||
.admin-content-container .note-list {
|
||||
min-width: 144px;
|
||||
}
|
||||
.admin-content-container .note-list a {
|
||||
display: block;
|
||||
padding: 0 10px;
|
||||
line-height: 35px;
|
||||
transition: 0.2s all;
|
||||
}
|
||||
.admin-content-container .note-list a:hover {
|
||||
background: #f5f7ff;
|
||||
color: #0041e8;
|
||||
font-weight: 600;
|
||||
}
|
||||
.admin-content-container .content-holder {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.admin-home-tab {
|
||||
overflow: auto;
|
||||
}
|
||||
.admin-home-tab a {
|
||||
color: #a0a8b5;
|
||||
padding: 9px 7.7px;
|
||||
text-align: center;
|
||||
border-right: 1px solid #dde1eb;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.admin-home-tab a:last-child {
|
||||
border: 0;
|
||||
}
|
||||
.admin-home-tab a:hover, .admin-home-tab a.current {
|
||||
background: #0041e8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.icons {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: block;
|
||||
}
|
||||
.icons.icon-search {
|
||||
background-position: -71px -40px;
|
||||
}
|
||||
.icons.header-support {
|
||||
height: 33px;
|
||||
background-position: -116px -42px;
|
||||
}
|
||||
.icons.icon-notification {
|
||||
height: 33px;
|
||||
background-position: -165px -42px;
|
||||
}
|
||||
.icons.icon-cart {
|
||||
background-position: -210px -36px;
|
||||
}
|
||||
.icons.icon-contact {
|
||||
background-position: -246px -36px;
|
||||
}
|
||||
.icons.icon-pay {
|
||||
background-position: -284px -36px;
|
||||
}
|
||||
.icons.icon-installment {
|
||||
background-position: -318px -36px;
|
||||
}
|
||||
.icons.icon-increase {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-position: -6px -85px;
|
||||
}
|
||||
.icons.icon-reduce {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-position: -43px -83px;
|
||||
}
|
||||
.icons.icon-edit {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -114px -89px;
|
||||
}
|
||||
.icons.icon-view {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -187px -88px;
|
||||
}
|
||||
.icons.icon-remove {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -151px -88px;
|
||||
}
|
||||
.icons.icon-hide {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -224px -88px;
|
||||
}
|
||||
.icons.icon-upload {
|
||||
background-position: -2px -43px;
|
||||
transform: rotate(-90deg);
|
||||
filter: invert(60%) sepia(90%) saturate(6183%) hue-rotate(228deg) brightness(92%) contrast(101%);
|
||||
}
|
||||
.icons.icon-feature {
|
||||
width: 18px;
|
||||
height: 16px;
|
||||
background-position: -259px -88px;
|
||||
}
|
||||
.icons.icon-copy {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background-position: -330px -88px;
|
||||
}
|
||||
|
||||
/* Bán hàng */
|
||||
.page-input {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
padding: 0 10px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d8d8d8;
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.order-page .order-page-title a {
|
||||
margin: 0 2px 0 0;
|
||||
border-radius: 4px 4px 0px 0px;
|
||||
background: #f6f6f6;
|
||||
color: #919699;
|
||||
font-weight: 500;
|
||||
padding: 0 24px;
|
||||
}
|
||||
.order-page .order-page-title a:hover, .order-page .order-page-title a.current, .order-page .order-page-title a.active {
|
||||
background: #0041e8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.is-close-btn {
|
||||
background: #ececec !important;
|
||||
border-radius: 50%;
|
||||
top: 10px !important;
|
||||
right: 10px !important;
|
||||
color: #9e9e9e !important;
|
||||
}
|
||||
|
||||
.paging {
|
||||
margin: 30px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 28px;
|
||||
}
|
||||
.paging a {
|
||||
margin: 0 3px;
|
||||
min-width: 28px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
padding: 0 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.paging a:hover, .paging a.current, .paging a.active {
|
||||
background: #0041e8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.global-breadcrumb-container {
|
||||
padding: 16px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.global-breadcrumb-container a {
|
||||
display: inline-block;
|
||||
}
|
||||
.global-breadcrumb-container a:hover {
|
||||
color: #0041e8;
|
||||
}
|
||||
.global-breadcrumb-container a::after {
|
||||
content: "\f054";
|
||||
font-family: Fontawesome;
|
||||
font-size: 10px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.global-breadcrumb-container a:last-child {
|
||||
color: #0041e8;
|
||||
}
|
||||
.global-breadcrumb-container a:last-child::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
#js-form-search [type=search]:focus::before {
|
||||
position: absolute;
|
||||
content: "\f00d";
|
||||
font-family: "Font Awesome 6 Free";
|
||||
font-weight: 900;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.autocomplete-suggestions {
|
||||
height: 334px;
|
||||
overflow-y: auto;
|
||||
z-index: 999;
|
||||
}
|
||||
.autocomplete-suggestions .item {
|
||||
padding: 10px 15px;
|
||||
border-bottom: 1px solid #ededed;
|
||||
}
|
||||
.autocomplete-suggestions .item:hover {
|
||||
font-weight: 700;
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
.input-file {
|
||||
position: relative;
|
||||
}
|
||||
.input-file input {
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
}
|
||||
.input-file .title {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.input-file .btn-input-file {
|
||||
width: 120px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #0041e8;
|
||||
color: #0041e8;
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.input-file .btn-input-file:hover {
|
||||
background: #0041e8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.modal .brand-letters a {
|
||||
width: 11.1111111111%;
|
||||
text-transform: capitalize;
|
||||
color: #0041e8;
|
||||
}
|
||||
.modal .brand-letters a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.input-date {
|
||||
position: relative;
|
||||
}
|
||||
.input-date::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 15px;
|
||||
transform: translate(0, -50%);
|
||||
content: "\f133";
|
||||
font-family: "Font Awesome 6 Free";
|
||||
}
|
||||
|
||||
.checkbox-success {
|
||||
--chkbg: #0041e8;
|
||||
--chkfg: #fff;
|
||||
border-color: #000 !important;
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.checkbox-success:checked,
|
||||
.checkbox-success[aria-checked=true] {
|
||||
background-color: #0041e8;
|
||||
border-color: #0041e8 !important;
|
||||
}
|
||||
|
||||
.radio {
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
}
|
||||
|
||||
.box-note {
|
||||
position: relative;
|
||||
}
|
||||
.box-note i {
|
||||
cursor: pointer;
|
||||
}
|
||||
.box-note .content {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
top: 6px;
|
||||
width: 250px;
|
||||
display: none;
|
||||
font-size: 12px;
|
||||
background: #e4b200;
|
||||
color: #fff;
|
||||
padding: 10px;
|
||||
box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.1490196078);
|
||||
border-radius: 6px;
|
||||
z-index: 9;
|
||||
}
|
||||
.box-note .content::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -14px;
|
||||
top: 0;
|
||||
width: 20px;
|
||||
height: 15px;
|
||||
-webkit-clip-path: polygon(0 0, 100% 100%, 100% 0);
|
||||
clip-path: polygon(0 0, 100% 100%, 100% 0);
|
||||
background: #e4b200;
|
||||
border-radius: 5px 0 0 0;
|
||||
}
|
||||
.box-note:hover .content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.order-detail-page .select2-container {
|
||||
width: 100% !important;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#overlay {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
z-index: 999;
|
||||
display: none;
|
||||
}
|
||||
#overlay.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.status-notificatiom {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: #fff;
|
||||
width: 550px;
|
||||
height: 240px;
|
||||
box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.1019607843);
|
||||
border-radius: 15px;
|
||||
display: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
.status-notificatiom.active {
|
||||
display: block;
|
||||
}
|
||||
.status-notificatiom .icon-close {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: #ececec;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.status-notificatiom .content {
|
||||
height: 100%;
|
||||
}
|
||||
.status-notificatiom .fa-check {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
background: #52c41a;
|
||||
color: #fff;
|
||||
font-size: 50px;
|
||||
text-align: center;
|
||||
line-height: 70px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.status-notificatiom b {
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.status-notificatiom p {
|
||||
color: rgba(0, 0, 0, 0.4509803922);
|
||||
}
|
||||
.status-notificatiom .fa-triangle-exclamation {
|
||||
font-size: 70px;
|
||||
color: #ffc53d;
|
||||
}
|
||||
|
||||
.table a {
|
||||
color: #0041e8;
|
||||
}
|
||||
.table .btn {
|
||||
color: #fff;
|
||||
padding: 0;
|
||||
}
|
||||
.table select {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d8d8d8;
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.12);
|
||||
height: 32px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0 0 0 5px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.table .icons {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 1px solid #ececec;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.table .icon-edit {
|
||||
background-color: #f5f7ff;
|
||||
background-position: -108px -82px;
|
||||
}
|
||||
.table .icon-delete {
|
||||
background-position: -145px -82px;
|
||||
}
|
||||
.table .icon-view {
|
||||
background-position: -180px -82px;
|
||||
}
|
||||
.table .icon-feature {
|
||||
background-position: -255px -82px;
|
||||
}
|
||||
|
||||
.home-report-holder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.not-border td {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.not-padding td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 2560px) {
|
||||
body {
|
||||
font-size: 18px;
|
||||
}
|
||||
.text-custom-14 {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.text-custom-16 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
.text-custom-22 {
|
||||
font-size: 22px !important;
|
||||
}
|
||||
.text-custom-28 {
|
||||
font-size: 28px !important;
|
||||
}
|
||||
.admin-menu-container {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.template-edit .tab-edit ul {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.template-edit .tab-edit .item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.template-edit .tab-edit li {
|
||||
list-style: inside;
|
||||
line-height: 24px;
|
||||
color: #6b7280;
|
||||
}
|
||||
.template-edit .tab-edit li.active {
|
||||
color: #0041e8;
|
||||
}
|
||||
|
||||
.monaco-editor .margin {
|
||||
border: 1px solid #ececec;
|
||||
}
|
||||
|
||||
.monaco-editor .margin-view-overlays .line-numbers {
|
||||
text-align: center !important;
|
||||
color: #000 !important;
|
||||
}/*# sourceMappingURL=extension_daisyui.css.map */
|
||||
@@ -1,929 +0,0 @@
|
||||
@import "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css";
|
||||
|
||||
:root {
|
||||
--p: 0.48 0.25 263.47;
|
||||
}
|
||||
|
||||
*,
|
||||
::after,
|
||||
::before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
button,
|
||||
select {
|
||||
cursor: pointer;
|
||||
}
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
outline: none;
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
color: #000;
|
||||
border-radius: 0;
|
||||
}
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
input[type="number"] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
input[type="date"]::-webkit-calendar-picker-indicator {
|
||||
background: transparent;
|
||||
bottom: 0;
|
||||
color: transparent;
|
||||
cursor: pointer;
|
||||
height: auto;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: auto;
|
||||
}
|
||||
body {
|
||||
color: #000;
|
||||
font-family: "Inter", sans-serif;
|
||||
background: #fafafb;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
word-break: break-word;
|
||||
counter-reset: section;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
margin: auto;
|
||||
min-height: 100vh;
|
||||
min-width: 1200px;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
table td,
|
||||
table th {
|
||||
padding: 8px !important;
|
||||
border: 1px solid #ececec;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: grey;
|
||||
border-radius: 5px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #ccc;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
&::after {
|
||||
content: "";
|
||||
clear: both;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.inherit {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
.icons {
|
||||
background: url(../images/global-sprite.png) no-repeat;
|
||||
background-size: 400px 400px;
|
||||
background-position: 0 40px;
|
||||
}
|
||||
.admin-global-container {
|
||||
margin: auto;
|
||||
display: flex;
|
||||
}
|
||||
.admin-menu-container {
|
||||
position: relative;
|
||||
background: #004180;
|
||||
color: #fff;
|
||||
width: 245px;
|
||||
padding: 20px 0;
|
||||
line-height: 20px;
|
||||
height: 100vh;
|
||||
left: 0;
|
||||
top: 0;
|
||||
&.active {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
&.show {
|
||||
position: fixed;
|
||||
display: block;
|
||||
z-index: 999;
|
||||
}
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
.menu-logo {
|
||||
display: table;
|
||||
margin-bottom: 25px;
|
||||
margin-left: 16px;
|
||||
img {
|
||||
height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
transition: 0.3s all;
|
||||
}
|
||||
.item {
|
||||
&.active {
|
||||
background: #22a2ff;
|
||||
.icons {
|
||||
filter: brightness(100);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: #22a2ff;
|
||||
.icons {
|
||||
filter: brightness(100);
|
||||
}
|
||||
.hover-menu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.icons {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 13px;
|
||||
}
|
||||
}
|
||||
.title-main {
|
||||
width: 100%;
|
||||
}
|
||||
.box-item {
|
||||
&:hover {
|
||||
.hover-menu {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
left: calc(100% + 10px);
|
||||
&::before {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.sub-menu {
|
||||
position: relative;
|
||||
display: none;
|
||||
a {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
margin-left: 25px;
|
||||
position: relative;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
&.current {
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
background: #22a2ff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
&:last-child {
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&::before {
|
||||
content: "";
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #79b0e2;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: -16px;
|
||||
z-index: 9;
|
||||
}
|
||||
&::after {
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: -12px;
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.hover-menu {
|
||||
padding: 10px 22px 10px 15px;
|
||||
border-radius: 6px;
|
||||
background: #004e99;
|
||||
box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.25);
|
||||
white-space: nowrap;
|
||||
z-index: -1;
|
||||
transition: 0.2s all;
|
||||
position: absolute;
|
||||
left: calc(100% + 30px);
|
||||
top: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
min-width: 200px;
|
||||
z-index: 999;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
&.bottom {
|
||||
bottom: -30px;
|
||||
top: unset;
|
||||
}
|
||||
&::before {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
top: 0;
|
||||
width: 30px;
|
||||
height: 100%;
|
||||
content: "";
|
||||
display: none;
|
||||
}
|
||||
a {
|
||||
display: block;
|
||||
line-height: 18px;
|
||||
position: relative;
|
||||
padding-bottom: 12px;
|
||||
padding-left: 20px;
|
||||
&::before {
|
||||
content: "";
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #79b0e2;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
&::after {
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
}
|
||||
&:last-child {
|
||||
padding-bottom: 0;
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-home {
|
||||
background-position: -9px -7px;
|
||||
}
|
||||
|
||||
.box-hover {
|
||||
padding: 10px 22px 10px 15px;
|
||||
border-radius: 6px;
|
||||
background: #004e99;
|
||||
box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.25);
|
||||
white-space: nowrap;
|
||||
position: fixed;
|
||||
left: 240px;
|
||||
top: 0;
|
||||
display: none;
|
||||
min-width: 200px;
|
||||
z-index: 999;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
&.active {
|
||||
display: block;
|
||||
}
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -29px;
|
||||
top: 0;
|
||||
width: 37px;
|
||||
height: 100%;
|
||||
}
|
||||
a {
|
||||
display: block;
|
||||
line-height: 18px;
|
||||
position: relative;
|
||||
padding-bottom: 12px;
|
||||
padding-left: 20px;
|
||||
&::before {
|
||||
content: "";
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #79b0e2;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
&::after {
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
}
|
||||
&:last-child {
|
||||
padding-bottom: 0;
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-order {
|
||||
background-position: -45px -7px;
|
||||
}
|
||||
.icon-product {
|
||||
background-position: -81px -8px;
|
||||
}
|
||||
.icon-customer {
|
||||
background-position: -117px -8px;
|
||||
}
|
||||
.icon-marketing {
|
||||
background-position: -154px -8px;
|
||||
}
|
||||
.icon-content {
|
||||
background-position: -187px -8px;
|
||||
}
|
||||
.icon-stats {
|
||||
background-position: -224px -8px;
|
||||
}
|
||||
.icon-system {
|
||||
background-position: -262px -8px;
|
||||
}
|
||||
.icon-settings {
|
||||
background-position: -297px -8px;
|
||||
}
|
||||
.icon-support {
|
||||
background-position: -332px -7px;
|
||||
}
|
||||
.icon-account {
|
||||
background-position: -367px -9px;
|
||||
}
|
||||
.icon-logout {
|
||||
background-position: -9px -45px;
|
||||
}
|
||||
.icon-close {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
}
|
||||
.icon-investor_relation {
|
||||
background-position: -9px -126px;
|
||||
}
|
||||
.icon-job {
|
||||
background-position: -52px -126px;
|
||||
}
|
||||
.icon-pcbuilder {
|
||||
background-position: -99px -126px;
|
||||
}
|
||||
.icon-payinstall {
|
||||
background-position: -142px -125px;
|
||||
}
|
||||
.icon-distributor {
|
||||
background-position: -187px -126px;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-content-container {
|
||||
width: calc(100% - 245px);
|
||||
overflow: auto;
|
||||
.note-list {
|
||||
min-width: 144px;
|
||||
a {
|
||||
display: block;
|
||||
padding: 0 10px;
|
||||
line-height: 35px;
|
||||
transition: 0.2s all;
|
||||
&:hover {
|
||||
background: #f5f7ff;
|
||||
color: #0041e8;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-holder {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-home-tab {
|
||||
overflow: auto;
|
||||
a {
|
||||
color: #a0a8b5;
|
||||
padding: 9px 7.7px;
|
||||
text-align: center;
|
||||
border-right: 1px solid #dde1eb;
|
||||
white-space: nowrap;
|
||||
&:last-child {
|
||||
border: 0;
|
||||
}
|
||||
&:hover,
|
||||
&.current {
|
||||
background: #0041e8;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icons {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: block;
|
||||
&.icon-search {
|
||||
background-position: -71px -40px;
|
||||
}
|
||||
&.header-support {
|
||||
height: 33px;
|
||||
background-position: -116px -42px;
|
||||
}
|
||||
&.icon-notification {
|
||||
height: 33px;
|
||||
background-position: -165px -42px;
|
||||
}
|
||||
&.icon-cart {
|
||||
background-position: -210px -36px;
|
||||
}
|
||||
&.icon-contact {
|
||||
background-position: -246px -36px;
|
||||
}
|
||||
&.icon-pay {
|
||||
background-position: -284px -36px;
|
||||
}
|
||||
&.icon-installment {
|
||||
background-position: -318px -36px;
|
||||
}
|
||||
&.icon-increase {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-position: -6px -85px;
|
||||
}
|
||||
&.icon-reduce {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-position: -43px -83px;
|
||||
}
|
||||
&.icon-edit {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -114px -89px;
|
||||
}
|
||||
&.icon-view {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -187px -88px;
|
||||
}
|
||||
&.icon-remove {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -151px -88px;
|
||||
}
|
||||
&.icon-hide {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -224px -88px;
|
||||
}
|
||||
&.icon-upload {
|
||||
background-position: -2px -43px;
|
||||
transform: rotate(-90deg);
|
||||
filter: invert(60%) sepia(90%) saturate(6183%) hue-rotate(228deg) brightness(92%) contrast(101%);
|
||||
}
|
||||
&.icon-feature {
|
||||
width: 18px;
|
||||
height: 16px;
|
||||
background-position: -259px -88px;
|
||||
}
|
||||
&.icon-copy {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background-position: -330px -88px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bán hàng */
|
||||
.page-input {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
padding: 0 10px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d8d8d8;
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.order-page {
|
||||
.order-page-title {
|
||||
a {
|
||||
margin: 0 2px 0 0;
|
||||
border-radius: 4px 4px 0px 0px;
|
||||
background: #f6f6f6;
|
||||
color: #919699;
|
||||
font-weight: 500;
|
||||
padding: 0 24px;
|
||||
&:hover,
|
||||
&.current,
|
||||
&.active {
|
||||
background: #0041e8;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.is-close-btn {
|
||||
background: #ececec !important;
|
||||
border-radius: 50%;
|
||||
top: 10px !important;
|
||||
right: 10px !important;
|
||||
color: #9e9e9e !important;
|
||||
}
|
||||
|
||||
.paging {
|
||||
margin: 30px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 28px;
|
||||
a {
|
||||
margin: 0 3px;
|
||||
min-width: 28px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
padding: 0 10px;
|
||||
border-radius: 4px;
|
||||
&:hover,
|
||||
&.current,
|
||||
&.active {
|
||||
background: #0041e8;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.global-breadcrumb-container {
|
||||
padding: 16px;
|
||||
line-height: 20px;
|
||||
a {
|
||||
display: inline-block;
|
||||
&:hover {
|
||||
color: #0041e8;
|
||||
}
|
||||
&::after {
|
||||
content: "\f054";
|
||||
font-family: Fontawesome;
|
||||
font-size: 10px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
&:last-child {
|
||||
color: #0041e8;
|
||||
&::after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#js-form-search [type="search"]:focus::before {
|
||||
position: absolute;
|
||||
content: "\f00d";
|
||||
font-family: "Font Awesome 6 Free";
|
||||
font-weight: 900;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.autocomplete-suggestions {
|
||||
height: 334px;
|
||||
overflow-y: auto;
|
||||
z-index: 999;
|
||||
.item {
|
||||
padding: 10px 15px;
|
||||
border-bottom: 1px solid #ededed;
|
||||
&:hover {
|
||||
font-weight: 700;
|
||||
background: #f6f6f6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-file {
|
||||
position: relative;
|
||||
input {
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
}
|
||||
.title {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.btn-input-file {
|
||||
width: 120px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #0041e8;
|
||||
color: #0041e8;
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
&:hover {
|
||||
background: #0041e8;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal {
|
||||
.brand-letters {
|
||||
a {
|
||||
width: calc(100% / 9);
|
||||
text-transform: capitalize;
|
||||
color: #0041e8;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-date {
|
||||
position: relative;
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 15px;
|
||||
transform: translate(0, -50%);
|
||||
content: "\f133";
|
||||
font-family: "Font Awesome 6 Free";
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-success {
|
||||
--chkbg: #0041e8;
|
||||
--chkfg: #fff;
|
||||
border-color: #000 !important;
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.checkbox-success:checked,
|
||||
.checkbox-success[aria-checked="true"] {
|
||||
background-color: #0041e8;
|
||||
border-color: #0041e8 !important;
|
||||
}
|
||||
|
||||
.radio {
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
}
|
||||
|
||||
.box-note {
|
||||
position: relative;
|
||||
i {
|
||||
cursor: pointer;
|
||||
}
|
||||
.content {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
top: 6px;
|
||||
width: 250px;
|
||||
display: none;
|
||||
font-size: 12px;
|
||||
background: #e4b200;
|
||||
color: #fff;
|
||||
padding: 10px;
|
||||
box-shadow: 0px 1px 1px 0px #00000026;
|
||||
border-radius: 6px;
|
||||
z-index: 9;
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -14px;
|
||||
top: 0;
|
||||
width: 20px;
|
||||
height: 15px;
|
||||
clip-path: polygon(0 0, 100% 100%, 100% 0);
|
||||
background: #e4b200;
|
||||
border-radius: 5px 0 0 0;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
.content {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order-detail-page .select2-container {
|
||||
width: 100% !important;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#overlay {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
z-index: 999;
|
||||
display: none;
|
||||
&.active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.status-notificatiom {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: #fff;
|
||||
width: 550px;
|
||||
height: 240px;
|
||||
box-shadow: 0px 1px 1px 0px #0000001a;
|
||||
border-radius: 15px;
|
||||
display: none;
|
||||
z-index: 9999;
|
||||
&.active {
|
||||
display: block;
|
||||
}
|
||||
.icon-close {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: #ececec;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.content {
|
||||
height: 100%;
|
||||
}
|
||||
.fa-check {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
background: #52c41a;
|
||||
color: #fff;
|
||||
font-size: 50px;
|
||||
text-align: center;
|
||||
line-height: 70px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
b {
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
margin-top: 5px;
|
||||
}
|
||||
p {
|
||||
color: #00000073;
|
||||
}
|
||||
.fa-triangle-exclamation {
|
||||
font-size: 70px;
|
||||
color: #ffc53d;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
a {
|
||||
color: #0041e8;
|
||||
}
|
||||
.btn {
|
||||
color: #fff;
|
||||
padding: 0;
|
||||
}
|
||||
select {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d8d8d8;
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.12);
|
||||
height: 32px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0 0 0 5px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.icons {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 1px solid #ececec;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.icon-edit {
|
||||
background-color: #f5f7ff;
|
||||
background-position: -108px -82px;
|
||||
}
|
||||
.icon-delete {
|
||||
background-position: -145px -82px;
|
||||
}
|
||||
.icon-view {
|
||||
background-position: -180px -82px;
|
||||
}
|
||||
.icon-feature {
|
||||
background-position: -255px -82px;
|
||||
}
|
||||
}
|
||||
.home-report-holder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.not-border td {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.not-padding td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 2560px) {
|
||||
body {
|
||||
font-size: 18px;
|
||||
}
|
||||
.text-custom-14 {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.text-custom-16 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
.text-custom-22 {
|
||||
font-size: 22px !important;
|
||||
}
|
||||
.text-custom-28 {
|
||||
font-size: 28px !important;
|
||||
}
|
||||
.admin-menu-container {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.template-edit {
|
||||
.tab-edit {
|
||||
ul {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
li {
|
||||
list-style: inside;
|
||||
line-height: 24px;
|
||||
color: #6b7280;
|
||||
&.active {
|
||||
color: #0041e8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.monaco-editor .margin {
|
||||
border: 1px solid #ececec;
|
||||
}
|
||||
|
||||
.monaco-editor .margin-view-overlays .line-numbers {
|
||||
text-align: center !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
179
assets/script/main.js
Normal file
@@ -0,0 +1,179 @@
|
||||
class LayoutCustomizer {
|
||||
constructor() {
|
||||
this.defaultConfig = {
|
||||
theme: "system",
|
||||
direction: "ltr",
|
||||
fontFamily: "default",
|
||||
sidebarTheme: "light",
|
||||
fullscreen: false,
|
||||
}
|
||||
const configCache = localStorage.getItem("__NEXUS_CONFIG_v3.0__")
|
||||
if (configCache) {
|
||||
this.config = JSON.parse(configCache)
|
||||
} else {
|
||||
this.config = { ...this.defaultConfig }
|
||||
}
|
||||
this.html = document.documentElement
|
||||
this.sidebar = document.getElementById("layout-sidebar")
|
||||
|
||||
window.config = this.config
|
||||
}
|
||||
|
||||
updateTheme = () => {
|
||||
localStorage.setItem("__NEXUS_CONFIG_v3.0__", JSON.stringify(this.config))
|
||||
|
||||
if (this.config.theme === "system") {
|
||||
this.html.removeAttribute("data-theme")
|
||||
} else {
|
||||
this.html.setAttribute("data-theme", this.config.theme)
|
||||
}
|
||||
|
||||
if (this.sidebar) {
|
||||
if (
|
||||
this.config.sidebarTheme === "dark" &&
|
||||
["light", "contrast"].includes(this.config.theme)
|
||||
) {
|
||||
this.sidebar.setAttribute("data-theme", this.config.sidebarTheme)
|
||||
} else {
|
||||
this.sidebar.removeAttribute("data-theme")
|
||||
}
|
||||
}
|
||||
|
||||
this.html.setAttribute("data-sidebar-theme", this.config.sidebarTheme)
|
||||
this.html.dir = this.config.direction
|
||||
|
||||
if (this.config.fullscreen) {
|
||||
this.html.setAttribute("data-fullscreen", "")
|
||||
} else {
|
||||
this.html.removeAttribute("data-fullscreen")
|
||||
}
|
||||
|
||||
if (this.config.fontFamily !== "default") {
|
||||
this.html.setAttribute("data-font-family", config.fontFamily)
|
||||
} else {
|
||||
this.html.removeAttribute("data-font-family")
|
||||
}
|
||||
}
|
||||
|
||||
initEventListener = () => {
|
||||
const themeControls = document.querySelectorAll("[data-theme-control]")
|
||||
themeControls.forEach((control) => {
|
||||
control.addEventListener("click", () => {
|
||||
let theme = control.getAttribute("data-theme-control") ?? "light"
|
||||
if (theme === "toggle") {
|
||||
theme = this.config.theme === "light" ? "dark" : "light"
|
||||
}
|
||||
this.config.theme = theme
|
||||
this.updateTheme()
|
||||
})
|
||||
})
|
||||
|
||||
const sidebarThemeControls = document.querySelectorAll("[data-sidebar-theme-control]")
|
||||
sidebarThemeControls.forEach((control) => {
|
||||
control.addEventListener("click", () => {
|
||||
this.config.sidebarTheme =
|
||||
control.getAttribute("data-sidebar-theme-control") ?? "light"
|
||||
this.updateTheme()
|
||||
})
|
||||
})
|
||||
|
||||
const fontFamilyControls = document.querySelectorAll("[data-font-family-control]")
|
||||
fontFamilyControls.forEach((control) => {
|
||||
control.addEventListener("click", () => {
|
||||
this.config.fontFamily =
|
||||
control.getAttribute("data-font-family-control") ?? "default"
|
||||
this.updateTheme()
|
||||
})
|
||||
})
|
||||
|
||||
const dirControls = document.querySelectorAll("[data-dir-control]")
|
||||
dirControls.forEach((control) => {
|
||||
control.addEventListener("click", () => {
|
||||
this.config.direction = control.getAttribute("data-dir-control") ?? "ltr"
|
||||
this.updateTheme()
|
||||
})
|
||||
})
|
||||
|
||||
const fullscreenControls = document.querySelectorAll("[data-fullscreen-control]")
|
||||
fullscreenControls.forEach((control) => {
|
||||
control.addEventListener("click", () => {
|
||||
if (document.fullscreenElement != null) {
|
||||
this.config.fullscreen = false
|
||||
document.exitFullscreen()
|
||||
} else {
|
||||
this.config.fullscreen = true
|
||||
this.html.requestFullscreen()
|
||||
}
|
||||
this.updateTheme()
|
||||
})
|
||||
})
|
||||
|
||||
const resetControls = document.querySelectorAll("[data-reset-control]")
|
||||
resetControls.forEach((control) => {
|
||||
control.addEventListener("click", () => {
|
||||
this.config = { ...this.defaultConfig }
|
||||
if (document.fullscreenElement != null) {
|
||||
document.exitFullscreen()
|
||||
}
|
||||
this.updateTheme()
|
||||
})
|
||||
})
|
||||
|
||||
const fullscreenMedia = window.matchMedia("(display-mode: fullscreen)")
|
||||
const fullscreenListener = () => {
|
||||
this.config.fullscreen = fullscreenMedia.matches
|
||||
this.updateTheme()
|
||||
}
|
||||
fullscreenMedia.addEventListener("change", fullscreenListener)
|
||||
fullscreenListener()
|
||||
}
|
||||
|
||||
initLeftmenu = () => {
|
||||
const initMenuActivation = () => {
|
||||
const menuItems = document.querySelectorAll(".sidebar-menu-activation a")
|
||||
let currentURL = window.location.href
|
||||
if (window.location.pathname === "/") {
|
||||
currentURL += "dashboards-ecommerce.html"
|
||||
}
|
||||
menuItems.forEach((item) => {
|
||||
if (item.href === currentURL) {
|
||||
item.classList.add("active")
|
||||
const parentElement1 = item.parentElement.parentElement
|
||||
if (parentElement1.classList.contains("collapse-content")) {
|
||||
const inputElement1 = parentElement1.parentElement.querySelector("input")
|
||||
if (inputElement1) {
|
||||
inputElement1.checked = true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const scrollToActiveMenu = () => {
|
||||
const simplebarEl = document.querySelector("#layout-sidebar [data-simplebar]")
|
||||
const activatedItem = document.querySelector("#layout-sidebar .menu a.active")
|
||||
if (simplebarEl && activatedItem) {
|
||||
const simplebar = new SimpleBar(simplebarEl)
|
||||
const top = activatedItem?.getBoundingClientRect().top
|
||||
if (top && top !== 0) {
|
||||
simplebar.getScrollElement().scrollTo({ top: top - 300, behavior: "smooth" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initMenuActivation()
|
||||
scrollToActiveMenu()
|
||||
}
|
||||
|
||||
afterInit = () => {
|
||||
this.initEventListener()
|
||||
this.initLeftmenu()
|
||||
}
|
||||
|
||||
init = () => {
|
||||
this.updateTheme()
|
||||
window.addEventListener("DOMContentLoaded", this.afterInit)
|
||||
}
|
||||
}
|
||||
|
||||
new LayoutCustomizer().init()
|
||||
16451
assets/script/style.css
Normal file
@@ -10,8 +10,28 @@ function debug_var($input) {
|
||||
}
|
||||
|
||||
function init_autoload(){
|
||||
$classLoader = require_once ROOT_DIR . '/package/vendor/autoload.php';
|
||||
$classLoader->add("Hura8", ROOT_DIR . '/inc' );
|
||||
$candidates = [
|
||||
ROOT_DIR . '/package/vendor/autoload.php',
|
||||
ROOT_DIR . '/vendor/autoload.php'
|
||||
];
|
||||
|
||||
$autoload = null;
|
||||
foreach ($candidates as $file) {
|
||||
if (file_exists($file)) {
|
||||
$autoload = $file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$autoload) {
|
||||
$paths = implode("', '", $candidates);
|
||||
trigger_error("Composer autoload not found. Expected one of: '" . $paths . "'.\nRun 'composer install' in the 'package' directory (or the project root) to install dependencies.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
$classLoader = require_once $autoload;
|
||||
if (is_object($classLoader) && method_exists($classLoader, 'add')) {
|
||||
$classLoader->add("Hura8", ROOT_DIR . '/inc');
|
||||
}
|
||||
|
||||
return $classLoader;
|
||||
}
|
||||
|
||||
212
src/Hura/App.php
Normal file
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
namespace Hura;
|
||||
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Template as LiquidTemplate;
|
||||
|
||||
class App
|
||||
{
|
||||
|
||||
protected $tpl_path = ROOT_DIR . "/template";
|
||||
|
||||
protected $current_route_info = [
|
||||
"module" => 'home',
|
||||
"view" => 'home',
|
||||
"url" => '/admin/product'
|
||||
];
|
||||
|
||||
protected $data = [];
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// start the app
|
||||
public function start() {
|
||||
$this->getRouter();
|
||||
$this->getData();
|
||||
echo $this->renderModule();
|
||||
}
|
||||
|
||||
|
||||
protected function getRouter() {
|
||||
/*$route = [
|
||||
"module" => (isset($_REQUEST['module'])) ? $_REQUEST['module'] : 'home',
|
||||
"view" => (isset($_REQUEST['view'])) ? $_REQUEST['view'] : 'home',
|
||||
];*/
|
||||
|
||||
$objRouter = new Router();
|
||||
$this->current_route_info = $objRouter->getRouting();
|
||||
}
|
||||
|
||||
|
||||
protected function getData() {
|
||||
$module_file = $this->getModuleFile();
|
||||
|
||||
if(!file_exists($module_file)) {
|
||||
// print_r($this->current_route_info);
|
||||
die('Page '. $module_file .' not found!');
|
||||
}
|
||||
|
||||
$data = include_once $module_file;
|
||||
|
||||
$global_data = [
|
||||
"module" => $this->current_route_info['module'],
|
||||
"view" => $this->current_route_info['view'],
|
||||
"url" => $this->current_route_info['url'],
|
||||
"query" => $this->current_route_info['query'],
|
||||
];
|
||||
|
||||
$this->data = array(
|
||||
'global' => $global_data,
|
||||
// module-specific data, just print {{ page }} to see all available data for the current page!!!
|
||||
'page' => (is_array($data)) ? $data : [],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
protected function getModuleFile(): string
|
||||
{
|
||||
return SRC_DIR . DIRECTORY_SEPARATOR . join(DIRECTORY_SEPARATOR, [
|
||||
"pages",
|
||||
$this->current_route_info["module"],
|
||||
str_replace("-", "_", $this->current_route_info["view"]).".php"
|
||||
]) ;
|
||||
}
|
||||
|
||||
|
||||
protected function renderModule() {
|
||||
|
||||
if(!$this->current_route_info['module'] || !$this->current_route_info['view']) {
|
||||
die("Module not exist");
|
||||
}
|
||||
|
||||
$template_file_path = $this->tpl_path ."/". $this->current_route_info['module'];
|
||||
$template_file_name = str_replace("-", '_', $this->current_route_info['view']).".html";
|
||||
$template_file_full_path = $template_file_path."/".$template_file_name;
|
||||
|
||||
//check exist
|
||||
if(!@file_exists( $template_file_full_path)) {
|
||||
// attempt to auto create first
|
||||
// todo: this MUST BE TURNED OFF IN PRODUCTION, else many files will be created unintentionally
|
||||
$module_file = $this->getModuleFile();
|
||||
// only create if module file exist
|
||||
if(file_exists($module_file) && !$this->autoCreateTplFile( $template_file_path, $template_file_name )) {
|
||||
die("Please manually create template file at: ". $template_file_full_path);
|
||||
}
|
||||
}
|
||||
|
||||
$theme_file_path = $this->tpl_path ."/theme.html";
|
||||
if( ! @file_exists( $theme_file_path)) {
|
||||
die("Theme not exist (please create): " . $theme_file_path);
|
||||
}
|
||||
|
||||
$theme_content = @file_get_contents( $theme_file_path );
|
||||
$module_content = @file_get_contents( $template_file_full_path );
|
||||
|
||||
$page_content_to_parse = preg_replace([
|
||||
"/{{(\s+)?page_content(\s+)?}}/"
|
||||
], [
|
||||
$module_content,
|
||||
] , $theme_content );
|
||||
|
||||
|
||||
return $this->parse(
|
||||
$page_content_to_parse,
|
||||
$template_file_path
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
protected function autoCreateTplFile($file_path, $file_name) : bool {
|
||||
// create dir if not exist
|
||||
if(!file_exists($file_path)) {
|
||||
if(!mkdir($file_path, 0755, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!file_exists($file_path)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//create file
|
||||
$file_full_path = $file_path . "/". $file_name;
|
||||
@file_put_contents($file_full_path, $file_full_path);
|
||||
|
||||
return file_exists($file_full_path);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 2 ways to render a html template
|
||||
* 1. Use $html_to_parse, which requires no dependencies
|
||||
* Example:
|
||||
* Template::parse(null, 'Age = {{age}}', ['age' => 21], '');
|
||||
*
|
||||
* 2. Use $template_file_path, which requires dependency $path
|
||||
* Template::parse(Template::$setting_template_path, null, ['age' => 21], 'email/test');
|
||||
* */
|
||||
protected function parse($html_to_parse = null, $template_file_path = '') {
|
||||
|
||||
if(!$html_to_parse && !$template_file_path) {
|
||||
return 'Nothing to parse';
|
||||
}
|
||||
|
||||
//output to html
|
||||
Liquid::set('INCLUDE_SUFFIX', 'html');
|
||||
Liquid::set('INCLUDE_PREFIX', '');
|
||||
//Liquid::set('INCLUDE_ALLOW_EXT', true);
|
||||
Liquid::set('ESCAPE_BY_DEFAULT', false);
|
||||
|
||||
$enable_cache = false; // default = true, turn this on-off to disable cache while working on local mode
|
||||
//$enable_cache = true;
|
||||
|
||||
//catch exception and print friendly notice
|
||||
try {
|
||||
|
||||
$objLiquidTemplate = new LiquidTemplate( $this->tpl_path );
|
||||
$objLiquidTemplate->registerFilter( TemplateFilter::class );
|
||||
if($enable_cache) {
|
||||
/*$objLiquidTemplate->setCache(new File([
|
||||
'cache_dir' => self::$cache_dir
|
||||
]));*/
|
||||
}
|
||||
|
||||
if($html_to_parse) {
|
||||
$objLiquidTemplate->parse($html_to_parse);
|
||||
}elseif ($template_file_path) {
|
||||
$objLiquidTemplate->parseFile($template_file_path);
|
||||
}
|
||||
|
||||
return $objLiquidTemplate->render($this->data);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$result = [];
|
||||
do {
|
||||
//printf("%s:%d %s (%d) [%s]\n", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
|
||||
//echo $e->getTraceAsString();
|
||||
//$code = $e->getTrace()[0]['args'][0];
|
||||
//if(is_array($code)) $code = serialize($code);
|
||||
$result[] = sprintf(
|
||||
"
|
||||
Lỗi code trong file template html: <br />
|
||||
- Chi tiết lỗi: %s<br />
|
||||
- File template: %s<br />
|
||||
- Hướng dẫn xử lý: Tách từng phần html để kiểm tra và nhấn F5 mỗi lần. Nếu không xuất hiện thông báo này nghĩa là phần đó không tạo lỗi
|
||||
",
|
||||
$e->getMessage(),
|
||||
substr($template_file_path, strrpos($template_file_path, DIRECTORY_SEPARATOR) + 1 ),
|
||||
//static::$cache_dir
|
||||
);
|
||||
|
||||
} while($e = $e->getPrevious());
|
||||
|
||||
return join(" - ", $result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
78
src/Hura/Router.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Hura;
|
||||
|
||||
|
||||
class Router {
|
||||
|
||||
private array $path_config = [];
|
||||
|
||||
public function __construct() {
|
||||
$path_config_file = CONFIG_DIR . '/routing.php';
|
||||
$this->path_config = require $path_config_file;
|
||||
}
|
||||
|
||||
// url: asdas.php?para1=value1
|
||||
public function getRouting(): array
|
||||
{
|
||||
$parsed = Url::parse($_SERVER['REQUEST_URI']); //abc/product?param1=12¶m2=value2
|
||||
//print_r($parsed);
|
||||
|
||||
// home
|
||||
if($parsed['path'] == '/') {
|
||||
return [
|
||||
'module' => preg_replace("/[^a-z0-9_\-]/i","", getRequest('module', 'home')),
|
||||
'view' => preg_replace("/[^a-z0-9_\-]/i","", getRequest('view', 'home')),
|
||||
'view_id'=> 0,
|
||||
'query' => $parsed['query'],
|
||||
'url' => $_SERVER['REQUEST_URI'],
|
||||
];
|
||||
}
|
||||
|
||||
// check match pattern in $this->path_config
|
||||
foreach ($this->path_config as $_config => $_route ) {
|
||||
if(preg_match("{^".$_config."$}", $parsed['path'], $match )) {
|
||||
|
||||
if(isset($_route['query']) && is_array($_route['query'])) {
|
||||
$_route['query'] = array_merge($_route['query'], $parsed['query']);
|
||||
}else{
|
||||
$_route['query'] = $parsed['query'];
|
||||
}
|
||||
|
||||
return array_merge([
|
||||
'path' => $parsed['path'],
|
||||
'match' => $match,
|
||||
], $_route);
|
||||
}
|
||||
}
|
||||
|
||||
// check database
|
||||
|
||||
// else error
|
||||
return [
|
||||
'module' => "error" ,
|
||||
'view' => "error" ,
|
||||
'view_id' => "not_found",
|
||||
'query' => $parsed['query'],
|
||||
'url' => $_SERVER['REQUEST_URI'],
|
||||
];
|
||||
|
||||
|
||||
// auto parse path base on convention: admin/module/view/view_id
|
||||
/* $ele = explode("/", $parsed['path']);
|
||||
|
||||
$module = $ele[2] ?? 'home';
|
||||
$view = isset($ele[3]) ? $ele[3] : getRequest('view', 'home');
|
||||
$view_id = isset($ele[4]) ? $ele[4] : getRequest('id', 'view_id');
|
||||
|
||||
// else error
|
||||
return [
|
||||
'module' => preg_replace("/[^a-z0-9_\-]/i","", $module ) ,
|
||||
'view' => preg_replace("/[^a-z0-9_\-]/i","", $view ) ,
|
||||
'view_id' => preg_replace("/[^a-z0-9_]/i","", $view_id ),
|
||||
'query' => $parsed['query'],
|
||||
'url' => $_SERVER['REQUEST_URI'],
|
||||
];*/
|
||||
}
|
||||
|
||||
}
|
||||
256
src/Hura/TemplateFilter.php
Normal file
@@ -0,0 +1,256 @@
|
||||
<?php
|
||||
|
||||
namespace Hura;
|
||||
|
||||
/**
|
||||
* Before attempting to make new filter, see built-in filters: https://shopify.github.io/liquid/
|
||||
*/
|
||||
class TemplateFilter
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function to_json(array $array) {
|
||||
return \json_encode($array);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create array of ['key' => '', 'value' => ] from [key1 => value1, key2=>value2, ...]
|
||||
*
|
||||
* @param array $key_values [key1 => value1, key2=>value2]
|
||||
*
|
||||
* @return array [['key' => 'key1', 'value' => value1], ['key' => 'key2', 'value' => value2]]
|
||||
*/
|
||||
public static function to_array(array $key_values) {
|
||||
$result = [];
|
||||
foreach ($key_values as $key => $value) {
|
||||
$result[] = [
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* split a s by line to create array
|
||||
*
|
||||
* @param string $txt
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_line($txt) {
|
||||
|
||||
if(is_array($txt)) {
|
||||
return $txt;
|
||||
}
|
||||
|
||||
$txt = trim($txt);
|
||||
if( ! $txt ) return [];
|
||||
|
||||
return preg_split("/\n/", $txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement strlen
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function length($str) {
|
||||
return strlen(trim($str));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make number easier to read: 1000 -> 1.000
|
||||
*
|
||||
* @param string $number
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function format_number($number) {
|
||||
if(!$number) return '';
|
||||
$number = floatval($number);
|
||||
|
||||
$number = number_format($number, 0, ",", "."); //Vietnamese format with decimals by a coma
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
public static function format_price($p_price, $currency = ''){
|
||||
if(!$p_price) return '';
|
||||
if(!$currency) $currency = (defined("DEFAULT_CURRENCY")) ? DEFAULT_CURRENCY : "vnd";
|
||||
//if(is_string($p_price)) return 0;
|
||||
if($currency == 'usd') {
|
||||
return number_format($p_price,2,".",",");
|
||||
}else {
|
||||
return number_format($p_price,0,",",".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Description: get the shop's full asset url for template's images/js/css
|
||||
*
|
||||
* //Returns the URL of a file in the "assets" folder of a theme.
|
||||
// {{ 'shop.css' | asset_url : 'arg1', 'arg2' ...}} -> //cdn.shopify.com/s/files/1/0087/0462/t/394/assets/shop.css?28253
|
||||
*
|
||||
* @param string $file_name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function asset_url($file_name = '')
|
||||
{
|
||||
if( !$file_name ) return '';
|
||||
|
||||
$file_ext = strtolower(strrchr($file_name, "."));
|
||||
|
||||
// script tags
|
||||
if(in_array($file_ext, ['.js', '.css'])) return TEMPLATE_ASSET . "/script/" . $file_name;
|
||||
|
||||
// default image
|
||||
return TEMPLATE_ASSET . "/images/" . $file_name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Description: construct a full html tag for images/js/css file
|
||||
*
|
||||
* @param string $file_path domain.com/static/style.css?v=3.1.1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function script_tag($file_path) {
|
||||
if( ! $file_path ) return '';
|
||||
|
||||
//check for ?
|
||||
if(strpos($file_path, "?") !== false) {
|
||||
$file_ext = str_replace(strrchr($file_path, "?"), "", $file_path);
|
||||
$file_ext = strtolower(strrchr($file_ext, "."));
|
||||
} else {
|
||||
$file_ext = strtolower(strrchr($file_path, "."));
|
||||
}
|
||||
|
||||
$tag_config = [
|
||||
".css" => "<link rel=\"stylesheet\" href=\"".$file_path."\" type=\"text/css\" />",
|
||||
".js" => "<script src=\"".$file_path."\"></script>",
|
||||
".jpg" => "<img src=\"".$file_path."\" alt=\"n\"/>",
|
||||
".jpeg" => "<img src=\"".$file_path."\" alt=\"\"/>",
|
||||
".gif" => "<img src=\"".$file_path."\" alt=\"\"/>",
|
||||
".png" => "<img src=\"".$file_path."\" alt=\"\"/>",
|
||||
];
|
||||
|
||||
return (isset($tag_config[$file_ext])) ? $tag_config[$file_ext] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {{ product_info.main_image | img_url: '300x300' }} => https://cdn.shopify.com/s/files/1/1183/1048/products/boat-shoes_300x300.jpeg?1459175177
|
||||
* @param string $full_path
|
||||
* @param string $modifier
|
||||
* $modifier:
|
||||
* - must be in format: NumberxNumber or Numberx where Number must within 10 -> 9999
|
||||
* - or be one of these: small | medium | large
|
||||
* @return string
|
||||
*/
|
||||
public static function img_url($full_path, $modifier)
|
||||
{
|
||||
$clean_modifier = ($modifier) ? trim($modifier) : "";
|
||||
|
||||
// verify $modifier
|
||||
// must be in format: NumberxNumber or Numberx where Number must within 10 -> 9999
|
||||
if($clean_modifier
|
||||
&& !preg_match("/^[0-9]{2,4}x([0-9]{2,4})?$/i", $clean_modifier)
|
||||
&& !in_array($clean_modifier, ["small", "medium", "large"])
|
||||
) {
|
||||
$clean_modifier = "";
|
||||
}
|
||||
|
||||
// return if no valid modifier
|
||||
if( ! $clean_modifier ) {
|
||||
return $full_path;
|
||||
}
|
||||
|
||||
$last_dot_position = strrpos($full_path, ".");
|
||||
if( ! $last_dot_position ) return $full_path . $clean_modifier;
|
||||
|
||||
return join("", [
|
||||
substr($full_path, 0, $last_dot_position),
|
||||
"_",
|
||||
$clean_modifier,
|
||||
substr($full_path, $last_dot_position)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* //Returns the URL of a file in the Files page of the admin.
|
||||
//{{ 'size-chart.pdf' | file_url }} -> //cdn.shopify.com/s/files/1/0087/0462/files/size-chart.pdf?28261
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function file_url($input, $string)
|
||||
{
|
||||
return strtoupper($input) . " = " . $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* //Returns the asset URL of an image in the Files page of the admin. file_img_url accepts an image size parameter.
|
||||
//{{ 'logo.png' | file_img_url: '1024x768' }} -> //cdn.shopify.com/s/files/1/0246/0527/files/logo_1024x768.png?42
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function file_img_url($input, $string)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show all content of a variable, useful for template development
|
||||
*
|
||||
* @param string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function print_r($input)
|
||||
{
|
||||
@ob_start();
|
||||
print_r($input);
|
||||
$content = ob_get_contents();
|
||||
@ob_end_clean();
|
||||
|
||||
return join("\r", ['<!-- print_r debug content: ', $content, '-->']) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all content of a variable, useful for template development
|
||||
*
|
||||
* @param string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function show_var($input)
|
||||
{
|
||||
@ob_start();
|
||||
print_r($input);
|
||||
$content = ob_get_contents();
|
||||
@ob_end_clean();
|
||||
|
||||
return join("\r", ['<textarea cols="80" rows="20">', $content, '</textarea>']) ;
|
||||
}
|
||||
}
|
||||
47
src/Hura/Url.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Hura;
|
||||
|
||||
class Url
|
||||
{
|
||||
|
||||
public static function parse($url) {
|
||||
$data = parse_url($url);
|
||||
$default = [
|
||||
'scheme' => '',
|
||||
'host' => '',
|
||||
'port' => '',
|
||||
'user' => '',
|
||||
'pass' => '',
|
||||
'path' => '',
|
||||
'query' => [],
|
||||
'fragment' => '',
|
||||
];
|
||||
foreach ($data as $key => $value) {
|
||||
if(isset($default[$key])) {
|
||||
$default[$key] = ($key == 'query') ? self::parsedQuery($value) : $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
public static function parsedQuery($query = '') {
|
||||
if(!$query) return [];
|
||||
$result = [];
|
||||
$parts = explode("&", $query);
|
||||
|
||||
foreach ($parts as $part) {
|
||||
$el = explode("=", $part);
|
||||
if(sizeof($el) != 2) continue;
|
||||
|
||||
$cleaned_key = preg_replace("/[^a-z0-9_\-\.]/i", '', $el[0]);
|
||||
$cleaned_value = preg_replace("/[^a-z0-9_\.\-;&]/i", '', $el[1]);
|
||||
|
||||
$result[$cleaned_key] = $cleaned_value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
45
src/inc/common.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
function debug_var($input) {
|
||||
@ob_start();
|
||||
print_r($input);
|
||||
$content = ob_get_contents();
|
||||
@ob_end_clean();
|
||||
|
||||
echo join("\r", ['<textarea cols="80" rows="20">', $content, '</textarea>']) ;
|
||||
}
|
||||
|
||||
function init_autoload(){
|
||||
$classLoader = require_once ROOT_DIR . '/package/vendor/autoload.php';
|
||||
$classLoader->add("Hura", ROOT_DIR . '/src' );
|
||||
|
||||
return $classLoader;
|
||||
}
|
||||
|
||||
//get current paging id
|
||||
function getPageId(){
|
||||
return getRequestInt('page', 1);
|
||||
}
|
||||
|
||||
function getPageSize($default=10){
|
||||
return getRequestInt('pageSize', $default);
|
||||
}
|
||||
|
||||
//Function to get the post value in submit
|
||||
function getPost($var, $default="", $encode = false, $keep_tag=""){
|
||||
return isset($_POST[$var]) ? $_POST[$var] : $default;
|
||||
}
|
||||
|
||||
//Function to get the INTERGER request value of a variable
|
||||
function getRequestInt($var, $min_value = 0){
|
||||
$request = isset($_REQUEST[$var]) ? (int) $_REQUEST[$var] : (int) $min_value;
|
||||
$request = ($request >= $min_value ) ? $request : $min_value; //if user tampers request parameter
|
||||
return $request;
|
||||
}
|
||||
|
||||
|
||||
//Function to get the request value of a variable
|
||||
function getRequest($var, $default=""){
|
||||
return $_REQUEST[$var] ?? $default;
|
||||
}
|
||||
|
||||
16
src/inc/fun.db.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
use Hura\Database\ConnectDB;
|
||||
use Hura\Database\iConnectDB;
|
||||
|
||||
function create_bind_sql_parameter_from_value_list(array $value_list = [], $data_type = 'int') {
|
||||
$parameterized_ids = join(",", array_map(function (){ return '?'; }, $value_list));
|
||||
$bind_types = array_map(function () use ($data_type){ return ($data_type == 'int') ? 'd' : 's'; }, $value_list);
|
||||
|
||||
return [$parameterized_ids, $bind_types];
|
||||
}
|
||||
|
||||
|
||||
function get_db($db_id ='', $debug=false) : iConnectDB {
|
||||
return ConnectDB::getInstance($db_id, $debug);
|
||||
}
|
||||
@@ -1,299 +1,501 @@
|
||||
<div class="content-holder xl:gap-[16px] 2xl:gap-[10px] grid 2xl:grid-cols-10">
|
||||
<!-- Start: Dashboard Stats Widget -->
|
||||
|
||||
<!-- col-left -->
|
||||
<div class="2xl:col-span-7 grid grid-cols-4 max-[1620px]:gap-[10px] gap-[16px] xl:col-span-10 diagram">
|
||||
|
||||
{% include 'home/components/main_stat' %}
|
||||
|
||||
<div
|
||||
class="bg-white rounded-[10px] shadow-[0px_1px_1px_0px_rgba(0,0,0,0.10)] p-[16px] max-[1620px]:p-[10px] col-span-4">
|
||||
<p class="inline-block text-[20px] text-custom-22 font-bold leading-[36px] mb-[16px] mr-[18px]"> Lịch sử
|
||||
chỉnh
|
||||
sửa </p>
|
||||
|
||||
<a href=""
|
||||
class="group inline-flex items-center px-[15px] mb-[16px] leading-[36px] text-[#0041E8] font-[500] rounded-[4px] bg-[#F5F7FF] hover:bg-[#0041E8] hover:text-white duration-100">
|
||||
<span class="mr-[5px]">Xem danh sách</span>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13" fill="none">
|
||||
<path class="group-hover:fill-[#fff]" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M6.5 1C3.46243 1 1 3.46243 1 6.5C1 9.53757 3.46243 12 6.5 12C9.53757 12 12 9.53757 12 6.5C12 3.46243 9.53757 1 6.5 1ZM0 6.5C0 2.91015 2.91015 0 6.5 0C10.0899 0 13 2.91015 13 6.5C13 10.0899 10.0899 13 6.5 13C2.91015 13 0 10.0899 0 6.5Z"
|
||||
fill="#0041E8" />
|
||||
<path class="group-hover:fill-[#fff]" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M6.52779 4.02767C6.72306 3.83241 7.03964 3.83241 7.2349 4.02767L9.35365 6.14642C9.54891 6.34168 9.54891 6.65827 9.35365 6.85353L7.2349 8.97228C7.03964 9.16754 6.72306 9.16754 6.52779 8.97228C6.33253 8.77702 6.33253 8.46043 6.52779 8.26517L8.29299 6.49998L6.52779 4.73478C6.33253 4.53952 6.33253 4.22293 6.52779 4.02767Z"
|
||||
fill="#0041E8" />
|
||||
<path class="group-hover:fill-[#fff]" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M3.5 6.5C3.5 6.22386 3.72386 6 4 6H9C9.27614 6 9.5 6.22386 9.5 6.5C9.5 6.77614 9.27614 7 9 7H4C3.72386 7 3.5 6.77614 3.5 6.5Z"
|
||||
fill="#0041E8" />
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<div class="2xl:w-full lg:w-full md:w-full overflow-x-auto whitespace-nowrap">
|
||||
<table class="table text-custom-16">
|
||||
<thead align="center" class="bg-[#F6F6F6] font-700 text-[14px] text-[#000]">
|
||||
<td width="50"> STT </td>
|
||||
<td width="265"> Người dùng </td>
|
||||
<td> Nội dung </td>
|
||||
<td width="150"> Thời gian </td>
|
||||
<td width="100"> Xem chi tiết </td>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
{% for item in page.lich_su_chinh_sua %}
|
||||
<tr>
|
||||
<td class="text-center"> {{ item.id }} </td>
|
||||
<td> {{ item.email }} </td>
|
||||
<td> {{ item.content }} </td>
|
||||
<td> {{ item.time }} </td>
|
||||
<td>
|
||||
<a href=""
|
||||
class="block text-center rounded-[4px] border border-[#0041E8] bg-[#F5F7FF] text-[#0041E8] font-[500] leading-[36px] hover:bg-[#0041E8] hover:text-[#fff]">
|
||||
Xem </a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- col-right -->
|
||||
<div class="2xl:col-span-3 xl:col-span-10">
|
||||
<div
|
||||
class="bg-white rounded-[10px] shadow-[0px_1px_1px_0px_rgba(0,0,0,0.10)] p-[16px] max-[1620px]:p-[10px] mb-[16px]">
|
||||
<div id="js-admin-home-tab"
|
||||
class="admin-home-tab rounded-[8px] bg-[#FAFAFA] mb-[16px] text-custom-14 text-[12px] font-[500] flex items-center">
|
||||
<a href="#js-report-most-viewed-products" class="current">Sản phẩm
|
||||
xem
|
||||
nhiều</a>
|
||||
<a href="#js-report-introduce-web"> Web giới thiệu</a>
|
||||
<a href="#js-report-key-word"> Từ khóa</a>
|
||||
<a href="#js-report-article"> Bài viết</a>
|
||||
</div>
|
||||
|
||||
<div class="home-report-holder block" id="js-report-most-viewed-products">
|
||||
<table class="table text-custom-16">
|
||||
<thead class="bg-[#f6f6f6] text-[14px] text-custom-16 font-700 text-[#000]">
|
||||
<td width="50" class="text-center">STT</td>
|
||||
<td>Sản phẩm</td>
|
||||
<td width="75">Lượt xem</td>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-center"> 1 </td>
|
||||
<td> <a href="" class="line-clamp-1"> Laptop Asus ZenBook UX3402VALaptop Asus ZenBook
|
||||
UX3402VALaptop
|
||||
Asus ZenBook UX3402VA </a> </td>
|
||||
<td> 30.000 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="text-center">2
|
||||
<td><a href="" class="line-clamp-1"> Laptop Asus ZenBook UX3402VALaptop Asus ZenBook
|
||||
UX3402VALaptop
|
||||
Asus ZenBook UX3402VA </a>
|
||||
<td>30.000
|
||||
<tr>
|
||||
<td class="text-center">3
|
||||
<td><a href="" class="line-clamp-1"> Laptop Asus ZenBook UX3402VALaptop Asus ZenBook
|
||||
UX3402VALaptop
|
||||
Asus ZenBook UX3402VA </a>
|
||||
<td>30.000
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="home-report-holder" id="js-report-introduce-web">
|
||||
<div class="grid gap-5 lg:grid-cols-2 xl:grid-cols-4">
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body gap-2">
|
||||
<div class="flex items-start justify-between gap-2 text-sm">
|
||||
<div>
|
||||
<p class="font-bold leading-[20px] text-[16px] mb-[15px] text-custom-18">Truy cập website</p>
|
||||
|
||||
<div>
|
||||
<div class="flex" id="devices">
|
||||
<label class="flex items-center me-4 cursor-pointer">
|
||||
<input id="web_1" type="checkbox" value="web_1" class="checkbox checkbox-success">
|
||||
<span for="web_1" class="text-custom-16 label-text ml-[10px]">Web 1</span>
|
||||
</label>
|
||||
|
||||
<label class="flex items-center me-4 cursor-pointer">
|
||||
<input id="web_2" type="checkbox" value="web_2" class="checkbox checkbox-success">
|
||||
<span for="web_2" class="label-text ml-[10px]">Web 2</span>
|
||||
</label>
|
||||
|
||||
<label class="flex items-center me-4 cursor-pointer">
|
||||
<input id="web_3" type="checkbox" value="web_3" class="checkbox checkbox-success">
|
||||
<span for="web_3" class="label-text ml-[10px]">Web 3</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Donut Chart -->
|
||||
<div class="py-6" id="js-introduce-web-chart"></div>
|
||||
|
||||
<div
|
||||
class="grid grid-cols-1 items-center border-gray-200 border-t dark:border-gray-700 justify-between">
|
||||
<div class="flex justify-between items-center pt-5">
|
||||
<select>
|
||||
<option value=""> Last 7 days </option>
|
||||
<option value=""> Yesterday </option>
|
||||
<option value=""> Today </option>
|
||||
<option value=""> Last 7 days </option>
|
||||
<option value=""> Last 30 days </option>
|
||||
<option value=""> Last 90 days </option>
|
||||
</select>
|
||||
<a href="#"
|
||||
class="uppercase text-sm font-semibold inline-flex items-center rounded-lg text-blue-600 hover:text-blue-700 dark:hover:text-blue-500 hover:bg-gray-100 dark:hover:bg-gray-700 dark:focus:ring-gray-700 dark:border-gray-700 px-3 py-2">
|
||||
Traffic analysis
|
||||
<svg class="w-2.5 h-2.5 ms-1.5 rtl:rotate-180" aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2" d="m1 9 4-4-4-4" />
|
||||
</svg>
|
||||
</a>
|
||||
<p class="text-base-content/80 font-medium">
|
||||
Doanh thu
|
||||
</p>
|
||||
<div class="mt-3 flex items-center gap-2">
|
||||
<p class="inline text-2xl font-semibold">
|
||||
$587.54
|
||||
</p>
|
||||
<div class="badge badge-soft badge-success badge-sm gap-0.5 px-1 font-medium">
|
||||
<span class="iconify lucide--arrow-up size-3.5"></span>
|
||||
10.8%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="home-report-holder" id="js-report-key-word">
|
||||
<a href=""
|
||||
class="inline-block text-[#9E9E9E] font-[500] leading-[20px] p-[8px] rounded-[4px] border-[#9E9E9E] border border-dashed m-[0_6px_6px_0] hover:bg-[#0041E8] hover:text-[#fff] hover:border-[#0041E8] duration-100">
|
||||
Laptop, Máy Tính Xách Tay
|
||||
</a>
|
||||
|
||||
<a href=""
|
||||
class="inline-block text-[#9E9E9E] font-[500] leading-[20px] p-[8px] rounded-[4px] border-[#9E9E9E] border border-dashed m-[0_6px_6px_0] hover:bg-[#0041E8] hover:text-[#fff] hover:border-[#0041E8] duration-100">
|
||||
Máy Tính Bảng </a><a href=""
|
||||
class="inline-block text-[#9E9E9E] font-[500] leading-[20px] p-[8px] rounded-[4px] border-[#9E9E9E] border border-dashed m-[0_6px_6px_0] hover:bg-[#0041E8] hover:text-[#fff] hover:border-[#0041E8] duration-100">
|
||||
Điện thoại iPhone </a><a href=""
|
||||
class="inline-block text-[#9E9E9E] font-[500] leading-[20px] p-[8px] rounded-[4px] border-[#9E9E9E] border border-dashed m-[0_6px_6px_0] hover:bg-[#0041E8] hover:text-[#fff] hover:border-[#0041E8] duration-100">
|
||||
Máy Đọc Sách </a><a href=""
|
||||
class="inline-block text-[#9E9E9E] font-[500] leading-[20px] p-[8px] rounded-[4px] border-[#9E9E9E] border border-dashed m-[0_6px_6px_0] hover:bg-[#0041E8] hover:text-[#fff] hover:border-[#0041E8] duration-100">
|
||||
Macbook </a><a href=""
|
||||
class="inline-block text-[#9E9E9E] font-[500] leading-[20px] p-[8px] rounded-[4px] border-[#9E9E9E] border border-dashed m-[0_6px_6px_0] hover:bg-[#0041E8] hover:text-[#fff] hover:border-[#0041E8] duration-100">
|
||||
Linh kiện máy tính </a>
|
||||
</div>
|
||||
|
||||
<div class="home-report-holder" id="js-report-article">
|
||||
<table class="table text-custom-16">
|
||||
<thead class="bg-[#F6F6F6] text-[14px] font-700 text-[#000]">
|
||||
<td width="50" class="text-center">STT</td>
|
||||
<td>Bài viết</td>
|
||||
<td width="75">Lượt xem</td>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-center"> 1 </td>
|
||||
<td> <a href="" class="line-clamp-1"> Laptop Asus ZenBook UX3402VALaptop Asus ZenBook
|
||||
UX3402VALaptop
|
||||
Asus ZenBook UX3402VA </a> </td>
|
||||
<td> 30.000 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="text-center">2
|
||||
<td><a href="" class="line-clamp-1"> Laptop Asus ZenBook UX3402VALaptop Asus ZenBook
|
||||
UX3402VALaptop
|
||||
Asus ZenBook UX3402VA </a>
|
||||
<td>30.000
|
||||
<tr>
|
||||
<td class="text-center">3
|
||||
<td><a href="" class="line-clamp-1"> Laptop Asus ZenBook UX3402VALaptop Asus ZenBook
|
||||
UX3402VALaptop
|
||||
Asus ZenBook UX3402VA </a>
|
||||
<td>30.000
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-[10px] shadow-[0px_1px_1px_0px_rgba(0,0,0,0.10)] p-[16px] max-[1620px]:p-[10px]">
|
||||
<div class="flex flex-wrap items-center justify-between mb-[10px]">
|
||||
<p class="font-[500] text-[14px] text-custom-16">Ghi nhắc việc làm cá nhân</p>
|
||||
|
||||
<div
|
||||
class="relative rounded-[4px] max-w-[120px] bg-white leading-[32px] border border-[#d8d8d8] shadow-[0px_2px_4px_0px_rgba(0,0,0,0.12)] p-[0px_9px_0px_30px]">
|
||||
<svg class="absolute top-[8px] left-[9px]" xmlns="http://www.w3.org/2000/svg" width="13" height="14"
|
||||
viewBox="0 0 13 14" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M1.90909 2.54545C1.55764 2.54545 1.27273 2.83036 1.27273 3.18181V12.0909C1.27273 12.4424 1.55764 12.7273 1.90909 12.7273H10.8182C11.1696 12.7273 11.4545 12.4424 11.4545 12.0909V3.18181C11.4545 2.83036 11.1696 2.54545 10.8182 2.54545H1.90909ZM0 3.18181C0 2.12745 0.854729 1.27272 1.90909 1.27272H10.8182C11.8725 1.27272 12.7273 2.12745 12.7273 3.18181V12.0909C12.7273 13.1453 11.8725 14 10.8182 14H1.90909C0.854729 14 0 13.1453 0 12.0909V3.18181Z"
|
||||
fill="#7E7E7E" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M8.90907 0C9.26052 0 9.54543 0.28491 9.54543 0.636364V3.18182C9.54543 3.53327 9.26052 3.81818 8.90907 3.81818C8.55761 3.81818 8.27271 3.53327 8.27271 3.18182V0.636364C8.27271 0.28491 8.55761 0 8.90907 0Z"
|
||||
fill="#7E7E7E" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M3.81813 0C4.16958 0 4.45449 0.28491 4.45449 0.636364V3.18182C4.45449 3.53327 4.16958 3.81818 3.81813 3.81818C3.46667 3.81818 3.18176 3.53327 3.18176 3.18182V0.636364C3.18176 0.28491 3.46667 0 3.81813 0Z"
|
||||
fill="#7E7E7E" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M0 5.72728C0 5.37582 0.28491 5.09091 0.636364 5.09091H12.0909C12.4424 5.09091 12.7273 5.37582 12.7273 5.72728C12.7273 6.07873 12.4424 6.36364 12.0909 6.36364H0.636364C0.28491 6.36364 0 6.07873 0 5.72728Z"
|
||||
fill="#7E7E7E" />
|
||||
</svg>
|
||||
|
||||
<input type="text" value="23/11/2023" class="w-[100%] h-[32px]">
|
||||
<div class="bg-base-200 rounded-box flex items-center p-2">
|
||||
<span class="iconify lucide--circle-dollar-sign size-5"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="flex items-center justify-between mb-[10px]">
|
||||
<input type="text" placeholder="Nhập việc cần làm của bạn"
|
||||
class="border border-[#ECECEC] h-[36px] mr-[10px] p-[0px_12px] rounded-[4px] w-[calc(100%-87px)]">
|
||||
<button type="button" class="bg-[#0041E8] font-[500] h-[36px] rounded-[4px] text-[#fff] w-[77px]">Tạo
|
||||
mới</button>
|
||||
</form>
|
||||
|
||||
<div class="home-todo-list overflow-x-auto 2xl:whitespace-normal sm:whitespace-nowrap">
|
||||
<table class="table text-custom-16">
|
||||
<thead class="bg-[#F6F6F6] text-[14px] text-[#000] font-700">
|
||||
<td class="text-center"> STT </td>
|
||||
<td> Nội dung </td>
|
||||
<td> Hết hạn </td>
|
||||
<td class="w-[100px]"> Trạng thái </td>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="text-center"> 2 </td>
|
||||
<td> Sửa trang chủ websiteLaptoptcc </td>
|
||||
<td> 28/11/2023 </td>
|
||||
<td>
|
||||
<span
|
||||
class="bg-[#F9F2F2] border-[#E00000] text-[#E00000] block border font-[500] p-[0px_5px] rounded-[50px] text-[12px] text-center">
|
||||
Quá hạn </span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="text-center"> 3 </td>
|
||||
<td> Sửa trang chủ websiteLaptoptcc </td>
|
||||
<td> 28/11/2023 </td>
|
||||
<td>
|
||||
<span
|
||||
class="bg-[#F7F5FF] border-[#0041E8] text-[#0041E8] block border font-[500] p-[0px_5px] rounded-[50px] text-[12px] text-center">
|
||||
Đã xong </span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="text-center"> 4 </td>
|
||||
<td> Sửa trang chủ websiteLaptoptcc </td>
|
||||
<td> 28/11/2023 </td>
|
||||
<td>
|
||||
<span
|
||||
class="whitespace-nowrap bg-[#FCFAF1] border-[#FFC700] text-[#FFC700] block border font-[500] p-[0px_5px] rounded-[50px] text-[12px] text-center">
|
||||
Sắp hết hạn </span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="text-base-content/60 text-sm">
|
||||
vs.
|
||||
<span class="mx-1">$494.16</span>
|
||||
last period
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body gap-2">
|
||||
<div class="flex items-start justify-between gap-2 text-sm">
|
||||
<div>
|
||||
<p class="text-base-content/80 font-medium">
|
||||
Sales
|
||||
</p>
|
||||
<div class="mt-3 flex items-center gap-2">
|
||||
<p class="inline text-2xl font-semibold">
|
||||
4500
|
||||
</p>
|
||||
<div class="badge badge-soft badge-success badge-sm gap-0.5 px-1 font-medium">
|
||||
<span class="iconify lucide--arrow-up size-3.5"></span>
|
||||
21.2%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-base-200 rounded-box flex items-center p-2">
|
||||
<span class="iconify lucide--package size-5"></span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-base-content/60 text-sm">
|
||||
vs.
|
||||
<span class="mx-1">3845</span>
|
||||
last period
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body gap-2">
|
||||
<div class="flex items-start justify-between gap-2 text-sm">
|
||||
<div>
|
||||
<p class="text-base-content/80 font-medium">
|
||||
Customers
|
||||
</p>
|
||||
<div class="mt-3 flex items-center gap-2">
|
||||
<p class="inline text-2xl font-semibold">
|
||||
2242
|
||||
</p>
|
||||
<div class="badge badge-soft badge-error badge-sm gap-0.5 px-1 font-medium">
|
||||
<span class="iconify lucide--arrow-down size-3.5"></span>
|
||||
-6.8%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-base-200 rounded-box flex items-center p-2">
|
||||
<span class="iconify lucide--users size-5"></span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-base-content/60 text-sm">
|
||||
vs.
|
||||
<span class="mx-1">2448</span>
|
||||
last period
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body gap-2">
|
||||
<div class="flex items-start justify-between gap-2 text-sm">
|
||||
<div>
|
||||
<p class="text-base-content/80 font-medium">
|
||||
Spending
|
||||
</p>
|
||||
<div class="mt-3 flex items-center gap-2">
|
||||
<p class="inline text-2xl font-semibold">
|
||||
$112.54
|
||||
</p>
|
||||
<div class="badge badge-soft badge-success badge-sm gap-0.5 px-1 font-medium">
|
||||
<span class="iconify lucide--arrow-up size-3.5"></span>
|
||||
8.5%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-base-200 rounded-box flex items-center p-2">
|
||||
<span class="iconify lucide--eraser size-5"></span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-base-content/60 text-sm">
|
||||
vs.
|
||||
<span class="mx-1">$98.14</span>
|
||||
last period
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End: Dashboard Stats Widget -->
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-6 xl:grid-cols-12">
|
||||
<div class="xl:col-span-7">
|
||||
<!-- Start: Revenue Statistic -->
|
||||
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body px-0 pb-0">
|
||||
<div class="px-6">
|
||||
<div class="flex items-start justify-between">
|
||||
<span class="font-medium">
|
||||
Revenue Statistics
|
||||
</span>
|
||||
<div class="tabs tabs-box tabs-xs hidden sm:block">
|
||||
<div class="tab false px-3">Day</div>
|
||||
<div class="tab false px-3">Month</div>
|
||||
<div class="tab tab-active px-3">Year</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-4xl font-semibold">
|
||||
$184.78K
|
||||
</span>
|
||||
<span class="text-success font-medium">
|
||||
+3.24%
|
||||
</span>
|
||||
</div>
|
||||
<span class="text-base-content/60 text-sm">
|
||||
Total income in this year
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="revenue-statics-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End: Revenue Statistic -->
|
||||
</div>
|
||||
<div class="xl:col-span-5">
|
||||
<!-- Start: Customer Acquisition -->
|
||||
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body p-0">
|
||||
<div class="flex items-center justify-between px-5 pt-5">
|
||||
<span class="font-medium">
|
||||
Customer Acquisition
|
||||
</span>
|
||||
<div class="inline-flex items-center gap-2">
|
||||
<div class="text-base-content/60 w-6 border border-dashed"></div>
|
||||
<span class="text-base-content/80 text-xs">
|
||||
Prediction
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 py-3">
|
||||
<div class="divide-base-300 grid grid-cols-2 gap-5 px-5 sm:grid-cols-3 sm:divide-x">
|
||||
<div class="text-center">
|
||||
<p>Advertise</p>
|
||||
<p class="mt-0.5 text-xl font-medium">
|
||||
$148
|
||||
</p>
|
||||
<div class="text-success mt-0.5 inline-flex items-center gap-1">
|
||||
<span class="iconify lucide--arrow-up size-3"></span>
|
||||
<p class="text-xs">4.78%</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden text-center sm:block">
|
||||
<p>Customers</p>
|
||||
<p class="mt-0.5 text-xl font-medium">
|
||||
427
|
||||
</p>
|
||||
<div class="text-success mt-0.5 inline-flex items-center gap-1">
|
||||
<span class="iconify lucide--arrow-up size-3"></span>
|
||||
<p class="text-xs">3.15%</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="-mt-25 sm:mx-5">
|
||||
<div id="customer-acquisition-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End: Customer Acquisition -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6 grid grid-cols-1 gap-6 xl:grid-cols-5 2xl:grid-cols-12">
|
||||
<div class="xl:col-span-3 2xl:col-span-5">
|
||||
<!-- Start: Recent Orders -->
|
||||
|
||||
<div aria-label="Card" class="card bg-base-100 shadow">
|
||||
<div class="card-body p-0">
|
||||
<div class="flex items-center gap-3 px-5 pt-5">
|
||||
<span class="iconify lucide--shopping-bag size-4.5"></span>
|
||||
<span class="font-medium">Recent Orders</span>
|
||||
<button class="btn btn-outline border-base-300 btn-sm ms-auto">
|
||||
<span class="iconify lucide--download size-3.5"></span>
|
||||
Report
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-2 overflow-auto">
|
||||
<table class="table *:text-nowrap">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<input aria-label="checked-all-order" class="checkbox checkbox-sm"
|
||||
type="checkbox" />
|
||||
</th>
|
||||
<th>Product</th>
|
||||
<th>Price</th>
|
||||
<th>Date</th>
|
||||
<th>Status</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
<input aria-label="checked-order" class="checkbox checkbox-sm" type="checkbox" />
|
||||
</th>
|
||||
<td class="flex items-center space-x-3 truncate">
|
||||
<img alt="order image" class="mask mask-squircle bg-base-200 size-7.5"
|
||||
src="./images/apps/ecommerce/products/1.jpg" />
|
||||
<p>Men's tracking shoes</p>
|
||||
</td>
|
||||
<td class="font-medium">$99</td>
|
||||
<td class="text-xs">25 Jun 2024</td>
|
||||
<td>
|
||||
<div class="badge badge-success badge-sm badge-soft">
|
||||
Delivered
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex items-center gap-1">
|
||||
<button aria-label="Show product" class="btn btn-square btn-ghost btn-xs">
|
||||
<span class="iconify lucide--eye text-base-content/60 size-4"></span>
|
||||
</button>
|
||||
<button aria-label="Show product"
|
||||
class="btn btn-square btn-error btn-outline btn-xs border-transparent">
|
||||
<span class="iconify lucide--trash size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<input aria-label="checked-order" class="checkbox checkbox-sm" type="checkbox" />
|
||||
</th>
|
||||
<td class="flex items-center space-x-3 truncate">
|
||||
<img alt="order image" class="mask mask-squircle bg-base-200 size-7.5"
|
||||
src="./images/apps/ecommerce/products/2.jpg" />
|
||||
<p>Cocooil body oil</p>
|
||||
</td>
|
||||
<td class="font-medium">$75</td>
|
||||
<td class="text-xs">22 Jun 2024</td>
|
||||
<td>
|
||||
<div class="badge badge-info badge-sm badge-soft">
|
||||
On Going
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex items-center gap-1">
|
||||
<button aria-label="Show product" class="btn btn-square btn-ghost btn-xs">
|
||||
<span class="iconify lucide--eye text-base-content/60 size-4"></span>
|
||||
</button>
|
||||
<button aria-label="Show product"
|
||||
class="btn btn-square btn-error btn-outline btn-xs border-transparent">
|
||||
<span class="iconify lucide--trash size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<input aria-label="checked-order" class="checkbox checkbox-sm" type="checkbox" />
|
||||
</th>
|
||||
<td class="flex items-center space-x-3 truncate">
|
||||
<img alt="order image" class="mask mask-squircle bg-base-200 size-7.5"
|
||||
src="./images/apps/ecommerce/products/3.jpg" />
|
||||
<p>Freeze Air</p>
|
||||
</td>
|
||||
<td class="font-medium">$47</td>
|
||||
<td class="text-xs">17 Jun 2024</td>
|
||||
<td>
|
||||
<div class="badge badge-primary badge-sm badge-soft">
|
||||
Confirmed
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex items-center gap-1">
|
||||
<button aria-label="Show product" class="btn btn-square btn-ghost btn-xs">
|
||||
<span class="iconify lucide--eye text-base-content/60 size-4"></span>
|
||||
</button>
|
||||
<button aria-label="Show product"
|
||||
class="btn btn-square btn-error btn-outline btn-xs border-transparent">
|
||||
<span class="iconify lucide--trash size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<input aria-label="checked-order" class="checkbox checkbox-sm" type="checkbox" />
|
||||
</th>
|
||||
<td class="flex items-center space-x-3 truncate">
|
||||
<img alt="order image" class="mask mask-squircle bg-base-200 size-7.5"
|
||||
src="./images/apps/ecommerce/products/4.jpg" />
|
||||
<p>Ladies's shoes</p>
|
||||
</td>
|
||||
<td class="font-medium">$52</td>
|
||||
<td class="text-xs">23 Jun 2024</td>
|
||||
<td>
|
||||
<div class="badge badge-error badge-sm badge-soft">
|
||||
Canceled
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex items-center gap-1">
|
||||
<button aria-label="Show product" class="btn btn-square btn-ghost btn-xs">
|
||||
<span class="iconify lucide--eye text-base-content/60 size-4"></span>
|
||||
</button>
|
||||
<button aria-label="Show product"
|
||||
class="btn btn-square btn-error btn-outline btn-xs border-transparent">
|
||||
<span class="iconify lucide--trash size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<input aria-label="checked-order" class="checkbox checkbox-sm" type="checkbox" />
|
||||
</th>
|
||||
<td class="flex items-center space-x-3 truncate">
|
||||
<img alt="order image" class="mask mask-squircle bg-base-200 size-7.5"
|
||||
src="./images/apps/ecommerce/products/10.jpg" />
|
||||
<p>Choco's cookie</p>
|
||||
</td>
|
||||
<td class="font-medium">$24</td>
|
||||
<td class="text-xs">21 Jun 2024</td>
|
||||
<td>
|
||||
<div class="badge badge-secondary badge-sm badge-soft">
|
||||
Waiting
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex items-center gap-1">
|
||||
<button aria-label="Show product" class="btn btn-square btn-ghost btn-xs">
|
||||
<span class="iconify lucide--eye text-base-content/60 size-4"></span>
|
||||
</button>
|
||||
<button aria-label="Show product"
|
||||
class="btn btn-square btn-error btn-outline btn-xs border-transparent">
|
||||
<span class="iconify lucide--trash size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End: Recent Orders -->
|
||||
</div>
|
||||
<div class="xl:col-span-2 2xl:col-span-3">
|
||||
<!-- Start: Quick Chat -->
|
||||
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body pb-3">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="iconify lucide--messages-square size-4.5"></span>
|
||||
<span class="font-medium">Quick Chat</span>
|
||||
<a href="./apps/chat.html" class="btn btn-outline btn-sm border-base-300 ms-auto">
|
||||
Go To Chat
|
||||
</a>
|
||||
</div>
|
||||
<div class="-mx-2 mt-2 space-y-0.5">
|
||||
<div
|
||||
class="rounded-box hover:bg-base-200 flex cursor-pointer items-center gap-3 px-2 py-2 transition-all active:scale-[.98]">
|
||||
<img alt="chat" class="bg-base-200 mask mask-squircle size-11" src="./images/avatars/1.png" />
|
||||
<div class="grow">
|
||||
<div class="flex gap-1">
|
||||
<p class="grow">Mia Johnson</p>
|
||||
<span class="text-base-content/60 text-xs">
|
||||
11:35 AM
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-base-content/80 line-clamp-1 text-sm text-ellipsis">
|
||||
It's called 'Dreamscape.' A must-watch!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-box hover:bg-base-200 flex cursor-pointer items-center gap-3 px-2 py-2 transition-all active:scale-[.98]">
|
||||
<img alt="chat" class="bg-base-200 mask mask-squircle size-11" src="./images/avatars/2.png" />
|
||||
<div class="grow">
|
||||
<div class="flex gap-1">
|
||||
<p class="grow">Ethan Patel</p>
|
||||
<span class="text-base-content/60 text-xs">
|
||||
09:58 AM
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-base-content/80 line-clamp-1 text-sm text-ellipsis">
|
||||
Just got a new book. Excited to start
|
||||
reading.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-box hover:bg-base-200 flex cursor-pointer items-center gap-3 px-2 py-2 transition-all active:scale-[.98]">
|
||||
<img alt="chat" class="bg-base-200 mask mask-squircle size-11" src="./images/avatars/3.png" />
|
||||
<div class="grow">
|
||||
<div class="flex gap-1">
|
||||
<p class="grow">Sophia Nguyen</p>
|
||||
<span class="text-base-content/60 text-xs">
|
||||
08:20 AM
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-base-content/80 line-clamp-1 text-sm text-ellipsis">
|
||||
How's your day going?
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-box hover:bg-base-200 flex cursor-pointer items-center gap-3 px-2 py-2 transition-all active:scale-[.98]">
|
||||
<img alt="chat" class="bg-base-200 mask mask-squircle size-11" src="./images/avatars/4.png" />
|
||||
<div class="grow">
|
||||
<div class="flex gap-1">
|
||||
<p class="grow">Emily Chen</p>
|
||||
<span class="text-base-content/60 text-xs">
|
||||
06:21 PM
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-base-content/80 line-clamp-1 text-sm text-ellipsis">
|
||||
Did you see that amazing sunset
|
||||
yesterday?
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-box hover:bg-base-200 flex cursor-pointer items-center gap-3 px-2 py-2 transition-all active:scale-[.98]">
|
||||
<img alt="chat" class="bg-base-200 mask mask-squircle size-11" src="./images/avatars/5.png" />
|
||||
<div class="grow">
|
||||
<div class="flex gap-1">
|
||||
<p class="grow">Kelvin S.</p>
|
||||
<span class="text-base-content/60 text-xs">
|
||||
08:15 AM
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-base-content/80 line-clamp-1 text-sm text-ellipsis">
|
||||
Not sure, what you talking about...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End: Quick Chat -->
|
||||
</div>
|
||||
<div class="xl:col-span-3 2xl:col-span-4">
|
||||
<!-- Start: Global Sales -->
|
||||
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body gap-0 p-0">
|
||||
<div class="flex items-center gap-3 px-5 pt-5">
|
||||
<span class="iconify lucide--globe-2 size-4.5"></span>
|
||||
<span class="font-medium">Global Sales (%)</span>
|
||||
<button class="btn btn-ghost btn-outline border-base-300 btn-sm z-1 ms-auto">
|
||||
<span class="iconify lucide--eye size-4"></span>
|
||||
Overview
|
||||
</button>
|
||||
</div>
|
||||
<div class="me-5 -mt-5 mb-1">
|
||||
<div id="global-sales-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End: Global Sales -->
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,76 +0,0 @@
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
// Sự kiện click để hiển thị menu
|
||||
$('#js-show-menu').click(function () {
|
||||
$('#js-menu-big').toggleClass('show');
|
||||
$('#overlay').addClass('active');
|
||||
});
|
||||
|
||||
// hover show danh muc con
|
||||
HoverShowMenu();
|
||||
|
||||
AdminFunctions.searchSuggestions('#js-input-search')
|
||||
})
|
||||
|
||||
|
||||
function clickBackground() {
|
||||
$('#js-menu-big').removeClass('show');
|
||||
$('#overlay').removeClass('active');
|
||||
}
|
||||
|
||||
|
||||
function HoverShowMenu() {
|
||||
const $menuBig = $('#js-menu-big');
|
||||
const $hoverMenu = $('#js-hover-menu');
|
||||
|
||||
$menuBig.find('.box-item .item').on('mousemove', function () {
|
||||
if ($menuBig.hasClass('active')) {
|
||||
const $parentItem = $(this).closest('.box-item');
|
||||
const $hoverContent = $parentItem.find('.hover-menu');
|
||||
|
||||
if ($hoverContent.length) {
|
||||
const offset = $parentItem.offset();
|
||||
const menuWidth = $menuBig.width();
|
||||
const hoverHeight = $hoverContent.outerHeight();
|
||||
const windowHeight = $(window).height();
|
||||
const maxY = $(window).scrollTop() + windowHeight;
|
||||
|
||||
let posX = offset.left + menuWidth;
|
||||
let posY = offset.top;
|
||||
|
||||
if (posY + hoverHeight > maxY) {
|
||||
posY = maxY - hoverHeight - 10;
|
||||
}
|
||||
|
||||
$hoverMenu.addClass('active')
|
||||
.html($hoverContent.html())
|
||||
.css({ left: posX, top: posY });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$hoverMenu.on('mouseleave', function () {
|
||||
$hoverMenu.removeClass('active');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function formatCurrency(a) {
|
||||
var b = parseFloat(a).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1.").toString();
|
||||
var len = b.length;
|
||||
b = b.substring(0, len - 3);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
function toggleSubMenu(id) {
|
||||
const submenu = $('#' + id);
|
||||
submenu.toggleClass('active');
|
||||
if ($('#js-menu-big .sub-menu').hasClass('active')) {
|
||||
$('#js-menu-big').addClass('active');
|
||||
} else {
|
||||
$('#js-menu-big').removeClass('active');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,346 +1,282 @@
|
||||
<script src="{{ 'charts.js' | asset_url }}"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
revenue_chart(); // Doanh thu
|
||||
|
||||
access_chart(); // Truy cập
|
||||
|
||||
introduce_web_chart(); // web giới thiệu
|
||||
|
||||
$("#js-admin-home-tab a").click(function () {
|
||||
event.preventDefault();
|
||||
|
||||
$("#js-admin-home-tab a").removeClass('current');
|
||||
$(this).addClass('current');
|
||||
|
||||
var id = $(this).attr('href');
|
||||
$('.home-report-holder').hide();
|
||||
$(id).show();
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
// Doanh thu
|
||||
function revenue_chart() {
|
||||
let options = {
|
||||
chart: {
|
||||
maxWidth: "100%",
|
||||
height: "320px",
|
||||
type: "area",
|
||||
fontFamily: "Inter, sans-serif",
|
||||
dropShadow: {
|
||||
enabled: false,
|
||||
},
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
x: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
fill: {
|
||||
type: "gradient",
|
||||
gradient: {
|
||||
opacityFrom: 0.55,
|
||||
opacityTo: 0,
|
||||
shade: "#1C64F2",
|
||||
gradientToColors: ["#1C64F2"],
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
stroke: {
|
||||
width: 6,
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
strokeDashArray: 4,
|
||||
padding: {
|
||||
left: 2,
|
||||
right: 2,
|
||||
top: 0
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "New users",
|
||||
data: [6500, 6418, 6456, 6526, 6356, 6456],
|
||||
color: "#0041E8",
|
||||
},
|
||||
],
|
||||
xaxis: {
|
||||
categories: [
|
||||
'01 February',
|
||||
'02 February',
|
||||
'03 February',
|
||||
'04 February',
|
||||
'05 February',
|
||||
'06 February',
|
||||
'07 February'
|
||||
],
|
||||
labels: {
|
||||
show: false,
|
||||
},
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
show: false,
|
||||
},
|
||||
}
|
||||
|
||||
if (document.getElementById("js-revenue-chart") && typeof ApexCharts !== 'undefined') {
|
||||
const chart = new ApexCharts(document.getElementById("js-revenue-chart"), options);
|
||||
chart.render();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Truy cập
|
||||
function access_chart() {
|
||||
const options = {
|
||||
colors: ["#0041E8", "#FFC700"],
|
||||
series: [
|
||||
{
|
||||
name: "Organic",
|
||||
color: "#0041E8",
|
||||
data: [
|
||||
{ x: "Mon", y: 231 },
|
||||
{ x: "Tue", y: 122 },
|
||||
{ x: "Wed", y: 63 },
|
||||
{ x: "Thu", y: 421 },
|
||||
{ x: "Fri", y: 122 },
|
||||
{ x: "Sat", y: 323 },
|
||||
{ x: "Sun", y: 111 },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Social media",
|
||||
color: "#FFC700",
|
||||
data: [
|
||||
{ x: "Mon", y: 232 },
|
||||
{ x: "Tue", y: 113 },
|
||||
{ x: "Wed", y: 341 },
|
||||
{ x: "Thu", y: 224 },
|
||||
{ x: "Fri", y: 522 },
|
||||
{ x: "Sat", y: 411 },
|
||||
{ x: "Sun", y: 243 },
|
||||
],
|
||||
},
|
||||
],
|
||||
chart: {
|
||||
type: "bar",
|
||||
height: "320px",
|
||||
fontFamily: "Inter, sans-serif",
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: "70%",
|
||||
borderRadiusApplication: "end",
|
||||
borderRadius: 8,
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
shared: true,
|
||||
intersect: false,
|
||||
style: {
|
||||
fontFamily: "Inter, sans-serif",
|
||||
},
|
||||
},
|
||||
states: {
|
||||
hover: {
|
||||
filter: {
|
||||
type: "darken",
|
||||
value: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
show: true,
|
||||
width: 0,
|
||||
colors: ["transparent"],
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
strokeDashArray: 4,
|
||||
padding: {
|
||||
left: 2,
|
||||
right: 2,
|
||||
top: -14
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
xaxis: {
|
||||
floating: false,
|
||||
labels: {
|
||||
show: true,
|
||||
style: {
|
||||
fontFamily: "Inter, sans-serif",
|
||||
cssClass: 'text-xs font-normal fill-gray-500 dark:fill-gray-400'
|
||||
}
|
||||
},
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
show: false,
|
||||
},
|
||||
fill: {
|
||||
opacity: 1,
|
||||
},
|
||||
}
|
||||
|
||||
if (document.getElementById("js-access-chart") && typeof ApexCharts !== 'undefined') {
|
||||
const chart = new ApexCharts(document.getElementById("js-access-chart"), options);
|
||||
chart.render();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// web giới thiệu
|
||||
function introduce_web_chart() {
|
||||
const getChartOptions = () => {
|
||||
return {
|
||||
series: [35.1, 23.5, 2.4, 5.4],
|
||||
colors: ["#0041E8", "#6DC580", "#FFC700", "#E00000"],
|
||||
const initCustomerAcquisitionChart = () => {
|
||||
const chartOptions = {
|
||||
chart: {
|
||||
height: 320,
|
||||
width: "100%",
|
||||
type: "donut",
|
||||
},
|
||||
stroke: {
|
||||
colors: ["transparent"],
|
||||
lineCap: "",
|
||||
},
|
||||
plotOptions: {
|
||||
pie: {
|
||||
donut: {
|
||||
labels: {
|
||||
show: true,
|
||||
name: {
|
||||
show: true,
|
||||
fontFamily: "Inter, sans-serif",
|
||||
offsetY: 20,
|
||||
},
|
||||
total: {
|
||||
showAlways: true,
|
||||
show: true,
|
||||
label: "Lượt truy cập",
|
||||
fontFamily: "Inter, sans-serif",
|
||||
formatter: function (w) {
|
||||
const sum = w.globals.seriesTotals.reduce((a, b) => {
|
||||
return a + b
|
||||
}, 0)
|
||||
return `${sum}k`
|
||||
},
|
||||
},
|
||||
value: {
|
||||
show: true,
|
||||
fontFamily: "Inter, sans-serif",
|
||||
offsetY: -20,
|
||||
formatter: function (value) {
|
||||
return value + "k"
|
||||
},
|
||||
},
|
||||
},
|
||||
size: "80%",
|
||||
},
|
||||
height: 356,
|
||||
sparkline: {
|
||||
enabled: false,
|
||||
},
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
zoom: {
|
||||
enabled: false,
|
||||
},
|
||||
background: "transparent",
|
||||
},
|
||||
forecastDataPoints: {
|
||||
count: 2,
|
||||
dashArray: [6, 4],
|
||||
},
|
||||
grid: {
|
||||
padding: {
|
||||
top: -2,
|
||||
show: false,
|
||||
},
|
||||
yaxis: {
|
||||
show: false,
|
||||
min: 125,
|
||||
max: 181,
|
||||
},
|
||||
xaxis: {
|
||||
categories: Array.from({ length: 15 }, (_, index) => index + 1),
|
||||
},
|
||||
tooltip: {
|
||||
y: {
|
||||
formatter: (val) => val.toString(),
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
curve: "stepline",
|
||||
width: [2, 1.5],
|
||||
},
|
||||
colors: ["#167bff", "rgba(150,150,150,0.3)"],
|
||||
series: [
|
||||
{
|
||||
name: "Customer",
|
||||
data: [144, 150, 146, 154, 150, 155, 160, 155, 140, 155, 160, 180, 170, 165, 165],
|
||||
},
|
||||
{
|
||||
name: "Advertise",
|
||||
data: [140, 142, 142, 140, 146, 148, 150, 136, 130, 133, 145, 148, 158, 150, 150],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
if (document.getElementById("customer-acquisition-chart")) {
|
||||
new ApexCharts(document.getElementById("customer-acquisition-chart"), chartOptions).render()
|
||||
}
|
||||
}
|
||||
|
||||
const initRevenueStatisticsChart = () => {
|
||||
const chartOptions = {
|
||||
chart: {
|
||||
height: 288,
|
||||
type: "bar",
|
||||
stacked: true,
|
||||
background: "transparent",
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 8,
|
||||
borderRadiusApplication: "end",
|
||||
borderRadiusWhenStacked: "last",
|
||||
colors: {
|
||||
backgroundBarColors: ["rgba(150,150,150,0.07)"],
|
||||
backgroundBarRadius: 8,
|
||||
},
|
||||
columnWidth: "45%",
|
||||
barHeight: "100%",
|
||||
},
|
||||
},
|
||||
labels: ["Trực tiếp", "Quảng cáo", "Liên kết", "Qua Email"],
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
colors: ["#ff8b4b", "#6c74f8"],
|
||||
legend: {
|
||||
position: "bottom",
|
||||
fontFamily: "Inter, sans-serif",
|
||||
show: true,
|
||||
horizontalAlign: "center",
|
||||
offsetX: 0,
|
||||
offsetY: 6,
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
formatter: function (value) {
|
||||
return value + "k"
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "Orders",
|
||||
data: [10, 12, 14, 16, 18, 20, 14, 16, 24, 12],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Revenue",
|
||||
data: [15, 24, 21, 28, 30, 40, 22, 32, 48, 20],
|
||||
},
|
||||
],
|
||||
xaxis: {
|
||||
labels: {
|
||||
formatter: function (value) {
|
||||
return value + "k"
|
||||
},
|
||||
categories: [
|
||||
new Date("1/1/2016"),
|
||||
new Date("1/1/2017"),
|
||||
new Date("1/1/2018"),
|
||||
new Date("1/1/2019"),
|
||||
new Date("1/1/2020"),
|
||||
new Date("1/1/2021"),
|
||||
new Date("1/1/2022"),
|
||||
new Date("1/1/2023"),
|
||||
new Date("1/1/2024"),
|
||||
new Date("1/1/2025"),
|
||||
],
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
labels: {
|
||||
formatter: (val) => {
|
||||
return new Date(val).getFullYear().toString()
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
labels: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
shared: true,
|
||||
intersect: false,
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 450,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 4,
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
tickAmount: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
if (document.getElementById("revenue-statics-chart")) {
|
||||
new ApexCharts(document.getElementById("revenue-statics-chart"), chartOptions).render()
|
||||
}
|
||||
}
|
||||
|
||||
if (document.getElementById("js-introduce-web-chart") && typeof ApexCharts !== 'undefined') {
|
||||
const chart = new ApexCharts(document.getElementById("js-introduce-web-chart"), getChartOptions());
|
||||
chart.render();
|
||||
const initGlobalSalesChart = () => {
|
||||
const data = [
|
||||
{
|
||||
name: "Turkey",
|
||||
orders: 9,
|
||||
},
|
||||
{
|
||||
name: "India",
|
||||
orders: 12,
|
||||
},
|
||||
{
|
||||
name: "Canada",
|
||||
orders: 13,
|
||||
},
|
||||
{
|
||||
name: "US",
|
||||
orders: 16,
|
||||
},
|
||||
{
|
||||
name: "Netherlands",
|
||||
orders: 14,
|
||||
},
|
||||
{
|
||||
name: "Italy",
|
||||
orders: 17,
|
||||
},
|
||||
{
|
||||
name: "Other",
|
||||
orders: 19,
|
||||
},
|
||||
]
|
||||
|
||||
// Get all the checkboxes by their class name
|
||||
const checkboxes = document.querySelectorAll('#devices input[type="checkbox"]');
|
||||
const chartOptions = {
|
||||
chart: {
|
||||
height: 344,
|
||||
type: "bar",
|
||||
parentHeightOffset: 0,
|
||||
background: "transparent",
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
borderRadius: 4,
|
||||
distributed: true,
|
||||
borderRadiusApplication: "end",
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
textAnchor: "start",
|
||||
style: {
|
||||
colors: ["#fff"],
|
||||
},
|
||||
formatter: function (val, opt) {
|
||||
return opt.w.globals.labels[opt.dataPointIndex] + ": " + val
|
||||
},
|
||||
offsetX: -10,
|
||||
dropShadow: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: data.map((country) => country.orders),
|
||||
},
|
||||
],
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
stroke: {
|
||||
width: 0,
|
||||
colors: ["#fff"],
|
||||
},
|
||||
xaxis: {
|
||||
categories: data.map((country) => country.name),
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
// Function to handle the checkbox change event
|
||||
function handleCheckboxChange(event, chart) {
|
||||
const checkbox = event.target;
|
||||
if (checkbox.checked) {
|
||||
switch (checkbox.value) {
|
||||
case 'web_1':
|
||||
chart.updateSeries([15.1, 22.5, 4.4, 8.4]);
|
||||
break;
|
||||
case 'web_2':
|
||||
chart.updateSeries([25.1, 26.5, 1.4, 3.4]);
|
||||
break;
|
||||
case 'web_3':
|
||||
chart.updateSeries([45.1, 27.5, 8.4, 2.4]);
|
||||
break;
|
||||
default:
|
||||
chart.updateSeries([55.1, 28.5, 1.4, 5.4]);
|
||||
}
|
||||
|
||||
} else {
|
||||
chart.updateSeries([35.1, 23.5, 2.4, 5.4]);
|
||||
}
|
||||
tooltip: {
|
||||
theme: "dark",
|
||||
x: {
|
||||
show: false,
|
||||
},
|
||||
y: {
|
||||
formatter: (val) => `${val}%`,
|
||||
},
|
||||
},
|
||||
colors: ["#7179ff", "#4bcd89", "#ff6c88", "#5cb7ff", "#9071ff", "#ff5892", "#ff8b4b"],
|
||||
}
|
||||
|
||||
// Attach the event listener to each checkbox
|
||||
checkboxes.forEach((checkbox) => {
|
||||
checkbox.addEventListener('change', (event) => handleCheckboxChange(event, chart));
|
||||
});
|
||||
if (document.getElementById("global-sales-chart")) {
|
||||
new ApexCharts(document.getElementById("global-sales-chart"), chartOptions).render()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
initCustomerAcquisitionChart()
|
||||
initRevenueStatisticsChart()
|
||||
initGlobalSalesChart()
|
||||
})
|
||||
|
||||
</script>
|
||||
@@ -1,6 +1,12 @@
|
||||
<script src="/assets/typescript/main.js?v=1.111"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/apexcharts/dist/apexcharts.min.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/apexcharts/dist/apexcharts.min.js"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplebar/6.2.7/simplebar.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/simplebar/6.2.7/simplebar.css" />
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||
|
||||
<script src="{{'main.js' | asset_url }}"></script>
|
||||
|
||||
{% include javascript/global %}
|
||||
|
||||
{% if global.module == 'home' %}
|
||||
|
||||
|
||||
144
template/other/header.html
Normal file
@@ -0,0 +1,144 @@
|
||||
<!-- Start: Layout - Sidebar -->
|
||||
|
||||
<input type="checkbox" id="layout-sidebar-toggle-trigger" class="hidden" aria-label="Toggle layout sidebar" />
|
||||
<input type="checkbox" id="layout-sidebar-hover-trigger" class="hidden" aria-label="Dense layout sidebar" />
|
||||
<div id="layout-sidebar-hover" class="bg-base-300 h-screen w-1"></div>
|
||||
|
||||
<div id="layout-sidebar" class="sidebar-menu sidebar-menu-activation">
|
||||
<div class="flex min-h-16 items-center justify-between gap-3 ps-5 pe-4">
|
||||
<a href="./dashboards-ecommerce.html">
|
||||
<img src="{{ 'logo_hura8.png' | asset_url }}" class="h-5.5" />
|
||||
</a>
|
||||
<label for="layout-sidebar-hover-trigger" title="Toggle sidebar hover"
|
||||
class="btn btn-circle btn-ghost btn-sm text-base-content/50 relative max-lg:hidden">
|
||||
<span
|
||||
class="iconify lucide--panel-left-close absolute size-4.5 opacity-100 transition-all duration-300 group-has-[[id=layout-sidebar-hover-trigger]:checked]/html:opacity-0"></span>
|
||||
<span
|
||||
class="iconify lucide--panel-left-dashed absolute size-4.5 opacity-0 transition-all duration-300 group-has-[[id=layout-sidebar-hover-trigger]:checked]/html:opacity-100"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="relative min-h-0 grow">
|
||||
<div data-simplebar class="size-full">
|
||||
<div class="mb-3 space-y-0.5 px-2.5">
|
||||
|
||||
<div class="collapse">
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="iconify lucide--home tw-tsa"></span>
|
||||
<a href="/" class="grow {% if global.url == '/' %}active{% endif %}">Trang
|
||||
chủ</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% for _category in global.main_menu %}
|
||||
{% assign _type = _category[0] %}
|
||||
{% assign _menuArray = _category[1].menu %}
|
||||
{% if _category[1].enable == 1 %}
|
||||
<div class="group collapse">
|
||||
<input aria-label="Sidemenu item trigger" type="checkbox" class="peer"
|
||||
name="sidebar-menu-parent-item" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
{% if _type == 'order' %}
|
||||
<span class="iconify lucide--store tw-tsa"></span>
|
||||
{% elsif _type == 'product' %}
|
||||
<span class="iconify lucide--package tw-tsa"></span>
|
||||
{% elsif _type == 'customer' %}
|
||||
<span class="iconify lucide--users tw-tsa"></span>
|
||||
{% elsif _type == 'article' %}
|
||||
<span class="iconify lucide--newspaper tw-tsa"></span>
|
||||
{% elsif _type == 'marketing' %}
|
||||
<span class="iconify lucide--megaphone tw-tsa"></span>
|
||||
{% elsif _type == 'job' %}
|
||||
<span class="iconify lucide--briefcase tw-tsa"></span>
|
||||
{% elsif _type == 'pcbuilder' %}
|
||||
<span class="iconify lucide--monitor-smartphone tw-tsa"></span>
|
||||
{% elsif _type == 'payinstall' %}
|
||||
<span class="iconify lucide--handshake tw-tsa"></span>
|
||||
{% elsif _type == 'distributor' %}
|
||||
<span class="iconify lucide--store tw-tsa"></span>
|
||||
{% elsif _type == 'report' %}
|
||||
<span class="iconify lucide--pie-chart tw-tsa"></span>
|
||||
{% elsif _type == 'system' %}
|
||||
<span class="iconify hugeicons--settings-04 tw-tsa"></span>
|
||||
{% endif %}
|
||||
<span class="grow">{{ _category[1].name }}</span>
|
||||
<span class="iconify lucide--chevron-right arrow-icon size-3.5"></span>
|
||||
</div>
|
||||
<div class="collapse-content ms-6.5 !p-0">
|
||||
<div class="mt-0.5 space-y-0.5">
|
||||
{% for _item in _menuArray %}
|
||||
<a class="menu-item false {% if _item.url == global.url %} active {% endif %}"
|
||||
href="{{ _item.url }}">
|
||||
<span class="grow">{{ _item.name }}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="from-base-100/60 pointer-events-none absolute start-0 end-0 bottom-0 h-7 bg-linear-to-t to-transparent">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<hr class="border-base-300 my-2 border-dashed" />
|
||||
<div class="dropdown dropdown-top dropdown-end w-full">
|
||||
<div tabindex="0" role="button"
|
||||
class="bg-base-200 hover:bg-base-300 rounded-box mx-2 mt-0 flex cursor-pointer items-center gap-2.5 px-3 py-2 transition-all">
|
||||
<div class="avatar">
|
||||
<div class="bg-base-200 mask mask-squircle w-8">
|
||||
<img src="./../../assets/images/avatars/1.png" alt="Avatar" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grow -space-y-0.5">
|
||||
<p class="text-sm font-medium">Denish N</p>
|
||||
<p class="text-base-content/60 text-xs">@withden</p>
|
||||
</div>
|
||||
<span class="iconify lucide--chevrons-up-down text-base-content/60 size-4"></span>
|
||||
</div>
|
||||
<ul role="menu" tabindex="0"
|
||||
class="dropdown-content menu bg-base-100 rounded-box shadow-base-content/4 mb-1 w-48 p-1 shadow-[0px_-10px_40px_0px]">
|
||||
<li>
|
||||
<a href="./pages/settings.html">
|
||||
<span class="iconify lucide--user size-4"></span>
|
||||
<span>My Profile</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="./pages/settings.html">
|
||||
<span class="iconify lucide--settings size-4"></span>
|
||||
<span>Settings</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="./pages/get-help.html">
|
||||
<span class="iconify lucide--help-circle size-4"></span>
|
||||
<span>Help</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div>
|
||||
<span class="iconify lucide--bell size-4"></span>
|
||||
<span>Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div>
|
||||
<span class="iconify lucide--arrow-left-right size-4"></span>
|
||||
<span>Switch Account</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="layout-sidebar-toggle-trigger" id="layout-sidebar-backdrop"></label>
|
||||
|
||||
<!-- End: Layout - Sidebar -->
|
||||
508
template/other/topbar.html
Normal file
@@ -0,0 +1,508 @@
|
||||
<!-- Start: Layout - Topbar -->
|
||||
|
||||
<div role="navigation" aria-label="Navbar" class="flex items-center justify-between px-3" id="layout-topbar">
|
||||
<div class="inline-flex items-center gap-3">
|
||||
<label class="btn btn-square btn-ghost btn-sm group-has-[[id=layout-sidebar-hover-trigger]:checked]/html:hidden"
|
||||
aria-label="Leftmenu toggle" for="layout-sidebar-toggle-trigger">
|
||||
<span class="iconify lucide--menu size-5"></span>
|
||||
</label>
|
||||
<label
|
||||
class="btn btn-square btn-ghost btn-sm hidden group-has-[[id=layout-sidebar-hover-trigger]:checked]/html:flex"
|
||||
aria-label="Leftmenu toggle" for="layout-sidebar-hover-trigger">
|
||||
<span class="iconify lucide--menu size-5"></span>
|
||||
</label>
|
||||
<button
|
||||
class="btn btn-outline btn-sm btn-ghost border-base-300 text-base-content/70 hidden h-9 w-48 justify-start gap-2 !text-sm md:flex"
|
||||
onclick="document.getElementById('topbar-search-modal')?.showModal()">
|
||||
<span class="iconify lucide--search size-4"></span>
|
||||
<span>Tìm Kiếm</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-outline btn-sm btn-square btn-ghost border-base-300 text-base-content/70 flex size-9 md:hidden"
|
||||
aria-label="Search" onclick="document.getElementById('topbar-search-modal')?.showModal()">
|
||||
<span class="iconify lucide--search size-4"></span>
|
||||
</button>
|
||||
<dialog id="topbar-search-modal" class="modal p-0">
|
||||
<div class="modal-box bg-transparent p-0 shadow-none">
|
||||
<div class="bg-base-100 rounded-box">
|
||||
<div class="input w-full border-0 !outline-none">
|
||||
<span class="iconify lucide--search text-base-content/60 size-4.5"></span>
|
||||
<input type="search" class="grow" placeholder="Tìm kiếm" aria-label="Search" />
|
||||
<form method="dialog">
|
||||
<button class="btn btn-xs btn-circle btn-ghost" aria-label="Close">
|
||||
<span class="iconify lucide--x text-base-content/80 size-4"></span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="border-base-300 flex items-center gap-3 border-t px-2 py-2">
|
||||
<div class="flex items-center gap-0.5">
|
||||
<div
|
||||
class="border-base-300 bg-base-200 flex size-5 items-center justify-center rounded-sm border shadow-xs">
|
||||
<span class="iconify lucide--arrow-up size-3.5"></span>
|
||||
</div>
|
||||
<div
|
||||
class="border-base-300 bg-base-200 flex size-5 items-center justify-center rounded-sm border shadow-xs">
|
||||
<span class="iconify lucide--arrow-down size-3.5"></span>
|
||||
</div>
|
||||
<p class="text-base-content/80 ms-1 text-sm">Điều hướng</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-0.5 max-sm:hidden">
|
||||
<div
|
||||
class="border-base-300 bg-base-200 flex size-5 items-center justify-center rounded-sm border shadow-xs">
|
||||
<span class="iconify lucide--undo-2 size-3.5"></span>
|
||||
</div>
|
||||
<p class="text-base-content/80 ms-1 text-sm">Quay lại</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-0.5">
|
||||
<div
|
||||
class="border-base-300 bg-base-200 flex size-5 items-center justify-center rounded-sm border shadow-xs">
|
||||
<span class="iconify lucide--corner-down-left size-3.5"></span>
|
||||
</div>
|
||||
<p class="text-base-content/80 ms-1 text-sm">Mở</p>
|
||||
</div>
|
||||
<div class="ms-auto flex items-center gap-0.5">
|
||||
<div
|
||||
class="border-base-300 bg-base-200 flex h-5 items-center justify-center rounded-sm border px-1 text-sm/none shadow-xs">
|
||||
esc
|
||||
</div>
|
||||
<p class="text-base-content/80 ms-1 text-sm">Đóng</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-base-100 rounded-box mt-4">
|
||||
<div class="px-5 py-3">
|
||||
<p class="text-base-content/80 text-sm font-medium">I'm looking for...</p>
|
||||
<div class="mt-2 flex flex-wrap gap-1.5">
|
||||
<div
|
||||
class="border-base-300 hover:bg-base-200 rounded-box cursor-pointer border px-2.5 py-1 text-sm/none">
|
||||
Writer
|
||||
</div>
|
||||
<div
|
||||
class="border-base-300 hover:bg-base-200 rounded-box cursor-pointer border px-2.5 py-1 text-sm/none">
|
||||
Editor
|
||||
</div>
|
||||
<div
|
||||
class="border-base-300 hover:bg-base-200 rounded-box cursor-pointer border px-2.5 py-1 text-sm/none">
|
||||
Explainer
|
||||
</div>
|
||||
<div
|
||||
class="border-base-300 hover:bg-base-200 rounded-box flex cursor-pointer items-center gap-1 border border-dashed px-2.5 py-1 text-sm/none">
|
||||
<span class="iconify lucide--plus size-3.5"></span>
|
||||
Action
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="border-base-300 h-px border-dashed" />
|
||||
|
||||
<ul class="menu w-full pt-1">
|
||||
<li class="menu-title">Talk to assistant</li>
|
||||
<li>
|
||||
<div class="group">
|
||||
<div
|
||||
class="from-primary to-primary/80 mask mask-squircle text-primary-content flex size-5 items-center justify-center bg-linear-to-b leading-none font-medium">
|
||||
R
|
||||
</div>
|
||||
<p class="grow text-sm">Research Buddy</p>
|
||||
<div
|
||||
class="flex translate-x-2 items-center gap-2.5 opacity-0 transition-all duration-300 group-hover:translate-x-0 group-hover:opacity-100">
|
||||
<span class="iconify lucide--star text-orange-500"></span>
|
||||
<div class="flex items-center gap-0.5">
|
||||
<div
|
||||
class="border-base-300 flex size-5 items-center justify-center rounded-sm border shadow-xs">
|
||||
<span class="iconify lucide--corner-down-left size-3.5"></span>
|
||||
</div>
|
||||
<p class="ms-1 text-sm opacity-80">Select</p>
|
||||
</div>
|
||||
<span class="iconify lucide--ellipsis-vertical opacity-80"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="group">
|
||||
<div
|
||||
class="from-secondary to-secondary/80 mask mask-squircle text-secondary-content flex size-5 items-center justify-center bg-linear-to-b leading-none font-medium">
|
||||
T
|
||||
</div>
|
||||
<p class="grow text-sm">Task Planner</p>
|
||||
<div
|
||||
class="flex translate-x-2 items-center gap-2.5 opacity-0 transition-all duration-300 group-hover:translate-x-0 group-hover:opacity-100">
|
||||
<span class="iconify lucide--star text-orange-500"></span>
|
||||
<div class="flex items-center gap-0.5">
|
||||
<div
|
||||
class="border-base-300 flex size-5 items-center justify-center rounded-sm border shadow-xs">
|
||||
<span class="iconify lucide--corner-down-left size-3.5"></span>
|
||||
</div>
|
||||
<p class="ms-1 text-sm opacity-80">Select</p>
|
||||
</div>
|
||||
<span class="iconify lucide--ellipsis-vertical opacity-80"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="group">
|
||||
<div
|
||||
class="from-success to-success/80 mask mask-squircle text-success-content flex size-5 items-center justify-center bg-linear-to-b leading-none font-medium">
|
||||
S
|
||||
</div>
|
||||
<p class="grow text-sm">Sparking Ideas</p>
|
||||
<div
|
||||
class="flex translate-x-2 items-center gap-2.5 opacity-0 transition-all duration-300 group-hover:translate-x-0 group-hover:opacity-100">
|
||||
<span class="iconify lucide--star text-orange-500"></span>
|
||||
<div class="flex items-center gap-0.5">
|
||||
<div
|
||||
class="border-base-300 flex size-5 items-center justify-center rounded-sm border shadow-xs">
|
||||
<span class="iconify lucide--corner-down-left size-3.5"></span>
|
||||
</div>
|
||||
<p class="ms-1 text-sm opacity-80">Select</p>
|
||||
</div>
|
||||
<span class="iconify lucide--ellipsis-vertical opacity-80"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="group">
|
||||
<div
|
||||
class="from-warning to-warning/80 mask mask-squircle text-warning-content flex size-5 items-center justify-center bg-linear-to-b leading-none font-medium">
|
||||
D
|
||||
</div>
|
||||
<p class="grow text-sm">Docs Assistant</p>
|
||||
<div
|
||||
class="flex translate-x-2 items-center gap-2.5 opacity-0 transition-all duration-300 group-hover:translate-x-0 group-hover:opacity-100">
|
||||
<span class="iconify lucide--star text-orange-500"></span>
|
||||
<div class="flex items-center gap-0.5">
|
||||
<div
|
||||
class="border-base-300 flex size-5 items-center justify-center rounded-sm border shadow-xs">
|
||||
<span class="iconify lucide--corner-down-left size-3.5"></span>
|
||||
</div>
|
||||
<p class="ms-1 text-sm opacity-80">Select</p>
|
||||
</div>
|
||||
<span class="iconify lucide--ellipsis-vertical opacity-80"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr class="border-base-300 h-px border-dashed" />
|
||||
|
||||
<ul class="menu w-full pt-1">
|
||||
<li class="menu-title flex flex-row items-center justify-between gap-2">
|
||||
<span>Tasks Manager</span>
|
||||
<span>Progress</span>
|
||||
</li>
|
||||
<li>
|
||||
<div>
|
||||
<span class="iconify lucide--notebook size-4"></span>
|
||||
<p class="grow text-sm">Creating an essay</p>
|
||||
<progress class="progress progress-primary h-1 w-30" value="60" max="100"></progress>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div>
|
||||
<span class="iconify lucide--message-circle size-4"></span>
|
||||
<p class="grow text-sm">Summarizing chat</p>
|
||||
<progress class="progress progress-secondary h-1 w-30" value="80" max="100"></progress>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div>
|
||||
<span class="iconify lucide--code size-4"></span>
|
||||
<p class="grow text-sm">Fixing syntax</p>
|
||||
<progress class="progress progress-accent h-1 w-30" value="35" max="100"></progress>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div>
|
||||
<span class="iconify lucide--book-open size-4"></span>
|
||||
<p class="grow text-sm">Reading docs</p>
|
||||
<progress class="progress progress-info h-1 w-30" value="90" max="100"></progress>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div>
|
||||
<span class="iconify lucide--lightbulb size-4"></span>
|
||||
<p class="grow text-sm">Generating ideas</p>
|
||||
<progress class="progress progress-warning h-1 w-30" value="50" max="100"></progress>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
</div>
|
||||
<div class="inline-flex items-center gap-0.5">
|
||||
<div class="dropdown dropdown-bottom dropdown-center">
|
||||
<div tabindex="0" class="btn btn-ghost btn-circle btn-sm cursor-pointer">
|
||||
<img src="https://flagcdn.com/us.svg" alt="Avatar" class="rounded-box size-4.5 object-cover" />
|
||||
</div>
|
||||
<div tabindex="0" class="dropdown-content bg-base-100 rounded-box mt-2 w-40 shadow">
|
||||
<ul class="menu w-full p-2">
|
||||
<li>
|
||||
<a class="flex items-center gap-2" href="#">
|
||||
<img src="https://flagcdn.com/us.svg" alt="Avatar"
|
||||
class="rounded-box size-4.5 cursor-pointer object-cover" />
|
||||
<span>English</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="flex items-center gap-2" href="#">
|
||||
<img src="https://flagcdn.com/vn.svg" alt="Avatar"
|
||||
class="rounded-box size-4.5 cursor-pointer object-cover" />
|
||||
<span>Tiếng việt</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button aria-label="Toggle Theme" class="relative tw-dp btn btn-sm btn-circle btn-ghost"
|
||||
data-theme-control="toggle">
|
||||
<span
|
||||
class="iconify lucide--sun absolute size-4.5 -translate-y-4 opacity-0 transition-all duration-300 group-data-[theme=light]/html:translate-y-0 group-data-[theme=light]/html:opacity-100"></span>
|
||||
<span
|
||||
class="iconify lucide--moon absolute size-4.5 translate-y-4 opacity-0 transition-all duration-300 group-data-[theme=dark]/html:translate-y-0 group-data-[theme=dark]/html:opacity-100"></span>
|
||||
<span
|
||||
class="iconify lucide--palette absolute size-4.5 opacity-100 group-data-[theme=dark]/html:opacity-0 group-data-[theme=light]/html:opacity-0"></span>
|
||||
</button>
|
||||
|
||||
|
||||
<label for="layout-rightbar-drawer" class="btn btn-circle btn-ghost btn-sm drawer-button">
|
||||
<span class="iconify lucide--settings-2 size-4.5"></span>
|
||||
</label>
|
||||
<div class="dropdown dropdown-bottom sm:dropdown-end dropdown-center">
|
||||
<div tabindex="0" role="button" class="btn btn-circle btn-ghost btn-sm relative" aria-label="Notifications">
|
||||
<span class="iconify lucide--bell motion-preset-seesaw size-4.5"></span>
|
||||
<div class="status status-error status-sm absolute end-1 top-1"></div>
|
||||
</div>
|
||||
<div tabindex="0"
|
||||
class="dropdown-content bg-base-100 rounded-box mt-1 w-84 shadow-md duration-1000 hover:shadow-lg">
|
||||
<div class="bg-base-200/30 rounded-t-box border-base-200 border-b ps-4 pe-2 pt-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="font-medium">Notification</p>
|
||||
<button class="btn btn-xs btn-circle btn-ghost" aria-label="Close"
|
||||
onclick="document.activeElement.blur()">
|
||||
<span class="iconify lucide--x size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="-ms-2 mt-2 -mb-px flex items-center justify-between">
|
||||
<div role="tablist" class="tabs tabs-sm tabs-border">
|
||||
<div role="tab" class="tab tab-active gap-2 px-3 font-medium">
|
||||
<span>All</span>
|
||||
<div class="badge badge-sm">4</div>
|
||||
</div>
|
||||
<div role="tab" class="tab gap-2 px-3"><span>Team</span></div>
|
||||
<div role="tab" class="tab gap-2 px-3"><span>AI</span></div>
|
||||
<div role="tab" class="tab gap-2 px-3"><span>@mention</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hover:bg-base-200/20 relative flex items-start gap-3 p-4 transition-all">
|
||||
<div class="avatar avatar-online size-12">
|
||||
<img src="../../assets/images//avatars/2.png"
|
||||
class="from-primary/80 to-primary/60 mask mask-squircle bg-linear-to-b px-1 pt-1" alt="" />
|
||||
</div>
|
||||
<div class="grow">
|
||||
<p class="text-sm leading-tight">Lena submitted a draft for review.</p>
|
||||
<p class="text-base-content/60 text-xs">15 min ago</p>
|
||||
<div class="mt-2 flex items-center gap-2">
|
||||
<button class="btn btn-sm btn-primary">Approve</button>
|
||||
<button class="btn btn-sm btn-outline border-base-300">Decline</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="status status-primary absolute end-4 top-4 size-1.5"></div>
|
||||
</div>
|
||||
<hr class="border-base-300 border-dashed" />
|
||||
<div class="hover:bg-base-200/20 flex items-start gap-3 p-4 transition-all">
|
||||
<div class="avatar avatar-offline size-12">
|
||||
<img src="/images/avatars/4.png"
|
||||
class="from-secondary/80 to-secondary/60 mask mask-squircle bg-linear-to-b px-1 pt-1"
|
||||
alt="" />
|
||||
</div>
|
||||
<div class="grow">
|
||||
<p class="text-sm leading-tight">Kai mentioned you in a project.</p>
|
||||
<p class="text-base-content/60 text-xs">22 min ago</p>
|
||||
<div
|
||||
class="from-base-200 via-base-200/80 rounded-box mt-2 flex items-center justify-between gap-2 bg-linear-to-r to-transparent py-1 ps-2.5">
|
||||
<p class="text-sm">Check model inputs?</p>
|
||||
<button class="btn btn-xs btn-ghost text-xs">
|
||||
<span class="iconify lucide--reply size-3.5"></span>
|
||||
Reply
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="border-base-300 border-dashed" />
|
||||
<div class="hover:bg-base-200/20 flex items-start gap-3 p-4 transition-all">
|
||||
<div class="avatar size-12">
|
||||
<img src="/images/avatars/5.png"
|
||||
class="mask mask-squircle bg-linear-to-b from-orange-500/80 to-orange-500/60 px-1 pt-1"
|
||||
alt="" />
|
||||
</div>
|
||||
<div class="grow">
|
||||
<p class="text-sm leading-tight">Your latest results are ready</p>
|
||||
<div
|
||||
class="border-base-200 rounded-box mt-2 flex items-center justify-between gap-2 border px-2.5 py-1.5">
|
||||
<p class="text-sm">
|
||||
Forecast Report
|
||||
<span class="text-base-content/60 text-xs">(12 MB)</span>
|
||||
</p>
|
||||
<button class="btn btn-xs btn-square btn-ghost text-xs">
|
||||
<span class="iconify lucide--arrow-down-to-line size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="border-base-200 rounded-box mt-2 flex items-center justify-between gap-2 border px-2.5 py-1.5">
|
||||
<p class="text-sm">
|
||||
Generated Summary
|
||||
<span class="text-base-content/60 text-xs">(354 KB)</span>
|
||||
</p>
|
||||
<button class="btn btn-xs btn-square btn-ghost text-xs">
|
||||
<span class="iconify lucide--arrow-down-to-line size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="border-base-200" />
|
||||
<div class="flex items-center justify-between px-2 py-2">
|
||||
<button class="btn btn-sm btn-soft btn-primary">View All</button>
|
||||
<div class="flex items-center gap-1">
|
||||
<button class="btn btn-sm btn-square btn-ghost">
|
||||
<span class="iconify lucide--check-check size-4"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-square btn-ghost">
|
||||
<span class="iconify lucide--bell-ring size-4"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-square btn-ghost">
|
||||
<span class="iconify lucide--settings size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drawer drawer-end">
|
||||
<input id="topbar-profile-drawer" type="checkbox" class="drawer-toggle" />
|
||||
<div class="drawer-content">
|
||||
<label for="topbar-profile-drawer" class="btn btn-ghost flex items-center gap-2 px-1.5">
|
||||
<div class="avatar">
|
||||
<div class="bg-base-200 mask mask-squircle w-8">
|
||||
<img src="../../assets/images/avatars/1.png" alt="Avatar" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-start">
|
||||
<p class="text-sm/none">Denish</p>
|
||||
<p class="text-base-content/50 mt-0.5 text-xs/none">Team</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="drawer-side">
|
||||
<label for="topbar-profile-drawer" aria-label="close sidebar" class="drawer-overlay"></label>
|
||||
<div class="h-full w-72 p-2 sm:w-84">
|
||||
<div class="bg-base-100 rounded-box relative flex h-full flex-col pt-4 sm:pt-8">
|
||||
<label for="topbar-profile-drawer"
|
||||
class="btn btn-xs btn-circle btn-ghost absolute start-2 top-2" aria-label="Close">
|
||||
<span class="iconify lucide--x size-4"></span>
|
||||
</label>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="relative">
|
||||
<div
|
||||
class="avatar bg-base-200 isolate size-20 cursor-pointer overflow-hidden rounded-full px-1 pt-1 md:size-24">
|
||||
<img src="/images/avatars/1.png" alt="User Avatar" />
|
||||
</div>
|
||||
<div
|
||||
class="bg-base-100 absolute end-0 bottom-0 flex items-center justify-center rounded-full p-1.5 shadow-sm">
|
||||
<span class="iconify lucide--pencil size-4"></span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-4 text-lg/none font-medium sm:mt-8">John Doe</p>
|
||||
<p class="text-base-content/60 mt-1 text-sm">john@company.com</p>
|
||||
<div class="mt-4 flex items-center gap-2 *:cursor-pointer sm:mt-6">
|
||||
<div class="avatar bg-base-200 size-10 overflow-hidden rounded-full px-1 pt-1">
|
||||
<img src="/images/avatars/2.png" alt="Team member" />
|
||||
</div>
|
||||
<div class="avatar bg-base-200 size-10 overflow-hidden rounded-full px-1 pt-1">
|
||||
<img src="/images/avatars/3.png" alt="Team member" />
|
||||
</div>
|
||||
<div class="avatar bg-base-200 size-10 overflow-hidden rounded-full px-1 pt-1">
|
||||
<img src="/images/avatars/4.png" alt="Team member" />
|
||||
</div>
|
||||
<div
|
||||
class="bg-base-200 border-base-300 flex size-10 items-center justify-center rounded-full border border-dashed">
|
||||
<span class="iconify lucide--plus size-4.5"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-base-300 mt-4 grow overflow-auto border-t border-dashed px-2 sm:mt-6">
|
||||
<ul class="menu w-full p-2">
|
||||
<li class="menu-title">Account</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<span class="iconify lucide--user size-4.5"></span>
|
||||
<span>View Profile</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<span class="iconify lucide--users size-4.5"></span>
|
||||
<span>Team</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<span class="iconify lucide--mail-plus size-4.5"></span>
|
||||
<span>Invites</span>
|
||||
<div class="badge badge-sm">4</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu-title">Platform</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<span class="iconify lucide--settings size-4.5"></span>
|
||||
<span>Settings</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<span class="iconify lucide--credit-card size-4.5"></span>
|
||||
<span>Billing</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<span class="iconify lucide--help-circle size-4.5"></span>
|
||||
<span>Support</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="text-error hover:bg-error/10" href="#">
|
||||
<span class="iconify lucide--log-out size-4.5"></span>
|
||||
<span>Sign Out</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-box from-primary to-secondary text-primary-content m-4 mt-auto flex cursor-pointer flex-col items-center justify-center bg-linear-to-br p-4 text-center transition-all hover:opacity-95 sm:p-6">
|
||||
<div
|
||||
class="bg-primary-content/10 border-primary-content/10 flex items-center justify-center rounded-full border p-1.5 sm:p-2.5">
|
||||
<span class="iconify lucide--zap size-5 sm:size-6"></span>
|
||||
</div>
|
||||
<p
|
||||
class="mt-2 font-mono text-[11px] font-medium tracking-wider uppercase opacity-70 sm:mt-4">
|
||||
Upgrade your plan
|
||||
</p>
|
||||
<p class="mt-1 leading-none font-medium sm:text-lg">
|
||||
Save
|
||||
<span class="font-semibold underline">30%</span>
|
||||
today
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End: Layout - Topbar -->
|
||||
@@ -7,198 +7,50 @@
|
||||
<title> Admin Hura Pc </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap"
|
||||
rel="stylesheet">
|
||||
<link rel="stylesheet" media="screen" href="{{ 'daisyui.css' | asset_url }}?v12.11" />
|
||||
<link rel="stylesheet" media="screen" href="{{ 'extension_daisyui.css' | asset_url }}?v2025.02" />
|
||||
<script src="{{ 'tailwindcss.js' | asset_url }}"></script>
|
||||
<script>
|
||||
try {
|
||||
const localStorageItem = localStorage.getItem("__NEXUS_CONFIG_v3.0__")
|
||||
if (localStorageItem) {
|
||||
const theme = JSON.parse(localStorageItem).theme
|
||||
if (theme !== "system") {
|
||||
document.documentElement.setAttribute("data-theme", theme)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet" href="{{'style.css' | asset_url}}?v=1.01">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="overlay" onclick="clickBackground()"></div>
|
||||
<div class="size-full">
|
||||
<div class="flex">
|
||||
|
||||
<div class="admin-global-container">
|
||||
{% include "other/header" %}
|
||||
|
||||
<!-- Menu full -->
|
||||
<div class="admin-menu-container box-menu" id="js-menu-big">
|
||||
<a href="" class="menu-logo">
|
||||
<img src="{{ 'logo.png' | asset_url }}" />
|
||||
</a>
|
||||
<div class="flex h-screen min-w-0 grow flex-col overflow-auto">
|
||||
|
||||
<div class="menu-list m-[25px_5px]">
|
||||
<a href="/"
|
||||
class="item flex items-center cursor-pointer p-[0_12px] rounded-[4px] relative delay-300 transition-all bg-[#004e99] mb-[4px] leading-[36px] {% if global.module == 'home' %} active {% endif %}">
|
||||
<i class="icons icon-home"></i>
|
||||
<span class="title"> Home </span>
|
||||
</a>
|
||||
{% include "other/topbar" %}
|
||||
|
||||
{% for _category in global.main_menu %}
|
||||
{% assign _type = _category[0] %}
|
||||
{% assign _menuArray = _category[1].menu %}
|
||||
{% if _category[1].enable == 1 %}
|
||||
<div class="relative w-[100%] box-item" {% if _type==global.module %} open {% endif %}>
|
||||
<div class="item flex items-center justify-between cursor-pointer p-[0_12px] rounded-[4px] relative delay-300 transition-all bg-[#004e99] mb-[4px] leading-[36px]
|
||||
{% if _type == global.module %} active {% endif %}" onclick="toggleSubMenu('{{ _type }}')">
|
||||
<div class="flex items-center">
|
||||
{% if _type == 'order' %} <i class="icons w-[20px] h-[20px] mr-[13px] icon-order"></i>
|
||||
{% elsif _type == 'product' %} <i
|
||||
class="icons w-[20px] h-[20px] mr-[13px] icon-product"></i>
|
||||
{% elsif _type == 'customer' %}<i
|
||||
class="icons w-[20px] h-[20px] mr-[13px] icon-customer"></i>
|
||||
{% elsif _type == 'marketing' %}<i
|
||||
class="icons w-[20px] h-[20px] mr-[13px] icon-marketing"></i>
|
||||
{% elsif _type == 'investor_relation' %} <i
|
||||
class="icons w-[20px] h-[20px] mr-[13px] icon-investor_relation"></i>
|
||||
{% elsif _type == 'article' %} <i class="icons icon-content"></i>
|
||||
{% elsif _type == 'job' %} <i class="icons w-[20px] h-[20px] mr-[13px] icon-job"></i>
|
||||
{% elsif _type == 'pcbuilder' %} <i
|
||||
class="icons w-[20px] h-[20px] mr-[13px] icon-pcbuilder"></i>
|
||||
{% elsif _type == 'payinstall' %} <i
|
||||
class="icons w-[20px] h-[20px] mr-[13px] icon-payinstall"></i>
|
||||
{% elsif _type == 'distributor' %} <i
|
||||
class="icons w-[20px] h-[20px] mr-[13px] icon-distributor"></i>
|
||||
{% elsif _type == 'report' %}<i class="icons w-[20px] h-[20px] mr-[13px] icon-stats"></i>
|
||||
{% elsif _type == 'system' %}<i class="icons w-[20px] h-[20px] mr-[13px] icon-system"></i>
|
||||
{% endif %}
|
||||
|
||||
<span class="title text-[14px]"> {{ _category[1].name }} </span>
|
||||
</div>
|
||||
|
||||
<i class="fa-solid fa-chevron-right"></i>
|
||||
</div>
|
||||
|
||||
<div class="sub-menu text-[14px]" id="{{ _type }}">
|
||||
{% for _item in _menuArray %}
|
||||
<a href="{{ _item.url }}"
|
||||
class="p-[8px_16px] flex items-center {% if _item.view == global.view and _item.module == global.module %}current {% endif %}">
|
||||
{{_item.name }} </a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="hover-menu {% if _type == 'system' or _type == 'report' %}bottom{% endif %}">
|
||||
{% for _item in _menuArray %}
|
||||
<a href="{{ _item.url }}"
|
||||
class="flex items-center {% if _item.view == global.view and _item.module == global.module %}current {% endif %}">
|
||||
{{_item.name }} </a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<a href=""
|
||||
class="item flex items-center cursor-pointer p-[0_12px] rounded-[4px] relative delay-300 transition-all bg-[#004e99] mb-[4px] leading-[36px]">
|
||||
<i class="icons w-[20px] h-[20px] mr-[13px] icon-account"></i>
|
||||
<span class="title text-[14px]">Quản lý tài khoản </span>
|
||||
</a>
|
||||
<a href=""
|
||||
class="item flex items-center cursor-pointer p-[0_12px] rounded-[4px] relative delay-300 transition-all bg-[#004e99] mb-[4px] leading-[36px]">
|
||||
<i class="icons w-[20px] h-[20px] mr-[13px] icon-settings"></i>
|
||||
<span class="title text-[14px]"> Cài đặt </span>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<div class="box-hover" id="js-hover-menu">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="admin-content-container h-screen" id="js-admin-content-container">
|
||||
<!-- Header -->
|
||||
<div
|
||||
class="admin-header-container flex items-center justify-between bg-white px-4 py-3 sticky top-0 z-[99] border-b-[1px] border-[#eef0f2]">
|
||||
<div class="flex items-center">
|
||||
<form class="w-[420px] relative w-[100%] menu-hide" id="js-form-search">
|
||||
<div
|
||||
class="content w-[100%] flex items-center border-[#ECECEC] border-[1px] rounded-[5px] focus-within:border-[#0041E8]">
|
||||
<div class="inset-y-0 start-0 flex items-center ps-3 pointer-events-none">
|
||||
<i class="icons icon-search"></i>
|
||||
</div>
|
||||
|
||||
<input type="search" class="block h-[36px] rounded w-full" id="js-input-search"
|
||||
placeholder="Tìm kiếm">
|
||||
</div>
|
||||
<div class="autocomplete-suggestions absolute bg-white w-[100%] shadow-[0_2px_7px_0_rgb(177_177_177)] hidden rounded-[4px]"
|
||||
id="js-show-search">
|
||||
<a href="" class="item line-clamp-1">Máy in mã vạch MH241</a>
|
||||
<a href="" class="item line-clamp-1">Chăn hè đũi xơ đậu nành mã 32 Gấu xanh</a>
|
||||
<a href="" class="item line-clamp-1">Máy đo độ bóng Horiba IG-320 (gloss meter)</a>
|
||||
<a href="" class="item line-clamp-1">iPhone 11 Chính Hãng</a>
|
||||
<a href="" class="item line-clamp-1">cpu core i3 1</a>
|
||||
<a href="" class="item line-clamp-1">Máy in mã vạch MH241</a>
|
||||
<a href="" class="item line-clamp-1">Chăn hè đũi xơ đậu nành mã 32 Gấu xanh</a>
|
||||
<a href="" class="item line-clamp-1">Máy đo độ bóng Horiba IG-320 (gloss meter)</a>
|
||||
<a href="" class="item line-clamp-1">iPhone 11 Chính Hãng</a>
|
||||
<a href="" class="item line-clamp-1">cpu core i3 1</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="admin-header-right flex items-center justify-end">
|
||||
<a href="" title="Truy cập trung tâm hỗ trợ của Hurasoft">
|
||||
<i class="icons header-support"></i>
|
||||
</a>
|
||||
|
||||
<div
|
||||
class="group relative cursor-pointer ml-[20px] mr-[35px] group [&_summary::-webkit-details-marker]:hidden">
|
||||
<div class="relative flex">
|
||||
<i class="icons icon-notification"></i>
|
||||
|
||||
<span
|
||||
class="absolute bg-[#E00000] font-[500] h-[17px] leading-[17px] note right-[-5px] rounded-lg text-[#fff] text-[13px] text-center top-[-3px] w-[17px]">
|
||||
0
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="group-hover:block hidden absolute bg-white leading-[30px] note-list shadow whitespace-nowrap z-[-1] rounded-[4px] right-[-10px]">
|
||||
<a href=""> Menu title </a>
|
||||
<a href=""> Menu title </a>
|
||||
<a href=""> Menu title </a>
|
||||
<a href=""> Menu title </a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group relative cursor-pointer group [&_summary::-webkit-details-marker]:hidden">
|
||||
<div class="flex items-center">
|
||||
<p class="m-0 mr-[10px]"> ducdt@hurasoft.com </p>
|
||||
|
||||
<img src="https://via.placeholder.com/72x72"
|
||||
class="block rounded-[50%] w-[36px] h-[36px] mr-[8px]" />
|
||||
|
||||
<i class="fa-solid fa-sort-down text-[#C9C9C9] mb-[3px]"></i>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="group-hover:block hidden absolute bg-white leading-[30px] note-list shadow whitespace-nowrap z-[-1] rounded-[4px] right-0">
|
||||
<a href="">Đổi mật khẩu</a>
|
||||
<a href="">Thoát quản trị</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="layout-content">
|
||||
{{ page_content }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Content -->
|
||||
{{ page_content }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-notificatiom">
|
||||
<a href="javascript:void(0)" class="icon-close" onclick="AdminFunction.closeForm()"><i
|
||||
class="fa fa-times"></i></a>
|
||||
<div class="content flex flex-col items-center justify-center">
|
||||
<i class="fa fa-check"></i>
|
||||
<b>Cập nhật thành công</b>
|
||||
<p>Đơn hàng #000-368 đã được cập nhật thành công</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{{ 'jquery.js' | asset_url }}"></script>
|
||||
<script src="{{ 'global.js' | asset_url }}"></script>
|
||||
|
||||
|
||||
{% include javascript/index %}
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"target": "esnext",
|
||||
"module": "nodenext",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
@@ -9,7 +9,8 @@
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"moduleResolution": "node" // Thay đổi giá trị này từ 'classic' thành 'node'
|
||||
"moduleResolution": "node16",
|
||||
"ignoreDeprecations": "6.0"
|
||||
},
|
||||
"include": ["./assets/typescript/main.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
|
||||
@@ -1,15 +1,72 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { defineConfig } from "vite"
|
||||
import injectHTML from "vite-plugin-html-inject"
|
||||
import { resolve } from "node:path"
|
||||
import fs from "node:fs"
|
||||
import tailwindcss from "@tailwindcss/vite"
|
||||
import { fileURLToPath } from "node:url"
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
build: {
|
||||
outDir: './assets/dist',
|
||||
minify: false,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
entryFileNames: '[name].js', // Đổi tên của các file JavaScript đầu ra
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url))
|
||||
|
||||
const getHtmlFiles = (dir: string): string[] => {
|
||||
let results: string[] = []
|
||||
const list = fs.readdirSync(dir)
|
||||
list.forEach((file) => {
|
||||
file = resolve(dir, file)
|
||||
const stat = fs.statSync(file)
|
||||
if (stat && stat.isDirectory()) {
|
||||
if (file.endsWith("/partials")) {
|
||||
return
|
||||
}
|
||||
results = results.concat(getHtmlFiles(file))
|
||||
} else if (file.endsWith(".html")) {
|
||||
results.push(file)
|
||||
}
|
||||
})
|
||||
return results
|
||||
}
|
||||
|
||||
// Normalize the paths to ensure consistent forward slashes
|
||||
const normalizePath = (path: string): string => path.split(resolve(__dirname, "src")).join("").replace(/\\/g, "/")
|
||||
|
||||
// Use normalizePath function to process the paths correctly
|
||||
const htmlFiles = getHtmlFiles("src")
|
||||
const input = Object.fromEntries(
|
||||
htmlFiles.map((file) => [normalizePath(file).replace(".html", "").replace(/^\//, ""), file])
|
||||
)
|
||||
|
||||
const removecors = () => {
|
||||
return {
|
||||
name: "remove-cors",
|
||||
transformIndexHtml: {
|
||||
order: "post" as const,
|
||||
handler(html: string) {
|
||||
return html.replace(/crossorigin\s*/g, "")
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
base: "",
|
||||
server: {
|
||||
open: "/",
|
||||
},
|
||||
});
|
||||
publicDir: "../public",
|
||||
plugins: [injectHTML(), removecors(), tailwindcss()],
|
||||
root: "src",
|
||||
optimizeDeps: {
|
||||
include: ["filepond", "filepond-plugin-image-preview"],
|
||||
},
|
||||
build: {
|
||||
outDir: "../html",
|
||||
emptyOutDir: true,
|
||||
rollupOptions: {
|
||||
input,
|
||||
output: {
|
||||
entryFileNames: `assets/script/[name].js`,
|
||||
chunkFileNames: `assets/script/[name].js`,
|
||||
assetFileNames: `assets/script/[name].[ext]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||