Browse Source

feat: integrate CoreUI for improved layout and UI, implement dynamic theme switching with dark mode support, and enhance DataTables with custom feature configurations.

master
Syarif Ubaidillah 2 weeks ago
parent
commit
07b402379c
  1. 18
      .ai/mcp/mcp.json
  2. 20
      app/Http/DataTables/Identity/UserDataTable.php
  3. 37
      package-lock.json
  4. 1
      package.json
  5. 96
      resources/js/bootstrap.js
  6. 20
      resources/js/plugin/datatables.js
  7. 31
      resources/js/sidebar.js
  8. 153
      resources/scss/_avatar.scss
  9. 34
      resources/scss/_border.scss
  10. 39
      resources/scss/_button.scss
  11. 138
      resources/scss/_custom.scss
  12. 50
      resources/scss/_icon-shape.scss
  13. 59
      resources/scss/_utilities.scss
  14. 141
      resources/scss/_variables.scss
  15. 74
      resources/scss/app.scss
  16. 3
      resources/scss/plugin/apexchart.scss
  17. 383
      resources/scss/plugin/datatables.scss
  18. 47
      resources/scss/plugin/filepond.scss
  19. 453
      resources/scss/plugin/select2.scss
  20. 90
      resources/scss/plugin/sweetalert.scss
  21. 1618
      resources/scss/style.css
  22. 52
      resources/views/components/layouts/app.blade.php
  23. 38
      resources/views/components/layouts/nav/sidebar.blade.php
  24. 5
      resources/views/components/layouts/nav/sidebar/nav-link.blade.php
  25. 74
      resources/views/components/layouts/nav/topbar.blade.php
  26. 2
      resources/views/components/layouts/⚡language-switcher/language-switcher.blade.php
  27. 2
      resources/views/components/layouts/⚡notification/notification.blade.php
  28. 39
      resources/views/pages/identity/users/index.blade.php

18
.ai/mcp/mcp.json

@ -1,11 +1,11 @@
{ {
"mcpServers": { "mcpServers": {
"laravel-boost": { "laravel-boost": {
"command": "php", "command": "php",
"args": [ "args": [
"artisan", "artisan",
"boost:mcp" "boost:mcp"
] ]
}
} }
} }
}

20
app/Http/DataTables/Identity/UserDataTable.php

@ -103,12 +103,30 @@ class UserDataTable extends DataTable
->orderBy(-1) ->orderBy(-1)
->layout([ ->layout([
'topStart' => [ 'topStart' => [
'rowClass' => 'row gap-1',
'className' => 'col-md-auto me-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-start align-items-center align-items-md-start gap-1', 'className' => 'col-md-auto me-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-start align-items-center align-items-md-start gap-1',
'features' => ['buttons', 'pageLength'], 'features' => ['buttons', 'pageLength'],
], ],
'topEnd' => [ 'topEnd' => [
'className' => 'col-md-auto ms-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-end align-items-center align-items-md-start gap-1', 'className' => 'col-md-auto ms-auto d-flex flex-sm-row flex-column justify-content-center justify-content-md-end align-items-center align-items-md-start gap-1',
'features' => ['status-filter', 'role-filter', 'search'], 'features' => [
// 1. Pass your first custom filter layout option cleanly mapping to the target element ID
[
'custom-features' => [
'targetId' => 'template-role-filter',
'style' => 'width: 200px;'
]
],
// 2. Pass your second custom filter layout option
[
'custom-features' => [
'targetId' => 'template-status-filter',
'style' => 'width: 200px;'
]
],
// Keep your original native layout features running seamlessly alongside them
'search'
],
], ],
'bottomStart' => 'info', 'bottomStart' => 'info',

37
package-lock.json

@ -1,10 +1,11 @@
{ {
"name": "laravel-base", "name": "keuangan-uniba",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"@coreui/coreui": "^5.8.0",
"datatables.net-bs5": "^2.3.7", "datatables.net-bs5": "^2.3.7",
"datatables.net-dt": "^2.3.7", "datatables.net-dt": "^2.3.7",
"datatables.net-fixedcolumns": "^5.0.5", "datatables.net-fixedcolumns": "^5.0.5",
@ -32,6 +33,24 @@
"vite": "^8.0.7" "vite": "^8.0.7"
} }
}, },
"node_modules/@coreui/coreui": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@coreui/coreui/-/coreui-5.8.0.tgz",
"integrity": "sha512-92v/kpla3YaGzAchwSEALRoouV0EQMiljEcaMQ7UqbMBISSoRCUtO+UbeiVBmRQTOdaJSJIu4rh3IwP+2QbKcQ==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/coreui"
}
],
"license": "MIT",
"dependencies": {
"html-entities": "^2.6.0"
},
"peerDependencies": {
"@popperjs/core": "^2.11.8"
}
},
"node_modules/@emnapi/core": { "node_modules/@emnapi/core": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz",
@ -2094,6 +2113,22 @@
"minimalistic-crypto-utils": "^1.0.1" "minimalistic-crypto-utils": "^1.0.1"
} }
}, },
"node_modules/html-entities": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz",
"integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/mdevils"
},
{
"type": "patreon",
"url": "https://patreon.com/mdevils"
}
],
"license": "MIT"
},
"node_modules/https-browserify": { "node_modules/https-browserify": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",

1
package.json

@ -21,6 +21,7 @@
"vite": "^8.0.7" "vite": "^8.0.7"
}, },
"dependencies": { "dependencies": {
"@coreui/coreui": "^5.8.0",
"datatables.net-bs5": "^2.3.7", "datatables.net-bs5": "^2.3.7",
"datatables.net-dt": "^2.3.7", "datatables.net-dt": "^2.3.7",
"datatables.net-fixedcolumns": "^5.0.5", "datatables.net-fixedcolumns": "^5.0.5",

96
resources/js/bootstrap.js

@ -1,4 +1,94 @@
import * as bootstrap from 'bootstrap'; import * as coreui from '@coreui/coreui';
import './sidebar.js' window.coreui = coreui;
window.bootstrap = bootstrap const THEME = 'coreui-free-bootstrap-admin-template-theme';
// Helper functions declared outside of event scopes so they stay clean
const getStoredTheme = () => localStorage.getItem(THEME);
const setStoredTheme = theme => localStorage.setItem(THEME, theme);
const getPreferredTheme = () => {
const storedTheme = getStoredTheme();
if (storedTheme) return storedTheme;
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
};
const setTheme = theme => {
if (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-coreui-theme', 'dark');
} else {
document.documentElement.setAttribute('data-coreui-theme', theme);
}
document.documentElement.dispatchEvent(new Event('ColorSchemeChange'));
};
const showActiveTheme = theme => {
const btnToActive = document.querySelector(`[data-coreui-theme-value="${theme}"]`);
if (!btnToActive) return; // Guard clause in case toggle buttons aren't on the current page
const activeThemeIcon = document.querySelector('.theme-icon-active');
const svgOfActiveBtn = btnToActive.querySelector('svg');
for (const element of document.querySelectorAll('[data-coreui-theme-value]')) {
element.classList.remove('active');
}
btnToActive.classList.add('active');
if (activeThemeIcon && svgOfActiveBtn) {
const useElement = svgOfActiveBtn.querySelector('use');
if (useElement) {
const activeUseElement = activeThemeIcon.querySelector('use');
if (activeUseElement) {
activeUseElement.setAttribute('xlink:href', useElement.getAttribute('xlink:href'));
}
} else {
activeThemeIcon.innerHTML = svgOfActiveBtn.innerHTML;
}
}
};
// 1. Run theme initialization immediately on file execution to prevent dark-mode flashbangs
(() => {
const urlParams = new URLSearchParams(window.location.href.split('?')[1]);
if (urlParams.get('theme') && ['auto', 'dark', 'light'].includes(urlParams.get('theme'))) {
localStorage.setItem(THEME, urlParams.get('theme'));
}
setTheme(getPreferredTheme());
})();
// System preferences watcher
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
const storedTheme = getStoredTheme();
if (storedTheme !== 'light' && storedTheme !== 'dark') {
setTheme(getPreferredTheme());
}
});
// 2. CORE LIVEWIRE FIX: Run UI bindings on every single page navigation step
document.addEventListener('livewire:navigated', () => {
const preferredTheme = getPreferredTheme();
// initiate sidebar toggle
const toggleButton = document.querySelector('.header-toggler');
const sidebar = document.querySelector('.sidebar');
if(toggleButton) {
toggleButton.addEventListener('click', () => {
window.coreui.Sidebar.getOrCreateInstance(sidebar).toggle();
})
}
// Ensure the state continues to match after navigation
setTheme(preferredTheme);
showActiveTheme(preferredTheme);
// Re-attach query click listeners to newly swapped DOM elements
for (const toggle of document.querySelectorAll('[data-coreui-theme-value]')) {
toggle.addEventListener('click', () => {
const theme = toggle.getAttribute('data-coreui-theme-value');
setStoredTheme(theme);
setTheme(theme);
showActiveTheme(theme);
});
}
});

20
resources/js/plugin/datatables.js

