Merge branch 'lpj'

# Conflicts:
#	composer.json
This commit is contained in:
Daeng Deni Mardaeni 2025-04-26 17:36:25 +07:00
commit c80ecb04db
22 changed files with 1616 additions and 1618 deletions

View File

@ -2,6 +2,7 @@
namespace App\Providers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
@ -19,6 +20,6 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
//
Model::automaticallyEagerLoadRelationships();
}
}

View File

@ -6,7 +6,9 @@
"license": "MIT",
"require": {
"php": "^8.2",
"barryvdh/laravel-dompdf": "^3.0",
"daengdeni/authentication-module": "dev-master",
"daengdeni/basicdata-module": "dev-master",
"daengdeni/laravel-id-generator": "^1.0",
"daengdeni/location-module": "dev-master",
"daengdeni/logs-module": "dev-master",
@ -14,7 +16,7 @@
"daengdeni/usermanagement-module": "dev-master",
"diglactic/laravel-breadcrumbs": "^9.0",
"joshbrw/laravel-module-installer": "^2.0",
"laravel/framework": "^11.9",
"laravel/framework": "^12.0",
"laravel/pulse": "^1.2",
"laravel/tinker": "^2.9",
"maatwebsite/excel": "^3.1",

View File

@ -3,5 +3,6 @@
"Location": true,
"Usermanagement": true,
"Logs": true,
"Authentication": true
"Authentication": true,
"Basicdata": true
}

View File

@ -23,9 +23,11 @@
"clipboard": "^2.0.11",
"esri-leaflet": "^3.0.12",
"esri-leaflet-geocoder": "^3.1.5",
"imask": "^7.6.1",
"jquery": "^3.7.1",
"mini-svg-data-uri": "^1.4.4",
"notie": "^4.3.1",
"pdfobject": "^2.3.0",
"sweetalert2": "^11.14.3",
"toastr": "^2.1.4",
"tom-select": "^2.3.1"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

BIN
public/img/pdf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

314
public/vendor/pdfobject.min.js vendored Normal file
View File

@ -0,0 +1,314 @@
/**
* PDFObject v2.3.0
* https://github.com/pipwerks/PDFObject
* @license
* Copyright (c) 2008-2024 Philip Hutchison
* MIT-style license: http://pipwerks.mit-license.org/
* UMD module pattern from https://github.com/umdjs/umd/blob/master/templates/returnExports.js
*/
!(function (root, factory) {
"function" == typeof define && define.amd
? define([], factory)
: "object" == typeof module && module.exports
? (module.exports = factory())
: (root.PDFObject = factory());
})(this, function () {
"use strict";
if (
"undefined" == typeof window ||
void 0 === window.navigator ||
void 0 === window.navigator.userAgent
)
return !1;
let win = window,
nav = win.navigator,
ua = nav.userAgent,
suppressConsole = !1,
validateAX = function (type) {
var ax = null;
try {
ax = new ActiveXObject(type);
} catch (e) {
ax = null;
}
return !!ax;
},
supportsPDFs = (function () {
if (
(void 0 !== nav.platform &&
"MacIntel" === nav.platform &&
void 0 !== nav.maxTouchPoints &&
nav.maxTouchPoints > 1) ||
/Mobi|Tablet|Android|iPad|iPhone/.test(ua)
)
return !1;
let supportsPDFVE = "boolean" == typeof nav.pdfViewerEnabled;
return (
!(supportsPDFVE && !nav.pdfViewerEnabled) &&
((supportsPDFVE && nav.pdfViewerEnabled) ||
(function () {
let isChromium = void 0 !== win.chrome,
isSafari =
void 0 !== win.safari ||
(void 0 !== nav.vendor &&
/Apple/.test(nav.vendor) &&
/Safari/.test(ua)),
isFirefox =
void 0 !== win.Mozilla || /irefox/.test(ua);
return isChromium || isSafari || isFirefox;
})() ||
("ActiveXObject" in win &&
(validateAX("AcroPDF.PDF") ||
validateAX("PDF.PdfCtrl"))))
);
})(),
embedError = function (msg) {
return suppressConsole || console.log("[PDFObject]", msg), !1;
},
generatePDFObjectMarkup = function (
embedType,
targetNode,
url,
pdfOpenFragment,
width,
height,
id,
title,
omitInlineStyles,
customAttribute,
PDFJS_URL,
) {
!(function (node) {
for (; node.firstChild; ) node.removeChild(node.firstChild);
})(targetNode);
let source = url;
if ("pdfjs" === embedType) {
source =
PDFJS_URL +
(-1 !== PDFJS_URL.indexOf("?") ? "&" : "?") +
"file=" +
encodeURIComponent(url) +
pdfOpenFragment;
} else source += pdfOpenFragment;
let el = document.createElement("iframe");
if (
((el.className = "pdfobject"),
(el.type = "application/pdf"),
(el.title = title),
(el.src = source),
(el.allow = "fullscreen"),
(el.frameborder = "0"),
id && (el.id = id),
!omitInlineStyles)
) {
let style = "border: none;";
targetNode !== document.body
? (style += "width: " + width + "; height: " + height + ";")
: (style +=
"position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%;"),
(el.style.cssText = style);
}
return (
customAttribute &&
customAttribute.key &&
-1 ===
[
"className",
"type",
"title",
"src",
"style",
"id",
"allow",
"frameborder",
].indexOf(customAttribute.key) &&
el.setAttribute(
customAttribute.key,
void 0 !== customAttribute.value
? customAttribute.value
: "",
),
targetNode.classList.add("pdfobject-container"),
targetNode.appendChild(el),
targetNode.getElementsByTagName("iframe")[0]
);
},
embed = function (url, targetSelector, options) {
let selector = targetSelector || !1,
opt = options || {};
suppressConsole =
"boolean" == typeof opt.suppressConsole && opt.suppressConsole;
let id = "string" == typeof opt.id ? opt.id : "",
page = opt.page || !1,
pdfOpenParams = opt.pdfOpenParams || {},
fallbackLink =
("string" != typeof opt.fallbackLink &&
"boolean" != typeof opt.fallbackLink) ||
opt.fallbackLink,
width = opt.width || "100%",
height = opt.height || "100%",
title = opt.title || "Embedded PDF",
forcePDFJS =
"boolean" == typeof opt.forcePDFJS && opt.forcePDFJS,
omitInlineStyles =
"boolean" == typeof opt.omitInlineStyles &&
opt.omitInlineStyles,
PDFJS_URL = opt.PDFJS_URL || !1,
targetNode = (function (targetSelector) {
let targetNode = document.body;
return (
"string" == typeof targetSelector
? (targetNode =
document.querySelector(targetSelector))
: void 0 !== win.jQuery &&
targetSelector instanceof jQuery &&
targetSelector.length
? (targetNode = targetSelector.get(0))
: void 0 !== targetSelector.nodeType &&
1 === targetSelector.nodeType &&
(targetNode = targetSelector),
targetNode
);
})(selector),
pdfOpenFragment = "",
customAttribute = opt.customAttribute || {},
fallbackHTML_default =
"<p>This browser does not support inline PDFs. Please download the PDF to view it: [pdflink]</p>";
if ("string" != typeof url) return embedError("URL is not valid");
if (!targetNode)
return embedError("Target element cannot be determined");
if (
(page && (pdfOpenParams.page = page),
(pdfOpenFragment = (function (pdfParams) {
let prop,
string = "",
paramArray = [],
fdf = "";
if (
((pdfParams.comment ||
pdfParams.viewrect ||
pdfParams.highlight) &&
(pdfParams.page ||
((pdfParams.page = 1),
embedError(
"The comment, viewrect, and highlight parameters require a page parameter, but none was specified. Defaulting to page 1.",
))),
pdfParams.page &&
(paramArray.push(
"page=" + encodeURIComponent(pdfParams.page),
),
delete pdfParams.page),
pdfParams.fdf &&
((fdf = pdfParams.fdf), delete pdfParams.fdf),
pdfParams)
) {
for (prop in pdfParams)
pdfParams.hasOwnProperty(prop) &&
paramArray.push(
encodeURIComponent(prop) +
"=" +
encodeURIComponent(pdfParams[prop]),
);
fdf &&
paramArray.push("fdf=" + encodeURIComponent(fdf)),
(string = paramArray.join("&")) &&
(string = "#" + string);
}
return string;
})(pdfOpenParams)),
forcePDFJS && PDFJS_URL)
)
return generatePDFObjectMarkup(
"pdfjs",
targetNode,
url,
pdfOpenFragment,
width,
height,
id,
title,
omitInlineStyles,
customAttribute,
PDFJS_URL,
);
if (supportsPDFs)
return generatePDFObjectMarkup(
"iframe",
targetNode,
url,
pdfOpenFragment,
width,
height,
id,
title,
omitInlineStyles,
customAttribute,
);
if (PDFJS_URL)
return generatePDFObjectMarkup(
"pdfjs",
targetNode,
url,
pdfOpenFragment,
width,
height,
id,
title,
omitInlineStyles,
customAttribute,
PDFJS_URL,
);
if (fallbackLink)
if ("string" == typeof fallbackLink)
targetNode.innerHTML = fallbackLink.replace(
/\[url\]/g,
url,
);
else if (-1 !== url.indexOf("data:application/pdf;base64"))
!(function (b64, filename, targetNode, fallbackHTML) {
if (
window.Blob &&
window.URL &&
window.URL.createObjectURL
) {
var xhr = new XMLHttpRequest();
xhr.open("GET", b64, !0),
(xhr.responseType = "blob"),
(xhr.onload = function () {
if (200 === xhr.status) {
var blob = xhr.response,
link = document.createElement("a");
(link.innerText = "Download PDF"),
(link.href =
URL.createObjectURL(blob)),
link.setAttribute(
"download",
filename,
),
(targetNode.innerHTML =
fallbackHTML.replace(
/\[pdflink\]/g,
link.outerHTML,
));
}
}),
xhr.send();
}
})(url, "file.pdf", targetNode, fallbackHTML_default);
else {
let link = "<a href='" + url + "'>Download PDF</a>";
targetNode.innerHTML = fallbackHTML_default.replace(
/\[pdflink\]/g,
link,
);
}
return embedError("This browser does not support embedded PDFs");
};
return {
embed: function (a, b, c) {
return embed(a, b, c);
},
pdfobjectversion: "2.3.0",
supportsPDFs: supportsPDFs,
};
});

595
public/vendor/signature.pad.js vendored Normal file
View File

@ -0,0 +1,595 @@
/*!
* Signature Pad v4.1.7 | https://github.com/szimek/signature_pad
* (c) 2023 Szymon Nowak | Released under the MIT license
*/
!(function (t, e) {
"object" == typeof exports && "undefined" != typeof module
? (module.exports = e())
: "function" == typeof define && define.amd
? define(e)
: ((t =
"undefined" != typeof globalThis
? globalThis
: t || self).SignaturePad = e());
})(this, function () {
"use strict";
class t {
constructor(t, e, i, s) {
if (isNaN(t) || isNaN(e))
throw new Error(`Point is invalid: (${t}, ${e})`);
(this.x = +t),
(this.y = +e),
(this.pressure = i || 0),
(this.time = s || Date.now());
}
distanceTo(t) {
return Math.sqrt(
Math.pow(this.x - t.x, 2) + Math.pow(this.y - t.y, 2),
);
}
equals(t) {
return (
this.x === t.x &&
this.y === t.y &&
this.pressure === t.pressure &&
this.time === t.time
);
}
velocityFrom(t) {
return this.time !== t.time
? this.distanceTo(t) / (this.time - t.time)
: 0;
}
}
class e {
static fromPoints(t, i) {
const s = this.calculateControlPoints(t[0], t[1], t[2]).c2,
n = this.calculateControlPoints(t[1], t[2], t[3]).c1;
return new e(t[1], s, n, t[2], i.start, i.end);
}
static calculateControlPoints(e, i, s) {
const n = e.x - i.x,
o = e.y - i.y,
h = i.x - s.x,
r = i.y - s.y,
a = (e.x + i.x) / 2,
c = (e.y + i.y) / 2,
d = (i.x + s.x) / 2,
l = (i.y + s.y) / 2,
u = Math.sqrt(n * n + o * o),
v = Math.sqrt(h * h + r * r),
_ = v / (u + v),
p = d + (a - d) * _,
m = l + (c - l) * _,
g = i.x - p,
w = i.y - m;
return { c1: new t(a + g, c + w), c2: new t(d + g, l + w) };
}
constructor(t, e, i, s, n, o) {
(this.startPoint = t),
(this.control2 = e),
(this.control1 = i),
(this.endPoint = s),
(this.startWidth = n),
(this.endWidth = o);
}
length() {
let t,
e,
i = 0;
for (let s = 0; s <= 10; s += 1) {
const n = s / 10,
o = this.point(
n,
this.startPoint.x,
this.control1.x,
this.control2.x,
this.endPoint.x,
),
h = this.point(
n,
this.startPoint.y,
this.control1.y,
this.control2.y,
this.endPoint.y,
);
if (s > 0) {
const s = o - t,
n = h - e;
i += Math.sqrt(s * s + n * n);
}
(t = o), (e = h);
}
return i;
}
point(t, e, i, s, n) {
return (
e * (1 - t) * (1 - t) * (1 - t) +
3 * i * (1 - t) * (1 - t) * t +
3 * s * (1 - t) * t * t +
n * t * t * t
);
}
}
class i {
constructor() {
try {
this._et = new EventTarget();
} catch (t) {
this._et = document;
}
}
addEventListener(t, e, i) {
this._et.addEventListener(t, e, i);
}
dispatchEvent(t) {
return this._et.dispatchEvent(t);
}
removeEventListener(t, e, i) {
this._et.removeEventListener(t, e, i);
}
}
class s extends i {
constructor(t, e = {}) {
super(),
(this.canvas = t),
(this._drawingStroke = !1),
(this._isEmpty = !0),
(this._lastPoints = []),
(this._data = []),
(this._lastVelocity = 0),
(this._lastWidth = 0),
(this._handleMouseDown = (t) => {
1 === t.buttons && this._strokeBegin(t);
}),
(this._handleMouseMove = (t) => {
this._strokeMoveUpdate(t);
}),
(this._handleMouseUp = (t) => {
1 === t.buttons && this._strokeEnd(t);
}),
(this._handleTouchStart = (t) => {
if (
(t.cancelable && t.preventDefault(),
1 === t.targetTouches.length)
) {
const e = t.changedTouches[0];
this._strokeBegin(e);
}
}),
(this._handleTouchMove = (t) => {
t.cancelable && t.preventDefault();
const e = t.targetTouches[0];
this._strokeMoveUpdate(e);
}),
(this._handleTouchEnd = (t) => {
if (t.target === this.canvas) {
t.cancelable && t.preventDefault();
const e = t.changedTouches[0];
this._strokeEnd(e);
}
}),
(this._handlePointerStart = (t) => {
t.preventDefault(), this._strokeBegin(t);
}),
(this._handlePointerMove = (t) => {
this._strokeMoveUpdate(t);
}),
(this._handlePointerEnd = (t) => {
this._drawingStroke &&
(t.preventDefault(), this._strokeEnd(t));
}),
(this.velocityFilterWeight = e.velocityFilterWeight || 0.7),
(this.minWidth = e.minWidth || 0.5),
(this.maxWidth = e.maxWidth || 2.5),
(this.throttle = "throttle" in e ? e.throttle : 16),
(this.minDistance = "minDistance" in e ? e.minDistance : 5),
(this.dotSize = e.dotSize || 0),
(this.penColor = e.penColor || "black"),
(this.backgroundColor = e.backgroundColor || "rgba(0,0,0,0)"),
(this.compositeOperation =
e.compositeOperation || "source-over"),
(this._strokeMoveUpdate = this.throttle
? (function (t, e = 250) {
let i,
s,
n,
o = 0,
h = null;
const r = () => {
(o = Date.now()),
(h = null),
(i = t.apply(s, n)),
h || ((s = null), (n = []));
};
return function (...a) {
const c = Date.now(),
d = e - (c - o);
return (
(s = this),
(n = a),
d <= 0 || d > e
? (h && (clearTimeout(h), (h = null)),
(o = c),
(i = t.apply(s, n)),
h || ((s = null), (n = [])))
: h || (h = window.setTimeout(r, d)),
i
);
};
})(s.prototype._strokeUpdate, this.throttle)
: s.prototype._strokeUpdate),
(this._ctx = t.getContext("2d")),
this.clear(),
this.on();
}
clear() {
const { _ctx: t, canvas: e } = this;
(t.fillStyle = this.backgroundColor),
t.clearRect(0, 0, e.width, e.height),
t.fillRect(0, 0, e.width, e.height),
(this._data = []),
this._reset(this._getPointGroupOptions()),
(this._isEmpty = !0);
}
fromDataURL(t, e = {}) {
return new Promise((i, s) => {
const n = new Image(),
o = e.ratio || window.devicePixelRatio || 1,
h = e.width || this.canvas.width / o,
r = e.height || this.canvas.height / o,
a = e.xOffset || 0,
c = e.yOffset || 0;
this._reset(this._getPointGroupOptions()),
(n.onload = () => {
this._ctx.drawImage(n, a, c, h, r), i();
}),
(n.onerror = (t) => {
s(t);
}),
(n.crossOrigin = "anonymous"),
(n.src = t),
(this._isEmpty = !1);
});
}
toDataURL(t = "image/png", e) {
return "image/svg+xml" === t
? ("object" != typeof e && (e = void 0),
`data:image/svg+xml;base64,${btoa(this.toSVG(e))}`)
: ("number" != typeof e && (e = void 0),
this.canvas.toDataURL(t, e));
}
on() {
(this.canvas.style.touchAction = "none"),
(this.canvas.style.msTouchAction = "none"),
(this.canvas.style.userSelect = "none");
const t =
/Macintosh/.test(navigator.userAgent) &&
"ontouchstart" in document;
window.PointerEvent && !t
? this._handlePointerEvents()
: (this._handleMouseEvents(),
"ontouchstart" in window && this._handleTouchEvents());
}
off() {
(this.canvas.style.touchAction = "auto"),
(this.canvas.style.msTouchAction = "auto"),
(this.canvas.style.userSelect = "auto"),
this.canvas.removeEventListener(
"pointerdown",
this._handlePointerStart,
),
this.canvas.removeEventListener(
"pointermove",
this._handlePointerMove,
),
this.canvas.ownerDocument.removeEventListener(
"pointerup",
this._handlePointerEnd,
),
this.canvas.removeEventListener(
"mousedown",
this._handleMouseDown,
),
this.canvas.removeEventListener(
"mousemove",
this._handleMouseMove,
),
this.canvas.ownerDocument.removeEventListener(
"mouseup",
this._handleMouseUp,
),
this.canvas.removeEventListener(
"touchstart",
this._handleTouchStart,
),
this.canvas.removeEventListener(
"touchmove",
this._handleTouchMove,
),
this.canvas.removeEventListener(
"touchend",
this._handleTouchEnd,
);
}
isEmpty() {
return this._isEmpty;
}
fromData(t, { clear: e = !0 } = {}) {
e && this.clear(),
this._fromData(
t,
this._drawCurve.bind(this),
this._drawDot.bind(this),
),
(this._data = this._data.concat(t));
}
toData() {
return this._data;
}
_getPointGroupOptions(t) {
return {
penColor: t && "penColor" in t ? t.penColor : this.penColor,
dotSize: t && "dotSize" in t ? t.dotSize : this.dotSize,
minWidth: t && "minWidth" in t ? t.minWidth : this.minWidth,
maxWidth: t && "maxWidth" in t ? t.maxWidth : this.maxWidth,
velocityFilterWeight:
t && "velocityFilterWeight" in t
? t.velocityFilterWeight
: this.velocityFilterWeight,
compositeOperation:
t && "compositeOperation" in t
? t.compositeOperation
: this.compositeOperation,
};
}
_strokeBegin(t) {
if (
!this.dispatchEvent(
new CustomEvent("beginStroke", {
detail: t,
cancelable: !0,
}),
)
)
return;
this._drawingStroke = !0;
const e = this._getPointGroupOptions(),
i = Object.assign(Object.assign({}, e), { points: [] });
this._data.push(i), this._reset(e), this._strokeUpdate(t);
}
_strokeUpdate(t) {
if (!this._drawingStroke) return;
if (0 === this._data.length) return void this._strokeBegin(t);
this.dispatchEvent(
new CustomEvent("beforeUpdateStroke", { detail: t }),
);
const e = t.clientX,
i = t.clientY,
s =
void 0 !== t.pressure
? t.pressure
: void 0 !== t.force
? t.force
: 0,
n = this._createPoint(e, i, s),
o = this._data[this._data.length - 1],
h = o.points,
r = h.length > 0 && h[h.length - 1],
a = !!r && n.distanceTo(r) <= this.minDistance,
c = this._getPointGroupOptions(o);
if (!r || !r || !a) {
const t = this._addPoint(n, c);
r ? t && this._drawCurve(t, c) : this._drawDot(n, c),
h.push({
time: n.time,
x: n.x,
y: n.y,
pressure: n.pressure,
});
}
this.dispatchEvent(
new CustomEvent("afterUpdateStroke", { detail: t }),
);
}
_strokeEnd(t) {
this._drawingStroke &&
(this._strokeUpdate(t),
(this._drawingStroke = !1),
this.dispatchEvent(
new CustomEvent("endStroke", { detail: t }),
));
}
_handlePointerEvents() {
(this._drawingStroke = !1),
this.canvas.addEventListener(
"pointerdown",
this._handlePointerStart,
),
this.canvas.addEventListener(
"pointermove",
this._handlePointerMove,
),
this.canvas.ownerDocument.addEventListener(
"pointerup",
this._handlePointerEnd,
);
}
_handleMouseEvents() {
(this._drawingStroke = !1),
this.canvas.addEventListener(
"mousedown",
this._handleMouseDown,
),
this.canvas.addEventListener(
"mousemove",
this._handleMouseMove,
),
this.canvas.ownerDocument.addEventListener(
"mouseup",
this._handleMouseUp,
);
}
_handleTouchEvents() {
this.canvas.addEventListener("touchstart", this._handleTouchStart),
this.canvas.addEventListener(
"touchmove",
this._handleTouchMove,
),
this.canvas.addEventListener("touchend", this._handleTouchEnd);
}
_reset(t) {
(this._lastPoints = []),
(this._lastVelocity = 0),
(this._lastWidth = (t.minWidth + t.maxWidth) / 2),
(this._ctx.fillStyle = t.penColor),
(this._ctx.globalCompositeOperation = t.compositeOperation);
}
_createPoint(e, i, s) {
const n = this.canvas.getBoundingClientRect();
return new t(e - n.left, i - n.top, s, new Date().getTime());
}
_addPoint(t, i) {
const { _lastPoints: s } = this;
if ((s.push(t), s.length > 2)) {
3 === s.length && s.unshift(s[0]);
const t = this._calculateCurveWidths(s[1], s[2], i),
n = e.fromPoints(s, t);
return s.shift(), n;
}
return null;
}
_calculateCurveWidths(t, e, i) {
const s =
i.velocityFilterWeight * e.velocityFrom(t) +
(1 - i.velocityFilterWeight) * this._lastVelocity,
n = this._strokeWidth(s, i),
o = { end: n, start: this._lastWidth };
return (this._lastVelocity = s), (this._lastWidth = n), o;
}
_strokeWidth(t, e) {
return Math.max(e.maxWidth / (t + 1), e.minWidth);
}
_drawCurveSegment(t, e, i) {
const s = this._ctx;
s.moveTo(t, e),
s.arc(t, e, i, 0, 2 * Math.PI, !1),
(this._isEmpty = !1);
}
_drawCurve(t, e) {
const i = this._ctx,
s = t.endWidth - t.startWidth,
n = 2 * Math.ceil(t.length());
i.beginPath(), (i.fillStyle = e.penColor);
for (let i = 0; i < n; i += 1) {
const o = i / n,
h = o * o,
r = h * o,
a = 1 - o,
c = a * a,
d = c * a;
let l = d * t.startPoint.x;
(l += 3 * c * o * t.control1.x),
(l += 3 * a * h * t.control2.x),
(l += r * t.endPoint.x);
let u = d * t.startPoint.y;
(u += 3 * c * o * t.control1.y),
(u += 3 * a * h * t.control2.y),
(u += r * t.endPoint.y);
const v = Math.min(t.startWidth + r * s, e.maxWidth);
this._drawCurveSegment(l, u, v);
}
i.closePath(), i.fill();
}
_drawDot(t, e) {
const i = this._ctx,
s = e.dotSize > 0 ? e.dotSize : (e.minWidth + e.maxWidth) / 2;
i.beginPath(),
this._drawCurveSegment(t.x, t.y, s),
i.closePath(),
(i.fillStyle = e.penColor),
i.fill();
}
_fromData(e, i, s) {
for (const n of e) {
const { points: e } = n,
o = this._getPointGroupOptions(n);
if (e.length > 1)
for (let s = 0; s < e.length; s += 1) {
const n = e[s],
h = new t(n.x, n.y, n.pressure, n.time);
0 === s && this._reset(o);
const r = this._addPoint(h, o);
r && i(r, o);
}
else this._reset(o), s(e[0], o);
}
}
toSVG({ includeBackgroundColor: t = !1 } = {}) {
const e = this._data,
i = Math.max(window.devicePixelRatio || 1, 1),
s = this.canvas.width / i,
n = this.canvas.height / i,
o = document.createElementNS(
"http://www.w3.org/2000/svg",
"svg",
);
if (
(o.setAttribute("xmlns", "http://www.w3.org/2000/svg"),
o.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"),
o.setAttribute("viewBox", `0 0 ${s} ${n}`),
o.setAttribute("width", s.toString()),
o.setAttribute("height", n.toString()),
t && this.backgroundColor)
) {
const t = document.createElement("rect");
t.setAttribute("width", "100%"),
t.setAttribute("height", "100%"),
t.setAttribute("fill", this.backgroundColor),
o.appendChild(t);
}
return (
this._fromData(
e,
(t, { penColor: e }) => {
const i = document.createElement("path");
if (
!(
isNaN(t.control1.x) ||
isNaN(t.control1.y) ||
isNaN(t.control2.x) ||
isNaN(t.control2.y)
)
) {
const s = `M ${t.startPoint.x.toFixed(3)},${t.startPoint.y.toFixed(3)} C ${t.control1.x.toFixed(3)},${t.control1.y.toFixed(3)} ${t.control2.x.toFixed(3)},${t.control2.y.toFixed(3)} ${t.endPoint.x.toFixed(3)},${t.endPoint.y.toFixed(3)}`;
i.setAttribute("d", s),
i.setAttribute(
"stroke-width",
(2.25 * t.endWidth).toFixed(3),
),
i.setAttribute("stroke", e),
i.setAttribute("fill", "none"),
i.setAttribute("stroke-linecap", "round"),
o.appendChild(i);
}
},
(
t,
{ penColor: e, dotSize: i, minWidth: s, maxWidth: n },
) => {
const h = document.createElement("circle"),
r = i > 0 ? i : (s + n) / 2;
h.setAttribute("r", r.toString()),
h.setAttribute("cx", t.x.toString()),
h.setAttribute("cy", t.y.toString()),
h.setAttribute("fill", e),
o.appendChild(h);
},
),
o.outerHTML
);
}
}
return s;
});
//# sourceMappingURL=signature_pad.umd.min.js.map