@ -5,8 +5,8 @@ window.ModulesFullyLoaded = false;
window.DataTableLockedQueue = window.DataTableLockedQueue || []; window.DataTableLockedQueue = window.DataTableLockedQueue || [];
import('laravel-datatables-vite').then(() => { import('laravel-datatables-vite').then(() => {
document.dispatchEvent(new CustomEvent('DOMContentLoaded'))
window.ModulesFullyLoaded = true; window.ModulesFullyLoaded = true;
document.dispatchEvent(new CustomEvent('DOMContentLoaded'))
window.checkAndFlushDataTables(); window.checkAndFlushDataTables();
}); });
@ -21,6 +21,24 @@ window.addEventListener('yajra:boot', (event) => {
try { try {
window.LaravelDataTables = window.LaravelDataTables || {}; window.LaravelDataTables = window.LaravelDataTables || {};
window.DataTable.feature.register('custom-features', function (settings, opts) {
let container = document.createElement('div');
// Fallback styles if none are provided dynamically
container.style = opts.style || 'width: 250px;';
// Look for a targeting template element or fallback to inline html string
if (opts.targetId) {
const template = document.getElementById(opts.targetId);
if (template) {
container.innerHTML = template.innerHTML;
}
} else if (opts.html) {
container.innerHTML = opts.html;
}
return container;
});
window.LaravelDataTables[id] = $el.DataTable(config); window.LaravelDataTables[id] = $el.DataTable(config);
} catch (e) { } catch (e) {
console.error(`Failed to boot DataTable [${id}]:`, e); console.error(`Failed to boot DataTable [${id}]:`, e);

31
resources/js/sidebar.js

@ -1,31 +0,0 @@
const sidebar = document.getElementById('sidebar');
const content = document.getElementById('content');
const topbar = document.getElementById('topbar');
const toggleBtn = document.getElementById('toggleBtn');
const mobileBtn = document.getElementById('mobileBtn');
const overlay = document.getElementById('overlay');
// Desktop collapse
if (toggleBtn) {
toggleBtn.addEventListener('click', () => {
if (sidebar) sidebar.classList.toggle('collapsed');
if (content) content.classList.toggle('full');
if (topbar) topbar.classList.toggle('full');
});
}
// Mobile sidebar open
if (mobileBtn) {
mobileBtn.addEventListener('click', () => {
if (sidebar) sidebar.classList.add('mobile-show');
if (overlay) overlay.classList.add('show');
});
}
// 🔥 Click outside to close
if (overlay) {
overlay.addEventListener('click', () => {
if (sidebar) sidebar.classList.remove('mobile-show');
if (overlay) overlay.classList.remove('show');
});
}

153
resources/scss/_avatar.scss

@ -1,153 +0,0 @@
// Avatar
.avatar {
position: relative;
display: inline-block;
width: 3rem;
height: 3rem;
}
// Avatar Size
.avatar-xs {
width: $avatar-size-xs;
height: $avatar-size-xs;
}
.avatar-sm {
width: $avatar-size-sm;
height: $avatar-size-sm;
}
.avatar-md {
width: $avatar-size-md;
height: $avatar-size-md;
}
.avatar-lg {
width: $avatar-size-lg;
height: $avatar-size-lg;
}
.avatar-xl {
width: $avatar-size-xl;
height: $avatar-size-xl;
}
.avatar-xxl {
width: $avatar-size-xxl;
height: $avatar-size-xxl;
}
// Avatar img
.avatar img {
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
}
.avatar-indicators {
position: relative;
}
.avatar-indicators:before {
content: '';
position: absolute;
bottom: 0px;
right: 5%;
width: 30%;
height: 30%;
border-radius: 50%;
border: 2px solid var(--#{$prefix}white);
display: table;
}
.avatar-xxl.avatar-indicators:before {
bottom: 5px;
right: 17%;
width: 16%;
height: 16%;
}
// Avatar indicators
.avatar-offline:before {
background-color: var(--#{$prefix}gray-400);
}
.avatar-online:before {
background-color: $success;
}
.avatar-away:before {
background-color: $warning;
}
.avatar-busy:before {
background-color: $danger;
}
.avatar-info:before {
background-color: $info;
}
// Avatar intials
.avatar-initials {
display: -ms-flexbox;
display: flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
height: 100%;
pointer-events: none;
text-transform: uppercase;
}
// Color varient
.avatar-primary .avatar-initials {
color: var(--#{$prefix}white);
background-color: $primary;
}
.avatar-secondary .avatar-initials {
color: var(--#{$prefix}white);
background-color: $secondary;
}
.avatar-success .avatar-initials {
color: var(--#{$prefix}white);
background-color: $success;
}
.avatar-warning .avatar-initials {
color: var(--#{$prefix}white);
background-color: $warning;
}
.avatar-info .avatar-initials {
color: var(--#{$prefix}white);
background-color: $info;
}
.avatar-danger .avatar-initials {
color: var(--#{$prefix}white);
background-color: $danger;
}
.avatar-light .avatar-initials {
color: var(--#{$prefix}white);
background-color: $light;
}
.avatar-dark .avatar-initials {
color: var(--#{$prefix}white);
background-color: $dark;
}
// Avatar Group
.avatar-group .avatar + .avatar {
margin-left: -1.2rem;
}
.avatar-group .avatar:hover {
z-index: 2;
}
// Avatar border
.avatar-group img,
.avatar-group .avatar .avatar-initials {
border: 2px solid var(--#{$prefix}white);
}

34
resources/scss/_border.scss

@ -1,34 +0,0 @@
// Border dashed
.border-dashed {
--ds-border-style: dashed;
}
.timeline-vertical {
position: relative;
.timeline-item {
.timeline-bar {
position: absolute;
height: 100px;
left: 5px;
top: 24px;
}
}
}
.timeline-vertical-height {
.timeline-item {
.timeline-bar {
height: calc(100% - 1rem) !important;
}
}
}
// vr border
.vr {
display: inline-block;
align-self: stretch;
width: $vr-border-width;
min-height: 1em;
background-color: var(--#{$prefix}border-color) !important;
opacity: $hr-opacity;
}

39
resources/scss/_button.scss

@ -1,39 +0,0 @@
.btn * {
// disable pointer event
pointer-events: none;
}
.btn-icon {
position: relative;
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-negative: 0;
flex-shrink: 0;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
font-size: 0.92969rem;
font-weight: 400;
width: 2.5rem;
height: 2.5rem;
padding: 0;
}
.btn-icon.btn-xs {
font-size: 0.75rem;
width: 1.75rem;
height: 1.75rem;
}
.btn-icon.btn-sm {
font-size: 0.875rem;
width: 2.1875rem;
height: 2.1875rem;
}
.btn-icon.btn-lg {
font-size: 1rem;
width: 3.36875rem;
height: 3.36875rem;
}

138
resources/scss/_custom.scss

@ -1,138 +0,0 @@
.overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, .45);
backdrop-filter: blur(1px);
display: none;
z-index: 1030;
}
.overlay.show {
display: block;
}
.sidebar {
width: 240px;
background: $white;
transition: width .3s, left .3s;
border-right: 1px solid $gray-200;
height: 100vh;
position: fixed;
top: 0;
left: 0;
padding-top: 60px;
z-index: 1030;
.nav-link {
color: $gray-800;
padding: 8px 10px;
display: flex;
align-items: center;
font-size: 14px;
font-weight: 400;
gap: 12px;
white-space: nowrap;
margin: 1px 12px;
border-radius: 8px;
&:hover {
color: $primary;
background-color: rgba($primary, 0.095);
}
&.active {
color: $primary;
background-color: rgba($primary, 0.095);
}
.ti {
font-size: 18px;
}
}
.nav-text {
transition: opacity .2s;
}
.logo-area {
position: absolute;
top: 0;
left: 0;
height: 60px;
width: 100%;
background: $white;
display: flex;
align-items: center;
gap: 10px;
padding-left: 17px;
color: $gray-800;
border-bottom: 1px solid $gray-200;
}
}
.sidebar.collapsed {
width: 60px;
.nav-link {
margin: 0 0px;
background-color: transparent;
padding: 8px 18px;
}
.nav-text {
display: none;
}
.logo-text {
display: none;
}
}
.topbar {
height: 60px;
margin-left: 240px;
// transition: margin-left .3s;
}
.topbar.full {
margin-left: 60px;
}
.content {
margin-left: 240px;
// transition: margin-left .3s;
// padding: 20px;
}
.content.full {
margin-left: 60px;
}
@media (max-width: 992px) {
.sidebar {
left: -240px;
}
.sidebar.mobile-show {
left: 0;
}
.topbar {
margin-left: 0 !important;
width: 100% !important;
}
.content {
margin-left: 0 !important;
}
}
.min-vh-90 {
min-height: 90vh;
}
@import "./avatar";
@import "./button";
@import "./icon-shape";
@import "./utilities";

50
resources/scss/_icon-shape.scss

@ -1,50 +0,0 @@
// Icon shape
.icon-xxs {
width: $icon-size-xxs;
height: $icon-size-xxs;
line-height: $icon-size-xxs;
}
.icon-xs {
width: $icon-size-xs;
height: $icon-size-xs;
line-height: $icon-size-xs;
}
.icon-sm {
width: $icon-size-sm;
height: $icon-size-sm;
line-height: $icon-size-sm;
}
.icon-md {
width: $icon-size-md;
height: $icon-size-md;
line-height: $icon-size-md;
}
.icon-lg {
width: $icon-size-lg;
height: $icon-size-lg;
line-height: $icon-size-lg;
}
.icon-xl {
width: $icon-size-xl;
height: $icon-size-xl;
line-height: $icon-size-xl;
}
.icon-xxl {
width: $icon-size-xxl;
height: $icon-size-xxl;
line-height: $icon-size-xxl;
}
.icon-xxxl {
width: $icon-size-xxxl;
height: $icon-size-xxxl;
line-height: $icon-size-xxxl;
}
.icon-shape {
display: inline-flex;
align-items: center;
justify-content: center;
text-align: center;
vertical-align: middle;
}

59
resources/scss/_utilities.scss

@ -1,59 +0,0 @@
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";
$utilities: map-merge(
$utilities,
(
"font-size": (
rfs: true,
responsive: true,
property: font-size,
class: fs,
values: $font-sizes
),
"position": (
property: position,
responsive: true,
values: static relative absolute fixed sticky
),
"top": (
property: top,
responsive: true,
values: $position-values
),
"bottom": (
property: bottom,
responsive: true,
values: $position-values
),
"start": (
property: left,
class: start,
responsive: true,
values: $position-values
),
"end": (
property: right,
class: end,
responsive: true,
values: $position-values
),
"translate-middle": (
property: transform,
class: translate-middle,
responsive: true,
values: (
null: translate(-50%, -50%),
x: translateX(-50%),
y: translateY(-50%),
)
),
)
);
@import "bootstrap/scss/utilities/api";

141
resources/scss/_variables.scss

@ -1,141 +0,0 @@
// Example: override Bootstrap color variables
$gray-50: #fafafa !default;
$gray-100: #f5f5f5 !default;
$gray-200: #e5e5e5 !default;
$gray-300: #d4d4d4 !default;
$gray-400: #a3a3a3 !default;
$gray-500: #737373 !default;
$gray-600: #525252 !default;
$gray-700: #404040 !default;
$gray-800: #262626 !default;
$gray-900: #171717 !default;
$gray-950: #0a0a0a !default;
$white: #ffffff !default;
$black: #000000 !default;
$orange: #E66239 !default;
$red: #FB2C36 !default;
$green: #00C951 !default;
$cyan: #00B8DB !default;
$yellow: #F0B100 !default;
$primary: $orange !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$min-contrast-ratio: 2.5 !default;
$link-hover-decoration: none !default;
$link-color: $gray-700 !default;
$link-hover-color: $primary !default;
$light: $gray-100 !default;
$border-color: $gray-200 !default;
$border-color-translucent: $gray-200 !default;
$enable-negative-margins: true !default;
$enable-rounded: true !default;
$headings-font-weight: 400 !default;
$grid-gutter-width: 2.5rem !default;
// scss-docs-start position-map
$position-values: (
0: 0,
10: 10%,
25: 25%,
50: 50%,
60: 60%,
65:65%,
70: 70%,
75: 75%,
100: 100%,
auto: auto
) !default;
// scss-docs-end position-map
// scss-docs-start spacer-variables-maps
$spacer: 1rem !default;
$spacers: (
0: 0,
1: $spacer * 0.25,
// 4px
2: $spacer * 0.5,
// 8px
3: $spacer,
// 16px
4: $spacer * 1.5,
// 24px
5: $spacer * 2,
// 32px
6: $spacer * 2.5,
// 40px
7: $spacer * 3,
// 48px
8: $spacer * 4,
// 64px
9: $spacer * 5,
// 80px
10: $spacer * 6,
// 96px
11: $spacer * 8,
// 128px
) !default;
// scss-docs-end spacer-variables-maps
$font-family-base: 'Poppins', sans-serif !default;
$font-size-root: null !default;
$font-size-base: .875rem !default; // Assumes the browser default, typically `16px`
$font-size-sm: $font-size-base * .85 !default;
$font-size-lg: $font-size-base * 1.25 !default;
$font-xs: 0.75rem !default;
$h1-font-size: $font-size-base * 2.5 !default;
$h2-font-size: $font-size-base * 2 !default;
$h3-font-size: $font-size-base * 1.75 !default;
$h4-font-size: $font-size-base * 1.5 !default;
$h5-font-size: $font-size-base * 1.25 !default;
$h6-font-size: $font-size-base !default;
// scss-docs-start border-radius-variables
$input-btn-padding-y: 0.5rem !default;
$input-btn-padding-x: .875rem !default;
$table-th-font-weight: 400!default;
$link-decoration: none !default;
$link-hover-decoration: underline !default;
// Icon
$icon-color: $gray-500 !default;
$icon-size-xxs: 1rem !default;
$icon-size-xs: 1.5rem !default;
$icon-size-sm: 2rem !default;
$icon-size-md: 2.5rem !default;
$icon-size-lg: 3rem !default;
$icon-size-xl: 3.5rem !default;
$icon-size-xxl: 4rem !default;
$icon-size-xxxl: 7rem !default;
// Avatar
$avatar-size-xs: 1.5rem !default;
$avatar-size-sm: 2rem !default;
$avatar-size-md: 2.5rem !default;
$avatar-size-lg: 3.5rem !default;
$avatar-size-xl: 5rem !default;
$avatar-size-xxl: 7.5rem !default;

74
resources/scss/app.scss

@ -1,13 +1,69 @@
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); @use "@coreui/coreui/scss/coreui" as * with (
$enable-deprecation-messages: false
);
// Import Bootstrap functions first body {
@import "bootstrap/scss/functions"; background-color: var(--cui-tertiary-bg);
}
// Override Bootstrap variables here .icon {
@import "./variables"; fill: none !important;
}
// Import Bootstrap .wrapper {
@import "bootstrap/scss/bootstrap"; width: 100%;
padding-inline: var(--cui-sidebar-occupy-start, 0) var(--cui-sidebar-occupy-end, 0);
will-change: auto;
@include transition(padding .15s);
}
// Custom styles .header > .container-fluid,
@import "./custom"; .sidebar-header {
min-height: calc(4rem + 1px); // stylelint-disable-line function-disallowed-list
}
.sidebar-brand-full {
margin-left: 3px;
}
.sidebar-header {
.nav-underline-border {
--cui-nav-underline-border-link-padding-x: 1rem;
--cui-nav-underline-border-gap: 0;
}
.nav-link {
display: flex;
align-items: center;
min-height: calc(4rem + 1px); // stylelint-disable-line function-disallowed-list
}
}
.sidebar-toggler {
margin-inline-start: auto;
}
.sidebar-narrow,
.sidebar-narrow-unfoldable:not(:hover) {
.sidebar-toggler {
margin-inline-end: auto;
}
}
.header > .container-fluid + .container-fluid {
min-height: 3rem;
}
.footer {
min-height: calc(3rem + 1px); // stylelint-disable-line function-disallowed-list
}
@include color-mode(dark) {
body {
background-color: var(--cui-dark-bg-subtle);
}
.footer {
--cui-footer-bg: var(--cui-body-bg);
}
}

3
resources/scss/plugin/apexchart.scss

@ -1,4 +1,5 @@
@import "../variables"; @import "@coreui/coreui/scss/variables";
@import "@coreui/coreui/scss/mixins";
@import "apexcharts/dist/apexcharts.css"; @import "apexcharts/dist/apexcharts.css";
// ApexCharts Theme Overrides // ApexCharts Theme Overrides

383
resources/scss/plugin/datatables.scss

@ -1,218 +1,222 @@
@import "../variables"; @import "@coreui/coreui/scss/variables";
@import "@coreui/coreui/scss/mixins";
@import "datatables.net-bs5/css/dataTables.bootstrap5.min.css"; @import "datatables.net-bs5/css/dataTables.bootstrap5.min.css";
// DataTables Theme Overrides // DataTables Theme Overrides
table.dataTable { table.dataTable {
font-family: $font-family-base; font-family: var(--cui-font-sans-serif);
font-size: $font-size-base; font-size: var(--cui-body-font-size);
color: $gray-800; color: var(--cui-body-color);
border-collapse: collapse !important; border-collapse: collapse !important;
border-color: $border-color; border-color: var(--cui-border-color);
// Header cells // Header cells
thead { thead {
th,
th, td {
td { font-weight: 500;
font-weight: 500; font-size: var(--cui-font-size-sm);
font-size: $font-size-sm; color: var(--cui-secondary-color);
color: $gray-600; background: var(--cui-tertiary-bg);
background: $gray-100; border-bottom: 1px solid var(--cui-border-color) !important;
border-bottom: 1px solid $border-color !important; padding: 0.625rem 0.75rem;
padding: 0.625rem 0.75rem; white-space: nowrap;
white-space: nowrap; }
}
// Sort icons // Sort icons
th.sorting, th.sorting,
th.sorting_asc, th.sorting_asc,
th.sorting_desc { th.sorting_desc {
cursor: pointer; cursor: pointer;
&::before, &::before,
&::after { &::after {
opacity: 0.4; opacity: 0.4;
color: $gray-500; color: var(--cui-secondary-color);
} }
&.sorting_asc::before, &.sorting_asc::before,
&.sorting_desc::after { &.sorting_desc::after {
opacity: 1; opacity: 1;
color: $primary; color: var(--cui-primary);
} }
} }
}
// Body cells
tbody {
td {
padding: 0.625rem 0.75rem;
vertical-align: middle;
border-top: 1px solid $border-color;
} }
tr { // Body cells
transition: background-color 0.15s; tbody {
td {
padding: 0.625rem 0.75rem;
vertical-align: middle;
border-top: 1px solid var(--cui-border-color);
}
&:hover>td { tr {
background-color: rgba($primary, 0.04); transition: background-color 0.15s;
&.dtfc-fixed-left, &:hover > td {
&.dtfc-fixed-right { // Safe runtime transparency generation via color-mix()
background-color: mix($primary, $white, 4%); background-color: color-mix(in srgb, var(--cui-primary) 4%, transparent);
}
} &.dtfc-fixed-left,
&.dtfc-fixed-right {
background-color: color-mix(in srgb, var(--cui-primary) 4%, var(--cui-body-bg));
}
}
&.selected>td { &.selected > td {
background-color: rgba($primary, 0.1); background-color: color-mix(in srgb, var(--cui-primary) 10%, transparent);
color: $gray-900; color: var(--cui-emphasis-color);
&.dtfc-fixed-left, &.dtfc-fixed-left,
&.dtfc-fixed-right { &.dtfc-fixed-right {
background-color: mix($primary, $white, 10%); background-color: color-mix(in srgb, var(--cui-primary) 10%, var(--cui-body-bg));
}
}
} }
}
} }
}
// Footer cells // Footer cells
tfoot { tfoot {
th,
th, td {
td { border-top: 2px solid var(--cui-border-color);
border-top: 2px solid $border-color; font-weight: 500;
font-weight: 500; color: var(--cui-emphasis-color);
color: $gray-800; }
} }
}
// Striped rows // Striped rows
&.table-striped>tbody>tr:nth-child(odd)>td { &.table-striped {
background-color: rgba($gray-50, 0.6); > tbody > tr:nth-child(odd) > td {
background-color: var(--cui-table-striped-bg);
&.dtfc-fixed-left, &.dtfc-fixed-left,
&.dtfc-fixed-right { &.dtfc-fixed-right {
background-color: mix($gray-50, $white, 60%); background-color: color-mix(in srgb, var(--cui-tertiary-bg) 60%, var(--cui-body-bg));
}
}
} }
}
} }
// Wrapper lengths control // Wrapper lengths control
.dataTables_wrapper { .dataTables_wrapper {
font-family: $font-family-base; font-family: var(--cui-font-sans-serif);
font-size: $font-size-base; font-size: var(--cui-body-font-size);
color: $gray-800; color: var(--cui-body-color);
// Length (items per page) select // Length (items per page) select
.dataTables_length { .dataTables_length {
label { label {
font-size: $font-size-sm; font-size: var(--cui-font-size-sm);
color: $gray-600; color: var(--cui-secondary-color);
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
} }
select { select {
font-family: $font-family-base; font-family: var(--cui-font-sans-serif);
font-size: $font-size-sm; font-size: var(--cui-font-size-sm);
border: 1px solid $border-color; border: 1px solid var(--cui-border-color);
border-radius: 0.5rem; border-radius: 0.5rem;
padding: 0.25rem 2.25rem 0.25rem 0.75rem; /* Increased padding-right for dropdown arrow */ padding: 0.25rem 2.25rem 0.25rem 0.75rem;
color: $gray-800; color: var(--cui-body-color);
background-color: $white; background-color: var(--cui-body-bg);
min-width: 80px; /* Force minimum width to prevent cut-off */ min-width: 80px;
&:focus { &:focus {
border-color: $primary; border-color: var(--cui-primary);
outline: 0; outline: 0;
box-shadow: 0 0 0 3px rgba($primary, 0.12); box-shadow: 0 0 0 3px color-mix(in srgb, var(--cui-primary) 12%, transparent);
} }
}
} }
}
// Search input
// Search input .dataTables_filter {
.dataTables_filter { label {
label { font-size: var(--cui-font-size-sm);
font-size: $font-size-sm; color: var(--cui-secondary-color);
color: $gray-600; display: flex;
display: flex; align-items: center;
align-items: center; gap: 0.5rem;
gap: 0.5rem; }
input {
font-family: var(--cui-font-sans-serif);
font-size: var(--cui-font-size-sm);
border: 1px solid var(--cui-border-color);
border-radius: 0.5rem;
padding: 0.375rem 0.75rem;
color: var(--cui-body-color);
background-color: var(--cui-body-bg);
&:focus {
border-color: var(--cui-primary);
outline: 0;
box-shadow: 0 0 0 3px color-mix(in srgb, var(--cui-primary) 12%, transparent);
}
}
} }
input { // Info text
font-family: $font-family-base; .dataTables_info {
font-size: $font-size-sm; font-size: var(--cui-font-size-sm);
border: 1px solid $border-color; color: var(--cui-secondary-color);
border-radius: 0.5rem; padding-top: 0.5rem;
padding: 0.375rem 0.75rem;
color: $gray-800;
&:focus {
border-color: $primary;
outline: 0;
box-shadow: 0 0 0 3px rgba($primary, 0.12);
}
} }
}
// Pagination
// Info text .dataTables_paginate {
.dataTables_info { .paginate_button {
font-size: $font-size-sm; font-family: var(--cui-font-sans-serif);
color: $gray-500; font-size: var(--cui-font-size-sm);
padding-top: 0.5rem; border-radius: 0.5rem !important;
} border: 1px solid transparent !important;
color: var(--cui-body-color) !important;
// Pagination padding: 0.3rem 0.65rem;
.dataTables_paginate { transition: all 0.15s;
.paginate_button {
font-family: $font-family-base; &:hover {
font-size: $font-size-sm; background: color-mix(in srgb, var(--cui-primary) 8%, transparent) !important;
border-radius: 0.5rem !important; color: var(--cui-primary) !important;
border: 1px solid transparent !important; border-color: transparent !important;
color: $gray-800 !important; box-shadow: none !important;
padding: 0.3rem 0.65rem; }
transition: all 0.15s;
&.current,
&:hover { &.current:hover {
background: rgba($primary, 0.08) !important; background: var(--cui-primary) !important;
color: $primary !important; color: var(--cui-white) !important;
border-color: transparent !important; border-color: var(--cui-primary) !important;
box-shadow: none !important; box-shadow: none !important;
} font-weight: 500;
}
&.current,
&.current:hover { &.disabled,
background: $primary !important; &.disabled:hover {
color: $white !important; color: var(--cui-secondary-color) !important;
border-color: $primary !important; background: transparent !important;
box-shadow: none !important; cursor: not-allowed;
font-weight: 500; }
} }
&.disabled,
&.disabled:hover {
color: $gray-600 !important;
cursor: not-allowed;
}
} }
}
// Processing indicator
// Processing indicator .dataTables_processing {
.dataTables_processing { font-family: var(--cui-font-sans-serif);
font-family: $font-family-base; font-size: var(--cui-font-size-sm);
font-size: $font-size-sm; border: 1px solid var(--cui-border-color);
border: 1px solid $border-color; border-radius: 0.5rem;
border-radius: 0.5rem; background: var(--cui-body-bg);
background: $white; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
box-shadow: 0 4px 16px rgba($black, 0.15); color: var(--cui-body-color);
color: $gray-800;
> div:last-child > div {
>div:last-child>div { background: var(--cui-primary);
background: $primary; }
} }
}
} }
.dt-length { .dt-length {
@ -220,3 +224,10 @@ table.dataTable {
min-width: 70px !important; min-width: 70px !important;
} }
} }
// Scoped CoreUI Theme High Contrast Shadows
[data-coreui-theme="dark"] {
.dataTables_wrapper .dataTables_processing {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
}
}

47
resources/scss/plugin/filepond.scss

@ -1,4 +1,5 @@
@import "../variables"; @import "@coreui/coreui/scss/variables";
@import "@coreui/coreui/scss/mixins";
@import "../../../vendor/spatie/livewire-filepond/resources/dist/filepond.css"; @import "../../../vendor/spatie/livewire-filepond/resources/dist/filepond.css";
.filepond--root { .filepond--root {
@ -6,24 +7,27 @@
width: 100%; width: 100%;
border-radius: 1rem; border-radius: 1rem;
overflow: hidden; overflow: hidden;
border: 2px dashed $primary; border: 2px dashed var(--cui-primary);
background: $light; // Uses adaptive background variable instead of static light mode background
box-shadow: 0 8px 24px rgba(#000, 0.08); background: var(--cui-tertiary-bg);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
&:hover { &:hover {
border-color: mix(#000, $primary, 20%); // Native browser mixing prevents compile errors with var()
box-shadow: 0 10px 28px rgba(#000, 0.12); border-color: color-mix(in srgb, var(--cui-primary) 80%, black);
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.12);
} }
.filepond--panel-root { .filepond--panel-root {
background-color: rgba($primary, 0.05) !important; // Combines primary color-mix transparency natively with background colors
background-color: color-mix(in srgb, var(--cui-primary) 5%, transparent) !important;
border-radius: 1rem !important; border-radius: 1rem !important;
} }
.filepond--drop-label { .filepond--drop-label {
font-size: 1.1rem; font-size: 1.1rem;
color: $secondary; color: var(--cui-secondary-color);
font-weight: 700; font-weight: 700;
padding: 1.4rem; padding: 1.4rem;
} }
@ -31,24 +35,24 @@
.filepond--item { .filepond--item {
border-radius: 0.75rem; border-radius: 0.75rem;
overflow: hidden; overflow: hidden;
box-shadow: 0 4px 12px rgba(#000, 0.06); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
margin-bottom: 0.75rem; margin-bottom: 0.75rem;
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
&:hover { &:hover {
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(#000, 0.1); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
} }
} }
.filepond--file-action-button { .filepond--file-action-button {
background-color: $primary !important; background-color: var(--cui-primary) !important;
color: #fff !important; color: var(--cui-white) !important;
border-radius: 0.5rem !important; border-radius: 0.5rem !important;
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
&:hover { &:hover {
background-color: mix(#000, $primary, 20%) !important; background-color: color-mix(in srgb, var(--cui-primary) 80%, black) !important;
} }
} }
@ -56,3 +60,20 @@
display: none !important; display: none !important;
} }
} }
// Scoped CoreUI Dark Theme Context overrides
[data-coreui-theme="dark"] {
.filepond--root {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4) !important;
&:hover {
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5) !important;
// Brightens the line accent relative to standard dark theme rules
border-color: color-mix(in srgb, var(--cui-primary) 85%, white);
}
.filepond--file-action-button:hover {
background-color: color-mix(in srgb, var(--cui-primary) 85%, white) !important;
}
}
}

453
resources/scss/plugin/select2.scss

@ -1,277 +1,288 @@
@import "../variables"; @import "@coreui/coreui/scss/variables";
@import "@coreui/coreui/scss/mixins";
@import "select2/dist/css/select2.min.css"; @import "select2/dist/css/select2.min.css";
@import "select2-bootstrap-5-theme/dist/select2-bootstrap-5-theme.min.css"; @import "select2-bootstrap-5-theme/dist/select2-bootstrap-5-theme.min.css";
// Select2 Theme Overrides // Select2 Theme Overrides
.select2-container { .select2-container {
font-family: $font-family-base; font-family: var(--cui-font-sans-serif);
font-size: $font-size-base; font-size: var(--cui-body-font-size);
width: 100% !important; width: 100% !important;
// Main selection box // Main selection box
.select2-selection--single, .select2-selection--single,
.select2-selection--multiple { .select2-selection--multiple {
font-family: $font-family-base; font-family: var(--cui-font-sans-serif);
font-size: $font-size-base; font-size: var(--cui-body-font-size);
border: 1px solid $border-color; border: 1px solid var(--cui-border-color);
border-radius: 0.5rem !important; border-radius: 0.5rem !important;
background-color: $white; background-color: var(--cui-body-bg);
transition: border-color 0.15s, box-shadow 0.15s; color: var(--cui-body-color);
transition: border-color 0.15s, box-shadow 0.15s;
&:hover { &:hover {
border-color: $gray-600; border-color: var(--cui-border-color-translucent);
}
} }
}
// Single select rendered value // Single select rendered value
.select2-selection--single { .select2-selection--single {
height: calc(1.5em + 0.75rem + 2px); height: calc(1.5em + 0.75rem + 2px);
.select2-selection__rendered { .select2-selection__rendered {
color: $gray-800; color: var(--cui-body-color);
padding-left: 0.75rem; padding-left: 0.75rem;
padding-right: 2rem; padding-right: 2rem;
width: 90%; width: 90%;
line-height: calc(1.5em + 0.75rem); line-height: calc(1.5em + 0.75rem);
overflow: hidden !important; overflow: hidden !important;
text-overflow: ellipsis !important; text-overflow: ellipsis !important;
white-space: nowrap !important; white-space: nowrap !important;
display: block !important; display: block !important;
// Increase padding right when clear button is present so text truncates before it // Increase padding right when clear button is present so text truncates before it
&:has(.select2-selection__clear) { &:has(.select2-selection__clear) {
padding-right: .3rem !important; padding-right: .3rem !important;
} }
} }
.select2-selection__placeholder { .select2-selection__placeholder {
color: $gray-600; color: var(--cui-secondary-color);
} }
.select2-selection__clear { .select2-selection__clear {
position: absolute; position: absolute;
right: 1.8rem; right: 1.8rem;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
z-index: 10; z-index: 10;
cursor: pointer; cursor: pointer;
color: $gray-500; color: var(--cui-secondary-color);
background: transparent; background: transparent;
padding: 0; padding: 0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: 1rem; height: 1rem;
width: 1rem; width: 1rem;
line-height: 1; line-height: 1;
&:hover { &:hover {
color: $danger; color: var(--cui-danger);
} }
} }
.select2-selection__arrow { .select2-selection__arrow {
height: 100%; height: 100%;
right: 0.5rem; right: 0.5rem;
b { b {
border-color: $gray-600 transparent transparent; // Native CSS properties to draw the carets cleanly in dark theme
border-width: 5px 4px 0; border-color: var(--cui-secondary-color) transparent transparent;
} border-width: 5px 4px 0;
}
}
} }
}
// Multiple select tags
.select2-selection--multiple {
padding: 0.25rem 0.5rem;
min-height: calc(1.5em + 0.75rem + 2px);
.select2-selection__choice {
background-color: rgba($primary, 0.1);
border: 1px solid rgba($primary, 0.2);
border-radius: 0.375rem;
color: $primary;
font-size: $font-size-sm;
font-weight: 500;
padding: 0.1rem 0.5rem;
.select2-selection__choice__remove {
color: $primary;
font-weight: 700;
margin-right: 4px;
&:hover { // Multiple select tags
color: $danger; .select2-selection--multiple {
background: transparent; padding: 0.25rem 0.5rem;
min-height: calc(1.5em + 0.75rem + 2px);
.select2-selection__choice {
background-color: color-mix(in srgb, var(--cui-primary) 10%, transparent);
border: 1px solid color-mix(in srgb, var(--cui-primary) 20%, transparent);
border-radius: 0.375rem;
color: var(--cui-primary);
font-size: var(--cui-font-size-sm);
font-weight: 500;
padding: 0.1rem 0.5rem;
.select2-selection__choice__remove {
color: var(--cui-primary);
font-weight: 700;
margin-right: 4px;
&:hover {
color: var(--cui-danger);
background: transparent;
}
}
} }
}
}
.select2-search__field { .select2-search__field {
font-family: $font-family-base; font-family: var(--cui-font-sans-serif);
font-size: $font-size-sm; font-size: var(--cui-font-size-sm);
color: $gray-800; color: var(--cui-body-color);
background-color: transparent;
&::placeholder { &::placeholder {
color: $gray-600; color: var(--cui-secondary-color);
} }
}
} }
}
// Focused state // Focused state
&--open, &--open,
&--focus { &--focus {
.select2-selection--single,
.select2-selection--single, .select2-selection--multiple {
.select2-selection--multiple { border-color: var(--cui-primary) !important;
border-color: $primary !important; box-shadow: 0 0 0 3px color-mix(in srgb, var(--cui-primary) 12%, transparent) !important;
box-shadow: 0 0 0 3px rgba($primary, 0.12) !important; outline: 0;
outline: 0; }
}
.select2-selection--single .select2-selection__arrow b { .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent $primary; border-color: transparent transparent var(--cui-primary);
border-width: 0 4px 5px; border-width: 0 4px 5px;
}
} }
}
} }
// Support for form-control-sm // Support for form-control-sm
select.form-control-sm + .select2-container, select.form-control-sm + .select2-container,
select.form-select-sm + .select2-container, select.form-select-sm + .select2-container,
.select2-container--sm { .select2-container--sm {
.select2-selection--single, .select2-selection--single,
.select2-selection--multiple { .select2-selection--multiple {
border-radius: 0.375rem !important; border-radius: 0.375rem !important;
}
.select2-selection--single {
height: calc(1.5em + 0.5rem + 2px) !important;
.select2-selection__rendered {
padding-left: 0.5rem;
font-size: $font-size-sm;
line-height: calc(1.5em + 0.5rem) !important;
} }
.select2-selection__clear { .select2-selection--single {
right: 0.5rem; height: calc(1.5em + 0.5rem + 2px) !important;
.select2-selection__rendered {
padding-left: 0.5rem;
font-size: var(--cui-font-size-sm);
line-height: calc(1.5em + 0.5rem) !important;
}
.select2-selection__clear {
right: 0.5rem;
}
} }
}
.select2-selection--multiple { .select2-selection--multiple {
min-height: calc(1.5em + 0.5rem + 2px) !important; min-height: calc(1.5em + 0.5rem + 2px) !important;
padding: 0.15rem 0.5rem; padding: 0.15rem 0.5rem;
.select2-search__field { .select2-search__field {
font-size: $font-size-sm; font-size: var(--cui-font-size-sm);
}
} }
}
} }
// Dropdown panel // Dropdown panel
.select2-dropdown { .select2-dropdown {
font-family: $font-family-base; font-family: var(--cui-font-sans-serif);
font-size: $font-size-base; font-size: var(--cui-body-font-size);
border: 1px solid $border-color; border: 1px solid var(--cui-border-color);
border-radius: 0.5rem !important; border-radius: 0.5rem !important;
box-shadow: 0 8px 24px rgba($black, 0.15); background-color: var(--cui-body-bg);
overflow: hidden; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
overflow: hidden;
// Search field inside dropdown
.select2-search--dropdown { // Search field inside dropdown
padding: 0.5rem; .select2-search--dropdown {
background: $gray-100; padding: 0.5rem;
border-bottom: 1px solid $border-color; background: var(--cui-tertiary-bg);
border-bottom: 1px solid var(--cui-border-color);
.select2-search__field {
font-family: $font-family-base; .select2-search__field {
font-size: $font-size-sm; font-family: var(--cui-font-sans-serif);
border: 1px solid $border-color; font-size: var(--cui-font-size-sm);
border-radius: 0.375rem; border: 1px solid var(--cui-border-color);
padding: 0.375rem 0.75rem; border-radius: 0.375rem;
color: $gray-800; padding: 0.375rem 0.75rem;
width: 100%; color: var(--cui-body-color);
background-color: $white; width: 100%;
background-color: var(--cui-body-bg);
&:focus {
border-color: $primary; &:focus {
outline: 0; border-color: var(--cui-primary);
box-shadow: 0 0 0 3px rgba($primary, 0.12); outline: 0;
} box-shadow: 0 0 0 3px color-mix(in srgb, var(--cui-primary) 12%, transparent);
}
}
} }
}
// Option list // Option list
.select2-results__options { .select2-results__options {
padding: 0.25rem 0; padding: 0.25rem 0;
max-height: 220px; max-height: 220px;
overflow-y: auto; overflow-y: auto;
// Scrollbar // Scrollbar styling to respect theme
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 5px; width: 5px;
} }
&::-webkit-scrollbar-track { &::-webkit-scrollbar-track {
background: $gray-100; background: var(--cui-tertiary-bg);
} }
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background: $gray-300; background: var(--cui-border-color);
border-radius: 4px; border-radius: 4px;
} }
}
.select2-results__option {
font-size: $font-size-sm;
color: $gray-800;
padding: 0.45rem 0.85rem;
transition: background 0.12s;
// Highlighted (hover or keyboard)
&--highlighted {
background-color: rgba($primary, 0.08) !important;
color: $primary !important;
} }
// Selected .select2-results__option {
&[aria-selected='true'] { font-size: var(--cui-font-size-sm);
background-color: rgba($primary, 0.12); color: var(--cui-body-color);
color: $primary; background-color: transparent;
font-weight: 500; padding: 0.45rem 0.85rem;
} transition: background 0.12s;
// Highlighted (hover or keyboard)
&--highlighted {
background-color: color-mix(in srgb, var(--cui-primary) 8%, transparent) !important;
color: var(--cui-primary) !important;
}
// Disabled // Selected
&[aria-disabled='true'] { &[aria-selected='true'] {
color: $gray-600; background-color: color-mix(in srgb, var(--cui-primary) 12%, transparent);
cursor: not-allowed; color: var(--cui-primary);
} font-weight: 500;
}
// Disabled
&[aria-disabled='true'] {
color: var(--cui-secondary-color);
cursor: not-allowed;
}
// Option group label // Option group label
&--group { &--group {
color: $gray-500; color: var(--cui-secondary-color);
font-size: $font-xs; font-size: var(--cui-font-size-sm);
font-weight: 600; font-weight: 600;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.04em; letter-spacing: 0.04em;
padding: 0.5rem 0.85rem 0.25rem; padding: 0.5rem 0.85rem 0.25rem;
cursor: default; cursor: default;
}
} }
}
} }
// Disabled state // Disabled state
.select2-container--disabled { .select2-container--disabled {
.select2-selection--single,
.select2-selection--multiple {
background-color: var(--cui-disabled-bg) !important;
border-color: var(--cui-border-color) !important;
cursor: not-allowed;
.select2-selection--single, .select2-selection__rendered {
.select2-selection--multiple { color: var(--cui-disabled-color);
background-color: $gray-100 !important; }
border-color: $border-color !important; }
cursor: not-allowed; }
.select2-selection__rendered { // Scoped CoreUI Theme adjustments for intense dark background shadows
color: $gray-600; [data-coreui-theme="dark"] {
.select2-dropdown {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
} }
}
} }

90
resources/scss/plugin/sweetalert.scss

@ -1,51 +1,54 @@
@import "../variables"; @import "@coreui/coreui/scss/variables";
@import "@coreui/coreui/scss/mixins";
@import "sweetalert2/src/sweetalert2.scss"; @import "sweetalert2/src/sweetalert2.scss";
// Override SweetAlert2 variables // ==========================================================================
// Brand Colors // 1. Core SweetAlert2 Base Variables (Safe Fallbacks)
// ==========================================================================
$swal2-confirm-button-background-color: $primary; $swal2-confirm-button-background-color: $primary;
$swal2-deny-button-background-color: $danger; $swal2-deny-button-background-color: $danger;
$swal2-cancel-button-background-color: $secondary; $swal2-cancel-button-background-color: $secondary;
// States
$swal2-success: $success; $swal2-success: $success;
$swal2-error: $danger; $swal2-error: $danger;
$swal2-warning: $warning; $swal2-warning: $warning;
$swal2-info: $info; $swal2-info: $info;
$swal2-question: $secondary; $swal2-question: $secondary;
// Typography & Base Styling
$swal2-font: $font-family-base; $swal2-font: $font-family-base;
$swal2-color: $gray-800; $swal2-color: $gray-800;
// Buttons matching UI Form Controls $swal2-button-padding: $input-btn-padding-y ($input-btn-padding-x * 1.5);
$swal2-button-padding: $input-btn-padding-y (
$input-btn-padding-x * 1.5
);
$swal2-confirm-button-border-radius: 0.5rem; $swal2-confirm-button-border-radius: 0.5rem;
$swal2-deny-button-border-radius: 0.5rem; $swal2-deny-button-border-radius: 0.5rem;
$swal2-cancel-button-border-radius: 0.5rem; $swal2-cancel-button-border-radius: 0.5rem;
$swal2-border-radius: 0.75rem; $swal2-border-radius: 0.75rem;
// ==========================================================================
// Custom Class Styles for Premium Look // 2. Custom Layout & Core Dark Mode Compatibility
// ==========================================================================
.swal2-popup { .swal2-popup {
padding: 1.5rem; padding: 1.5rem;
box-shadow: 0 10px 40px rgba($black, 0.08); // CoreUI native background tracking (automatically dark/light compliant)
border: 1px solid rgba($gray-900, 0.05); background: var(--cui-body-bg);
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08);
border: 1px solid var(--cui-border-color-translucent);
// Global adjustments inside popup tracking CoreUI mode text
color: var(--cui-body-color);
.swal2-title { .swal2-title {
font-weight: 600; font-weight: 600;
font-size: 1.25rem; font-size: 1.25rem;
color: $gray-900; color: var(--cui-emphasis-color);
margin-bottom: 0.75rem; margin-bottom: 0.75rem;
padding-top: 0.5rem; padding-top: 0.5rem;
} }
.swal2-html-container { .swal2-html-container {
font-size: 0.95rem; font-size: 0.95rem;
color: $gray-600; color: var(--cui-secondary-color);
line-height: 1.6; line-height: 1.6;
margin: 0.5rem 1rem 0; margin: 0.5rem 1rem 0;
} }
@ -62,7 +65,8 @@ $swal2-border-radius: 0.75rem;
&:hover { &:hover {
transform: translateY(-1px); transform: translateY(-1px);
filter: brightness(1.05); // Pure CSS adjustment safely altering colors inside runtime vars
filter: brightness(1.1);
} }
&:active { &:active {
@ -70,50 +74,66 @@ $swal2-border-radius: 0.75rem;
} }
&.swal2-confirm { &.swal2-confirm {
background-color: $primary !important; background-color: var(--cui-primary) !important;
color: var(--cui-white) !important;
} }
&.swal2-cancel { &.swal2-cancel {
background-color: $gray-200 !important; background-color: var(--cui-secondary-bg) !important;
color: $gray-800 !important; color: var(--cui-secondary-color) !important;
border: 1px solid $border-color; border: 1px solid var(--cui-border-color) !important;
} }
&.swal2-deny { &.swal2-deny {
background-color: $danger !important; background-color: var(--cui-danger) !important;
color: var(--cui-white) !important;
} }
} }
} }
// Modal Status Indicators
.swal2-icon { .swal2-icon {
margin-top: 0.5rem; margin-top: 0.5rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
border-width: 2px; border-width: 2px;
&.swal2-success { &.swal2-success {
border-color: $success; border-color: var(--cui-success);
[class^='swal2-success-line'] { [class^='swal2-success-line'] {
background-color: $success; background-color: var(--cui-success);
} }
.swal2-success-ring { .swal2-success-ring {
border-color: rgba($success, 0.3); // native CSS color-mix handles alpha modifications without triggering compilation crash
border-color: color-mix(in srgb, var(--cui-success) 30%, transparent);
} }
} }
&.swal2-error { &.swal2-error {
border-color: $danger; border-color: var(--cui-danger);
.swal2-x-mark-line-left, .swal2-x-mark-line-left,
.swal2-x-mark-line-right { .swal2-x-mark-line-right {
background-color: $danger; background-color: var(--cui-danger);
} }
} }
&.swal2-warning {
border-color: var(--cui-warning);
color: var(--cui-warning);
}
&.swal2-info {
border-color: var(--cui-info);
color: var(--cui-info);
}
} }
} }
// Toast styling // ==========================================================================
// 3. Toast Customization
// ==========================================================================
@keyframes swal2-toast-show { @keyframes swal2-toast-show {
0% { 0% {
transform: scale(0.9) translateY(-10px); transform: scale(0.9) translateY(-10px);
@ -127,7 +147,10 @@ $swal2-border-radius: 0.75rem;
.swal2-toast { .swal2-toast {
padding: 0.75rem 1rem !important; padding: 0.75rem 1rem !important;
box-shadow: 0 5px 15px rgba($black, 0.08) !important; background: var(--cui-body-bg) !important;
color: var(--cui-body-color) !important;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08) !important;
border: 1px solid var(--cui-border-color-translucent) !important;
border-radius: 0.5rem !important; border-radius: 0.5rem !important;
&.swal2-show { &.swal2-show {
@ -135,8 +158,19 @@ $swal2-border-radius: 0.75rem;
} }
.swal2-title { .swal2-title {
color: var(--cui-emphasis-color) !important;
font-size: 0.875rem !important; font-size: 0.875rem !important;
margin: 0 0.5rem !important; margin: 0 0.5rem !important;
padding-top: 0 !important; padding-top: 0 !important;
} }
} }
// ==========================================================================
// 4. Scoped CoreUI Dark Mode Hooks
// ==========================================================================
[data-coreui-theme="dark"] {
.swal2-popup, .swal2-toast {
// High Contrast Shadow adjustments for Dark Backgrounds
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.45) !important;
}
}

1618
resources/scss/style.css

File diff suppressed because it is too large

52
resources/views/components/layouts/app.blade.php

@ -21,45 +21,29 @@
<body> <body>
@gtmBody @gtmBody
<div id="overlay" class="overlay"></div> <x-layouts.nav.sidebar />
<!-- TOPBAR -->
<x-layouts.nav.topbar/>
<!-- SIDEBAR --> <div class="wrapper d-flex flex-column min-vh-100">
<x-layouts.nav.sidebar/> <x-layouts.nav.topbar />
<div class="body flex-grow-1 px-4 py-3">
<!-- MAIN CONTENT --> <div class="container-fluid">
<main id="content" class="content"> {{ $slot }}
<div class="container-fluid min-vh-90 pt-10">
<div class="d-flex flex-column mb-5">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
@foreach($breadcrumbs as $breadcrumb)
<li class="breadcrumb-item {{ $loop->index==0 ? 'active' : '' }}" aria-current="page">
@if($breadcrumb['url']) <a href="{{ $breadcrumb['url'] }}"> @endif
{{ $breadcrumb['label'] }}
@if($breadcrumb['url']) </a> @endif
</li>
@endforeach
</ol>
</nav>
<h1 class="fs-3">{{ $header }}</h1>
</div> </div>
{{ $slot }}
</div> </div>
<footer class="footer px-4">
<footer class="text-secondary mt-6 py-2 text-center"> <div>
<p>Copyright © 2026 InApp Inventory Dashboard. Developed by <a href="https://codescandy.com/" <a href="https://coreui.io">CoreUI</a>
target="_blank" <a href="https://coreui.io/product/free-bootstrap-admin-template/">Bootstrap Admin Template</a>
class="text-primary">CodesCandy</a> &copy; 2026 creativeLabs.
Distributed by <a href="https://themewagon.com/" target="_blank" class="text-primary">ThemeWagon</a> </div>
</p> <div class="ms-auto">
Powered by&nbsp;
<a href="https://coreui.io/bootstrap/docs/">CoreUI UI Components</a>
</div>
</footer> </footer>
</main> </div>
@livewireScriptConfig
@stack('page-scripts') @stack('page-scripts')
@livewireScriptConfig()
<div id="swal-container" wire:ignore></div>
</body> </body>
</html> </html>

38
resources/views/components/layouts/nav/sidebar.blade.php

@ -1,17 +1,26 @@
<aside id="sidebar" class="sidebar"> <div class="sidebar sidebar-dark sidebar-fixed border-end" id="sidebar">
<div class="logo-area"> <div class="sidebar-header border-bottom">
<x-link href="{{ url('/') }}" class="d-inline-flex p-3 w-100 h-100"> <div class="sidebar-brand me-auto">
<x-slot:label class="d-flex flex-row gap-2 align-items-center h-100"> <svg role="img" aria-label="CoreUI Logo Full" class="sidebar-brand-full" width="88" height="32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 312 115">
@isset($logo) <g style="fill: currentColor">
<img src="{{ asset_static($logo) }}" alt="Web Logo" class="h-100" /> <path d="M96 24.124 57 1.608a12 12 0 0 0-12 0L6 24.124a12.034 12.034 0 0 0-6 10.393V79.55a12.033 12.033 0 0 0 6 10.392l39 22.517a12 12 0 0 0 12 0l39-22.517a12.033 12.033 0 0 0 6-10.392V34.517a12.034 12.034 0 0 0-6-10.393ZM94 79.55a4 4 0 0 1-2 3.464l-39 22.517a4 4 0 0 1-4 0L10 83.014a4 4 0 0 1-2-3.464V34.517a4 4 0 0 1 2-3.464L49 8.536a4 4 0 0 1 4 0l39 22.517a4 4 0 0 1 2 3.464V79.55Z" />
@else <path d="M74.022 70.071h-2.866a4 4 0 0 0-1.925.494L51.95 80.05 32 68.531V45.554l19.95-11.519 17.29 9.455a4 4 0 0 0 1.919.49h2.863a2 2 0 0 0 2-2v-2.71a2 2 0 0 0-1.04-1.756L55.793 27.02a8.04 8.04 0 0 0-7.843.09L28 38.626a8.025 8.025 0 0 0-4 6.929V68.53a8 8 0 0 0 4 6.928l19.95 11.519a8.043 8.043 0 0 0 7.843.088l19.19-10.532a2 2 0 0 0 1.038-1.753v-2.71a2 2 0 0 0-2-2Z" />
@svg('tabler-brand-laravel') <g transform="translate(118 33)">
@endisset <path d="M50.745.428c-8.28.01-14.99 6.72-15 15v17.277c0 8.285 6.715 15 15 15 8.284 0 15-6.715 15-15V15.428c-.01-8.28-6.72-14.99-15-15Zm7 32.277a7 7 0 0 1-14 0V15.428a7 7 0 0 1 14 0v17.277ZM14.079 8.488a7.01 7.01 0 0 1 7.868 6.075.99.99 0 0 0 .984.865h6.03a1.01 1.01 0 0 0 1-1.097C29.354 6.206 22.38.046 14.243.447 6.161 1-.086 7.762 0 15.864V32.27c-.087 8.101 6.161 14.864 14.244 15.416 8.137.401 15.11-5.759 15.716-13.883a1.01 1.01 0 0 0-.999-1.098h-6.03a.99.99 0 0 0-.985.865 7.01 7.01 0 0 1-7.868 6.076A7.164 7.164 0 0 1 8 32.461V15.672a7.164 7.164 0 0 1 6.079-7.184ZM96.922 27.994a12.158 12.158 0 0 0 7.184-11.077v-3.7c0-6.71-5.44-12.15-12.149-12.15H75a1 1 0 0 0-1 1v44a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-17h6.621l7.916 17.413a1 1 0 0 0 .91.587h6.591a1 1 0 0 0 .91-1.414l-8.026-17.659Zm-.816-11.077a4.154 4.154 0 0 1-4.148 4.15h-9.852v-12h9.852a4.154 4.154 0 0 1 4.148 4.15v3.7ZM139 1.067h-26a1 1 0 0 0-1 1v44a1 1 0 0 0 1 1h26a1 1 0 0 0 1-1v-6a1 1 0 0 0-1-1h-19v-12h13a1 1 0 0 0 1-1v-6a1 1 0 0 0-1-1h-13v-10h19a1 1 0 0 0 1-1v-6a1 1 0 0 0-1-1ZM177 1.067h-6a1 1 0 0 0-1 1v22.647a7.007 7.007 0 1 1-14 0V2.067a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v22.647a15.003 15.003 0 1 0 30 0V2.067a1 1 0 0 0-1-1Z" />
<span class="fs-5 fw-bold ms-2">{{ config('seotools.meta.defaults.title') }}</span> <rect width="8" height="38" x="186" y="1.067" rx="1" />
</x-slot:label> </g>
</x-link> </g>
</svg>
<svg role="img" aria-label="CoreUI Logo Signet" class="sidebar-brand-narrow" width="88" height="32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 102 115">
<g style="fill: currentColor">
<path d="M96 24.124 57 1.608a12 12 0 0 0-12 0L6 24.124a12.034 12.034 0 0 0-6 10.393V79.55a12.033 12.033 0 0 0 6 10.392l39 22.517a12 12 0 0 0 12 0l39-22.517a12.033 12.033 0 0 0 6-10.392V34.517a12.034 12.034 0 0 0-6-10.393ZM94 79.55a4 4 0 0 1-2 3.464l-39 22.517a4 4 0 0 1-4 0L10 83.014a4 4 0 0 1-2-3.464V34.517a4 4 0 0 1 2-3.464L49 8.536a4 4 0 0 1 4 0l39 22.517a4 4 0 0 1 2 3.464V79.55Z" />
<path d="M74.022 70.071h-2.866a4 4 0 0 0-1.925.494L51.95 80.05 32 68.531V45.554l19.95-11.519 17.29 9.455a4 4 0 0 0 1.919.49h2.863a2 2 0 0 0 2-2v-2.71a2 2 0 0 0-1.04-1.756L55.793 27.02a8.04 8.04 0 0 0-7.843.09L28 38.626a8.025 8.025 0 0 0-4 6.929V68.53a8 8 0 0 0 4 6.928l19.95 11.519a8.043 8.043 0 0 0 7.843.088l19.19-10.532a2 2 0 0 0 1.038-1.753v-2.71a2 2 0 0 0-2-2Z" />
</g>
</svg>
</div>
<button class="btn-close d-lg-none" type="button" data-coreui-theme="dark" aria-label="Close" onclick="coreui.Sidebar.getInstance(document.querySelector('#sidebar')).toggle()"></button>
</div> </div>
<ul class="nav flex-column"> <ul class="sidebar-nav" data-coreui="navigation" data-simplebar="">
<x-layouts.nav.sidebar.nav-link :route="route('dashboard')" icon="tabler-home" <x-layouts.nav.sidebar.nav-link :route="route('dashboard')" icon="tabler-home"
:text="__('ui.menu.dashboard')" permission="dashboard.index" /> :text="__('ui.menu.dashboard')" permission="dashboard.index" />
<x-layouts.nav.sidebar.nav-link :route="route('roles.index')" icon="tabler-shield" <x-layouts.nav.sidebar.nav-link :route="route('roles.index')" icon="tabler-shield"
@ -19,5 +28,4 @@
<x-layouts.nav.sidebar.nav-link :route="route('users.index')" icon="tabler-user" <x-layouts.nav.sidebar.nav-link :route="route('users.index')" icon="tabler-user"
:text="__('ui.menu.users')" permission="user.viewAny" /> :text="__('ui.menu.users')" permission="user.viewAny" />
</ul> </ul>
</div>
</aside>

5
resources/views/components/layouts/nav/sidebar/nav-link.blade.php

@ -6,7 +6,8 @@
]) ])
@if((is_string($permission) && auth()->user()->hasPermissionTo($permission))) @if((is_string($permission) && auth()->user()->hasPermissionTo($permission)))
<li> <li class="">
<x-link :href="$route" :label="$text" :icon="$icon" @class(['nav-link', 'active' => url()->current() == $route]) /> <x-link :href="$route" :label="$text" :icon="$icon" :icon-config="['class' => 'nav-icon']"
@class(['nav-link', 'active' => url()->current() == $route]) />
</li> </li>
@endif @endif

74
resources/views/components/layouts/nav/topbar.blade.php

@ -1,28 +1,64 @@
<nav id="topbar" class="navbar border-bottom fixed-top topbar bg-white px-3"> <header class="header header-sticky p-0 mb-4">
<button id="toggleBtn" class="d-none d-lg-inline-flex btn btn-light btn-icon btn-sm"> <div class="container-fluid d-flex align-items-center">
<x-tabler-menu-2 width="16" /> <button class="header-toggler" type="button" style="margin-inline-start: -14px">
</button> <svg class="icon icon-lg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="var(--ci-primary-color, currentcolor)" d="M80 96h352v32H80zm0 144h352v32H80zm0 144h352v32H80z" class="ci-primary" />
</svg>
</button>
<!-- MOBILE -->
<button id="mobileBtn" class="btn btn-light btn-icon btn-sm d-lg-none me-2"> <ul class="header-nav">
<x-tabler-menu-2 width="16" /> <li class="nav-item dropdown">
</button>
<div>
<!-- Navbar nav -->
<ul class="list-unstyled d-flex align-items-center mb-0 gap-1">
<!-- Bell icon -->
<li>
<livewire:layouts::notification /> <livewire:layouts::notification />
</li> </li>
<!-- Language switcher --> <li class="nav-item py-1">
<li> <div class="vr h-100 mx-2 text-body text-opacity-75"></div>
</li>
<li class="nav-item dropdown">
<livewire:layouts::language-switcher /> <livewire:layouts::language-switcher />
</li> </li>
<!-- Dropdown --> <li class="nav-item py-1">
<li class="ms-3"> <div class="vr h-100 mx-2 text-body text-opacity-75"></div>
</li>
<li class="nav-item dropdown">
<button class="btn btn-link nav-link py-2 px-2 d-flex align-items-center" type="button" aria-expanded="false" data-coreui-toggle="dropdown">
<svg class="icon icon-lg theme-icon-active" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="var(--ci-primary-color, currentcolor)" d="M256 16C123.452 16 16 123.452 16 256s107.452 240 240 240 240-107.452 240-240S388.548 16 256 16m-22 446.849a208.35 208.35 0 0 1-169.667-125.9c-.364-.859-.706-1.724-1.057-2.587L234 429.939Zm0-69.582L50.889 290.76A210 210 0 0 1 48 256q0-9.912.922-19.67L234 339.939Zm0-90L54.819 202.96a206 206 0 0 1 9.514-27.913Q67.1 168.5 70.3 162.191L234 253.934Zm0-86.015L86.914 134.819a209.4 209.4 0 0 1 22.008-25.9q3.72-3.72 7.6-7.228L234 166.027Zm0-87.708-89.648-49.093A206.95 206.95 0 0 1 234 49.151ZM464 256a207.775 207.775 0 0 1-198 207.761V48.239A207.79 207.79 0 0 1 464 256" class="ci-primary" />
</svg>
</button>
<ul class="dropdown-menu dropdown-menu-end" style="--cui-dropdown-min-width: 8rem">
<li>
<button class="dropdown-item d-flex align-items-center" type="button" data-coreui-theme-value="light">
<svg class="icon icon-lg me-3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="var(--ci-primary-color, currentcolor)" d="M256 104c-83.813 0-152 68.187-152 152s68.187 152 152 152 152-68.187 152-152-68.187-152-152-152m0 272a120 120 0 1 1 120-120 120.136 120.136 0 0 1-120 120M240 16h32v48h-32zm0 432h32v48h-32zm208-208h48v32h-48zm-432 0h48v32H16zm372.687 171.314 22.627-22.627 32 32-22.627 22.627zm-320-320 22.628-22.628 32 32-22.628 22.628zm-.002 329.375 32-32 22.628 22.626-32 32zm320.002-320.003 32-32 22.628 22.628-32 32z" class="ci-primary" />
</svg>
Light
</button>
</li>
<li>
<button class="dropdown-item d-flex align-items-center" type="button" data-coreui-theme-value="dark">
<svg class="icon icon-lg me-3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="var(--ci-primary-color, currentcolor)" d="M268.279 496c-67.574 0-130.978-26.191-178.534-73.745S16 311.293 16 243.718A252.25 252.25 0 0 1 154.183 18.676a24.44 24.44 0 0 1 34.46 28.958 220.12 220.12 0 0 0 54.8 220.923A218.75 218.75 0 0 0 399.085 333.2a220.2 220.2 0 0 0 65.277-9.846 24.439 24.439 0 0 1 28.959 34.461A252.26 252.26 0 0 1 268.279 496M153.31 55.781A219.3 219.3 0 0 0 48 243.718C48 365.181 146.816 464 268.279 464a219.3 219.3 0 0 0 187.938-105.31 253 253 0 0 1-57.13 6.513 250.54 250.54 0 0 1-178.268-74.016 252.15 252.15 0 0 1-67.509-235.4Z" class="ci-primary" />
</svg>
Dark
</button>
</li>
<li>
<button class="dropdown-item d-flex align-items-center active" type="button" data-coreui-theme-value="auto">
<svg class="icon icon-lg me-3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="var(--ci-primary-color, currentcolor)" d="M256 16C123.452 16 16 123.452 16 256s107.452 240 240 240 240-107.452 240-240S388.548 16 256 16m-22 446.849a208.35 208.35 0 0 1-169.667-125.9c-.364-.859-.706-1.724-1.057-2.587L234 429.939Zm0-69.582L50.889 290.76A210 210 0 0 1 48 256q0-9.912.922-19.67L234 339.939Zm0-90L54.819 202.96a206 206 0 0 1 9.514-27.913Q67.1 168.5 70.3 162.191L234 253.934Zm0-86.015L86.914 134.819a209.4 209.4 0 0 1 22.008-25.9q3.72-3.72 7.6-7.228L234 166.027Zm0-87.708-89.648-49.093A206.95 206.95 0 0 1 234 49.151ZM464 256a207.775 207.775 0 0 1-198 207.761V48.239A207.79 207.79 0 0 1 464 256" class="ci-primary" />
</svg>
Auto
</button>
</li>
</ul>
</li>
<li class="nav-item py-1">
<div class="vr h-100 mx-2 text-body text-opacity-75"></div>
</li>
<li class="nav-item dropdown">
<livewire:layouts::profile-dropdown /> <livewire:layouts::profile-dropdown />
</li> </li>
</ul> </ul>
</div> </div>
</header>
</nav>