View File

@ -1,33 +1,39 @@
import "./bootstrap";
import "../metronic/core/index";
import "../metronic/app/layouts/base.js";
import $ from "jquery";
import Swal from "sweetalert2";
import TomSelect from "tom-select";
import toast from "toastr";
import "toastr/build/toastr.css";
import IMask from "imask";
// import FilerobotImageEditor from "filerobot-image-editor";
window.jQuery = $;
window.$ = $;
import Swal from "sweetalert2";
window.Swal = Swal;
window.swal = Swal;
import TomSelect from "tom-select";
window.IMask = IMask;
// window.FilerobotImageEditor = FilerobotImageEditor;
window.TomSelect = TomSelect;
document.querySelectorAll(".tomselect").forEach((el) => {
let settings = {
plugins: ["dropdown_input"],
plugins: ["dropdown_input", "remove_button", "clear_button"],
create: false,
createOnBlur: true,
closeButton: true,
html: function (data) {
return `<div class="${data.className}" title="${data.title}">&times;</div>`;
},
};
new TomSelect(el, settings);
});
import toast from "toastr";
window.toast = toast;
import "toastr/build/toastr.css";
document.querySelectorAll(".toastr").forEach((el) => {
toast.options = {
@ -41,3 +47,73 @@ document.querySelectorAll(".toastr").forEach((el) => {
};
toast[el.dataset.type](el.dataset.message);
});
// Fungsi untuk memformat tanggal ke format Indonesia
window.formatTanggalIndonesia = function (date) {
const options = {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
};
return new Date(date).toLocaleDateString("id-ID", options);
};
// Fungsi untuk memformat tanggal dan waktu ke format Indonesia
window.formatTanggalWaktuIndonesia = function (date) {
const options = {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
};
return new Date(date).toLocaleString("id-ID", options);
};
// Fungsi untuk memformat angka ke format Rupiah
window.formatRupiah = function (angka) {
const formatter = new Intl.NumberFormat("id-ID", {
style: "currency",
currency: "IDR",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
return formatter.format(angka);
};
document.querySelectorAll(".currency").forEach((el) => {
IMask(el, {
mask: Number, // enable number mask
// other options are optional with defaults below
scale: 2, // digits after point, 0 for integers
thousandsSeparator: ".", // any single char
padFractionalZeros: false, // if true, then pads zeros at end to the length of scale
normalizeZeros: true, // appends or removes zeros at ends
radix: ",", // fractional delimiter
mapToRadix: ["."], // symbols to process as radix
autofix: true,
});
});
document.querySelectorAll(".persen").forEach((el) => {
IMask(el, {
mask: Number, // enable number mask
min: 0,
max: 100,
// other options are optional with defaults below
scale: 2, // digits after point, 0 for integers
thousandsSeparator: ".", // any single char
padFractionalZeros: false, // if true, then pads zeros at end to the length of scale
normalizeZeros: true, // appends or removes zeros at ends
radix: ",", // fractional delimiter
mapToRadix: ["."], // symbols to process as radix
autofix: true,
});
});

View File

@ -1,230 +1,269 @@
/* eslint-disable max-len */
import plugin from 'tailwindcss/plugin';
import svgToDataUri from 'mini-svg-data-uri';
import plugin from "tailwindcss/plugin";
import svgToDataUri from "mini-svg-data-uri";
export default plugin(({ addComponents, theme }) => {
// Base
addComponents({
'.table': {
'width': '100%',
'caption-side': 'bottom',
'border-collapse': 'collapse',
'vertical-align': 'middle',
'text-align': 'left',
'color': 'var(--tw-gray-700)',
'font-weight': theme('fontWeight.medium'),
'font-size': theme('fontSize.sm'),
'line-height': theme('fontSize.sm.1.lineHeight'),
'th, td': {
".table": {
width: "100%",
"caption-side": "bottom",
"border-collapse": "collapse",
"vertical-align": "middle",
"text-align": "left",
color: "var(--tw-gray-700)",
"font-weight": theme("fontWeight.medium"),
"font-size": theme("fontSize.sm"),
"line-height": theme("fontSize.sm.1.lineHeight"),
"th, td": {
'input[type="checkbox"]': {
'vertical-align': 'inherit'
}
},
'thead, tfoot': {
'td, th': {
'background-color': 'var(--tw-table-head-background-color)',
'color': 'var(--tw-gray-600)',
'font-weight': theme('fontWeight.medium'),
'font-size': theme('fontSize.2sm'),
'line-height': theme('fontSize.2sm.1.lineHeight'),
'vertical-align': 'middle'
"vertical-align": "inherit",
},
},
'thead': {
'td, th': {
'border-bottom': 'var(--tw-table-border)'
"thead, tfoot": {
"td, th": {
"background-color": "var(--tw-gray-100)",
color: "var(--tw-gray-800)",
"font-weight": theme("fontWeight.bolder"),
"font-size": theme("fontSize.2sm"),
"line-height": theme("fontSize.2sm.1.lineHeight"),
"vertical-align": "middle",
},
},
'tfoot': {
'td, th': {
'border-top': 'var(--tw-table-border)'
thead: {
"td, th": {
"border-bottom": "var(--tw-table-border)",
},
},
tfoot: {
"td, th": {
"border-top": "var(--tw-table-border)",
},
},
tbody: {
"vertical-align": "inherit",
tr: {
"td, th": {
"border-bottom": "var(--tw-table-border)",
},
"&:last-child": {
"td, th": {
"border-bottom": "0",
},
},
},
'tbody': {
'vertical-align': 'inherit',
'tr': {
'td, th': {
'border-bottom': 'var(--tw-table-border)'
},
'&:last-child': {
'td, th': {
'border-bottom': '0',
},
},
}
}
}
});
// Sizes
addComponents({
'.table': {
'thead, tfoot': {
'td, th': {
'padding-left': theme('custom.components.table.px.DEFAULT'),
'padding-right': theme('custom.components.table.px.DEFAULT'),
'padding-top': theme('custom.components.table.py.DEFAULT.head'),
'padding-bottom': theme('custom.components.table.py.DEFAULT.head')
".table": {
"thead, tfoot": {
"td, th": {
"padding-left": theme("custom.components.table.px.DEFAULT"),
"padding-right": theme(
"custom.components.table.px.DEFAULT",
),
"padding-top": theme(
"custom.components.table.py.DEFAULT.head",
),
"padding-bottom": theme(
"custom.components.table.py.DEFAULT.head",
),
},
},
'tbody': {
'tr': {
'td, th': {
'padding-left': theme('custom.components.table.px.DEFAULT'),
'padding-right': theme('custom.components.table.px.DEFAULT'),
'padding-top': theme('custom.components.table.py.DEFAULT.body'),
'padding-bottom': theme('custom.components.table.py.DEFAULT.body')
}
}
}
},
'.table-xs': {
'thead, tfoot': {
'td, th': {
'padding-left': theme('custom.components.table.px.xs'),
'padding-right': theme('custom.components.table.px.xs'),
'padding-top': theme('custom.components.table.py.xs.head'),
'padding-bottom': theme('custom.components.table.py.xs.head')
tbody: {
tr: {
"td, th": {
"padding-left": theme(
"custom.components.table.px.DEFAULT",
),
"padding-right": theme(
"custom.components.table.px.DEFAULT",
),
"padding-top": theme(
"custom.components.table.py.DEFAULT.body",
),
"padding-bottom": theme(
"custom.components.table.py.DEFAULT.body",
),
},
},
'tbody': {
'tr': {
'td, th': {
'padding-left': theme('custom.components.table.px.xs'),
'padding-right': theme('custom.components.table.px.xs'),
'padding-top': theme('custom.components.table.py.xs.body'),
'padding-bottom': theme('custom.components.table.py.xs.body')
}
}
}
},
'.table-sm': {
'thead, tfoot': {
'td, th': {
'padding-left': theme('custom.components.table.px.sm'),
'padding-right': theme('custom.components.table.px.sm'),
'padding-top': theme('custom.components.table.py.sm.head'),
'padding-bottom': theme('custom.components.table.py.sm.head')
},
},
'tbody': {
'tr': {
'td, th': {
'padding-left': theme('custom.components.table.px.sm'),
'padding-right': theme('custom.components.table.px.sm'),
'padding-top': theme('custom.components.table.py.sm.body'),
'padding-bottom': theme('custom.components.table.py.sm.body')
}
}
}
},
'.table-lg': {
'thead, tfoot': {
'td, th': {
'padding-left': theme('custom.components.table.px.lg'),
'padding-right': theme('custom.components.table.px.lg'),
'padding-top': theme('custom.components.table.py.lg.head'),
'padding-bottom': theme('custom.components.table.py.lg.head')
".table-xs": {
"thead, tfoot": {
"td, th": {
"padding-left": theme("custom.components.table.px.xs"),
"padding-right": theme("custom.components.table.px.xs"),
"padding-top": theme("custom.components.table.py.xs.head"),
"padding-bottom": theme(
"custom.components.table.py.xs.head",
),
},
},
tbody: {
tr: {
"td, th": {
"padding-left": theme("custom.components.table.px.xs"),
"padding-right": theme("custom.components.table.px.xs"),
"padding-top": theme(
"custom.components.table.py.xs.body",
),
"padding-bottom": theme(
"custom.components.table.py.xs.body",
),
},
},
},
},
".table-sm": {
"thead, tfoot": {
"td, th": {
"padding-left": theme("custom.components.table.px.sm"),
"padding-right": theme("custom.components.table.px.sm"),
"padding-top": theme("custom.components.table.py.sm.head"),
"padding-bottom": theme(
"custom.components.table.py.sm.head",
),
},
},
tbody: {
tr: {
"td, th": {
"padding-left": theme("custom.components.table.px.sm"),
"padding-right": theme("custom.components.table.px.sm"),
"padding-top": theme(
"custom.components.table.py.sm.body",
),
"padding-bottom": theme(
"custom.components.table.py.sm.body",
),
},
},
},
},
".table-lg": {
"thead, tfoot": {
"td, th": {
"padding-left": theme("custom.components.table.px.lg"),
"padding-right": theme("custom.components.table.px.lg"),
"padding-top": theme("custom.components.table.py.lg.head"),
"padding-bottom": theme(
"custom.components.table.py.lg.head",
),
},
},
tbody: {
tr: {
"td, th": {
"padding-left": theme("custom.components.table.px.lg"),
"padding-right": theme("custom.components.table.px.lg"),
"padding-top": theme(
"custom.components.table.py.lg.body",
),
"padding-bottom": theme(
"custom.components.table.py.lg.body",
),
},
},
},
},
'tbody': {
'tr': {
'td, th': {
'padding-left': theme('custom.components.table.px.lg'),
'padding-right': theme('custom.components.table.px.lg'),
'padding-top': theme('custom.components.table.py.lg.body'),
'padding-bottom': theme('custom.components.table.py.lg.body')
}
}
}
}
});
// Border
addComponents({
'.table-border': {
'border': 'var(--tw-table-border)',
'td, th': {
'border-right': 'var(--tw-table-border)',
'&:last-child': {
'border-right': '0'
}
}
".table-border": {
border: "var(--tw-table-border)",
"td, th": {
"border-right": "var(--tw-table-border)",
"&:last-child": {
"border-right": "0",
},
'.table-border-l': {
'border-left': 'var(--tw-table-border)'
},
'.table-border-r': {
'border-right': 'var(--tw-table-border)'
tbody: {
tr: {
"&:nth-of-type(even)": {
"background-color":
"var(--tw-table-striped-background-color, var(--tw-table-head-background-color))",
},
'.table-border-t': {
'border-top': 'var(--tw-table-border)'
},
'.table-border-b': {
'border-bottom': 'var(--tw-table-border)'
}
},
},
".table-border-l": {
"border-left": "var(--tw-table-border)",
},
".table-border-r": {
"border-right": "var(--tw-table-border)",
},
".table-border-t": {
"border-top": "var(--tw-table-border)",
},
".table-border-b": {
"border-bottom": "var(--tw-table-border)",
},
});
// Sort
addComponents({
'.sort': {
'display': 'inline-flex',
'align-items': 'center',
'gap': '0.35rem',
'cursor': 'pointer',
'line-height': '1'
".sort": {
display: "inline-flex",
"align-items": "center",
gap: "0.35rem",
cursor: "pointer",
"line-height": "1",
},
'.sort-icon': {
'display': 'inline-flex',
'flex-direction': 'column',
'justify-content': 'center',
'align-items': 'center',
'height': '0.875rem',
'width': '0.875rem',
'gap': '0.125rem',
'line-height': '1',
'&:before': {
'display': 'inline-block',
'content': '""',
'height': '0.25rem',
'width': '0.438rem',
'background-repeat': 'no-repeat',
'background-position': `center`,
'background-size': 'cover',
'background-image': `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z" fill="${theme('base.colors.gray.light.600')}"/></svg>`)}")`
".sort-icon": {
display: "inline-flex",
"flex-direction": "column",
"justify-content": "center",
"align-items": "center",
height: "0.875rem",
width: "0.875rem",
gap: "0.125rem",
"line-height": "1",
"&:before": {
display: "inline-block",
content: '""',
height: "0.25rem",
width: "0.438rem",
"background-repeat": "no-repeat",
"background-position": `center`,
"background-size": "cover",
"background-image": `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z" fill="${theme("base.colors.gray.light.600")}"/></svg>`)}")`,
},
'&:after': {
'display': 'inline-block',
'content': '""',
'height': '0.25rem',
'width': '0.438rem',
'background-repeat': 'no-repeat',
'background-position': `center`,
'background-size': 'cover',
'background-image': `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z" fill="${theme('base.colors.gray.light.600')}"/></svg>`)}")`
"&:after": {
display: "inline-block",
content: '""',
height: "0.25rem",
width: "0.438rem",
"background-repeat": "no-repeat",
"background-position": `center`,
"background-size": "cover",
"background-image": `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z" fill="${theme("base.colors.gray.light.600")}"/></svg>`)}")`,
},
'.asc > &': {
'&:before': {
'background-image': `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z" fill="${theme('base.colors.gray.light.700')}"/></svg>`)}")`
".asc > &": {
"&:before": {
"background-image": `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z" fill="${theme("base.colors.gray.light.700")}"/></svg>`)}")`,
},
'&:after': {
'background-image': `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z" fill="${theme('base.colors.gray.light.400')}"/></svg>`)}")`
}
"&:after": {
"background-image": `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z" fill="${theme("base.colors.gray.light.400")}"/></svg>`)}")`,
},
'.desc > &': {
'&:before': {
'background-image': `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z" fill="${theme('base.colors.gray.light.400')}"/></svg>`)}")`
},
'&:after': {
'background-image': `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z" fill="${theme('base.colors.gray.light.700')}"/></svg>`)}")`
}
}
".desc > &": {
"&:before": {
"background-image": `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z" fill="${theme("base.colors.gray.light.400")}"/></svg>`)}")`,
},
"&:after": {
"background-image": `url("${svgToDataUri(`<svg xmlns="http://www.w3.org/2000/svg" width="8" height="5" viewBox="0 0 8 5" fill="none"><path d="M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z" fill="${theme("base.colors.gray.light.700")}"/></svg>`)}")`,
},
},
},
".sort-label": {
display: "inline-flex",
"align-items": "center",
gap: "0.35rem",
},
'.sort-label': {
'display': 'inline-flex',
'align-items': 'center',
'gap': '0.35rem'
}
});
});

View File

@ -10,6 +10,8 @@
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="{{ asset('vendor/dropzone/dropzone.min.css') }}" type="text/css" />
@vite(Module::getAssets())
@stack('styles')
</head>
@ -17,13 +19,17 @@
<body style="zoom:80%!important" class="flex h-full metronic sidebar-fixed header-fixed bg-[#fefefe] dark:bg-coal-500">
@if (session('error'))
<em class="hidden toastr" data-type="error" data-message=" {{ session('status') }}"></em>
<em class="hidden toastr" data-type="error" data-message=" {{ session('error') }}"></em>
@endif
@if (session('info'))
<em class="hidden toastr" data-type="info" data-message=" {{ session('info') }}"></em>
@endif
@if (session('warning'))
<em class="hidden toastr" data-type="warning" data-message=" {{ session('warning') }}"></em>
@endif
@if (session('success'))
<em class="hidden toastr" data-type="success" data-message=" {{ session('success') }}"></em>
@endif
@ -51,6 +57,8 @@
}
</script>
<!--end::Theme mode setup on page load-->
<script src="{{ asset('vendor/filerobot-image-editor/filerobot-image-editor.min.js') }}"></script>
<script src="{{ asset('vendor/dropzone/dropzone.min.js') }}"></script>
@yield('main')
@stack('scripts')

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<div
class="sidebar dark:bg-coal-600 bg-light border-r border-r-gray-200 dark:border-r-coal-100 fixed top-0 bottom-0 z-20 hidden lg:flex flex-col items-stretch shrink-0 h-full"
class="sidebar bg-agi-50 dark:bg-coal-600 border-r border-r-gray-200 dark:border-r-coal-100 fixed top-0 bottom-0 z-20 hidden lg:flex flex-col items-stretch shrink-0 h-full"
data-drawer="true" data-drawer-class="drawer drawer-start top-0 bottom-0" data-drawer-enable="true|lg:false"
id="sidebar">
<div class="sidebar-header hidden lg:flex items-center relative justify-between px-3 lg:px-6 shrink-0"
@ -19,61 +19,61 @@
</i>
</button>
</div>
<div class="sidebar-content flex grow shrink-0 py-5 pr-2" id="sidebar_content">
<div class="sidebar-content flex grow shrink-0 py-5 pr-2 h-[100%]" id="sidebar_content">
<div class="scrollable-y-hover grow shrink-0 flex pl-2 lg:pl-5 pr-1 lg:pr-3" data-scrollable="true"
data-scrollable-dependencies="#sidebar_header" data-scrollable-height="auto" data-scrollable-offset="0px"
data-scrollable-wrappers="#sidebar_content" id="sidebar_scrollable">
data-scrollable-dependencies="#sidebar_header" data-scrollable-height="auto" data-scrollable-offset="10px"
data-scrollable-wrappers="#sidebar_content" id="sidebar_scrollable" style="--tw-scrollbar-thumb-color: var(--tw-primary)">
<div class="menu flex flex-col grow gap-0.5" data-menu="true" data-menu-accordion-expand-all="false"
id="sidebar_menu">
<div class="menu-item" data-menu-item-toggle="accordion" data-menu-item-trigger="click">
<a class="menu-item" href="/">
<div
class="menu-link flex items-center grow cursor-pointer border border-transparent gap-[10px] pl-[10px] pr-[10px] py-[6px]"
tabindex="0">
<span class="menu-icon items-start text-gray-500 dark:text-gray-400 w-[20px]">
<i class="ki-filled ki-element-11 text-lg"></i>
<i class="ki-filled ki-element-11 text-lg text-primary"></i>
</span>
<span
class="menu-title text-sm font-semibold text-gray-700 menu-item-active:text-primary menu-link-hover:!text-primary">
Dashboards
</span>
</div>
</div>
</a>
@php
$headingSystem = 0;
$headingMain = 0;
$headingMaster = 0;
// Ensure $menus is defined and is an object
$menus = isset($menus) ? json_decode(json_encode($menus)) : new stdClass;
// Define the order of sections
$sectionOrder = ['main', 'otorisator','laporan', 'master', 'system'];
$sectionTitles = [
'main' => 'Apps',
'otorisator' => 'Otorisator',
'laporan' => 'Laporan',
'master' => 'Master Data',
'system' => 'Systems'
];
@endphp
@php $menus = json_decode(json_encode($menus)); @endphp
@foreach($menus as $key => $value)
@foreach($value as $menu)
@if($key=='main')
@if($headingMain == 0)
@foreach($sectionOrder as $section)
@if(!empty($menus->$section))
@php
$hasVisibleItems = false;
foreach($menus->$section as $menu) {
if(auth()->user()->hasRole($menu->roles)) {
$hasVisibleItems = true;
break;
}
}
@endphp
@if($hasVisibleItems)
<div class="menu-item pt-2.25 pb-px">
<span class="menu-heading uppercase text-2sm font-semibold text-gray-500 pl-[10px] pr-[10px]">
Apps
{{ $sectionTitles[$section] }}
</span>
</div>
@php $headingMain = 1; @endphp
@endif
@elseif($key=='master')
@if($headingMaster == 0)
<div class="menu-item pt-2.25 pb-px">
<span class="menu-heading uppercase text-2sm font-semibold text-gray-500 pl-[10px] pr-[10px]">
Master Data
</span>
</div>
@php $headingMaster = 1; @endphp
@endif
@elseif($key=='system')
@if($headingSystem == 0)
<div class="menu-item pt-2.25 pb-px">
<span class="menu-heading uppercase text-2sm font-semibold text-gray-500 pl-[10px] pr-[10px]">
Systems
</span>
</div>
@php $headingSystem = 1; @endphp
@endif
@endif
@foreach($menus->$section as $menu)
@if(auth()->user()->hasRole($menu->roles))
@if(isset($menu->sub))
<div class="menu-item {{ request()->routeIs($menu->path) || request()->routeIs($menu->path.'.*') ? 'show' : '' }}" data-menu-item-toggle="accordion" data-menu-item-trigger="click">
@ -84,7 +84,31 @@
<i class="{{ $menu->icon ?? 'ki-filled ki-element-11 text-lg' }}"></i>
</span>
<span class="menu-title text-sm font-semibold text-gray-700 menu-item-active:text-primary menu-link-hover:!text-primary">
{{ $menu->title }}
@php
$title = $menu->title;
if(strlen($title) > 30) {
$words = explode(' ', $title);
$lines = [];
$currentLine = '';
foreach($words as $word) {
if(strlen($currentLine . ' ' . $word) <= 30 || empty($currentLine)) {
$currentLine = empty($currentLine) ? $word : $currentLine . ' ' . $word;
} else {
$lines[] = $currentLine;
$currentLine = $word;
}
}
if(!empty($currentLine)) {
$lines[] = $currentLine;
}
echo implode('<br>', $lines);
} else {
echo $title;
}
@endphp
</span>
<span class="menu-arrow text-gray-400 w-[20px] shrink-0 justify-end ml-1 mr-[-10px]">
<i class="ki-filled ki-plus text-2xs menu-item-show:hidden">
@ -97,7 +121,7 @@
<div class="menu-accordion gap-0.5 pl-[10px] relative before:absolute before:left-[20px] before:top-0 before:bottom-0 before:border-l before:border-gray-200">
@foreach($menu->sub as $sub)
@if(auth()->user()->hasRole($sub->roles))
<div class="menu-item {{ request()->routeIs($sub->path.'.*') && in_array(request()->route()->getName(), [$sub->path.'.index', $sub->path.'.create', $sub->path.'.edit']) ? 'active' : '' }}">
<div class="menu-item {{ request()->routeIs($sub->path.'.*') && in_array(request()->route()->getName(), [$sub->path.'.index', $sub->path.'.create', $sub->path.'.edit', $sub->path.'.restore']) ? 'active' : '' }}">
<a class="menu-link gap-[14px] pl-[10px] pr-[10px] py-[8px] border border-transparent items-center grow menu-item-active:bg-secondary-active dark:menu-item-active:bg-coal-300 dark:menu-item-active:border-gray-100 menu-item-active:rounded-lg hover:bg-secondary-active dark:hover:bg-coal-300 dark:hover:border-gray-100 hover:rounded-lg"
href="{{ $sub->path ? route($sub->path.'.index') : '' }}" tabindex="0">
<span
@ -117,17 +141,43 @@
@else
<div class="menu-item {{ request()->routeIs($menu->path.'.*') ? 'active' : '' }}">
<a class="menu-link flex items-center grow cursor-pointer border border-transparent gap-[10px] pl-[10px] pr-[10px] py-[6px]" href="{{ $menu->path ? route($menu->path.'.index') : '' }}">
<span class="menu-icon items-start text-gray-500 dark:text-gray-400 w-[20px]">
<span class="menu-icon items-start text-gray-500 dark:text-gray-400 w-[20px] menu-item-active:text-primary menu-link-hover:!text-primary">
<i class="{{ $menu->icon ?? 'ki-filled ki-element-11 text-lg' }}"></i>
</span>
<span class="menu-title text-sm font-semibold text-gray-700 menu-item-active:text-primary menu-link-hover:!text-primary">
{{ $menu->title }}
@php
$title = $menu->title;
if(strlen($title) > 30) {
$words = explode(' ', $title);
$lines = [];
$currentLine = '';
foreach($words as $word) {
if(strlen($currentLine . ' ' . $word) <= 30 || empty($currentLine)) {
$currentLine = empty($currentLine) ? $word : $currentLine . ' ' . $word;
} else {
$lines[] = $currentLine;
$currentLine = $word;
}
}
if(!empty($currentLine)) {
$lines[] = $currentLine;
}
echo implode('<br>', $lines);
} else {
echo $title;
}
@endphp
</span>
</a>
</div>
@endif
@endif
@endforeach
@endif
@endif
@endforeach
</div>
</div>

View File

@ -6,4 +6,9 @@ use Illuminate\Support\Facades\Route;
return view('welcome');
})->name('dashboard');
Route::get('/notifications/count', function () {
return response()->json([
'count' => auth()->user()->unreadNotifications->count()
]);
})->name('notifications.count')->middleware('auth');
});

View File

@ -1,9 +1,6 @@
/** @type {import('tailwindcss').Config} */
/** @type {import("tailwindcss").Config} */
export default {
content: [
"./resources/**/*.{blade.php,js,vue,tsx}",
"./Modules/**/*.php",
],
content: ["./resources/**/*.{blade.php,js,vue,tsx}", "./Modules/**/*.php"],
safelist: [
"metronic",
"hidden",
@ -27,7 +24,7 @@ export default {
400: "#C4CADA",
500: "#99A1B7",
600: "#78829D",
700: "#4B5675",
700: "#252F4A",
800: "#252F4A",
900: "#071437",
},
@ -53,8 +50,8 @@ export default {
inverse: "#ffffff",
},
primary: {
default: "#1B84FF",
active: "#056EE9",
default: "#35C1D0", // Base color
active: "#1AA3B5", // Lebih gelap untuk efek active
light: "#EFF6FF",
clarity: "rgba(27, 132, 255, 0.20)",
inverse: "#ffffff",
@ -118,8 +115,8 @@ export default {
inverse: "#ffffff",
},
primary: {
default: "#006AE6",
active: "#107EFF",
default: "#35C1D0", // Base color
active: "#1AA3B5", // Lebih gelap untuk efek active
light: "#172331",
clarity: "rgba(0, 106, 230, 0.20)",
inverse: "#ffffff",
@ -214,6 +211,19 @@ export default {
800: "var(--tw-gray-800)",
900: "var(--tw-gray-900)",
},
agi: {
50: "#effcfc",
100: "#d5f6f8",
200: "#b1ecf0",
300: "#7bdde5",
400: "#35c1d0",
500: "#22a7b8",
600: "#1f879b",
700: "#206d7e",
800: "#225968",
900: "#214b58",
950: "#10313c",
},
primary: {
DEFAULT: "var(--tw-primary)",
active: "var(--tw-primary-active)",
@ -601,9 +611,9 @@ export default {
metronic: {
sidebar: {
width: {
desktop: "280px",
desktop: "320px",
desktopCollapse: "80px",
mobile: "280px",
mobile: "320px",
},
},
header: {