2
resources/views/components/layouts/⚡language-switcher/language-switcher.blade.php

@ -1,5 +1,5 @@
<div> <div>
<a class="position-relative btn-icon btn-sm btn-light btn rounded-circle" data-bs-toggle="dropdown" <a class="btn btn-link nav-link py-2 px-2 d-flex align-items-center" data-bs-toggle="dropdown"
aria-expanded="false" href="#" role="button"> aria-expanded="false" href="#" role="button">
<x-tabler-language width="20" /> <x-tabler-language width="20" />
</a> </a>

2
resources/views/components/layouts/⚡notification/notification.blade.php

@ -1,5 +1,5 @@
<div> <div>
<a class="position-relative btn-icon btn-sm btn-light btn rounded-circle" data-bs-toggle="dropdown" <a class="btn btn-link nav-link py-2 px-2 d-flex align-items-center" data-bs-toggle="dropdown"
aria-expanded="false" href="#" role="button"> aria-expanded="false" href="#" role="button">
<x-tabler-bell width="20" /> <x-tabler-bell width="20" />
<span class="position-absolute start-100 translate-middle badge rounded-pill bg-danger ms-n2 top-0 mt-2"> <span class="position-absolute start-100 translate-middle badge rounded-pill bg-danger ms-n2 top-0 mt-2">

39
resources/views/pages/identity/users/index.blade.php

@ -3,6 +3,19 @@
{{ $dataTable->table() }} {{ $dataTable->table() }}
</x-card> </x-card>
<template id="template-role-filter">
<x-form.select id="role-filter" no-label class="form-select-sm"
x-select2="{allowClear: true, placeholder: 'Role Filter', url: '{{ route('api.v1.lookups.roles') }}'}"
x-on:change="LaravelDataTables['user-table'].ajax.reload()" />
</template>
<template id="template-status-filter">
<x-form.select id="status-filter"
no-label class="form-select form-select-sm" x-select2="{allowClear: true, placeholder: 'Status Filter'}"
:options="collect(\App\Domains\Identity\Enums\UserStatus::cases())
->mapWithKeys(fn($stats) => [$stats->value => $stats->label()])"
x-on:change="LaravelDataTables['user-table'].ajax.reload()" />
</template>
<livewire:pages::identity.users.form-modal /> <livewire:pages::identity.users.form-modal />
<livewire:pages::system.audit.audit-view-modal key-name="ulid" model="\App\Domains\Identity\Models\User::class" <livewire:pages::system.audit.audit-view-modal key-name="ulid" model="\App\Domains\Identity\Models\User::class"
translation="domains/identity/field.user." /> translation="domains/identity/field.user." />
@ -13,32 +26,6 @@
resource-name="user" /> resource-name="user" />
@push('page-scripts') @push('page-scripts')
<script type="module">
document.addEventListener('DOMContentLoaded', function() {
if (typeof DataTable !== 'undefined') {
window.DataTable.feature.register('role-filter', function (settings, opts) {
let container = document.createElement('div');
container.style = 'width: 250px;';
container.innerHTML = `<x-form.select id="role-filter" no-label class="form-select-sm"
x-select2="{allowClear: true, placeholder: 'Role Filter', url: '{{ route('api.v1.lookups.roles') }}'}"
x-on:change="LaravelDataTables['user-table'].ajax.reload()" />`;
return container;
});
window.DataTable.feature.register('status-filter', function (settings, opts) {
let container = document.createElement('div');
container.style = 'width: 250px;';
container.innerHTML = `<x-form.select id="status-filter"
no-label class="form-select form-select-sm" x-select2="{allowClear: true, placeholder: 'Status Filter'}"
:options="collect(\App\Domains\Identity\Enums\UserStatus::cases())
->mapWithKeys(fn($stats) => [$stats->value => $stats->label()])"
x-on:change="LaravelDataTables['user-table'].ajax.reload()" />`;
return container;
});
}
});
</script>
@vite(['resources/js/plugin/datatables.js', 'resources/js/plugin/select2.js']) @vite(['resources/js/plugin/datatables.js', 'resources/js/plugin/select2.js'])
{{ $dataTable->scripts(attributes: ['type' => 'module']) }} {{ $dataTable->scripts(attributes: ['type' => 'module']) }}
@endpush @endpush

Loading…
Cancel
Save